package OpenILS::Application::SIP2;
use strict; use warnings;
use base 'OpenILS::Application';
+use DateTime;
+use DateTime::Format::ISO8601;
use OpenILS::Application;
use OpenILS::Event;
use OpenILS::Utils::Fieldmapper;
use OpenSRF::Utils::Logger qw(:logger);
use OpenILS::Utils::CStoreEditor qw/:funcs/;
use OpenILS::Application::AppUtils;
+use OpenILS::Utils::DateTime qw/:datetime/;
use OpenILS::Application::SIP2::Common;
use OpenILS::Application::SIP2::Session;
use OpenILS::Application::SIP2::Item;
use OpenILS::Application::SIP2::Patron;
+use OpenILS::Application::SIP2::Checkout;
my $U = 'OpenILS::Application::AppUtils';
my $SC = 'OpenILS::Application::SIP2::Common';
}
my $MESSAGE_MAP = {
+ '11' => \&handle_checkout,
'17' => \&handle_item_info,
'23' => \&handle_patron_status,
'63' => \&handle_patron_info,
};
}
+sub handle_checkout {
+ my ($session, $message) = @_;
+
+ my $patron_barcode = $SC->get_field_value($message, 'AA');
+ my $item_barcode = $SC->get_field_value($message, 'AB');
+ my $fee_ack = $SC->get_field_value($message, 'BO');
+ my $config = $session->config;
+
+ my $item_details = OpenILS::Application::SIP2::Item->get_item_details(
+ $session, barcode => $item_barcode
+ );
+
+ my $patron_details = OpenILS::Application::SIP2::Patron->get_patron_details(
+ $session, barcode => $patron_barcode
+ );
+
+ if (!$item_details || !$patron_details) { # bad data
+ return {
+ code => '12',
+ fixed_fields => [
+ 0, # checkout ok
+ $SC->sipbool(0), # renewal ok
+ $SC->sipbool(0), # magnetic media
+ $SC->sipbool(0), # desensitize
+ $SC->sipdate, # transaction date
+ ],
+ fields => [
+ {AA => $patron_barcode},
+ {AB => $item_barcode},
+ ]
+ };
+ }
+
+ my $circ_details = OpenILS::Application::SIP2::Checkout->checkout(
+ $session,
+ patron_barcode => $patron_barcode,
+ item_barcode => $item_barcode,
+ fee_ack => $fee_ack
+ );
+
+ use Data::Dumper;
+ $Data::Dumper::Indent = 0;
+ $logger->info("CHECKOUT RESULTED IN ".Dumper($circ_details));
+
+ my $magnetic = $item_details->{magnetic_media};
+ my $can_renew = 0;
+
+ my $circ = $circ_details->{circ};
+ if ($circ) {
+ $can_renew = !$patron_details->{renew_denied}
+ && $circ->renewal_remaining > 0;
+ }
+
+ my $response = {
+ code => '12',
+ fixed_fields => [
+ $circ ? 1 : 0, # checkout ok
+ $SC->sipbool($can_renew), # renewal ok
+ $SC->sipbool($magnetic), # magnetic media
+ $SC->sipbool(!$magnetic), # desensitize
+ $SC->sipdate, # transaction date
+ ],
+ fields => [
+ {AA => $patron_barcode},
+ {AB => $item_barcode},
+ {AJ => $item_details->{title}},
+ {AO => $config->{institution}},
+ {BT => $item_details->{fee_type}},
+ {CI => 0}, # security inhibit
+ {CK => $item_details->{media_type}}
+ ]
+ };
+
+ if ($circ) {
+ $SC->add_field($response, 'AH', $circ_details->{due_date});
+ $SC->add_field($response, 'BK', $circ->id);
+
+ $SC->maybe_add_field(
+ $response, 'BV', $item_details->{item}->deposit_amount);
+ }
+
+ $SC->maybe_add_field($response, 'AF', $circ_details->{screen_msg});
+
+ return $response;
+}
+
1;
--- /dev/null
+package OpenILS::Application::SIP2::Checkout;
+use strict; use warnings;
+use DateTime;
+use DateTime::Format::ISO8601;
+use OpenSRF::System;
+use OpenILS::Utils::CStoreEditor q/:funcs/;
+use OpenSRF::Utils::Logger q/$logger/;
+use OpenILS::Application::AppUtils;
+use OpenILS::Utils::DateTime qw/:datetime/;
+use OpenILS::Const qw/:const/;
+use OpenILS::Application::SIP2::Common;
+use OpenILS::Application::SIP2::Session;
+my $U = 'OpenILS::Application::AppUtils';
+my $SC = 'OpenILS::Application::SIP2::Common';
+
+
+# Returns the 'circ' object on success, undef on error.
+sub checkout {
+ my ($class, $session, %params) = @_;
+
+ my $circ_details = {};
+ my $override = 0;
+
+ for (0, 1) { # 2 checkout requests max
+
+ $override = $class->perform_checkout(
+ $session, $circ_details, $override, %params);
+
+ last unless $override;
+ }
+
+ return $circ_details;
+}
+
+# Returns 1 if the checkout should be performed again with override.
+# Returns 0 if there's nothing left to do (final success / error)
+# Updates $circ_details along the way.
+sub perform_checkout {
+ my ($class, $session, $circ_details, $override, %params) = @_;
+ my $config = $session->config;
+
+ my $args = {
+ copy_barcode => $params{item_barcode},
+ patron_barcode => $params{patron_barcode}
+ };
+
+ my $method = $params{is_renew} ?
+ 'open-ils.circ.renew' : 'open-ils.circ.checkout.full';
+
+ $method .= '.override' if $override;
+
+ my $resp = $U->simplereq(
+ 'open-ils.circ', $method, $session->editor->authtoken, $args);
+
+ $resp = [$resp] unless ref $resp eq 'ARRAY';
+
+ for my $event (@$resp) {
+ next unless $U->is_event($event); # this should never happen.
+ my $textcode = $event->{textcode};
+
+ if ($textcode eq 'SUCCESS' && $event->{payload}) {
+ if (my $circ = $event->{payload}->{circ}) {
+ $circ_details->{circ} = $circ;
+
+ my $due_date=
+ DateTime::Format::ISO8601->new
+ ->parse_datetime(clean_ISO8601($circ->due_date));
+
+ $circ_details->{due_date} =
+ $config->{due_date_use_sip_date_format} ?
+ $SC->sipdate($due_date) :
+ $due_date->strftime('%F %T');
+
+ return 0;
+ }
+ }
+
+ if (!$override) {
+ if ($config->{"checkout.override.$textcode"}) {
+ # Event type is configured for override;
+ return 1;
+
+ } elsif ($params{fee_ack} &&
+ $textcode =~ /ITEM_(?:DEPOSIT|RENTAL)_FEE_REQUIRED/ ) {
+ # Patron acknowledged the fee. Redo with override.
+ return 1;
+ }
+ }
+
+ if ($textcode eq 'OPEN_CIRCULATION_EXISTS' ) {
+ # TODO: messages
+ $circ_details->{screen_msg} = 'This item is already checked out';
+
+ } else {
+ $circ_details->{screen_msg} = # TODO messages
+ 'Patron is not allowed to check out the selected item';
+ }
+ }
+
+ return 0;
+}
+
+
+1;
return $_cache;
}
+sub add_field {
+ my ($class, $message, $field, $value) = @_;
+ $value = '' unless defined $value;
+ push (@{$message->{fields}}, {$field => $value});
+}
+
+sub maybe_add_field {
+ my ($class, $message, $field, $value) = @_;
+ push (@{$message->{fields}}, {$field => $value}) if defined $value;
+}
+
sub sipdate {
my ($class, $date) = @_;
$date ||= DateTime->now;
return undef unless $item;
- my $details = {item => $item};
+ my $details = {
+ item => $item,
+ security_marker => '02' # matches SIP/Item.pm
+ };
$details->{circ} = $e->search_action_circulation([{
target_copy => $item->id,
(SELECT id FROM config.sip_setting_group WHERE institution = 'example'),
'Patron holds data may be returned as either "title" or "barcode"',
'msg64_hold_items_available', '"title"'
+), (
+ (SELECT id FROM config.sip_setting_group WHERE institution = 'example'),
+ 'Checkout override copy alert message',
+ 'checkout.override.COPY_ALERT_MESSAGE', 'true'
+), (
+ (SELECT id FROM config.sip_setting_group WHERE institution = 'example'),
+ 'Checkin override copy alert message',
+ 'checkin.override.COPY_ALERT_MESSAGE', 'true'
+), (
+ (SELECT id FROM config.sip_setting_group WHERE institution = 'example'),
+ 'Checkin override bad copy status',
+ 'checkin.override.COPY_BAD_STATUS', 'true'
+), (
+ (SELECT id FROM config.sip_setting_group WHERE institution = 'example'),
+ 'Checkin override copy status missing',
+ 'checkin.override.COPY_STATUS_MISSING', 'true'
);
-
/* EXAMPLE SETTINGS