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