LP#1270289 Support canceling already-canceled lineitems
authorBill Erickson <berick@esilibrary.com>
Tue, 3 Jun 2014 14:18:43 +0000 (10:18 -0400)
committerBen Shum <bshum@biblio.org>
Thu, 7 Aug 2014 21:06:43 +0000 (17:06 -0400)
If a lineitem is canceled and the cancel_reason has keep_debits == true
(i.e. the lineitem is "delayed"), allow the lineitem to be canceled
again, up until the point the lineitem cancel_reason has keep_debits ==
false, at which point, no more cancelations are allowed.

Similarly, when a copy is canceled with a keep_debits==true reason,
allow the copy to be canceled when its parent lineitem is canceled,
following the rules above.

Signed-off-by: Bill Erickson <berick@esilibrary.com>
Signed-off-by: Kathy Lussier <klussier@masslnc.org>
Signed-off-by: Ben Shum <bshum@biblio.org>
Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/Order.pm
Open-ILS/web/js/ui/default/acq/common/li_table.js

index eac934b..4dc88af 100644 (file)
@@ -3037,8 +3037,10 @@ sub cancel_lineitem_api {
 
 sub cancel_lineitem {
     my ($mgr, $li_id, $cancel_reason) = @_;
+
     my $li = $mgr->editor->retrieve_acq_lineitem([
-        $li_id, {flesh => 1, flesh_fields => {jub => ['purchase_order']}}
+        $li_id, {flesh => 1, 
+            flesh_fields => {jub => ['purchase_order','cancel_reason']}}
     ]) or return 0;
 
     return 0 unless $mgr->editor->allowed(
@@ -3046,14 +3048,16 @@ sub cancel_lineitem {
     );
 
     # Depending on context, this may not warrant an event.
-    return -1 if $li->state eq "cancelled";
+    return -1 if $li->state eq "cancelled" 
+        and $li->cancel_reason->keep_debits eq 'f';
 
     # But this always does.  Note that this used to be looser, but you can
     # no longer cancel lineitems that lack a PO or that are in "pending-order"
     # state (you could in the past).
     return new OpenILS::Event(
         "ACQ_NOT_CANCELABLE", "note" => "lineitem $li_id"
-    ) unless $li->purchase_order and $li->state eq "on-order";
+    ) unless $li->purchase_order and 
+        ($li->state eq "on-order" or $li->state eq "cancelled");
 
     $li->state("cancelled");
     $li->cancel_reason($cancel_reason->id);
@@ -3218,13 +3222,17 @@ sub cancel_lineitem_detail {
         $lid_id, {
             "flesh" => 2,
             "flesh_fields" => {
-                "acqlid" => ["lineitem"], "jub" => ["purchase_order"]
+                "acqlid" => ["lineitem","cancel_reason"], 
+                "jub" => ["purchase_order"]
             }
         }
     ]) or return 0;
 
+    # It's OK to cancel an already-canceled copy if the copy was
+    # previously "delayed" -- keep_debits == true
     # Depending on context, this may not warrant an event.
-    return -1 if $lid->cancel_reason;
+    return -1 if $lid->cancel_reason 
+        and $lid->cancel_reason->keep_debits eq 'f';
 
     # But this always does.
     return new OpenILS::Event(
@@ -3236,7 +3244,8 @@ sub cancel_lineitem_detail {
             $lid->lineitem and
             $lid->lineitem->purchase_order and (
                 $lid->lineitem->state eq "on-order" or
-                $lid->lineitem->state eq "pending-order"
+                $lid->lineitem->state eq "pending-order" or
+                $lid->lineitem->state eq "cancelled"
             )
         )
     );
index 913f354..c65bca2 100644 (file)
@@ -2944,11 +2944,20 @@ function AcqLiTable() {
 
     this._cancelLineitems = function(reason) {
 
-        // ignore canceled lineitems during batch lineitem cancel
-        var states = li_active_states.filter(
-            function(s) { return s != 'cancelled' });
+        var li_list = this.getSelected();
+
+        // canceled lineitems may be canceled again if they were 
+        // previously delayed (keep_debits = true).
+        li_list = li_list.filter(
+            function(li) {
+                return (
+                    li.state() != 'cancelled' ||
+                    li.cancel_reason().keep_debits() == 't'
+                );
+            }
+        );
 
-        var id_list = this.getSelected(null, null, true, states);
+        id_list = li_list.map(function(l) {return l.id()});
 
         if (!id_list.length) {
             alert(localeStrings.NO_LI_GENERAL);