LP1331174_Long_Overdue_processing_needs_org_unit_settings
authorblake <blake@mobiusconsortium.org>
Mon, 10 Aug 2015 16:06:12 +0000 (11:06 -0500)
committerblake <blake@mobiusconsortium.org>
Tue, 7 Feb 2017 15:29:51 +0000 (09:29 -0600)
    Added two library settings.
    "Assess Billing When Marked Long-Overdue"
    Making it an option to bill patrons when marking LOD.
    "Continue Overdue Billing When Marked Long-Overdue"
    Allowing the system to continue to generate overdue fines
    after the circulation has been marked LONGOVERDUE.
    Altered the select query to respect that setting.
    Edited the query in fm_IDL so that Long overdues
    are still listed in the OPAC for the patrons even
    without billing. If there are bills, they are listed
    at the bottom under the fine category.

Signed-off-by: blake <blake@mobiusconsortium.org>
Conflicts:
Open-ILS/src/perlmods/lib/OpenILS/Application/Cat/AssetCommon.pm

Open-ILS/examples/fm_IDL.xml
Open-ILS/src/perlmods/lib/OpenILS/Application/Actor.pm
Open-ILS/src/perlmods/lib/OpenILS/Application/Cat/AssetCommon.pm
Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/action.pm
Open-ILS/src/perlmods/lib/OpenILS/Const.pm
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm
Open-ILS/src/sql/Pg/950.data.seed-values.sql
Open-ILS/src/sql/Pg/upgrade/XXXX.data.long-overdue-asses-fines-library-setting.sql [new file with mode: 0644]
docs/RELEASE_NOTES_NEXT/Circulation/lod_new_lib_settings.txt [new file with mode: 0644]
docs/circulation/circulating_items.txt

index 7126f16..8c60bac 100644 (file)
@@ -4069,7 +4069,8 @@ SELECT  usr,
             CASE
                 WHEN (
                     ((fine_interval >= '1 day' AND due_date &lt; 'today') OR (fine_interval &lt; '1 day'  AND due_date &lt; 'now'))
-                    AND (stop_fines IS NULL OR stop_fines NOT IN ('LOST','CLAIMSRETURNED','LONGOVERDUE'))
+                    AND (stop_fines IS NULL OR stop_fines NOT IN ('LOST','CLAIMSRETURNED','LONGOVERDUE') OR (stop_fines IN ('LONGOVERDUE') AND ID NOT IN(SELECT xact FROM money.billing WHERE xact=acirc.id)))
+                                       
                 ) THEN 1
                 ELSE 0
             END
@@ -4077,8 +4078,8 @@ SELECT  usr,
 
         SUM( CASE WHEN (xact_finish IS NULL AND stop_fines = 'LOST') THEN 1 ELSE 0 END) AS lost,
         SUM( CASE WHEN stop_fines = 'CLAIMSRETURNED' THEN 1 ELSE 0 END) AS claims_returned,
-        SUM( CASE WHEN (xact_finish IS NULL AND stop_fines = 'LONGOVERDUE') THEN 1 ELSE 0 END) AS long_overdue
-  FROM  action.circulation
+        SUM( CASE WHEN (xact_finish IS NULL AND stop_fines = 'LONGOVERDUE' AND ID IN(SELECT xact FROM money.billing WHERE xact=acirc.id)) THEN 1 ELSE 0 END) AS long_overdue        
+  FROM  action.circulation acirc
   WHERE checkin_time IS NULL
   GROUP BY 1
         </oils_persist:source_definition>
@@ -4111,7 +4112,7 @@ SELECT  usr,
             CASE
                 WHEN (
                     ((fine_interval >= '1 day' AND due_date &lt; 'today') OR (fine_interval &lt; '1 day'  AND due_date &lt; 'now'))
-                    AND (stop_fines IS NULL OR stop_fines NOT IN ('LOST','CLAIMSRETURNED','LONGOVERDUE'))
+                    AND (stop_fines IS NULL OR stop_fines NOT IN ('LOST','CLAIMSRETURNED','LONGOVERDUE') OR (stop_fines IN ('LONGOVERDUE') AND ID NOT IN(SELECT xact FROM money.billing WHERE xact=acirc.id)))
                 ) THEN id::TEXT
                 ELSE '0'
             END
@@ -4119,8 +4120,8 @@ SELECT  usr,
 
         STRING_AGG( CASE WHEN (xact_finish IS NULL AND stop_fines = 'LOST') THEN id::TEXT ELSE '0' END,',') AS lost,
         STRING_AGG( CASE WHEN stop_fines = 'CLAIMSRETURNED' THEN id::TEXT ELSE '0' END,',') AS claims_returned,
