From 598dce281c1ca06ca18d2e0841ef64c33c67c95d Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Thu, 3 Sep 2020 15:41:36 -0400 Subject: [PATCH] migrating top sip2 service Signed-off-by: Bill Erickson --- .../src/perlmods/lib/OpenILS/Application/SIP2.pm | 184 ++++++++++++++++++++- .../lib/OpenILS/Application/SIP2/Common.pm | 6 +- .../perlmods/lib/OpenILS/Application/SIP2/Item.pm | 18 ++ .../lib/OpenILS/Application/SIP2/Session.pm | 20 ++- 4 files changed, 217 insertions(+), 11 deletions(-) diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/SIP2.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/SIP2.pm index e765d5b3f1..b7ce0b57f4 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/SIP2.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/SIP2.pm @@ -1,3 +1,21 @@ +# --------------------------------------------------------------- +# Copyright (C) 2020 King County Library System +# Bill Erickson +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# --------------------------------------------------------------- +# Code borrows heavily and sometimes copies directly from from +# ../SIP* and SIPServer* +# --------------------------------------------------------------- package OpenILS::Application::SIP2; use strict; use warnings; use base 'OpenILS::Application'; @@ -11,6 +29,7 @@ use OpenILS::Application::AppUtils; use OpenILS::Application::SIP2::Common; use OpenILS::Application::SIP2::Session; use OpenILS::Application::SIP2::Item; +use OpenILS::Application::SIP2::Patron; my $U = 'OpenILS::Application::AppUtils'; my $SC = 'OpenILS::Application::SIP2::Common'; @@ -55,9 +74,9 @@ sub dispatch_sip2_request { return OpenILS::Event->new('SIP2_SESSION_REQUIRED') unless $session; my $MESSAGE_MAP = { - '17' => &handle_item_info, - '23' => &handle_patron_status, - '63' => &handle_patron_info + '17' => \&handle_item_info, + '23' => \&handle_patron_status, + '63' => \&handle_patron_info }; return OpenILS::Event->new('SIP2_NOT_IMPLEMENTED', {payload => $message}) @@ -74,8 +93,8 @@ sub handle_login { # Default to login-failed my $response = {code => '94', fixed_fields => ['0']}; - my $sip_username = get_field_value($message, 'CN'); - my $sip_password = get_field_value($message, 'CO'); + my $sip_username = $SC->get_field_value($message, 'CN'); + my $sip_password = $SC->get_field_value($message, 'CO'); my $sip_account = $e->search_config_sip_account([ {sip_username => $sip_username, enabled => 't'}, {flesh => 1, flesh_fields => {csa => ['workstation']}} @@ -133,7 +152,7 @@ sub handle_sc_status { '2.00' # protocol_version ], fields => [ - {AO => $config->{id}}, + {AO => $config->{institution}}, {BX => join('', @{$config->{supports}})} ] } @@ -142,7 +161,7 @@ sub handle_sc_status { sub handle_item_info { my ($session, $message) = @_; - my $barcode = get_field_value($message, 'AB'); + my $barcode = $SC->get_field_value($message, 'AB'); my $config = $session->config; my $idetails = OpenILS::Application::SIP2::Item->get_item_details( @@ -187,6 +206,157 @@ sub handle_item_info { }; } +sub handle_patron_info { + my ($session, $message) = @_; + my $sip_account = $session->sip_account; + + my $barcode = get_field_value($message, 'AA'); + my $password = get_field_value($message, 'AD'); + + my $summary = + ref $message->{fixed_fields} ? $message->{fixed_fields}->[2] : ''; + + my $list_items = patron_summary_list_items($summary); + + my $pdetails = OpenILS::Application::SIP2::Patron->get_patron_details( + $session, + barcode => $barcode, + password => $password, + summary_start_item => $SC->get_field_value($message, 'BP'), + summary_end_item => $SC->get_field_value($message, 'BQ'), + summary_list_items => $list_items + ); + + my $response = patron_response_common_data( + $session, $barcode, $password, $pdetails); + + $response->{code} = '64'; + + return $response unless $pdetails; + + push( + @{$response->{fixed_fields}}, + count4($pdetails->{holds_count}), + count4($pdetails->{overdue_count}), + count4($pdetails->{out_count}), + count4($pdetails->{fine_count}), + count4($pdetails->{recall_count}), + count4($pdetails->{unavail_holds_count}) + ); + + # TODO: Add + # overdue items AT variable-length optional field (this field should be sent for each overdue item). + # charged items AU variable-length optional field (this field should be sent for each charged item). + # fine items AV variable-length optional field (this field should be sent for each fine item). + # recall items BU variable-length optional field (this field should be sent for each recall item). + # unavailable hold items CD variable-length optional field (this field should be sent for each unavailable hold item). + + if ($list_items eq 'hold_items') { + for my $hold (@{$pdetails->{hold_items}}) { + push(@{$response->{fields}}, {AS => $hold}); + } + } + + return $response; +} + +sub handle_patron_status { + my ($session, $message) = @_; + my $sip_account = $session->sip_account; + + my $barcode = $SC->get_field_value($message, 'AA'); + my $password = $SC->get_field_value($message, 'AD'); + + my $pdetails = OpenILS::Application::SIP2::Patron->get_patron_details( + $session, + barcode => $barcode, + password => $password + ); + + my $response = patron_response_common_data( + $session, $barcode, $password, $pdetails); + + $response->{code} = '24'; + + return $response; +} + +# Patron Info and Patron Status responses share mostly the same data. +# This returns the base data which can be augmented as needed. +# Note we don't call Patron->get_patron_details here since different +# messages collect different amounts of data. +sub patron_response_common_data { + my ($session, $barcode, $password, $pdetails) = @_; + + if (!$pdetails) { + # No such user. Return a stub response with all things denied. + + return { + fixed_fields => [ + $SC->spacebool(1), # charge denied + $SC->spacebool(1), # renew denied + $SC->spacebool(1), # recall denied + $SC->spacebool(1), # holds denied + split('', (' ' x 10)), + '000', # language + $SC->sipdate + ], + fields => [ + {AO => $session->config->{institution}}, + {AA => $barcode}, + {BL => $SC->sipbool(0)}, # valid patron + {CQ => $SC->sipbool(0)} # valid patron password + ] + }; + } + + return { + fixed_fields => [ + $SC->spacebool($pdetails->{charge_denied}), + $SC->spacebool($pdetails->{renew_denied}), + $SC->spacebool($pdetails->{recall_denied}), + $SC->spacebool($pdetails->{holds_denied}), + $SC->spacebool($pdetails->{patron}->card->active eq 'f'), + $SC->spacebool(0), # too many charged + $SC->spacebool($pdetails->{too_may_overdue}), + $SC->spacebool(0), # too many renewals + $SC->spacebool(0), # too many claims retruned + $SC->spacebool(0), # too many lost + $SC->spacebool($pdetails->{too_many_fines}), + $SC->spacebool($pdetails->{too_many_fines}), + $SC->spacebool(0), # recall overdue + $SC->spacebool($pdetails->{too_many_fines}), + '000', # language + $SC->sipdate + ], + fields => [ + {AO => $session->config->{institution}}, + {AA => $barcode}, + {BL => $SC->sipbool(1)}, # valid patron + {BV => $pdetails->{balance_owed}}, # fee amount + {CQ => $SC->sipbool($password)} # password verified if exists + ] + }; +} + +# Determines which class of data the SIP client wants detailed +# information on in the patron info request. +sub patron_summary_list_items { + my $summary = shift; + + my $idx = index($summary, 'Y'); + + return 'hold_items' if $idx == 0; + return 'overdue_items' if $idx == 1; + return 'charged_items' if $idx == 2; + return 'fine_items' if $idx == 3; + return 'recall_items' if $idx == 4; + return 'unavailable_holds' if $idx == 5; + return ''; +} + + + 1; diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/SIP2/Common.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/SIP2/Common.pm index 424fa52296..6ac3908718 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/SIP2/Common.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/SIP2/Common.pm @@ -17,19 +17,19 @@ sub sipbool { # False == ' ' sub spacebool { - my $bool = shift; + my ($class, $bool) = @_; return $bool ? 'Y' : ' '; } sub count4 { - my $value = shift; + my ($class, $value) = @_; return ' ' unless defined $value; return sprintf("%04d", $value); } # Returns the value of the first occurrence of the requested SIP code. sub get_field_value { - my ($message, $code) = @_; + my ($class, $message, $code) = @_; for my $field (@{$message->{fields}}) { while (my ($c, $v) = each(%$field)) { # one pair per field return $v if $c eq $code; diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/SIP2/Item.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/SIP2/Item.pm index 1def432981..f2b86542da 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/SIP2/Item.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/SIP2/Item.pm @@ -1,3 +1,21 @@ +# --------------------------------------------------------------- +# Copyright (C) 2020 King County Library System +# Bill Erickson +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# --------------------------------------------------------------- +# Code borrows heavily and sometimes copies directly from from +# ../SIP* and SIPServer* +# --------------------------------------------------------------- package OpenILS::Application::SIP2::Item; use strict; use warnings; use DateTime; diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/SIP2/Session.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/SIP2/Session.pm index 12f36bfd4e..8a237e72c5 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/SIP2/Session.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/SIP2/Session.pm @@ -1,3 +1,21 @@ +# --------------------------------------------------------------- +# Copyright (C) 2020 King County Library System +# Bill Erickson +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# --------------------------------------------------------------- +# Code borrows heavily and sometimes copies directly from from +# ../SIP* and SIPServer* +# --------------------------------------------------------------- package OpenILS::Application::SIPSession; use strict; use warnings; use JSON::XS; @@ -52,7 +70,7 @@ sub config { my $inst = $self->sip_account->institution; my $config = { - id => $inst, + institution => $inst, settings => { currency => 'USD' # TODO add db setting }, -- 2.11.0