Option to generate lacking overdues on lost checkin
authorBill Erickson <berick@esilibrary.com>
Fri, 24 Jun 2011 15:27:26 +0000 (11:27 -0400)
committerMike Rylander <mrylander@gmail.com>
Mon, 27 Jun 2011 17:54:26 +0000 (13:54 -0400)
New org unit setting "circ.lost.generate_overdue_on_checkin".

This org unit setting enables retroactive overdue fine generation for
lost item checkin.  When enabled, the system will generate overdue fines
starting from the date of the last created overdue fine for the
circulation and working its way up to the checkin time or stopping at
the max fine amount (consistent with regular overdue fine generation).

This differs from the existing org unit setting
"circ.restore_overdue_on_lost_return", which only un-voids existing
overdue fines.

Consider an item whose due date is the 1st, that gets marked lost on the
7th, then checked in on the 14th.  If set,
"circ.restore_overdue_on_lost_return" would un-void the fines created up
to the 7th and "circ.lost.generate_overdue_on_checkin" would create new
overdue fines from the 7th up to the 14th (or up to the max fine
amount).

Signed-off-by: Bill Erickson <berick@esilibrary.com>
Signed-off-by: Mike Rylander <mrylander@gmail.com>

Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm
Open-ILS/src/perlmods/lib/OpenILS/Const.pm
Open-ILS/src/sql/Pg/950.data.seed-values.sql

index 4d65617..0b36f40 100644 (file)
@@ -342,20 +342,31 @@ sub run_method {
         $circulator->editor->rollback;
 
     } else {
+
         $circulator->editor->commit;
-    }
 
-    $circulator->script_runner->cleanup if $circulator->script_runner;
+        if ($circulator->generate_lost_overdue) {
+            # Generating additional overdue billings has to happen after the 
+            # main commit and before the final respond() so the caller can
+            # receive the latest transaction summary.
+            my $evt = $circulator->generate_lost_overdue_fines;
+            $circulator->bail_on_events($evt) if $evt;
+        }
+    }
     
     $conn->respond_complete(circ_events($circulator));
 
-    unless($circulator->bail_out) {
-        $circulator->do_hold_notify($circulator->notify_hold)
-            if $circulator->notify_hold;
-        $circulator->retarget_holds if $circulator->retarget;
-        $circulator->append_reading_list;
-        $circulator->make_trigger_events;
-    }
+    $circulator->script_runner->cleanup if $circulator->script_runner;
+
+    return undef if $circulator->bail_out;
+
+    $circulator->do_hold_notify($circulator->notify_hold)
+        if $circulator->notify_hold;
+    $circulator->retarget_holds if $circulator->retarget;
+    $circulator->append_reading_list;
+    $circulator->make_trigger_events;
+    
+    return undef;
 }
 
 sub circ_events {
@@ -522,6 +533,7 @@ my @AUTOLOAD_FIELDS = qw/
     skip_deposit_fee
     skip_rental_fee
     use_booking
+    generate_lost_overdue
 /;
 
 
@@ -3134,10 +3146,12 @@ sub checkin_handle_lost {
             $circ_lib, OILS_SETTING_VOID_LOST_PROCESS_FEE_ON_CHECKIN, $self->editor) || 0;
         my $restore_od = $U->ou_ancestor_setting_value(
             $circ_lib, OILS_SETTING_RESTORE_OVERDUE_ON_LOST_RETURN, $self->editor) || 0;
+        $self->generate_lost_overdue(1) if $U->ou_ancestor_setting_value(
+            $circ_lib, OILS_SETTING_GENERATE_OVERDUE_ON_LOST_RETURN, $self->editor);
 
         $self->checkin_handle_lost_now_found(3) if $void_lost;
         $self->checkin_handle_lost_now_found(4) if $void_lost_fee;
-        $self->checkin_handle_lost_now_found_restore_od() if $restore_od && ! $self->void_overdues;
+        $self->checkin_handle_lost_now_found_restore_od($circ_lib) if $restore_od && ! $self->void_overdues;
     }
 
     $self->copy->status($U->copy_status(OILS_COPY_STATUS_RESHELVING));
