From 1d48c734c75ab59800e540ee855239dec5cfa295 Mon Sep 17 00:00:00 2001 From: erickson Date: Thu, 29 Apr 2010 20:28:36 +0000 Subject: [PATCH] Subsequent EDI patch from Joe Atzberger. In this installmanent, EDI really does some stuff. Also included are a number of test scripts and some mild code cleanup git-svn-id: svn://svn.open-ils.org/ILS/trunk@16353 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- Open-ILS/examples/fm_IDL.xml | 1 + Open-ILS/src/extras/Makefile.install | 1 + .../src/perlmods/OpenILS/Application/Acq/EDI.pm | 174 +- .../perlmods/OpenILS/Application/Acq/Lineitem.pm | 173 +- .../src/perlmods/OpenILS/Application/CreditCard.pm | 2 +- Open-ILS/src/perlmods/OpenILS/Utils/Cronscript.pm | 100 + Open-ILS/src/perlmods/OpenILS/Utils/Editor.pm | 8 +- .../src/perlmods/OpenILS/Utils/RemoteAccount.pm | 44 +- Open-ILS/src/sql/Pg/002.schema.config.sql | 2 +- .../upgrade/0167.data.event_definition_po_jedi.sql | 2 +- .../sql/Pg/upgrade/0245.schema.acq_edi_message.sql | 7 + .../upgrade/0246.data.event_definition_po_jedi.sql | 64 + Open-ILS/src/support-scripts/Cstore_test.t | 60 + Open-ILS/src/support-scripts/Cstore_test2.t | 62 + .../clear_expired_circ_history.srfsh | 2 +- Open-ILS/src/support-scripts/edi_fetcher.pl | 64 + Open-ILS/src/support-scripts/edi_pusher.pl | 104 + .../src/support-scripts/test-scripts/edi_object.pl | 2985 +++++++++++++++++++ Open-ILS/src/support-scripts/test-scripts/ftp.pl | 83 + .../src/support-scripts/test-scripts/ftp_ls.pl | 131 + .../src/support-scripts/test-scripts/net_ssh2.pl | 52 + .../support-scripts/test-scripts/net_ssh2_ls.pl | 43 + Open-ILS/src/support-scripts/test-scripts/notes.pl | 2 +- .../support-scripts/test-scripts/ordrsp_parse.pl | 3058 ++++++++++++++++++++ .../support-scripts/test-scripts/payment_test.pl | 2 +- .../js/ui/default/conify/global/acq/edi_account.js | 23 + Open-ILS/web/opac/locale/en-US/lang.dtd | 2 + .../default/conify/global/acq/edi_account.tt2 | 69 + .../default/conify/global/acq/provider.tt2 | 27 +- .../xul/staff_client/chrome/content/main/menu.js | 4 + .../chrome/content/main/menu_frame_menus.xul | 2 + .../staff_client/chrome/content/util/fm_view.xul | 6 +- .../chrome/locale/en-US/offline.properties | 1 + build/tools/update.sh | 1 + 34 files changed, 7215 insertions(+), 146 deletions(-) create mode 100644 Open-ILS/src/sql/Pg/upgrade/0245.schema.acq_edi_message.sql create mode 100644 Open-ILS/src/sql/Pg/upgrade/0246.data.event_definition_po_jedi.sql create mode 100644 Open-ILS/src/support-scripts/Cstore_test.t create mode 100644 Open-ILS/src/support-scripts/Cstore_test2.t create mode 100644 Open-ILS/src/support-scripts/edi_fetcher.pl create mode 100644 Open-ILS/src/support-scripts/edi_pusher.pl create mode 100644 Open-ILS/src/support-scripts/test-scripts/edi_object.pl create mode 100644 Open-ILS/src/support-scripts/test-scripts/ftp.pl create mode 100644 Open-ILS/src/support-scripts/test-scripts/ftp_ls.pl create mode 100644 Open-ILS/src/support-scripts/test-scripts/net_ssh2.pl create mode 100644 Open-ILS/src/support-scripts/test-scripts/net_ssh2_ls.pl create mode 100644 Open-ILS/src/support-scripts/test-scripts/ordrsp_parse.pl create mode 100644 Open-ILS/web/js/ui/default/conify/global/acq/edi_account.js create mode 100644 Open-ILS/web/templates/default/conify/global/acq/edi_account.tt2 diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml index bd4886dc5..67387789f 100644 --- a/Open-ILS/examples/fm_IDL.xml +++ b/Open-ILS/examples/fm_IDL.xml @@ -5795,6 +5795,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + diff --git a/Open-ILS/src/extras/Makefile.install b/Open-ILS/src/extras/Makefile.install index 8df11b3c5..454a70bf1 100644 --- a/Open-ILS/src/extras/Makefile.install +++ b/Open-ILS/src/extras/Makefile.install @@ -230,6 +230,7 @@ DEB_APACHE_DISMODS = \ # Chronically unpackaged CPAN modules CPAN_MODULES = \ Business::CreditCard::Object \ + Business::EDI \ Net::uFTP \ Net::Z3950::Simple2ZOOM \ UUID::Tiny \ diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Acq/EDI.pm b/Open-ILS/src/perlmods/OpenILS/Application/Acq/EDI.pm index aebd43af8..1e303a304 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Acq/EDI.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Acq/EDI.pm @@ -10,11 +10,15 @@ use OpenSRF::EX qw/:try/; use OpenSRF::Utils::Logger qw(:logger); use OpenSRF::Utils::JSON; +use OpenILS::Application::Acq::Lineitem; use OpenILS::Utils::RemoteAccount; use OpenILS::Utils::CStoreEditor q/new_editor/; use OpenILS::Utils::Fieldmapper; use OpenILS::Application::Acq::EDI::Translator; +use Business::EDI; +use Business::EDI::Segment::BGM; + use Data::Dumper; our $verbose = 0; @@ -111,7 +115,7 @@ sub retrieve_core { $e->create_acq_edi_message($incoming); $e->xact_commit; __PACKAGE__->record_activity($account, $e); - __PACKAGE__->process_jedi($incoming, $e); + __PACKAGE__->process_jedi($incoming, $server, $e); # $server->delete(remote_file => $_); # delete remote copies of saved message push @return, $incoming->id; } @@ -317,43 +321,185 @@ sub jedi2perl { my ($class, $jedi) = @_; $jedi or return; my $msg = OpenSRF::Utils::JSON->JSON2perl( $jedi ); - open (FOO, ">>/tmp/joe_jedi_dump.txt"); + open (FOO, ">>/tmp/JSON2perl_dump.txt"); print FOO Dumper($msg), "\n\n"; close FOO; $logger->warn("Dumped JSON2perl to /tmp/JSON2perl_dump.txt"); return $msg; } -# ->process_jedi($message, $e) +# ->process_jedi($message, $server, $e) sub process_jedi { my $class = shift; my $message = shift or return; + my $server = shift || {}; # context my $jedi = ref($message) ? $message->jedi : $message; # If we got an object, it's an edi_message. A string is the jedi content itself. unless ($jedi) { $logger->warn("EDI process_jedi missing required argument (edi_message object with jedi or jedi scalar)!"); return; } + my $e = @_ ? shift : new_editor(); my $perl = __PACKAGE__->jedi2perl($jedi); if (ref($message) and not $perl) { - my $e = @_ ? shift : new_editor(); - $message->error(($message->error || '') . " JSON2perl FAILED to convert jedi"); + $message->error(($message->error || '') . " JSON2perl (jedi2perl) FAILED to convert jedi"); $message->error_time('NOW'); $e->xact_begin; $e->udpate_acq_edi_message($message) or $logger->warn("EDI update_acq_edi_message failed! $!"); $e->xact_commit; + return; + } + if (! $perl->{body}) { + $logger->warn("EDI interchange body not found!"); + return; + } + if (! $perl->{body}->[0]) { + $logger->warn("EDI interchange body not a populated arrayref!"); + return; + } + +# Crazy data structure. Most of the arrays will be 1 element... we think. +# JEDI looks like: +# {'body' => [{'ORDERS' => [['UNH',{'0062' => '4635','S009' => {'0057' => 'EAN008','0051' => 'UN','0052' => 'D','0065' => 'ORDERS', ... +# +# So you might access it like: +# $obj->{body}->[0]->{ORDERS}->[0]->[0] eq 'UNH' + + $logger->info("EDI interchange body has " . scalar(@{$perl->{body}}) . " messages(s)"); + my @li; + my $i = 0; + foreach my $part (@{$perl->{body}}) { + $i++; + unless (ref $part and scalar keys %$part) { + $logger->warn("EDI interchange message $i lacks structure. Skipping it."); + next; + } + foreach my $key (keys %$part) { + unless ($key eq 'ORDRSP') { # We only do one type for now. TODO: other types here + $logger->warn("EDI interchange message $i contains unhandled type '$key'. Ignoring."); + next; + } + my @li_chunk = __PACKAGE__->parse_ordrsp($part->{$key}, $server, $e); + $logger->info("EDI $key parsing returned " . scalar(@li_chunk) . " line items"); + push @li, @li_chunk; + } + } + return \@li, $perl; # TODO process perl +} + + +=head2 ->parse_ordrsp($segments, $server, $e) + +Returns array of lineitems. + +=cut + +# TODO: Build Business::EDI::Message::ORDRSP object instead +# TODO: Convert access to methods, not reaching inside the data/object like $segbody->{S009}->{'0065'} + +sub parse_ordrsp { + my ($class, $segments, $server, $e, $test) = @_; # test not implemented + $e ||= new_editor(); + my $type = 'ORDRSP'; + $logger->info("EDI " . scalar(@$segments) . " segments in $type message"); + my (@lins, $bgm); + foreach my $segment (@$segments) { # Prepass: catch the conditions that might cause us to bail + my ($tag, $segbody, @extra) = @$segment; + unless ($tag ) {$logger->warn("EDI empty segment received" ); next;} + unless ($segbody) {$logger->warn("EDI segment '$tag' missing body"); next;} + @extra and $logger->warn("EDI extra data (" . scalar(@extra) . " elements) found after pseudohash pair for $tag"); + if ($tag eq 'UNH') { + unless ($segbody->{S009}->{'0065'} and $segbody->{S009}->{'0065'} eq $type) { + $logger->error("EDI $tag/S009/0065 ('" . ($segbody->{S009}->{'0065'} || '') . "') conflict w/ message type $type\. Aborting"); + return; + } + unless ($segbody->{S009}->{'0051'} and $segbody->{S009}->{'0051'} eq 'UN') { + $logger->warn("EDI $tag/S009/0051 does not designate 'UN' as controlling agency. Will attempt to process anyway"); + } + } elsif ($tag eq 'BGM') { + $bgm = Business::EDI::Segment::BGM->new($segbody); + $bgm->seg4343 or $logger->warn(sprintf "EDI $tag/4343 Response Type Code '%s' unrecognized", ($segbody->{4343} || '')); + $logger->info(sprintf "EDI $tag/4343 response type: %s - %s (%s)", $bgm->seg4343->value, $bgm->seg4343->label, $bgm->seg4343->desc); + my $fcn = $bgm->seg1225; + unless ($fcn) { + $logger->error(sprintf "EDI $tag/1225 Message Function Code '%s' unrecognized. Aborting", ($segbody->{1225} || '')); + return; + } + } } - # __PACKAGE__->process_eval_msg(__PACKAGE__->jedi2perl($jedi), @_); - return $perl; # TODO process perl + my @ignored; + foreach my $segment (@$segments) { # The main pass + my ($tag, $segbody, @extra) = @$segment; + next unless ($tag and $segbody); # warnings above + if ($tag eq 'LIN') { + my @chunks = @{$segbody->{SG26}}; + my $count = scalar(@chunks); + $logger->debug("EDI LIN/SG26 has $count chunks"); +# CHUNK: +# ["RFF", { +# "C506": { +# "1153": "LI", +# "1154": "4639/1" +# } +# }] + foreach (@chunks) { + my $label = $_->[0]; + my $body = $_->[1]; + # $label eq 'QTY' and push @qtys, $body; + $label eq 'RFF' or next; + my $obj; + unless ($obj = Business::EDI::Segment::RFF->new($body)) { # assignment, not comparison + $logger->error("EDI $tag/$label failed to convert to an object"); + } + $obj->seg1153 and $obj->seg1153->value eq 'LI' or $logger->warn("EDI $tag/$label object unexpected 1153 value (not 'LI')"); + __PACKAGE__->update_li($obj->seg1154->value, $segbody, $server, $e); + } + push @lins, \@chunks; + } elsif ($tag ne 'UNH' and $tag ne 'BGM') { + push @ignored, $tag; + } + } + @ignored and $logger->debug("EDI: ignoring " . scalar(@ignored) . " segment(s): " . join(', ', @ignored)); + return @lins; } -sub process_eval_msg { - my ($class, $msg, $e) = @_; - $msg or return; +=head2 ->update_li($lineitem_id, $lineitem_object, [$server, $editor]) + +Updates: + acq.lineitem.estimated_unit_price, + acq.lineitem.state (dependent on mapping codes), + acq.lineitem.expected_recv_time, + acq.lineitem.edit_time (consequently) + +=cut + +sub update_li { + my ($class, $id, $object, $server, $e) = @_; $e ||= new_editor(); -## Do all the hard work. -# ID the message type -# Find PO references -# update POs & lineitems(?) + $id =~ s#^.*\/##; # Temporary fix for mbklein's testdata + print STDERR "Here we would retrieve/update lineitem $id\n"; + my $li = OpenILS::Application::Acq::Lineitem::retrieve_lineitem_impl($e, $id); # Could send {options} + if (! $li or ref($li) ne 'Fieldmapper::acq::lineitem') { + $logger->error("EDI failed to retrieve lineitem by id '$id'"); + return; + } + unless ((! $server) or (! $server->provider)) { + if ($server->provider != $li->provider) { + # links go both ways: acq.provider.edi_default and acq.edi_account.provider + $logger->info("EDI acct provider (" . $server->provider. ") doesn't match lineitem provider(" + . $li->provider . "). Checking acq.provider.edi_default..."); + my $provider = $e->retrieve_acq_provider($li->provider); + if ($provider->edi_default != $server->id) { + $logger->error(sprintf "EDI provider/acct %s/%s (%s) is blocked from updating lineitem $id belonging to provider/edi_default %s/%s", + $server->provider, $server->id, $server->label, $li->provider, $provider->edi_default); + return; + } + } + } + return; # TODO: actual updates + $e->xact_begin; + $e->update_acq_lineitem($li) or $logger->warn("EDI: in update_li, update_acq_lineitem FAILED"); + $e->xact_commit; + # print STDERR "Lineitem to update: ", Dumper($li); } 1; diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Acq/Lineitem.pm b/Open-ILS/src/perlmods/OpenILS/Application/Acq/Lineitem.pm index 691771acc..bce94cf45 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Acq/Lineitem.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Acq/Lineitem.pm @@ -70,11 +70,14 @@ __PACKAGE__->register_method( signature => { desc => 'Retrieves a lineitem', params => [ - {desc => 'Authentication token', type => 'string'}, + {desc => 'Authentication token', type => 'string'}, {desc => 'lineitem ID to retrieve', type => 'number'}, - {options => q/Hash of options, including - "flesh_attrs", which fleshes the attributes; - "flesh_li_details", which fleshes the order details objects/, type => 'hash'}, + {options => q/Hash of options, including: +flesh_attrs : for attributes, +flesh_notes : for notes, +flesh_cancel_reason : for cancel reason, +flesh_li_details : for order details objects, +clear_marc : to clear marcxml from lineitem/, type => 'hash'}, ], return => {desc => 'lineitem object on success, Event on error'} } @@ -269,10 +272,10 @@ __PACKAGE__->register_method( signature => { desc => 'Searches lineitems', params => [ - {desc => 'Authentication token', type => 'string'}, - {desc => 'Search definition', type => 'object'}, + {desc => 'Authentication token', type => 'string'}, + {desc => 'Search definition', type => 'object'}, {desc => 'Options hash. idlist=true', type => 'object'}, - {desc => 'List of lineitems', type => 'object/number'}, + {desc => 'List of lineitems', type => 'object/number'}, ] } ); @@ -296,9 +299,9 @@ sub lineitem_search { } __PACKAGE__->register_method ( - method => 'lineitems_related_by_bib', - api_name => 'open-ils.acq.lineitems_for_bib.by_bib_id', - stream => 1, + method => 'lineitems_related_by_bib', + api_name => 'open-ils.acq.lineitems_for_bib.by_bib_id', + stream => 1, signature => q/ Retrieves lineitems attached to same bib record, subject to the PO ordering agency. This variant takes the bib id. @param authtoken Login session key @@ -308,9 +311,9 @@ __PACKAGE__->register_method ( ); __PACKAGE__->register_method ( - method => 'lineitems_related_by_bib', - api_name => 'open-ils.acq.lineitems_for_bib.by_lineitem_id', - stream => 1, + method => 'lineitems_related_by_bib', + api_name => 'open-ils.acq.lineitems_for_bib.by_lineitem_id', + stream => 1, signature => q/ Retrieves lineitems attached to same bib record, subject to the PO ordering agency. This variant takes the id for any of the pertinent lineitems. @param authtoken Login session key @@ -320,9 +323,9 @@ __PACKAGE__->register_method ( ); __PACKAGE__->register_method ( - method => 'lineitems_related_by_bib', - api_name => 'open-ils.acq.lineitems_for_bib.by_lineitem_id.count', - stream => 1, + method => 'lineitems_related_by_bib', + api_name => 'open-ils.acq.lineitems_for_bib.by_lineitem_id.count', + stream => 1, signature => q/See open-ils.acq.lineitems_for_bib.by_lineitem_id. This version returns numbers of lineitems only (XXX may count lineitems we don't actually have permission to retrieve)/ ); @@ -391,11 +394,11 @@ sub lineitems_related_by_bib { __PACKAGE__->register_method( - method => "lineitem_search_by_attributes", - api_name => "open-ils.acq.lineitem.search.by_attributes", - stream => 1, + method => "lineitem_search_by_attributes", + api_name => "open-ils.acq.lineitem.search.by_attributes", + stream => 1, signature => { - desc => "Performs a search against lineitem_attrs", + desc => "Performs a search against lineitem_attrs", params => [ {desc => "Authentication token", type => "string"}, { desc => q/ @@ -419,11 +422,11 @@ Options hash: ); __PACKAGE__->register_method( - method => "lineitem_search_by_attributes", - api_name => "open-ils.acq.lineitem.search.by_attributes.ident", - stream => 1, + method => "lineitem_search_by_attributes", + api_name => "open-ils.acq.lineitem.search.by_attributes.ident", + stream => 1, signature => { - desc => "Performs a search against lineitem_attrs where ident is true.". + desc => "Performs a search against lineitem_attrs where ident is true. ". "See open-ils.acq.lineitem.search.by_attributes for params." } ); @@ -519,9 +522,9 @@ sub lineitem_search_by_attributes { __PACKAGE__->register_method( - method => 'lineitem_search_ident', - api_name => 'open-ils.acq.lineitem.search.ident', - stream => 1, + method => 'lineitem_search_ident', + api_name => 'open-ils.acq.lineitem.search.ident', + stream => 1, signature => { desc => 'Performs a search against lineitem_attrs where ident is true', params => [ @@ -546,20 +549,20 @@ __PACKAGE__->register_method( ); my $LI_ATTR_SEARCH = { - select => {acqlia => ['lineitem']}, - from => { + select => { acqlia => ['lineitem'] }, + from => { acqlia => { acqliad => { field => 'id', - fkey => 'definition' + fkey => 'definition' }, jub => { field => 'id', - fkey => 'lineitem', - join => { + fkey => 'lineitem', + join => { acqpo => { field => 'id', - fkey => 'purchase_order' + fkey => 'purchase_order' } } } @@ -622,9 +625,9 @@ sub lineitem_search_ident { # this call duplicates a call in Order.pm and makes references to subs that don't exist. # TODO: Verify then remove. __PACKAGE__->register_method( - method => 'lineitem_detail_CUD_batch', - api_name => 'open-ils.acq.lineitem_detail.cud.batch_', - stream => 1, + method => 'lineitem_detail_CUD_batch', + api_name => 'open-ils.acq.lineitem_detail.cud.batch_', + stream => 1, signature => { desc => q/Creates a new purchase order line item detail. Additionally creates the associated fund_debit/, @@ -718,15 +721,15 @@ sub update_li_edit_time { __PACKAGE__->register_method( - method => 'retrieve_lineitem_detail', - api_name => 'open-ils.acq.lineitem_detail.retrieve', - signature => { - desc => q/Updates a lineitem detail/, + method => 'retrieve_lineitem_detail', + api_name => 'open-ils.acq.lineitem_detail.retrieve', + signature => { + desc => q/Updates a lineitem detail/, params => [ - {desc => 'Authentication token', type => 'string'}, - {desc => 'id of lineitem_detail to retrieve', type => 'number'}, + { desc => 'Authentication token', type => 'string' }, + { desc => 'id of lineitem_detail to retrieve', type => 'number' }, ], - return => {desc => 'object on success, Event on failure'} + return => { desc => 'object on success, Event on failure' } } ); sub retrieve_lineitem_detail { @@ -748,17 +751,16 @@ sub retrieve_lineitem_detail { } - __PACKAGE__->register_method( - method => 'approve_lineitem', - api_name => 'open-ils.acq.lineitem.approve', - signature => { - desc => 'Mark a lineitem as approved', + method => 'approve_lineitem', + api_name => 'open-ils.acq.lineitem.approve', + signature => { + desc => 'Mark a lineitem as approved', params => [ - {desc => 'Authentication token', type => 'string'}, - {desc => 'lineitem ID', type => 'number'} + { desc => 'Authentication token', type => 'string' }, + { desc => 'lineitem ID', type => 'number' } ], - return => {desc => '1 on success, Event on error'} + return => { desc => '1 on success, Event on error' } } ); sub approve_lineitem { @@ -797,32 +799,32 @@ sub approve_lineitem { __PACKAGE__->register_method( - method => 'set_lineitem_attr', - api_name => 'open-ils.acq.lineitem_usr_attr.set', - signature => { - desc => 'Sets a lineitem_usr_attr value', + method => 'set_lineitem_attr', + api_name => 'open-ils.acq.lineitem_usr_attr.set', + signature => { + desc => 'Sets a lineitem_usr_attr value', params => [ - {desc => 'Authentication token', type => 'string'}, - {desc => 'Lineitem ID', type => 'number'}, - {desc => 'Attr name', type => 'string'}, - {desc => 'Attr value', type => 'string'} + { desc => 'Authentication token', type => 'string' }, + { desc => 'Lineitem ID', type => 'number' }, + { desc => 'Attr name', type => 'string' }, + { desc => 'Attr value', type => 'string' } ], - return => {desc => '1 on success, Event on error'} + return => { desc => '1 on success, Event on error' } } ); __PACKAGE__->register_method( - method => 'set_lineitem_attr', - api_name => 'open-ils.acq.lineitem_local_attr.set', - signature => { - desc => 'Sets a lineitem_local_attr value', + method => 'set_lineitem_attr', + api_name => 'open-ils.acq.lineitem_local_attr.set', + signature => { + desc => 'Sets a lineitem_local_attr value', params => [ - {desc => 'Authentication token', type => 'string'}, - {desc => 'Lineitem ID', type => 'number'}, - {desc => 'Attr name', type => 'string'}, - {desc => 'Attr value', type => 'string'} + { desc => 'Authentication token', type => 'string' }, + { desc => 'Lineitem ID', type => 'number' }, + { desc => 'Attr name', type => 'string' }, + { desc => 'Attr value', type => 'string' } ], - return => {desc => 'ID of the attr object on success, Event on error'} + return => { desc => 'ID of the attr object on success, Event on error' } } ); @@ -865,14 +867,12 @@ sub set_lineitem_attr { } __PACKAGE__->register_method( - method => 'get_lineitem_attr_defs', - api_name => 'open-ils.acq.lineitem_attr_definition.retrieve.all', - signature => { - desc => 'Retrieve lineitem attr definitions', - params => [ - {desc => 'Authentication token', type => 'string'}, - ], - return => {desc => 'List of attr definitions'} + method => 'get_lineitem_attr_defs', + api_name => 'open-ils.acq.lineitem_attr_definition.retrieve.all', + signature => { + desc => 'Retrieve lineitem attr definitions', + params => [ { desc => 'Authentication token', type => 'string' }, ], + return => { desc => 'List of attr definitions' } } ); @@ -890,16 +890,17 @@ sub get_lineitem_attr_defs { __PACKAGE__->register_method( - method => 'lineitem_note_CUD_batch', - api_name => 'open-ils.acq.lineitem_note.cud.batch', - stream => 1, - signature => { - desc => q/Manage lineitem notes/, + method => 'lineitem_note_CUD_batch', + api_name => 'open-ils.acq.lineitem_note.cud.batch', + stream => 1, + signature => { + desc => q/Manage lineitem notes/, params => [ - {desc => 'Authentication token', type => 'string'}, - {desc => 'List of lineitem_notes to manage', type => 'array'}, + { desc => 'Authentication token', type => 'string' }, + { desc => 'List of lineitem_notes to manage', type => 'array' }, ], - return => {desc => 'Streaming response of current position in the array'} + return => + { desc => 'Streaming response of current position in the array' } } ); @@ -946,7 +947,7 @@ sub lineitem_note_CUD_batch { __PACKAGE__->register_method( method => 'ranged_line_item_alert_text', - api_name => 'open-ils.acq.line_item_alert_text.ranged.retrieve.all'); + api_name => 'open-ils.acq.line_item_alert_text.ranged.retrieve.all'); # TODO: signature sub ranged_line_item_alert_text { my($self, $conn, $auth, $org_id, $depth) = @_; diff --git a/Open-ILS/src/perlmods/OpenILS/Application/CreditCard.pm b/Open-ILS/src/perlmods/OpenILS/Application/CreditCard.pm index 35e66a501..10d779c2d 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/CreditCard.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/CreditCard.pm @@ -2,7 +2,7 @@ # Copyright (C) 2008 Niles Ingalls # Niles Ingalls # Bill Erickson -# Joe Atzberger +# Joe Atzberger # Lebbeous Fogle-Weekley # # This program is free software; you can redistribute it and/or diff --git a/Open-ILS/src/perlmods/OpenILS/Utils/Cronscript.pm b/Open-ILS/src/perlmods/OpenILS/Utils/Cronscript.pm index 7a967730a..89b3cd9c2 100644 --- a/Open-ILS/src/perlmods/OpenILS/Utils/Cronscript.pm +++ b/Open-ILS/src/perlmods/OpenILS/Utils/Cronscript.pm @@ -31,6 +31,7 @@ use OpenSRF::Utils::JSON; use OpenSRF::EX qw(:try); use OpenILS::Utils::Fieldmapper; use OpenILS::Utils::Lockfile; +use OpenILS::Utils::CStoreEditor q/:funcs/; use File::Basename qw/fileparse/; @@ -268,4 +269,103 @@ sub bootstrap { }; } +sub editor_init { + my $self = shift or return; + OpenILS::Utils::CStoreEditor::init(); # no return value to check + $self->{editor_inited} = 1; +} + +sub editor { + my $self = shift or return; + $self->{bootstrapped} or $self->bootstrap(); + $self->{editor_inited} or $self->editor_init(); + return new_editor(@_); +} + 1; +__END__ + +=pod + +=head1 NAME + +OpenILS::Utils::Cronscript - Consolidated options handling for any script (not just cron, really) + +=head1 SYNOPSIS + + use OpenILS::Utils::Cronscript; + + my %defaults = ( + 'min=i' => 0, # keys are Getopt::Long style options + 'max=i' => 999, # values are default values + 'user=s' => 'admin', + 'password=s' => '', + 'nolockfile' => 1, + }; + + my $core = OpenILS::Utils::Cronscript->new(\%defaults); + my $opts = $core->MyGetOptions(); # options now in, e.g.: $opts->{max} + $ocre->bootstrap; + +Or if you don't need any additional options and just want to get a session going: + + use OpenILS::Utils::Cronscript; + my $session = OpenILS::Utils::Cronscript->new()->session('open-ils.acq'); + +=head1 DESCRIPTION + +There are a few main problems when writing a new script for Evergreen. + +=head2 Initialization + +The runtime +environment for the application requires a lot of initialization, but during normal operation it +has already occured (when Evergreen was started). So most of the EG code never has to deal with +this problem, but standalone scripts do. The timing and sequence of requisite events is important and not obvious. + +=head2 Common Options, Consistent Options + +We need several common options for each script that accesses the database or +uses EG data objects and methods. Logically, these options often deal with initialization. They +should take the B same form(s) for each script and should not be +dependent on the local author to copy and paste them from some reference source. We really don't want to encourage (let alone force) +admins to use C<--config>, C<--osrf-confg>, C<-c>, and C<@ARGV[2]> for the same purpose in different scripts, with different +default handling, help descriptions and error messages (or lack thereof). + +This suggests broader problem of UI consistency and uniformity, also partially addressed by this module. + +=head2 Lockfiles + +A lockfile is necessary for a script that wants to prevent possible simultaneous execution. For example, consider a script +that is scheduled to run frequently, but that experiences occasional high load: you wouldn't want crontab to start running +it again if the first instance had not yet finished. + +But the code for creating, writing to, checking for, reading and cleaning up a lockfile for the script bloats what might otherwise be a terse +method call. Conscript handles lockfile generation and removal automatically. + +=head1 OPTIONS + +The common options (and default values) are: + + 'lock-file=s' => OpenILS::Utils::Lockfile::default_filename, + 'osrf-config=s' => '/openils/conf/opensrf_core.xml', + 'debug' => 0, + 'verbose+' => 0, + 'help' => 0, + +=head1 TODO + +More docs here. + +=head1 SEE ALSO + + Getopt::Long + OpenILS::Utils::Lockfile + oils_header.pl + +=head1 AUTHOR + +Joe Atzberger + +=cut + diff --git a/Open-ILS/src/perlmods/OpenILS/Utils/Editor.pm b/Open-ILS/src/perlmods/OpenILS/Utils/Editor.pm index c817c6774..801faff55 100644 --- a/Open-ILS/src/perlmods/OpenILS/Utils/Editor.pm +++ b/Open-ILS/src/perlmods/OpenILS/Utils/Editor.pm @@ -27,10 +27,10 @@ sub new_editor { return OpenILS::Utils::Editor->new(@_); } # These need to be auto-generated # ----------------------------------------------------------------------------- my %PERMS = ( - 'biblio.record_entry' => { update => 'UPDATE_MARC' }, - 'asset.copy' => { update => 'UPDATE_COPY'}, - 'asset.call_number' => { update => 'UPDATE_VOLUME'}, - 'action.circulation' => { retrieve => 'VIEW_CIRCULATIONS'}, + 'biblio.record_entry' => { update => 'UPDATE_MARC' }, + 'asset.copy' => { update => 'UPDATE_COPY' }, + 'asset.call_number' => { update => 'UPDATE_VOLUME' }, + 'action.circulation' => { retrieve => 'VIEW_CIRCULATIONS' }, ); use constant E => 'error'; diff --git a/Open-ILS/src/perlmods/OpenILS/Utils/RemoteAccount.pm b/Open-ILS/src/perlmods/OpenILS/Utils/RemoteAccount.pm index c55bac33b..89596accc 100644 --- a/Open-ILS/src/perlmods/OpenILS/Utils/RemoteAccount.pm +++ b/Open-ILS/src/perlmods/OpenILS/Utils/RemoteAccount.pm @@ -8,6 +8,8 @@ use Net::uFTP; use Net::SSH2; # because uFTP doesn't handle SSH keys (yet?) use File::Temp; use File::Basename; +use File::Spec; +use Text::Glob qw( match_glob glob_to_regex ); # use Error; $Data::Dumper::Indent = 0; @@ -305,6 +307,21 @@ sub ls { return $self->ls_uftp(@targets); } +# Checks if the filename part of a pathname has one or more glob characters +# We split out the filename portion of the path +# Detect glob or no glob. +# return: regex for matching filenames +sub glob_parse { + my $self = shift; + my $path = shift or return; + my ($vol, $dir, $file) = File::Spec->splitpath($path); # we don't care about attempted globs in mid-filepath + $file =~ /\*/ and return (File::Spec->catdir($vol, $dir), glob_to_regex($file)); + $file =~ /\?/ and return (File::Spec->catdir($vol, $dir), glob_to_regex($file)); + $logger->debug("No glob detected in '$path'"); + return; +} + + # Internal Mechanics sub _ssh2 { @@ -314,7 +331,7 @@ sub _ssh2 { my $ssh2 = Net::SSH2->new(); unless($ssh2->connect($self->remote_host)) { - $logger->warn($self->error("SSH2 connect FAILED: $!" . join(" ", $ssh2->error))); + $logger->warn($self->error("SSH2 connect FAILED: $! " . join(" ", $ssh2->error))); return; # we cannot connect } @@ -397,7 +414,7 @@ sub get_ssh2 { } $logger->info("*** get args: " . Dumper(\@_)); - $logger->info("*** attempting get (" . join(", ", map {$_ =~ /\S/ ? $_ : '*Object'} map {$_ || '*Object'} @_) . ") with ssh keys"); + $logger->info("*** attempting get (" . join(", ", map {$_ =~ /\S/ ? $_ : '*Object'} map {defined($_) ? $_ : '*Object'} @_) . ") with ssh keys"); my $ssh2 = $self->_ssh2($keys) or return; my $res; if ($res = $ssh2->scp_get( @_ )) { @@ -427,9 +444,10 @@ sub ls_ssh2_full { my @list = (); foreach my $target (@targets) { my ($dir, $file); - $dir = $sftp->opendir($target); + my ($dirpath, $regex) = $self->glob_parse($target); + $dir = $sftp->opendir($dirpath || $target); # Try to open it like a directory unless ($dir) { - $file = $sftp->stat($target); + $file = $sftp->stat($target); # Otherwise, check it like a file if ($file) { $file->{slash_path} = $self->_slash_path($target, $file->{name}); # it was a file, not a dir. That's OK. push @list, $file; @@ -438,11 +456,17 @@ sub ls_ssh2_full { } next; } + my @pool = (); while ($file = $dir->read()) { $file->{slash_path} = $self->_slash_path($target, $file->{name}); - push @list, $file; - # foreach (sort keys %$line) { printf " %20s => %s\n", $_, $line->{$_}; } + push @pool, $file; + } + if ($regex) { + my $count = scalar(@pool); + @pool = grep {$_->{name} =~ /$regex/} @pool; + $logger->info("Glob regex($regex) matches " . scalar(@pool) . " of $count files"); } + push @list, @pool; } return @list; @@ -516,11 +540,17 @@ sub ls_uftp { my @list; foreach (@_) { my @part; - eval { @part = $ftp->ls($_) }; + my ($dirpath, $regex) = $self->glob_parse($_); + eval { @part = $ftp->ls($dirpath || $_) }; if ($@) { $logger->error($self->_error("ls from", $self->remote_host, "failed with error: $@")); next; } + if ($regex) { + my $count = scalar(@part); + @part = grep {/$regex/} @part; + $logger->info("Glob regex($regex) matches " . scalar(@part) . " of $count files"); + } push @list, @part; } return @list; diff --git a/Open-ILS/src/sql/Pg/002.schema.config.sql b/Open-ILS/src/sql/Pg/002.schema.config.sql index 3f0efae4c..af5c930f8 100644 --- a/Open-ILS/src/sql/Pg/002.schema.config.sql +++ b/Open-ILS/src/sql/Pg/002.schema.config.sql @@ -60,7 +60,7 @@ CREATE TABLE config.upgrade_log ( install_date TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW() ); -INSERT INTO config.upgrade_log (version) VALUES ('0244'); -- Scott McKellar +INSERT INTO config.upgrade_log (version) VALUES ('0246'); -- atz CREATE TABLE config.bib_source ( id SERIAL PRIMARY KEY, diff --git a/Open-ILS/src/sql/Pg/upgrade/0167.data.event_definition_po_jedi.sql b/Open-ILS/src/sql/Pg/upgrade/0167.data.event_definition_po_jedi.sql index f4d075326..2bd8d4459 100644 --- a/Open-ILS/src/sql/Pg/upgrade/0167.data.event_definition_po_jedi.sql +++ b/Open-ILS/src/sql/Pg/upgrade/0167.data.event_definition_po_jedi.sql @@ -73,7 +73,7 @@ INSERT INTO action_trigger.environment (event_def, path) VALUES ((SELECT id FROM action_trigger.event_definition WHERE name='PO JEDI'), 'provider'); -- The environment insert has to happen here because it relies on subquerying the user-editable field "name" to --- provide the FK. Outside of this tranasaction, we cannot be sure the user hasn't changed the name to something else. +-- provide the FK. Outside of this transaction, we cannot be sure the user hasn't changed the name to something else. COMMIT; diff --git a/Open-ILS/src/sql/Pg/upgrade/0245.schema.acq_edi_message.sql b/Open-ILS/src/sql/Pg/upgrade/0245.schema.acq_edi_message.sql new file mode 100644 index 000000000..f6caa0225 --- /dev/null +++ b/Open-ILS/src/sql/Pg/upgrade/0245.schema.acq_edi_message.sql @@ -0,0 +1,7 @@ +BEGIN; + +INSERT INTO config.upgrade_log (version) VALUES ('0245'); -- atz + +ALTER TABLE acq.edi_account ADD COLUMN vendcode TEXT; + +COMMIT; diff --git a/Open-ILS/src/sql/Pg/upgrade/0246.data.event_definition_po_jedi.sql b/Open-ILS/src/sql/Pg/upgrade/0246.data.event_definition_po_jedi.sql new file mode 100644 index 000000000..1595f673e --- /dev/null +++ b/Open-ILS/src/sql/Pg/upgrade/0246.data.event_definition_po_jedi.sql @@ -0,0 +1,64 @@ +BEGIN; + +INSERT INTO config.upgrade_log (version) VALUES ('0246'); + +UPDATE action_trigger.event_definition SET template = +$$[%- USE date -%] +[%# start JEDI document -%] +[%- BLOCK big_block -%] +{ + "recipient":"[% target.provider.san %]", + "sender":"[% target.ordering_agency.mailing_address.san %]", + "body": [{ + "ORDERS":[ "order", { + "po_number":[% target.id %], + "date":"[% date.format(date.now, '%Y%m%d') %]", + "buyer":[{ + [%- IF target.provider.edi_default.vendcode -%] + "id":"[% target.ordering_agency.mailing_address.san _ ' ' _ target.provider.edi_default.vendcode %]", + "id-qualifier": 91 + [%- ELSE -%] + "id":"[% target.ordering_agency.mailing_address.san %]" + [%- END -%] + }], + "vendor":[ + [%- # target.provider.name (target.provider.id) -%] + "[% target.provider.san %]", + {"id-qualifier": 92, "id":"[% target.provider.id %]"} + ], + "currency":"[% target.provider.currency_type %]", + "items":[ + [% FOR li IN target.lineitems %] + { + "identifiers":[ + {"id-qualifier":"SA","id":"[% li.id %]"}, + {"id-qualifier":"IB","id":"[% helpers.get_li_attr('isbn', li.attributes) %]"} + ], + "price":[% helpers.get_li_attr('estimated_price', '', li.attributes) %], + "desc":[ + {"BTI":"[% helpers.get_li_attr('title', '', li.attributes) %]"}, + {"BPU":"[% helpers.get_li_attr('publisher', '', li.attributes) %]"}, + {"BPD":"[% helpers.get_li_attr('pubdate', '', li.attributes) %]"}, + {"BPH":"[% helpers.get_li_attr('pagination','', li.attributes) %]"} + ], + "quantity":[% li.lineitem_details.size %] + [%-# TODO: lineitem details (later) -%] + }[% UNLESS loop.last %],[% END %] + [% END %] + ], + "line_items":[% target.lineitems.size %] + }] [% # close ORDERS array %] + }] [% # close body array %] +} +[% END %] +[% tempo = PROCESS big_block; helpers.escape_json(tempo) %] +$$ +WHERE name='PO JEDI'; + +INSERT INTO action_trigger.environment (event_def, path) VALUES + ((SELECT id FROM action_trigger.event_definition WHERE name='PO JEDI'), 'provider.edi_default'); + +-- Hope they haven't changed the name... + +COMMIT; + diff --git a/Open-ILS/src/support-scripts/Cstore_test.t b/Open-ILS/src/support-scripts/Cstore_test.t new file mode 100644 index 000000000..2d577edce --- /dev/null +++ b/Open-ILS/src/support-scripts/Cstore_test.t @@ -0,0 +1,60 @@ +#!/usr/bin/perl +# --------------------------------------------------------------- +# Copyright (C) 2010 Equinox Software, Inc +# Author: Joe Atzberger +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# --------------------------------------------------------------- + +use strict; use warnings; +use vars qw/ $session $e $i $call/; + +use Test::More qw/no_plan/; + +sub nappy { + if (@ARGV) { + my $nap = shift @ARGV; + diag("OK, this time we'll sleep for $nap seconds to see if CStore wakes up"); + sleep $nap; + } +} + +BEGIN { + $i = 5; + $call = 'retrieve_all_acq_edi_account'; + use_ok('OpenILS::Utils::Cronscript'); + nappy(); + use_ok('OpenILS::Utils::CStoreEditor'); +} + +ok($session = OpenILS::Utils::Cronscript->new()->session('open-ils.acq'), + "new session created"); + +nappy(); + +ok($e = OpenILS::Utils::CStoreEditor->new(xact => 1), + "new CStoreEditor created"); + +until (can_ok($e, $call) or $i-- == 0) { + diag("CStore FAIL: cannot $call"); + sleep 2; + diag("reloading: prepare for a ton of warnings"); + delete $INC{'OpenILS/Utils/CStoreEditor.pm'}; + require_ok('OpenILS::Utils::CStoreEditor'); + diag("reloaded"); + ok($e = OpenILS::Utils::CStoreEditor->new(xact => 1), + "replacement CStoreEditor created"); +} + +my $set = $e->retrieve_all_acq_edi_account(); +ok(defined($set), $call); +print "\ndone\n"; + diff --git a/Open-ILS/src/support-scripts/Cstore_test2.t b/Open-ILS/src/support-scripts/Cstore_test2.t new file mode 100644 index 000000000..68f139abe --- /dev/null +++ b/Open-ILS/src/support-scripts/Cstore_test2.t @@ -0,0 +1,62 @@ +#!/usr/bin/perl +# --------------------------------------------------------------- +# Copyright (C) 2010 Equinox Software, Inc +# Author: Joe Atzberger +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# --------------------------------------------------------------- + +use strict; use warnings; +use vars qw/ $session $e $i $call/; + +use Test::More qw/no_plan/; + +sub nappy { + if (@ARGV) { + my $nap = shift @ARGV; + diag("OK, this time we'll sleep for $nap seconds to see if CStore wakes up"); + sleep $nap; + } +} + +BEGIN { + $i = 5; + $call = 'retrieve_all_acq_edi_account'; + use_ok('OpenILS::Utils::Cronscript'); + ok($session = OpenILS::Utils::Cronscript->new()->session('open-ils.acq'), + "new session created"); +} + +INIT { + nappy(); + use_ok('OpenILS::Utils::CStoreEditor'); +} + +nappy(); + +ok($e = OpenILS::Utils::CStoreEditor->new(xact => 1), + "new CStoreEditor created"); + +until (can_ok($e, $call) or $i-- == 0) { + diag("CStore FAIL: cannot $call"); + sleep 2; + diag("reloading: prepare for a ton of warnings"); + delete $INC{'OpenILS/Utils/CStoreEditor.pm'}; + require_ok('OpenILS::Utils::CStoreEditor'); + diag("reloaded"); + ok($e = OpenILS::Utils::CStoreEditor->new(xact => 1), + "replacement CStoreEditor created"); +} + +my $set = $e->retrieve_all_acq_edi_account(); +ok(defined($set), $call); +print "\ndone\n"; + diff --git a/Open-ILS/src/support-scripts/clear_expired_circ_history.srfsh b/Open-ILS/src/support-scripts/clear_expired_circ_history.srfsh index 16628ec1f..935a28be4 100644 --- a/Open-ILS/src/support-scripts/clear_expired_circ_history.srfsh +++ b/Open-ILS/src/support-scripts/clear_expired_circ_history.srfsh @@ -1,2 +1,2 @@ -#!BINDIR/srfsh +#!/openils/bin/srfsh request open-ils.cstore open-ils.cstore.json_query {"from":["container.clear_all_expired_circ_history_items"]} diff --git a/Open-ILS/src/support-scripts/edi_fetcher.pl b/Open-ILS/src/support-scripts/edi_fetcher.pl new file mode 100644 index 000000000..25a37326c --- /dev/null +++ b/Open-ILS/src/support-scripts/edi_fetcher.pl @@ -0,0 +1,64 @@ +#!/usr/bin/perl +# --------------------------------------------------------------- +# Copyright (C) 2010 Equinox Software, Inc +# Author: Joe Atzberger +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# --------------------------------------------------------------- + +use strict; +use warnings; + +use Data::Dumper; +use vars qw/$debug/; + +use OpenILS::Application::Acq::EDI; +use OpenILS::Utils::CStoreEditor; # needs init() after IDL is loaded (by Cronscript session) +use OpenILS::Utils::Cronscript; + +INIT { + $debug = 1; +} + +OpenILS::Utils::Cronscript->new()->session('open-ils.acq') or die "No session created"; +OpenILS::Utils::CStoreEditor::init(); + +sub editor { + my $ed = OpenILS::Utils::CStoreEditor->new(@_) or die "Failed to get new CStoreEditor"; + return $ed; +} + + +my $e = editor(); +my $set = $e->retrieve_all_acq_edi_account(); +my $total_accts = scalar(@$set); + +($total_accts) or die "No EDI accounts found in database (table: acq.edi_account)"; + +print "EDI Accounts Total : ", scalar(@$set), "\n"; + +my $subset = $e->search_acq_edi_account([ + {'+acqpro' => {active => 't'}}, + { + 'join' => 'acqpro', + flesh => 1, + flesh_fields => {acqedi => ['provider']}, + } +]); + +print "EDI Accounts Active: ", scalar(@$subset), "\n"; + +my $res = OpenILS::Application::Acq::EDI->retrieve_core(); +print "Files retrieved: ", scalar(@$res), "\n"; +$debug and print "retrieve_core returns ", scalar(@$res), " ids: " . join(', ', @$res), "\n"; + +$debug and print Dumper($set); +print "\ndone\n"; diff --git a/Open-ILS/src/support-scripts/edi_pusher.pl b/Open-ILS/src/support-scripts/edi_pusher.pl new file mode 100644 index 000000000..885659c1b --- /dev/null +++ b/Open-ILS/src/support-scripts/edi_pusher.pl @@ -0,0 +1,104 @@ +#!/usr/bin/perl +# --------------------------------------------------------------- +# Copyright (C) 2010 Equinox Software, Inc +# Author: Joe Atzberger +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# --------------------------------------------------------------- + +use strict; +use warnings; + +use Data::Dumper; +use vars qw/$debug/; + +use OpenILS::Utils::CStoreEditor; # needs init() after IDL is loaded (by Cronscript session) +use OpenILS::Utils::Cronscript; +use OpenILS::Utils::Fieldmapper; +use OpenILS::Application::AppUtils; +use OpenILS::Application::Acq::EDI; + +INIT { + $debug = 1; +} + +my %opts = ( + 'quiet' => 0, +); + +OpenILS::Utils::Cronscript->new()->session('open-ils.acq') or die "No session created"; +OpenILS::Utils::CStoreEditor::init(); + +sub editor { + my $ed = OpenILS::Utils::CStoreEditor->new(@_) or die "Failed to get new CStoreEditor"; + return $ed; +} + +my $e = editor(); +my $hook = 'format.po.jedi'; +my $defs = $e->search_action_trigger_event_definition({hook => $hook}); +# print Dumper($defs); +print "\nHook '$hook' is used in ", scalar(@$defs), " event definition(s):\n"; + +$Data::Dumper::Indent = 1; +foreach my $def (@$defs) { + printf "%3s - '%s'\n", $def->id, $def->name; + my $events = $e->search_action_trigger_event([ + {event_def => $def->id}, + {flesh => 1, flesh_fields => { atev => ['template_output'] }} + ]); + print "Event definition ", $def->id, " has ", scalar(@$events), " event(s)\n"; + foreach (@$events) { + my $message = Fieldmapper::acq::edi_message->new; + $message->create_time('NOW'); # will need this later when we try to update from the object + print "Event ", $_->id, " targets PO ", $_->target, ":\n"; # target is an opaque identifier, so we cannot flesh it + print Dumper($_), "\n"; + my $target = $e->retrieve_acq_purchase_order([ # instead we retrieve it separately + $_->target, { + flesh => 2, + flesh_fields => { + acqpo => ['provider'], + acqpro => ['edi_default'], + }, + } + ]); + + $debug and print "Target: ", Dumper($target), "\n"; + my $logstr = sprintf "provider %s (%s)", $target->provider->id, $target->provider->name; + unless ($target->provider->edi_default and $message->account($target->provider->edi_default->id)) { + printf STDERR "ERROR: No edi_default account found for $logstr. File will not be sent!\n"; + } + $message->jedi($_->template_output()->data); + print "\ntarget->provider->edi_default->id: ", $target->provider->edi_default->id, "\n"; + print "\nNow calling attempt_translation\n\n"; + unless (OpenILS::Application::Acq::EDI->attempt_translation($message, 1)) { + print STDERR "ERROR: attempt_translation failed, skipping message\n"; + next; + # The premise here is that if the translator failed, it is better to try again later from a "fresh" fetched file + # than to add a cascade of failing inscrutable copies of the same message(s) to our DB. + } + print "Writing new message + translation to DB\n"; + $e->xact_begin; + $e->create_acq_edi_message($message) or warn "create_acq_edi_message failed! $!"; + $e->xact_commit; + + print "Calling send_core(...)\n"; + my $res = OpenILS::Application::Acq::EDI->send_core($target->provider->edi_default, [$message->id]); + if (@$res) { + my $message_out = shift @$res; + print "\tmessage ", $message->id, " status: ", $message_out->status, "\n"; + } else { + print STDERR "ERROR: send_core failed for message ", $message->id, "\n"; + } + } +} + +print "\ndone\n"; diff --git a/Open-ILS/src/support-scripts/test-scripts/edi_object.pl b/Open-ILS/src/support-scripts/test-scripts/edi_object.pl new file mode 100644 index 000000000..5c4fd91eb --- /dev/null +++ b/Open-ILS/src/support-scripts/test-scripts/edi_object.pl @@ -0,0 +1,2985 @@ +#!/usr/bin/perl +# + +use strict; use warnings; + +use Data::Dumper; + +use OpenILS::Application::Acq::EDI; +use OpenILS::Utils::Cronscript; +use Business::EDI::Object; +use Business::EDI::Segment::RFF; +use vars qw/%code_hash/; + +require Business::EDI::DataElement; + +my $core = OpenILS::Utils::Cronscript->new(); +my $editor = $core->editor; + +my $slurp = join '', ; + +my ($aref, $whole) = OpenILS::Application::Acq::EDI->process_jedi($slurp); + +$Data::Dumper::Indent = 1; +my $i = 0; +foreach (@$aref) { + print "Building object from chunk ", ++$i, "\n"; + my $obj = Business::EDI::Object->new($_); + print Dumper($obj); +} + +print "\ndone\n"; + +__DATA__ +{ +"trailer": ["UNZ", { + "0020": "2045", + "0036": 1 +}], +"body": [{ + "ORDRSP": [["UNH", { + "S009": { + "0052": "D", + "0054": "96A", + "0065": "ORDRSP", + "0051": "UN" + }, + "0062": "723" + }], ["BGM", { + "4343": "AC", + "1225": "29", + "C002": { + "1001": "231" + }, + "1004": "582822" + }], ["DTM", { + "C507": { + "2379": "102", + "2380": "20070618", + "2005": "137" + } + }], ["RFF", { + "C506": { + "1153": "ON", + "1154": "E07158FIC" + } + }], ["NAD", { + "C082": { + "3039": "8888888", + "3055": "31B" + }, + "3035": "BY" + }], ["NAD", { + "C082": { + "3039": "1556150", + "3055": "31B" + }, + "3035": "SU" + }], ["NAD", { + "C082": { + "3039": "8888888", + "3055": "91" + }, + "3035": "BY" + }], ["CUX", { + "C504": [{ + "6345": "USD", + "6347": "2", + "6343": "9" + }] + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["LACY, AL THINGS NOT SEEN"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 10.99 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/1" + } + }]], + "C212": { + "7140": "9781576734131", + "7143": "EN" + }, + "1082": 1, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["LACY, AL FINAL JUSTICE"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 1, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 1, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 14.99 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/2" + } + }]], + "C212": { + "7140": "9781590529966", + "7143": "EN" + }, + "1082": 2, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["MALAMUD, B NATURAL"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 14 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/3" + } + }]], + "C212": { + "7140": "9780374502003", + "7143": "EN" + }, + "1082": 3, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["SCOTT, PAU RAJ QUARTET THE JEWEL IN"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 32.5 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/4" + } + }]], + "C212": { + "7140": "9780307263964", + "7143": "EN" + }, + "1082": 4, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["JAMES, P. SHROUD FOR A NIGHTINGALE"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 14 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/6" + } + }]], + "C212": { + "7140": "9780743219600", + "7143": "EN" + }, + "1082": 5, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["LAHAYE, TI TRIBULATION FORCE THE CO"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 14.99 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/7" + } + }]], + "C212": { + "7140": "9780842329217", + "7143": "EN" + }, + "1082": 6, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["ZANE AFTERBURN A NOVEL"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 15 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/8" + } + }]], + "C212": { + "7140": "9780743470988", + "7143": "EN" + }, + "1082": 7, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["CABOT, MEG BOY NEXT DOOR"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 13.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/9" + } + }]], + "C212": { + "7140": "9780060096199", + "7143": "EN" + }, + "1082": 8, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["VONNEGUT, BREAKFAST OF CHAMPIONS"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 14 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/10" + } + }]], + "C212": { + "7140": "9780385334204", + "7143": "EN" + }, + "1082": 9, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["DOSTOYEVSK BROTHERS KARAMAZOV"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 9.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/11" + } + }]], + "C212": { + "7140": "9781593083526", + "7143": "EN" + }, + "1082": 10, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["KINGSBURY, FORGIVEN"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 6, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 6, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 13.99 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/12" + } + }]], + "C212": { + "7140": "9780842387446", + "7143": "EN" + }, + "1082": 11, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["BERLINSKI, FIELDWORK"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 24 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/13" + } + }]], + "C212": { + "7140": "9780374299163", + "7143": "EN" + }, + "1082": 12, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["GREGORY, P MERIDON A NOVEL"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 16 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/14" + } + }]], + "C212": { + "7140": "9780743249317", + "7143": "EN" + }, + "1082": 13, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["MCCALL SMI MORALITY FOR BEAUTIFUL G"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 12.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/15" + } + }]], + "C212": { + "7140": "9781400031368", + "7143": "EN" + }, + "1082": 14, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["CLEAGE, PE WHAT LOOKS LIKE CRAZY ON"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 13.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/16" + } + }]], + "C212": { + "7140": "9780380794874", + "7143": "EN" + }, + "1082": 15, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["GREGORY, P WIDEACRE"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 16 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/17" + } + }]], + "C212": { + "7140": "9780743249294", + "7143": "EN" + }, + "1082": 16, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["FERBER, ED SO BIG"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "07", + "3055": "28", + "1131": "7B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 13 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/18" + } + }]], + "C212": { + "7140": "9780060956691", + "7143": "EN" + }, + "1082": 17, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["GREGORY, P OTHER BOLEYN GIRL"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 16 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/19" + } + }]], + "C212": { + "7140": "9780743227445", + "7143": "EN" + }, + "1082": 18, + "1229": "5" + }], ["UNS", { + "0081": "S" + }], ["CNT", { + "C270": { + "6069": "2", + "6066": 18 + } + }], ["UNT", { + "0074": 155, + "0062": "723" + }]] +}, +{ + "ORDRSP": [["UNH", { + "S009": { + "0052": "D", + "0054": "96A", + "0065": "ORDRSP", + "0051": "UN" + }, + "0062": "724" + }], ["BGM", { + "4343": "AC", + "1225": "29", + "C002": { + "1001": "231" + }, + "1004": "582828" + }], ["DTM", { + "C507": { + "2379": "102", + "2380": "20070618", + "2005": "137" + } + }], ["RFF", { + "C506": { + "1153": "ON", + "1154": "E07159ANF" + } + }], ["NAD", { + "C082": { + "3039": "8888888", + "3055": "31B" + }, + "3035": "BY" + }], ["NAD", { + "C082": { + "3039": "1556150", + "3055": "31B" + }, + "3035": "SU" + }], ["NAD", { + "C082": { + "3039": "8888888", + "3055": "91" + }, + "3035": "BY" + }], ["CUX", { + "C504": [{ + "6345": "USD", + "6347": "2", + "6343": "9" + }] + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["HOLM, BILL WINDOWS OF BRIMNES"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 22 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/1" + } + }]], + "C212": { + "7140": "9781571313027", + "7143": "EN" + }, + "1082": 1, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["REPA, BARB YOUR RIGHTS IN THE WORKP"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 29.99 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/2" + } + }]], + "C212": { + "7140": "9781413306439", + "7143": "EN" + }, + "1082": 2, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["GUERIN, LI ESSENTIAL GUIDE TO WORKP"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 39.99 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/3" + } + }]], + "C212": { + "7140": "9781413306910", + "7143": "EN" + }, + "1082": 3, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["CLIFFORD, ESTATE PLANNING BASICS"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 21.99 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/4" + } + }]], + "C212": { + "7140": "9781413307023", + "7143": "EN" + }, + "1082": 4, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["FRIEDMAN, BABY CARE BOOK"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 29.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/5" + } + }]], + "C212": { + "7140": "9780778801603", + "7143": "EN" + }, + "1082": 5, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["KING, RUSS ATLAS OF HUMAN MIGRATION"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 40 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/6" + } + }]], + "C212": { + "7140": "9781554072873", + "7143": "EN" + }, + "1082": 6, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["ASH, RUSSE FIREFLYS WORLD OF FACTS"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 6, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 6, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 29.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/7" + } + }]], + "C212": { + "7140": "9781554073139", + "7143": "EN" + }, + "1082": 7, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["WARNER, RA 101 LAW FORMS FOR PERSON"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 6, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 6, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 29.99 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/8" + } + }]], + "C212": { + "7140": "9781413307122", + "7143": "EN" + }, + "1082": 8, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["BRAY, ILON NOLOS ESSENTIAL GUIDE TO"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 10, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 10, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 24.99 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/9" + } + }]], + "C212": { + "7140": "9781413306286", + "7143": "EN" + }, + "1082": 9, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["WESTWOOD, HOW TO WRITE A MARKETING"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 1, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "99", + "3055": "28", + "1131": "7B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 17.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/10" + } + }]], + "C212": { + "7140": "9780749445546", + "7143": "EN" + }, + "1082": 10, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["ROANE, SUS HOW TO WORK A ROOM YOUR "] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 14.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/11" + } + }]], + "C212": { + "7140": "9780061238673", + "7143": "EN" + }, + "1082": 11, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["GERMAIN, D REACHING PAST THE WIRE A"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 24.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/12" + } + }]], + "C212": { + "7140": "9780873516068", + "7143": "EN" + }, + "1082": 12, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["KLING, KEV DOG SAYS HOW"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 22.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/13" + } + }]], + "C212": { + "7140": "9780873515993", + "7143": "EN" + }, + "1082": 13, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["SHORT, SUS BUNDT CAKE BLISS DELICIO"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 16.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/14" + } + }]], + "C212": { + "7140": "9780873515856", + "7143": "EN" + }, + "1082": 14, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["BRADY, TIM GOPHER GOLD LEGENDARY FI"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 24.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/15" + } + }]], + "C212": { + "7140": "9780873516013", + "7143": "EN" + }, + "1082": 15, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["ROBERTS, K MINNESOTA 150 THE PEOPLE"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 19.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/16" + } + }]], + "C212": { + "7140": "9780873515948", + "7143": "EN" + }, + "1082": 16, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["MAK, GEERT IN EUROPE A JOURNEY THRO"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 35 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/17" + } + }]], + "C212": { + "7140": "9780375424953", + "7143": "EN" + }, + "1082": 17, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["DONAHUE, P PARENTING WITHOUT FEAR O"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 14.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/18" + } + }]], + "C212": { + "7140": "9780312358914", + "7143": "EN" + }, + "1082": 18, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["MURRAY, LI BABYCENTERS ESSENTIAL GU"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 15.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/19" + } + }]], + "C212": { + "7140": "9781594864117", + "7143": "EN" + }, + "1082": 19, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["LAPINE, MI SNEAKY CHEF SIMPLE STRAT"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 6, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 6, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 17.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/20" + } + }]], + "C212": { + "7140": "9780762430758", + "7143": "EN" + }, + "1082": 20, + "1229": "5" + }], ["UNS", { + "0081": "S" + }], ["CNT", { + "C270": { + "6069": "2", + "6066": 20 + } + }], ["UNT", { + "0074": 171, + "0062": "724" + }]] +}, +{ + "ORDRSP": [["UNH", { + "S009": { + "0052": "D", + "0054": "96A", + "0065": "ORDRSP", + "0051": "UN" + }, + "0062": "725" + }], ["BGM", { + "4343": "AC", + "1225": "29", + "C002": { + "1001": "231" + }, + "1004": "582830" + }], ["DTM", { + "C507": { + "2379": "102", + "2380": "20070618", + "2005": "137" + } + }], ["RFF", { + "C506": { + "1153": "ON", + "1154": "E07160FIC" + } + }], ["NAD", { + "C082": { + "3039": "8888888", + "3055": "31B" + }, + "3035": "BY" + }], ["NAD", { + "C082": { + "3039": "1556150", + "3055": "31B" + }, + "3035": "SU" + }], ["NAD", { + "C082": { + "3039": "8888888", + "3055": "91" + }, + "3035": "BY" + }], ["CUX", { + "C504": [{ + "6345": "USD", + "6347": "2", + "6343": "9" + }] + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["SHAW, REBE COUNTRY LOVERS"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 12.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/1" + } + }]], + "C212": { + "7140": "9781400098224", + "7143": "EN" + }, + "1082": 1, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["BLAKE, TON TEMPT ME TONIGHT"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "07", + "3055": "28", + "1131": "7B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 13.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/2" + } + }]], + "C212": { + "7140": "9780061136092", + "7143": "EN" + }, + "1082": 2, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["MONING, KA BLOODFEVER"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 6, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 6, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 22 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/3" + } + }]], + "C212": { + "7140": "9780385339162", + "7143": "EN" + }, + "1082": 3, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["MCKENNA, S EDGE OF MIDNIGHT"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 14 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/4" + } + }]], + "C212": { + "7140": "9780758211859", + "7143": "EN" + }, + "1082": 4, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["BALZO, SAN GROUNDS FOR MURDER"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 27.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/5" + } + }]], + "C212": { + "7140": "9780727865496", + "7143": "EN" + }, + "1082": 5, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["PALMER, DI HARD TO HANDLE"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 13.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/6" + } + }]], + "C212": { + "7140": "9780373772612", + "7143": "EN" + }, + "1082": 6, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["JONES, LLO MR PIP"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 20 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/7" + } + }]], + "C212": { + "7140": "9780385341066", + "7143": "EN" + }, + "1082": 7, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["JILES, PAU STORMY WEATHER"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 24.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/8" + } + }]], + "C212": { + "7140": "9780060537326", + "7143": "EN" + }, + "1082": 8, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["DELILLO, D FALLING MAN A NOVEL"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 26 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/9" + } + }]], + "C212": { + "7140": "9781416546023", + "7143": "EN" + }, + "1082": 9, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["MORRISON, SWEETER THAN HONEY"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 24 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/10" + } + }]], + "C212": { + "7140": "9780758215116", + "7143": "EN" + }, + "1082": 10, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["SMITH, SHE FOX"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 25.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/11" + } + }]], + "C212": { + "7140": "9780756404215", + "7143": "EN" + }, + "1082": 11, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["GROSSMAN, SOON I WILL BE INVINCIBL"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 22.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/12" + } + }]], + "C212": { + "7140": "9780375424861", + "7143": "EN" + }, + "1082": 12, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["LEWYCKA, M SHORT HISTORY OF TRACTOR"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 14 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/13" + } + }]], + "C212": { + "7140": "9780143036746", + "7143": "EN" + }, + "1082": 13, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["BANNISTER, FLAWED"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 24.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/14" + } + }]], + "C212": { + "7140": "9780312375669", + "7143": "EN" + }, + "1082": 14, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["ALEXANDER, REMEMBERED"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 13.99 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/15" + } + }]], + "C212": { + "7140": "9780764201103", + "7143": "EN" + }, + "1082": 15, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["TANIGUCHI, OCEAN IN THE CLOSET"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 14.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/16" + } + }]], + "C212": { + "7140": "9781566891943", + "7143": "EN" + }, + "1082": 16, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["HENKE, ROX SECRET OF US"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 13.99 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/17" + } + }]], + "C212": { + "7140": "9780736917018", + "7143": "EN" + }, + "1082": 17, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["HERMAN, KA EVER PRESENT DANGER"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 12.99 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/18" + } + }]], + "C212": { + "7140": "9781590529218", + "7143": "EN" + }, + "1082": 18, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["CHAPMAN, G IT HAPPENS EVERY SPRING"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "07", + "3055": "28", + "1131": "7B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 12.99 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/19" + } + }]], + "C212": { + "7140": "9781414311654", + "7143": "EN" + }, + "1082": 19, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["JACKSON, N YADA YADA PRAYER GROUP G"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 13.99 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/20" + } + }]], + "C212": { + "7140": "9781591453628", + "7143": "EN" + }, + "1082": 20, + "1229": "5" + }], ["UNS", { + "0081": "S" + }], ["CNT", { + "C270": { + "6069": "2", + "6066": 20 + } + }], ["UNT", { + "0074": 171, + "0062": "725" + }]] +}], +"recipient": "8888888", +"sender": "1556150", +"header": ["UNB", { + "S003": { + "0007": "31B", + "0010": "8888888" + }, + "0020": "2045", + "S004": { + "0019": 1556, + "0017": 70618 + }, + "S001": { + "0001": "UNOC", + "0002": 3 + }, + "S002": { + "0007": "31B", + "0004": "1556150" + } +}], +"sender_qual": "31B", +"UNA": { + "seg_term": "'", + "decimal_sign": ".", + "esc_char": "?", + "de_sep": "+", + "ce_sep": ":", + "rep_sep": " " +}, +"recipient_qual": "31B" +} diff --git a/Open-ILS/src/support-scripts/test-scripts/ftp.pl b/Open-ILS/src/support-scripts/test-scripts/ftp.pl new file mode 100644 index 000000000..932c719c7 --- /dev/null +++ b/Open-ILS/src/support-scripts/test-scripts/ftp.pl @@ -0,0 +1,83 @@ +#!/usr/bin/perl -IOpen-ILS/src/perlmods + +use strict; use warnings; + +use Data::Dumper; + +use OpenILS::Utils::RemoteAccount; + +my $delay = 1; + +my %config = ( + remote_host => 'example.org', + remote_user => 'some_user', + remote_password => 'some_user', + remote_file => './out/testfile', +); + +sub content { + my $time = localtime; + return <new( + remote_host => $config{remote_host}, + remote_user => $config{remote_user}, + content => content(), +); + +$Data::Dumper::Indent = 1; +print Dumper($x); + +$delay and print "Sleeping $delay seconds\n" and sleep $delay; + +$x->put({ + remote_file => $config{remote_file} . "1.$$", + content => content(), +}) or die "ERROR: $x->error"; + +print "\n\n", Dumper($x); + +my $file = $x->local_file; +open TEMP, "< $file" or die "Cannot read tempfile $file: $!"; +print "\n\ncontent from tempfile $file:\n"; +while (my $line = ) { + print $line; +} +close TEMP; + +print "\n\nls :\n", join "\n", $x->ls; +print "\n\nls ('out'):\n", join "\n", $x->ls('out'); + +print "\nThis one should fail (at put)\n"; +my $y; + +$y = OpenILS::Utils::RemoteAccount->new( + remote_host => $config{remote_host}, + remote_user => $config{remote_user}, + remote_password => 'some_junk', + content => content(), + type => 'FTP', +); +print STDERR "ERROR: $@ $! : \n", $y->error, "\n"; + +print "\n\n", Dumper($y); + +$delay and print "Sleeping $delay seconds\n" and sleep $delay; +$y->put({ + remote_file => $config{remote_file} . "2.$$", + content => content(), +}) or warn "ERROR with put: " . $y->error; + +print "\nThis one might succeed\n"; +$y->put({ + remote_file => $config{remote_file} . "3.$$", + content => content(), + remote_password => $config{remote_password}, +}) or warn "ERROR with put: " . $y->error; + diff --git a/Open-ILS/src/support-scripts/test-scripts/ftp_ls.pl b/Open-ILS/src/support-scripts/test-scripts/ftp_ls.pl new file mode 100644 index 000000000..987a41985 --- /dev/null +++ b/Open-ILS/src/support-scripts/test-scripts/ftp_ls.pl @@ -0,0 +1,131 @@ +#!/usr/bin/perl -IOpen-ILS/src/perlmods + +use strict; use warnings; + +use Data::Dumper; + +use OpenILS::Utils::RemoteAccount; +use IO::Scalar; +use IO::File; +use Text::Glob qw( match_glob ); +$Text::Glob::strict_leading_dot = 0; +$Text::Glob::strict_wildcard_slash = 0; + +my $delay = 1; + +my %config = ( + remote_host => 'example.org', + remote_user => 'some_user', + remote_password => 'some_user', + remote_file => '/home/some_user/out/zzz_testfile', +); + +sub content { + my $time = localtime; + return <new( + remote_host => $config{remote_host}, + remote_user => $config{remote_user}, + content => content(), +); + +$Data::Dumper::Indent = 1; +# print Dumper($x); + +$delay and print "Sleeping $delay seconds\n" and sleep $delay; + +$x->put({ + remote_file => $config{remote_file} . "1.$$", + content => content(), +}) or die "ERROR: $x->error"; + +# print "\n\n", Dumper($x); + +my $file = $x->local_file; +my $rfile = $x->remote_file; +open TEMP, "< $file" or die "Cannot read tempfile $file: $!"; +print "\n\ncontent from tempfile $file:\n"; +while (my $line = ) { + print $line; +} +close TEMP; + +my $dir = '/home/some_user/out'; +$delay and print "Sleeping $delay seconds\n" and sleep $delay; + +my $glob6 = $dir . '/*Q*'; + +my @res1 = grep {! /\/\.?\.$/} $x->ls({remote_file => $dir}); +my @res2 = grep {! /\/\.?\.$/} $x->ls($dir); +my @res3 = grep {! /\/\.?\.$/} $x->ls(); +my @res4 = grep {! /\/\.?\.$/} $x->ls('.'); +my @res6 = $x->ls($glob6); + +my $mismatch = 0; +my $found = 0; +my $i=0; +print "\n\n"; +printf " %50s | %s\n", "ls ({remote_file => '$dir'})", "ls ('$dir')"; +foreach (@res1) { + my $partner = @res2 ? shift @res2 : ''; + $mismatch++ unless ($_ eq $partner); + $_ eq $rfile and $found++; + printf "%4d)%1s%50s %s %s\n", ++$i, ($_ eq $rfile ? '*' : ' '), $_, ($_ eq $partner ? '=' : '!'), $partner; +} + +print "\n"; +print ($found ? "* The file we just sent" : sprintf("Did not find the file we just sent: \n%58s", $rfile)); +print "\nNumber of mismatches: $mismatch\n"; +$mismatch and warn "Different style calls to ls got different results. Please check again."; + +$mismatch = $found = $i = 0; +print "\n\n"; +printf " %50s | %s\n", "ls ('.')", "ls ()"; +foreach (@res4) { + my $partner = @res3 ? shift @res3 : ''; + $mismatch++ unless ($_ eq $partner); + printf "%4d)%1s%50s %s %s\n", ++$i, ($_ eq $rfile ? '*' : ' '), $_, ($_ eq $partner ? '=' : '!'), $partner; +} +print "\n"; +print "\nNumber of mismatches: $mismatch\n"; +$mismatch and warn "Different style calls to ls got different results. Please check again."; + +$x->debug(1); +my $target = $res1[0] || $res3[0]; +my $slurp; + +my $io = IO::Scalar->new(\$slurp); +print "Trying to read $target into an IO::Scalar\n"; +$x->get({remote_file => $target, local_file => $io}); + +my $iofile = IO::File->new(">/tmp/io_file_sftp_test.tmp"); +print "Trying to read $target into an IO::File\n"; +$x->get({remote_file => $target, local_file => $iofile}); + +my $glob = '*t*'; +my @res5 = (match_glob($glob, @res4)); +print scalar(@res5) . " of " . scalar(@res4) . " files matching $glob :\n"; +$i = 0; +foreach my $orig (@res4) { + printf "%4d)%1s %s\n", ++$i, ((grep {$orig eq $_} @res5 )? '*' : ' '), $orig; +} +scalar(@res5) and print "\n* Matching file\n"; + +print scalar(@res6) . " of " . scalar(@res1) . " files matching $glob6 :\n"; +$i = 0; +foreach my $orig (@res1) { + printf "%4d)%1s %s\n", ++$i, ((grep {$orig eq $_} @res6 )? '*' : ' '), $orig; +} +scalar(@res6) and print "\n* Matching file\n"; + +print join("\n", @res6), "\n"; +print "\n\ndone\n"; +exit; + diff --git a/Open-ILS/src/support-scripts/test-scripts/net_ssh2.pl b/Open-ILS/src/support-scripts/test-scripts/net_ssh2.pl new file mode 100644 index 000000000..4cfc5bda0 --- /dev/null +++ b/Open-ILS/src/support-scripts/test-scripts/net_ssh2.pl @@ -0,0 +1,52 @@ +#!/usr/bin/perl +# + +use strict; +use warnings; + +use Test::More qw/no_plan/; + +my %config = ( + hostname => @ARGV ? shift @ARGV : 'example.org', + username => @ARGV ? shift @ARGV : 'some_user', + file => @ARGV ? shift @ARGV : '.bashrc', + privatekey => glob("~/.ssh/id_rsa") || glob("~/.ssh/id_dsa"), +); +$config{publickey} = $config{privatekey} . '.pub'; + +BEGIN { + use_ok( 'Net::SSH2' ); + use_ok( 'IO::Scalar' ); + use_ok( 'IO::File' ); + use_ok( 'File::Glob', qw/:glob/ ); +} + +my $ssh; + +ok($ssh = Net::SSH2->new, + 'Net::SSH2->new'); + +ok($ssh->connect( $config{hostname} ), + "ssh->connect('$config{hostname}')"); + +ok($ssh->auth_publickey(@config{qw/username publickey privatekey/}), + "ssh->auth_publickey(" + . join(', ', map{"'$_'"} @config{qw/username publickey privatekey/}) + . ")" +); + +my (@list, $io, $iofile); + +my $scalar = "## This line starts in the variable before we read the file\n## This line too.\n"; + +ok($io = IO::Scalar->new(\$scalar), "IO::Scalar->new"); +ok($iofile = IO::File->new(">/tmp/io_file.tmp"), + "IO::File->new('>/tmp/io_file.tmp')"); + +ok($ssh->scp_get($config{file}, $io), + "ssh->scp_get($config{file}, \$io) # trying to retrieve file into IO::Scalar" +); + +diag("Now printing remote file from IO::Scalar:"); +print $io; + diff --git a/Open-ILS/src/support-scripts/test-scripts/net_ssh2_ls.pl b/Open-ILS/src/support-scripts/test-scripts/net_ssh2_ls.pl new file mode 100644 index 000000000..b51e669a3 --- /dev/null +++ b/Open-ILS/src/support-scripts/test-scripts/net_ssh2_ls.pl @@ -0,0 +1,43 @@ +#!/usr/bin/perl -IOpen-ILS/src/perlmods + +use strict; use warnings; + +use Net::SSH2; +use Data::Dumper; + +my $delay = 1; + +my %config = ( + remote_host => 'example.org', + remote_user => 'some_user', + remote_password => 'whatever', +); + +$config{remote_file} = '/home/' . $config{remote_user}; + +my $x = Net::SSH2->new(); + +$x->connect($config{remote_host}) or die "Could not connect to $config{remote_host}: " . $x->error; +$x->auth( + publickey => '/home/opensrf/.ssh/id_rsa.pub', + privatekey => '/home/opensrf/.ssh/id_rsa', + username => $config{remote_user}, +# password => $config{remote_password}, + rank => [ qw/ publickey hostbased password / ], +) or die "Auth failed for $config{remote_host}: " . $x->error; + +print "Reading directory: $config{remote_file}\n"; +my $sftp = $x->sftp; +my $dir = $sftp->opendir($config{remote_file}) or die $sftp->error; + +print "Directory listing:\n"; +my $i = 0; +while (my $line = $dir->read()) { + printf "%3s)\n", ++$i; + foreach (sort keys %$line) { + printf " %20s => %s\n", $_, $line->{$_}; + } +} + +exit; + diff --git a/Open-ILS/src/support-scripts/test-scripts/notes.pl b/Open-ILS/src/support-scripts/test-scripts/notes.pl index 21fcaf8fa..0bbbc156a 100755 --- a/Open-ILS/src/support-scripts/test-scripts/notes.pl +++ b/Open-ILS/src/support-scripts/test-scripts/notes.pl @@ -7,7 +7,7 @@ use Data::Dumper; use OpenSRF::Utils::JSON; #----------------------------------------------------------------------------- -# Does a checkout, renew, and checkin +# Creates, retrieves and deletes notes #----------------------------------------------------------------------------- err("usage: $0 <text>") unless $ARGV[5]; diff --git a/Open-ILS/src/support-scripts/test-scripts/ordrsp_parse.pl b/Open-ILS/src/support-scripts/test-scripts/ordrsp_parse.pl new file mode 100644 index 000000000..c57b33187 --- /dev/null +++ b/Open-ILS/src/support-scripts/test-scripts/ordrsp_parse.pl @@ -0,0 +1,3058 @@ +#!/usr/bin/perl +# + +use strict; use warnings; + +use Data::Dumper; + +use OpenILS::Utils::Cronscript; +use OpenILS::Application::Acq::EDI; +use Business::EDI::DataElement; +use Business::EDI::Segment::RFF; +use vars qw/%code_hash/; + +require Business::EDI::DataElement; + +my $verbose = @ARGV ? shift : 0; + +my $core = OpenILS::Utils::Cronscript->new(); +my $editor = $core->editor; + +my $slurp = join '', <DATA>; + +my ($aref, $whole) = OpenILS::Application::Acq::EDI->process_jedi($slurp); + +$Data::Dumper::Indent = 1; +# print Dumper($aref); +my @innards = @$aref; +my @rffs; + +# `print Dumper(\@innards); + +=pod + ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["LACY, AL THINGS NOT SEEN"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "21" + } + }], ... + ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/1" + } + }], ... ]}] + +=cut + +my @qtys = (); +foreach (@innards) { + +# my $count = scalar(@{$_->{SG26}}); + my $count = scalar(@$_); + print STDERR "->{SG26} has $count pieces: "; + for (my $i = 0; $i < $count; $i++) { + my $label = $_->[$i]->[0]; + my $body = $_->[$i]->[1]; + print STDERR "$label "; + $label eq 'QTY' and push @qtys, $body; + $label eq 'RFF' and push @rffs, $body; + } + print STDERR "\n"; + # foreach my $qty (@{$_->{SG26}->[0]}) { +} + +printf "%4d LINs found\n", scalar(@innards); +printf "%4d QTYs found\n", scalar(@qtys); +printf "%4d RFFs found (inside LINs)\n", scalar(@rffs); + +sub example_dump { + my $example = shift or return; + print "\nexample QTY: ", Dumper($example); + foreach (keys %{$example->{C186}}) { + # no warnings 'uninitialized'; + my $x = Business::EDI::DataElement->new($_); + print $x->label, " ($_) : ", $example->{C186}->{$_}, "\n"; + } +} + +# example_dump($qtys[-1]); + +# We want: RFF > C506 > 1154 where 1153 = LI +foreach my $rff (@rffs) { + my $obj = Business::EDI::Segment::RFF->new($rff); + $verbose and print Dumper ($obj); + foreach my $subrff (keys %$rff) { + $subrff eq 'C506' or next; + my $i = 0; + foreach (sort keys %{$rff->{$subrff}}) { + my $x = Business::EDI::DataElement->new($_, $rff->{$subrff}->{$_}); + $x or warn "Unknown DataElement code $_"; + print "$_ ", $x->label, " ", $x->value, " "; + $i++ == 0 and print "==> "; + } + print "\n"; + } +} +print "\ndone\n"; + +__DATA__ +{ +"trailer": ["UNZ", { + "0020": "2045", + "0036": 1 +}], +"body": [{ + "ORDRSP": [["UNH", { + "S009": { + "0052": "D", + "0054": "96A", + "0065": "ORDRSP", + "0051": "UN" + }, + "0062": "723" + }], ["BGM", { + "4343": "AC", + "1225": "29", + "C002": { + "1001": "231" + }, + "1004": "582822" + }], ["DTM", { + "C507": { + "2379": "102", + "2380": "20070618", + "2005": "137" + } + }], ["RFF", { + "C506": { + "1153": "ON", + "1154": "E07158FIC" + } + }], ["NAD", { + "C082": { + "3039": "8888888", + "3055": "31B" + }, + "3035": "BY" + }], ["NAD", { + "C082": { + "3039": "1556150", + "3055": "31B" + }, + "3035": "SU" + }], ["NAD", { + "C082": { + "3039": "8888888", + "3055": "91" + }, + "3035": "BY" + }], ["CUX", { + "C504": [{ + "6345": "USD", + "6347": "2", + "6343": "9" + }] + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["LACY, AL THINGS NOT SEEN"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 10.99 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/1" + } + }]], + "C212": { + "7140": "9781576734131", + "7143": "EN" + }, + "1082": 1, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["LACY, AL FINAL JUSTICE"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 1, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 1, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 14.99 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/2" + } + }]], + "C212": { + "7140": "9781590529966", + "7143": "EN" + }, + "1082": 2, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["MALAMUD, B NATURAL"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 14 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/3" + } + }]], + "C212": { + "7140": "9780374502003", + "7143": "EN" + }, + "1082": 3, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["SCOTT, PAU RAJ QUARTET THE JEWEL IN"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 32.5 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/4" + } + }]], + "C212": { + "7140": "9780307263964", + "7143": "EN" + }, + "1082": 4, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["JAMES, P. SHROUD FOR A NIGHTINGALE"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 14 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/6" + } + }]], + "C212": { + "7140": "9780743219600", + "7143": "EN" + }, + "1082": 5, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["LAHAYE, TI TRIBULATION FORCE THE CO"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 14.99 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/7" + } + }]], + "C212": { + "7140": "9780842329217", + "7143": "EN" + }, + "1082": 6, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["ZANE AFTERBURN A NOVEL"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 15 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/8" + } + }]], + "C212": { + "7140": "9780743470988", + "7143": "EN" + }, + "1082": 7, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["CABOT, MEG BOY NEXT DOOR"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 13.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/9" + } + }]], + "C212": { + "7140": "9780060096199", + "7143": "EN" + }, + "1082": 8, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["VONNEGUT, BREAKFAST OF CHAMPIONS"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 14 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/10" + } + }]], + "C212": { + "7140": "9780385334204", + "7143": "EN" + }, + "1082": 9, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["DOSTOYEVSK BROTHERS KARAMAZOV"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 9.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/11" + } + }]], + "C212": { + "7140": "9781593083526", + "7143": "EN" + }, + "1082": 10, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["KINGSBURY, FORGIVEN"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 6, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 6, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 13.99 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/12" + } + }]], + "C212": { + "7140": "9780842387446", + "7143": "EN" + }, + "1082": 11, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["BERLINSKI, FIELDWORK"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 24 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/13" + } + }]], + "C212": { + "7140": "9780374299163", + "7143": "EN" + }, + "1082": 12, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["GREGORY, P MERIDON A NOVEL"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 16 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/14" + } + }]], + "C212": { + "7140": "9780743249317", + "7143": "EN" + }, + "1082": 13, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["MCCALL SMI MORALITY FOR BEAUTIFUL G"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 12.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/15" + } + }]], + "C212": { + "7140": "9781400031368", + "7143": "EN" + }, + "1082": 14, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["CLEAGE, PE WHAT LOOKS LIKE CRAZY ON"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 13.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/16" + } + }]], + "C212": { + "7140": "9780380794874", + "7143": "EN" + }, + "1082": 15, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["GREGORY, P WIDEACRE"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 16 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/17" + } + }]], + "C212": { + "7140": "9780743249294", + "7143": "EN" + }, + "1082": 16, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["FERBER, ED SO BIG"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "07", + "3055": "28", + "1131": "7B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 13 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/18" + } + }]], + "C212": { + "7140": "9780060956691", + "7143": "EN" + }, + "1082": 17, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["GREGORY, P OTHER BOLEYN GIRL"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 16 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4639/19" + } + }]], + "C212": { + "7140": "9780743227445", + "7143": "EN" + }, + "1082": 18, + "1229": "5" + }], ["UNS", { + "0081": "S" + }], ["CNT", { + "C270": { + "6069": "2", + "6066": 18 + } + }], ["UNT", { + "0074": 155, + "0062": "723" + }]] +}, +{ + "ORDRSP": [["UNH", { + "S009": { + "0052": "D", + "0054": "96A", + "0065": "ORDRSP", + "0051": "UN" + }, + "0062": "724" + }], ["BGM", { + "4343": "AC", + "1225": "29", + "C002": { + "1001": "231" + }, + "1004": "582828" + }], ["DTM", { + "C507": { + "2379": "102", + "2380": "20070618", + "2005": "137" + } + }], ["RFF", { + "C506": { + "1153": "ON", + "1154": "E07159ANF" + } + }], ["NAD", { + "C082": { + "3039": "8888888", + "3055": "31B" + }, + "3035": "BY" + }], ["NAD", { + "C082": { + "3039": "1556150", + "3055": "31B" + }, + "3035": "SU" + }], ["NAD", { + "C082": { + "3039": "8888888", + "3055": "91" + }, + "3035": "BY" + }], ["CUX", { + "C504": [{ + "6345": "USD", + "6347": "2", + "6343": "9" + }] + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["HOLM, BILL WINDOWS OF BRIMNES"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 22 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/1" + } + }]], + "C212": { + "7140": "9781571313027", + "7143": "EN" + }, + "1082": 1, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["REPA, BARB YOUR RIGHTS IN THE WORKP"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 29.99 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/2" + } + }]], + "C212": { + "7140": "9781413306439", + "7143": "EN" + }, + "1082": 2, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["GUERIN, LI ESSENTIAL GUIDE TO WORKP"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 39.99 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/3" + } + }]], + "C212": { + "7140": "9781413306910", + "7143": "EN" + }, + "1082": 3, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["CLIFFORD, ESTATE PLANNING BASICS"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 21.99 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/4" + } + }]], + "C212": { + "7140": "9781413307023", + "7143": "EN" + }, + "1082": 4, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["FRIEDMAN, BABY CARE BOOK"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 29.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/5" + } + }]], + "C212": { + "7140": "9780778801603", + "7143": "EN" + }, + "1082": 5, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["KING, RUSS ATLAS OF HUMAN MIGRATION"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 40 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/6" + } + }]], + "C212": { + "7140": "9781554072873", + "7143": "EN" + }, + "1082": 6, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["ASH, RUSSE FIREFLYS WORLD OF FACTS"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 6, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 6, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 29.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/7" + } + }]], + "C212": { + "7140": "9781554073139", + "7143": "EN" + }, + "1082": 7, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["WARNER, RA 101 LAW FORMS FOR PERSON"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 6, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 6, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 29.99 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/8" + } + }]], + "C212": { + "7140": "9781413307122", + "7143": "EN" + }, + "1082": 8, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["BRAY, ILON NOLOS ESSENTIAL GUIDE TO"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 10, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 10, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 24.99 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/9" + } + }]], + "C212": { + "7140": "9781413306286", + "7143": "EN" + }, + "1082": 9, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["WESTWOOD, HOW TO WRITE A MARKETING"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 1, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "99", + "3055": "28", + "1131": "7B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 17.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/10" + } + }]], + "C212": { + "7140": "9780749445546", + "7143": "EN" + }, + "1082": 10, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["ROANE, SUS HOW TO WORK A ROOM YOUR "] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 14.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/11" + } + }]], + "C212": { + "7140": "9780061238673", + "7143": "EN" + }, + "1082": 11, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["GERMAIN, D REACHING PAST THE WIRE A"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 24.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/12" + } + }]], + "C212": { + "7140": "9780873516068", + "7143": "EN" + }, + "1082": 12, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["KLING, KEV DOG SAYS HOW"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 22.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/13" + } + }]], + "C212": { + "7140": "9780873515993", + "7143": "EN" + }, + "1082": 13, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["SHORT, SUS BUNDT CAKE BLISS DELICIO"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 16.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/14" + } + }]], + "C212": { + "7140": "9780873515856", + "7143": "EN" + }, + "1082": 14, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["BRADY, TIM GOPHER GOLD LEGENDARY FI"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 24.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/15" + } + }]], + "C212": { + "7140": "9780873516013", + "7143": "EN" + }, + "1082": 15, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["ROBERTS, K MINNESOTA 150 THE PEOPLE"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 19.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/16" + } + }]], + "C212": { + "7140": "9780873515948", + "7143": "EN" + }, + "1082": 16, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["MAK, GEERT IN EUROPE A JOURNEY THRO"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 35 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/17" + } + }]], + "C212": { + "7140": "9780375424953", + "7143": "EN" + }, + "1082": 17, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["DONAHUE, P PARENTING WITHOUT FEAR O"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 14.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/18" + } + }]], + "C212": { + "7140": "9780312358914", + "7143": "EN" + }, + "1082": 18, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["MURRAY, LI BABYCENTERS ESSENTIAL GU"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 15.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/19" + } + }]], + "C212": { + "7140": "9781594864117", + "7143": "EN" + }, + "1082": 19, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["LAPINE, MI SNEAKY CHEF SIMPLE STRAT"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 6, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 6, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 17.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4640/20" + } + }]], + "C212": { + "7140": "9780762430758", + "7143": "EN" + }, + "1082": 20, + "1229": "5" + }], ["UNS", { + "0081": "S" + }], ["CNT", { + "C270": { + "6069": "2", + "6066": 20 + } + }], ["UNT", { + "0074": 171, + "0062": "724" + }]] +}, +{ + "ORDRSP": [["UNH", { + "S009": { + "0052": "D", + "0054": "96A", + "0065": "ORDRSP", + "0051": "UN" + }, + "0062": "725" + }], ["BGM", { + "4343": "AC", + "1225": "29", + "C002": { + "1001": "231" + }, + "1004": "582830" + }], ["DTM", { + "C507": { + "2379": "102", + "2380": "20070618", + "2005": "137" + } + }], ["RFF", { + "C506": { + "1153": "ON", + "1154": "E07160FIC" + } + }], ["NAD", { + "C082": { + "3039": "8888888", + "3055": "31B" + }, + "3035": "BY" + }], ["NAD", { + "C082": { + "3039": "1556150", + "3055": "31B" + }, + "3035": "SU" + }], ["NAD", { + "C082": { + "3039": "8888888", + "3055": "91" + }, + "3035": "BY" + }], ["CUX", { + "C504": [{ + "6345": "USD", + "6347": "2", + "6343": "9" + }] + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["SHAW, REBE COUNTRY LOVERS"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 12.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/1" + } + }]], + "C212": { + "7140": "9781400098224", + "7143": "EN" + }, + "1082": 1, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["BLAKE, TON TEMPT ME TONIGHT"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "07", + "3055": "28", + "1131": "7B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 13.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/2" + } + }]], + "C212": { + "7140": "9780061136092", + "7143": "EN" + }, + "1082": 2, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["MONING, KA BLOODFEVER"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 6, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 6, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 22 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/3" + } + }]], + "C212": { + "7140": "9780385339162", + "7143": "EN" + }, + "1082": 3, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["MCKENNA, S EDGE OF MIDNIGHT"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 14 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/4" + } + }]], + "C212": { + "7140": "9780758211859", + "7143": "EN" + }, + "1082": 4, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["BALZO, SAN GROUNDS FOR MURDER"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 27.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/5" + } + }]], + "C212": { + "7140": "9780727865496", + "7143": "EN" + }, + "1082": 5, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["PALMER, DI HARD TO HANDLE"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 13.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/6" + } + }]], + "C212": { + "7140": "9780373772612", + "7143": "EN" + }, + "1082": 6, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["JONES, LLO MR PIP"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 20 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/7" + } + }]], + "C212": { + "7140": "9780385341066", + "7143": "EN" + }, + "1082": 7, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["JILES, PAU STORMY WEATHER"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 24.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/8" + } + }]], + "C212": { + "7140": "9780060537326", + "7143": "EN" + }, + "1082": 8, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["DELILLO, D FALLING MAN A NOVEL"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 26 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/9" + } + }]], + "C212": { + "7140": "9781416546023", + "7143": "EN" + }, + "1082": 9, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["MORRISON, SWEETER THAN HONEY"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 24 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/10" + } + }]], + "C212": { + "7140": "9780758215116", + "7143": "EN" + }, + "1082": 10, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["SMITH, SHE FOX"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 25.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/11" + } + }]], + "C212": { + "7140": "9780756404215", + "7143": "EN" + }, + "1082": 11, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["GROSSMAN, SOON I WILL BE INVINCIBL"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 22.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/12" + } + }]], + "C212": { + "7140": "9780375424861", + "7143": "EN" + }, + "1082": 12, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["LEWYCKA, M SHORT HISTORY OF TRACTOR"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 3, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 14 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/13" + } + }]], + "C212": { + "7140": "9780143036746", + "7143": "EN" + }, + "1082": 13, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["BANNISTER, FLAWED"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 4, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "03", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 24.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/14" + } + }]], + "C212": { + "7140": "9780312375669", + "7143": "EN" + }, + "1082": 14, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["ALEXANDER, REMEMBERED"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 13.99 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/15" + } + }]], + "C212": { + "7140": "9780764201103", + "7143": "EN" + }, + "1082": 15, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["TANIGUCHI, OCEAN IN THE CLOSET"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 2, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 14.95 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/16" + } + }]], + "C212": { + "7140": "9781566891943", + "7143": "EN" + }, + "1082": 16, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["HENKE, ROX SECRET OF US"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 13.99 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/17" + } + }]], + "C212": { + "7140": "9780736917018", + "7143": "EN" + }, + "1082": 17, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["HERMAN, KA EVER PRESENT DANGER"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 12.99 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/18" + } + }]], + "C212": { + "7140": "9781590529218", + "7143": "EN" + }, + "1082": 18, + "1229": "5" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["CHAPMAN, G IT HAPPENS EVERY SPRING"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 5, + "6063": "83" + } + }], ["FTX", { + "C107": { + "4441": "07", + "3055": "28", + "1131": "7B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 12.99 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/19" + } + }]], + "C212": { + "7140": "9781414311654", + "7143": "EN" + }, + "1082": 19, + "1229": "24" + }], ["LIN", { + "SG26": [["IMD", { + "C273": { + "7008": ["JACKSON, N YADA YADA PRAYER GROUP G"] + }, + "7077": "F", + "7081": "BST" + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "21" + } + }], ["QTY", { + "C186": { + "6060": 8, + "6063": "12" + } + }], ["QTY", { + "C186": { + "6060": 0, + "6063": "85" + } + }], ["FTX", { + "C107": { + "4441": "01", + "3055": "28", + "1131": "8B" + }, + "4451": "LIN" + }], ["PRI", { + "C509": { + "5387": "SRP", + "5125": "AAB", + "5118": 13.99 + } + }], ["RFF", { + "C506": { + "1153": "LI", + "1154": "4641/20" + } + }]], + "C212": { + "7140": "9781591453628", + "7143": "EN" + }, + "1082": 20, + "1229": "5" + }], ["UNS", { + "0081": "S" + }], ["CNT", { + "C270": { + "6069": "2", + "6066": 20 + } + }], ["UNT", { + "0074": 171, + "0062": "725" + }]] +}], +"recipient": "8888888", +"sender": "1556150", +"header": ["UNB", { + "S003": { + "0007": "31B", + "0010": "8888888" + }, + "0020": "2045", + "S004": { + "0019": 1556, + "0017": 70618 + }, + "S001": { + "0001": "UNOC", + "0002": 3 + }, + "S002": { + "0007": "31B", + "0004": "1556150" + } +}], +"sender_qual": "31B", +"UNA": { + "seg_term": "'", + "decimal_sign": ".", + "esc_char": "?", + "de_sep": "+", + "ce_sep": ":", + "rep_sep": " " +}, +"recipient_qual": "31B" +} diff --git a/Open-ILS/src/support-scripts/test-scripts/payment_test.pl b/Open-ILS/src/support-scripts/test-scripts/payment_test.pl index 41ece54d6..e0d5ecc8c 100644 --- a/Open-ILS/src/support-scripts/test-scripts/payment_test.pl +++ b/Open-ILS/src/support-scripts/test-scripts/payment_test.pl @@ -32,7 +32,7 @@ Transaction data: Example: -$0 --login=seller_1254418209_biz_api1.esilibrary.com \\ +$0 --login=seller_1254418209_biz_api1.example.org \\ --password=1254618222 \\ --signature=AiPC9xjkCyDFQXbSkoZcgqH3hpacAVPVw5GcZgNKVA9SGKcbrqLuhLks \\ --amount=32.75 \\ diff --git a/Open-ILS/web/js/ui/default/conify/global/acq/edi_account.js b/Open-ILS/web/js/ui/default/conify/global/acq/edi_account.js new file mode 100644 index 000000000..40ab63ba7 --- /dev/null +++ b/Open-ILS/web/js/ui/default/conify/global/acq/edi_account.js @@ -0,0 +1,23 @@ +dojo.require('openils.widget.AutoGrid'); +dojo.require('dijit.form.FilteringSelect'); +dojo.require('openils.PermaCrud'); + +function draw() { + if (! targetId) { + pListGrid.loadAll({order_by:{acqedi : 'id'}}); + pListGrid.onPostCreate = function(fmObject) { + location.href = location.href + '/' + fmObject.id(); + }; + return; + } + + var pcrud = new openils.PermaCrud(); + pcrud.retrieve('acqedi', targetId, { + oncomplete : function(r) { + console.log('edi_account is' + js2JSON(openils.Util.readResponse(r))); + } + }); +} + +openils.Util.addOnLoad(draw); + diff --git a/Open-ILS/web/opac/locale/en-US/lang.dtd b/Open-ILS/web/opac/locale/en-US/lang.dtd index 60c5ed67a..29eca0129 100644 --- a/Open-ILS/web/opac/locale/en-US/lang.dtd +++ b/Open-ILS/web/opac/locale/en-US/lang.dtd @@ -819,6 +819,8 @@ <!ENTITY staff.main.menu.acq.funding_source.accesskey "S"> <!ENTITY staff.main.menu.acq.provider.label "Providers"> <!ENTITY staff.main.menu.acq.provider.accesskey "V"> +<!ENTITY staff.main.menu.acq.edi_account.label "EDI Accounts"> +<!ENTITY staff.main.menu.acq.edi_account.accesskey "A"> <!ENTITY staff.main.menu.acq.distrib_formula.label "Distribution Formulas"> <!ENTITY staff.main.menu.acq.distrib_formula.accesskey "D"> <!ENTITY staff.main.menu.acq.currency_type.label "Currency Types"> diff --git a/Open-ILS/web/templates/default/conify/global/acq/edi_account.tt2 b/Open-ILS/web/templates/default/conify/global/acq/edi_account.tt2 new file mode 100644 index 000000000..56b21c044 --- /dev/null +++ b/Open-ILS/web/templates/default/conify/global/acq/edi_account.tt2 @@ -0,0 +1,69 @@ +[% WRAPPER default/base.tt2 %] +<script type="text/javascript" src='[% ctx.media_prefix %]/js/ui/default/conify/global/acq/edi_account.js'> </script> + +<script type="text/javascript"> +// dojo.require('openils.widget.OrgUnitFilteringSelect'); +dojo.require('fieldmapper.OrgUtils'); + +var targetId = '[% ctx.page_args.0 %]'; + +function getOrgName(orgId) { + return fieldmapper.aou.findOrgUnit(orgId).shortname(); +} +function getOwner(rowIndex, item) { + if (!item) return ''; + var id = this.grid.store.getValue(item, 'owner'); + return getOrgName(id); +} +function getProvider(rowIndex, item) { + if (!item) return ''; + var id = this.grid.store.getValue(item, 'provider'); + return id + ':' + id; // TODO: get acq.provider.code from fieldmapper or elsewhere +} +function formatProvider(value) { + if (value) { + var vals = value.split(/:/); + return '<a href="[% ctx.base_path %]/conify/global/acq/provider/'+vals[0]+'">'+vals[1]+'</a>'; + } +} +</script> + +<div id='main-list-div'> + <div dojoType="dijit.layout.ContentPane" layoutAlign='top'> + <div dojoType="dijit.layout.ContentPane" layoutAlign="top" class='oils-header-panel'> + <div>EDI Accounts</div> + <div> + <button dojoType='dijit.form.Button' onClick='pListGrid.showCreateDialog()'>New Account</button> + <button dojoType='dijit.form.Button' onClick='pListGrid.deleteSelected()'>Delete Selected</button> + </div> + </div> + </div> + <!-- + <div> + <span>Context Org Unit</span> + <select dojoType="openils.widget.OrgUnitFilteringSelect" jsId='btContextOrgSelect' + searchAttr='shortname' labelAttr='shortname'> </select> + </div> + --> + <div dojoType="dijit.layout.ContentPane" layoutAlign="client"> + <table jsId="pListGrid" + dojoType="openils.widget.AutoGrid" + fieldOrder="['id', 'label', 'host', 'username', 'password', 'account', 'owner', 'last_activity', 'provider', 'path', 'in_dir', 'vendcode']" + query="{id: '*'}" + defaultCellWidth='"auto"' + autoHeight='true' + fmClass='acqedi' + showPaginator='true' + editOnEnter='true'> + <thead> + <tr> + <th field='provider' get='getProvider' formatter='formatProvider'/> + <th field='owner' get='getOwner'/> + </tr> + </thead> + </table> + </div> +</div> + +[% END %] + diff --git a/Open-ILS/web/templates/default/conify/global/acq/provider.tt2 b/Open-ILS/web/templates/default/conify/global/acq/provider.tt2 index e65112383..de3a7fa61 100644 --- a/Open-ILS/web/templates/default/conify/global/acq/provider.tt2 +++ b/Open-ILS/web/templates/default/conify/global/acq/provider.tt2 @@ -1,34 +1,9 @@ [% WRAPPER default/base.tt2 %] -<script src='[% ctx.media_prefix %]/js/ui/default/conify/global/acq/provider.js'> </script> +<script type="text/javascript" src='[% ctx.media_prefix %]/js/ui/default/conify/global/acq/provider.js'> </script> <script type="text/javascript"> var providerId = '[% ctx.page_args.0 %]'; - - -function formatName(inDatum) { - switch (inDatum) { - case 'owning_lib': - return 'Owning Library'; - case 'quantity': - return 'Quantity'; - case 'call_number': - return 'Call Number'; - case 'fund_code': - return 'Fund Code'; - case 'local_note': - return 'Local Note'; - case 'price': - return 'Price'; - case 'circ_modifier': - return 'Circulation Modifier'; - case 'copy_location': - return 'Copy Location'; - case 'collection_code': - return 'Collection Code'; - } -} - function getInvIdent(rowIndex, item) { if (!item) return {}; return { diff --git a/Open-ILS/xul/staff_client/chrome/content/main/menu.js b/Open-ILS/xul/staff_client/chrome/content/main/menu.js index d0d216965..2124e1da1 100644 --- a/Open-ILS/xul/staff_client/chrome/content/main/menu.js +++ b/Open-ILS/xul/staff_client/chrome/content/main/menu.js @@ -778,6 +778,10 @@ main.menu.prototype = { ['oncommand'], function() { open_eg_web_page('conify/global/acq/provider', 'menu.cmd_acq_view_provider.tab'); } ], + 'cmd_acq_view_edi_account' : [ + ['oncommand'], + function() { open_eg_web_page('conify/global/acq/edi_account', 'menu.cmd_acq_view_edi_account.tab'); } + ], 'cmd_acq_view_currency_type' : [ ['oncommand'], function() { open_eg_web_page('acq/currency_type/list', 'menu.cmd_acq_view_currency_type.tab'); } diff --git a/Open-ILS/xul/staff_client/chrome/content/main/menu_frame_menus.xul b/Open-ILS/xul/staff_client/chrome/content/main/menu_frame_menus.xul index 08045ed7e..3d617f7ec 100644 --- a/Open-ILS/xul/staff_client/chrome/content/main/menu_frame_menus.xul +++ b/Open-ILS/xul/staff_client/chrome/content/main/menu_frame_menus.xul @@ -89,6 +89,7 @@ <command id="cmd_acq_view_fund" /> <command id="cmd_acq_view_funding_source" /> <command id="cmd_acq_view_provider" /> + <command id="cmd_acq_view_edi_account" /> <command id="cmd_acq_view_currency_type" /> <command id="cmd_acq_view_exchange_rate" /> <command id="cmd_acq_view_distrib_formula" /> @@ -274,6 +275,7 @@ <menuitem label="&staff.main.menu.acq.fund.label;" accesskey="&staff.main.menu.acq.fund.accesskey;" command="cmd_acq_view_fund" /> <menuitem label="&staff.main.menu.acq.funding_source.label;" accesskey="&staff.main.menu.acq.funding_source.accesskey;" command="cmd_acq_view_funding_source" /> <menuitem label="&staff.main.menu.acq.provider.label;" accesskey="&staff.main.menu.acq.provider.accesskey;" command="cmd_acq_view_provider" /> + <menuitem label="&staff.main.menu.acq.edi_account.label;" accesskey="&staff.main.menu.acq.edi_account.accesskey;" command="cmd_acq_view_edi_account" /> <menuitem label="&staff.main.menu.acq.currency_type.label;" accesskey="&staff.main.menu.acq.currency_type.accesskey;" command="cmd_acq_view_currency_type" /> <menuitem label="&staff.main.menu.acq.exchange_rate.label;" accesskey="&staff.main.menu.acq.exchange_rate.accesskey;" command="cmd_acq_view_exchange_rate" /> <menuitem label="&staff.main.menu.acq.distrib_formula.label;" accesskey="&staff.main.menu.acq.distrib_formula.accesskey;" command="cmd_acq_view_distrib_formula" /> diff --git a/Open-ILS/xul/staff_client/chrome/content/util/fm_view.xul b/Open-ILS/xul/staff_client/chrome/content/util/fm_view.xul index 45047114b..e75d08b09 100644 --- a/Open-ILS/xul/staff_client/chrome/content/util/fm_view.xul +++ b/Open-ILS/xul/staff_client/chrome/content/util/fm_view.xul @@ -13,12 +13,12 @@ onload="try { my_init(); font_helper(); } catch(E) { dump(E+'\n'); alert(E); }" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> - <script type="text/javascript">var myPackageDir = 'open_ils_staff_client'; var IAMXUL = true; var g = {};</script> - <scripts id="openils_util_scripts"/> + <script type="text/javascript">var myPackageDir = 'open_ils_staff_client'; var IAMXUL = true; var g = {};</script> + <scripts id="openils_util_scripts"/> <script type="text/javascript" src="/xul/server/main/JSAN.js"/> - <script> + <script type="text/javascript"> <![CDATA[ var tree; var mw = { diff --git a/Open-ILS/xul/staff_client/chrome/locale/en-US/offline.properties b/Open-ILS/xul/staff_client/chrome/locale/en-US/offline.properties index 51b03d0b5..facfd9322 100644 --- a/Open-ILS/xul/staff_client/chrome/locale/en-US/offline.properties +++ b/Open-ILS/xul/staff_client/chrome/locale/en-US/offline.properties @@ -234,6 +234,7 @@ menu.cmd_acq_user_requests.tab=User Requests menu.cmd_acq_view_fund.tab=Funds menu.cmd_acq_view_funding_source.tab=Funding Sources menu.cmd_acq_view_provider.tab=Providers +menu.cmd_acq_view_edi_account.tab=EDI Accounts menu.cmd_acq_view_currency_type.tab=Currency Types menu.cmd_acq_view_exchange_rate.tab=Exchange Rates menu.cmd_acq_view_distrib_formula.tab=Distribution Formulas diff --git a/build/tools/update.sh b/build/tools/update.sh index 03fe90321..5b6e5293c 100755 --- a/build/tools/update.sh +++ b/build/tools/update.sh @@ -183,3 +183,4 @@ sleep 2; cd $INSTALL/bin; ./autogen.sh ../conf/opensrf_core.xml; sudo /etc/init.d/apache2 start; +echo $'done\a' # \a = Bell character for beep -- 2.11.0