truncate fines to max fine amount (LP#1145284)
authorJeff Davis <jdavis@sitka.bclibraries.ca>
Mon, 4 Mar 2013 21:42:08 +0000 (13:42 -0800)
committerMike Rylander <mrylander@gmail.com>
Tue, 5 Mar 2013 20:09:03 +0000 (15:09 -0500)
When the max fine amount is not a multiple of the recurring fine amount,
fines will actually max out at an amount greater than the max fine
value.  This commit adds YAOUS and some simple functionality to
optionally truncate the final amount billed to the max fine amount.

For example, if max fine is $5.00 and recurring fine is $0.30, the 17th
billing will bring the total amount billed to $5.10 (17 x $0.30),
thereby exceeding the max fine amount.  With this commit, if
circ.fines.truncate_to_max_fine is true, the final billing amount will
be reduced and the total amount billed will be $5.00.

Signed-off-by: Jeff Davis <jdavis@sitka.bclibraries.ca>
Signed-off-by: Mike Rylander <mrylander@gmail.com>
Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/action.pm
Open-ILS/src/sql/Pg/upgrade/XXXX.data.truncate-to-max-fine-setting.sql [new file with mode: 0644]

index 05dedcf..abe4c46 100644 (file)
@@ -1111,6 +1111,10 @@ sub generate_fines {
                                $c->$circ_lib_method->to_fieldmapper->id, 'circ.fines.charge_when_closed');
                        $skip_closed_check = $U->is_true($skip_closed_check);
 
+                       my $truncate_to_max_fine = $U->ou_ancestor_setting_value(
+                               $c->$circ_lib_method->to_fieldmapper->id, 'circ.fines.truncate_to_max_fine');
+                       $truncate_to_max_fine = $U->is_true($truncate_to_max_fine);
+
                        my ($latest_billing_ts, $latest_amount) = ('',0);
                        for (my $bill = 1; $bill <= $pending_fine_count; $bill++) {
        
@@ -1149,8 +1153,15 @@ sub generate_fines {
                                        next if (@cl);
                                }
 
-                               $current_fine_total += $recurring_fine;
-                               $latest_amount += $recurring_fine;
+                               # The billing amount for this billing normally ought to be the recurring fine amount.
+                               # However, if the recurring fine amount would cause total fines to exceed the max fine amount,
+                               # we may wish to reduce the amount for this billing (if circ.fines.truncate_to_max_fine is true).
+                               my $this_billing_amount = $recurring_fine;
+                               if ( $truncate_to_max_fine && ($current_fine_total + $this_billing_amount) > $max_fine ) {
+                                       $this_billing_amount = ($max_fine - $current_fine_total);
+                               }
+                               $current_fine_total += $this_billing_amount;
+                               $latest_amount += $this_billing_amount;
                                $latest_billing_ts = $timestamptz;
 
                                money::billing->create(
@@ -1158,7 +1169,7 @@ sub generate_fines {
                                          note          => "System Generated Overdue Fine",
                                          billing_type  => "Overdue materials",
                                          btype         => 1,
-                                         amount        => sprintf('%0.2f', $recurring_fine/100),
+                                         amount        => sprintf('%0.2f', $this_billing_amount/100),
                                          billing_ts    => $timestamptz,
                                        }
                                );
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.data.truncate-to-max-fine-setting.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.data.truncate-to-max-fine-setting.sql
new file mode 100644 (file)
index 0000000..f9fd754
--- /dev/null
@@ -0,0 +1,15 @@
+BEGIN;
+
+SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version);
+
+INSERT INTO config.org_unit_setting_type (
+    name, label, grp, datatype
+) VALUES (
+    'circ.fines.truncate_to_max_fine',
+    'Truncate fines to max fine amount',
+    'circ',
+    'bool'
+);
+
+COMMIT;
+