Bug 37762: ISO18626 KOHA classes
Signed-off-by: Jason Robb <jrobb@sekls.org> Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com> Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This commit is contained in:
parent
2f17713637
commit
8e87fae1cc
|
|
@ -0,0 +1,291 @@
|
|||
package Koha::ILL::ISO18626;
|
||||
|
||||
# Copyright PTFS Europe 2025
|
||||
#
|
||||
# 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 <https://www.gnu.org/licenses>.
|
||||
|
||||
use Modern::Perl;
|
||||
|
||||
use JSON qw( encode_json decode_json );
|
||||
use File::Basename qw( dirname );
|
||||
|
||||
use Koha::ILL::ISO18626::RequestingAgencies;
|
||||
use Koha::DateUtils qw( dt_from_string );
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Koha::ILL::ISO18626 - Koha ILL ISO18626 class
|
||||
|
||||
=cut
|
||||
|
||||
=head2 Class methods
|
||||
|
||||
=head3 is_invalid
|
||||
|
||||
=cut
|
||||
|
||||
sub is_invalid {
|
||||
my ( $definition, $json ) = @_;
|
||||
|
||||
my $spec_file = dirname(__FILE__) . "/../../api/v1/swagger/swagger_bundle.json";
|
||||
if ( !-f $spec_file ) {
|
||||
$spec_file = dirname(__FILE__) . "/../../api/v1/swagger/swagger.yaml";
|
||||
}
|
||||
|
||||
my $schema = JSON::Validator::Schema::OpenAPIv2->new($spec_file);
|
||||
|
||||
$schema->resolve( $schema->data->{definitions}->{$definition} );
|
||||
my @errors = $schema->validate($json);
|
||||
|
||||
my @formatted_errors;
|
||||
for my $error (@errors) {
|
||||
my @details = @{ $error->{details} };
|
||||
my $mapped_details = join( ', ', map { "$_" } @details );
|
||||
|
||||
push @formatted_errors,
|
||||
{ errorValue => $error->{path} . ': ' . $mapped_details, errorType => 'BadlyFormedMessage' };
|
||||
}
|
||||
|
||||
return \@formatted_errors if @formatted_errors;
|
||||
return 0;
|
||||
}
|
||||
|
||||
=head2 is_auth_ok
|
||||
|
||||
my $is_auth_ok = is_auth_ok($json);
|
||||
|
||||
Checks the validity of the requestingAgencyAuthentication against the database.
|
||||
Returns the Koha::ILL::ISO18626::RequestingAgency object if a matching accountId and securityCode are found, 0 otherwise.
|
||||
|
||||
=cut
|
||||
|
||||
sub is_auth_ok {
|
||||
my ( $messageType, $json ) = @_;
|
||||
|
||||
my $accountId = $json->{$messageType}->{header}->{requestingAgencyAuthentication}->{accountId};
|
||||
my $securityCode = $json->{$messageType}->{header}->{requestingAgencyAuthentication}->{securityCode};
|
||||
|
||||
my $requesting_agency =
|
||||
Koha::ILL::ISO18626::RequestingAgencies->find( { account_id => $accountId, securityCode => $securityCode } );
|
||||
|
||||
return $requesting_agency if $requesting_agency;
|
||||
return 0;
|
||||
}
|
||||
|
||||
=head3 confirmation_response
|
||||
|
||||
This function returns an openapi ISO18626 message confirmation response based on the ISO18626 messages's type and body.
|
||||
e.g. If the message_type is request, it returns a requestConfirmation message
|
||||
|
||||
It does not verify if:
|
||||
- The message type is valid.
|
||||
- The message is valid.
|
||||
These things should be done beforehand
|
||||
|
||||
=cut
|
||||
|
||||
sub confirmation_response {
|
||||
my ( $message_type, $body, $requesting_agency ) = @_;
|
||||
|
||||
my $json = JSON::decode_json($body);
|
||||
my $confirmation_message_type = $message_type . 'Confirmation';
|
||||
my ( $iso18626_request, $response, $action );
|
||||
|
||||
if ( $message_type eq 'request' ) {
|
||||
#
|
||||
# Handle incoming request message
|
||||
#
|
||||
my $request = {
|
||||
supplyingAgencyId => $json->{request}->{header}->{supplyingAgencyId},
|
||||
iso18626_requesting_agency_id => $requesting_agency->iso18626_requesting_agency_id,
|
||||
requestingAgencyRequestId => $json->{request}->{header}->{requestingAgencyRequestId},
|
||||
service_type => $json->{request}->{serviceInfo}->{serviceType},
|
||||
_json_payload => $json
|
||||
};
|
||||
|
||||
$iso18626_request = Koha::ILL::ISO18626::Request->new($request)->store();
|
||||
$iso18626_request->add_message( { type => $message_type, message => $body } );
|
||||
|
||||
#
|
||||
# Prepare outgoing requestConfirmation response
|
||||
#
|
||||
$response = {
|
||||
$confirmation_message_type => {
|
||||
confirmationHeader => {
|
||||
timestamp => _now_utc_str(),
|
||||
timestampReceived => _now_utc_str(),
|
||||
messageStatus => 'OK',
|
||||
}
|
||||
}
|
||||
};
|
||||
} elsif ( $message_type eq 'requestingAgencyMessage' ) {
|
||||
#
|
||||
# Handle incoming requestingAgencyMessage message
|
||||
#
|
||||
my $supplyingAgencyRequestId =
|
||||
$json->{requestingAgencyMessage}->{header}->{supplyingAgencyRequestId};
|
||||
$iso18626_request = Koha::ILL::ISO18626::Requests->find($supplyingAgencyRequestId);
|
||||
|
||||
return {
|
||||
status => 400,
|
||||
openapi => error_response(
|
||||
$confirmation_message_type,
|
||||
[
|
||||
{
|
||||
errorValue => "supplyingAgencyRequestId: " . $supplyingAgencyRequestId,
|
||||
errorType => "UnrecognizedDataValue"
|
||||
}
|
||||
]
|
||||
)
|
||||
} unless $iso18626_request;
|
||||
$action = $json->{$message_type}->{action};
|
||||
my $requestingAgencyMessage = $iso18626_request->add_message( { type => $message_type, message => $body } );
|
||||
|
||||
# Verify if the provided action is supported
|
||||
my $supported_action_types = supported_action_types($iso18626_request);
|
||||
return {
|
||||
status => 400,
|
||||
openapi => error_response(
|
||||
$confirmation_message_type,
|
||||
[
|
||||
{
|
||||
errorValue => "action: " . $json->{$message_type}->{action},
|
||||
errorType => "UnsupportedActionType"
|
||||
}
|
||||
]
|
||||
)
|
||||
}
|
||||
unless ( grep { $_ eq $json->{$message_type}->{action} } @$supported_action_types );
|
||||
|
||||
#
|
||||
# Do the things that need to be done depending on the action
|
||||
#
|
||||
|
||||
if ( $action eq 'Cancel' || $action eq 'Renew' ) {
|
||||
$iso18626_request->pending_requesting_agency_action($action)->store();
|
||||
}
|
||||
|
||||
# TODO: Only send out supplyingAgencyMessage if $action == statusRequest (?)
|
||||
#$iso18626_request->progress_request( 'requestingAgency', { message => $requestingAgencyMessage } ); #TODO: Rethink this but good enough for now
|
||||
|
||||
#
|
||||
# Prepare outgoing requestingAgencyMessageConfirmation response
|
||||
#
|
||||
$response = {
|
||||
$confirmation_message_type => {
|
||||
confirmationHeader => {
|
||||
timestamp => _now_utc_str(),
|
||||
timestampReceived => _now_utc_str(),
|
||||
messageStatus => 'OK',
|
||||
},
|
||||
action => $json->{$message_type}->{action},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#TODO: Handle supplyingAgencyMessage ?
|
||||
# IF a supplyingAgencyMessage is received, it means this Koha is acting as a requesting agency and we need to handle Koha::ILL::Request instead of Koha::ILL::ISO18626::Request (?)
|
||||
|
||||
# Ensure the produced confirmation message is ISO18626 conformant
|
||||
my $validation_errors = is_invalid( $confirmation_message_type, $response );
|
||||
if ($validation_errors) {
|
||||
return {
|
||||
status => 400,
|
||||
openapi => error_response(
|
||||
$confirmation_message_type,
|
||||
$validation_errors
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
# All good, save the message and return the response
|
||||
sleep 1;
|
||||
$iso18626_request->add_message( { type => $confirmation_message_type, message => JSON::encode_json($response) } );
|
||||
return { status => 201, openapi => $response };
|
||||
|
||||
}
|
||||
|
||||
=head3 _now_utc_str
|
||||
|
||||
=cut
|
||||
|
||||
sub _now_utc_str {
|
||||
return dt_from_string( undef, undef, 'UTC' )->strftime('%Y-%m-%dT%H:%M:%SZ');
|
||||
}
|
||||
|
||||
=head3 error_response
|
||||
|
||||
=cut
|
||||
|
||||
sub error_response {
|
||||
my ( $message_type, $error_data ) = @_;
|
||||
|
||||
return {
|
||||
$message_type => {
|
||||
confirmationHeader => {
|
||||
timestamp => _now_utc_str(),
|
||||
timestampReceived => _now_utc_str(),
|
||||
messageStatus => 'ERROR',
|
||||
},
|
||||
errorData => $error_data,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
=head3 message_types
|
||||
|
||||
=cut
|
||||
|
||||
sub message_types {
|
||||
return [
|
||||
'request',
|
||||
'requestConfirmation',
|
||||
'requestingAgencyMessage',
|
||||
'requestingAgencyMessageConfirmation',
|
||||
'supplyingAgencyMessage',
|
||||
'supplyingAgencyMessageConfirmation'
|
||||
];
|
||||
}
|
||||
|
||||
=head3 supported_action_types
|
||||
|
||||
Returns an array of supported action types for a given ISO18626 request.
|
||||
Returns an empty array if the request has already been completed.
|
||||
|
||||
=cut
|
||||
|
||||
sub supported_action_types {
|
||||
my ($iso18626_request) = @_;
|
||||
|
||||
return []
|
||||
if $iso18626_request->status =~ /^(?:Cancelled|CopyCompleted|CompletedWithoutReturn|LoanCompleted|Unfilled)$/;
|
||||
|
||||
return [
|
||||
'StatusRequest',
|
||||
'Received',
|
||||
'Cancel',
|
||||
|
||||
# TODO: Uncomment these once implemented
|
||||
#'Renew',
|
||||
#'HoldReturn',
|
||||
#'ShippedReturn',
|
||||
#'ShippedForward',
|
||||
#'Notification',
|
||||
#'Lost',
|
||||
];
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package Koha::ILL::ISO18626::Message;
|
||||
|
||||
# Copyright Open Fifth 2026
|
||||
#
|
||||
# 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 <https://www.gnu.org/licenses>.
|
||||
|
||||
use Modern::Perl;
|
||||
|
||||
use base qw(Koha::Object);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Koha::ILL::ISO18626::Message - Koha ILL ISO18626 message Object class
|
||||
|
||||
=cut
|
||||
|
||||
=head2 Internal methods
|
||||
|
||||
=head3 _type
|
||||
|
||||
=cut
|
||||
|
||||
sub _type {
|
||||
return 'Iso18626Message';
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package Koha::ILL::ISO18626::Messages;
|
||||
|
||||
# Copyright Open Fifth 2026
|
||||
#
|
||||
# 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 <https://www.gnu.org/licenses>.
|
||||
|
||||
use Modern::Perl;
|
||||
|
||||
use Koha::Database;
|
||||
use Koha::ILL::ISO18626::Message;
|
||||
|
||||
use base qw(Koha::Objects);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Koha::ILL::Messages - Koha ISO18626 messages Object class
|
||||
|
||||
=cut
|
||||
|
||||
=head2 Internal methods
|
||||
|
||||
=head3 _type
|
||||
|
||||
=cut
|
||||
|
||||
sub _type {
|
||||
return 'Iso18626Message';
|
||||
}
|
||||
|
||||
=head3 object_class
|
||||
|
||||
=cut
|
||||
|
||||
sub object_class {
|
||||
return 'Koha::ILL::ISO18626::Message';
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
@ -0,0 +1,407 @@
|
|||
package Koha::ILL::ISO18626::Request;
|
||||
|
||||
# Copyright Open Fifth 2026
|
||||
#
|
||||
# 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 <https://www.gnu.org/licenses>.
|
||||
|
||||
use Modern::Perl;
|
||||
|
||||
use Koha::ILL::ISO18626::Messages;
|
||||
use Koha::REST::V1;
|
||||
use XML::LibXML;
|
||||
use JSON qw( encode_json decode_json );
|
||||
use File::Basename qw( dirname );
|
||||
|
||||
use Koha::Biblios;
|
||||
use Koha::ILL::ISO18626::RequestingAgency;
|
||||
use Koha::DateUtils qw( dt_from_string );
|
||||
|
||||
use base qw(Koha::Object);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Koha::ILL::ISO18626::Request - Koha ILL ISO18626 request Object class
|
||||
|
||||
=cut
|
||||
|
||||
=head2 Internal methods
|
||||
|
||||
=head3 new
|
||||
|
||||
Intercept the 'new' I<Koha::Object> lifecycle method
|
||||
If a supplierUniqueRecordId exists in the request payload, the
|
||||
corresponding bib record is linked to this request on creation
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my ( $class, $params ) = @_;
|
||||
|
||||
my $json = delete $params->{_json_payload};
|
||||
if ( $json && $json->{request}->{bibliographicInfo}->{supplierUniqueRecordId} ) {
|
||||
my $supplierUniqueRecordId = $json->{request}->{bibliographicInfo}->{supplierUniqueRecordId};
|
||||
|
||||
my $biblio = Koha::Biblios->find($supplierUniqueRecordId);
|
||||
$params->{biblio_id} = $biblio->biblionumber if $biblio;
|
||||
}
|
||||
|
||||
my $self = $class->SUPER::new($params);
|
||||
return $self;
|
||||
}
|
||||
|
||||
=head3 add_message
|
||||
|
||||
Add the I<Koha::ILL::ISO18626::Message> to this ISO18626 request
|
||||
|
||||
=cut
|
||||
|
||||
sub add_message {
|
||||
my ( $self, $params ) = @_;
|
||||
|
||||
my $type = $params->{type};
|
||||
my $message = $params->{message};
|
||||
|
||||
if ( ref $message eq 'HASH' ) {
|
||||
$message = encode_json($message);
|
||||
}
|
||||
|
||||
return $self->_result->add_to_iso18626_messages(
|
||||
{
|
||||
type => $type,
|
||||
content => $message,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
=head3 messages
|
||||
|
||||
Return the I<Koha::ILL::ISO18626::Messages> for this ISO18626 request
|
||||
|
||||
=cut
|
||||
|
||||
sub messages {
|
||||
my ($self) = @_;
|
||||
my $messages = $self->_result->iso18626_messages->search(
|
||||
{},
|
||||
{ order_by => { -desc => 'timestamp' } }
|
||||
);
|
||||
return Koha::ILL::ISO18626::Messages->_new_from_dbic($messages);
|
||||
}
|
||||
|
||||
=head3 send_message
|
||||
|
||||
Send a message to the requesting agency
|
||||
# $message must be a valid XML string.
|
||||
|
||||
=cut
|
||||
|
||||
sub send_message {
|
||||
my ( $self, $type, $message ) = @_;
|
||||
|
||||
# my $requesting_agency = $self->_result->requesting_agency;
|
||||
|
||||
# return unless $requesting_agency->callback_endpoint;
|
||||
|
||||
# my $ua = LWP::UserAgent->new( agent => 'Koha ILL' );
|
||||
# $ua->agent( 'Koha/' . Koha::version() );
|
||||
|
||||
# my $response = $ua->post(
|
||||
# $requesting_agency->callback_endpoint,
|
||||
# Content_Type => 'application/xml',
|
||||
# Content => $message,
|
||||
# );
|
||||
|
||||
# if ( $response->is_success ) {
|
||||
#FIXME: Better way to convert this to json other than invoking Koha::REST::V1 ?
|
||||
# my $parser = XML::LibXML->new();
|
||||
# my $doc = $parser->parse_string($message);
|
||||
# my $root = $doc->documentElement();
|
||||
# my $json = Koha::REST::V1::parse_xml($root);
|
||||
|
||||
# $json = JSON::encode_json($json);
|
||||
$self->add_message( { type => $type, message => $message } );
|
||||
return 1;
|
||||
|
||||
# }
|
||||
# else {
|
||||
# $self->_result->add_message( 'Request', "Failed to send message: " . $response->status_line );
|
||||
# return;
|
||||
# }
|
||||
}
|
||||
|
||||
=head3 requesting_agency
|
||||
|
||||
Returns the associated Koha::ILL::ISO18626::RequestingAgency object.
|
||||
|
||||
=cut
|
||||
|
||||
sub requesting_agency {
|
||||
my ($self) = @_;
|
||||
my $ra_rs = $self->_result->iso18626_requesting_agency;
|
||||
return unless $ra_rs;
|
||||
return Koha::ILL::ISO18626::RequestingAgency->_new_from_dbic($ra_rs);
|
||||
}
|
||||
|
||||
=head3 hold
|
||||
|
||||
my $hold = $iso18626_request->hold();
|
||||
|
||||
Method that returns the related I<Koha::Hold>
|
||||
|
||||
=cut
|
||||
|
||||
sub hold {
|
||||
my ($self) = @_;
|
||||
my $hold_rs = $self->_result->reserve;
|
||||
return unless $hold_rs;
|
||||
return Koha::Hold->_new_from_dbic($hold_rs);
|
||||
}
|
||||
|
||||
=head3 get_checkout
|
||||
|
||||
Returns the related Koha::Checkout obj for this ISO18626 request
|
||||
|
||||
=cut
|
||||
|
||||
sub get_checkout {
|
||||
my ($self) = @_;
|
||||
my $rs = $self->_result->issue;
|
||||
return unless $rs;
|
||||
return Koha::Checkout->_new_from_dbic($rs);
|
||||
}
|
||||
|
||||
=head3 progress_request
|
||||
|
||||
Progress the request by sending a message to the requesting agency with the status of the request.
|
||||
|
||||
Params:
|
||||
- actor: supplyingAgency or requestingAgency
|
||||
- params: may contain status, messageInfoNote, message
|
||||
|
||||
=cut
|
||||
|
||||
sub progress_request {
|
||||
my ( $self, $actor, $params ) = @_;
|
||||
|
||||
return unless $actor;
|
||||
|
||||
my $resulting_status = $self->status;
|
||||
my $old_status = $self->status;
|
||||
my $new_status = $params->{status};
|
||||
|
||||
my $reasonForMessage = 'RequestResponse';
|
||||
my $messageInfoNote = $params->{messageInfoNote} // undef;
|
||||
my $answerYesNo = $params->{answerYesNo} // undef;
|
||||
my $expectedDeliveryDate = _format_iso_payload_date_param( $params->{expectedDeliveryDate} );
|
||||
my $reasonUnfilled = $params->{reasonUnfilled} // undef;
|
||||
my $reasonRetry = $params->{reasonRetry} // undef;
|
||||
|
||||
my $courierName =
|
||||
( $params->{courierName}
|
||||
&& $params->{reasonRetry} eq 'ReqDelMethodNotSupp'
|
||||
&& $params->{deliveryMethod}
|
||||
&& grep { $_ eq 'Courier' } @{ $params->{deliveryMethod} } ) ? $params->{courierName} : undef;
|
||||
my $deliveryMethod = $params->{deliveryMethod}
|
||||
&& $params->{reasonRetry} eq 'ReqDelMethodNotSupp' ? $params->{deliveryMethod} : undef;
|
||||
my $edition =
|
||||
$params->{edition} && $params->{reasonRetry} eq 'ReqEditionNotPossible' ? $params->{edition} : undef;
|
||||
my $itemFormat =
|
||||
$params->{itemFormat} && $params->{reasonRetry} eq 'ReqFormatNotPossible' ? $params->{itemFormat} : undef;
|
||||
my $loanCondition = $params->{loanCondition}
|
||||
&& $params->{reasonRetry} eq 'MustMeetLoanCondition' ? $params->{loanCondition} : undef;
|
||||
my $offeredCostsCurrencyCode = $params->{offeredCostsCurrencyCode}
|
||||
&& $params->{reasonRetry} eq 'CostExceedsMaxCost' ? $params->{offeredCostsCurrencyCode} : undef;
|
||||
my $offeredCostsMonetaryValue = $params->{offeredCostsMonetaryValue}
|
||||
&& $params->{reasonRetry} eq 'CostExceedsMaxCost' ? $params->{offeredCostsMonetaryValue} : undef;
|
||||
my $paymentMethod =
|
||||
$params->{paymentMethod} && $params->{reasonRetry} eq 'ReqPayMethodNotSupported'
|
||||
? $params->{paymentMethod}
|
||||
: undef;
|
||||
my $retryBefore = $params->{retryBefore} && $new_status eq 'RetryPossible' ? $params->{retryBefore} : undef;
|
||||
my $retryAfter = $params->{retryAfter} && $new_status eq 'RetryPossible' ? $params->{retryAfter} : undef;
|
||||
my $serviceLevel = $params->{serviceLevel}
|
||||
&& $params->{reasonRetry} eq 'ReqServLevelNotSupp' ? $params->{serviceLevel} : undef;
|
||||
my $serviceType =
|
||||
$params->{serviceType} && $params->{reasonRetry} eq 'ReqServTypeNotPossible' ? $params->{serviceType} : undef;
|
||||
my $volume = $params->{volume} && $params->{reasonRetry} eq 'MultiVolAvail' ? $params->{volume} : undef;
|
||||
|
||||
if ( $actor eq 'requestingAgency' ) {
|
||||
return unless $params->{message};
|
||||
|
||||
my $message = $params->{message};
|
||||
my $json_message = JSON::decode_json( $message->content );
|
||||
|
||||
my $requesting_agency_action = $json_message->{requestingAgencyMessage}->{action};
|
||||
|
||||
if ( $requesting_agency_action eq 'StatusRequest' ) {
|
||||
$reasonForMessage = 'StatusRequestResponse';
|
||||
} elsif ( $requesting_agency_action eq 'Received' ) {
|
||||
return;
|
||||
}
|
||||
} elsif ( $actor eq 'supplyingAgency' ) {
|
||||
return unless $new_status;
|
||||
|
||||
$resulting_status = $new_status if $actor eq 'supplyingAgency';
|
||||
|
||||
if ( $resulting_status ne $old_status ) {
|
||||
$reasonForMessage = 'StatusChange';
|
||||
}
|
||||
|
||||
if ( $new_status eq 'Cancelled' ) {
|
||||
$reasonForMessage = 'CancelResponse';
|
||||
$resulting_status = $old_status unless $answerYesNo eq 'Y';
|
||||
$self->pending_requesting_agency_action(undef)->store;
|
||||
}
|
||||
|
||||
#TODO: Handle other statuses
|
||||
# elsif ( $new_status eq 'Renew' ) { #Handle 'renew', it's not a status
|
||||
# $reasonForMessage = 'RenewResponse';
|
||||
# $answerYesNo = $params->{answerYesNo};
|
||||
# $resulting_status = ?????;
|
||||
# }
|
||||
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
my $check_out = $self->get_checkout;
|
||||
my $check_out_item = $self->get_checkout ? $self->get_checkout->item : undef;
|
||||
|
||||
my $json = {
|
||||
supplyingAgencyMessage => {
|
||||
header => {
|
||||
supplyingAgencyId => {
|
||||
agencyIdType => 'ISIL',
|
||||
agencyIdValue => 'sup_agency_value',
|
||||
},
|
||||
requestingAgencyRequestId => 'XYZ',
|
||||
supplyingAgencyRequestId => $self->iso18626_request_id,
|
||||
timestamp => _format_iso_payload_date_param('now'),
|
||||
requestingAgencyId => {
|
||||
agencyIdType => 'ISIL',
|
||||
agencyIdValue => 'req_agency_value',
|
||||
},
|
||||
},
|
||||
messageInfo => {
|
||||
reasonForMessage => $reasonForMessage,
|
||||
$answerYesNo ? ( answerYesNo => $answerYesNo ) : (),
|
||||
$messageInfoNote ? ( note => $messageInfoNote ) : (),
|
||||
$reasonUnfilled && $resulting_status eq 'Unfilled' ? ( reasonUnfilled => $reasonUnfilled ) : (),
|
||||
$reasonRetry && $resulting_status eq 'RetryPossible' ? ( reasonRetry => $reasonRetry ) : (),
|
||||
},
|
||||
statusInfo => {
|
||||
status => $resulting_status,
|
||||
$expectedDeliveryDate ? ( expectedDeliveryDate => $expectedDeliveryDate ) : (),
|
||||
$check_out ? ( dueDate => $check_out->date_due ) : (),
|
||||
lastChange => $self->updated_on,
|
||||
},
|
||||
$resulting_status eq 'RetryPossible'
|
||||
? (
|
||||
retryInfo => {
|
||||
$loanCondition ? ( loanCondition => $loanCondition ) : (),
|
||||
$edition ? ( edition => [ split /,/, $edition ] ) : (),
|
||||
$itemFormat ? ( itemFormat => $itemFormat ) : (),
|
||||
$volume ? ( volume => [ split /,/, $volume ] ) : (),
|
||||
$serviceType ? ( serviceType => $serviceType ) : (),
|
||||
$serviceLevel ? ( serviceLevel => $serviceLevel ) : (),
|
||||
$deliveryMethod ? ( deliveryMethod => $deliveryMethod ) : (),
|
||||
$courierName ? ( courierName => $courierName ) : (),
|
||||
$offeredCostsMonetaryValue && $offeredCostsCurrencyCode
|
||||
? (
|
||||
offeredCosts => [
|
||||
{ currencyCode => $offeredCostsCurrencyCode, monetaryValue => $offeredCostsMonetaryValue }
|
||||
]
|
||||
)
|
||||
: (),
|
||||
$paymentMethod ? ( paymentMethod => $paymentMethod ) : (),
|
||||
$retryBefore ? ( retryBefore => $retryBefore ) : (),
|
||||
$retryAfter ? ( retryAfter => $retryAfter ) : (),
|
||||
}
|
||||
)
|
||||
: (),
|
||||
( $resulting_status eq 'Loaned' && $check_out_item )
|
||||
? (
|
||||
deliveryInfo => {
|
||||
dateSent => $check_out->issuedate,
|
||||
itemId => $check_out_item->barcode,
|
||||
|
||||
#itemFormat => ['PaperCopy'], # TODO: Implement: Must come from payload (only needed if specified by RA?)
|
||||
serviceType => 'Loan',
|
||||
|
||||
#deliveryMethod => 'Email', # TODO: Implement: Must come from payload (only needed if specified by RA?)
|
||||
#paymentMethod => 'BankTransfer' # TODO: Implement: Must come from payload (only needed if specified by RA?)
|
||||
}
|
||||
)
|
||||
: (),
|
||||
|
||||
# TODO: Implement shippingInfo
|
||||
# shippingInfo => {
|
||||
# courierName => 'DHL',
|
||||
# trackingId => [ '123', 'abc' ],
|
||||
# insurance => 'N',
|
||||
# insuranceThirdParty => 'N',
|
||||
# thirdPartyName => 'Some name, if insuranceThirdParty',
|
||||
# insuranceCosts => [ { currencyCode => 'EUR', monetaryValue => '50.00' } ]
|
||||
# }
|
||||
},
|
||||
};
|
||||
|
||||
my $spec_file = dirname(__FILE__) . "/../../../api/v1/swagger/swagger_bundle.json";
|
||||
if ( !-f $spec_file ) {
|
||||
$spec_file = dirname(__FILE__) . "/../../../api/v1/swagger/swagger.yaml";
|
||||
}
|
||||
|
||||
my $schema = JSON::Validator::Schema::OpenAPIv2->new($spec_file);
|
||||
$schema->resolve( $schema->data->{definitions}->{supplyingAgencyMessage} );
|
||||
my @errors = $schema->validate($json);
|
||||
|
||||
if (@errors) {
|
||||
|
||||
#TODO: Throw exception
|
||||
use Data::Dumper;
|
||||
$Data::Dumper::Maxdepth = 4;
|
||||
warn Dumper( '##### 2 #######################################################line: ' . __LINE__ );
|
||||
warn Dumper( \@errors );
|
||||
warn Dumper('##### end2 #######################################################');
|
||||
}
|
||||
$self->status($resulting_status)->store;
|
||||
$self->send_message( 'supplyingAgencyMessage', $json );
|
||||
return 1;
|
||||
}
|
||||
|
||||
=head2 _format_iso_payload_date_param
|
||||
|
||||
Normalizes a date string to C<YYYY-MM-DD HH:MM:SS>
|
||||
|
||||
=cut
|
||||
|
||||
sub _format_iso_payload_date_param {
|
||||
my ($date_str) = @_;
|
||||
return unless $date_str;
|
||||
|
||||
my $dt = eval { $date_str eq 'now' ? dt_from_string() : dt_from_string($date_str) };
|
||||
return $dt ? $dt->strftime('%Y-%m-%d %H:%M:%S') : $date_str;
|
||||
}
|
||||
|
||||
=head3 _type
|
||||
|
||||
=cut
|
||||
|
||||
sub _type {
|
||||
return 'Iso18626Request';
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package Koha::ILL::ISO18626::RequestingAgencies;
|
||||
|
||||
# Copyright Open Fifth 2026
|
||||
#
|
||||
# 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 <https://www.gnu.org/licenses>.
|
||||
|
||||
use Modern::Perl;
|
||||
|
||||
use Koha::Database;
|
||||
use Koha::ILL::ISO18626::RequestingAgency;
|
||||
|
||||
use base qw(Koha::Objects);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Koha::ILL::RequestingAgencies - Koha ISO18626 Requesting Agencies Object class
|
||||
|
||||
=cut
|
||||
|
||||
=head2 Internal methods
|
||||
|
||||
=head3 _type
|
||||
|
||||
=cut
|
||||
|
||||
sub _type {
|
||||
return 'Iso18626RequestingAgency';
|
||||
}
|
||||
|
||||
=head3 object_class
|
||||
|
||||
=cut
|
||||
|
||||
sub object_class {
|
||||
return 'Koha::ILL::ISO18626::RequestingAgency';
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
package Koha::ILL::ISO18626::RequestingAgency;
|
||||
|
||||
# Copyright Open Fifth 2026
|
||||
#
|
||||
# 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 <https://www.gnu.org/licenses>.
|
||||
|
||||
use Modern::Perl;
|
||||
|
||||
use base qw(Koha::Object);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Koha::ILL::ISO18626::RequestingAgency - Koha ILL ISO18626 Requesting Agency Object class
|
||||
|
||||
=cut
|
||||
|
||||
=head2 Internal methods
|
||||
|
||||
=head3 to_api_mapping
|
||||
|
||||
This method returns the mapping for representing a Koha::ILL::ISO18626::RequestingAgency
|
||||
object on the API.
|
||||
|
||||
=cut
|
||||
|
||||
sub to_api_mapping {
|
||||
return {
|
||||
borrowernumber => 'patron_id',
|
||||
};
|
||||
}
|
||||
|
||||
=head3 ill_partner
|
||||
|
||||
Return the ill_partner patron for this requesting agency
|
||||
|
||||
=cut
|
||||
|
||||
sub ill_partner {
|
||||
my ($self) = @_;
|
||||
my $patrons_rs = $self->_result->patron;
|
||||
return unless $patrons_rs;
|
||||
return Koha::Patron->_new_from_dbic($patrons_rs);
|
||||
}
|
||||
|
||||
=head3 _type
|
||||
|
||||
=cut
|
||||
|
||||
sub _type {
|
||||
return 'Iso18626RequestingAgency';
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
package Koha::ILL::ISO18626::Requests;
|
||||
|
||||
# Copyright Open Fifth 2026
|
||||
#
|
||||
# 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 <https://www.gnu.org/licenses>.
|
||||
|
||||
use Modern::Perl;
|
||||
|
||||
use Koha::Database;
|
||||
use Koha::ILL::ISO18626::Request;
|
||||
|
||||
use base qw(Koha::Objects);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Koha::ILL::Requests - Koha ISO18626 requests Object class
|
||||
|
||||
=cut
|
||||
|
||||
=head2 Internal methods
|
||||
|
||||
=head3 get_request_by_issue_id
|
||||
|
||||
my $iso18626_request = Koha::ILL::ISO18626::Requests->get_request_by_issue_id( $c->{issue_id} );
|
||||
|
||||
Returns the request provided an issue_id.
|
||||
|
||||
=cut
|
||||
|
||||
sub get_request_by_issue_id {
|
||||
my ( $self, $issue_id ) = @_;
|
||||
|
||||
return $self->find( { 'issue_id' => $issue_id } );
|
||||
}
|
||||
|
||||
=head2 Internal methods
|
||||
|
||||
=head3 _type
|
||||
|
||||
=cut
|
||||
|
||||
sub _type {
|
||||
return 'Iso18626Request';
|
||||
}
|
||||
|
||||
=head3 object_class
|
||||
|
||||
=cut
|
||||
|
||||
sub object_class {
|
||||
return 'Koha::ILL::ISO18626::Request';
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
@ -0,0 +1,209 @@
|
|||
package Koha::REST::V1::ILL::ISO18626::RequestingAgencies;
|
||||
|
||||
# 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 <https://www.gnu.org/licenses>.
|
||||
|
||||
use Modern::Perl;
|
||||
|
||||
use Mojo::Base 'Mojolicious::Controller';
|
||||
|
||||
use Koha::ILL::ISO18626::RequestingAgencies;
|
||||
use Try::Tiny qw( catch try );
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Koha::REST::V1::ILL::ISO18626::RequestingAgencies
|
||||
|
||||
=head2 Operations
|
||||
|
||||
=head3 list
|
||||
|
||||
Controller function that handles listing Koha::ILL::ISO18626::RequestingAgency objects
|
||||
|
||||
=cut
|
||||
|
||||
sub list {
|
||||
my $c = shift->openapi->valid_input or return;
|
||||
|
||||
return try {
|
||||
my $reqs = $c->objects->search( Koha::ILL::ISO18626::RequestingAgencies->new );
|
||||
return $c->render(
|
||||
status => 200,
|
||||
openapi => $reqs,
|
||||
);
|
||||
} catch {
|
||||
$c->unhandled_exception($_);
|
||||
};
|
||||
}
|
||||
|
||||
=head3 get
|
||||
|
||||
Controller function that handles retrieving a single Koha::ILL::ISO18626::RequestingAgency object
|
||||
|
||||
=cut
|
||||
|
||||
sub get {
|
||||
my $c = shift->openapi->valid_input or return;
|
||||
|
||||
return try {
|
||||
my $iso18626_requesting_agency = $c->objects->find(
|
||||
Koha::ILL::ISO18626::RequestingAgencies->search,
|
||||
$c->param('iso18626_requesting_agency_id')
|
||||
);
|
||||
|
||||
return $c->render_resource_not_found("ISO18626 requesting agency")
|
||||
unless $iso18626_requesting_agency;
|
||||
|
||||
return $c->render(
|
||||
status => 200,
|
||||
openapi => $iso18626_requesting_agency
|
||||
);
|
||||
} catch {
|
||||
$c->unhandled_exception($_);
|
||||
};
|
||||
}
|
||||
|
||||
=head3 add
|
||||
|
||||
Controller function that handles adding a new Koha::ILL::ISO18626::RequestingAgency object
|
||||
|
||||
=cut
|
||||
|
||||
sub add {
|
||||
my $c = shift->openapi->valid_input or return;
|
||||
|
||||
return try {
|
||||
Koha::Database->new->schema->txn_do(
|
||||
sub {
|
||||
|
||||
my $body = $c->req->json;
|
||||
|
||||
my $requesting_agency = Koha::ILL::ISO18626::RequestingAgency->new_from_api($body)->store;
|
||||
$c->res->headers->location(
|
||||
$c->req->url->to_string . '/' . $requesting_agency->iso18626_requesting_agency_id );
|
||||
return $c->render(
|
||||
status => 201,
|
||||
openapi => $c->objects->to_api($requesting_agency),
|
||||
);
|
||||
}
|
||||
);
|
||||
} catch {
|
||||
|
||||
my $to_api_mapping = Koha::ILL::ISO18626::RequestingAgency->new->to_api_mapping;
|
||||
|
||||
if ( blessed $_ ) {
|
||||
if ( $_->isa('Koha::Exceptions::Object::DuplicateID') ) {
|
||||
return $c->render(
|
||||
status => 409,
|
||||
openapi => { error => $_->error, conflict => $_->duplicate_id }
|
||||
);
|
||||
} elsif ( $_->isa('Koha::Exceptions::Object::FKConstraint') ) {
|
||||
return $c->render(
|
||||
status => 400,
|
||||
openapi => { error => "Given " . $to_api_mapping->{ $_->broken_fk } . " does not exist" }
|
||||
);
|
||||
} elsif ( $_->isa('Koha::Exceptions::BadParameter') ) {
|
||||
return $c->render(
|
||||
status => 400,
|
||||
openapi => { error => "Given " . $to_api_mapping->{ $_->parameter } . " does not exist" }
|
||||
);
|
||||
} elsif ( $_->isa('Koha::Exceptions::PayloadTooLarge') ) {
|
||||
return $c->render(
|
||||
status => 413,
|
||||
openapi => { error => $_->error }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$c->unhandled_exception($_);
|
||||
};
|
||||
}
|
||||
|
||||
=head3 update
|
||||
|
||||
Controller function that handles updating a Koha::ILL::ISO18626::RequestingAgency object
|
||||
|
||||
=cut
|
||||
|
||||
sub update {
|
||||
my $c = shift->openapi->valid_input or return;
|
||||
|
||||
my $requesting_agency = Koha::ILL::ISO18626::RequestingAgencies->find( $c->param('iso18626_requesting_agency_id') );
|
||||
|
||||
return $c->render_resource_not_found("ISO18626 requesting agency")
|
||||
unless $requesting_agency;
|
||||
|
||||
return try {
|
||||
Koha::Database->new->schema->txn_do(
|
||||
sub {
|
||||
|
||||
my $body = $c->req->json;
|
||||
|
||||
$requesting_agency->set_from_api($body)->store;
|
||||
$c->res->headers->location(
|
||||
$c->req->url->to_string . '/' . $requesting_agency->iso18626_requesting_agency_id );
|
||||
return $c->render(
|
||||
status => 200,
|
||||
openapi => $c->objects->to_api($requesting_agency),
|
||||
);
|
||||
}
|
||||
);
|
||||
} catch {
|
||||
my $to_api_mapping = Koha::ILL::ISO18626::RequestingAgency->new->to_api_mapping;
|
||||
|
||||
if ( blessed $_ ) {
|
||||
if ( $_->isa('Koha::Exceptions::Object::FKConstraint') ) {
|
||||
return $c->render(
|
||||
status => 400,
|
||||
openapi => { error => "Given " . $to_api_mapping->{ $_->broken_fk } . " does not exist" }
|
||||
);
|
||||
} elsif ( $_->isa('Koha::Exceptions::BadParameter') ) {
|
||||
return $c->render(
|
||||
status => 400,
|
||||
openapi => { error => "Given " . $to_api_mapping->{ $_->parameter } . " does not exist" }
|
||||
);
|
||||
} elsif ( $_->isa('Koha::Exceptions::PayloadTooLarge') ) {
|
||||
return $c->render(
|
||||
status => 413,
|
||||
openapi => { error => $_->error }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$c->unhandled_exception($_);
|
||||
};
|
||||
}
|
||||
|
||||
=head3 delete
|
||||
|
||||
=cut
|
||||
|
||||
sub delete {
|
||||
my $c = shift->openapi->valid_input or return;
|
||||
|
||||
my $requesting_agency = Koha::ILL::ISO18626::RequestingAgencies->find( $c->param('iso18626_requesting_agency_id') );
|
||||
|
||||
return $c->render_resource_not_found("ISO18626 requesting agency")
|
||||
unless $requesting_agency;
|
||||
|
||||
return try {
|
||||
$requesting_agency->delete;
|
||||
return $c->render_resource_deleted;
|
||||
} catch {
|
||||
$c->unhandled_exception($_);
|
||||
};
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
package Koha::REST::V1::ILL::ISO18626::Requests;
|
||||
|
||||
# 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 <https://www.gnu.org/licenses>.
|
||||
|
||||
use Modern::Perl;
|
||||
|
||||
use Mojo::Base 'Mojolicious::Controller';
|
||||
|
||||
use Koha::ILL::ISO18626::Requests;
|
||||
use Try::Tiny qw( catch try );
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Koha::REST::V1::ILL::ISO18626::Requests
|
||||
|
||||
=head2 Operations
|
||||
|
||||
=head3 list
|
||||
|
||||
Controller function that handles listing Koha::ILL::ISO18626::Request objects
|
||||
|
||||
=cut
|
||||
|
||||
sub list {
|
||||
my $c = shift->openapi->valid_input or return;
|
||||
|
||||
return try {
|
||||
my $reqs = $c->objects->search( Koha::ILL::ISO18626::Requests->new );
|
||||
return $c->render(
|
||||
status => 200,
|
||||
openapi => $reqs,
|
||||
);
|
||||
} catch {
|
||||
$c->unhandled_exception($_);
|
||||
};
|
||||
}
|
||||
|
||||
=head3 get
|
||||
|
||||
Controller function that handles retrieving a single Koha::ILL::ISO18626::Request object
|
||||
|
||||
=cut
|
||||
|
||||
sub get {
|
||||
my $c = shift->openapi->valid_input or return;
|
||||
|
||||
return try {
|
||||
my $iso18626_request =
|
||||
$c->objects->find( Koha::ILL::ISO18626::Requests->search, $c->param('iso18626_request_id') );
|
||||
|
||||
return $c->render_resource_not_found("Iso18626 request")
|
||||
unless $iso18626_request;
|
||||
|
||||
return $c->render(
|
||||
status => 200,
|
||||
openapi => $iso18626_request
|
||||
);
|
||||
} catch {
|
||||
$c->unhandled_exception($_);
|
||||
};
|
||||
}
|
||||
|
||||
=head3 edit
|
||||
|
||||
Controller function that handles editing a single Koha::ILL::ISO18626::Request object
|
||||
|
||||
=cut
|
||||
|
||||
sub edit {
|
||||
my $c = shift or return;
|
||||
|
||||
my $request_id = $c->param('iso18626_request_id');
|
||||
my $request = Koha::ILL::ISO18626::Requests->find($request_id);
|
||||
|
||||
return try {
|
||||
my $body = $c->req->json;
|
||||
my $status = $body->{status};
|
||||
|
||||
$request->progress_request( 'supplyingAgency', $body ); #TODO: Rethink this but good enough for now
|
||||
|
||||
return $c->render(
|
||||
status => 200,
|
||||
openapi => $request->to_api
|
||||
);
|
||||
} catch {
|
||||
return $c->unhandled_exception($_);
|
||||
};
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
@ -1526,6 +1526,21 @@ __PACKAGE__->has_many(
|
|||
{ cascade_copy => 0, cascade_delete => 0 },
|
||||
);
|
||||
|
||||
=head2 iso18626_requesting_agency
|
||||
|
||||
Type: might_have
|
||||
|
||||
Related object: L<Koha::Schema::Result::Iso18626RequestingAgency>
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->might_have(
|
||||
"iso18626_requesting_agency",
|
||||
"Koha::Schema::Result::Iso18626RequestingAgency",
|
||||
{ "foreign.borrowernumber" => "self.borrowernumber" },
|
||||
{ cascade_copy => 0, cascade_delete => 0 },
|
||||
);
|
||||
|
||||
=head2 issues
|
||||
|
||||
Type: has_many
|
||||
|
|
@ -2227,8 +2242,8 @@ Composing rels: L</user_permissions> -> permission
|
|||
__PACKAGE__->many_to_many("permissions", "user_permissions", "permission");
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07051 @ 2025-11-03 14:19:07
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:NHrhTcf4p6JW5fNgfYiqeQ
|
||||
# Created by DBIx::Class::Schema::Loader v0.07051 @ 2026-04-14 10:19:11
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:Tptr5nUuS5haVck624FS3Q
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
"library",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,150 @@
|
|||
use utf8;
|
||||
package Koha::Schema::Result::Iso18626Message;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Koha::Schema::Result::Iso18626Message
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
|
||||
=head1 TABLE: C<iso18626_messages>
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->table("iso18626_messages");
|
||||
|
||||
=head1 ACCESSORS
|
||||
|
||||
=head2 iso18626_message_id
|
||||
|
||||
data_type: 'integer'
|
||||
is_auto_increment: 1
|
||||
is_nullable: 0
|
||||
|
||||
Internal message number
|
||||
|
||||
=head2 iso18626_request_id
|
||||
|
||||
data_type: 'integer'
|
||||
is_foreign_key: 1
|
||||
is_nullable: 0
|
||||
|
||||
Associated ISO18626 request
|
||||
|
||||
=head2 content
|
||||
|
||||
data_type: 'mediumtext'
|
||||
is_nullable: 0
|
||||
|
||||
Message content (XML)
|
||||
|
||||
=head2 type
|
||||
|
||||
data_type: 'enum'
|
||||
extra: {list => ["request","requestConfirmation","supplyingAgencyMessage","supplyingAgencyMessageConfirmation","requestingAgencyMessage","requestingAgencyMessageConfirmation"]}
|
||||
is_nullable: 0
|
||||
|
||||
ISO18626 message type
|
||||
|
||||
=head2 timestamp
|
||||
|
||||
data_type: 'timestamp'
|
||||
datetime_undef_if_invalid: 1
|
||||
default_value: current_timestamp
|
||||
is_nullable: 0
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->add_columns(
|
||||
"iso18626_message_id",
|
||||
{ data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
|
||||
"iso18626_request_id",
|
||||
{ data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
|
||||
"content",
|
||||
{ data_type => "mediumtext", is_nullable => 0 },
|
||||
"type",
|
||||
{
|
||||
data_type => "enum",
|
||||
extra => {
|
||||
list => [
|
||||
"request",
|
||||
"requestConfirmation",
|
||||
"supplyingAgencyMessage",
|
||||
"supplyingAgencyMessageConfirmation",
|
||||
"requestingAgencyMessage",
|
||||
"requestingAgencyMessageConfirmation",
|
||||
],
|
||||
},
|
||||
is_nullable => 0,
|
||||
},
|
||||
"timestamp",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
datetime_undef_if_invalid => 1,
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 0,
|
||||
},
|
||||
);
|
||||
|
||||
=head1 PRIMARY KEY
|
||||
|
||||
=over 4
|
||||
|
||||
=item * L</iso18626_message_id>
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->set_primary_key("iso18626_message_id");
|
||||
|
||||
=head1 RELATIONS
|
||||
|
||||
=head2 iso18626_request
|
||||
|
||||
Type: belongs_to
|
||||
|
||||
Related object: L<Koha::Schema::Result::Iso18626Request>
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
"iso18626_request",
|
||||
"Koha::Schema::Result::Iso18626Request",
|
||||
{ iso18626_request_id => "iso18626_request_id" },
|
||||
{ is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
|
||||
);
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07051 @ 2025-09-26 14:56:58
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:3IbJ4SgKGHU+cXJL4LFqwg
|
||||
|
||||
=head2 koha_object_class
|
||||
|
||||
Missing POD for koha_object_class.
|
||||
|
||||
=cut
|
||||
|
||||
sub koha_object_class {
|
||||
'Koha::ILL::ISO18626::Message';
|
||||
}
|
||||
|
||||
=head2 koha_objects_class
|
||||
|
||||
Missing POD for koha_objects_class.
|
||||
|
||||
=cut
|
||||
|
||||
sub koha_objects_class {
|
||||
'Koha::ILL::ISO18626::Messages';
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
@ -0,0 +1,276 @@
|
|||
use utf8;
|
||||
package Koha::Schema::Result::Iso18626Request;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Koha::Schema::Result::Iso18626Request
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
|
||||
=head1 TABLE: C<iso18626_requests>
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->table("iso18626_requests");
|
||||
|
||||
=head1 ACCESSORS
|
||||
|
||||
=head2 iso18626_request_id
|
||||
|
||||
data_type: 'integer'
|
||||
is_auto_increment: 1
|
||||
is_nullable: 0
|
||||
|
||||
Internal request number
|
||||
|
||||
=head2 supplyingAgencyId
|
||||
|
||||
accessor: 'supplying_agency_id'
|
||||
data_type: 'varchar'
|
||||
is_nullable: 1
|
||||
size: 80
|
||||
|
||||
Supplying agency ID
|
||||
|
||||
=head2 iso18626_requesting_agency_id
|
||||
|
||||
data_type: 'integer'
|
||||
is_foreign_key: 1
|
||||
is_nullable: 0
|
||||
|
||||
Associated ISO18626 requesting agency
|
||||
|
||||
=head2 created_on
|
||||
|
||||
data_type: 'timestamp'
|
||||
datetime_undef_if_invalid: 1
|
||||
default_value: current_timestamp
|
||||
is_nullable: 0
|
||||
|
||||
Date and time the request was created
|
||||
|
||||
=head2 updated_on
|
||||
|
||||
data_type: 'timestamp'
|
||||
datetime_undef_if_invalid: 1
|
||||
default_value: current_timestamp
|
||||
is_nullable: 0
|
||||
|
||||
Date and time the request was last updated
|
||||
|
||||
=head2 requestingAgencyRequestId
|
||||
|
||||
accessor: 'requesting_agency_request_id'
|
||||
data_type: 'varchar'
|
||||
is_nullable: 1
|
||||
size: 80
|
||||
|
||||
Requesting agency request ID or number
|
||||
|
||||
=head2 status
|
||||
|
||||
data_type: 'enum'
|
||||
default_value: 'RequestReceived'
|
||||
extra: {list => ["RequestReceived","ExpectToSupply","WillSupply","Loaned","Overdue","Recalled","RetryPossible","Unfilled","HoldReturn","ReleaseHoldReturn","CopyCompleted","LoanCompleted","CompletedWithoutReturn","Cancelled"]}
|
||||
is_nullable: 1
|
||||
|
||||
Current ISO18626 status of request
|
||||
|
||||
=head2 service_type
|
||||
|
||||
data_type: 'enum'
|
||||
extra: {list => ["Copy","Loan","CopyOrLoan"]}
|
||||
is_nullable: 0
|
||||
|
||||
ISO18626 service type
|
||||
|
||||
=head2 pending_requesting_agency_action
|
||||
|
||||
data_type: 'enum'
|
||||
extra: {list => ["Cancel","Renew"]}
|
||||
is_nullable: 1
|
||||
|
||||
ISO18626 Requesting Agency action that requires a manual response (yes or no)
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->add_columns(
|
||||
"iso18626_request_id",
|
||||
{ data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
|
||||
"supplyingAgencyId",
|
||||
{
|
||||
accessor => "supplying_agency_id",
|
||||
data_type => "varchar",
|
||||
is_nullable => 1,
|
||||
size => 80,
|
||||
},
|
||||
"iso18626_requesting_agency_id",
|
||||
{ data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
|
||||
"created_on",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
datetime_undef_if_invalid => 1,
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 0,
|
||||
},
|
||||
"updated_on",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
datetime_undef_if_invalid => 1,
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 0,
|
||||
},
|
||||
"requestingAgencyRequestId",
|
||||
{
|
||||
accessor => "requesting_agency_request_id",
|
||||
data_type => "varchar",
|
||||
is_nullable => 1,
|
||||
size => 80,
|
||||
},
|
||||
"status",
|
||||
{
|
||||
data_type => "enum",
|
||||
default_value => "RequestReceived",
|
||||
extra => {
|
||||
list => [
|
||||
"RequestReceived",
|
||||
"ExpectToSupply",
|
||||
"WillSupply",
|
||||
"Loaned",
|
||||
"Overdue",
|
||||
"Recalled",
|
||||
"RetryPossible",
|
||||
"Unfilled",
|
||||
"HoldReturn",
|
||||
"ReleaseHoldReturn",
|
||||
"CopyCompleted",
|
||||
"LoanCompleted",
|
||||
"CompletedWithoutReturn",
|
||||
"Cancelled",
|
||||
],
|
||||
},
|
||||
is_nullable => 1,
|
||||
},
|
||||
"service_type",
|
||||
{
|
||||
data_type => "enum",
|
||||
extra => { list => ["Copy", "Loan", "CopyOrLoan"] },
|
||||
is_nullable => 0,
|
||||
},
|
||||
"pending_requesting_agency_action",
|
||||
{
|
||||
data_type => "enum",
|
||||
extra => { list => ["Cancel", "Renew"] },
|
||||
is_nullable => 1,
|
||||
},
|
||||
);
|
||||
|
||||
=head1 PRIMARY KEY
|
||||
|
||||
=over 4
|
||||
|
||||
=item * L</iso18626_request_id>
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->set_primary_key("iso18626_request_id");
|
||||
|
||||
=head1 RELATIONS
|
||||
|
||||
=head2 iso18626_messages
|
||||
|
||||
Type: has_many
|
||||
|
||||
Related object: L<Koha::Schema::Result::Iso18626Message>
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->has_many(
|
||||
"iso18626_messages",
|
||||
"Koha::Schema::Result::Iso18626Message",
|
||||
{ "foreign.iso18626_request_id" => "self.iso18626_request_id" },
|
||||
{ cascade_copy => 0, cascade_delete => 0 },
|
||||
);
|
||||
|
||||
=head2 iso18626_requesting_agency
|
||||
|
||||
Type: belongs_to
|
||||
|
||||
Related object: L<Koha::Schema::Result::Iso18626RequestingAgency>
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
"iso18626_requesting_agency",
|
||||
"Koha::Schema::Result::Iso18626RequestingAgency",
|
||||
{
|
||||
iso18626_requesting_agency_id => "iso18626_requesting_agency_id",
|
||||
},
|
||||
{ is_deferrable => 1, on_delete => "RESTRICT", on_update => "CASCADE" },
|
||||
);
|
||||
|
||||
=head2 old_reserve
|
||||
|
||||
Type: might_have
|
||||
|
||||
Related object: L<Koha::Schema::Result::OldReserve>
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->might_have(
|
||||
"old_reserve",
|
||||
"Koha::Schema::Result::OldReserve",
|
||||
{ "foreign.iso18626_request_id" => "self.iso18626_request_id" },
|
||||
{ cascade_copy => 0, cascade_delete => 0 },
|
||||
);
|
||||
|
||||
=head2 reserve
|
||||
|
||||
Type: might_have
|
||||
|
||||
Related object: L<Koha::Schema::Result::Reserve>
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->might_have(
|
||||
"reserve",
|
||||
"Koha::Schema::Result::Reserve",
|
||||
{ "foreign.iso18626_request_id" => "self.iso18626_request_id" },
|
||||
{ cascade_copy => 0, cascade_delete => 0 },
|
||||
);
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07051 @ 2026-03-04 14:57:44
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:T0PCb3b3SH9O7/f3TYDnTw
|
||||
|
||||
=head2 koha_object_class
|
||||
|
||||
Missing POD for koha_object_class.
|
||||
|
||||
=cut
|
||||
|
||||
sub koha_object_class {
|
||||
'Koha::ILL::ISO18626::Request';
|
||||
}
|
||||
|
||||
=head2 koha_objects_class
|
||||
|
||||
Missing POD for koha_objects_class.
|
||||
|
||||
=cut
|
||||
|
||||
sub koha_objects_class {
|
||||
'Koha::ILL::ISO18626::Requests';
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
@ -0,0 +1,206 @@
|
|||
use utf8;
|
||||
package Koha::Schema::Result::Iso18626RequestingAgency;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Koha::Schema::Result::Iso18626RequestingAgency
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
|
||||
=head1 TABLE: C<iso18626_requesting_agencies>
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->table("iso18626_requesting_agencies");
|
||||
|
||||
=head1 ACCESSORS
|
||||
|
||||
=head2 iso18626_requesting_agency_id
|
||||
|
||||
data_type: 'integer'
|
||||
is_auto_increment: 1
|
||||
is_nullable: 0
|
||||
|
||||
Internal requesting agency number
|
||||
|
||||
=head2 name
|
||||
|
||||
data_type: 'varchar'
|
||||
is_nullable: 1
|
||||
size: 80
|
||||
|
||||
Requesting agency name
|
||||
|
||||
=head2 borrowernumber
|
||||
|
||||
data_type: 'integer'
|
||||
is_foreign_key: 1
|
||||
is_nullable: 0
|
||||
|
||||
foreign key, linking this to the borrowers table (ILL partner patron)
|
||||
|
||||
=head2 type
|
||||
|
||||
data_type: 'enum'
|
||||
extra: {list => ["DNUCNI","ICOLC","ISIL"]}
|
||||
is_nullable: 0
|
||||
|
||||
ISO18626 agency type
|
||||
|
||||
=head2 account_id
|
||||
|
||||
data_type: 'varchar'
|
||||
is_nullable: 0
|
||||
size: 80
|
||||
|
||||
Authentication: Requesting agency account ID
|
||||
|
||||
=head2 securityCode
|
||||
|
||||
accessor: 'security_code'
|
||||
data_type: 'varchar'
|
||||
is_nullable: 0
|
||||
size: 80
|
||||
|
||||
Authentication: Requesting agency security code
|
||||
|
||||
=head2 callback_endpoint
|
||||
|
||||
data_type: 'mediumtext'
|
||||
is_nullable: 0
|
||||
|
||||
Callback endpoint to send messages back to
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->add_columns(
|
||||
"iso18626_requesting_agency_id",
|
||||
{ data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
|
||||
"name",
|
||||
{ data_type => "varchar", is_nullable => 1, size => 80 },
|
||||
"borrowernumber",
|
||||
{ data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
|
||||
"type",
|
||||
{
|
||||
data_type => "enum",
|
||||
extra => { list => ["DNUCNI", "ICOLC", "ISIL"] },
|
||||
is_nullable => 0,
|
||||
},
|
||||
"account_id",
|
||||
{ data_type => "varchar", is_nullable => 0, size => 80 },
|
||||
"securityCode",
|
||||
{
|
||||
accessor => "security_code",
|
||||
data_type => "varchar",
|
||||
is_nullable => 0,
|
||||
size => 80,
|
||||
},
|
||||
"callback_endpoint",
|
||||
{ data_type => "mediumtext", is_nullable => 0 },
|
||||
);
|
||||
|
||||
=head1 PRIMARY KEY
|
||||
|
||||
=over 4
|
||||
|
||||
=item * L</iso18626_requesting_agency_id>
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->set_primary_key("iso18626_requesting_agency_id");
|
||||
|
||||
=head1 UNIQUE CONSTRAINTS
|
||||
|
||||
=head2 C<uniq_borrowernumber>
|
||||
|
||||
=over 4
|
||||
|
||||
=item * L</borrowernumber>
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->add_unique_constraint("uniq_borrowernumber", ["borrowernumber"]);
|
||||
|
||||
=head1 RELATIONS
|
||||
|
||||
=head2 borrowernumber
|
||||
|
||||
Type: belongs_to
|
||||
|
||||
Related object: L<Koha::Schema::Result::Borrower>
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
"borrowernumber",
|
||||
"Koha::Schema::Result::Borrower",
|
||||
{ borrowernumber => "borrowernumber" },
|
||||
{ is_deferrable => 1, on_delete => "RESTRICT", on_update => "CASCADE" },
|
||||
);
|
||||
|
||||
=head2 iso18626_requests
|
||||
|
||||
Type: has_many
|
||||
|
||||
Related object: L<Koha::Schema::Result::Iso18626Request>
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->has_many(
|
||||
"iso18626_requests",
|
||||
"Koha::Schema::Result::Iso18626Request",
|
||||
{
|
||||
"foreign.iso18626_requesting_agency_id" => "self.iso18626_requesting_agency_id",
|
||||
},
|
||||
{ cascade_copy => 0, cascade_delete => 0 },
|
||||
);
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07051 @ 2026-01-21 12:22:43
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:vqPIA624r/PznpUwlK2FBg
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
"patron",
|
||||
"Koha::Schema::Result::Borrower",
|
||||
{ borrowernumber => "borrowernumber" },
|
||||
{
|
||||
is_deferrable => 1,
|
||||
join_type => "LEFT",
|
||||
on_delete => "CASCADE",
|
||||
on_update => "CASCADE",
|
||||
},
|
||||
);
|
||||
|
||||
=head2 koha_object_class
|
||||
|
||||
Missing POD for koha_object_class.
|
||||
|
||||
=cut
|
||||
|
||||
sub koha_object_class {
|
||||
'Koha::ILL::ISO18626::RequestingAgency';
|
||||
}
|
||||
|
||||
=head2 koha_objects_class
|
||||
|
||||
Missing POD for koha_objects_class.
|
||||
|
||||
=cut
|
||||
|
||||
sub koha_objects_class {
|
||||
'Koha::ILL::ISO18626::RequestingAgencies';
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
---
|
||||
type: object
|
||||
properties:
|
||||
iso18626_request_id:
|
||||
type: integer
|
||||
description: Internal ILL request identifier
|
||||
supplyingAgencyId:
|
||||
type:
|
||||
- string
|
||||
- "null"
|
||||
description: Internal supplying agency identifier
|
||||
status:
|
||||
type: string
|
||||
description: ISO18626 request status
|
||||
service_type:
|
||||
description: ISO18626 request service type
|
||||
$ref: "../definitions/ISO18626/types/serviceType.yaml"
|
||||
pending_requesting_agency_action:
|
||||
type:
|
||||
- string
|
||||
- "null"
|
||||
enum:
|
||||
- Cancel
|
||||
- Renew
|
||||
- null
|
||||
description: Requesting Agency action that requires an action from the supplying agency
|
||||
created_on:
|
||||
type:
|
||||
- string
|
||||
- "null"
|
||||
format: date-time
|
||||
description: Date and time the request was created
|
||||
updated_on:
|
||||
type:
|
||||
- string
|
||||
- "null"
|
||||
format: date-time
|
||||
description: Date and time the request was last updated
|
||||
requestingAgencyRequestId:
|
||||
type: string
|
||||
description: Requesting agency request ID or number
|
||||
iso18626_requesting_agency_id:
|
||||
type: integer
|
||||
description: Associated ISO18626 requesting agency internal identifier
|
||||
requesting_agency:
|
||||
type:
|
||||
- object
|
||||
- "null"
|
||||
description: Embeded object
|
||||
messages:
|
||||
type:
|
||||
- array
|
||||
- "null"
|
||||
description: The linked messages (x-koha-embed)
|
||||
required:
|
||||
- service_type
|
||||
- status
|
||||
additionalProperties: false
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
---
|
||||
type: object
|
||||
properties:
|
||||
iso18626_requesting_agency_id:
|
||||
type: integer
|
||||
description: Internal requesting agency number
|
||||
readOnly: true
|
||||
name:
|
||||
type: string
|
||||
description: Requesting agency name
|
||||
patron_id:
|
||||
type:
|
||||
- integer
|
||||
- "null"
|
||||
description: Internal patron id
|
||||
type:
|
||||
type: string
|
||||
enum:
|
||||
- DNUCNI # Danish National Union Catalogue Non-ISIL Identifier
|
||||
- ICOLC # https://icolc.net/consortia
|
||||
- ISIL # ISO 15511
|
||||
description: ISO18626 requesting agency type
|
||||
account_id:
|
||||
type: string
|
||||
description: 'Authentication: Requesting agency account ID'
|
||||
securityCode:
|
||||
type: string
|
||||
description: 'Authentication: Requesting agency security code'
|
||||
callback_endpoint:
|
||||
type: string
|
||||
description: Callback endpoint to send messages back to
|
||||
ill_partner:
|
||||
description: ILL partner patron object
|
||||
type:
|
||||
- object
|
||||
- "null"
|
||||
required:
|
||||
- iso18626_requesting_agency_id
|
||||
- name
|
||||
- type
|
||||
- account_id
|
||||
- securityCode
|
||||
- callback_endpoint
|
||||
additionalProperties: false
|
||||
|
|
@ -0,0 +1,281 @@
|
|||
---
|
||||
/ill/iso18626_requesting_agencies:
|
||||
get:
|
||||
x-mojo-to: ILL::ISO18626::RequestingAgencies#list
|
||||
operationId: listIso18626IllrequestingAgencies
|
||||
tags:
|
||||
- iso18626_requesting_agencies
|
||||
summary: List ISO18626 ILL requesting agencies
|
||||
parameters:
|
||||
- name: x-koha-embed
|
||||
in: header
|
||||
required: false
|
||||
description: Embed list sent as a request header
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
enum:
|
||||
- ill_partner
|
||||
- $ref: "../swagger.yaml#/parameters/page"
|
||||
- $ref: "../swagger.yaml#/parameters/per_page"
|
||||
- $ref: "../swagger.yaml#/parameters/match"
|
||||
- $ref: "../swagger.yaml#/parameters/order_by"
|
||||
- $ref: "../swagger.yaml#/parameters/q_param"
|
||||
- $ref: "../swagger.yaml#/parameters/q_body"
|
||||
- $ref: "../swagger.yaml#/parameters/request_id_header"
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: A list of ISO18626 ILL requesting agencies
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "../swagger.yaml#/definitions/iso18626_requesting_agency"
|
||||
"400":
|
||||
description: |
|
||||
Bad request. Possible `error_code` attribute values:
|
||||
|
||||
* `invalid_query`
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"403":
|
||||
description: Access forbidden
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"404":
|
||||
description: Patron 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: ILL::ISO18626::RequestingAgencies#add
|
||||
operationId: addIso18626IllrequestingAgencies
|
||||
tags:
|
||||
- iso18626_requesting_agencies
|
||||
summary: Add ISO18626 requesting agency
|
||||
consumes:
|
||||
- application/json
|
||||
produces:
|
||||
- application/json
|
||||
parameters:
|
||||
- description: A JSON object containing information about the new requesting agency
|
||||
in: body
|
||||
name: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/iso18626_requesting_agency"
|
||||
responses:
|
||||
201:
|
||||
description: A successfully created ISO18626 requesting agency
|
||||
schema:
|
||||
items:
|
||||
$ref: "../swagger.yaml#/definitions/iso18626_requesting_agency"
|
||||
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: Ressource not found
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
409:
|
||||
description: Conflict in creating resource
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
413:
|
||||
description: Payload too large
|
||||
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
|
||||
|
||||
/ill/iso18626_requesting_agencies/{iso18626_requesting_agency_id}:
|
||||
get:
|
||||
x-mojo-to: ILL::ISO18626::RequestingAgencies#get
|
||||
operationId: getIso18626IllrequestingAgency
|
||||
tags:
|
||||
- iso18626_requesting_agencies
|
||||
summary: Retrieve a single ISO18626 ILL requesting agency
|
||||
parameters:
|
||||
- name: x-koha-embed
|
||||
in: header
|
||||
required: false
|
||||
description: Embed list sent as a request header
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
enum:
|
||||
- ill_partner
|
||||
- $ref: "../swagger.yaml#/parameters/iso18626_requesting_agency_id_pp"
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: A single ISO18626 ILL requesting agency
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/iso18626_requesting_agency"
|
||||
"400":
|
||||
description: |
|
||||
Bad request. Possible `error_code` attribute values:
|
||||
|
||||
* `invalid_query`
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"403":
|
||||
description: Access forbidden
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"404":
|
||||
description: Patron 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: ILL::ISO18626::RequestingAgencies#update
|
||||
operationId: updateIso18626IllrequestingAgency
|
||||
tags:
|
||||
- iso18626_requesting_agencies
|
||||
summary: Update ISO18626 ILL requesting agency
|
||||
consumes:
|
||||
- application/json
|
||||
produces:
|
||||
- application/json
|
||||
parameters:
|
||||
- $ref: "../swagger.yaml#/parameters/iso18626_requesting_agency_id_pp"
|
||||
- name: body
|
||||
in: body
|
||||
description: A JSON object containing new information about existing ISO18626 ILL requesting agency
|
||||
required: true
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/iso18626_requesting_agency"
|
||||
responses:
|
||||
200:
|
||||
description: A successfully updated ISO18626 ILL requesting agency
|
||||
schema:
|
||||
items:
|
||||
$ref: "../swagger.yaml#/definitions/iso18626_requesting_agency"
|
||||
400:
|
||||
description: Bad request
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
403:
|
||||
description: Access forbidden
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
404:
|
||||
description: Ressource not found
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
409:
|
||||
description: Conflict in updating resource
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
413:
|
||||
description: Payload too large
|
||||
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:
|
||||
erm: 1
|
||||
delete:
|
||||
x-mojo-to: ILL::ISO18626::RequestingAgencies#delete
|
||||
operationId: deleteIso18626IllrequestingAgency
|
||||
tags:
|
||||
- iso18626_requesting_agencies
|
||||
summary: Delete ISO18626 ILL requesting agency
|
||||
produces:
|
||||
- application/json
|
||||
parameters:
|
||||
- $ref: "../swagger.yaml#/parameters/iso18626_requesting_agency_id_pp"
|
||||
responses:
|
||||
204:
|
||||
description: ISO18626 ILL requesting agency deleted
|
||||
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: Ressource not found
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
409:
|
||||
description: Conflict in deleting 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:
|
||||
erm: 1
|
||||
|
|
@ -0,0 +1,185 @@
|
|||
---
|
||||
/ill/iso18626_requests:
|
||||
get:
|
||||
x-mojo-to: ILL::ISO18626::Requests#list
|
||||
operationId: listIso18626Illrequests
|
||||
tags:
|
||||
- iso18626_requests
|
||||
summary: List ISO18626 ILL requests
|
||||
parameters:
|
||||
- $ref: "../swagger.yaml#/parameters/page"
|
||||
- $ref: "../swagger.yaml#/parameters/per_page"
|
||||
- $ref: "../swagger.yaml#/parameters/match"
|
||||
- $ref: "../swagger.yaml#/parameters/order_by"
|
||||
- $ref: "../swagger.yaml#/parameters/q_param"
|
||||
- $ref: "../swagger.yaml#/parameters/q_body"
|
||||
- $ref: "../swagger.yaml#/parameters/request_id_header"
|
||||
- name: x-koha-embed
|
||||
in: header
|
||||
required: false
|
||||
description: Embed list sent as a request header
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
enum:
|
||||
- messages
|
||||
- requesting_agency
|
||||
collectionFormat: csv
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: A list of ISO18626 ILL requests
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "../swagger.yaml#/definitions/iso18626_request"
|
||||
"400":
|
||||
description: |
|
||||
Bad request. Possible `error_code` attribute values:
|
||||
|
||||
* `invalid_query`
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"403":
|
||||
description: Access forbidden
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"404":
|
||||
description: Patron 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"
|
||||
|
||||
/ill/iso18626_requests/{iso18626_request_id}:
|
||||
get:
|
||||
x-mojo-to: ILL::ISO18626::Requests#get
|
||||
operationId: getIso18626Illrequest
|
||||
tags:
|
||||
- iso18626_requests
|
||||
summary: Retrieve a single ISO18626 ILL request
|
||||
parameters:
|
||||
- $ref: "../swagger.yaml#/parameters/iso18626_request_id_pp"
|
||||
- name: x-koha-embed
|
||||
in: header
|
||||
required: false
|
||||
description: Embed list sent as a request header
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
enum:
|
||||
- messages
|
||||
- requesting_agency
|
||||
collectionFormat: csv
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: A single ISO18626 ILL request
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/iso18626_request"
|
||||
"400":
|
||||
description: |
|
||||
Bad request. Possible `error_code` attribute values:
|
||||
|
||||
* `invalid_query`
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"403":
|
||||
description: Access forbidden
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"404":
|
||||
description: Patron 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"
|
||||
patch:
|
||||
x-mojo-to: ILL::ISO18626::Requests#edit
|
||||
operationId: editIso18626Illrequest
|
||||
tags:
|
||||
- iso18626_requests
|
||||
summary: Edit a single ISO18626 ILL request
|
||||
produces:
|
||||
- application/json
|
||||
parameters:
|
||||
- description: A JSON object containing the new status
|
||||
in: body
|
||||
name: status
|
||||
required: true
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
status:
|
||||
description: The status of the ISO18626 request
|
||||
$ref: "../definitions/ISO18626/types/status.yaml"
|
||||
answerYesNo:
|
||||
description: The answerYesNo of the ISO18626 request
|
||||
$ref: "../definitions/ISO18626/types/yesNo.yaml"
|
||||
messageInfoNote:
|
||||
description: The messageInfo note of the ISO18626 request
|
||||
type:
|
||||
- string
|
||||
- "null"
|
||||
additionalProperties: false
|
||||
- $ref: "../swagger.yaml#/parameters/iso18626_request_id_pp"
|
||||
responses:
|
||||
200:
|
||||
description: The ISO18626 ILL request that was updated
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/iso18626_request"
|
||||
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: Package 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
|
||||
|
|
@ -120,6 +120,10 @@ definitions:
|
|||
$ref: ./definitions/ill_batchstatus.yaml
|
||||
ill_batchstatuses:
|
||||
$ref: ./definitions/ill_batchstatuses.yaml
|
||||
iso18626_request:
|
||||
$ref: ./definitions/iso18626_request.yaml
|
||||
iso18626_requesting_agency:
|
||||
$ref: ./definitions/iso18626_requesting_agency.yaml
|
||||
ISO18626request:
|
||||
$ref: ./definitions/ISO18626/request.yaml
|
||||
ISO18626requestingAgencyMessage:
|
||||
|
|
@ -471,6 +475,14 @@ paths:
|
|||
$ref: ./paths/ill_backends.yaml#/~1ill~1backends
|
||||
"/ill/backends/{ill_backend_id}":
|
||||
$ref: "./paths/ill_backends.yaml#/~1ill~1backends~1{ill_backend_id}"
|
||||
/ill/iso18626_requests:
|
||||
$ref: ./paths/ill_iso18626_requests.yaml#/~1ill~1iso18626_requests
|
||||
"/ill/iso18626_requests/{iso18626_request_id}":
|
||||
$ref: ./paths/ill_iso18626_requests.yaml#/~1ill~1iso18626_requests~1{iso18626_request_id}
|
||||
/ill/iso18626_requesting_agencies:
|
||||
$ref: ./paths/ill_iso18626_requesting_agencies.yaml#/~1ill~1iso18626_requesting_agencies
|
||||
"/ill/iso18626_requesting_agencies/{iso18626_requesting_agency_id}":
|
||||
$ref: ./paths/ill_iso18626_requesting_agencies.yaml#/~1ill~1iso18626_requesting_agencies~1{iso18626_requesting_agency_id}
|
||||
/ill/requests:
|
||||
$ref: ./paths/ill_requests.yaml#/~1ill~1requests
|
||||
/ill/batches:
|
||||
|
|
@ -887,6 +899,12 @@ parameters:
|
|||
name: iso18626_request_id
|
||||
required: true
|
||||
type: integer
|
||||
iso18626_requesting_agency_id_pp:
|
||||
description: ISO18626 ILL requesting agency internal identifier
|
||||
in: path
|
||||
name: iso18626_requesting_agency_id
|
||||
required: true
|
||||
type: integer
|
||||
import_batch_profile_id_pp:
|
||||
description: Internal profile identifier
|
||||
in: path
|
||||
|
|
|
|||
Loading…
Reference in New Issue