Acq: lineitem batch updater - untested handling for counts in implementation
authorLebbeous Fogle-Weekley <lebbeous@esilibrary.com>
Mon, 18 Feb 2013 22:27:01 +0000 (17:27 -0500)
committerLebbeous Fogle-Weekley <lebbeous@esilibrary.com>
Mon, 11 Mar 2013 18:00:48 +0000 (14:00 -0400)
Signed-off-by: Lebbeous Fogle-Weekley <lebbeous@esilibrary.com>
Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/Lineitem.pm

index 4fdc0aa..e6c7ace 100644 (file)
@@ -1070,7 +1070,7 @@ sub lineitem_batch_update_perm_test {
 # lineitem_batch_update_impl() should be handed everything pre-perm-checked
 # and ready-to-go. $e is in a transaction.
 sub lineitem_batch_update_impl {
-    my ($e, $target, $changes, $dist_formula) = @_;
+    my ($conn, $e, $target, $changes, $dist_formula) = @_;
 
     # First, retrieve existing lineitem details.
 
@@ -1100,14 +1100,47 @@ sub lineitem_batch_update_impl {
         ) or return $e->die_event;
     }
 
-    # XXX Here, send one of those opensrf continue thingers in case (or substream on previous search_*()? ask berick 
+    # XXX Is this the best way to tell the client not to get bored at this
+    # point? Or substream on previous search_*()?  Ask berick.
+    $conn->status(new OpenSRF::DomainObject::oilsContinueStatus);
 
-    # XXX TODO
-    # Count how many lineitem details we have per lineitem, and for each
-    # lineitem add or remove lineitems to match $changes->{count}, as needed.
+    # [Part 1] Count how many lineitem details we have per lineitem, and for
+    # each lineitem add or remove lineitems to match $changes->{count}, as
+    # needed.
+
+    my %counts;
+    foreach my $lid (@$lineitem_details) {
+        $counts{$lid->lineitem} ||= 0;
+        $counts{$lid->lineitem}++;
+
+        # [Part 1a] Take care of excess lineitem details.
+        if ($counts{$lid->lineitem} > $changes->{count}) {
+            $e->delete_acq_lineitem_detail($lid) or return $e->die_event;
+            $counts{$lid->lineitem}--;
+        }
+    }
+
+    # [Part 1b] Add missing lineitem details.
+    foreach my $lineitem_id (grep { $_ < $changes->{count} } (keys %counts)) {
+        for (my $i = $counts{$lineitem_id}; $i < $changes->{count}; $i++) {
+            my $lid = new Fieldmapper::acq::lineitem_detail;
+            $lid->isnew(1);
+            $lid->lineitem($lineitem_id);
 
-    # Now, going through all our lineitem details, make the updates called for
-    # in $changes, other than the 'count' field (handled above).
+            push @$lineitem_details, $lid;
+        }
+    }
+
+    # [Part 1c] Sort lineitem details again so that we can send responses in
+    # grouped together when we create/update them.
+    $lineitem_details = [
+        sort { $a->lineitem <=> $b->lineitem } @$lineitem_details
+    ];
+
+    # [Pass 2] Now, going through all our lineitem details, make the updates
+    # called for in $changes, other than the 'count' field (handled above).
+
+    my $last_jub_id_sent = 0;
 
     foreach my $lid (@$lineitem_details) {
         foreach my $field (qw/owning_lib fund location collection_code circ_modifer/) {
@@ -1124,8 +1157,13 @@ sub lineitem_batch_update_impl {
             }
         }
 
-        # XXX TODO cstore update, and send client a response per LI (not per
-        # LID I think...)
+        my $method = ($lid->isnew ? "create":"update") . "_acq_lineitem_detail";
+        $e->$method($lid) or return $e->die_event;
+
+        if ($lid->lineitem != $last_jub_id_sent) {
+            $conn->respond($lid->lineitem);
+            $last_jub_id_sent = $lid->lineitem;
+        }
     }
 
     $e->commit;
@@ -1198,7 +1236,9 @@ sub lineitem_batch_update_api {
     return $evt if $U->event_code($evt);
 
     # Now do the actual work.
-    return lineitem_batch_update_impl($e, $target, $changes, $dist_formula);
+    return lineitem_batch_update_impl(
+        $conn, $e, $target, $changes, $dist_formula
+    );
 }
 
 1;