1 # ---------------------------------------------------------------
2 # Copyright (C) 2012 Equinox Software, Inc
3 # Author: Bill Erickson <berickr@esilibrary.com>
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 # ---------------------------------------------------------------
15 package OpenILS::Utils::EDIReader;
16 use strict; use warnings;
18 my $NEW_MSG_RE = '^UNH'; # starts a new message
19 my $NEW_LIN_RE = '^LIN'; # starts a new line item
22 message_type => qr/^UNH\+\d+\+(\S{6})/,
23 buyer_san => qr/^NAD\+BY\+([^:]+)/,
24 vendor_san => qr/^NAD\+SU\+([^:]+)/,
25 purchase_order => qr/^RFF\+ON:(\S+)/,
26 invoice_ident => qr/^BGM\+380\+([^\+]+)/,
27 total_billed => qr/^MOA\+86:(\d+)/
31 id => qr/^RFF\+LI:\S+\/(\S+)/,
32 index => qr/^LIN\+([^\+]+)/,
33 amount_billed => qr/^MOA\+203:(\d+)/,
34 net_unit_price => qr/^PRI\+AAA:(\d+)/,
35 gross_unit_price=> qr/^PRI\+AAB:(\d+)/,
36 expected_date => qr/^DTM\+44:([^:]+)/
39 my %edi_li_ident_fields = (
40 ident => qr/^LIN\+\S+\++([^:]+):?(\S+)?/,
41 ident2 => qr/^PIA\+0*5\+([^:]+):?(\S+)?/,
44 my %edi_li_quant_fields = (
45 code => qr/^QTY\+(\d+):/,
46 quantity => qr/^QTY\+\d+:(\d+)/
49 my %edi_charge_fields = (
50 charge_type => qr/^ALC\+C\++([^\+]+)/,
51 charge_amount => qr/^MOA\+(8|131):(\d+)/
55 return bless({}, shift());
63 open(EDI_FILE, $file) or die "Cannot open $file: $!\n";
64 my $edi = join('', <EDI_FILE>);
67 return $self->read($edi);
70 # Reads an EDI string and parses the package one "line" at a time, extracting
71 # needed information via regular expressions. Returns an array of messages,
72 # each represented as a hash. See %edi_*fields above for lists of which fields
73 # may be present within a message.
77 my $edi = shift or return [];
82 foreach (split(/'/, $edi)) {
85 # - starting a new message
88 $msg = {lineitems => [], misc_charges => []};
92 # extract top-level message fields
96 for my $field (keys %edi_fields) {
97 ($msg->{$field}) = $_ =~ /$edi_fields{$field}/
98 if /$edi_fields{$field}/;
101 # - starting a new lineitem
104 $msg->{_current_li} = {};
105 push(@{$msg->{lineitems}}, $msg->{_current_li});
108 # - extract lineitem fields
110 if (my $li = $msg->{_current_li}) {
112 for my $field (keys %edi_li_fields) {
113 ($li->{$field}) = $_ =~ /$edi_li_fields{$field}/g
114 if /$edi_li_fields{$field}/;
117 for my $field (keys %edi_li_ident_fields) {
118 if (/$edi_li_ident_fields{$field}/) {
119 my ($ident, $type) = $_ =~ /$edi_li_ident_fields{$field}/;
120 push(@{$li->{identifiers}}, {code => $type, value => $ident});
124 if (/$edi_li_quant_fields{quantity}/) {
126 ($quant->{quantity}) = $_ =~ /$edi_li_quant_fields{quantity}/;
127 ($quant->{code}) = $_ =~ /$edi_li_quant_fields{code}/;
128 push(@{$li->{quantities}}, $quant);
133 # - starting a new misc. charge
135 if (/$edi_charge_fields{charge_type}/) {
136 $msg->{_current_charge} = {};
137 push (@{$msg->{misc_charges}}, $msg->{_current_charge});
140 # - extract charge fields
142 if (my $charge = $msg->{_current_charge}) {
143 for my $field (keys %edi_charge_fields) {
144 ($charge->{$field}) = $_ =~ /$edi_charge_fields{$field}/
145 if /$edi_charge_fields{$field}/;
150 # remove the state-maintenance keys
151 for my $msg (@msgs) {
152 foreach (grep /^_/, keys %$msg) {