From: Galen Charlton Date: Tue, 22 Aug 2017 20:00:47 +0000 (-0400) Subject: LP#1373690: normalize IMD values better X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=e4b050edc3a6d9ca8202f9747f673b00004483db;p=Evergreen.git LP#1373690: normalize IMD values better The EDItEUR book ORDERS message allows two 35-character item description data elements in IMD segments; this patch accounts for that. It also, for IMD fields, uses the EDIFACT release character to escape certain characters, better matching how the Ruby EDI translator did it. Signed-off-by: Galen Charlton Signed-off-by: Bill Erickson Signed-off-by: Mike Rylander --- diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Utils/EDIWriter.pm b/Open-ILS/src/perlmods/lib/OpenILS/Utils/EDIWriter.pm index 2b94467f13..3b4cdfdbea 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Utils/EDIWriter.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Utils/EDIWriter.pm @@ -65,7 +65,16 @@ sub get_po { ]); } -sub escape_edi { +sub add_release_characters { + my ($self, $value) = @_; + return '' if (not defined $value || ref($value)); + + # escape ? ' + : with the release character ? + $value =~ s/([\?'\+:])/?$1/g; + + return $value; +} +sub escape_edi_imd { my ($self, $value) = @_; return '' if (not defined $value || ref($value)); @@ -79,16 +88,28 @@ sub escape_edi { # LP #812593). $value =~ s/[\[\]]//g; - # Characters [? + ' \ : ] are all potentially problematic for + # Characters [\ ] are all potentially problematic for # EDI messages, regardless of their position in the string. - # Safest to simply remove them. - $value =~ s/[\\\?\+':]//g; + # Safest to simply remove them. Note that unlike escape_edi(), + # we're not stripping out +, ', :, and + because we'll escape + # them when buidling IMD segments + $value =~ s/[\\]//g; # Replace newlines with spaces. $value =~ s/\n/ /g; return $value; } +sub escape_edi { + my ($self, $value) = @_; + + my $str = $self->escape_edi_imd($value); + + # further strip + ' : + + $str =~ s/[\?\+':]//g; + + return $str; +} # Returns an EDI-escaped version of the requested lineitem attribute # value. If $attr_type is not set, the first attribute found matching @@ -105,6 +126,20 @@ sub get_li_attr { return ''; } +# Like get_li_attr, but don't strip out ? + : ' as we'll +# escape them later +sub get_li_attr_imd { + my ($self, $li, $attr_name, $attr_type) = @_; + + for my $attr (@{$li->attributes}) { + next unless $attr->attr_name eq $attr_name; + next if $attr_type && $attr->attr_type ne $attr_type; + return $self->escape_edi_imd($attr->attr_value); + } + + return ''; +} + # Generates a HASH version of the PO with all of the data necessary # to generate an EDI message from the PO. sub compile_po { @@ -264,7 +299,7 @@ sub compile_li { $self->set_li_order_ident($li, $li_hash); for my $name (qw/title author edition pubdate publisher pagination/) { - $li_hash->{$name} = $self->get_li_attr($li, $name); + $li_hash->{$name} = $self->get_li_attr_imd($li, $name); } $self->compile_copies($li, $li_hash); @@ -345,8 +380,8 @@ sub compile_copy { }); } -# IMD fields are limited to 70 chars per value. Any values longer -# should be carried via repeating IMD fields. +# IMD fields are limited to 70 chars per value over two DEs. +# Any values longer # should be carried via repeating IMD fields. # IMD fields should only display the +::: when a value is present sub IMD { my ($self, $code, $value) = @_; @@ -359,7 +394,16 @@ sub IMD { if ($value) { my $s = ''; for my $part ($value =~ m/.{1,70}/g) { - $s .= "IMD+F+$code+:::$part'\n"; } + my $de; + if (length($part) > 35) { + $de = $self->add_release_characters(substr($part, 0, 35)) . + ':' . + $self->add_release_characters(substr($part, 35)); + } else { + $de = $self->add_release_characters($part); + } + $s .= "IMD+F+$code+:::$de'\n"; + } return $s; } else {