@@ -3486,6 +3500,7 @@ sub checkin_handle_lost_now_found {
 
 sub checkin_handle_lost_now_found_restore_od {
     my $self = shift;
+    my $circ_lib = shift;
 
     # ------------------------------------------------------------------
     # restore those overdue charges voided when item was set to lost
@@ -3514,4 +3529,58 @@ sub checkin_handle_lost_now_found_restore_od {
     }
 }
 
+# ------------------------------------------------------------------
+# Lost-then-found item checked in.  This sub generates new overdue
+# fines, beyond the point of any existing and possibly voided 
+# overdue fines, up to the point of final checkin time (or max fine
+# amount).  
+# ------------------------------------------------------------------
+sub generate_lost_overdue_fines {
+    my $self = shift;
+    my $circ = $self->circ;
+    my $e = $self->editor;
+
+    # Re-open the transaction so the fine generator can see it
+    if($circ->xact_finish or $circ->stop_fines) {
+        $e->xact_begin;
+        $circ->clear_xact_finish;
+        $circ->clear_stop_fines;
+        $circ->clear_stop_fines_time;
+        $e->update_action_circulation($circ) or return $e->die_event;
+        $e->xact_commit;
+    }
+
+    $e->xact_begin; # generate_fines expects an in-xact editor
+    $self->generate_fines;
+    $circ = $self->circ; # generate fines re-fetches the circ
+    
+    my $update = 0;
+
+    # Re-close the transaction if no money is owed
+    my ($obt) = $U->fetch_mbts($circ->id, $e);
+    if ($obt and $obt->balance_owed == 0) {
+        $circ->xact_finish('now');
+        $update = 1;
+    }
+
+    # Set stop fines if the fine generator didn't have to
+    unless($circ->stop_fines) {
+        $circ->stop_fines(OILS_STOP_FINES_CHECKIN);
+        $circ->stop_fines_time('now');
+        $update = 1;
+    }
+
+    # update the event data sent to the caller within the transaction
+    $self->checkin_flesh_events;
+
+    if ($update) {
+        $e->update_action_circulation($circ) or return $e->die_event;
+        $e->commit;
+    } else {
+        $e->rollback;
+    }
+
+    return undef;
+}
+
 1;
index 6da2ed6..f86a801 100644 (file)
@@ -91,6 +91,7 @@ econst OILS_SETTING_VOID_LOST_PROCESS_FEE_ON_CHECKIN    => 'circ.void_lost_proc_
 econst OILS_SETTING_RESTORE_OVERDUE_ON_LOST_RETURN      => 'circ.restore_overdue_on_lost_return';
 econst OILS_SETTING_LOST_IMMEDIATELY_AVAILABLE          => 'circ.lost_immediately_available';
 econst OILS_SETTING_BLOCK_HOLD_FOR_EXPIRED_PATRON       => 'circ.holds.expired_patron_block';
+econst OILS_SETTING_GENERATE_OVERDUE_ON_LOST_RETURN     => 'circ.lost.generate_overdue_on_checkin';
 
 
 
index dc036a9..279f2a4 100644 (file)
@@ -8788,3 +8788,19 @@ INSERT INTO action_trigger.environment (event_def, path) VALUES
     (38, 'bib_rec.bib_record.simple_record');
 
 
+INSERT INTO config.org_unit_setting_type ( name, label, description, datatype ) VALUES (
+    'circ.lost.generate_overdue_on_checkin',
+    oils_i18n_gettext( 
+        'circ.lost.generate_overdue_on_checkin',
+        'Circ:  Lost Checkin Generates New Overdues',
+        'coust',
+        'label'
+    ),
+    oils_i18n_gettext( 
+        'circ.lost.generate_overdue_on_checkin',
+        'Enabling this setting causes retroactive creation of not-yet-existing overdue fines on lost item checkin, up to the point of checkin time (or max fines is reached).  This is different than "restore overdue on lost", because it only creates new overdue fines.  Use both settings together to get the full complement of overdue fines for a lost item',
+        'coust',
+        'label'
+    ),
+    'bool'
+);