Merge branch 'master' of git.evergreen-ils.org:Evergreen into template-toolkit-opac
[working/Evergreen.git] / Open-ILS / src / perlmods / lib / OpenILS / Application / Circ / Survey.pm
1 # ---------------------------------------------------------------
2 # Copyright (C) 2005  Georgia Public Library Service 
3 # Bill Erickson <highfalutin@gmail.com>
4
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
9
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 # ---------------------------------------------------------------
15
16 package OpenILS::Application::Circ::Survey;
17 use base qw/OpenILS::Application/;
18 use strict; use warnings;
19 use OpenSRF::EX qw/:try/;
20 use OpenILS::Application::AppUtils;
21 use Data::Dumper;
22 use OpenILS::Event;
23 use Time::HiRes qw(time);
24 use OpenILS::Utils::CStoreEditor qw/:funcs/;
25
26 my $apputils = "OpenILS::Application::AppUtils";
27
28 # - creates a new survey
29 # expects a survey complete with questions and answers
30 __PACKAGE__->register_method(
31         method  => "add_survey",
32         api_name        => "open-ils.circ.survey.create");
33
34 sub add_survey {
35         my( $self, $client, $user_session, $survey ) = @_;
36
37         my($user_obj, $evt) = $apputils->checkses($user_session); 
38     return $evt if $evt;
39
40         my $session = $apputils->start_db_session();
41         my $err = undef; my $id;
42
43
44         try {
45
46                 $survey = _add_survey($session, $survey);
47                 _add_questions($session, $survey);
48                 $apputils->commit_db_session($session);
49
50         } catch Error with {
51                 my $e = shift;
52                 $err = "Error creating survey: $e\n";
53                 $apputils->rollback_db_session($session);
54         };
55
56         if($err) { throw OpenSRF::EX::ERROR ($err); }
57
58         # re-retrieve the survey from the db and return it
59         return get_fleshed_survey($self, $client, $survey->id() );
60 }
61
62
63 sub _add_survey {
64         my($session, $survey) = @_;
65         my $req = $session->request(
66                 "open-ils.storage.direct.action.survey.create",
67                 $survey );
68
69         my $id = $req->gather(1);
70
71         if(!$id) { 
72                 throw OpenSRF::EX::ERROR 
73                         ("Unable to create new survey " . $survey->name()); 
74         }
75
76         $survey->id($id);
77         return $survey;
78 }
79
80 sub _update_survey {
81         my($session, $survey) = @_;
82 }
83
84 sub _add_questions {
85         my($session, $survey) = @_;
86
87         # create new questions in the db
88         if( $survey->questions() ) {
89                 for my $question (@{$survey->questions()}){
90         
91                         $question->survey($survey->id());
92                         my $virtual_id = $question->id();
93                         $question->clear_id();
94
95         
96                         my $req = $session->request(
97                                 'open-ils.storage.direct.action.survey_question.create',
98                                 $question );
99                         my $new_id = $req->gather(1);
100         
101                         if(!$new_id) {
102                                 throw OpenSRF::EX::ERROR
103                                         ("Error creating new survey question " . $question->question() . "\n")
104                         }
105         
106                         # now update the responses to this question
107                         if($question->answers()) {
108                                 for my $answer (@{$question->answers()}) {
109                                         $answer->question($new_id);
110                                         _add_answer($session,$answer);
111                                 }
112                         }
113                 }
114         }
115 }
116
117
118 sub _add_answer {
119         my($session, $answer) = @_;
120         $answer->clear_id();
121         my $req = $session->request(
122                 "open-ils.storage.direct.action.survey_answer.create",
123                 $answer );
124         my $id = $req->gather(1);
125         if(!$id) {
126                 throw OpenSRF::EX::ERROR
127                         ("Error creating survey answer " . $answer->answer() );
128         }
129
130 }
131
132
133
134 # retrieve surveys for a specific org subtree.
135 __PACKAGE__->register_method(
136         method  => "get_required_surveys",
137         api_name        => "open-ils.circ.survey.retrieve.required");
138
139 sub get_required_surveys {
140         my( $self, $client, $user_session ) = @_;
141         
142
143         my ($user_obj, $evt) = $apputils->checkses($user_session); 
144     return $evt if $evt;
145
146         my $orgid = $user_obj->ws_ou() ? $user_obj->ws_ou() : $user_obj->home_ou();
147         my $surveys = $apputils->simple_scalar_request(
148                 "open-ils.storage",
149                 "open-ils.storage.action.survey.required.atomic",
150                 $orgid );
151
152         my @fleshed;
153         for my $survey (@$surveys) {
154                 push(@fleshed, get_fleshed_survey($self, $client, $survey));
155         }
156         return \@fleshed;
157
158 }
159
160 __PACKAGE__->register_method(
161         method  => "get_survey_responses",
162         api_name        => "open-ils.circ.survey.response.retrieve");
163
164 sub get_survey_responses {
165         my( $self, $client, $user_session, $survey_id, $user_id ) = @_;
166         
167         if(!$user_id) {
168             my ($user_obj, $evt) = $apputils->checkses($user_session); 
169         return $evt if $evt;
170                 $user_id = $user_obj->id;
171         }
172
173         my $res = $apputils->simple_scalar_request(
174                 "open-ils.cstore",
175                 "open-ils.cstore.direct.action.survey_response.search.atomic",
176                 { usr => $user_id, survey => $survey_id } );
177
178         if( $res && ref($res) and $res->[0]) {
179                 return [ sort { $a->id() <=> $b->id() } @$res ];
180         } 
181
182         return [];
183 }
184
185 __PACKAGE__->register_method(
186         method  => "get_all_surveys",
187         api_name        => "open-ils.circ.survey.retrieve.all");
188
189 sub get_all_surveys {
190         my( $self, $client, $user_session ) = @_;
191         
192     my ($user_obj, $evt) = $apputils->checkses($user_session); 
193     return $evt if $evt;
194
195         my $orgid = $user_obj->ws_ou() ? $user_obj->ws_ou() : $user_obj->home_ou();
196         my $surveys = $apputils->simple_scalar_request(
197                 "open-ils.storage",
198                 "open-ils.storage.action.survey.all.atomic",
199                 $orgid );
200
201         my @fleshed;
202         for my $survey (@$surveys) {
203                 push(@fleshed, get_fleshed_survey($self, $client, $survey));
204         }
205         return \@fleshed;
206 }
207
208
209
210
211 __PACKAGE__->register_method(
212         method  => "get_fleshed_survey",
213         api_name        => "open-ils.circ.survey.fleshed.retrieve");
214
215 sub get_fleshed_survey {
216         my( $self, $client, $survey_id ) = @_;
217
218         my $session = OpenSRF::AppSession->create("open-ils.storage");
219
220         my $survey;
221         if( ref($survey_id) and 
222                         (ref($survey_id) =~ /^Fieldmapper/)) {
223                 $survey = $survey_id;
224
225         } else {
226
227                 my $sreq = $session->request(
228                         "open-ils.storage.direct.action.survey.retrieve",
229                         $survey_id );
230                 $survey = $sreq->gather(1);
231                 if(! $survey) { return undef; }
232         }
233
234         $survey->questions([]);
235         
236
237         my $qreq = $session->request(
238                 "open-ils.storage.direct.action.survey_question.search.survey.atomic", 
239                 $survey->id() );
240
241         my $questions = $qreq->gather(1); 
242
243         if($questions) {
244
245                 for my $question (@$questions) {
246                         next unless defined $question;
247         
248                         # add this question to the survey
249                         push( @{$survey->questions()}, $question );
250         
251
252                         my $ans_req = $session->request(
253                                 "open-ils.storage.direct.action.survey_answer.search.question.atomic",
254                                 $question->id() );
255         
256                         # add this array of answers to this question
257                         $question->answers( $ans_req->gather(1) );
258         
259                 }
260         }
261
262         $session->disconnect();
263         return $survey;
264
265 }
266
267
268
269 __PACKAGE__->register_method(
270         method  => "submit_survey",
271         api_name        => "open-ils.circ.survey.submit.session");
272
273 __PACKAGE__->register_method(
274         method  => "submit_survey",
275         api_name        => "open-ils.circ.survey.submit.user_id");
276
277 __PACKAGE__->register_method(
278         method  => "submit_survey",
279         api_name        => "open-ils.circ.survey.submit.anon");
280
281
282 sub submit_survey {
283         my( $self, $client, $responses ) = @_;
284
285         if(!$responses) {
286                 throw OpenSRF::EX::ERROR 
287                         ("No survey object sent in update");
288         }
289
290
291         if(!ref($responses)) { $responses = [$responses]; }
292
293         my $session = $apputils->start_db_session();
294
295         my $group_id = $session->request(
296                 "open-ils.storage.action.survey_response.next_group_id")->gather(1);
297
298         my %already_seen;
299         for my $res (@$responses) {
300
301                 my $id; 
302
303                 if($self->api_name =~ /session/) {
304                         if( ! ($id = $already_seen{$res->usr}) ) {
305                 my ($user_obj, $evt) = $apputils->checkses($res->usr);
306                 return $evt if $evt;
307                                 $id = $user_obj->id;
308                                 $already_seen{$res->usr} = $id;
309                         }
310                         $res->usr($id);
311                 } elsif( $self->api_name =~ /anon/ ) {
312                         $res->clear_usr();
313                 }
314                 
315                 $res->response_group_id($group_id);
316                 my $req = $session->request(
317                         "open-ils.storage.direct.action.survey_response.create",
318                         $res );
319                 my $newid = $req->gather(1);
320
321                 if(!$newid) {
322                         throw OpenSRF::EX::ERROR
323                                 ("Error creating new survey response");
324                 }
325         }
326
327         $apputils->commit_db_session($session);
328
329         return 1;
330 }
331
332
333 __PACKAGE__->register_method(
334         method  => "get_random_survey",
335         api_name        => "open-ils.circ.survey.retrieve.opac.random");
336
337 sub get_random_survey {
338         my( $self, $client, $user_session ) = @_;
339         
340     my ($user_obj, $evt) = $apputils->checkses($user_session); 
341     return $evt if $evt;
342
343         my $surveys = $apputils->simple_scalar_request(
344                 "open-ils.storage",
345                 "open-ils.storage.action.survey.opac.atomic",
346                 $user_obj->home_ou() );
347
348         my $random = int(rand(scalar(@$surveys)));
349         my $surv = $surveys->[$random];
350
351         return get_fleshed_survey($self, $client, $surv);
352
353 }
354
355 __PACKAGE__->register_method(
356         method  => "get_random_survey_global",
357         api_name        => "open-ils.circ.survey.retrieve.opac.random.global");
358
359 sub get_random_survey_global {
360         my( $self, $client ) = @_;
361         
362         my $surveys = $apputils->simple_scalar_request(
363                 "open-ils.storage",
364                 "open-ils.storage.direct.action.survey.search.atomic",
365                 # XXX grab the org tree to get the root id...
366                 { owner => 1, opac => 't' } );
367
368         my $random = int(rand(scalar(@$surveys)));
369         my $surv = $surveys->[$random];
370
371         return get_fleshed_survey($self, $client, $surv);
372
373 }
374
375
376 __PACKAGE__->register_method (
377         method          => 'delete_survey',
378         api_name        => 'open-ils.circ.survey.delete.cascade'
379 );
380 __PACKAGE__->register_method (
381         method          => 'delete_survey',
382         api_name        => 'open-ils.circ.survey.delete.cascade.override'
383 );
384
385 sub delete_survey {
386     my($self, $conn, $auth, $survey_id) = @_;
387     my $e = new_editor(authtoken => $auth, xact => 1);
388     return $e->die_event unless $e->checkauth;
389
390     my $survey = $e->retrieve_action_survey($survey_id) 
391         or return $e->die_event;
392     return $e->die_event unless $e->allowed('ADMIN_SURVEY', $survey->owner);
393
394     my $questions = $e->search_action_survey_question({survey => $survey_id});
395     my @answers;
396     push(@answers, @{$e->search_action_survey_answer({question => $_->id})}) for @$questions;
397     my $responses = $e->search_action_survey_response({survey => $survey_id});
398
399     return OpenILS::Event->new('SURVEY_RESPONSES_EXIST')
400         if @$responses and $self->api_name =! /override/;
401
402     for my $resp (@$responses) {
403         $e->delete_action_survey_response($resp) or return $e->die_event;
404     }
405
406     for my $ans (@answers) {
407         $e->delete_action_survey_answer($ans) or return $e->die_event;
408     }
409
410     for my $quest (@$questions) {
411         $e->delete_action_survey_question($quest) or return $e->die_event;
412     }
413
414     $e->delete_action_survey($survey) or return $e->die_event;
415
416     $e->commit;
417     return 1;
418 }
419
420
421
422
423
424 1;