Offline checkin & renewal checks, & ou settings
authorJason Etheridge <jason@esilibrary.com>
Thu, 4 Aug 2011 02:32:51 +0000 (22:32 -0400)
committerMike Rylander <mrylander@gmail.com>
Tue, 9 Aug 2011 17:18:36 +0000 (13:18 -0400)
Augmented edoceo's patch for checking an offline checkout against an item's
Status Changed Time and throwing a SKIP_ASSET_CHANGED event if warranted as
follows:

1) include checkin and renewal transactions
2) add org unit settings for each, and a corresponding upgrade script
3) removed the description from the payload and created a dedicated ils_event

However, there are two issues affecting this functionality, even before my
meddling:

1) the Reshelving -> Available rollover updates an item's Status Changed Time,
   and can thus trigger this event
2) if an item is manipulated more than once in an offline session, then its
   Status Changed Time can be updated as the transactions are being processed,
   causing related transactions after the initial transaction to fail

Signed-off-by: Jason Etheridge <jason@esilibrary.com>
Signed-off-by: Mike Rylander <mrylander@gmail.com>
Open-ILS/src/extras/ils_events.xml
Open-ILS/src/offline/offline.pl
Open-ILS/src/sql/Pg/950.data.seed-values.sql
Open-ILS/src/sql/Pg/upgrade/XXXX.data.org-setting-circ.offline.skip_foo_if_newer_status_changed_time.sql [new file with mode: 0644]

index ee68f72..0297eff 100644 (file)
        <event code='8010' textcode='OFFLINE_SESSION_COMPLETE'>
                <desc xml:lang="en-US"> No org id was provided </desc>
        </event>
+       <event code='8011' textcode='SKIP_ASSET_CHANGED'>
+               <desc xml:lang="en-US"> Asset status was changed since the offline transaction was recorded</desc>
+       </event>
 
        <event code='9000' textcode='REPORT_TEMPLATE_EXISTS'>
                <desc xml:lang="en-US"> A report template with the given name and folder already exists</desc>
