def main(inn,out): root = {} rec_counts = {} # == HEADER - WEO00R == if True: ELEMENT = "WEO00R" SEGMENT = "00" rec_counts[SEGMENT] = rec_counts.setdefault(SEGMENT, 0) + 1 HEAD_ID = inn.get({'BOTSID': 'picking'}, {'BOTSID': 'header', 'message_id': None}) HEAD_DATE, HEAD_TIME = get_datetime(inn.get({'BOTSID': 'picking'}, {'BOTSID': 'header', 'date_msg': None})) HEAD_TYPE = inn.get({'BOTSID': 'picking'}, {'BOTSID': 'header', 'type': None}) assert HEAD_TYPE == 'in', "Warehouse Entry Orders must have type 'in', not '%s'" % (HEAD_TYPE,) HEAD_TYPE = "943" # Warehouse Entry Order d = OrderedDict([ ('Segment_Number', SEGMENT), ('Identification_Nbr', HEAD_ID or ''), ('Message_Date', HEAD_DATE or ''), ('Message_Time', HEAD_TIME or ''), ('Message_Type_Id', HEAD_TYPE), ]) root.setdefault(ELEMENT, []).append(d) pinn = inn.getloop({'BOTSID': 'picking'}, {'BOTSID': 'pickings'}) for pick in pinn: ORD_ID = pick.get({'BOTSID': 'pickings', 'id': None}) assert ORD_ID, "Order ID must be present" ORD_ID = re.sub(r'[\\/_-]', r'', ORD_ID.upper()) ORD_STATE = pick.get({'BOTSID': 'pickings', 'state': None}) # == Cancelled Orders - WEO05R == if ORD_STATE == 'delete': ELEMENT = "WEO05R" SEGMENT = "05" rec_counts[SEGMENT] = rec_counts.setdefault(SEGMENT, 0) + 1 d = OrderedDict([ ('Segment_Number', SEGMENT), ('Order_Reference', ORD_ID), ]) root.setdefault(ELEMENT, []).append(d) # == New Orders - WEO10R == elif ORD_STATE == 'new': ELEMENT = "WEO10R" SEGMENT = "10" rec_counts[SEGMENT] = rec_counts.setdefault(SEGMENT, 0) + 1 ORD_REMARK = pick.get({'BOTSID': 'pickings', 'desc': None}) ORD_DELIVERY_DATE, dummy = get_datetime(pick.get({'BOTSID': 'pickings', 'date': None}) + ' 00:00:00.00000') ord_root = OrderedDict([ ('Segment_Number', SEGMENT), ('Order_Type', 'I'), # Incoming ('Indicator_Transport', 'N'), ('Order_Reference', ORD_ID), ('Indicator_Labelling', 'N'), ('Indicator_contact_cl', 'N'), ('Order_Category', 'N'), # N = New ('Date_expected', ORD_DELIVERY_DATE), ('Remark', ORD_REMARK), ]) root.setdefault(ELEMENT, []).append(ord_root) # == Order Remarks - WEO20R == if ORD_REMARK: ELEMENT = "WEO20R" SEGMENT = "20" rec_counts[SEGMENT] = rec_counts.setdefault(SEGMENT, 0) + 1 d = OrderedDict([ ('Segment_Number', SEGMENT), ('Order_Remark', ORD_REMARK), ('Order_Remark_Qual', 'G'), # General note (not for box label) ]) ord_root.setdefault(ELEMENT, []).append(d) # == Order Party - WEO30R == ELEMENT = "WEO30R" SEGMENT = "30" rec_counts[SEGMENT] = rec_counts.setdefault(SEGMENT, 0) + 1 PART_ID = pick.get({'BOTSID': 'pickings'}, {'BOTSID': 'partner', 'id': None}) PART_EMAIL = pick.get({'BOTSID': 'pickings'}, {'BOTSID': 'partner', 'email': None}) party_root = OrderedDict([ ('Segment_Number', SEGMENT), ('Order_Party_Qual', 'CO'), # Consignor - Party sending goods ('Party_External_Ref', PART_ID), ]) ord_root.setdefault(ELEMENT, []).append(party_root) # == Order Party Address - WEO32R == ELEMENT = "WEO32R" SEGMENT = "32" rec_counts[SEGMENT] = rec_counts.setdefault(SEGMENT, 0) + 1 PART_NAME = pick.get({'BOTSID': 'pickings'}, {'BOTSID': 'partner', 'name': None}) or '' PART_STREET1 = pick.get({'BOTSID': 'pickings'}, {'BOTSID': 'partner', 'street1': None}) or '' PART_STREET2 = pick.get({'BOTSID': 'pickings'}, {'BOTSID': 'partner', 'street2': None}) or '' PART_CITY = pick.get({'BOTSID': 'pickings'}, {'BOTSID': 'partner', 'city': None}) or '' PART_ZIP = pick.get({'BOTSID': 'pickings'}, {'BOTSID': 'partner', 'zip': None}) or '' PART_COUNTRY = pick.get({'BOTSID': 'pickings'}, {'BOTSID': 'partner', 'country': None}) or '' PART_STATE = pick.get({'BOTSID': 'pickings'}, {'BOTSID': 'partner', 'state': None}) or '' PART_PHONE = pick.get({'BOTSID': 'pickings'}, {'BOTSID': 'partner', 'phone': None}) or '' PART_FAX = pick.get({'BOTSID': 'pickings'}, {'BOTSID': 'partner', 'fax': None}) or '' PART_LANG = pick.get({'BOTSID': 'pickings'}, {'BOTSID': 'partner', 'language': None}) or '' PART_VAT = pick.get({'BOTSID': 'pickings'}, {'BOTSID': 'partner', 'vat': None}) or '' # Spill the first address line over to the second if too long, else truncate if len(PART_STREET1) > 35 and not PART_STREET2: space = PART_STREET1.rfind(' ', 0, 35) if space: OLD_STREET1 = PART_STREET1 PART_STREET1 = OLD_STREET1[:space] PART_STREET2 = OLD_STREET1[space+1:] PART_STREET1 = PART_STREET1[:35] PART_STREET2 = PART_STREET2[:35] d = OrderedDict([ ('Segment_Number', SEGMENT), ('Company_Name_1', PART_NAME[:35]), ('Address_3', PART_STREET2), ('Postal_Code', PART_ZIP), ('Place_Name', PART_CITY[:35]), ('Country_Code', PART_COUNTRY), ('Language_code', get_dsv_lang(PART_LANG)), ('Telephone_Number', PART_PHONE), ('Telefax_Number', PART_FAX), ('VAT-number', PART_VAT), ('Address_2', PART_STREET1), ('Address_4', PART_STATE), ]) party_root.setdefault(ELEMENT, []).append(d) plines = pick.getloop({'BOTSID': 'pickings'}, {'BOTSID': 'line'}) for pline in plines: # == Order Line - WEO40R == ELEMENT = "WEO40R" SEGMENT = "40" rec_counts[SEGMENT] = rec_counts.setdefault(SEGMENT, 0) + 1 LINE_ID = pline.get({'BOTSID': 'line', 'id': None}) LINE_SEQ = "%03d" % (int(pline.get({'BOTSID': 'line', 'seq': None})),) LINE_PRODUCT = pline.get({'BOTSID': 'line', 'product': None}).upper() LINE_TYPE = '*FIRST' LINE_QTY = pline.get({'BOTSID': 'line', 'product_qty': None}) LINE_DESC = pline.get({'BOTSID': 'line', 'desc': None}) LINE_VOLUME_NET = pline.get({'BOTSID': 'line', 'volume_net': None}) LINE_WEIGHT = pline.get({'BOTSID': 'line', 'weight': None}) LINE_WEIGHT_NET = pline.get({'BOTSID': 'line', 'weight_net': None}) LINE_PRICE_UNIT = pline.get({'BOTSID': 'line', 'price_unit': None}) LINE_CURRENCY = pline.get({'BOTSID': 'line', 'price_currency': None}) LINE_CUSTOMS_FROM = pline.get({'BOTSID': 'line', 'customs_free_from': None}) LINE_CUSTOMS_FROM = (LINE_CUSTOMS_FROM in ("1", "True", None) and 'FR') or 'T1' line_root = OrderedDict([ ('Segment_Number', SEGMENT), ('Orderline_ID', LINE_SEQ), ('SKU_Reference', LINE_PRODUCT), ('Customs_Status_from', LINE_CUSTOMS_FROM), ('Currency_customs_val', LINE_CURRENCY), ('Type_of_package', LINE_TYPE), ('Measure_unit_specifier', 'PCE'), # FIXME: We only support units UoM currently ('Number_of_packages', LINE_QTY), ('Number_of_units_measure_unit_specifier', LINE_QTY), ('Number_of_units_measure_unit_specifier_per_type_of_package', 1), # FIXME: We only support units UoM currently ('Orderline_remarks', LINE_DESC), ('Net_volume_per_unit_measure_unit_specifier', LINE_VOLUME_NET), ]) ord_root.setdefault(ELEMENT, []).append(line_root) # == Order Line Customs Value - WEO48R == ELEMENT = "WEO48R" SEGMENT = "48" rec_counts[SEGMENT] = rec_counts.setdefault(SEGMENT, 0) + 1 d = OrderedDict([ ('Segment_Number', SEGMENT), ('Customs_value_qual', '001'), # Goods value ('Customs_value', "%015.02f" % (float(LINE_PRICE_UNIT) * float(LINE_QTY)),), ('Positive-sign', 'Y'), ]) line_root.setdefault(ELEMENT, []).append(d) # Catch all else: raise NotImplementedError('Unable to handle order with state %s' % (ORD_STATE,)) # == FOOTER - WEO99R == rec_counts['99'] = len(rec_counts.keys()) for FOOT_REC_TYPE, FOOT_REC_COUNT in rec_counts.iteritems(): ELEMENT = "WEO99R" SEGMENT = "99" d = OrderedDict([ ('Segment_Number', SEGMENT), ('RecordType', FOOT_REC_TYPE), ('Total_Nbrs_of_Rec', FOOT_REC_COUNT), ]) root.setdefault(ELEMENT, []).append(d) root = OrderedDict(sorted(root.items(), key=lambda t: t[0])) document = OrderedDict([('WEO', root)]) data = serialize_dsv_xml(document, SCHEMA) out.root = data return
def main(inn,out): root = {} rec_counts = {} # == HEADER - WSO00R == if True: ELEMENT = "WSO00R" SEGMENT = "00" rec_counts[SEGMENT] = rec_counts.setdefault(SEGMENT, 0) + 1 HEAD_ID = inn.get({'BOTSID': 'picking'}, {'BOTSID': 'header', 'message_id': None}) HEAD_DATE, HEAD_TIME = get_datetime(inn.get({'BOTSID': 'picking'}, {'BOTSID': 'header', 'date_msg': None})) HEAD_TYPE = inn.get({'BOTSID': 'picking'}, {'BOTSID': 'header', 'type': None}) assert HEAD_TYPE == 'out', "Warehouse Shipping Orders must have type 'out', not '%s'" % (HEAD_TYPE,) HEAD_TYPE = "940" # Warehouse Shipping Order d = OrderedDict([ ('Segment_Number', SEGMENT), ('Identification_Nbr', HEAD_ID or ''), ('Message_Date', HEAD_DATE or ''), ('Message_Time', HEAD_TIME or ''), ('Message_Type_Id', HEAD_TYPE), ]) root.setdefault(ELEMENT, []).append(d) pinn = inn.getloop({'BOTSID': 'picking'}, {'BOTSID': 'pickings'}) for pick in pinn: ORD_ID = pick.get({'BOTSID': 'pickings', 'id': None}) assert ORD_ID, "Order ID must be present" ORD_ID = re.sub(r'[\\/_-]', r'', ORD_ID.upper()) out.ta_info['botskey'] = ORD_ID # Set the botskey to the last order ID ORD_STATE = pick.get({'BOTSID': 'pickings', 'state': None}) # == Cancelled Orders - WSO05R == if ORD_STATE == 'delete': ELEMENT = "WSO05R" SEGMENT = "05" rec_counts[SEGMENT] = rec_counts.setdefault(SEGMENT, 0) + 1 d = OrderedDict([ ('Segment_Number', SEGMENT), ('Order_reference', ORD_ID), ]) root.setdefault(ELEMENT, []).append(d) # == New Orders - WSO10R == elif ORD_STATE == 'new': ELEMENT = "WSO10R" SEGMENT = "10" rec_counts[SEGMENT] = rec_counts.setdefault(SEGMENT, 0) + 1 INCOTERM = pick.get({'BOTSID': 'pickings', 'incoterm': None}) ORD_PRIO = pick.get({'BOTSID': 'pickings', 'prio': None}) ORD_REMARK = pick.get({'BOTSID': 'pickings', 'desc': None}) ORD_DELIVERY_DATE, dummy = get_datetime(pick.get({'BOTSID': 'pickings', 'date': None}) + ' 00:00:00.00000') ord_root = OrderedDict([ ('Segment_Number', SEGMENT), ('Order_Type', 'O'), # Outgoing ('Indicator_Transport', 'Y'), ('Order_Reference', ORD_ID), ('Indicator_Labelling', 'Y'), ('Indicator_contact_cl', 'Y'), ('Terms_of_Delivery', INCOTERM), ('COD_amount', '0.0'), ('Currency_COD-amount', ''), ('Order_Category', 'N'), # N = New ('Order_priority', ORD_PRIO), ('Delivery_date', ORD_DELIVERY_DATE), ('Remark', ORD_REMARK), # FIXME: We add this last to validate against DSV's example messages, it should come just before priority ]) root.setdefault(ELEMENT, []).append(ord_root) # == Order Remarks - WSO20R == if ORD_REMARK: ELEMENT = "WSO20R" SEGMENT = "20" rec_counts[SEGMENT] = rec_counts.setdefault(SEGMENT, 0) + 1 d = OrderedDict([ ('Segment_Number', SEGMENT), ('Order_Remark', ORD_REMARK), ('Order_Remark_Qual', 'D'), # Delivery Instructions ]) ord_root.setdefault(ELEMENT, []).append(d) # == Order Party - WSO30R == ELEMENT = "WSO30R" SEGMENT = "30" rec_counts[SEGMENT] = rec_counts.setdefault(SEGMENT, 0) + 1 PART_ID = pick.get({'BOTSID': 'pickings'}, {'BOTSID': 'partner', 'id': None}) CLIENT_REF = pick.get({'BOTSID': 'pickings', 'client_order_ref': None}) PART_EMAIL = pick.get({'BOTSID': 'pickings'}, {'BOTSID': 'partner', 'email': None}) party_root = OrderedDict([ ('Segment_Number', SEGMENT), ('Order_Party_Qual', 'CN'), # Consignee - Party receiving goods ('Party_External_Ref', PART_ID), ('Client_Ref_to_Order', CLIENT_REF), ]) ord_root.setdefault(ELEMENT, []).append(party_root) # == Order Party Email - WSO31R == if PART_EMAIL: ELEMENT = "WSO31R" SEGMENT = "31" rec_counts[SEGMENT] = rec_counts.setdefault(SEGMENT, 0) + 1 d = OrderedDict([ ('Segment_Number', SEGMENT), ('Communication_Number_Qualifier', 'EA'), # Email ('Communication_Number', PART_EMAIL), ('Recipient_type', 0), # 0=To, 1=CC, 2=BCC ]) party_root.setdefault(ELEMENT, []).append(d) # == Order Party Address - WSO32R == ELEMENT = "WSO32R" SEGMENT = "32" rec_counts[SEGMENT] = rec_counts.setdefault(SEGMENT, 0) + 1 PART_NAME = pick.get({'BOTSID': 'pickings'}, {'BOTSID': 'partner', 'name': None}) or '' PART_STREET1 = pick.get({'BOTSID': 'pickings'}, {'BOTSID': 'partner', 'street1': None}) or '' PART_STREET2 = pick.get({'BOTSID': 'pickings'}, {'BOTSID': 'partner', 'street2': None}) or '' PART_CITY = pick.get({'BOTSID': 'pickings'}, {'BOTSID': 'partner', 'city': None}) or '' PART_ZIP = pick.get({'BOTSID': 'pickings'}, {'BOTSID': 'partner', 'zip': None}) or '' PART_COUNTRY = pick.get({'BOTSID': 'pickings'}, {'BOTSID': 'partner', 'country': None}) or '' PART_STATE = pick.get({'BOTSID': 'pickings'}, {'BOTSID': 'partner', 'state': None}) or '' PART_PHONE = pick.get({'BOTSID': 'pickings'}, {'BOTSID': 'partner', 'phone': None}) or '' PART_FAX = pick.get({'BOTSID': 'pickings'}, {'BOTSID': 'partner', 'fax': None}) or '' PART_LANG = pick.get({'BOTSID': 'pickings'}, {'BOTSID': 'partner', 'language': None}) or '' PART_VAT = pick.get({'BOTSID': 'pickings'}, {'BOTSID': 'partner', 'vat': None}) or '' # Spill the first address line over to the second if too long, else truncate if len(PART_STREET1) > 35 and not PART_STREET2: space = PART_STREET1.rfind(' ', 0, 35) if space: OLD_STREET1 = PART_STREET1 PART_STREET1 = OLD_STREET1[:space] PART_STREET2 = OLD_STREET1[space+1:] PART_STREET1 = PART_STREET1[:35] PART_STREET2 = PART_STREET2[:35] d = OrderedDict([ ('Segment_Number', SEGMENT), ('Company_Name_1', PART_NAME[:35]), ('Address_3', PART_STREET2), ('Postal_Code', PART_ZIP), ('Place_Name', PART_CITY[:35]), ('Country_Code', PART_COUNTRY), ('Language_code', get_dsv_lang(PART_LANG)), ('Telephone_Number', PART_PHONE), ('Telefax_Number', PART_FAX), ('VAT-number', PART_VAT), ('Address_2', PART_STREET1), ('Address_4', PART_STATE), ]) party_root.setdefault(ELEMENT, []).append(d) plines = pick.getloop({'BOTSID': 'pickings'}, {'BOTSID': 'line'}) for pline in plines: # == Order Line - WSO40R == ELEMENT = "WSO40R" SEGMENT = "40" rec_counts[SEGMENT] = rec_counts.setdefault(SEGMENT, 0) + 1 LINE_ID = pline.get({'BOTSID': 'line', 'id': None}) LINE_SEQ = "%03d" % (int(pline.get({'BOTSID': 'line', 'seq': None})),) LINE_PRODUCT = pline.get({'BOTSID': 'line', 'product': None}).upper() LINE_TYPE = '*FIRST' LINE_QTY = pline.get({'BOTSID': 'line', 'product_qty': None}) LINE_DESC = pline.get({'BOTSID': 'line', 'desc': None}) LINE_VOLUME_NET = pline.get({'BOTSID': 'line', 'volume_net': None}) LINE_WEIGHT = pline.get({'BOTSID': 'line', 'weight': None}) LINE_WEIGHT_NET = pline.get({'BOTSID': 'line', 'weight_net': None}) LINE_PRICE_UNIT = pline.get({'BOTSID': 'line', 'price_unit_ex_vat': None}) or 0.0 LINE_CURRENCY = pline.get({'BOTSID': 'line', 'price_currency': None}) line_root = OrderedDict([ ('Segment_Number', SEGMENT), ('Orderline_ID', LINE_SEQ), ('SKU_Reference', LINE_PRODUCT), ('Type_of_package', LINE_TYPE), ('Number_of_packages', LINE_QTY), ('Number_of_units_measure_unit_specifier', LINE_QTY), ('Number_of_units_measure_unit_specifier_per_type_of_package', 1), # FIXME: We only support units UoM currently ('Orderline_remarks', LINE_DESC), ('Net_volume_per_unit_measure_unit-specifier', LINE_VOLUME_NET), ]) ord_root.setdefault(ELEMENT, []).append(line_root) # == Order Line Invoice - WSO41R == ELEMENT = "WSO41R" SEGMENT = "41" rec_counts[SEGMENT] = rec_counts.setdefault(SEGMENT, 0) + 1 assert (ord_root.get('Currency_COD-amount', LINE_CURRENCY) or LINE_CURRENCY) == LINE_CURRENCY, 'Multiple currencies per order is not supported' ord_root.update({'Currency_COD-amount': LINE_CURRENCY}) try: LINE_PRICE_UNIT = "%.2f" % (round(float(LINE_PRICE_UNIT), 2),) except ValueError: LINE_PRICE_UNIT = "" d = OrderedDict([ ('Segment_Number', SEGMENT), ('Goods_invoice_amount', LINE_PRICE_UNIT), ('Goods_inv_amoun_Qual', 'U'), # Unit price ]) line_root.setdefault(ELEMENT, []).append(d) # Catch all else: raise NotImplementedError('Unable to handle order with state %s' % (ORD_STATE,)) # == FOOTER - WSO99R == rec_counts['99'] = len(rec_counts.keys()) for FOOT_REC_TYPE, FOOT_REC_COUNT in rec_counts.iteritems(): ELEMENT = "WSO99R" SEGMENT = "99" d = OrderedDict([ ('Segment_Number', SEGMENT), ('RecordType', FOOT_REC_TYPE), ('Total_Nbrs_of_Rec', FOOT_REC_COUNT), ]) root.setdefault(ELEMENT, []).append(d) root = OrderedDict(sorted(root.items(), key=lambda t: t[0])) document = OrderedDict([('WSO', root)]) data = serialize_dsv_xml(document, SCHEMA) out.root = data return
def main(inn, out): root = {} rec_counts = {} # == HEADER - WSO00R == if True: ELEMENT = "WSO00R" SEGMENT = "00" rec_counts[SEGMENT] = rec_counts.setdefault(SEGMENT, 0) + 1 HEAD_ID = inn.get({'BOTSID': 'picking'}, { 'BOTSID': 'header', 'message_id': None }) HEAD_DATE, HEAD_TIME = get_datetime( inn.get({'BOTSID': 'picking'}, { 'BOTSID': 'header', 'date_msg': None })) HEAD_TYPE = inn.get({'BOTSID': 'picking'}, { 'BOTSID': 'header', 'type': None }) assert HEAD_TYPE == 'out', "Warehouse Shipping Orders must have type 'out', not '%s'" % ( HEAD_TYPE, ) HEAD_TYPE = "940" # Warehouse Shipping Order d = OrderedDict([ ('Segment_Number', SEGMENT), ('Identification_Nbr', HEAD_ID or ''), ('Message_Date', HEAD_DATE or ''), ('Message_Time', HEAD_TIME or ''), ('Message_Type_Id', HEAD_TYPE), ]) root.setdefault(ELEMENT, []).append(d) pinn = inn.getloop({'BOTSID': 'picking'}, {'BOTSID': 'pickings'}) for pick in pinn: ORD_ID = pick.get({'BOTSID': 'pickings', 'id': None}) assert ORD_ID, "Order ID must be present" ORD_ID = re.sub(r'[\\/_-]', r'', ORD_ID.upper()) out.ta_info['botskey'] = ORD_ID # Set the botskey to the last order ID ORD_STATE = pick.get({'BOTSID': 'pickings', 'state': None}) # == Cancelled Orders - WSO05R == if ORD_STATE == 'delete': ELEMENT = "WSO05R" SEGMENT = "05" rec_counts[SEGMENT] = rec_counts.setdefault(SEGMENT, 0) + 1 d = OrderedDict([ ('Segment_Number', SEGMENT), ('Order_reference', ORD_ID), ]) root.setdefault(ELEMENT, []).append(d) # == New Orders - WSO10R == elif ORD_STATE == 'new': ELEMENT = "WSO10R" SEGMENT = "10" rec_counts[SEGMENT] = rec_counts.setdefault(SEGMENT, 0) + 1 INCOTERM = pick.get({'BOTSID': 'pickings', 'incoterm': None}) ORD_PRIO = pick.get({'BOTSID': 'pickings', 'prio': None}) ORD_REMARK = pick.get({'BOTSID': 'pickings', 'desc': None}) ORD_DELIVERY_DATE, dummy = get_datetime( pick.get({ 'BOTSID': 'pickings', 'date': None }) + ' 00:00:00.00000') ord_root = OrderedDict([ ('Segment_Number', SEGMENT), ('Order_Type', 'O'), # Outgoing ('Indicator_Transport', 'Y'), ('Order_Reference', ORD_ID), ('Indicator_Labelling', 'Y'), ('Indicator_contact_cl', 'Y'), ('Terms_of_Delivery', INCOTERM), ('COD_amount', '0.0'), ('Currency_COD-amount', ''), ('Order_Category', 'N'), # N = New ('Order_priority', ORD_PRIO), ('Delivery_date', ORD_DELIVERY_DATE), ( 'Remark', ORD_REMARK ), # FIXME: We add this last to validate against DSV's example messages, it should come just before priority ]) root.setdefault(ELEMENT, []).append(ord_root) # == Order Remarks - WSO20R == if ORD_REMARK: ELEMENT = "WSO20R" SEGMENT = "20" rec_counts[SEGMENT] = rec_counts.setdefault(SEGMENT, 0) + 1 d = OrderedDict([ ('Segment_Number', SEGMENT), ('Order_Remark', ORD_REMARK), ('Order_Remark_Qual', 'D'), # Delivery Instructions ]) ord_root.setdefault(ELEMENT, []).append(d) # == Order Party - WSO30R == ELEMENT = "WSO30R" SEGMENT = "30" rec_counts[SEGMENT] = rec_counts.setdefault(SEGMENT, 0) + 1 PART_ID = pick.get({'BOTSID': 'pickings'}, { 'BOTSID': 'partner', 'id': None }) CLIENT_REF = pick.get({ 'BOTSID': 'pickings', 'client_order_ref': None }) PART_EMAIL = pick.get({'BOTSID': 'pickings'}, { 'BOTSID': 'partner', 'email': None }) party_root = OrderedDict([ ('Segment_Number', SEGMENT), ('Order_Party_Qual', 'CN'), # Consignee - Party receiving goods ('Party_External_Ref', PART_ID), ('Client_Ref_to_Order', CLIENT_REF), ]) ord_root.setdefault(ELEMENT, []).append(party_root) # == Order Party Email - WSO31R == if PART_EMAIL: ELEMENT = "WSO31R" SEGMENT = "31" rec_counts[SEGMENT] = rec_counts.setdefault(SEGMENT, 0) + 1 d = OrderedDict([ ('Segment_Number', SEGMENT), ('Communication_Number_Qualifier', 'EA'), # Email ('Communication_Number', PART_EMAIL), ('Recipient_type', 0), # 0=To, 1=CC, 2=BCC ]) party_root.setdefault(ELEMENT, []).append(d) # == Order Party Address - WSO32R == ELEMENT = "WSO32R" SEGMENT = "32" rec_counts[SEGMENT] = rec_counts.setdefault(SEGMENT, 0) + 1 PART_NAME = pick.get({'BOTSID': 'pickings'}, { 'BOTSID': 'partner', 'name': None }) or '' PART_STREET1 = pick.get({'BOTSID': 'pickings'}, { 'BOTSID': 'partner', 'street1': None }) or '' PART_STREET2 = pick.get({'BOTSID': 'pickings'}, { 'BOTSID': 'partner', 'street2': None }) or '' PART_CITY = pick.get({'BOTSID': 'pickings'}, { 'BOTSID': 'partner', 'city': None }) or '' PART_ZIP = pick.get({'BOTSID': 'pickings'}, { 'BOTSID': 'partner', 'zip': None }) or '' PART_COUNTRY = pick.get({'BOTSID': 'pickings'}, { 'BOTSID': 'partner', 'country': None }) or '' PART_STATE = pick.get({'BOTSID': 'pickings'}, { 'BOTSID': 'partner', 'state': None }) or '' PART_PHONE = pick.get({'BOTSID': 'pickings'}, { 'BOTSID': 'partner', 'phone': None }) or '' PART_FAX = pick.get({'BOTSID': 'pickings'}, { 'BOTSID': 'partner', 'fax': None }) or '' PART_LANG = pick.get({'BOTSID': 'pickings'}, { 'BOTSID': 'partner', 'language': None }) or '' PART_VAT = pick.get({'BOTSID': 'pickings'}, { 'BOTSID': 'partner', 'vat': None }) or '' # Spill the first address line over to the second if too long, else truncate if len(PART_STREET1) > 35 and not PART_STREET2: space = PART_STREET1.rfind(' ', 0, 35) if space: OLD_STREET1 = PART_STREET1 PART_STREET1 = OLD_STREET1[:space] PART_STREET2 = OLD_STREET1[space + 1:] PART_STREET1 = PART_STREET1[:35] PART_STREET2 = PART_STREET2[:35] d = OrderedDict([ ('Segment_Number', SEGMENT), ('Company_Name_1', PART_NAME[:35]), ('Address_3', PART_STREET2), ('Postal_Code', PART_ZIP), ('Place_Name', PART_CITY[:35]), ('Country_Code', PART_COUNTRY), ('Language_code', get_dsv_lang(PART_LANG)), ('Telephone_Number', PART_PHONE), ('Telefax_Number', PART_FAX), ('VAT-number', PART_VAT), ('Address_2', PART_STREET1), ('Address_4', PART_STATE), ]) party_root.setdefault(ELEMENT, []).append(d) plines = pick.getloop({'BOTSID': 'pickings'}, {'BOTSID': 'line'}) for pline in plines: # == Order Line - WSO40R == ELEMENT = "WSO40R" SEGMENT = "40" rec_counts[SEGMENT] = rec_counts.setdefault(SEGMENT, 0) + 1 LINE_ID = pline.get({'BOTSID': 'line', 'id': None}) LINE_SEQ = "%03d" % (int( pline.get({ 'BOTSID': 'line', 'seq': None })), ) LINE_PRODUCT = pline.get({ 'BOTSID': 'line', 'product': None }).upper() LINE_TYPE = '*FIRST' LINE_QTY = pline.get({'BOTSID': 'line', 'product_qty': None}) LINE_DESC = pline.get({'BOTSID': 'line', 'desc': None}) LINE_VOLUME_NET = pline.get({ 'BOTSID': 'line', 'volume_net': None }) LINE_WEIGHT = pline.get({'BOTSID': 'line', 'weight': None}) LINE_WEIGHT_NET = pline.get({ 'BOTSID': 'line', 'weight_net': None }) LINE_PRICE_UNIT = pline.get({ 'BOTSID': 'line', 'price_unit_ex_vat': None }) or 0.0 LINE_CURRENCY = pline.get({ 'BOTSID': 'line', 'price_currency': None }) line_root = OrderedDict([ ('Segment_Number', SEGMENT), ('Orderline_ID', LINE_SEQ), ('SKU_Reference', LINE_PRODUCT), ('Type_of_package', LINE_TYPE), ('Number_of_packages', LINE_QTY), ('Number_of_units_measure_unit_specifier', LINE_QTY), ('Number_of_units_measure_unit_specifier_per_type_of_package', 1), # FIXME: We only support units UoM currently ('Orderline_remarks', LINE_DESC), ('Net_volume_per_unit_measure_unit-specifier', LINE_VOLUME_NET), ]) ord_root.setdefault(ELEMENT, []).append(line_root) # == Order Line Invoice - WSO41R == ELEMENT = "WSO41R" SEGMENT = "41" rec_counts[SEGMENT] = rec_counts.setdefault(SEGMENT, 0) + 1 assert ( ord_root.get('Currency_COD-amount', LINE_CURRENCY) or LINE_CURRENCY ) == LINE_CURRENCY, 'Multiple currencies per order is not supported' ord_root.update({'Currency_COD-amount': LINE_CURRENCY}) try: LINE_PRICE_UNIT = "%.2f" % (round(float(LINE_PRICE_UNIT), 2), ) except ValueError: LINE_PRICE_UNIT = "" d = OrderedDict([ ('Segment_Number', SEGMENT), ('Goods_invoice_amount', LINE_PRICE_UNIT), ('Goods_inv_amoun_Qual', 'U'), # Unit price ]) line_root.setdefault(ELEMENT, []).append(d) # Catch all else: raise NotImplementedError('Unable to handle order with state %s' % (ORD_STATE, )) # == FOOTER - WSO99R == rec_counts['99'] = len(rec_counts.keys()) for FOOT_REC_TYPE, FOOT_REC_COUNT in rec_counts.iteritems(): ELEMENT = "WSO99R" SEGMENT = "99" d = OrderedDict([ ('Segment_Number', SEGMENT), ('RecordType', FOOT_REC_TYPE), ('Total_Nbrs_of_Rec', FOOT_REC_COUNT), ]) root.setdefault(ELEMENT, []).append(d) root = OrderedDict(sorted(root.items(), key=lambda t: t[0])) document = OrderedDict([('WSO', root)]) data = serialize_dsv_xml(document, SCHEMA) out.root = data return