From eb4d0beac896aa3dcf714162397b86e7e0f37280 Mon Sep 17 00:00:00 2001 From: bleeson Date: Tue, 28 May 2024 07:50:09 -0700 Subject: [PATCH] Mapping ship-to customers. --- edi_867.py | 121 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 107 insertions(+), 14 deletions(-) diff --git a/edi_867.py b/edi_867.py index 4834906..eac556d 100644 --- a/edi_867.py +++ b/edi_867.py @@ -2,6 +2,11 @@ """ Consume a 867 file from Shandex, and translate into a Sage X3 readable file-ZSHIP867. + +New changes, need to bring in under ship to customer whenever possible. +Build a mapping file of known customers by matching their address to x3 codes +need to not import a shipment if a customer mapping doesn't exist. + """ # pylint: disable=too-many-instance-attributes import dataclasses @@ -13,6 +18,9 @@ import re import shutil import typing import pprint +import smtplib +from email.mime.multipart import MIMEMultipart +from email.mime.text import MIMEText import records # type: ignore @@ -25,13 +33,38 @@ IMPORTS_DIRECTORY = THIS_DIRECTORY / "x3_imports" EDI_997_DIRECTORY = THIS_DIRECTORY / "997_processing" SOURCE_867_FILENAME_RE = re.compile( - r"\A 867_YAMAMOTOYAMA_ .* [.]edi \Z", re.X | re.M | re.S + r"\A 867_STASH-YAMAMOTOYAMA_ .* [.]edi \Z", re.X | re.M | re.S ) UOM_MAPPING = { "CA" : "CS", "EC" : "EA" } +#NAME_ADDRESS_CITY_TERRITORY_POSTAL : X3 Customer Code +X3_CUSTOMER_MAPPING = { + 'AVRI1000_AVRIQC' : 'AVRI0001', + 'BULK1000_BULKAU' : 'BULK0001', + 'COOP2000_190148' : 'FEDE0006', + 'COOP2000_190149' : 'FEDE0005', + 'COOP2000_607S' : 'FEDE0003', + 'COOP2000_CAL' : 'FEDE0007', + 'HORI1000_HORIBC' : 'HORI0001', + 'LOND1000_190005' : 'LOND0001', + 'NATI1000_28' : 'LOBL0002', + 'NATI1000_34' : 'LOBL0006', + 'NATI1000_D022' : 'LOBL0001', + 'ONTA1100_ONTAON' : 'ONTA0002', + 'OVER1000_5111' : 'OVER0002', + 'OVER1000_A24' : 'OVER0004', + 'PARA1100_PARABC' : 'PARA0004', + 'PSCN1000_PSCBC' : 'PSCN0002', + 'PURE1000_PUREON' : 'PURE0004', + 'PURI1000_PURION' : 'PURI0002', + 'SATA1000_SATAQC' : 'SATA0002', + 'UNFI1000_UNFIBC' : 'UNFI0011', + 'UNFI1000_UNFION' : 'UNFI0004', + 'SAMP1000_0000' : 'YARI0001' +} def main(): """ @@ -45,6 +78,19 @@ def main(): combine_zship867s() +def missing_customer_alert(customer_key): + msg = MIMEMultipart() + msg['Subject'] = 'Shandex 867 - Missing X3 Customer' + msg['Precedence'] = 'bulk' + msg['From'] = 'x3report@stashtea.com' + msg['To'] = 'technical-contact@stashtea.com' + emailtext = f'Missing value: {customer_key}' + msg.attach(MIMEText(emailtext, 'plain')) + with smtplib.SMTP_SSL("smtp.gmail.com", 465) as smtp: + smtp.login(user='x3reportmk2@yamamotoyama.com', password=r'n 2:#There is one PTD in the header that is not used + picking_number = fields[5] + warehouse_shipment.header.ylicplate = f'{previous_picking_number}' + if picking_number != previous_picking_number and previous_picking_number != '': + if warehouse_shipment.header.bpdnam != 'Shandex Group': + #pprint.pprint(warehouse_shipment.header.ylicplate) + warehouse_shipment.header.shidat = datetime.datetime.strptime( + shipping_date, "%Y%m%d") + time_stamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") + with yamamotoyama.x3_imports.open_import_file( + IMPORTS_DIRECTORY / f"ZSHIP867_{picking_number}_{time_stamp}.dat" + ) as import_file: + warehouse_shipment.output(import_file) + warehouse_shipment = WarehouseShipment() + warehouse_shipment.header.ylicplate = f'{picking_number}' + previous_picking_number = picking_number + if fields[0] =='REF' and fields[1] == 'IL': + picking_number = fields[2] + if fields[0] == "N1" and fields[1] == 'ST': + ship_to_customer = fields[2] + shandex_code_part1 = fields[4] + warehouse_shipment.header.bpdnam = ship_to_customer + if fields[0] == "N1" and fields[1] == 'BY': + shandex_code_part2 = fields[4] + if fields[0] == "N3": + ship_to_address = fields[1] + warehouse_shipment.header.bpdaddlig = ship_to_address + if fields[0] == "N4": + ship_to_city = fields[1] + ship_to_province = fields[2] + ship_to_zip = fields[3] + warehouse_shipment.header.bpdposcod = ship_to_zip + warehouse_shipment.header.bpdcty = ship_to_city + warehouse_shipment.header.bpdsat = ship_to_province + customer_key = warehouse_shipment.create_customer_key(shandex_code_part2, shandex_code_part1) + if customer_key not in X3_CUSTOMER_MAPPING.keys(): + pprint.pprint(customer_key + ' not found.') + missing_customer_alert(customer_key) + raise NotImplementedError + else: + warehouse_shipment.header.bpcord = X3_CUSTOMER_MAPPING[customer_key] if fields[0] == "QTY": #QTY*39*10*CA _, _, qty_str, uom = fields[:4] @@ -127,14 +209,14 @@ def process_file(edi_filename: pathlib.Path): if fields[0] == "LIN": #LIN**VN*10077652082224*LT*09032026C# _, _, _, gtin, _, lot = fields[:6] - if fields[0] == "UIT": - #UIT*CA*0.00 + if fields[0] == "AMT": + #AMT*LP*53.90 _, _, price = fields[:3] sau = UOM_MAPPING[uom] lookup_values = get_product_from_gtin(gtin) itmref = lookup_values['ITMREF_0'] itmdes = lookup_values['ITMDES1_0'] - + #pprint.pprint(itmdes) subdetail = WarehouseShipmentSubDetail( qtypcu=-1 * int(qty_str), lot=lot, @@ -151,9 +233,12 @@ def process_file(edi_filename: pathlib.Path): ), subdetail, ) + #pprint.pprint(warehouse_shipment.header.ylicplate) + warehouse_shipment.header.shidat = datetime.datetime.strptime( + shipping_date, "%Y%m%d") time_stamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") with yamamotoyama.x3_imports.open_import_file( - IMPORTS_DIRECTORY / f"ZSHIP867_{control_number}_{time_stamp}.dat" + IMPORTS_DIRECTORY / f"ZSHIP867_{picking_number}_{time_stamp}.dat" ) as import_file: warehouse_shipment.output(import_file) @@ -316,6 +401,7 @@ class WarehouseShipmentHeader: salfcy: str = "STC" stofcy: str = "WON" sdhnum: str = "" + bpcinv: str = "SHAN0001" bpcord: str = "SHAN0001" bpaadd: str = "BL001" cur: str = "CAD" @@ -399,6 +485,7 @@ class WarehouseShipmentHeader: self.salfcy, self.stofcy, self.sdhnum, + self.bpcinv, self.bpcord, self.bpaadd, self.cur, @@ -548,6 +635,12 @@ class WarehouseShipment: if value: self._fill_info_from_so() + + def create_customer_key(self, part1, part2): + key = (part1 + '_' + part2).replace(' ', '_') + return key + + def _get_so_from_x3(self) -> records.Record: """ Fetch sales order from X3 database.