index d3f5de8..3ff9126 100755 (executable)
@@ -706,8 +706,16 @@ sub ol_handle_checkout {
         return $e if $e;
 
         my $barcode = $args->{barcode};
-        # Have to have this config option & a status_changed_time for skippage
-        if ( ($config{skip_late}) && (length($c->status_changed_time())) ) {
+        # Have to have this config option (or org setting) and a
+        # status_changed_time for skippage
+        if ((
+                ol_get_org_setting(
+                    'circ.offline.skip_checkout_if_newer_status_changed_time'
+                )
+                || $config{skip_late}
+            )
+            && length($c->status_changed_time())
+        ) {
             my $cts = DateTime::Format::ISO8601->parse_datetime( cleanse_ISO8601($c->status_changed_time()) )->epoch();
             my $xts = $command->{timestamp}; # Transaction Time Stamp
             $logger->activity("offline: ol_handle_checkout: barcode=$barcode, cts=$cts, xts=$xts");
@@ -715,8 +723,7 @@ sub ol_handle_checkout {
             # Asset has changed after this transaction, ignore
             if ($cts >= $xts) {
                 return OpenILS::Event->new(
-                    'SKIP_ASSET_CHANGED',
-                    payload => 'The Asset has been update since this transaction, so it will be ignored'
+                    'SKIP_ASSET_CHANGED'
                 );
             }
     #       $logger->activity("offline: fetch_copy_by_barcode: " . Dumper($c->real_fields()));
@@ -746,6 +753,38 @@ sub ol_handle_renew {
        my $command = shift;
        my $args = ol_circ_args_from_command($command);
        my $t = time;
+
+    if( $args->{barcode} ) {
+
+        # $c becomes the Copy
+        # $e possibily becomes the Exception
+        my( $c, $e ) = $U->fetch_copy_by_barcode($args->{barcode});
+        return $e if $e;
+
+        my $barcode = $args->{barcode};
+        # Have to have this config option (or org setting) and a
+        # status_changed_time for skippage
+        if ((
+                ol_get_org_setting(
+                    'circ.offline.skip_renew_if_newer_status_changed_time'
+                )
+                || $config{skip_late}
+            )
+            && length($c->status_changed_time())
+        ) {
+            my $cts = DateTime::Format::ISO8601->parse_datetime( cleanse_ISO8601($c->status_changed_time()) )->epoch();
+            my $xts = $command->{timestamp}; # Transaction Time Stamp
+            $logger->activity("offline: ol_handle_renew: barcode=$barcode, cts=$cts, xts=$xts");
+
+            # Asset has changed after this transaction, ignore
+            if ($cts >= $xts) {
+                return OpenILS::Event->new(
+                    'SKIP_ASSET_CHANGED'
+                );
+            }
+        }
+    }
+
        return $U->simplereq(
                'open-ils.circ', 'open-ils.circ.renew.override', $authtoken, $args );
 }
@@ -765,6 +804,36 @@ sub ol_handle_checkin {
        $logger->activity("offline: checkin : requestor=". $requestor->id.
                ", realtime=$realtime, ".  "workstation=$ws, barcode=$barcode, backdate=$backdate");
 
+    if( $barcode ) {
+
+        # $c becomes the Copy
+        # $e possibily becomes the Exception
+        my( $c, $e ) = $U->fetch_copy_by_barcode($barcode);
+        return $e if $e;
+
+        # Have to have this config option (or org setting) and a
+        # status_changed_time for skippage
+        if ((
+                ol_get_org_setting(
+                    'circ.offline.skip_checkin_if_newer_status_changed_time'
+                )
+                || $config{skip_late}
+            )
+            && length($c->status_changed_time())
+        ) {
+            my $cts = DateTime::Format::ISO8601->parse_datetime( cleanse_ISO8601($c->status_changed_time()) )->epoch();
+            my $xts = $command->{timestamp}; # Transaction Time Stamp
+            $logger->activity("offline: ol_handle_checkin: barcode=$barcode, cts=$cts, xts=$xts");
+
+            # Asset has changed after this transaction, ignore
+            if ($cts >= $xts) {
+                return OpenILS::Event->new(
+                    'SKIP_ASSET_CHANGED'
+                );
+            }
+        }
+    }
+
        return $U->simplereq(
                'open-ils.circ', 
                'open-ils.circ.checkin', $authtoken,
index 43f9634..29a4f90 100644 (file)
@@ -2783,6 +2783,63 @@ INSERT into config.org_unit_setting_type
         ),
         'bool'
     )
+,( 
+        'circ.offline.skip_checkout_if_newer_status_changed_time',
+        oils_i18n_gettext(
+            'circ.offline.skip_checkout_if_newer_status_changed_time',
+            'Offline: Skip offline checkout if newer item Status Changed Time.',
+            'coust',
+            'label'
+        ),
+        oils_i18n_gettext(
+            'circ.offline.skip_checkout_if_newer_status_changed_time',
+            'Skip offline checkout transaction (raise exception when'
+            || ' processing) if item Status Changed Time is newer than the'
+            || ' recorded transaction time.  WARNING: The Reshelving to'
+            || ' Available status rollover will trigger this.',
+            'coust',
+            'description'
+        ),
+        'bool'
+    )
+,( 
+        'circ.offline.skip_renew_if_newer_status_changed_time',
+        oils_i18n_gettext(
+            'circ.offline.skip_renew_if_newer_status_changed_time',
+            'Offline: Skip offline renewal if newer item Status Changed Time.',
+            'coust',
+            'label'
+        ),
+        oils_i18n_gettext(
+            'circ.offline.skip_renew_if_newer_status_changed_time',
+            'Skip offline renewal transaction (raise exception when'
+            || ' processing) if item Status Changed Time is newer than the'
+            || ' recorded transaction time.  WARNING: The Reshelving to'
+            || ' Available status rollover will trigger this.',
+            'coust',
+            'description'
+        ),
+        'bool'
+    )
+,( 
+        'circ.offline.skip_checkin_if_newer_status_changed_time',
+        oils_i18n_gettext(
+            'circ.offline.skip_checkin_if_newer_status_changed_time',
+            'Offline: Skip offline checkin if newer item Status Changed Time.',
+            'coust',
+            'label'
+        ),
+        oils_i18n_gettext(
+            'circ.offline.skip_checkin_if_newer_status_changed_time',
+            'Skip offline checkin transaction (raise exception when'
+            || ' processing) if item Status Changed Time is newer than the'
+            || ' recorded transaction time.  WARNING: The Reshelving to'
+            || ' Available status rollover will trigger this.',
+            'coust',
+            'description'
+        ),
+        'bool'
+    )
 ;
 
 UPDATE config.org_unit_setting_type
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.data.org-setting-circ.offline.skip_foo_if_newer_status_changed_time.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.data.org-setting-circ.offline.skip_foo_if_newer_status_changed_time.sql
new file mode 100644 (file)
index 0000000..0a68459
--- /dev/null
@@ -0,0 +1,69 @@
+-- Evergreen DB patch XXXX.data.org-setting-circ.offline.skip_foo_if_newer_status_changed_time.sql
+--
+-- New org setting circ.offline.skip_checkout_if_newer_status_changed_time
+-- New org setting circ.offline.skip_renew_if_newer_status_changed_time
+-- New org setting circ.offline.skip_checkin_if_newer_status_changed_time
+--
+BEGIN;
+
+-- check whether patch can be applied
+SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version);
+
+INSERT INTO config.org_unit_setting_type ( name, label, description, datatype ) 
+    VALUES ( 
+        'circ.offline.skip_checkout_if_newer_status_changed_time',
+        oils_i18n_gettext(
+            'circ.offline.skip_checkout_if_newer_status_changed_time',
+            'Offline: Skip offline checkout if newer item Status Changed Time.',
+            'coust',
+            'label'
+        ),
+        oils_i18n_gettext(
+            'circ.offline.skip_checkout_if_newer_status_changed_time',
+            'Skip offline checkout transaction (raise exception when'
+            || ' processing) if item Status Changed Time is newer than the'
+            || ' recorded transaction time.  WARNING: The Reshelving to'
+            || ' Available status rollover will trigger this.',
+            'coust',
+            'description'
+        ),
+        'bool'
+    ),( 
+        'circ.offline.skip_renew_if_newer_status_changed_time',
+        oils_i18n_gettext(
+            'circ.offline.skip_renew_if_newer_status_changed_time',
+            'Offline: Skip offline renewal if newer item Status Changed Time.',
+            'coust',
+            'label'
+        ),
+        oils_i18n_gettext(
+            'circ.offline.skip_renew_if_newer_status_changed_time',
+            'Skip offline renewal transaction (raise exception when'
+            || ' processing) if item Status Changed Time is newer than the'
+            || ' recorded transaction time.  WARNING: The Reshelving to'
+            || ' Available status rollover will trigger this.',
+            'coust',
+            'description'
+        ),
+        'bool'
+    ),( 
+        'circ.offline.skip_checkin_if_newer_status_changed_time',
+        oils_i18n_gettext(
+            'circ.offline.skip_checkin_if_newer_status_changed_time',
+            'Offline: Skip offline checkin if newer item Status Changed Time.',
+            'coust',
+            'label'
+        ),
+        oils_i18n_gettext(
+            'circ.offline.skip_checkin_if_newer_status_changed_time',
+            'Skip offline checkin transaction (raise exception when'
+            || ' processing) if item Status Changed Time is newer than the'
+            || ' recorded transaction time.  WARNING: The Reshelving to'
+            || ' Available status rollover will trigger this.',
+            'coust',
+            'description'
+        ),
+        'bool'
+    );
+
+COMMIT;