From 08ef7ad8174db0e8ec589addca8594216bce870b Mon Sep 17 00:00:00 2001 From: Pedro Amorim Date: Fri, 5 Jan 2024 15:24:07 +0000 Subject: [PATCH] Bug 35604: ConfirmAuto workflow stage Sponsored-by: NHS England Sponsored-by: PTFS Europe Ltd Signed-off-by: David Nind Signed-off-by: Martin Renvoize --- Koha/ILL/Request/Workflow/ConfirmAuto.pm | 116 +++++++++++++ ill/ill-requests.pl | 39 +++-- .../prog/en/modules/ill/ill-requests.tt | 48 +++++ .../intranet-tmpl/prog/js/ill-autobackend.js | 164 ++++++++++++++++++ .../bootstrap/en/modules/opac-illrequests.tt | 42 ++++- .../opac-tmpl/bootstrap/js/ill-autobackend.js | 161 +++++++++++++++++ opac/opac-illrequests.pl | 11 ++ 7 files changed, 566 insertions(+), 15 deletions(-) create mode 100644 Koha/ILL/Request/Workflow/ConfirmAuto.pm create mode 100644 koha-tmpl/intranet-tmpl/prog/js/ill-autobackend.js create mode 100644 koha-tmpl/opac-tmpl/bootstrap/js/ill-autobackend.js diff --git a/Koha/ILL/Request/Workflow/ConfirmAuto.pm b/Koha/ILL/Request/Workflow/ConfirmAuto.pm new file mode 100644 index 00000000000..fe257020114 --- /dev/null +++ b/Koha/ILL/Request/Workflow/ConfirmAuto.pm @@ -0,0 +1,116 @@ +package Koha::ILL::Request::Workflow::ConfirmAuto; + +# Copyright 2023 PTFS Europe Ltd +# +# This file is part of Koha. +# +# Koha 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 3 of the License, or +# (at your option) any later version. +# +# Koha 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. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use base qw(Koha::ILL::Request::Workflow); + +use JSON qw( encode_json ); +use Koha::ILL::Backends; + +=head1 NAME + +Koha::ILL::Request::Workflow::ConfirmAuto - Koha ILL ConfirmAuto Workflow + +=head1 SYNOPSIS + +Object-oriented class that provides the AutoILLBackendPriority confirmation screen + +=head1 DESCRIPTION + +This class provides the ability to verify if it should render the AutoILLBackendPriority +confirmation screen and handle the template params accordingly + +=head1 API + +=head2 Class Methods + +=head3 show_confirm_auto + + my $show_confirm_auto = + Koha::ILL::Request::Workflow::ConfirmAuto->show_confirm_auto($params); + +Given $request, returns true if confirm auto should be shown + +=cut + +sub show_confirm_auto { + my ( $self, $request ) = @_; + + return + + # AutoILLBackendPriority is enabled + C4::Context->preference("AutoILLBackendPriority") + + # Confirm auto has not yet been submitted + && !$self->{metadata}->{confirm_auto_submitted} + + # The form has been submitted and the backend is able to create the request + && $request->_backend_capability( 'can_create_request', $self->{metadata} ); + +} + +=head3 confirm_auto_template_params + +Given $params, returns the template parameters for rendering the confirm auto screen + +=cut + +sub confirm_auto_template_params { + my ( $self, $params ) = @_; + + $params->{method} = 'confirmautoill' if $self->{ui_context} eq 'staff'; + delete $params->{stage} if $self->{ui_context} eq 'staff'; + + my @backends = $self->get_priority_backends(); + return ( + whole => $params, + metadata => $self->prep_metadata($params), + core_fields => Koha::ILL::Backend::Standard->_get_core_fields, + auto_backends_json => scalar encode_json( \@backends ), + $self->{ui_context} eq 'opac' + ? ( + illrequestsview => 1, + message => $params->{message}, + op => 'confirmautoill', + ) + : () + ); +} + +=head3 get_priority_backends + +Returns backends ordered by AutoILLBackendPriority + +=cut + +sub get_priority_backends { + my ( $self, $params ) = @_; + + my @backends; + my @priority_enabled_backends = split ",", C4::Context->preference('AutoILLBackendPriority'); + foreach my $backend (@priority_enabled_backends) { + my $loaded_backend = Koha::ILL::Request->new->load_backend($backend); + my $availability_check_info = $loaded_backend->_backend->availability_check_info( $self->{metadata} ); + push @backends, $availability_check_info if $availability_check_info; + } + return @backends; +} + +1; diff --git a/ill/ill-requests.pl b/ill/ill-requests.pl index 3f093bb062f..825f5ea00fa 100755 --- a/ill/ill-requests.pl +++ b/ill/ill-requests.pl @@ -31,6 +31,7 @@ use Koha::ILL::Request; use Koha::ILL::Batches; use Koha::ILL::Request::Workflow::Availability; use Koha::ILL::Request::Workflow::TypeDisclaimer; +use Koha::ILL::Request::Workflow::ConfirmAuto; use Koha::Libraries; use Koha::Plugins; @@ -97,7 +98,7 @@ if ( $backends_available ) { if ( $op eq 'illview' ) { # View the details of an ILL - my $request = Koha::ILL::Requests->find($params->{illrequest_id}); + my $request = Koha::ILL::Requests->find( $params->{illrequest_id} ); # Get the details for notices that can be sent from here my $notices = Koha::Notice::Templates->search( @@ -137,6 +138,8 @@ if ( $backends_available ) { Koha::ILL::Request::Workflow::Availability->new( $params, 'staff' ); my $type_disclaimer = Koha::ILL::Request::Workflow::TypeDisclaimer->new( $params, 'staff' ); + my $confirm_auto = + Koha::ILL::Request::Workflow::ConfirmAuto->new( $params, 'staff' ); # ILLCheckAvailability operation if ($availability->show_availability($request)) { @@ -150,6 +153,12 @@ if ( $backends_available ) { $template->param( $type_disclaimer->type_disclaimer_template_params($params) ); + # ConfirmAuto operation + } elsif ( $confirm_auto->show_confirm_auto($request)) { + $op = 'confirmautoill'; + $template->param( + $confirm_auto->confirm_auto_template_params($params) + ); # Ready to create ILL request } else { my $backend_result = $request->backend_create($params); @@ -167,7 +176,7 @@ if ( $backends_available ) { } } elsif ( $op eq 'migrate' ) { # We're in the process of migrating a request - my $request = Koha::ILL::Requests->find($params->{illrequest_id}); + my $request = Koha::ILL::Requests->find( $params->{illrequest_id} ); my $backend_result; if ( $params->{backend} ) { $backend_result = $request->backend_migrate($params); @@ -198,7 +207,7 @@ if ( $backends_available ) { } elsif ( $op eq 'confirm' ) { # Backend 'confirm' method # confirm requires a specific request, so first, find it. - my $request = Koha::ILL::Requests->find($params->{illrequest_id}); + my $request = Koha::ILL::Requests->find( $params->{illrequest_id} ); my $backend_result = $request->backend_confirm($params); $template->param( whole => $backend_result, @@ -211,7 +220,7 @@ if ( $backends_available ) { } elsif ( $op eq 'cud-cancel' ) { # Backend 'cancel' method # cancel requires a specific request, so first, find it. - my $request = Koha::ILL::Requests->find($params->{illrequest_id}); + my $request = Koha::ILL::Requests->find( $params->{illrequest_id} ); my $backend_result = $request->backend_cancel($params); $template->param( whole => $backend_result, @@ -227,7 +236,7 @@ if ( $backends_available ) { # (not the Illrequestattributes) # We simulate the API for backend requests for uniformity. # So, init: - my $request = Koha::ILL::Requests->find($params->{illrequest_id}); + my $request = Koha::ILL::Requests->find( $params->{illrequest_id} ); my $batches = Koha::ILL::Batches->search(undef, { order_by => { -asc => 'name' } }); @@ -295,7 +304,7 @@ if ( $backends_available ) { redirect_to_list(); } elsif ( $op eq 'delete_confirm') { - my $request = Koha::ILL::Requests->find($params->{illrequest_id}); + my $request = Koha::ILL::Requests->find( $params->{illrequest_id} ); $template->param( request => $request @@ -319,7 +328,7 @@ if ( $backends_available ) { } } elsif ( $op eq 'mark_completed' ) { - my $request = Koha::ILL::Requests->find($params->{illrequest_id}); + my $request = Koha::ILL::Requests->find( $params->{illrequest_id} ); my $backend_result = $request->mark_completed($params); $template->param( whole => $backend_result, @@ -334,7 +343,7 @@ if ( $backends_available ) { my $backend_result; my $request; try { - $request = Koha::ILL::Requests->find($params->{illrequest_id}); + $request = Koha::ILL::Requests->find( $params->{illrequest_id} ); $params->{current_branchcode} = C4::Context->mybranch; $backend_result = $request->generic_confirm($params); @@ -392,7 +401,7 @@ if ( $backends_available ) { redirect_user($backend_result, $request); } elsif ( $op eq 'cud-check_out') { $op =~ s/^cud-//; - my $request = Koha::ILL::Requests->find($params->{illrequest_id}); + my $request = Koha::ILL::Requests->find( $params->{illrequest_id} ); my $backend_result = $request->check_out($params); $template->param( params => $params, @@ -434,11 +443,13 @@ if ( $backends_available ) { $template->param( table_actions => encode_json( Koha::ILL::Request->get_staff_table_actions ) ); } elsif ( $op eq "cud-save_comment" ) { - my $comment = Koha::ILL::Comment->new({ - illrequest_id => scalar $params->{illrequest_id}, - borrowernumber => $patronnumber, - comment => scalar $params->{comment}, - }); + my $comment = Koha::ILL::Comment->new( + { + illrequest_id => scalar $params->{illrequest_id}, + borrowernumber => $patronnumber, + comment => scalar $params->{comment}, + } + ); $comment->store(); # Redirect to view the whole request print $cgi->redirect("/cgi-bin/koha/ill/ill-requests.pl?op=illview&illrequest_id=". diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/ill/ill-requests.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/ill/ill-requests.tt index ad624ad9692..bfd7d251de2 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/ill/ill-requests.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/ill/ill-requests.tt @@ -44,6 +44,13 @@ [% WRAPPER breadcrumb_item bc_active= 1 %] Request type disclaimer [% END %] + [% ELSIF op == 'confirmautoill' %] + [% WRAPPER breadcrumb_item %] + ILL requests + [% END %] + [% WRAPPER breadcrumb_item bc_active= 1 %] + Confirm automatic request + [% END %] [% ELSE %] [% WRAPPER breadcrumb_item bc_active= 1 %] ILL requests @@ -933,6 +940,39 @@ + [% ELSIF op == 'confirmautoill' %] + +

