Transit minimum checkin interval setting
authorBill Erickson <berick@esilibrary.com>
Thu, 9 Jun 2011 14:03:10 +0000 (10:03 -0400)
committerJason Etheridge <jason@esilibrary.com>
Thu, 9 Jun 2011 17:30:32 +0000 (13:30 -0400)
OK, here's the situation, a copy went away on a week's vacation...

Support for preventing checkin of a copy that was put into transit "too
recently".  The scenario that prompted the development is this:

Copy at Branch A is checked in and put into transit to fill a hold at
Branch B.  The copy is then accidentally checked in at Branch B.
(Imagine a crate of items with a superbarcode gets checked in at
Branch B and the copy in question was presumed to be in that crate).
This puts the item on the holds shelf (assuming a hold transit) at
Branch B and notifies the patrom the item is ready for pickup.
However, the copy is still just embarking from Branch A.

This new setting allows libraries to configure a minimum transit time.
If a copy is put into transit and checked in during the configured
interval, the checkin will return an (overridable) event that prevents
checkin.  If the setting is not configured, this has no affect on
checkin.

Signed-off-by: Bill Erickson <berick@esilibrary.com>
Signed-off-by: Jason Etheridge <jason@esilibrary.com>
Open-ILS/src/extras/ils_events.xml
Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm
Open-ILS/src/sql/Pg/950.data.seed-values.sql
Open-ILS/xul/staff_client/server/circ/util.js

index 96021e6..0eb3f8a 100644 (file)
         <desc xml:lang="en-US">Units cannot be created for the given item because its associated distribution does not have a call number.</desc>
     </event>
 
+    <event code='11103' textcode='TRANSIT_CHECKIN_INTERVAL_BLOCK'>
+        <desc xml:lang="en-US">Checkin attempted on item during minimum transit checkin interval.</desc>
+    </event>
+
        <!-- ================================================================ -->
 
 </ils_events>
index 1479c1f..4d65617 100644 (file)
@@ -2206,6 +2206,34 @@ sub checkout_noncat {
    }
 }
 
+# If a copy goes into transit and is then checked in before the transit checkin 
+# interval has expired, push an event onto the overridable events list.
+sub check_transit_checkin_interval {
+    my $self = shift;
+
+    # only concerned with in-transit items
+    return unless $U->copy_status($self->copy->status)->id == OILS_COPY_STATUS_IN_TRANSIT;
+
+    # no interval, no problem
+    my $interval = $U->ou_ancestor_setting_value($self->circ_lib, 'circ.transit.min_checkin_interval');
+    return unless $interval;
+
+    # capture the transit so we don't have to fetch it again later during checkin
+    $self->transit(
+        $self->editor->search_action_transit_copy(
+            {target_copy => $self->copy->id, dest_recv_time => undef}
+        )->[0]
+    ); 
+
+    my $seconds = OpenSRF::Utils->interval_to_seconds($interval);
+    my $t_start = DateTime::Format::ISO8601->new->parse_datetime(cleanse_ISO8601($self->transit->source_send_time));
+    my $horizon = $t_start->add(seconds => $seconds);
+
+    # See if we are still within the transit checkin forbidden range
+    $self->push_events(OpenILS::Event->new('TRANSIT_CHECKIN_INTERVAL_BLOCK')) 
+        if $horizon > DateTime->now;
+}
+
 
 sub do_checkin {
     my $self = shift;
@@ -2215,6 +2243,8 @@ sub do_checkin {
         OpenILS::Event->new('ASSET_COPY_NOT_FOUND')) 
         unless $self->copy;
 
+    $self->check_transit_checkin_interval;
+
     # the renew code and mk_env should have already found our circulation object
     unless( $self->circ ) {
 
@@ -2257,7 +2287,7 @@ sub do_checkin {
     $self->override_events unless $self->is_renewal;
     return if $self->bail_out;
     
-    if( $self->copy ) {
+    if( $self->copy and !$self->transit ) {
         $self->transit(
             $self->editor->search_action_transit_copy(
                 { target_copy => $self->copy->id, dest_recv_time => undef }
index e5db758..0e73ad2 100644 (file)
@@ -1427,6 +1427,8 @@ INSERT INTO permission.perm_list ( id, code, description ) VALUES
     'Allows a user to abort a transit on a copy with status of LOST', 'ppl', 'description')),
  ( 508, 'ABORT_TRANSIT_ON_MISSING', oils_i18n_gettext(508,
     'Allows a user to abort a transit on a copy with status of MISSING', 'ppl', 'description'));
+ ( 509, 'TRANSIT_CHECKIN_INTERVAL_BLOCK.override', oils_i18n_gettext(509,
+    'Allows a user to override the TRANSIT_CHECKIN_INTERVAL_BLOCK event', 'ppl', 'description'));
 
 
 SELECT SETVAL('permission.perm_list_id_seq'::TEXT, 1000);
@@ -1986,6 +1988,7 @@ INSERT INTO permission.grp_perm_map (grp, perm, depth, grantable)
                        'VIEW_REPORT_OUTPUT',
                        'VIEW_STANDING_PENALTY',
                        'VOID_BILLING',
+            'TRANSIT_CHECKIN_INTERVAL_BLOCK.override',
                        'VOLUME_HOLDS');
 
 
@@ -8707,3 +8710,21 @@ INSERT INTO config.usr_setting_type
   oils_i18n_gettext('circ.collections.exempt', 'User is exempt from collections tracking/processing', 'cust', 'description'),
   'bool'
 );
+
+INSERT INTO config.org_unit_setting_type ( name, label, description, datatype ) VALUES (
+    'circ.transit.min_checkin_interval',
+    oils_i18n_gettext( 
+        'circ.transit.min_checkin_interval', 
+        'Circ:  Minimum Transit Checkin Interval',
+        'coust',
+        'label'
+    ),
+    oils_i18n_gettext( 
+        'circ.transit.min_checkin_interval', 
+        'In-Transit items checked in this close to the transit start time will be prevented from checking in',
+        'coust',
+        'label'
+    ),
+    'interval'
+);
+
index 5351da1..64c4279 100644 (file)
@@ -2662,7 +2662,8 @@ circ.util.checkin_via_barcode = function(session,params,backdate,auto_print,asyn
                     7010 /* COPY_ALERT_MESSAGE */,
                     7011 /* COPY_STATUS_LOST */,
                     7012 /* COPY_STATUS_MISSING */,
-                    7013 /* PATRON_EXCEEDS_FINES */
+                    7013 /* PATRON_EXCEEDS_FINES */,
+                    11103 /* TRANSIT_CHECKIN_INTERVAL_BLOCK */ 
                 ],
                 'text' : {
                     '1203' : function(r) {