-        STRING_AGG( CASE WHEN (xact_finish IS NULL AND stop_fines = 'LONGOVERDUE') THEN id::TEXT ELSE '0' END,',') AS long_overdue
-  FROM  action.circulation
+        STRING_AGG( CASE WHEN (xact_finish IS NULL AND stop_fines = 'LONGOVERDUE' AND ID IN(SELECT xact FROM money.billing WHERE xact=acirc.id)) THEN id::TEXT ELSE '0' END,',') AS long_overdue       
+  FROM  action.circulation acirc
   WHERE checkin_time IS NULL
   GROUP BY 1
         </oils_persist:source_definition>
index 0e936cf..8159a72 100644 (file)
@@ -1780,7 +1780,7 @@ sub user_opac_vitals {
         ->run($auth => $user_id);
     return $out if (defined($U->event_code($out)));
 
-    $out->{"total_out"} = reduce { $a + $out->{$b} } 0, qw/out overdue/;
+    $out->{"total_out"} = reduce { $a + $out->{$b} } 0, qw/out overdue long_overdue/;
 
     my $unread_msgs = $e->search_actor_usr_message([
         {usr => $user_id, read_date => undef, deleted => 'f'},
index 50a4fc3..660d984 100644 (file)
@@ -740,16 +740,17 @@ sub set_item_long_overdue {
     return $class->set_item_lost_or_lod(
         $e, $copy_id,
         perm => 'SET_CIRC_LONG_OVERDUE',
-        status => 16, # Long Overdue
-        ous_proc_fee => 'circ.longoverdue_materials_processing_fee',
-        ous_void_od => 'circ.void_overdue_on_longoverdue',
+        status => OILS_COPY_STATUS_LONG_OVERDUE,
+        ous_proc_fee => OILS_SETTING_LONG_OVERDUE_PROCESSING_FEE,
+        ous_void_od => OILS_SETTING_VOID_OVERDUE_ON_LONG_OVERDUE,
         bill_type => 10,
         bill_fee_type => 11,
         bill_note => 'Long Overdue Materials',
         bill_fee_note => 'Long Overdue Materials Processing Fee',
         event => 'COPY_MARKED_LONG_OVERDUE',
-        stop_fines => 'LONGOVERDUE',
-        at_hook => 'longoverdue'
+        stop_fines => OILS_STOP_FINES_LONGOVERDUE,
+        at_hook => 'longoverdue',
+        ous_assess_billing => OILS_SETTING_LONG_OVERDUE_ASSESS_BILLING
     );
 }
 
@@ -782,43 +783,54 @@ sub set_item_lost_or_lod {
         $owning_lib, $args{ous_proc_fee}, $e) || 0;
     my $void_overdue = $U->ou_ancestor_setting_value(
         $owning_lib, $args{ous_void_od}, $e) || 0;
+    my $lod_assess_billing = $U->ou_ancestor_setting_value(
+        $owning_lib, $args{ous_assess_billing}, $e);
+    $lod_assess_billing = 1 unless defined $lod_assess_billing;        
 
     # ---------------------------------------------------------------------
-    # move the copy into LOST status
+    # move the copy into LOST/LONGOVERDUE status
     $copy->status($args{status});
     $copy->editor($e->requestor->id);
     $copy->edit_date('now');
     $e->update_asset_copy($copy) or return $e->die_event;
 
-    my $price = $U->get_copy_price($e, $copy, $copy->call_number);
+    # ---------------------------------------------------------------------
+    # Assess billing only when proceeding as "Lost"
+    # or if this is lod and circ.longoverdue.assess_billing is true *or null
+    
+    if( !( ($args{status} == OILS_COPY_STATUS_LONG_OVERDUE) && !$lod_assess_billing) ) {
 
-    if( $price > 0 ) {
-        my $evt = OpenILS::Application::Circ::CircCommon->create_bill($e, 
-            $price, $args{bill_type}, $args{bill_note}, $circ->id);
-        return $evt if $evt;
-    }
+        my $price = $U->get_copy_price($e, $copy, $copy->call_number);
+       
+        if( $price > 0 ) {
+            my $evt = OpenILS::Application::Circ::CircCommon->create_bill($e, 
+                $price, $args{bill_type}, $args{bill_note}, $circ->id);
+            return $evt if $evt;
+        }
 
-    # ---------------------------------------------------------------------
-    # if there is a processing fee, charge that too
-    if( $proc_fee > 0 ) {
-        my $evt = OpenILS::Application::Circ::CircCommon->create_bill($e, 
-            $proc_fee, $args{bill_fee_type}, $args{bill_fee_note}, $circ->id);
-        return $evt if $evt;
+        # ---------------------------------------------------------------------
+        # if there is a processing fee, charge that too
+        if( $proc_fee > 0 ) {
+            my $evt = OpenILS::Application::Circ::CircCommon->create_bill($e, 
+                $proc_fee, $args{bill_fee_type}, $args{bill_fee_note}, $circ->id);
+            return $evt if $evt;
+        }
     }
 
     # ---------------------------------------------------------------------
-    # mark the circ as lost and stop the fines
+    # mark the circ as lost/longoverdue and stop the fines
     $circ->stop_fines($args{stop_fines});
     $circ->stop_fines_time('now') unless $circ->stop_fines_time;
     $e->update_action_circulation($circ) or return $e->die_event;
 
-    # ---------------------------------------------------------------------
-    # zero out overdue fines on this circ if configured
-    if( $void_overdue ) {
-        my $evt = OpenILS::Application::Circ::CircCommon->void_or_zero_overdues($e, $circ, {force_zero => 1, note => "System: OVERDUE REVERSED for " . $args{bill_note} . " Processing"});
-        return $evt if $evt;
+    if( !( ($args{status} == OILS_COPY_STATUS_LONG_OVERDUE) && !$lod_assess_billing) ) {
+        # ---------------------------------------------------------------------
+        # zero out overdue fines on this circ if configured
+        if( $void_overdue ) {
+            my $evt = OpenILS::Application::Circ::CircCommon->void_or_zero_overdues($e, $circ, {force_zero => 1, note => "System: OVERDUE REVERSED for " . $args{bill_note} . " Processing"});
+            return $evt if $evt;
+        }
     }
-
     my $evt = OpenILS::Application::Circ::CircCommon->reopen_xact($e, $circ->id);
     return $evt if $evt;
 
index 652acc1..76da69b 100644 (file)
@@ -169,8 +169,20 @@ sub overdue_circs {
 
     my $sql = <<"    SQL";
         SELECT  $contents
-          FROM  $c_t
-          WHERE stop_fines IS NULL
+          FROM  $c_t acirc
+          WHERE 
+           (
+              (stop_fines IS NULL)
+              OR
+              (stop_fines='LONGOVERDUE' AND
+                COALESCE (
+                  (SELECT value::BOOLEAN FROM
+                    actor.org_unit_ancestor_setting
+                    ('circ.longoverdue.continue_overdue_billing',acirc.circ_lib)
+                  ),FALSE
+                )
+              )
+            )
             $fines_filter
             AND due_date < ( CURRENT_TIMESTAMP - grace_period )
             AND fine_interval < ?::INTERVAL
index c568d89..7919d5d 100644 (file)
@@ -77,12 +77,14 @@ econst OILS_UNLIMITED_CIRC_DURATION   => 'unlimited';
 # Settings
 # ---------------------------------------------------------------------
 econst OILS_SETTING_LOST_PROCESSING_FEE => 'circ.lost_materials_processing_fee';
+econst OILS_SETTING_LONG_OVERDUE_PROCESSING_FEE => 'circ.longoverdue_materials_processing_fee';
 econst OILS_SETTING_DEF_ITEM_PRICE => 'cat.default_item_price';
 econst OILS_SETTING_MIN_ITEM_PRICE => 'circ.min_item_price';
 econst OILS_SETTING_MAX_ITEM_PRICE => 'circ.max_item_price';
 econst OILS_SETTING_ORG_BOUNCED_EMAIL => 'org.bounced_emails';
 econst OILS_SETTING_CHARGE_LOST_ON_ZERO => 'circ.charge_lost_on_zero';
 econst OILS_SETTING_VOID_OVERDUE_ON_LOST => 'circ.void_overdue_on_lost';
+econst OILS_SETTING_VOID_OVERDUE_ON_LONG_OVERDUE => 'circ.void_overdue_on_longoverdue';
 econst OILS_SETTING_HOLD_SOFT_STALL => 'circ.hold_stalling.soft';
 econst OILS_SETTING_HOLD_HARD_STALL => 'circ.hold_stalling.hard';
 econst OILS_SETTING_HOLD_SOFT_BOUNDARY => 'circ.hold_boundary.soft';
@@ -96,6 +98,7 @@ econst OILS_SETTING_RESTORE_OVERDUE_ON_LOST_RETURN      => 'circ.restore_overdue
 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';
+econst OILS_SETTING_LONG_OVERDUE_ASSESS_BILLING => 'circ.longoverdue.assess_billing';
 
 
 
index 9896ff2..64177b1 100644 (file)
@@ -1458,7 +1458,7 @@ sub fetch_user_circs {
                     checkin_time => undef,
                     '-or' => [
                         {stop_fines => undef},
-                        {stop_fines => {'not in' => ['LOST','CLAIMSRETURNED','LONGOVERDUE']}}
+                        {stop_fines => {'not in' => ['LOST','CLAIMSRETURNED']}}
                     ],
                 }
             },
index e029263..779947c 100644 (file)
@@ -1573,7 +1573,7 @@ INSERT INTO permission.perm_list ( id, code, description ) VALUES
         'When granted, newly added lineitem identifiers will propagate to linked bib records', 'ppl', 'description')),
  ( 548, 'ACQ_SET_LINEITEM_IDENTIFIER', oils_i18n_gettext(548,
         'Allows staff to change the lineitem identifier', 'ppl', 'description')),
- ( 549, 'COPY_STATUS_LONGOVERDUE.override', oils_i18n_gettext(549,
+ ( 549, 'COPY_STATUS_LONG_OVERDUE.override', oils_i18n_gettext(549,
         'Allows the user to check-in long-overdue items, prompting ' ||
             'long-overdue check-in processing', 'ppl', 'code')), 
  ( 550, 'SET_CIRC_LONG_OVERDUE', oils_i18n_gettext(550,
@@ -15669,7 +15669,42 @@ INSERT INTO config.org_unit_setting_type
             'circ.max_accept_return_of_longoverdue',
         'coust',
         'description'
+   )
+), (
+    'circ.longoverdue.assess_billing',
+    'finance', 'bool',
+    oils_i18n_gettext(
+        'circ.longoverdue.assess_billing',
+        'Assess Billing When Marked Long-Overdue',
+        'coust',
+        'label'
+    ),
+    oils_i18n_gettext(
+        'circ.longoverdue.assess_billing',
+        'When an item is marked long overdue a bill for the item will be ' ||
+               'assesed unless this setting is false. The default is true. If false ' ||
+               'void overdue setting will be ignored and processing fee will be ignored',
+        'coust',
+        'description'
+   )
+), (
+    'circ.longoverdue.continue_overdue_billing',
+    'finance', 'bool',
+    oils_i18n_gettext(
+        'circ.longoverdue.continue_overdue_billing',
+        'Continue Overdue Billing When Marked Long-Overdue',
+        'coust',
+        'label'
+    ),
+    oils_i18n_gettext(
+        'circ.longoverdue.continue_overdue_billing',
+       'When an item is marked long overdue, overdues are halted. ' ||
+               'A setting of true here will allow the overdues to continue ' ||
+               'until another condition is met.',
+        'coust',
+        'description'
     )
+
 );
 
 -- mark long-overdue reactor
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.data.long-overdue-asses-fines-library-setting.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.data.long-overdue-asses-fines-library-setting.sql
new file mode 100644 (file)
index 0000000..f151b49
--- /dev/null
@@ -0,0 +1,50 @@
+BEGIN;
+
+SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version);
+
+INSERT INTO config.org_unit_setting_type ( name, grp, label, description, datatype ) VALUES (   
+    'circ.longoverdue.assess_billing',
+    'finance',
+    oils_i18n_gettext(
+        'circ.longoverdue.assess_billing',
+        'Assess Billing When Marked Long-Overdue',
+        'coust',
+        'label'
+    ),
+    oils_i18n_gettext(
+        'circ.longoverdue.assess_billing',
+        'When an item is marked long overdue, a bill for the item will be ' ||
+               'assessed unless this setting is false. The default is true. If false, ' ||
+               '"Void Overdue Fines When Items are Marked Long-Overdue" and "Long-Overdue'||
+               ' Materials Processing Fee" settings will be ignored.',
+        'coust',
+        'description'
+    ), 'bool'
+)
+;
+
+INSERT INTO config.org_unit_setting_type ( name, grp, label, description, datatype ) VALUES (   
+     'circ.longoverdue.continue_overdue_billing',
+     'finance',
+     oils_i18n_gettext(
+         'circ.longoverdue.continue_overdue_billing',
+         'Continue Overdue Billing When Marked Long-Overdue',
+         'coust',
+         'label'
+     ),
+     oils_i18n_gettext(
+         'circ.longoverdue.continue_overdue_billing',
+         'When an item is marked long overdue, overdues are halted. ' ||
+                'A setting of true here will allow the overdues to continue ' ||
+                'until another condition is met.',
+         'coust',
+         'description'
+     ), 'bool'
+ )
+ ;
+
+UPDATE PERMISSION.PERM_LIST SET CODE='COPY_STATUS_LONG_OVERDUE.override' WHERE CODE='COPY_STATUS_LONGOVERDUE.override';
+
+
+
+COMMIT;
diff --git a/docs/RELEASE_NOTES_NEXT/Circulation/lod_new_lib_settings.txt b/docs/RELEASE_NOTES_NEXT/Circulation/lod_new_lib_settings.txt
new file mode 100644 (file)
index 0000000..1631283
--- /dev/null
@@ -0,0 +1,3 @@
+*New Library Setting*
+**Finances: Assess Billing When Marked Long-Overdue - When an item is marked long overdue a bill for the item will be assesed unless this setting is false. The default is true. If false, void overdue setting will be ignored and processing fee will be ignored
+**Finances: Continue Overdue Billing When Marked Long-Overdue - When an item is marked long overdue, overdues are halted. A setting of true here will allow the overdues to continue until another condition is met.
index 7f3fc0c..b0bd6af 100644 (file)
@@ -559,5 +559,73 @@ image::media/copy_alert_message.png[]
 5) Click *Modify Copies*, then confirm the action.
 
 
+Mark an Item Long Overdue
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+*Marking an item Long Overdue*
+
+Once an item has been overdue for a configurable amount of time, Evergreen will mark the item long overdue in the borrowing patron’s account.  This will be done automatically through a Notification/Action Trigger.   When the item is marked long overdue, several actions will take place:
+
+. The item will go into the status of “Long Overdue” 
+
+. The item will be moved to the “Lost, Claimed Returned, Long Overdue, Has Unpaid Billings” section of the Items Out screen in the patron’s account
+
+. The accrual of overdue fines will be stopped
+
+Optionally the patron can be billed for the item price, a long overdue processing fee, and any overdue fines can be voided from the account.  Patrons can also be sent a notification that the item was marked long overdue.
+image::media/long_overdue1.jpg[Patron Account-Long Overdue]
+
+
+*Checking in a Long Overdue item*
+
+If an item that has been marked long overdue is checked in, an alert will appear on the screen informing the staff member that the item was long overdue.  Once checked in, the item will go into the status of “In process”.  Optionally, the item price and long overdue processing fee can be voided and overdue fines can be reinstated on the patron’s account.  If the item is checked in at a library other than its home library, a library setting controls whether the item can immediately fill a hold or circulate, or if it needs to be sent to its home library for processing.
+image::media/long_overdue2.jpg[Long Overdue Checkin]
+*Notification/Action Triggers*
+
+Evergreen has two sample Notification/Action Triggers that are related to marking items long overdue.  The sample triggers are configured for 6 months.  These triggers can be configured for any amount of time according to library policy and will need to be activated for use.
+
+* Sample Triggers
+
+** 6 Month Auto Mark Long-Overdue—will mark an item long overdue after the configured period of time
+
+** 6 Month Long Overdue Notice—will send patron notification that an item has been marked long overdue on their account
+
+*Library Settings* 
+
+The following Library Settings enable you to set preferences related to long overdue items:
+
+* *Circulation: Long-Overdue Check-In Interval Uses Last Activity Date* —Use the long-overdue last-activity date instead of the due_date to determine whether the item has been checked out too long to perform long-overdue check-in processing. If set, the system will first check the last payment time, followed by the last billing time, followed by the due date. See also circ.max_accept_return_of_longoverdue 
+
+* *Circulation: Long-Overdue Items Usable on Checkin* —Long-overdue items are usable on checkin instead of going "home" first
+
+* *Circulation: Long-Overdue Max Return Interval* —Long-overdue check-in processing (voiding fees, re-instating overdues, etc.) will not take place for items that have been overdue for (or have last activity older than) this amount of time 
+
+* *Circulation: Restore Overdues on Long-Overdue Item Return*
+
+* *Circulation: Void Long-Overdue item Billing When Returned*
+
+* *Circulation: Void Processing Fee on Long-Overdue Item Return*
+
+* *Finances: Leave transaction open when long overdue balance equals zero* —Leave transaction open when long-overdue balance equals zero. This leaves the lost copy on the patron record when it is paid
+
+* *Finances: Long-Overdue Materials Processing Fee*
+
+* *Finances: Void Overdue Fines When Items are Marked Long-Overdue*
+
+* *Finances: Assess Billing When Marked Long-Overdue* -Optionally skip billing price of item
+
+* *Finances: Continue Overdue Billing When Marked Long-Overdue*
+
+
+*Permissions to use this Feature*
+
+The following permissions are related to this feature:
+
+* COPY_STATUS_LONG_OVERDUE.override
+
+** Allows the user to check-in long-overdue items thus removing the long-overdue status on the item