From: Bill Erickson Date: Thu, 2 Dec 2021 22:16:06 +0000 (-0500) Subject: LP1952931 ASN shipment notifiation Perl X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=3e4cece6dd39eb3ab5a4b934ddc7c5c034f88d0c;p=working%2FEvergreen.git LP1952931 ASN shipment notifiation Perl Signed-off-by: Bill Erickson --- diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/EDI.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/EDI.pm index 55570272dd..c7f1e26acd 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/EDI.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/EDI.pm @@ -636,6 +636,10 @@ sub process_parsed_msg { if ($incoming->message_type eq 'INVOIC') { return $class->create_acq_invoice_from_edi( $msg_hash, $account->provider, $incoming); + + } elsif ($incoming->message_type eq 'DESADV') { + return $class->create_shipment_notification_from_edi( + $msg_hash, $account->provider, $incoming); } # ORDRSP @@ -1070,6 +1074,7 @@ sub create_acq_invoice_from_edi { # those. my ($eg_inv_entries, $unknowns) = process_invoice_lineitems( $e, \%msg_kludges, $log_prefix, $message, $msg_data->{lineitems} + ); if (@$unknowns) { @@ -1140,5 +1145,125 @@ sub create_acq_invoice_from_edi { return 1; } +sub create_shipment_notification_from_edi { + my ($class, $msg_data, $provider_id, $edi_message) = @_; + # $msg_data is O::U::EDIReader hash + + my $e = new_editor(); + + my $eg_asn = Fieldmapper::acq::shipment_notification->new; + $eg_asn->isnew(1); + + # 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 . "."); + + $eg_asn->provider($provider_id); + $eg_asn->shipper($provider_id); + $eg_asn->recv_method('EDI'); + + $eg_asn->recv_date( # invoice_date is a misnomer; should be message date. + $class->edi_date_to_iso($msg_data->{invoice_date})); + + $class->process_message_buyer($e, $msg_data, $edi_message, "ASN" , $eg_asn); + + 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->container_code($msg_data->{container_code}); + + die("No container code in DESADV message") unless $eg_asn->container_code; + + my $entries = extract_shipment_notification_entries($msg_data->{lineitems}); + + $e->xact_begin; + + 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); + + 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; + return 1; +} + +sub extract_shipment_notification_entries { + my ($lineitem_hashes) = @_; + + my $e = new_editor(); + my @entries; + for my $li_hash (@$lineitem_hashes) { + + # A shipment notification may cover multiple PO's. + # Each LI will include its own PO ID. + my $po_id = $li_hash->{purchase_order}; + + unless ($po_id) { + $logger->warn("Skipping ASN lineitem which has no PO ID"); + next; + } + + my ($quant) = grep {$_->{code} eq '12'} @{$li_hash->{quantities}}; + my $quantity = ($quant) ? $quant->{quantity} : 0; + + # LI identifiers map to order identifiers, not lineitem IDs, + # at least not in the data seen so far. + my $li_id; + for my $ident_spec (@{$li_hash->{identifiers}}) { + + my $ident = $ident_spec->{value}; + next unless $ident; + + my $li_id_hash = $e->json_query({ + select => {jub => ['id']}, + from => { + jub => { + acqlia => { + filter => {order_ident => 't', value => $ident} + } + } + }, + where => {'+jub' => {purchase_order => $po_id}} + })->[0]; + + if ($li_id_hash) { + $li_id = $li_id_hash->{id}; + last; + } else { + $logger->warn("Cannot find lineitem with order ". + "identifier=$ident and purchase_order=$po_id"); + } + } + + unless ($li_id) { + $logger->warn("Cannot find lineitem for ASN entry; skippping"); + next; + } + + my $entry = Fieldmapper::acq::shipment_notification_entry->new; + + $entry->lineitem($li_id); + $entry->item_count($quant); + + push(@entries, $entry); + } + + return \@entries; +} + 1; diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Utils/EDIReader.pm b/Open-ILS/src/perlmods/lib/OpenILS/Utils/EDIReader.pm index e68f6eabdf..cd2ecbeb1d 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Utils/EDIReader.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Utils/EDIReader.pm @@ -114,11 +114,6 @@ sub read { next unless $msg; for my $field (keys %edi_fields) { - - # With ASN, a purchase_order value specified per lineitem. - # Avoid tracking a message-level PO to avoid confusion. - next if $msg->{message_type} eq 'DESADV' && $field eq 'purchase_order'; - ($msg->{$field}) = $_ =~ /$edi_fields{$field}/ if /$edi_fields{$field}/; }