LP#1373690 continued
authorBill Erickson <berickxx@gmail.com>
Thu, 25 Sep 2014 15:00:32 +0000 (11:00 -0400)
committerBill Erickson <berickxx@gmail.com>
Wed, 13 May 2015 22:41:40 +0000 (18:41 -0400)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/perlmods/lib/OpenILS/Application/Trigger/Reactor.pm
Open-ILS/src/sql/Pg/upgrade/XXXX.data.acq-order-edi.sql

index 70d3844..3705fe6 100644 (file)
@@ -300,6 +300,10 @@ $_TT_helpers = {
     # Removes potentially troublesome characters from text for inclusion
     # in an EDI document.
     # See also get_li_attr_jedi()
+    # XXX: strictly speaking, we can escape ', +, :, and ? characters
+    # with the escape character '?'.  Historically, scrubbing the data
+    # has worked with known vendors, so such a change would require
+    # a new round of vendor testing.
     escape_edi => sub {
         my $value = shift;
         {
index a9d65a0..96bece6 100644 (file)
@@ -68,21 +68,22 @@ $$
         INC_ITEM_TYPE = 0;
     END;
 
-    # END GIR configuration ---------------------------------
-
-    # TODO: helpers.escape_edi() for removing/escaping single quotes!
+    # add one to this number for each lineitem segment and copy segment
+    SEGMENT_COUNT = 13; 
 
+    # END GIR configuration ---------------------------------
 -%]
 [%- BLOCK big_block -%]
 UNA:+.? '
-UNB+UNOB:3+338277X:31B+1556150:31B+140924:1351+1'
+UNB+UNOB:3+[% VENDCODE %]:31B+[% VENDOR_SAN %]:31B+140924:1351+1'
 UNH+1+ORDERS:D:96A:UN'
 BGM+220+98+9'
-DTM+137:20140909:102'
-NAD+BY+338277X 0021::91'
-NAD+SU+1556150::31B'
+DTM+137:[% date.format(date.now, '%Y%m%d') %]:102'
+[%- BUYER = VENDCODE; IF VENDOR_BT; BUYER = BUYER _ ' ' _ VENDACCT; END -%]
+NAD+BY+[% BUYER %]::91'
+NAD+SU+[% VENDOR_SAN %]::31B'
 NAD+SU+12::92'
-CUX+2:USD:9'
+CUX+2:[% target.provider.currency_type %]:9'
 [% FOR li IN target.lineitems;
     idval = '';
     idqual = 'EN'; # default ISBN/UPC/EAN-13
@@ -98,7 +99,12 @@ CUX+2:USD:9'
     ELSE;
         idqual = 'IN';
         idval = li.id;
-    END -%]
+    END;
+
+    # every lineitem has 10 segments, plus optional copy segments
+    SEGMENT_COUNT = SEGMENT_COUNT + 10;
+
+-%]
 LIN+[% li.id %]++[% idval %]:[% idqual %]'
 PIA+5+[% idval %]:[% idqual %]'
 IMD+F+BTI+:::[% helpers.get_li_attr_edi('title',     '', li.attributes) %]'
@@ -106,16 +112,106 @@ IMD+F+BPU+:::[% helpers.get_li_attr_edi('author',    '', li.attributes) %]'
 IMD+F+BPD+:::[% helpers.get_li_attr_edi('pubdate',   '', li.attributes) %]'
 IMD+F+BPH+:::[% helpers.get_li_attr_edi('pagination','', li.attributes) %]'
 QTY+21:[% li.lineitem_details.size %]'
+[%- IF INC_COPIES;
+    GIR_INDEX = 1;
+    compressed_copies = [];
+    FOR lid IN li.lineitem_details;
+        fund = lid.fund.code;
+        item_type = lid.circ_modifier;
+        callnumber = lid.cn_label;
+        owning_lib = lid.owning_lib.shortname;
+        location = lid.location;
+        collection_code = lid.collection_code;
+
+        # when we have real copy data, treat it as authoritative for some fields
+        acp = lid.eg_copy_id;
+        IF acp;
+            item_type = acp.circ_modifier;
+            callnumber = acp.call_number.label;
+            location = acp.location.name;
+        END ;
+
+
+        # collapse like copies into groups w/ quantity
+
+        found_match = 0;
+        IF !INC_COPY_ID; # INC_COPY_ID implies 1 copy per GIR
+            FOR copy IN compressed_copies;
+                IF  (fund == copy.fund OR (!fund AND !copy.fund)) AND
+                    (item_type == copy.item_type OR (!item_type AND !copy.item_type)) AND
+                    (callnumber == copy.callnumber OR (!callnumber AND !copy.callnumber)) AND
+                    (owning_lib == copy.owning_lib OR (!owning_lib AND !copy.owning_lib)) AND
+                    (location == copy.location OR (!location AND !copy.location)) AND
+                    (collection_code == copy.collection_code OR (!collection_code AND !copy.collection_code));
+
+                    copy.quantity = copy.quantity + 1;
+                    found_match = 1;
+                END;
+            END;
+        END;
+
+        IF !found_match;
+            compressed_copies.push({
+                fund => fund,
+                item_type => item_type,
+                callnumber => callnumber,
+                owning_lib => owning_lib,
+                location => location,
+                collection_code => collection_code,
+                copy_id => lid.id, # for INC_COPY_ID
+                quantity => 1
+            });
+        END;
+    END;
+    FOR copy IN compressed_copies;
+
+    # If we assume owning_lib is required and set, 
+    # it is safe to prepend each following copy field w/ a ","
+
+    # B&T EDI requires expected GIR fields to be 
+    # present regardless of whether a value exists.  
+    # some fields are required to have a value in ACQ, 
+    # though, so they are not forced into place below. 
+    
+    OWNING_LIB='';
+    FUND='';
+    CALLNUMBER='';
+    ITEM_TYPE='';
+    LOCATION='';
+    COLLECTION_CODE='';
+    QUANTITY='';
+    COPY_ID='';
+-%]
+
+
+[%- IF INC_OWNING_LIB AND copy.owning_lib %]OWNING_LIB= "owning_lib":"[% copy.owning_lib %]"[% END -%]
+[%- IF INC_FUND AND copy.fund %],"fund":"[% copy.fund %]"[% END -%]
+[%- IF INC_CALLNUMBER AND (VENDOR_BT OR copy.callnumber) %],"call_number":"[% copy.callnumber %]"[% END -%]
+[%- IF INC_ITEM_TYPE AND (VENDOR_BT OR copy.item_type) %],"item_type":"[% copy.item_type %]"[% END -%]
+[%- IF INC_LOCATION AND copy.location %],"copy_location":"[% copy.location %]"[% END -%]
+[%- IF INC_COLLECTION_CODE AND (VENDOR_BT OR copy.collection_code) %],"collection_code":"[% copy.collection_code %]"[% END -%]
+[%- IF INC_QUANTITY %],"quantity":"[% copy.quantity %]"[% END -%]
+[%- IF INC_COPY_ID %],"copy_id":"[% copy.copy_id %]" [% END %]
+
+GIR+[% GIR_INDEX.format('%d.03') %]
+
+[%- END -%] [%# FOR compressed_copies -%]
+[%- END -%] [%# IF INC_COPIES -%]
 FTX+LIN+1'
-PRI+AAB:30'
+PRI+AAB:[% li.estimated_unit_price || "0.00" %]'
 RFF+LI:[% target.id %]/[% li.id %]'
-[% END %]
+[%- END -%]
 UNS+S'
-CNT+2:3'
+CNT+2:[% target.lineitems.size %]'
 UNT+40+1'
 UNZ+1+1'
 [% END %]
-[% tempo = PROCESS big_block; tempo; %]
+[% 
+    tempo = PROCESS big_block; 
+    # EDI should not have newlines, but they are useful for testing.
+    #tempo.remove('\n');
+    tempo;
+%]
 $$
 );
 
@@ -144,8 +240,8 @@ COMMIT;
 
 -- TESTING
 
-INSERT INTO action_trigger.event (target, event_def, run_time,state) 
-VALUES (1, 51, now(), 'pending');
+\i /home/berick/code/Evergreen/Open-ILS/src/sql/Pg/upgrade/XXXX.data.acq-order-edi.sql
+INSERT INTO action_trigger.event (target, event_def, run_time,state) VALUES (1, 51, now(), 'pending');
 
 */