Bug 26341: Database update for bug 21443 is not idempotent and will destroy settings
[koha.git] / ill / ill-requests.pl
blobdf80dd5406695fc25d7c0df05006b66ad594dd29
1 #!/usr/bin/perl
3 # Copyright 2013 PTFS-Europe Ltd and Mark Gavillet
4 # Copyright 2014 PTFS-Europe Ltd
6 # This file is part of Koha.
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
20 use Modern::Perl;
22 use CGI;
24 use C4::Auth;
25 use C4::Output;
26 use Koha::AuthorisedValues;
27 use Koha::Illcomment;
28 use Koha::Illrequests;
29 use Koha::Illrequest::Availability;
30 use Koha::Libraries;
31 use Koha::Token;
33 use Try::Tiny;
34 use URI::Escape;
35 use JSON;
37 our $cgi = CGI->new;
38 my $illRequests = Koha::Illrequests->new;
40 # Grab all passed data
41 # 'our' since Plack changes the scoping
42 # of 'my'
43 our $params = $cgi->Vars();
45 # Leave immediately if ILLModule is disabled
46 unless ( C4::Context->preference('ILLModule') ) {
47 print $cgi->redirect("/cgi-bin/koha/errors/404.pl");
48 exit;
51 my $op = $params->{method} || 'illlist';
53 my ( $template, $patronnumber, $cookie ) = get_template_and_user( {
54 template_name => 'ill/ill-requests.tt',
55 query => $cgi,
56 type => 'intranet',
57 flagsrequired => { ill => '*' },
58 } );
60 # Are we able to actually work?
61 my $cfg = Koha::Illrequest::Config->new;
62 my $backends = $cfg->available_backends;
63 my $has_branch = $cfg->has_branch;
64 my $backends_available = ( scalar @{$backends} > 0 );
65 $template->param(
66 backends_available => $backends_available,
67 has_branch => $has_branch
70 if ( $backends_available ) {
71 if ( $op eq 'illview' ) {
72 # View the details of an ILL
73 my $request = Koha::Illrequests->find($params->{illrequest_id});
75 $template->param(
76 request => $request,
77 csrf_token => Koha::Token->new->generate_csrf({
78 session_id => scalar $cgi->cookie('CGISESSID'),
79 }),
80 ( $params->{error} ? ( error => $params->{error} ) : () ),
83 } elsif ( $op eq 'create' ) {
84 # We're in the process of creating a request
85 my $request = Koha::Illrequest->new->load_backend( $params->{backend} );
86 # Does this backend enable us to insert an availability stage and should
87 # we? If not, proceed as normal.
88 if (
89 # If the user has elected to continue with the request despite
90 # having viewed availability info, this flag will be set
91 C4::Context->preference("ILLCheckAvailability")
92 && !$params->{checked_availability}
93 && $request->_backend_capability( 'should_display_availability', $params )
94 ) {
95 # Establish which of the installed availability providers
96 # can service our metadata
97 my $availability = Koha::Illrequest::Availability->new($params);
98 my $services = $availability->get_services({
99 ui_context => 'staff'
101 if (scalar @{$services} > 0) {
102 # Modify our method so we use the correct part of the
103 # template
104 $op = 'availability';
105 $params->{method} = 'availability';
106 delete $params->{stage};
107 # Prepare the metadata we're sending them
108 my $metadata = $availability->prep_metadata($params);
109 $template->param(
110 whole => $params,
111 metadata => $metadata,
112 services_json => scalar encode_json($services),
113 services => $services
115 } else {
116 # No services can process this metadata, so continue as normal
117 my $backend_result = $request->backend_create($params);
118 $template->param(
119 whole => $backend_result,
120 request => $request
122 handle_commit_maybe($backend_result, $request);
124 } else {
125 my $backend_result = $request->backend_create($params);
126 $template->param(
127 whole => $backend_result,
128 request => $request
130 handle_commit_maybe($backend_result, $request);
133 } elsif ( $op eq 'migrate' ) {
134 # We're in the process of migrating a request
135 my $request = Koha::Illrequests->find($params->{illrequest_id});
136 my $backend_result;
137 if ( $params->{backend} ) {
138 my $new_request = Koha::Illrequest->new->load_backend( $params->{backend} );
139 $backend_result = $new_request->backend_migrate($params);
140 if ($backend_result) {
141 $template->param(
142 whole => $backend_result,
143 request => $new_request
145 $request = $new_request;
146 } else {
147 # Backend failure, redirect back to illview
148 print $cgi->redirect( '/cgi-bin/koha/ill/ill-requests.pl'
149 . '?method=illview'
150 . '&illrequest_id='
151 . $request->id
152 . '&error=migrate_target' );
153 exit;
156 else {
157 $backend_result = $request->backend_migrate($params);
158 $template->param(
159 whole => $backend_result,
160 request => $request
163 handle_commit_maybe( $backend_result, $request );
165 } elsif ( $op eq 'confirm' ) {
166 # Backend 'confirm' method
167 # confirm requires a specific request, so first, find it.
168 my $request = Koha::Illrequests->find($params->{illrequest_id});
169 my $backend_result = $request->backend_confirm($params);
170 $template->param(
171 whole => $backend_result,
172 request => $request,
175 # handle special commit rules & update type
176 handle_commit_maybe($backend_result, $request);
178 } elsif ( $op eq 'cancel' ) {
179 # Backend 'cancel' method
180 # cancel requires a specific request, so first, find it.
181 my $request = Koha::Illrequests->find($params->{illrequest_id});
182 my $backend_result = $request->backend_cancel($params);
183 $template->param(
184 whole => $backend_result,
185 request => $request,
188 # handle special commit rules & update type
189 handle_commit_maybe($backend_result, $request);
191 } elsif ( $op eq 'edit_action' ) {
192 # Handle edits to the Illrequest object.
193 # (not the Illrequestattributes)
194 # We simulate the API for backend requests for uniformity.
195 # So, init:
196 my $request = Koha::Illrequests->find($params->{illrequest_id});
197 if ( !$params->{stage} ) {
198 my $backend_result = {
199 error => 0,
200 status => '',
201 message => '',
202 method => 'edit_action',
203 stage => 'init',
204 next => '',
205 value => {}
207 $template->param(
208 whole => $backend_result,
209 request => $request
211 } else {
212 # Commit:
213 # Save the changes
214 $request->borrowernumber($params->{borrowernumber});
215 $request->biblio_id($params->{biblio_id});
216 $request->branchcode($params->{branchcode});
217 $request->price_paid($params->{price_paid});
218 $request->notesopac($params->{notesopac});
219 $request->notesstaff($params->{notesstaff});
220 my $alias = (length $params->{status_alias} > 0) ?
221 $params->{status_alias} :
222 "-1";
223 $request->status_alias($alias);
224 $request->store;
225 my $backend_result = {
226 error => 0,
227 status => '',
228 message => '',
229 method => 'edit_action',
230 stage => 'commit',
231 next => 'illlist',
232 value => {}
234 handle_commit_maybe($backend_result, $request);
237 } elsif ( $op eq 'moderate_action' ) {
238 # Moderate action is required for an ILL submodule / syspref.
239 # Currently still needs to be implemented.
240 redirect_to_list();
242 } elsif ( $op eq 'delete_confirm') {
243 my $request = Koha::Illrequests->find($params->{illrequest_id});
245 $template->param(
246 request => $request
249 } elsif ( $op eq 'delete' ) {
251 # Check if the request is confirmed, if not, redirect
252 # to the confirmation view
253 if ($params->{confirmed}) {
254 # We simply delete the request...
255 Koha::Illrequests->find( $params->{illrequest_id} )->delete;
256 # ... then return to list view.
257 redirect_to_list();
258 } else {
259 print $cgi->redirect(
260 "/cgi-bin/koha/ill/ill-requests.pl?" .
261 "method=delete_confirm&illrequest_id=" .
262 $params->{illrequest_id});
263 exit;
266 } elsif ( $op eq 'mark_completed' ) {
267 my $request = Koha::Illrequests->find($params->{illrequest_id});
268 my $backend_result = $request->mark_completed($params);
269 $template->param(
270 whole => $backend_result,
271 request => $request,
274 # handle special commit rules & update type
275 handle_commit_maybe($backend_result, $request);
277 } elsif ( $op eq 'generic_confirm' ) {
278 my $backend_result;
279 my $request;
280 try {
281 $request = Koha::Illrequests->find($params->{illrequest_id});
282 $params->{current_branchcode} = C4::Context->mybranch;
283 $backend_result = $request->generic_confirm($params);
285 $template->param(
286 whole => $backend_result,
287 request => $request,
290 # Prepare availability searching, if required
291 # Get the definition for the z39.50 plugin
292 if ( C4::Context->preference('ILLCheckAvailability') ) {
293 my $availability = Koha::Illrequest::Availability->new($request->metadata);
294 my $services = $availability->get_services({
295 ui_context => 'partners',
296 metadata => {
297 name => 'ILL availability - z39.50'
300 # Only pass availability searching stuff to the template if
301 # appropriate
302 if ( scalar @{$services} > 0 ) {
303 my $metadata = $availability->prep_metadata($request->metadata);
304 $template->param( metadata => $metadata );
305 $template->param(
306 services_json => scalar encode_json($services)
308 $template->param( services => $services );
312 $template->param( error => $params->{error} )
313 if $params->{error};
315 catch {
316 my $error;
317 if ( ref($_) eq 'Koha::Exceptions::Ill::NoTargetEmail' ) {
318 $error = 'no_target_email';
320 elsif ( ref($_) eq 'Koha::Exceptions::Ill::NoLibraryEmail' ) {
321 $error = 'no_library_email';
323 else {
324 $error = 'unknown_error';
326 print $cgi->redirect(
327 "/cgi-bin/koha/ill/ill-requests.pl?" .
328 "method=generic_confirm&illrequest_id=" .
329 $params->{illrequest_id} .
330 "&error=$error" );
331 exit;
334 # handle special commit rules & update type
335 handle_commit_maybe($backend_result, $request);
336 } elsif ( $op eq 'check_out') {
337 my $request = Koha::Illrequests->find($params->{illrequest_id});
338 my $backend_result = $request->check_out($params);
339 $template->param(
340 params => $params,
341 whole => $backend_result,
342 request => $request
344 } elsif ( $op eq 'illlist') {
346 # If we receive a pre-filter, make it available to the template
347 my $possible_filters = ['borrowernumber'];
348 my $active_filters = {};
349 foreach my $filter(@{$possible_filters}) {
350 if ($params->{$filter}) {
351 # We shouldn't need to escape $filter here since we're using
352 # a whitelist, but just to be sure...
353 $active_filters->{uri_escape_utf8($filter)} =
354 uri_escape_utf8(scalar $params->{$filter});
357 my @tpl_arr = ();
358 if (keys %{$active_filters}) {
359 foreach my $key (keys %{$active_filters}) {
360 push @tpl_arr, $key . "=" . $active_filters->{$key};
363 $template->param(
364 prefilters => join("&", @tpl_arr)
366 } elsif ( $op eq "save_comment" ) {
367 die "Wrong CSRF token" unless Koha::Token->new->check_csrf({
368 session_id => scalar $cgi->cookie('CGISESSID'),
369 token => scalar $cgi->param('csrf_token'),
371 my $comment = Koha::Illcomment->new({
372 illrequest_id => scalar $params->{illrequest_id},
373 borrowernumber => $patronnumber,
374 comment => scalar $params->{comment},
376 $comment->store();
377 # Redirect to view the whole request
378 print $cgi->redirect("/cgi-bin/koha/ill/ill-requests.pl?method=illview&illrequest_id=".
379 scalar $params->{illrequest_id}
381 exit;
383 } else {
384 my $request = Koha::Illrequests->find($params->{illrequest_id});
385 my $backend_result = $request->custom_capability($op, $params);
386 $template->param(
387 whole => $backend_result,
388 request => $request,
391 # handle special commit rules & update type
392 handle_commit_maybe($backend_result, $request);
396 $template->param(
397 backends => $backends,
398 types => [ "Book", "Article", "Journal" ],
399 query_type => $op,
400 branches => scalar Koha::Libraries->search,
403 output_html_with_http_headers( $cgi, $cookie, $template->output );
405 sub handle_commit_maybe {
406 my ( $backend_result, $request ) = @_;
408 # We need to special case 'commit'
409 if ( $backend_result->{stage} eq 'commit' ) {
410 if ( $backend_result->{next} eq 'illview' ) {
412 # Redirect to a view of the newly created request
413 print $cgi->redirect( '/cgi-bin/koha/ill/ill-requests.pl'
414 . '?method=illview'
415 . '&illrequest_id='
416 . $request->id );
417 exit;
419 elsif ( $backend_result->{next} eq 'emigrate' ) {
421 # Redirect to a view of the newly created request
422 print $cgi->redirect( '/cgi-bin/koha/ill/ill-requests.pl'
423 . '?method=migrate'
424 . '&stage=emigrate'
425 . '&illrequest_id='
426 . $request->id );
427 exit;
429 else {
430 # Redirect to a requests list view
431 redirect_to_list();
436 sub redirect_to_list {
437 print $cgi->redirect('/cgi-bin/koha/ill/ill-requests.pl');
438 exit;