# --------------------------------------------------------------- # Copyright (C) 2005 Georgia Public Library Service # Bill Erickson # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # --------------------------------------------------------------- package OpenILS::Application::Circ::Survey; use base qw/OpenILS::Application/; use strict; use warnings; use OpenSRF::EX qw/:try/; use OpenILS::Application::AppUtils; use Data::Dumper; use OpenILS::Event; use Time::HiRes qw(time); use OpenILS::Utils::CStoreEditor qw/:funcs/; my $apputils = "OpenILS::Application::AppUtils"; # - creates a new survey # expects a survey complete with questions and answers __PACKAGE__->register_method( method => "add_survey", api_name => "open-ils.circ.survey.create"); sub add_survey { my( $self, $client, $user_session, $survey ) = @_; my($user_obj, $evt) = $apputils->checkses($user_session); return $evt if $evt; my $session = $apputils->start_db_session(); my $err = undef; my $id; try { $survey = _add_survey($session, $survey); _add_questions($session, $survey); $apputils->commit_db_session($session); } catch Error with { my $e = shift; $err = "Error creating survey: $e\n"; $apputils->rollback_db_session($session); }; if($err) { throw OpenSRF::EX::ERROR ($err); } # re-retrieve the survey from the db and return it return get_fleshed_survey($self, $client, $survey->id() ); } sub _add_survey { my($session, $survey) = @_; my $req = $session->request( "open-ils.storage.direct.action.survey.create", $survey ); my $id = $req->gather(1); if(!$id) { throw OpenSRF::EX::ERROR ("Unable to create new survey " . $survey->name()); } $survey->id($id); return $survey; } sub _update_survey { my($session, $survey) = @_; } sub _add_questions { my($session, $survey) = @_; # create new questions in the db if( $survey->questions() ) { for my $question (@{$survey->questions()}){ $question->survey($survey->id()); my $virtual_id = $question->id(); $question->clear_id(); my $req = $session->request( 'open-ils.storage.direct.action.survey_question.create', $question ); my $new_id = $req->gather(1); if(!$new_id) { throw OpenSRF::EX::ERROR ("Error creating new survey question " . $question->question() . "\n") } # now update the responses to this question if($question->answers()) { for my $answer (@{$question->answers()}) { $answer->question($new_id); _add_answer($session,$answer); } } } } } sub _add_answer { my($session, $answer) = @_; $answer->clear_id(); my $req = $session->request( "open-ils.storage.direct.action.survey_answer.create", $answer ); my $id = $req->gather(1); if(!$id) { throw OpenSRF::EX::ERROR ("Error creating survey answer " . $answer->answer() ); } } # retrieve surveys for a specific org subtree. __PACKAGE__->register_method( method => "get_required_surveys", api_name => "open-ils.circ.survey.retrieve.required"); sub get_required_surveys { my( $self, $client, $user_session ) = @_; my ($user_obj, $evt) = $apputils->checkses($user_session); return $evt if $evt; my $orgid = $user_obj->ws_ou() ? $user_obj->ws_ou() : $user_obj->home_ou(); my $surveys = $apputils->simple_scalar_request( "open-ils.storage", "open-ils.storage.action.survey.required.atomic", $orgid ); my @fleshed; for my $survey (@$surveys) { push(@fleshed, get_fleshed_survey($self, $client, $survey)); } return \@fleshed; } __PACKAGE__->register_method( method => "get_survey_responses", api_name => "open-ils.circ.survey.response.retrieve"); sub get_survey_responses { my( $self, $client, $user_session, $survey_id, $user_id ) = @_; if(!$user_id) { my ($user_obj, $evt) = $apputils->checkses($user_session); return $evt if $evt; $user_id = $user_obj->id; } my $res = $apputils->simple_scalar_request( "open-ils.cstore", "open-ils.cstore.direct.action.survey_response.search.atomic", { usr => $user_id, survey => $survey_id } ); if( $res && ref($res) and $res->[0]) { return [ sort { $a->id() <=> $b->id() } @$res ]; } return []; } __PACKAGE__->register_method( method => "get_all_surveys", api_name => "open-ils.circ.survey.retrieve.all"); sub get_all_surveys { my( $self, $client, $user_session ) = @_; my ($user_obj, $evt) = $apputils->checkses($user_session); return $evt if $evt; my $orgid = $user_obj->ws_ou() ? $user_obj->ws_ou() : $user_obj->home_ou(); my $surveys = $apputils->simple_scalar_request( "open-ils.storage", "open-ils.storage.action.survey.all.atomic", $orgid ); my @fleshed; for my $survey (@$surveys) { push(@fleshed, get_fleshed_survey($self, $client, $survey)); } return \@fleshed; } __PACKAGE__->register_method( method => "get_fleshed_survey", api_name => "open-ils.circ.survey.fleshed.retrieve"); sub get_fleshed_survey { my( $self, $client, $survey_id ) = @_; my $session = OpenSRF::AppSession->create("open-ils.storage"); my $survey; if( ref($survey_id) and (ref($survey_id) =~ /^Fieldmapper/)) { $survey = $survey_id; } else { my $sreq = $session->request( "open-ils.storage.direct.action.survey.retrieve", $survey_id ); $survey = $sreq->gather(1); if(! $survey) { return undef; } } $survey->questions([]); my $qreq = $session->request( "open-ils.storage.direct.action.survey_question.search.survey.atomic", $survey->id() ); my $questions = $qreq->gather(1); if($questions) { for my $question (@$questions) { next unless defined $question; # add this question to the survey push( @{$survey->questions()}, $question ); my $ans_req = $session->request( "open-ils.storage.direct.action.survey_answer.search.question.atomic", $question->id() ); # add this array of answers to this question $question->answers( $ans_req->gather(1) ); } } $session->disconnect(); return $survey; } __PACKAGE__->register_method( method => "submit_survey", api_name => "open-ils.circ.survey.submit.session"); __PACKAGE__->register_method( method => "submit_survey", api_name => "open-ils.circ.survey.submit.user_id"); __PACKAGE__->register_method( method => "submit_survey", api_name => "open-ils.circ.survey.submit.anon"); sub submit_survey { my( $self, $client, $responses ) = @_; if(!$responses) { throw OpenSRF::EX::ERROR ("No survey object sent in update"); } if(!ref($responses)) { $responses = [$responses]; } my $session = $apputils->start_db_session(); my $group_id = $session->request( "open-ils.storage.action.survey_response.next_group_id")->gather(1); my %already_seen; for my $res (@$responses) { my $id; if($self->api_name =~ /session/) { if( ! ($id = $already_seen{$res->usr}) ) { my ($user_obj, $evt) = $apputils->checkses($res->usr); return $evt if $evt; $id = $user_obj->id; $already_seen{$res->usr} = $id; } $res->usr($id); } elsif( $self->api_name =~ /anon/ ) { $res->clear_usr(); } $res->response_group_id($group_id); my $req = $session->request( "open-ils.storage.direct.action.survey_response.create", $res ); my $newid = $req->gather(1); if(!$newid) { throw OpenSRF::EX::ERROR ("Error creating new survey response"); } } $apputils->commit_db_session($session); return 1; } __PACKAGE__->register_method( method => "get_random_survey", api_name => "open-ils.circ.survey.retrieve.opac.random"); sub get_random_survey { my( $self, $client, $user_session ) = @_; my ($user_obj, $evt) = $apputils->checkses($user_session); return $evt if $evt; my $surveys = $apputils->simple_scalar_request( "open-ils.storage", "open-ils.storage.action.survey.opac.atomic", $user_obj->home_ou() ); my $random = int(rand(scalar(@$surveys))); my $surv = $surveys->[$random]; return get_fleshed_survey($self, $client, $surv); } __PACKAGE__->register_method( method => "get_random_survey_global", api_name => "open-ils.circ.survey.retrieve.opac.random.global"); sub get_random_survey_global { my( $self, $client ) = @_; my $surveys = $apputils->simple_scalar_request( "open-ils.storage", "open-ils.storage.direct.action.survey.search.atomic", # XXX grab the org tree to get the root id... { owner => 1, opac => 't' } ); my $random = int(rand(scalar(@$surveys))); my $surv = $surveys->[$random]; return get_fleshed_survey($self, $client, $surv); } __PACKAGE__->register_method ( method => 'delete_survey', api_name => 'open-ils.circ.survey.delete.cascade' ); __PACKAGE__->register_method ( method => 'delete_survey', api_name => 'open-ils.circ.survey.delete.cascade.override' ); sub delete_survey { my($self, $conn, $auth, $survey_id) = @_; my $e = new_editor(authtoken => $auth, xact => 1); return $e->die_event unless $e->checkauth; my $survey = $e->retrieve_action_survey($survey_id) or return $e->die_event; return $e->die_event unless $e->allowed('ADMIN_SURVEY', $survey->owner); my $questions = $e->search_action_survey_question({survey => $survey_id}); my @answers; push(@answers, @{$e->search_action_survey_answer({question => $_->id})}) for @$questions; my $responses = $e->search_action_survey_response({survey => $survey_id}); return OpenILS::Event->new('SURVEY_RESPONSES_EXIST') if @$responses and $self->api_name =! /override/; for my $resp (@$responses) { $e->delete_action_survey_response($resp) or return $e->die_event; } for my $ans (@answers) { $e->delete_action_survey_answer($ans) or return $e->die_event; } for my $quest (@$questions) { $e->delete_action_survey_question($quest) or return $e->die_event; } $e->delete_action_survey($survey) or return $e->die_event; $e->commit; return 1; } 1;