Bug 30719: ILL Batches
- Add batch column to requests table - Establish if there are any availability or metadata enrichment plugins and pass that to the template - Verify if we have any backend that can support batches, if not, don't show the option - Updates to the ILL toolbar - New ILL batch modal - New Koha classes - API specs Co-authored-by: Andrew Isherwood <andrew.isherwood@ptfs-europe.com> Signed-off-by: Edith Speller <Edith.Speller@ukhsa.gov.uk> Signed-off-by: Katrin Fischer <katrin.fischer@bsz-bw.de> Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
This commit is contained in:
parent
5bf5860370
commit
a5dbafec5b
|
|
@ -0,0 +1,196 @@
|
|||
package Koha::Illbatch;
|
||||
|
||||
# Copyright PTFS Europe 2022
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses>.
|
||||
|
||||
use Modern::Perl;
|
||||
use Koha::Database;
|
||||
use Koha::Illrequest::Logger;
|
||||
use Koha::IllbatchStatus;
|
||||
use JSON qw( to_json );
|
||||
use base qw(Koha::Object);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Koha::Illbatch - Koha Illbatch Object class
|
||||
|
||||
=head2 Class methods
|
||||
|
||||
=head3 status
|
||||
|
||||
my $status = Koha::Illbatch->status;
|
||||
|
||||
Return the status object associated with this batch
|
||||
|
||||
=cut
|
||||
|
||||
sub status {
|
||||
my ( $self ) = @_;
|
||||
return Koha::IllbatchStatus->_new_from_dbic(
|
||||
scalar $self->_result->statuscode
|
||||
);
|
||||
}
|
||||
|
||||
=head3 patron
|
||||
|
||||
my $patron = Koha::Illbatch->patron;
|
||||
|
||||
Return the patron object associated with this batch
|
||||
|
||||
=cut
|
||||
|
||||
sub patron {
|
||||
my ( $self ) = @_;
|
||||
return Koha::Patron->_new_from_dbic(
|
||||
scalar $self->_result->borrowernumber
|
||||
);
|
||||
}
|
||||
|
||||
=head3 branch
|
||||
|
||||
my $branch = Koha::Illbatch->branch;
|
||||
|
||||
Return the branch object associated with this batch
|
||||
|
||||
=cut
|
||||
|
||||
sub branch {
|
||||
my ( $self ) = @_;
|
||||
return Koha::Library->_new_from_dbic(
|
||||
scalar $self->_result->branchcode
|
||||
);
|
||||
}
|
||||
|
||||
=head3 requests_count
|
||||
|
||||
my $requests_count = Koha::Illbatch->requests_count;
|
||||
|
||||
Return the number of requests associated with this batch
|
||||
|
||||
=cut
|
||||
|
||||
sub requests_count {
|
||||
my ( $self ) = @_;
|
||||
return Koha::Illrequests->search({
|
||||
batch_id => $self->id
|
||||
})->count;
|
||||
}
|
||||
|
||||
=head3 create_and_log
|
||||
|
||||
$batch->create_and_log;
|
||||
|
||||
Log batch creation following storage
|
||||
|
||||
=cut
|
||||
|
||||
sub create_and_log {
|
||||
my ( $self ) = @_;
|
||||
|
||||
$self->store;
|
||||
|
||||
my $logger = Koha::Illrequest::Logger->new;
|
||||
|
||||
$logger->log_something({
|
||||
modulename => 'ILL',
|
||||
actionname => 'batch_create',
|
||||
objectnumber => $self->id,
|
||||
infos => to_json({})
|
||||
});
|
||||
}
|
||||
|
||||
=head3 update_and_log
|
||||
|
||||
$batch->update_and_log;
|
||||
|
||||
Log batch update following storage
|
||||
|
||||
=cut
|
||||
|
||||
sub update_and_log {
|
||||
my ( $self, $params ) = @_;
|
||||
|
||||
my $before = {
|
||||
name => $self->name,
|
||||
branchcode => $self->branchcode
|
||||
};
|
||||
|
||||
$self->set( $params );
|
||||
my $update = $self->store;
|
||||
|
||||
my $after = {
|
||||
name => $self->name,
|
||||
branchcode => $self->branchcode
|
||||
};
|
||||
|
||||
my $logger = Koha::Illrequest::Logger->new;
|
||||
|
||||
$logger->log_something({
|
||||
modulename => 'ILL',
|
||||
actionname => 'batch_update',
|
||||
objectnumber => $self->id,
|
||||
infos => to_json({
|
||||
before => $before,
|
||||
after => $after
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
=head3 delete_and_log
|
||||
|
||||
$batch->delete_and_log;
|
||||
|
||||
Log batch delete
|
||||
|
||||
=cut
|
||||
|
||||
sub delete_and_log {
|
||||
my ( $self ) = @_;
|
||||
|
||||
my $logger = Koha::Illrequest::Logger->new;
|
||||
|
||||
$logger->log_something({
|
||||
modulename => 'ILL',
|
||||
actionname => 'batch_delete',
|
||||
objectnumber => $self->id,
|
||||
infos => to_json({})
|
||||
});
|
||||
|
||||
$self->delete;
|
||||
}
|
||||
|
||||
=head2 Internal methods
|
||||
|
||||
=head3 _type
|
||||
|
||||
my $type = Koha::Illbatch->_type;
|
||||
|
||||
Return this object's type
|
||||
|
||||
=cut
|
||||
|
||||
sub _type {
|
||||
return 'Illbatch';
|
||||
}
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Andrew Isherwood <andrew.isherwood@ptfs-europe.com>
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
package Koha::Illbatches;
|
||||
|
||||
# Copyright PTFS Europe 2022
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses>.
|
||||
|
||||
use Modern::Perl;
|
||||
use Koha::Database;
|
||||
use Koha::Illbatch;
|
||||
use base qw(Koha::Objects);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Koha::Illbatches - Koha Illbatches Object class
|
||||
|
||||
=head2 Internal methods
|
||||
|
||||
=head3 _type
|
||||
|
||||
my $type = Koha::Illbatches->_type;
|
||||
|
||||
Return this object's type
|
||||
|
||||
=cut
|
||||
|
||||
sub _type {
|
||||
return 'Illbatch';
|
||||
}
|
||||
|
||||
=head3 object_class
|
||||
|
||||
my $class = Koha::Illbatches->object_class;
|
||||
|
||||
Return this object's class name
|
||||
|
||||
=cut
|
||||
|
||||
sub object_class {
|
||||
return 'Koha::Illbatch';
|
||||
}
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Andrew Isherwood <andrew.isherwood@ptfs-europe.com>
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
|
|
@ -0,0 +1,256 @@
|
|||
package Koha::REST::V1::Illbatches;
|
||||
|
||||
# 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 <http://www.gnu.org/licenses>.
|
||||
|
||||
use Modern::Perl;
|
||||
|
||||
use Mojo::Base 'Mojolicious::Controller';
|
||||
|
||||
use Koha::Illbatches;
|
||||
use Koha::IllbatchStatuses;
|
||||
use Koha::Illrequests;
|
||||
|
||||
use Try::Tiny qw( catch try );
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Koha::REST::V1::Illbatches
|
||||
|
||||
=head2 Operations
|
||||
|
||||
=head3 list
|
||||
|
||||
Return a list of available ILL batches
|
||||
|
||||
=cut
|
||||
|
||||
sub list {
|
||||
my $c = shift->openapi->valid_input;
|
||||
|
||||
#FIXME: This should be $c->objects-search
|
||||
my @batches = Koha::Illbatches->search()->as_list;
|
||||
|
||||
#FIXME: Below should be coming from $c->objects accessors
|
||||
# Get all patrons associated with all our batches
|
||||
# in one go
|
||||
my $patrons = {};
|
||||
foreach my $batch(@batches) {
|
||||
my $patron_id = $batch->borrowernumber;
|
||||
$patrons->{$patron_id} = 1
|
||||
};
|
||||
my @patron_ids = keys %{$patrons};
|
||||
my $patron_results = Koha::Patrons->search({
|
||||
borrowernumber => { -in => \@patron_ids }
|
||||
});
|
||||
|
||||
# Get all branches associated with all our batches
|
||||
# in one go
|
||||
my $branches = {};
|
||||
foreach my $batch(@batches) {
|
||||
my $branch_id = $batch->branchcode;
|
||||
$branches->{$branch_id} = 1
|
||||
};
|
||||
my @branchcodes = keys %{$branches};
|
||||
my $branch_results = Koha::Libraries->search({
|
||||
branchcode => { -in => \@branchcodes }
|
||||
});
|
||||
|
||||
# Get all batch statuses associated with all our batches
|
||||
# in one go
|
||||
my $statuses = {};
|
||||
foreach my $batch(@batches) {
|
||||
my $code = $batch->statuscode;
|
||||
$statuses->{$code} = 1
|
||||
};
|
||||
my @statuscodes = keys %{$statuses};
|
||||
my $status_results = Koha::IllbatchStatuses->search({
|
||||
code => { -in => \@statuscodes }
|
||||
});
|
||||
|
||||
# Populate the response
|
||||
my @to_return = ();
|
||||
foreach my $it_batch(@batches) {
|
||||
my $patron = $patron_results->find({ borrowernumber => $it_batch->borrowernumber});
|
||||
my $branch = $branch_results->find({ branchcode => $it_batch->branchcode });
|
||||
my $status = $status_results->find({ code => $it_batch->statuscode });
|
||||
push @to_return, {
|
||||
%{$it_batch->unblessed},
|
||||
patron => $patron,
|
||||
branch => $branch,
|
||||
status => $status,
|
||||
requests_count => $it_batch->requests_count
|
||||
};
|
||||
}
|
||||
|
||||
return $c->render( status => 200, openapi => \@to_return );
|
||||
}
|
||||
|
||||
=head3 get
|
||||
|
||||
Get one batch
|
||||
|
||||
=cut
|
||||
|
||||
sub get {
|
||||
my $c = shift->openapi->valid_input;
|
||||
|
||||
my $batchid = $c->validation->param('illbatch_id');
|
||||
|
||||
my $batch = Koha::Illbatches->find($batchid);
|
||||
|
||||
if (not defined $batch) {
|
||||
return $c->render(
|
||||
status => 404,
|
||||
openapi => { error => "ILL batch not found" }
|
||||
);
|
||||
}
|
||||
|
||||
return $c->render(
|
||||
status => 200,
|
||||
openapi => {
|
||||
%{$batch->unblessed},
|
||||
patron => $batch->patron->unblessed,
|
||||
branch => $batch->branch->unblessed,
|
||||
status => $batch->status->unblessed,
|
||||
requests_count => $batch->requests_count
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
=head3 add
|
||||
|
||||
Add a new batch
|
||||
|
||||
=cut
|
||||
|
||||
sub add {
|
||||
my $c = shift->openapi->valid_input or return;
|
||||
|
||||
my $body = $c->validation->param('body');
|
||||
|
||||
# We receive cardnumber, so we need to look up the corresponding
|
||||
# borrowernumber
|
||||
my $patron = Koha::Patrons->find({ cardnumber => $body->{cardnumber} });
|
||||
|
||||
if ( not defined $patron ) {
|
||||
return $c->render(
|
||||
status => 404,
|
||||
openapi => { error => "Patron with cardnumber " . $body->{cardnumber} . " not found" }
|
||||
);
|
||||
}
|
||||
|
||||
delete $body->{cardnumber};
|
||||
$body->{borrowernumber} = $patron->borrowernumber;
|
||||
|
||||
return try {
|
||||
my $batch = Koha::Illbatch->new( $body );
|
||||
$batch->create_and_log;
|
||||
$c->res->headers->location( $c->req->url->to_string . '/' . $batch->id );
|
||||
|
||||
my $ret = {
|
||||
%{$batch->unblessed},
|
||||
patron => $batch->patron->unblessed,
|
||||
branch => $batch->branch->unblessed,
|
||||
status => $batch->status->unblessed,
|
||||
requests_count => 0
|
||||
};
|
||||
|
||||
return $c->render(
|
||||
status => 201,
|
||||
openapi => $ret
|
||||
);
|
||||
}
|
||||
catch {
|
||||
if ( blessed $_ ) {
|
||||
if ( $_->isa('Koha::Exceptions::Object::DuplicateID') ) {
|
||||
return $c->render(
|
||||
status => 409,
|
||||
openapi => { error => "A batch named " . $body->{name} . " already exists" }
|
||||
);
|
||||
}
|
||||
}
|
||||
$c->unhandled_exception($_);
|
||||
};
|
||||
}
|
||||
|
||||
=head3 update
|
||||
|
||||
Update a batch
|
||||
|
||||
=cut
|
||||
|
||||
sub update {
|
||||
my $c = shift->openapi->valid_input or return;
|
||||
|
||||
my $batch = Koha::Illbatches->find( $c->validation->param('illbatch_id') );
|
||||
|
||||
if ( not defined $batch ) {
|
||||
return $c->render(
|
||||
status => 404,
|
||||
openapi => { error => "ILL batch not found" }
|
||||
);
|
||||
}
|
||||
|
||||
my $params = $c->req->json;
|
||||
delete $params->{cardnumber};
|
||||
|
||||
return try {
|
||||
$batch->update_and_log( $params );
|
||||
|
||||
my $ret = {
|
||||
%{$batch->unblessed},
|
||||
patron => $batch->patron->unblessed,
|
||||
branch => $batch->branch->unblessed,
|
||||
status => $batch->status->unblessed,
|
||||
requests_count => $batch->requests_count
|
||||
};
|
||||
|
||||
return $c->render(
|
||||
status => 200,
|
||||
openapi => $ret
|
||||
);
|
||||
}
|
||||
catch {
|
||||
$c->unhandled_exception($_);
|
||||
};
|
||||
}
|
||||
|
||||
=head3 delete
|
||||
|
||||
Delete a batch
|
||||
|
||||
=cut
|
||||
|
||||
sub delete {
|
||||
|
||||
my $c = shift->openapi->valid_input or return;
|
||||
|
||||
my $batch = Koha::Illbatches->find( $c->validation->param( 'illbatch_id' ) );
|
||||
|
||||
if ( not defined $batch ) {
|
||||
return $c->render( status => 404, openapi => { error => "ILL batch not found" } );
|
||||
}
|
||||
|
||||
return try {
|
||||
$batch->delete_and_log;
|
||||
return $c->render( status => 204, openapi => '');
|
||||
}
|
||||
catch {
|
||||
$c->unhandled_exception($_);
|
||||
};
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
@ -835,6 +835,8 @@ modules:
|
|||
columns:
|
||||
-
|
||||
columnname: ill_request_id
|
||||
-
|
||||
columnname: batch
|
||||
-
|
||||
columnname: metadata_author
|
||||
-
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
---
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: Internal ILL batch identifier
|
||||
name:
|
||||
type: string
|
||||
description: Name of the ILL batch
|
||||
backend:
|
||||
type: string
|
||||
description: Backend name
|
||||
cardnumber:
|
||||
type: string
|
||||
description: Card number of the patron of the ILL batch
|
||||
borrowernumber:
|
||||
type: string
|
||||
description: Borrower number of the patron of the ILL batch
|
||||
branchcode:
|
||||
type: string
|
||||
description: Branch code of the branch of the ILL batch
|
||||
patron:
|
||||
type:
|
||||
- object
|
||||
- "null"
|
||||
description: The patron associated with the batch
|
||||
branch:
|
||||
type:
|
||||
- object
|
||||
- "null"
|
||||
description: The branch associated with the batch
|
||||
statuscode:
|
||||
type: string
|
||||
description: Code of the status of the ILL batch
|
||||
status:
|
||||
type:
|
||||
- object
|
||||
- "null"
|
||||
description: The status associated with the batch
|
||||
requests_count:
|
||||
type: string
|
||||
description: The number of requests in this batch
|
||||
additionalProperties: false
|
||||
required:
|
||||
- name
|
||||
- backend
|
||||
- branchcode
|
||||
- statuscode
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
type: array
|
||||
items:
|
||||
$ref: "illbatch.yaml"
|
||||
additionalProperties: false
|
||||
|
|
@ -0,0 +1,236 @@
|
|||
---
|
||||
/illbatches:
|
||||
get:
|
||||
x-mojo-to: Illbatches#list
|
||||
operationId: listIllbatches
|
||||
tags:
|
||||
- illbatches
|
||||
summary: List ILL batches
|
||||
parameters: []
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: A list of ILL batches
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/illbatches"
|
||||
"401":
|
||||
description: Authentication required
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"403":
|
||||
description: Access forbidden
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"404":
|
||||
description: ILL batches not found
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"500":
|
||||
description: |
|
||||
Internal server error. Possible `error_code` attribute values:
|
||||
|
||||
* `internal_server_error`
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"503":
|
||||
description: Under maintenance
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
x-koha-authorization:
|
||||
permissions:
|
||||
ill: "1"
|
||||
post:
|
||||
x-mojo-to: Illbatches#add
|
||||
operationId: addIllbatch
|
||||
tags:
|
||||
- illbatches
|
||||
summary: Add ILL batch
|
||||
parameters:
|
||||
- name: body
|
||||
in: body
|
||||
description: A JSON object containing informations about the new batch
|
||||
required: true
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/illbatch"
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"201":
|
||||
description: Batch added
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/illbatch"
|
||||
"400":
|
||||
description: Bad request
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"401":
|
||||
description: Authentication required
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"403":
|
||||
description: Access forbidden
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"404":
|
||||
description: Patron with given cardnumber not found
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"409":
|
||||
description: Conflict in creating resource
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"500":
|
||||
description: |
|
||||
Internal server error. Possible `error_code` attribute values:
|
||||
|
||||
* `internal_server_error`
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"503":
|
||||
description: Under maintenance
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
x-koha-authorization:
|
||||
permissions:
|
||||
ill: "1"
|
||||
"/illbatches/{illbatch_id}":
|
||||
get:
|
||||
x-mojo-to: Illbatches#get
|
||||
operationId: getIllbatches
|
||||
tags:
|
||||
- illbatches
|
||||
summary: Get ILL batch
|
||||
parameters:
|
||||
- name: illbatch_id
|
||||
in: path
|
||||
description: ILL batch id/name/contents
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: An ILL batch
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/illbatch"
|
||||
"401":
|
||||
description: Authentication required
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"403":
|
||||
description: Access forbidden
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"404":
|
||||
description: ILL batch not found
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"500":
|
||||
description: |
|
||||
Internal server error. Possible `error_code` attribute values:
|
||||
|
||||
* `internal_server_error`
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"503":
|
||||
description: Under maintenance
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
x-koha-authorization:
|
||||
permissions:
|
||||
ill: "1"
|
||||
put:
|
||||
x-mojo-to: Illbatches#update
|
||||
operationId: updateIllBatch
|
||||
tags:
|
||||
- illbatches
|
||||
summary: Update batch
|
||||
parameters:
|
||||
- $ref: "../swagger.yaml#/parameters/illbatch_id_pp"
|
||||
- name: body
|
||||
in: body
|
||||
description: A JSON object containing information on the batch
|
||||
required: true
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/illbatch"
|
||||
consumes:
|
||||
- application/json
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: An ILL batch
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/illbatch"
|
||||
"400":
|
||||
description: Bad request
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"401":
|
||||
description: Authentication required
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"403":
|
||||
description: Access forbidden
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"404":
|
||||
description: ILL batch not found
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"500":
|
||||
description: |
|
||||
Internal server error. Possible `error_code` attribute values:
|
||||
|
||||
* `internal_server_error`
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"503":
|
||||
description: Under maintenance
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
x-koha-authorization:
|
||||
permissions:
|
||||
ill: "1"
|
||||
delete:
|
||||
x-mojo-to: Illbatches#delete
|
||||
operationId: deleteBatch
|
||||
tags:
|
||||
- illbatches
|
||||
summary: Delete ILL batch
|
||||
parameters:
|
||||
- $ref: "../swagger.yaml#/parameters/illbatch_id_pp"
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"204":
|
||||
description: ILL batch deleted
|
||||
schema:
|
||||
type: string
|
||||
"401":
|
||||
description: Authentication required
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"403":
|
||||
description: Access forbidden
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"404":
|
||||
description: ILL batch not found
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"500":
|
||||
description: |
|
||||
Internal server error. Possible `error_code` attribute values:
|
||||
|
||||
* `internal_server_error`
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"503":
|
||||
description: Under maintenance
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
x-koha-authorization:
|
||||
permissions:
|
||||
ill: "1"
|
||||
|
|
@ -27,10 +27,12 @@ use Koha::Notice::Templates;
|
|||
use Koha::AuthorisedValues;
|
||||
use Koha::Illcomment;
|
||||
use Koha::Illrequests;
|
||||
use Koha::Illbatches;
|
||||
use Koha::Illrequest::Workflow::Availability;
|
||||
use Koha::Illrequest::Workflow::TypeDisclaimer;
|
||||
use Koha::Libraries;
|
||||
use Koha::Token;
|
||||
use Koha::Plugins;
|
||||
|
||||
use Try::Tiny qw( catch try );
|
||||
use URI::Escape qw( uri_escape_utf8 );
|
||||
|
|
@ -66,10 +68,27 @@ my $has_branch = $cfg->has_branch;
|
|||
my $backends_available = ( scalar @{$backends} > 0 );
|
||||
$template->param(
|
||||
backends_available => $backends_available,
|
||||
has_branch => $has_branch
|
||||
has_branch => $has_branch,
|
||||
have_batch => have_batch_backends($backends)
|
||||
);
|
||||
|
||||
if ( $backends_available ) {
|
||||
# Establish what metadata enrichment plugins we have available
|
||||
my $enrichment_services = get_metadata_enrichment();
|
||||
if (scalar @{$enrichment_services} > 0) {
|
||||
$template->param(
|
||||
metadata_enrichment_services => encode_json($enrichment_services)
|
||||
);
|
||||
}
|
||||
# Establish whether we have any availability services that can provide availability
|
||||
# for the batch identifier types we support
|
||||
my $batch_availability_services = get_ill_availability($enrichment_services);
|
||||
if (scalar @{$batch_availability_services} > 0) {
|
||||
$template->param(
|
||||
batch_availability_services => encode_json($batch_availability_services)
|
||||
);
|
||||
}
|
||||
|
||||
if ( $op eq 'illview' ) {
|
||||
# View the details of an ILL
|
||||
my $request = Koha::Illrequests->find($params->{illrequest_id});
|
||||
|
|
@ -138,8 +157,8 @@ if ( $backends_available ) {
|
|||
}
|
||||
|
||||
$template->param(
|
||||
whole => $backend_result,
|
||||
request => $request
|
||||
whole => $backend_result,
|
||||
request => $request
|
||||
);
|
||||
handle_commit_maybe($backend_result, $request);
|
||||
}
|
||||
|
|
@ -205,6 +224,9 @@ if ( $backends_available ) {
|
|||
# We simulate the API for backend requests for uniformity.
|
||||
# So, init:
|
||||
my $request = Koha::Illrequests->find($params->{illrequest_id});
|
||||
my $batches = Koha::Illbatches->search(undef, {
|
||||
order_by => { -asc => 'name' }
|
||||
});
|
||||
if ( !$params->{stage} ) {
|
||||
my $backend_result = {
|
||||
error => 0,
|
||||
|
|
@ -217,13 +239,15 @@ if ( $backends_available ) {
|
|||
};
|
||||
$template->param(
|
||||
whole => $backend_result,
|
||||
request => $request
|
||||
request => $request,
|
||||
batches => $batches
|
||||
);
|
||||
} else {
|
||||
# Commit:
|
||||
# Save the changes
|
||||
$request->borrowernumber($params->{borrowernumber});
|
||||
$request->biblio_id($params->{biblio_id});
|
||||
$request->batch_id($params->{batch_id});
|
||||
$request->branchcode($params->{branchcode});
|
||||
$request->price_paid($params->{price_paid});
|
||||
$request->notesopac($params->{notesopac});
|
||||
|
|
@ -356,7 +380,7 @@ if ( $backends_available ) {
|
|||
} elsif ( $op eq 'illlist') {
|
||||
|
||||
# If we receive a pre-filter, make it available to the template
|
||||
my $possible_filters = ['borrowernumber'];
|
||||
my $possible_filters = ['borrowernumber', 'batch_id'];
|
||||
my $active_filters = {};
|
||||
foreach my $filter(@{$possible_filters}) {
|
||||
if ($params->{$filter}) {
|
||||
|
|
@ -375,6 +399,17 @@ if ( $backends_available ) {
|
|||
$template->param(
|
||||
prefilters => join("&", @tpl_arr)
|
||||
);
|
||||
|
||||
if ($active_filters->{batch_id}) {
|
||||
my $batch_id = $active_filters->{batch_id};
|
||||
if ($batch_id) {
|
||||
my $batch = Koha::Illbatches->find($batch_id);
|
||||
$template->param(
|
||||
batch => $batch
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
} elsif ( $op eq "save_comment" ) {
|
||||
die "Wrong CSRF token" unless Koha::Token->new->check_csrf({
|
||||
session_id => scalar $cgi->cookie('CGISESSID'),
|
||||
|
|
@ -409,6 +444,10 @@ if ( $backends_available ) {
|
|||
scalar $params->{illrequest_id} . $append
|
||||
);
|
||||
exit;
|
||||
} elsif ( $op eq "batch_list" ) {
|
||||
# Do not remove, it prevents us falling through to the 'else'
|
||||
} elsif ( $op eq "batch_create" ) {
|
||||
# Do not remove, it prevents us falling through to the 'else'
|
||||
} else {
|
||||
my $request = Koha::Illrequests->find($params->{illrequest_id});
|
||||
my $backend_result = $request->custom_capability($op, $params);
|
||||
|
|
@ -466,3 +505,59 @@ sub redirect_to_list {
|
|||
print $cgi->redirect('/cgi-bin/koha/ill/ill-requests.pl');
|
||||
exit;
|
||||
}
|
||||
|
||||
# Do any of the available backends provide batch requesting
|
||||
sub have_batch_backends {
|
||||
my ( $backends ) = @_;
|
||||
|
||||
my @have_batch = ();
|
||||
|
||||
foreach my $backend(@{$backends}) {
|
||||
my $can_batch = can_batch($backend);
|
||||
if ($can_batch) {
|
||||
push @have_batch, $backend;
|
||||
}
|
||||
}
|
||||
return \@have_batch;
|
||||
}
|
||||
|
||||
# Does a given backend provide batch requests
|
||||
# FIXME: This should be moved to Koha::Illbackend
|
||||
sub can_batch {
|
||||
my ( $backend ) = @_;
|
||||
my $request = Koha::Illrequest->new->load_backend( $backend );
|
||||
return $request->_backend_capability( 'provides_batch_requests' );
|
||||
}
|
||||
|
||||
# Get available metadata enrichment plugins
|
||||
sub get_metadata_enrichment {
|
||||
my @candidates = Koha::Plugins->new()->GetPlugins({
|
||||
method => 'provides_api'
|
||||
});
|
||||
my @services = ();
|
||||
foreach my $plugin(@candidates) {
|
||||
my $supported = $plugin->provides_api();
|
||||
if ($supported->{type} eq 'search') {
|
||||
push @services, $supported;
|
||||
}
|
||||
}
|
||||
return \@services;
|
||||
}
|
||||
|
||||
# Get ILL availability plugins that can help us with the batch identifier types
|
||||
# we support
|
||||
sub get_ill_availability {
|
||||
my ( $services ) = @_;
|
||||
|
||||
my $id_types = {};
|
||||
foreach my $service(@{$services}) {
|
||||
foreach my $id_supported(keys %{$service->{identifiers_supported}}) {
|
||||
$id_types->{$id_supported} = 1;
|
||||
}
|
||||
}
|
||||
|
||||
my $availability = Koha::Illrequest::Workflow::Availability->new($id_types);
|
||||
return $availability->get_services({
|
||||
ui_context => 'staff'
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3706,6 +3706,112 @@ input.renew {
|
|||
}
|
||||
|
||||
#interlibraryloans {
|
||||
|
||||
.ill-toolbar {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#ill-batch {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
#ill-batch-requests {
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
#ill-batch-modal {
|
||||
.modal-footer {
|
||||
display: flex;
|
||||
& > * {
|
||||
flex: 1;
|
||||
}
|
||||
#lhs {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
#create-progress {
|
||||
margin-top: 17px;
|
||||
}
|
||||
.fetch-failed {
|
||||
background-color: rgba(255,0,0,0.1);
|
||||
& > * {
|
||||
background-color: inherit;
|
||||
}
|
||||
}
|
||||
.progress {
|
||||
margin-bottom: 0;
|
||||
margin-top: 17px;
|
||||
}
|
||||
#create-requests {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.action-column {
|
||||
text-align: center;
|
||||
& > * {
|
||||
margin-left: 5px;
|
||||
}
|
||||
& > *:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
.metadata-row:not(:first-child) {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
.metadata-label {
|
||||
font-weight: 600;
|
||||
}
|
||||
.more-less {
|
||||
text-align: right;
|
||||
margin: 2px 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#batch-form {
|
||||
legend {
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
textarea {
|
||||
width: 100%;
|
||||
min-height: 100px;
|
||||
padding: 5px;
|
||||
resize: vertical;
|
||||
}
|
||||
#new-batch-form {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
}
|
||||
li#process-button {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
#textarea-metadata {
|
||||
padding: 0 15px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
#textarea-errors {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
padding: 20px 15px 10px
|
||||
}
|
||||
.batch-modal-actions {
|
||||
text-align: center;
|
||||
}
|
||||
fieldset {
|
||||
border: 2px solid #b9d8d9;
|
||||
}
|
||||
}
|
||||
|
||||
#dataPreviewLabel {
|
||||
margin: .3em 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
<!-- ill-batch-table-strings.inc -->
|
||||
<script>
|
||||
var ill_batch_add = _("Add new batch");
|
||||
var ill_batch_update = _("Update batch");
|
||||
var ill_batch_none = _("None");
|
||||
var ill_batch_retrieving_metadata = _("Retrieving metadata");
|
||||
var ill_batch_api_fail = _("Unable to retrieve batch details");
|
||||
var ill_batch_statuses_api_fail = _("Unable to retrieve batch statuses");
|
||||
var ill_batch_api_request_fail = _("Unable to create local request");
|
||||
var ill_batch_requests_api_fail = _("Unable to retrieve batch requests");
|
||||
var ill_batch_unknown = _("Unknown");
|
||||
var ill_batch_doi = _("DOI");
|
||||
var ill_batch_pmid = _("PubMed ID");
|
||||
var ill_populate_waiting = _("Retrieving...");
|
||||
var ill_populate_failed = _("Failed to retrieve");
|
||||
var ill_button_remove = _("Remove");
|
||||
var ill_batch_create_api_fail = _("Unable to create batch request");
|
||||
var ill_batch_update_api_fail = _("Unable to updatecreate batch request");
|
||||
var ill_batch_item_remove = _("Are you sure you want to remove this item from the batch");
|
||||
var ill_batch_create_cancel_button = _("Close");
|
||||
var ill_batch_metadata_more = _("More");
|
||||
var ill_batch_metadata_less = _("Less");
|
||||
var ill_batch_available_via = _("Available via");
|
||||
var ill_batch_metadata = {
|
||||
'doi': _("DOI"),
|
||||
'pmid': _("PubMed ID"),
|
||||
'issn': _("ISSN"),
|
||||
'title': _("Title"),
|
||||
'year': _("Year"),
|
||||
'issue': _("Issue"),
|
||||
'pages': _("Pages"),
|
||||
'publisher': _("Publisher"),
|
||||
'article_title': _("Article title"),
|
||||
'article_author': _("Article author"),
|
||||
'volume': _("Volume")
|
||||
};
|
||||
</script>
|
||||
<!-- / ill-batch-table-strings.inc -->
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
<div id="ill-batch-details" style="display:none"></div>
|
||||
<div id="ill-batch-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="ill-batch-modal-label" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 id="ill-batch-modal-label"></h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div id="batch-form">
|
||||
<form id="new-batch-form">
|
||||
<fieldset class="rows">
|
||||
<legend id="legend">Batch details</legend>
|
||||
<ol>
|
||||
<li id="batch_name">
|
||||
<label class="required" for="name">Batch name:</label>
|
||||
<input type="text" autocomplete="off" name="name" id="name" type="text"
|
||||
value="" />
|
||||
</li>
|
||||
<li id="batch_patron">
|
||||
<label class="required" for="batchcardnumber">Card number, username or surname:</label>
|
||||
<input type="text" autocomplete="off" name="batchcardnumber" id="batchcardnumber" type="text" value="" />
|
||||
<span id="patron_link"></span>
|
||||
</li>
|
||||
<li id="batch_branch">
|
||||
<label class="required" for="branchcode">Library:</label>
|
||||
<select id="branchcode" name="branchcode">
|
||||
[% PROCESS options_for_libraries libraries => Branches.all( selected => branchcode ) %]
|
||||
</select>
|
||||
</li>
|
||||
<li id="batch_statuscode" style="display:none">
|
||||
<label class="required" for="statuscode">Status:</label>
|
||||
<select id="statuscode" name="statuscode"></select>
|
||||
</li>
|
||||
</ol>
|
||||
</fieldset>
|
||||
<fieldset id="add_batch_items" class="rows" style="display:none">
|
||||
<legend id="legend">Add batch items</legend>
|
||||
<div id="textarea-metadata">
|
||||
<div id="supported">Supported identifiers: <span id="supported_identifiers"></span></div>
|
||||
<div id="row_count">Row count: <span id="row_count_value"></span></div>
|
||||
</div>
|
||||
<div id="textarea-errors" style="display:none" class="error">
|
||||
<div id="duplicates" style="display:none">The following duplicates were found, these have been de-duplicated: <span id="dupelist"></span></div>
|
||||
<div id="badidentifiers" style="display:none">The following unknown identifiers were found, it was not possible to establish their type: <span id="badids"></span></div>
|
||||
</div>
|
||||
<ol>
|
||||
<li>
|
||||
<textarea id="identifiers_input" placeholder="Enter identifiers, one per line"></textarea>
|
||||
</li>
|
||||
<li id="process-button">
|
||||
<button id="process_button" disabled aria-disabled="true" type="button">Process identifiers</button>
|
||||
</li>
|
||||
</ol>
|
||||
</fieldset>
|
||||
</form>
|
||||
<div id="create-progress" class="alert alert-info" role="alert" style="display:none">
|
||||
<span id="progress-label"><strong></strong></span> -
|
||||
Items processed: <span id="processed_count">0</span> out of <span id="processed_total">0</span>.
|
||||
Items failed: <span id="processed_failed">0</span>.
|
||||
<div class="progress">
|
||||
<div id="processed_progress_bar" class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="min-width: 2em;">
|
||||
0%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<table id="identifier-table" style="display:none">
|
||||
<thead>
|
||||
<tr id="identifier-table-header">
|
||||
<th scope="col">Identifier type</th>
|
||||
<th scope="col">Identifier value</th>
|
||||
<th scope="col">Metadata</th>
|
||||
<th scope="col">Request ID</th>
|
||||
<th scope="col">Request Status</th>
|
||||
<th scope="col"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="identifier-table-body">
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div id="create-requests" style="display:none">
|
||||
<button id="create-requests-button" type="button" class="btn btn-primary" aria-label="Add items to batch">Add items to batch</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<div id="lhs">
|
||||
<button class="btn btn-default" data-dismiss="modal" aria-hidden="false">Cancel</button>
|
||||
</div>
|
||||
<div id="rhs">
|
||||
<button id="button_create_batch" class="btn btn-default" aria-hidden="true" disabled>Continue</button>
|
||||
<button id="button_finish" disabled type="button" class="btn btn-default" aria-hidden="true">Finish and view batch</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<!-- ill-batch-table-strings.inc -->
|
||||
<script>
|
||||
var ill_batch_borrower_details = _("View borrower details");
|
||||
var ill_batch_edit = _("Edit");
|
||||
var ill_batch_delete = _("Delete");
|
||||
var ill_batch_confirm_delete = _("Are you sure you want to delete this batch? All attached requests will be detached.");
|
||||
var ill_batch_delete_fail = _("Unable to delete batch");
|
||||
</script>
|
||||
<!-- / ill-batch-table-strings.inc -->
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
[% IF query_type == "batch_list" %]
|
||||
<div>
|
||||
<table id="ill-batch-requests">
|
||||
<thead>
|
||||
<tr id="ill-batch-header">
|
||||
<th scope="col">Batch ID</th>
|
||||
<th scope="col">Name</th>
|
||||
<th scope="col">Number of requests</th>
|
||||
<th scope="col">Status</th>
|
||||
<th scope="col">Patron</th>
|
||||
<th scope="col">Branch</th>
|
||||
<th scope="col"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="ill-batch-body">
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
[% END %]
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
<!-- ill-list-table-strings.inc -->
|
||||
<script>
|
||||
var ill_borrower_details = _("View patron details");
|
||||
var ill_manage = _("Manage request");
|
||||
var ill_manage_select_backend_first = _("Select a backend first");
|
||||
var ill_all_statuses = _("All statuses");
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
[% IF patron.borrowernumber %]
|
||||
<table id="ill-requests-patron-[% patron.borrowernumber | html %]">
|
||||
[% ELSIF batch.id %]
|
||||
<table id="ill-requests-batch-[% batch.id | html %]">
|
||||
[% ELSE %]
|
||||
<table id="ill-requests">
|
||||
[% END %]
|
||||
<thead>
|
||||
<tr id="ill_requests_header">
|
||||
<th scope="col">Request ID</th>
|
||||
<th scope="col">Batch</th>
|
||||
<th scope="col" data-datatype="related-object" data-related="extended_attributes" data-related-key="type" data-related-value="author" data-related-search-on="value">Author</th>
|
||||
<th scope="col" data-datatype="related-object" data-related="extended_attributes" data-related-key="type" data-related-value="title" data-related-search-on="value">Title</th>
|
||||
<th scope="col" data-datatype="related-object" data-related="extended_attributes" data-related-key="type" data-related-value="article_title" data-related-search-on="value">Article title</th>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
[% INCLUDE 'blocking_errors.inc' %]
|
||||
[% USE Koha %]
|
||||
[% IF Koha.Preference('ILLModule ') && CAN_user_ill %]
|
||||
<div id="toolbar" class="btn-toolbar">
|
||||
[% IF Koha.Preference('ILLModule') && CAN_user_ill %]
|
||||
<div id="toolbar" class="btn-toolbar ill-toolbar">
|
||||
[% IF backends_available %]
|
||||
[% IF backends.size > 1 %]
|
||||
<div class="dropdown btn-group">
|
||||
|
|
@ -33,5 +33,22 @@
|
|||
<i class="fa fa-list"></i> List requests
|
||||
</a>
|
||||
[% END %]
|
||||
[% IF have_batch.size > 0 && metadata_enrichment_services %]
|
||||
<div id="ill-batch">
|
||||
<div class="dropdown btn-group">
|
||||
<button class="btn btn-default dropdown-toggle" type="button" id="ill-batch-backend-dropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||
<i class="fa fa-plus"></i> New ILL batch request <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="ill-batch-backend-dropdown">
|
||||
[% FOREACH backend IN have_batch %]
|
||||
<li><a href="#" role="button" onclick="window.openBatchModal(null, '[% backend | html %]')">[% backend | html %]</a></li>
|
||||
[% END %]
|
||||
</ul>
|
||||
</div>
|
||||
<a class="btn btn-default" type="button" href="/cgi-bin/koha/ill/ill-requests.pl?method=batch_list" %]">
|
||||
<i class="fa fa-tasks"></i> Batch requests</span>
|
||||
</a>
|
||||
</div>
|
||||
[% END %]
|
||||
</div>
|
||||
[% END %]
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@
|
|||
<div class="dialog message">ILL module configuration problem. Take a look at the <a href="/cgi-bin/koha/about.pl#sysinfo_panel">about page</a></div>
|
||||
[% ELSE %]
|
||||
[% INCLUDE 'ill-toolbar.inc' %]
|
||||
[% INCLUDE 'ill-batch-modal.inc' %]
|
||||
|
||||
[% IF whole.error %]
|
||||
<h1>Error performing operation</h1>
|
||||
|
|
@ -437,6 +438,23 @@
|
|||
[% END %]
|
||||
</select>
|
||||
</li>
|
||||
[% IF batches.count > 0 %]
|
||||
<li class="batch">
|
||||
<label class="batch_label">Batch:</label>
|
||||
<select id="batch_id" name="batch_id">
|
||||
<option value="">
|
||||
[% FOREACH batch IN batches %]
|
||||
[% IF batch.id == request.batch_id %]
|
||||
<option value="[% batch.id | html %]" selected>
|
||||
[% ELSE %]
|
||||
<option value="[% batch.id | html %]">
|
||||
[% END %]
|
||||
[% batch.name | html %]
|
||||
</option>
|
||||
[% END %]
|
||||
</select>
|
||||
</li>
|
||||
[% END %]
|
||||
<li class="updated">
|
||||
<label class="updated">Last updated:</label>
|
||||
[% request.updated | $KohaDates with_hours => 1 %]
|
||||
|
|
@ -648,6 +666,14 @@
|
|||
[% END %]
|
||||
[% END %]
|
||||
</li>
|
||||
[% IF request.batch > 0 %]
|
||||
<li class="batch">
|
||||
<span class="label batch">Batch:</span>
|
||||
<a href="/cgi-bin/koha/ill/ill-requests.pl?batch_id=[% request.batch.id | html %]">
|
||||
[% request.batch.name | html %]
|
||||
</a>
|
||||
</li>
|
||||
[% END %]
|
||||
<li class="updated">
|
||||
<span class="label updated">Last updated:</span>
|
||||
[% request.updated | $KohaDates with_hours => 1 %]
|
||||
|
|
@ -779,7 +805,12 @@
|
|||
|
||||
[% ELSIF query_type == 'illlist' %]
|
||||
<!-- illlist -->
|
||||
<h1>View ILL requests</h1>
|
||||
<h1>
|
||||
View ILL requests
|
||||
[% IF batch %]
|
||||
for batch "[% batch.name | html %]"
|
||||
[% END %]
|
||||
</h1>
|
||||
<div id="results" class="page-section">
|
||||
<h2>Details for all requests</h2>
|
||||
[% INCLUDE 'ill-list-table.inc' %]
|
||||
|
|
@ -858,6 +889,8 @@
|
|||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
[% ELSIF query_type == 'batch_list' || query_type == 'batch_create' %]
|
||||
[% INCLUDE 'ill-batch.inc' %]
|
||||
[% ELSE %]
|
||||
<!-- Custom Backend Action -->
|
||||
[% PROCESS $whole.template %]
|
||||
|
|
@ -877,6 +910,18 @@
|
|||
[% INCLUDE 'columns_settings.inc' %]
|
||||
[% INCLUDE 'calendar.inc' %]
|
||||
[% INCLUDE 'select2.inc' %]
|
||||
[% IF metadata_enrichment_services %]
|
||||
<script>
|
||||
var metadata_enrichment_services = [% metadata_enrichment_services | $raw %];
|
||||
</script>
|
||||
<script>
|
||||
[% IF batch_availability_services %]
|
||||
var batch_availability_services = [% batch_availability_services | $raw %];
|
||||
[% ELSE %]
|
||||
var batch_availability_services = [];
|
||||
[% END %]
|
||||
</script>
|
||||
[% END %]
|
||||
<script>
|
||||
var prefilters = '[% prefilters | $raw %]';
|
||||
// Set column settings
|
||||
|
|
@ -901,7 +946,12 @@
|
|||
});
|
||||
</script>
|
||||
[% INCLUDE 'ill-list-table-strings.inc' %]
|
||||
[% INCLUDE 'ill-batch-table-strings.inc' %]
|
||||
[% INCLUDE 'ill-batch-modal-strings.inc' %]
|
||||
[% Asset.js("js/ill-list-table.js") | $raw %]
|
||||
[% Asset.js("js/ill-batch.js") | $raw %]
|
||||
[% Asset.js("js/ill-batch-table.js") | $raw %]
|
||||
[% Asset.js("js/ill-batch-modal.js") | $raw %]
|
||||
[% IF (query_type == 'availability' || query_type == 'generic_confirm') && Koha.Preference('ILLCheckAvailability') %]
|
||||
[% Asset.js("js/ill-availability.js") | $raw %]
|
||||
[% END %]
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,216 @@
|
|||
(function () {
|
||||
var table;
|
||||
var batchesProxy;
|
||||
|
||||
window.addEventListener('load', onload);
|
||||
|
||||
function onload() {
|
||||
// Only proceed if appropriate
|
||||
if (!document.getElementById('ill-batch-requests')) return;
|
||||
|
||||
// A proxy that will give us some element of reactivity to
|
||||
// changes in our list of batches
|
||||
batchesProxy = new Proxy(
|
||||
{ data: [] },
|
||||
{
|
||||
get: function (obj, prop) {
|
||||
return obj[prop];
|
||||
},
|
||||
set: function (obj, prop, value) {
|
||||
obj[prop] = value;
|
||||
updateTable();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Initialise the Datatable, binding it to our proxy object
|
||||
table = initTable();
|
||||
|
||||
// Do the initial data population
|
||||
window.doBatchApiRequest()
|
||||
.then(function (response) {
|
||||
return response.json();
|
||||
})
|
||||
.then(function (data) {
|
||||
batchesProxy.data = data;
|
||||
});
|
||||
|
||||
// Clean up any event listeners we added
|
||||
window.addEventListener('beforeunload', removeEventListeners);
|
||||
};
|
||||
|
||||
// Initialise the Datatable
|
||||
// FIXME: This should be a kohaTable not KohaTable
|
||||
var initTable = function () {
|
||||
return KohaTable("ill-batch-requests", {
|
||||
data: batchesProxy.data,
|
||||
columns: [
|
||||
{
|
||||
data: 'id',
|
||||
width: '10%'
|
||||
},
|
||||
{
|
||||
data: 'name',
|
||||
render: createName,
|
||||
width: '30%'
|
||||
},
|
||||
{
|
||||
data: 'requests_count',
|
||||
width: '10%'
|
||||
},
|
||||
{
|
||||
data: 'status',
|
||||
render: createStatus,
|
||||
width: '10%'
|
||||
},
|
||||
{
|
||||
data: 'patron',
|
||||
render: createPatronLink,
|
||||
width: '10%'
|
||||
},
|
||||
{
|
||||
data: 'branch',
|
||||
render: createBranch,
|
||||
width: '20%'
|
||||
},
|
||||
{
|
||||
render: createActions,
|
||||
width: '10%',
|
||||
orderable: false
|
||||
}
|
||||
],
|
||||
processing: true,
|
||||
deferRender: true,
|
||||
drawCallback: addEventListeners
|
||||
});
|
||||
}
|
||||
|
||||
// A render function for branch name
|
||||
var createBranch = function (data) {
|
||||
return data.branchname;
|
||||
};
|
||||
|
||||
// A render function for batch name
|
||||
var createName = function (x, y, data) {
|
||||
var a = document.createElement('a');
|
||||
a.setAttribute('href', '/cgi-bin/koha/ill/ill-requests.pl?batch_id=' + data.id);
|
||||
a.setAttribute('title', data.name);
|
||||
a.textContent = data.name;
|
||||
return a.outerHTML;
|
||||
};
|
||||
|
||||
// A render function for batch status
|
||||
var createStatus = function (x, y, data) {
|
||||
return data.status.name;
|
||||
};
|
||||
|
||||
// A render function for our patron link
|
||||
var createPatronLink = function (data) {
|
||||
var link = document.createElement('a');
|
||||
link.setAttribute('title', ill_batch_borrower_details);
|
||||
link.setAttribute('href', '/cgi-bin/koha/members/moremember.pl?borrowernumber=' + data.borrowernumber);
|
||||
var displayText = [data.firstname, data.surname].join(' ') + ' ( ' + data.cardnumber + ' )';
|
||||
link.appendChild(document.createTextNode(displayText));
|
||||
|
||||
return link.outerHTML;
|
||||
};
|
||||
|
||||
// A render function for our row action buttons
|
||||
var createActions = function (data, type, row) {
|
||||
var div = document.createElement('div');
|
||||
div.setAttribute('class', 'action-buttons');
|
||||
|
||||
var editButton = document.createElement('button');
|
||||
editButton.setAttribute('type', 'button');
|
||||
editButton.setAttribute('class', 'editButton btn btn-xs btn-default');
|
||||
editButton.setAttribute('data-batch-id', row.id);
|
||||
editButton.appendChild(document.createTextNode(ill_batch_edit));
|
||||
|
||||
var deleteButton = document.createElement('button');
|
||||
deleteButton.setAttribute('type', 'button');
|
||||
deleteButton.setAttribute('class', 'deleteButton btn btn-xs btn-danger');
|
||||
deleteButton.setAttribute('data-batch-id', row.id);
|
||||
deleteButton.appendChild(document.createTextNode(ill_batch_delete));
|
||||
|
||||
div.appendChild(editButton);
|
||||
div.appendChild(deleteButton);
|
||||
|
||||
return div.outerHTML;
|
||||
};
|
||||
|
||||
// Add event listeners to our row action buttons
|
||||
var addEventListeners = function () {
|
||||
var del = document.querySelectorAll('.deleteButton');
|
||||
del.forEach(function (el) {
|
||||
el.addEventListener('click', handleDeleteClick);
|
||||
});
|
||||
|
||||
var edit = document.querySelectorAll('.editButton');
|
||||
edit.forEach(function (elEdit) {
|
||||
elEdit.addEventListener('click', handleEditClick);
|
||||
});
|
||||
};
|
||||
|
||||
// Remove all added event listeners
|
||||
var removeEventListeners = function () {
|
||||
var del = document.querySelectorAll('.deleteButton');
|
||||
del.forEach(function (el) {
|
||||
el.removeEventListener('click', handleDeleteClick);
|
||||
});
|
||||
window.removeEventListener('load', onload);
|
||||
window.removeEventListener('beforeunload', removeEventListeners);
|
||||
};
|
||||
|
||||
// Handle "Delete" clicks
|
||||
var handleDeleteClick = function(e) {
|
||||
var el = e.srcElement;
|
||||
if (confirm(ill_batch_confirm_delete)) {
|
||||
deleteBatch(el);
|
||||
}
|
||||
};
|
||||
|
||||
// Handle "Edit" clicks
|
||||
var handleEditClick = function(e) {
|
||||
var el = e.srcElement;
|
||||
var id = el.dataset.batchId;
|
||||
window.openBatchModal(id);
|
||||
};
|
||||
|
||||
// Delete a batch
|
||||
// - Make the API call
|
||||
// - Handle errors
|
||||
// - Update our proxy data
|
||||
var deleteBatch = function (el) {
|
||||
var id = el.dataset.batchId;
|
||||
doBatchApiRequest(
|
||||
'/' + id,
|
||||
{ method: 'DELETE' }
|
||||
)
|
||||
.then(function (response) {
|
||||
if (!response.ok) {
|
||||
window.handleApiError(ill_batch_delete_fail);
|
||||
} else {
|
||||
removeBatch(el.dataset.batchId);
|
||||
}
|
||||
})
|
||||
.catch(function (response) {
|
||||
window.handleApiError(ill_batch_delete_fail);
|
||||
})
|
||||
};
|
||||
|
||||
// Remove a batch from our proxy data
|
||||
var removeBatch = function(id) {
|
||||
batchesProxy.data = batchesProxy.data.filter(function (batch) {
|
||||
return batch.id != id;
|
||||
});
|
||||
};
|
||||
|
||||
// Redraw the table
|
||||
var updateTable = function () {
|
||||
table.api()
|
||||
.clear()
|
||||
.rows.add(batchesProxy.data)
|
||||
.draw();
|
||||
};
|
||||
|
||||
})();
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
(function () {
|
||||
// Enable the modal to be opened from anywhere
|
||||
// If we're working with an existing batch, set the ID so the
|
||||
// modal can access it
|
||||
window.openBatchModal = function (id, backend) {
|
||||
var idEl = document.getElementById('ill-batch-details');
|
||||
idEl.dataset.backend = backend;
|
||||
if (id) {
|
||||
idEl.dataset.batchId = id;
|
||||
}
|
||||
$('#ill-batch-modal').modal({ show: true });
|
||||
};
|
||||
|
||||
// Make a batch API call, returning the resulting promise
|
||||
window.doBatchApiRequest = function (url, options) {
|
||||
var batchListApi = '/api/v1/illbatches';
|
||||
var fullUrl = batchListApi + (url ? url : '');
|
||||
return doApiRequest(fullUrl, options);
|
||||
};
|
||||
|
||||
// Make a "create local ILL submission" call
|
||||
window.doCreateSubmission = function (body, options) {
|
||||
options = Object.assign(
|
||||
options || {},
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
method: 'POST',
|
||||
body: JSON.stringify(body)
|
||||
}
|
||||
);
|
||||
return doApiRequest(
|
||||
'/api/v1/ill/requests',
|
||||
options
|
||||
)
|
||||
}
|
||||
|
||||
// Make an API call, returning the resulting promise
|
||||
window.doApiRequest = function (url, options) {
|
||||
return fetch(url, options);
|
||||
};
|
||||
|
||||
// Display an API error
|
||||
window.handleApiError = function (error) {
|
||||
alert(error);
|
||||
};
|
||||
|
||||
})();
|
||||
|
|
@ -51,7 +51,7 @@ $(document).ready(function() {
|
|||
return '';
|
||||
}
|
||||
|
||||
// At the moment, the only prefilter possible is borrowernumber
|
||||
// Possible prefilters: borrowernumber, batch_id
|
||||
// see ill/ill-requests.pl and members/ill-requests.pl
|
||||
let additional_prefilters = {};
|
||||
if(prefilters){
|
||||
|
|
@ -63,6 +63,7 @@ $(document).ready(function() {
|
|||
}
|
||||
|
||||
let borrower_prefilter = additional_prefilters['borrowernumber'] || null;
|
||||
let batch_id_prefilter = additional_prefilters['batch_id'] || null;
|
||||
|
||||
let additional_filters = {
|
||||
"me.backend": function(){
|
||||
|
|
@ -78,6 +79,9 @@ $(document).ready(function() {
|
|||
"me.borrowernumber": function(){
|
||||
return borrower_prefilter ? { "=": borrower_prefilter } : "";
|
||||
},
|
||||
"me.batch_id": function(){
|
||||
return batch_id_prefilter ? { "=": batch_id_prefilter } : "";
|
||||
},
|
||||
"-or": function(){
|
||||
let patron = $("#illfilter_patron").val();
|
||||
let status = $("#illfilter_status").val();
|
||||
|
|
@ -119,7 +123,7 @@ $(document).ready(function() {
|
|||
return filters;
|
||||
},
|
||||
"me.placed": function(){
|
||||
if ( Object.keys(additional_prefilters).length ) return "";
|
||||
if (Object.keys(additional_prefilters).length && borrower_prefilter) return "";
|
||||
let placed_start = $('#illfilter_dateplaced_start').get(0)._flatpickr.selectedDates[0];
|
||||
let placed_end = $('#illfilter_dateplaced_end').get(0)._flatpickr.selectedDates[0];
|
||||
if (!placed_start && !placed_end) return "";
|
||||
|
|
@ -129,7 +133,7 @@ $(document).ready(function() {
|
|||
}
|
||||
},
|
||||
"me.updated": function(){
|
||||
if (Object.keys(additional_prefilters).length) return "";
|
||||
if (Object.keys(additional_prefilters).length && borrower_prefilter) return "";
|
||||
let updated_start = $('#illfilter_datemodified_start').get(0)._flatpickr.selectedDates[0];
|
||||
let updated_end = $('#illfilter_datemodified_end').get(0)._flatpickr.selectedDates[0];
|
||||
if (!updated_start && !updated_end) return "";
|
||||
|
|
@ -175,8 +179,11 @@ $(document).ready(function() {
|
|||
};
|
||||
|
||||
let table_id = "#ill-requests";
|
||||
|
||||
if (borrower_prefilter) {
|
||||
table_id += "-patron-" + borrower_prefilter;
|
||||
} else if ( batch_id_prefilter ){
|
||||
table_id += "-batch-" + batch_id_prefilter;
|
||||
}
|
||||
|
||||
var ill_requests_table = $(table_id).kohaTable({
|
||||
|
|
@ -188,6 +195,7 @@ $(document).ready(function() {
|
|||
'biblio',
|
||||
'comments+count',
|
||||
'extended_attributes',
|
||||
'batch',
|
||||
'library',
|
||||
'id_prefix',
|
||||
'patron'
|
||||
|
|
@ -206,6 +214,19 @@ $(document).ready(function() {
|
|||
'">' + escape_str(row.id_prefix) + escape_str(data) + '</a>';
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "batch.name", // batch
|
||||
"orderable": false,
|
||||
"render": function(data, type, row, meta) {
|
||||
return row.batch ?
|
||||
'<a href="/cgi-bin/koha/ill/ill-requests.pl?batch_id=' +
|
||||
row.batch_id +
|
||||
'">' +
|
||||
row.batch.name +
|
||||
'</a>'
|
||||
: "";
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "", // author
|
||||
"orderable": false,
|
||||
|
|
|
|||
Loading…
Reference in New Issue