LP1198475: The code that actually checks settings and changes status.
authorJason Stephenson <jason@sigio.com>
Sun, 3 Nov 2013 15:18:17 +0000 (10:18 -0500)
committerKathy Lussier <klussier@masslnc.org>
Tue, 3 Jun 2014 16:59:07 +0000 (12:59 -0400)
Add checks to O::A::Circ::Money::make_payments to check for LOST
status and org_unit settings and change the status to LOST_AND_PAID
as appropriate.

Also add checks for LOST_AND_PAID copy status wherever LOST copy
status is used.

Add checks for LOSTANDPAID stop fines wherever LOST stop fines is
used.

Set the styles in the staff client of the lost and paid stop fines.

Someone might want to customize this, but for now, we just handle it
the same as lost.

Add the COPY_STATUS_LOST_AND_PAID event.

Add the event to ils_events.xml with id 7026.

Check for the event in circ/util.js in the staff client.

Signed-off-by: Jason Stephenson <jason@sigio.com>
Signed-off-by: Kathy Lussier <klussier@masslnc.org>
14 files changed:
Open-ILS/src/extras/ils_events.xml
Open-ILS/src/perlmods/lib/OpenILS/Application/Actor.pm
Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm
Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Money.pm
Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Transit.pm
Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/action.pm
Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/actor.pm
Open-ILS/src/perlmods/lib/OpenILS/Application/Trigger.pm
Open-ILS/src/perlmods/lib/OpenILS/Const.pm
Open-ILS/src/perlmods/lib/OpenILS/SIP/Item.pm
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm
Open-ILS/xul/staff_client/server/circ/util.js
Open-ILS/xul/staff_client/server/patron/bill2.js
Open-ILS/xul/staff_client/server/skin/circ.css

index 21d59a7..80892ad 100644 (file)
        <event code='7025' textcode='COPY_STATUS_LONG_OVERDUE'>
                <desc xml:lang="en-US">Copy is marked as long-overdue</desc>
        </event>
+       <event code='7026' textcode='COPY_STATUS_LOST_AND_PAID'>
+               <desc xml:lang="en-US">Copy is marked as lost and paid</desc>
+       </event>
 
 
        <!-- ================================================================ -->
