LP1952931 ASN EDI can contain multiple containers
authorBill Erickson <berickxx@gmail.com>
Tue, 15 Mar 2022 17:03:47 +0000 (13:03 -0400)
committerBill Erickson <berickxx@gmail.com>
Wed, 21 Sep 2022 15:29:35 +0000 (11:29 -0400)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/EDI.pm
Open-ILS/src/perlmods/lib/OpenILS/Utils/EDIReader.pm

index c5e9dbc..c0af836 100644 (file)
@@ -1156,53 +1156,62 @@ sub create_shipment_notification_from_edi {
 
     my $e = new_editor();
 
-    my $eg_asn = Fieldmapper::acq::shipment_notification->new;
-    $eg_asn->isnew(1);
+    # Uniqify the container codes
+    my %containers = map {$_->{container_code} => 1} @{$msg_data->{lineitems}};
 
-    # Some troubleshooting aids.  Yeah we should have made appropriate links
-    # for this in the schema, but this is better than nothing.  Probably
-    # *don't* try to i18n this.
-    $eg_asn->note("Generated from acq.edi_message #" . $edi_message->id . ".");
+    for my $container_code (keys %containers) {
+        $logger->info("ACQ processing container: $container_code");
 
-    $eg_asn->provider($provider_id);
-    $eg_asn->shipper($provider_id);
-    $eg_asn->recv_method('EDI');
+        my $eg_asn = Fieldmapper::acq::shipment_notification->new;
+        $eg_asn->isnew(1);
 
-    $eg_asn->recv_date( # invoice_date is a misnomer; should be message date.
-        $class->edi_date_to_iso($msg_data->{invoice_date}));
+        # Some troubleshooting aids.  Yeah we should have made appropriate links
+        # for this in the schema, but this is better than nothing.  Probably
+        # *don't* try to i18n this.
+        $eg_asn->note("Generated from acq.edi_message #" . $edi_message->id . ".");
 
-    $class->process_message_buyer($e, $msg_data, $edi_message, "ASN" , $eg_asn);
+        $eg_asn->provider($provider_id);
+        $eg_asn->shipper($provider_id);
+        $eg_asn->recv_method('EDI');
 
-    if (!$eg_asn->receiver) {
-        die(sprintf(
-            "Unable to determine buyer (org unit) in shipment notification; ".
-            "buyer_san=%s; buyer_acct=%s",
-            ($msg_data->{buyer_san} || ''), 
-            ($msg_data->{buyer_acct} || '')
-        ));
-    }
+        $eg_asn->recv_date( # invoice_date is a misnomer; should be message date.
+            $class->edi_date_to_iso($msg_data->{invoice_date}));
 
-    $eg_asn->container_code($msg_data->{container_code});
+        $class->process_message_buyer($e, $msg_data, $edi_message, "ASN" , $eg_asn);
 
-    die("No container code in DESADV message") unless $eg_asn->container_code;
+        if (!$eg_asn->receiver) {
+            die(sprintf(
+                "Unable to determine buyer (org unit) in shipment notification; ".
+                "buyer_san=%s; buyer_acct=%s",
+                ($msg_data->{buyer_san} || ''), 
+                ($msg_data->{buyer_acct} || '')
+            ));
+        }
 
-    my $entries = extract_shipment_notification_entries($msg_data->{lineitems});
+        $eg_asn->container_code($container_code);
 
-    $e->xact_begin;
+        die("No container code in DESADV message") unless $eg_asn->container_code;
+
+        my $entries = extract_shipment_notification_entries([
+            grep {$_->{container_code} eq $container_code} @{$msg_data->{lineitems}}]);
+
+        $e->xact_begin;
 
-    die "Error updating EDI message: " . $e->die_event
-        unless $e->update_acq_edi_message($edi_message);
+        die "Error updating EDI message: " . $e->die_event
+            unless $e->update_acq_edi_message($edi_message);
 
-    die "Error creating shipment notification: " . $e->die_event
-        unless $e->create_acq_shipment_notification($eg_asn);
+        die "Error creating shipment notification: " . $e->die_event
+            unless $e->create_acq_shipment_notification($eg_asn);
 
-    for my $entry (@$entries) {
-        $entry->shipment_notification($eg_asn->id);
-        die "Error creating shipment notification entry: " . $e->die_event
-            unless $e->create_acq_shipment_notification_entry($entry);
+        for my $entry (@$entries) {
+            $entry->shipment_notification($eg_asn->id);
+            die "Error creating shipment notification entry: " . $e->die_event
+                unless $e->create_acq_shipment_notification_entry($entry);
+        }
+
+        $e->xact_commit;
     }
 
-    $e->xact_commit;
     return 1;
 }
 
index bf8b7c3..5433f9f 100644 (file)
@@ -32,7 +32,8 @@ my %edi_fields = (
     invoice_ident   => qr/^BGM\+380\+([^\+]+)/,
     total_billed    => qr/^MOA\+86:([^:]+)/,
     invoice_date    => qr/^DTM\+137:([^:]+)/, # This is really "messge date"
-    container_code  => qr/^GIN\+BJ\+([^:]+)/,
+    # We don't retain a top-level container code -- they can repeat.
+    _container_code => qr/^GIN\+BJ\+([^:]+)/,
     lading_number   => qr/^RFF\+BM:([^:]+)/
 );
 
@@ -124,6 +125,15 @@ sub read {
 
         if (/$NEW_LIN_RE/) {
             $msg->{_current_li} = {};
+
+            # In DESADV messages there may be multiple container codes
+            # per message.  They precede the lineitems contained within
+            # each container.  Instead of restructuring the messages to
+            # be containers of lineitems, just tag each lineitem with
+            # its container if one is specified.
+            $msg->{_current_li}->{container_code} = 
+                $msg->{_container_code} if $msg->{_container_code};
+
             push(@{$msg->{lineitems}}, $msg->{_current_li});
         }