Confirm automatic request

+
+
+
+

Confirm backend:

+

+

+
+
+ [% FOREACH key IN whole.keys %] + [% value = whole.$key %] + [% IF key != 'method' && key != 'custom_key' && key != 'custom_value' %] + + [% END %] + [% END %] + [% custom_keys = whole.custom_key.split('\0') %] + [% custom_values = whole.custom_value.split('\0') %] + [% i = 0 %] + [% FOREACH custom_key IN custom_keys %] + + + [% i = i + 1 %] + [% END %] + + + + + Cancel +
+
+
[% ELSIF op == 'batch_list' || op == 'batch_create' %] [% INCLUDE 'ill-batch.inc' %] [% ELSE %] @@ -977,6 +1017,11 @@ [% ELSE %] var services = []; [% END %] + [% IF auto_backends_json.length > 0 %] + var auto_backends = [% auto_backends_json | $raw %]; + [% ELSE %] + var auto_backends = []; + [% END %] [% IF metadata.length > 0 %] var metadata = "[% metadata | $raw %]"; [% END %] @@ -1012,6 +1057,9 @@ [% IF (op == 'availability' || op == 'generic_confirm') && Koha.Preference('ILLCheckAvailability') %] [% Asset.js("js/ill-availability.js") | $raw %] [% END %] + [% IF (op == 'confirmautoill' && Koha.Preference('AutoILLBackendPriority')) %] + [% Asset.js("js/ill-autobackend.js") | $raw %] + [% END %] [% IF op == 'availability' && Koha.Preference('ILLCheckAvailability') %] [% END %] + [% IF op == 'confirmautoill' %] + [% Asset.js("js/ill-autobackend.js") | $raw %] + [% END %] [% TRY %] [% PROCESS backend_jsinclude %] [% CATCH %] diff --git a/koha-tmpl/opac-tmpl/bootstrap/js/ill-autobackend.js b/koha-tmpl/opac-tmpl/bootstrap/js/ill-autobackend.js new file mode 100644 index 00000000000..cc258854731 --- /dev/null +++ b/koha-tmpl/opac-tmpl/bootstrap/js/ill-autobackend.js @@ -0,0 +1,161 @@ +$(document).ready(function () { + let auto_ill_el = "#confirmautoill-form #autoillbackends"; + let auto_ill_message_el = "#confirmautoill-form #autoillbackend-message"; + + confirmAutoInit(); + getBackendsAvailability(auto_backends, metadata); + + /** + * Retrieves the backend availability for a given auto backend and metadata. + * + * @param {Object} auto_backend - The auto backend object. + * @param {string} metadata - The metadata string. + * @return {Promise} A Promise that resolves to the JSON response. + */ + async function getBackendAvailability(auto_backend, metadata) { + return $.ajax({ + url: auto_backend.endpoint + metadata, + type: "GET", + dataType: "json", + beforeSend: function () { + _addBackendPlaceholderEl(auto_backend.name); + _addBackendOption(auto_backend.name); + _addVerifyingMessage(auto_backend.name); + auto_backend.available = 0; + }, + success: function (data) { + _addSuccessMessage(auto_backend.name); + auto_backend.available = 1; + }, + error: function (request, textstatus) { + if (textstatus === "timeout") { + _addErrorMessage( + auto_backend.name, + __("Verification timed out.") + ); + } else { + let message = "Error"; + if (request.hasOwnProperty("responseJSON")) { + if (request.responseJSON.error) { + message = request.responseJSON.error; + } else if (request.responseJSON.errors) { + message = request.responseJSON.errors + .map(error => error.message) + .join(", "); + } + } + _addErrorMessage(auto_backend.name, message); + } + }, + timeout: 10000, + }); + } + + /** + * Asynchronously checks the availability of multiple auto backends. + * + * @param {Array} auto_backends - An array of auto backends to check availability for. + * @param {Object} metadata - Additional metadata for the availability check. + * @return {void} + */ + function getBackendsAvailability(auto_backends, metadata) { + let promises = []; + for (const auto_backend of auto_backends) { + try { + const prom = getBackendAvailability(auto_backend, metadata); + promises.push(prom); + } catch (e) { + console.log(e); + } + } + Promise.allSettled(promises).then(() => { + let auto_backend = auto_backends.find(backend => backend.available); + if (typeof auto_backend === "undefined") { + _setAutoBackend("Standard"); + } else { + _setAutoBackend(auto_backend.name); + } + $('#confirmautoill-form .action input[type="submit"]').prop( + "disabled", + false + ); + }); + _addBackendPlaceholderEl("Standard"); + _addBackendOption("Standard"); + } + + function _addSuccessMessage(auto_backend_name) { + _removeVerifyingMessage(auto_backend_name); + $(auto_ill_el + " > #backend-" + auto_backend_name).append( + ' ' + + __("Available.").format(auto_backend_name) + + "" + ); + } + + function _addErrorMessage(auto_backend_name, message) { + _removeVerifyingMessage(auto_backend_name); + $(auto_ill_el + " > #backend-" + auto_backend_name).append( + ' ' + + __("Not readily available:").format(auto_backend_name) + + " " + + message + + "" + ); + } + + function _addBackendOption(auto_backend_name) { + $(auto_ill_el + " > #backend-" + auto_backend_name).append( + ' ' + + ' " + ); + } + + function _addVerifyingMessage(auto_backend_name) { + $(auto_ill_el + " > #backend-" + auto_backend_name).append( + ' ' + + __("Verifying availability...").format(auto_backend_name) + + "" + ); + } + function _removeVerifyingMessage(auto_backend_name) { + $( + auto_ill_el + + " #backend-" + + auto_backend_name + + " #verifying-availabilty" + ).remove(); + } + + function _setAutoBackend(auto_backend_name) { + $( + '#confirmautoill-form #autoillbackends input[id="' + + auto_backend_name + + '"]' + ).prop("checked", true); + $("#confirmautoill-form").submit(); + } + + function _addBackendPlaceholderEl(auto_backend_name) { + $(auto_ill_el) + .append('
') + .hide(); + } + + function confirmAutoInit() { + $('#confirmautoill-form .action input[name="backend"]').remove(); + $(auto_ill_message_el).html( + ' ' + + __("Placing your request...") + + "" + ); + } +}); diff --git a/opac/opac-illrequests.pl b/opac/opac-illrequests.pl index bb746547a31..9e83d082be4 100755 --- a/opac/opac-illrequests.pl +++ b/opac/opac-illrequests.pl @@ -33,6 +33,7 @@ use Koha::ILL::Request; use Koha::Libraries; use Koha::Patrons; use Koha::ILL::Request::Workflow::Availability; +use Koha::ILL::Request::Workflow::ConfirmAuto; use Koha::ILL::Request::Workflow::TypeDisclaimer; my $query = CGI->new; @@ -126,6 +127,8 @@ if ( $op eq 'list' ) { Koha::ILL::Request::Workflow::Availability->new( $params, 'opac' ); my $type_disclaimer = Koha::ILL::Request::Workflow::TypeDisclaimer->new( $params, 'opac' ); + my $confirm_auto = + Koha::ILL::Request::Workflow::ConfirmAuto->new( $params, 'opac' ); # ILLCheckAvailability operation if ($availability->show_availability($request)) { @@ -147,6 +150,14 @@ if ( $op eq 'list' ) { $template->output, undef, { force_no_caching => 1 }; exit; + # ConfirmAuto operation + } elsif ( $confirm_auto->show_confirm_auto($request) ) { + $op = 'confirmautoill'; + $template->param( $confirm_auto->confirm_auto_template_params($params) ); + output_html_with_http_headers $query, $cookie, + $template->output, undef, + { force_no_caching => 1 }; + exit; } my $patron = Koha::Patrons->find( { borrowernumber => $loggedinuser } ); -- 2.39.5