index 9c9efc4..87cf241 100644 (file)
@@ -2106,7 +2106,7 @@ sub checked_in_with_fines {
 
     my( @lost, @cr, @lo );
     for my $c (@$open) {
-        push( @lost, $c->id ) if $c->stop_fines eq 'LOST';
+        push( @lost, $c->id ) if ($c->stop_fines eq 'LOST' || $c->stop_fines eq 'LOSTANDPAID');
         push( @cr, $c->id ) if $c->stop_fines eq 'CLAIMSRETURNED';
         push( @lo, $c->id ) if $c->stop_fines eq 'LONGOVERDUE';
     }
index 4fec8e4..fa1b3ef 100644 (file)
@@ -3420,7 +3420,7 @@ sub checkin_handle_circ {
         $self->copy->circ_lib->id : $self->copy->circ_lib;
     my $stat = $U->copy_status($self->copy->status)->id;
 
-    if ($stat == OILS_COPY_STATUS_LOST) {
+    if ($stat == OILS_COPY_STATUS_LOST || $stat == OILS_COPY_STATUS_LOST_AND_PAID) {
         # we will now handle lost fines, but the copy will retain its 'lost'
         # status if it needs to transit home unless lost_immediately_available
         # is true
@@ -3668,6 +3668,9 @@ sub check_checkin_copy_status {
    return OpenILS::Event->new('COPY_STATUS_LOST', payload => $copy )
       if( $status == OILS_COPY_STATUS_LOST );
 
+    return OpenILS::Event->new('COPY_STATUS_LOST_AND_PAID', payload => $copy)
+        if ($status == OILS_COPY_STATUS_LOST_AND_PAID);
+
    return OpenILS::Event->new('COPY_STATUS_LONG_OVERDUE', payload => $copy )
       if( $status == OILS_COPY_STATUS_LONG_OVERDUE );
 
index 0c1493a..640d24c 100644 (file)
@@ -29,6 +29,7 @@ use OpenILS::Utils::CStoreEditor qw/:funcs/;
 use OpenILS::Utils::Penalty;
 use Business::Stripe;
 $Data::Dumper::Indent = 0;
+use OpenILS::Const qw/:const/;
 
 sub get_processor_settings {
     my $e = shift;
@@ -466,10 +467,19 @@ sub make_payments {
             # credit
             $cred = -$cred;
             $credit += $cred;
-            my $circ = $e->retrieve_action_circulation($transid);
+            my $circ = $e->retrieve_action_circulation(
+                [
+                    $transid,
+                    {
+                        flesh => 1,
+                        flesh_fields => {circ => ['target_copy','billings']}
+                    }
+                ]
+            ); # Flesh the copy, so we can monkey with the status if
+               # necessary.
 
             # Whether or not we close the transaction. We definitely
-            # close is no circulation transaction is present,
+            # close if no circulation transaction is present,
             # otherwise we check if the circulation is in a state that
             # allows itself to be closed.
             if (!$circ || OpenILS::Application::Circ::CircCommon->can_close_circ($e, $circ)) {
@@ -482,6 +492,55 @@ sub make_payments {
                     )
                 }
             }
+
+            # If we have a circ, we need to check if there are lost or
+            # long overdue billings and if it looks like one of these
+            # is being paid.  If it is then we check org_unit_settings
+            # for the copy owning library and adjust statuses and stop
+            # fines reasons accordingly.
+            if ($circ) {
+                # We need the copy to check settings and to possibly
+                # change its status.
+                my $copy = $circ->target_copy();
+                # Library where we'll check settings.
+                my $check_lib = $copy->circ_lib();
+
+                # Find all lost billings that match the payment amount
+                # being made.  As crazy as it sounds, there could be
+                # more than one.
+                my @lost = grep {$_->btype() == 3 && $_->amount() <= $amount} @{$circ->billings()};
+
+                # Find all long overdue billings that match the
+                # payment amount being made.  As crazy as it sounds,
+                # there could be more than one.
+                my @loverdue = grep {$_->btype() == 10 && $_->amount() <= $amount} @{$circ->billings()};
+
+                # A little logical simplification.  We'll precheck if
+                # we have the conditions that we need to set the stop
+                # fines or copy status and put these each in their own
+                # bool variable.  This will save us some complication
+                # in the logic below.
+                my $stop_fines_cond = (($circ->stop_fines() eq OILS_STOP_FINES_LOST && scalar(@lost))
+                                           || ($circ->stop_fines() eq OILS_STOP_FINES_LONGOVERDUE  && scalar(@loverdue)));
+                my $copy_status_cond = (($copy->status() == OILS_COPY_STATUS_LOST && scalar(@lost))
+                                           || ($copy->status() == OILS_COPY_STATUS_LONG_OVERDUE  && scalar(@loverdue)));
+
+                # check the stop fines.
+                if ($stop_fines_cond) {
+                    if ($U->is_true($U->ou_ancestor_setting_value($check_lib, 'circ.use_lost_paid_stop_fines', $e))) {
+                        $circ->stop_fines_time('now');
+                        $circ->stop_fines(OILS_STOP_FINES_LOSTANDPAID);
+                        $e->update_action_circulation($circ);
+                    }
+                }
+                # check the copy status
+                if ($copy_status_cond) {
+                    if ($U->is_true($U->ou_ancestor_setting_value($check_lib, 'circ.use_lost_paid_copy_status', $e))) {
+                        $copy->status(OILS_COPY_STATUS_LOST_AND_PAID);
+                        $e->update_asset_copy($copy);
+                    }
+                }
+            }
         }
 
         # Urgh, clean up this mega-function one day.
index e4e021b..bd687c4 100644 (file)
@@ -226,7 +226,8 @@ sub __abort_transit {
     my $evt;
     my $hold;
 
-    if( ($transit->copy_status == OILS_COPY_STATUS_LOST and !$e->allowed('ABORT_TRANSIT_ON_LOST')) or
+    if( (($transit->copy_status == OILS_COPY_STATUS_LOST || $transit->copy_status == OILS_COPY_STATUS_LOST_AND_PAID)
+             and !$e->allowed('ABORT_TRANSIT_ON_LOST')) or
         ($transit->copy_status == OILS_COPY_STATUS_MISSING and !$e->allowed('ABORT_TRANSIT_ON_MISSING')) ) {
         $e->rollback;
         return OpenILS::Event->new('TRANSIT_ABORT_NOT_ALLOWED', copy_status => $transit->copy_status);
index 7cc2086..5b1b770 100644 (file)
@@ -242,7 +242,7 @@ sub mark_longoverdue {
                       FROM  $circ circ
                             LEFT JOIN $setting setting
                                 ON (circ.circ_lib = setting.org_unit AND setting.name = 'circ.long_overdue.interval')
-                      WHERE circ.checkin_time IS NULL AND (stop_fines IS NULL OR stop_fines NOT IN ('LOST','LONGOVERDUE'))
+                      WHERE circ.checkin_time IS NULL AND (stop_fines IS NULL OR stop_fines NOT IN ('LOST','LONGOVERDUE','LOSTANDPAID'))
                             AND AGE(circ.due_date) > CAST( COALESCE( BTRIM( setting.value,'"' ), ? )  AS INTERVAL)
                   )
     SQL
@@ -648,7 +648,7 @@ sub patron_circ_summary {
           WHERE c.usr = ?
             AND c.xact_finish IS NULL
             AND (
-                c.stop_fines NOT IN ('CLAIMSRETURNED','LOST')
+                c.stop_fines NOT IN ('CLAIMSRETURNED','LOST','LOSTANDPAID')
                 OR c.stop_fines IS NULL
             )
     SQL
index 06117ff..62f8ac5 100644 (file)
@@ -86,7 +86,7 @@ sub usr_breakdown_out {
                     AND (  (fine_interval >= '1 day' AND due_date >= 'today')
                         OR (fine_interval < '1 day'  AND due_date > 'now'   ))
                     AND (stop_fines IS NULL
-                        OR stop_fines NOT IN ('LOST','CLAIMSRETURNED','LONGOVERDUE'))
+                        OR stop_fines NOT IN ('LOST','CLAIMSRETURNED','LONGOVERDUE','LOSTANDPAID'))
     SQL
 
     my $out = actor::user->db_Main->selectcol_arrayref($out_sql, {}, $usr);
@@ -99,7 +99,7 @@ sub usr_breakdown_out {
                     AND (  (fine_interval >= '1 day' AND due_date < 'today')
                         OR (fine_interval < '1 day'  AND due_date < 'now'  ))
                     AND (stop_fines IS NULL
-                        OR stop_fines NOT IN ('LOST','CLAIMSRETURNED','LONGOVERDUE'))
+                        OR stop_fines NOT IN ('LOST','CLAIMSRETURNED','LONGOVERDUE','LOSTANDPAID'))
     SQL
 
     my $od = actor::user->db_Main->selectcol_arrayref($od_sql, {}, $usr);
@@ -128,6 +128,14 @@ sub usr_breakdown_out {
 
     my $lo = actor::user->db_Main->selectcol_arrayref($lo_sql, {}, $usr);
 
+    my $lp_sql = <<"    SQL";
+            SELECT  id
+              FROM  action.circulation
+              WHERE usr = ? AND checkin_time IS NULL AND stop_fines = 'LOSTANDPAID'
+    SQL
+
+    my $lp = actor::user->db_Main->selectcol_arrayref($lo_sql, {}, $usr);
+
     $self->method_lookup('open-ils.storage.transaction.rollback')->run($client);
 
     if ($self->api_name =~/count$/o) {
index ed83cba..525a4af 100644 (file)
@@ -255,7 +255,7 @@ __PACKAGE__->register_method(
 #              checkin_time => undef, 
 #              '-or' => [
 #                { stop_fines => undef },
-#                { stop_fines => { 'not in' => ['LOST','LONGOVERDUE','CLAIMSRETURNED'] } }
+#                { stop_fines => { 'not in' => ['LOST','LONGOVERDUE','CLAIMSRETURNED','LOSTANDPAID'] } }
 #              ]
 #            }
 
index 4f9e5c2..6178aa9 100644 (file)
@@ -43,6 +43,7 @@ econst OILS_COPY_STATUS_DISCARD       => 13;
 econst OILS_COPY_STATUS_DAMAGED       => 14;
 econst OILS_COPY_STATUS_ON_RESV_SHELF => 15;
 econst OILS_COPY_STATUS_LONG_OVERDUE  => 16;
+econst OILS_COPY_STATUS_LOST_AND_PAID => 17;
 
 
 # ---------------------------------------------------------------------
@@ -68,6 +69,7 @@ econst OILS_STOP_FINES_RENEW          => 'RENEW';
 econst OILS_STOP_FINES_LOST           => 'LOST';
 econst OILS_STOP_FINES_CLAIMSRETURNED => 'CLAIMSRETURNED';
 econst OILS_STOP_FINES_LONGOVERDUE    => 'LONGOVERDUE';
+econst OILS_STOP_FINES_LOSTANDPAID    => 'LOSTANDPAID';
 econst OILS_STOP_FINES_MAX_FINES      => 'MAXFINES';
 econst OILS_STOP_FINES_CLAIMS_NEVERCHECKEDOUT => 'CLAIMSNEVERCHECKEDOUT';
 econst OILS_UNLIMITED_CIRC_DURATION   => 'unlimited';
index a2523e1..eb40e97 100644 (file)
@@ -356,7 +356,7 @@ sub sip_circulation_status {
     return '08' if $stat == OILS_COPY_STATUS_ON_HOLDS_SHELF;
     return '09' if $stat == OILS_COPY_STATUS_RESHELVING;
     return '10' if $stat == OILS_COPY_STATUS_IN_TRANSIT;
-    return '12' if $stat == OILS_COPY_STATUS_LOST;
+    return '12' if ($stat == OILS_COPY_STATUS_LOST || $stat == OILS_COPY_STATUS_LOST_AND_PAID);
     return '13' if $stat == OILS_COPY_STATUS_MISSING;
         
     return '01';
index c2e6450..826a663 100644 (file)
@@ -1209,7 +1209,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','LONGOVERDUE','LOSTANDPAID']}}
                     ],
                 }
             },
index 67472c4..058eb92 100644 (file)
@@ -2756,6 +2756,7 @@ circ.util.checkin_via_barcode = function(session,params,backdate,auto_print,asyn
                     7010 /* COPY_ALERT_MESSAGE */,
                     7011 /* COPY_STATUS_LOST */,
                     7025 /* COPY_STATUS_LONG_OVERDUE */, 
+                    7026 /* COPY_STATUS_LOST_AND_PAID */,
                     7012 /* COPY_STATUS_MISSING */,
                     7013 /* PATRON_EXCEEDS_FINES */
                 ] : [],
@@ -2770,6 +2771,7 @@ circ.util.checkin_via_barcode = function(session,params,backdate,auto_print,asyn
                     7010 /* COPY_ALERT_MESSAGE */,
                     7011 /* COPY_STATUS_LOST */,
                     7025 /* COPY_STATUS_LONG_OVERDUE */, 
+                    7026 /* COPY_STATUS_LOST_AND_PAID */,
                     7012 /* COPY_STATUS_MISSING */,
                     7013 /* PATRON_EXCEEDS_FINES */,
                     11103 /* TRANSIT_CHECKIN_INTERVAL_BLOCK */ 
index 8a248f3..04c77f3 100644 (file)
@@ -574,7 +574,7 @@ function init_lists() {
                             var stop_fines = row.my.circ.stop_fines() || '';
 
                             // we have custom syling for these stop-fines reasons
-                            if (stop_fines.match(/LOST|LONGOVERDUE/)) 
+                            if (stop_fines.match(/LOST|LONGOVERDUE|LOSTANDPAID/)) 
                                 style_type = stop_fines.toLowerCase();
 
                             $(style_type + '_hint').hidden = false;
index 27ae6ca..feb37e7 100644 (file)
@@ -23,6 +23,10 @@ treechildren::-moz-tree-cell(lost) {
     background-color: maroon;
 }
 
+treechildren::-moz-tree-cell(lostandpaid) {
+    background-color: maroon;
+}
+
 treechildren::-moz-tree-cell-text(circulating) {
     color: white;
 }
@@ -31,6 +35,10 @@ treechildren::-moz-tree-cell-text(lost) {
     color: white;
 }
 
+treechildren::-moz-tree-cell-text(lostandpaid) {
+    color: white;
+}
+
 treechildren::-moz-tree-cell-text(longoverdue) {
     color: black;
 }
@@ -45,6 +53,11 @@ treechildren::-moz-tree-cell-text(longoverdue) {
     color: white;
 }
 
+#lostandpaid_hint {
+    background-color: maroon;
+    color: white;
+}
+
 #longoverdue_hint {
     background-color: orange;
     color: black;