1 # ---------------------------------------------------------------
2 # Copyright (C) 2005 Georgia Public Library Service
3 # Bill Erickson <highfalutin@gmail.com>
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.
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 # ---------------------------------------------------------------
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;
23 use Time::HiRes qw(time);
24 use OpenILS::Utils::CStoreEditor qw/:funcs/;
25 use OpenSRF::Utils::Logger qw/$logger/;
27 my $apputils = "OpenILS::Application::AppUtils";
29 __PACKAGE__->register_method(
30 method => "update_survey",
31 api_name => "open-ils.circ.survey.update",
33 desc => q/Create, update, delete surveys, survey questions, and
34 survey answers. Relies on isnew ; isnchanged ; isdeleted
35 attributes of provided objects to determine outcome.
38 {desc => 'Authtoken', type => 'string'},
39 {desc => 'Fleshed survey (asv) object', type => 'object'}
41 return => '1 on success, event on error'
47 my ($self, $client, $auth, $survey) = @_;
49 my $e = new_editor(authtoken => $auth, xact => 1);
50 return $e->die_event unless $e->checkauth;
51 return $e->die_event unless $e->allowed('ADMIN_SURVEY', $survey->owner);
53 my $questions = $survey->questions || [];
55 if ($survey->isdeleted) {
57 $questions = $e->search_action_survey_question({survey => $survey->id});
58 $_->isdeleted(1) for @$questions;
59 $survey->questions($questions);
61 # Remove dependent data first.
62 return $e->die_event if update_questions($e, $survey);
63 return $e->die_event unless $e->delete_action_survey($survey);
70 return $e->die_event unless $e->create_action_survey($survey);
72 $_->isnew(1) for @$questions;
74 } elsif ($survey->ischanged) {
76 return $e->die_event unless $e->update_action_survey($survey);
79 return $e->die_event if update_questions($e, $survey);
85 $survey = $e->retrieve_action_survey([
88 flesh_fields => {asv => ['questions'], 'asvq' => ['answers']}
96 # returns undef on success, event on error
97 sub update_questions {
98 my ($e, $survey) = @_;
100 for my $question (@{$survey->questions}) {
102 if ($question->isdeleted) {
106 $e->search_action_survey_answer({question => $question->id});
107 $_->isdeleted(1) for @$answers;
108 $question->answers($answers);
110 # Delete linked objects first.
111 return 1 if update_answers($e, $question);
113 unless $e->delete_action_survey_question($question);
117 if ($question->ischanged) {
120 unless $e->update_action_survey_question($question);
122 } elsif ($question->isnew) {
124 $question->survey($survey->id);
127 return $e->die_event unless $e->create_action_survey_question($question);
130 return 1 if update_answers($e, $question);
138 my ($e, $question) = @_;
140 return undef unless $question->answers;
142 for my $answer (@{$question->answers}) {
144 if ($answer->isdeleted) {
146 $e->search_action_survey_response({answer => $answer->id});
148 for my $response (@$responses) {
149 return $e->die_event unless
150 $e->delete_action_survey_response($response);
153 return $e->die_event unless $e->delete_action_survey_answer($answer);
155 } elsif ($answer->isnew) {
158 $answer->question($question->id);
161 unless $e->create_action_survey_answer($answer);
163 } elsif ($answer->ischanged) {
165 unless $e->update_action_survey_answer($answer);
174 # - creates a new survey
175 # expects a survey complete with questions and answers
176 __PACKAGE__->register_method(
177 method => "add_survey",
178 api_name => "open-ils.circ.survey.create");
181 my( $self, $client, $user_session, $survey ) = @_;
183 my($user_obj, $evt) = $apputils->checkses($user_session);
186 my $session = $apputils->start_db_session();
187 $apputils->set_audit_info($session, $user_session, $user_obj->id, $user_obj->wsid);
188 my $err = undef; my $id;
193 $survey = _add_survey($session, $survey);
194 _add_questions($session, $survey);
195 $apputils->commit_db_session($session);
199 $err = "Error creating survey: $e\n";
200 $apputils->rollback_db_session($session);
203 if($err) { throw OpenSRF::EX::ERROR ($err); }
205 # re-retrieve the survey from the db and return it
206 return get_fleshed_survey($self, $client, $survey->id() );
211 my($session, $survey) = @_;
212 my $req = $session->request(
213 "open-ils.storage.direct.action.survey.create",
216 my $id = $req->gather(1);
219 throw OpenSRF::EX::ERROR
220 ("Unable to create new survey " . $survey->name());
228 my($session, $survey) = @_;
230 # create new questions in the db
231 if( $survey->questions() ) {
232 for my $question (@{$survey->questions()}){
234 $question->survey($survey->id());
235 my $virtual_id = $question->id();
236 $question->clear_id();
239 my $req = $session->request(
240 'open-ils.storage.direct.action.survey_question.create',
242 my $new_id = $req->gather(1);
245 throw OpenSRF::EX::ERROR
246 ("Error creating new survey question " . $question->question() . "\n")
249 # now update the responses to this question
250 if($question->answers()) {
251 for my $answer (@{$question->answers()}) {
252 $answer->question($new_id);
253 _add_answer($session,$answer);
262 my($session, $answer) = @_;
264 my $req = $session->request(
265 "open-ils.storage.direct.action.survey_answer.create",
267 my $id = $req->gather(1);
269 throw OpenSRF::EX::ERROR
270 ("Error creating survey answer " . $answer->answer() );
277 # retrieve surveys for a specific org subtree.
278 __PACKAGE__->register_method(
279 method => "get_required_surveys",
280 api_name => "open-ils.circ.survey.retrieve.required");
282 sub get_required_surveys {
283 my( $self, $client, $user_session ) = @_;
286 my ($user_obj, $evt) = $apputils->checkses($user_session);
289 my $orgid = $user_obj->ws_ou() ? $user_obj->ws_ou() : $user_obj->home_ou();
290 my $surveys = $apputils->simple_scalar_request(
292 "open-ils.storage.action.survey.required.atomic",
296 for my $survey (@$surveys) {
297 push(@fleshed, get_fleshed_survey($self, $client, $survey));
303 __PACKAGE__->register_method(
304 method => "get_survey_responses",
305 api_name => "open-ils.circ.survey.response.retrieve");
307 sub get_survey_responses {
308 my( $self, $client, $user_session, $survey_id, $user_id ) = @_;
311 my ($user_obj, $evt) = $apputils->checkses($user_session);
313 $user_id = $user_obj->id;
316 my $res = $apputils->simple_scalar_request(
318 "open-ils.cstore.direct.action.survey_response.search.atomic",
319 { usr => $user_id, survey => $survey_id } );
321 if( $res && ref($res) and $res->[0]) {
322 return [ sort { $a->id() <=> $b->id() } @$res ];
328 __PACKAGE__->register_method(
329 method => "get_all_surveys",
330 api_name => "open-ils.circ.survey.retrieve.all");
332 sub get_all_surveys {
333 my( $self, $client, $user_session ) = @_;
335 my ($user_obj, $evt) = $apputils->checkses($user_session);
338 my $orgid = $user_obj->ws_ou() ? $user_obj->ws_ou() : $user_obj->home_ou();
339 my $surveys = $apputils->simple_scalar_request(
341 "open-ils.storage.action.survey.all.atomic",
345 for my $survey (@$surveys) {
346 push(@fleshed, get_fleshed_survey($self, $client, $survey));
354 __PACKAGE__->register_method(
355 method => "get_fleshed_survey",
356 api_name => "open-ils.circ.survey.fleshed.retrieve");
358 sub get_fleshed_survey {
359 my( $self, $client, $survey_id ) = @_;
361 my $session = OpenSRF::AppSession->create("open-ils.storage");
364 if( ref($survey_id) and
365 (ref($survey_id) =~ /^Fieldmapper/)) {
366 $survey = $survey_id;
370 my $sreq = $session->request(
371 "open-ils.storage.direct.action.survey.retrieve",
373 $survey = $sreq->gather(1);
374 if(! $survey) { return undef; }
377 $survey->questions([]);
380 my $qreq = $session->request(
381 "open-ils.storage.direct.action.survey_question.search.survey.atomic",
384 my $questions = $qreq->gather(1);
388 for my $question (@$questions) {
389 next unless defined $question;
391 # add this question to the survey
392 push( @{$survey->questions()}, $question );
395 my $ans_req = $session->request(
396 "open-ils.storage.direct.action.survey_answer.search.question.atomic",
399 # add this array of answers to this question
400 $question->answers( $ans_req->gather(1) );
405 $session->disconnect();
412 __PACKAGE__->register_method(
413 method => "submit_survey",
414 api_name => "open-ils.circ.survey.submit.session");
416 __PACKAGE__->register_method(
417 method => "submit_survey",
418 api_name => "open-ils.circ.survey.submit.user_id");
420 __PACKAGE__->register_method(
421 method => "submit_survey",
422 api_name => "open-ils.circ.survey.submit.anon");
426 my( $self, $client, $responses ) = @_;
429 throw OpenSRF::EX::ERROR
430 ("No survey object sent in update");
434 if(!ref($responses)) { $responses = [$responses]; }
436 my $session = $apputils->start_db_session();
438 my $group_id = $session->request(
439 "open-ils.storage.action.survey_response.next_group_id")->gather(1);
442 for my $res (@$responses) {
446 if($self->api_name =~ /session/) {
447 if( ! ($id = $already_seen{$res->usr}) ) {
448 my ($user_obj, $evt) = $apputils->checkses($res->usr);
451 $already_seen{$res->usr} = $id;
454 } elsif( $self->api_name =~ /anon/ ) {
458 $res->response_group_id($group_id);
459 my $req = $session->request(
460 "open-ils.storage.direct.action.survey_response.create",
462 my $newid = $req->gather(1);
465 throw OpenSRF::EX::ERROR
466 ("Error creating new survey response");
470 $apputils->commit_db_session($session);
476 __PACKAGE__->register_method(
477 method => "get_random_survey",
478 api_name => "open-ils.circ.survey.retrieve.opac.random");
480 sub get_random_survey {
481 my( $self, $client, $user_session ) = @_;
483 my ($user_obj, $evt) = $apputils->checkses($user_session);
486 my $surveys = $apputils->simple_scalar_request(
488 "open-ils.storage.action.survey.opac.atomic",
489 $user_obj->home_ou() );
491 my $random = int(rand(scalar(@$surveys)));
492 my $surv = $surveys->[$random];
494 return get_fleshed_survey($self, $client, $surv);
498 __PACKAGE__->register_method(
499 method => "get_random_survey_global",
500 api_name => "open-ils.circ.survey.retrieve.opac.random.global");
502 sub get_random_survey_global {
503 my( $self, $client ) = @_;
505 my $surveys = $apputils->simple_scalar_request(
507 "open-ils.storage.direct.action.survey.search.atomic",
508 # XXX grab the org tree to get the root id...
509 { owner => 1, opac => 't' } );
511 my $random = int(rand(scalar(@$surveys)));
512 my $surv = $surveys->[$random];
514 return get_fleshed_survey($self, $client, $surv);
519 __PACKAGE__->register_method (
520 method => 'delete_survey',
521 api_name => 'open-ils.circ.survey.delete.cascade'
523 __PACKAGE__->register_method (
524 method => 'delete_survey',
525 api_name => 'open-ils.circ.survey.delete.cascade.override'
529 my($self, $conn, $auth, $survey_id, $oargs) = @_;
530 my $e = new_editor(authtoken => $auth, xact => 1);
531 return $e->die_event unless $e->checkauth;
532 $oargs = { all => 1 } unless defined $oargs;
534 my $survey = $e->retrieve_action_survey($survey_id)
535 or return $e->die_event;
536 return $e->die_event unless $e->allowed('ADMIN_SURVEY', $survey->owner);
538 my $questions = $e->search_action_survey_question({survey => $survey_id});
540 push(@answers, @{$e->search_action_survey_answer({question => $_->id})}) for @$questions;
541 my $responses = $e->search_action_survey_response({survey => $survey_id});
543 return OpenILS::Event->new('SURVEY_RESPONSES_EXIST')
544 if @$responses and ($self->api_name =! /override/ || !($oargs->{all} || grep { $_ eq 'SURVEY_RESPONSES_EXIST' } @{$oargs->{events}}));
546 for my $resp (@$responses) {
547 $e->delete_action_survey_response($resp) or return $e->die_event;
550 for my $ans (@answers) {
551 $e->delete_action_survey_answer($ans) or return $e->die_event;
554 for my $quest (@$questions) {
555 $e->delete_action_survey_question($quest) or return $e->die_event;
558 $e->delete_action_survey($survey) or return $e->die_event;