Mapping ship-to customers.
parent
7c50f8b6c7
commit
eb4d0beac8
121
edi_867.py
121
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</W<7fr"VD~\2&[pZc5')
|
||||
smtp.send_message(msg)
|
||||
|
||||
|
||||
def combine_zship867s():
|
||||
"""
|
||||
Collect all ZSHIP867 imports into a single file for easy import.
|
||||
|
@ -79,11 +125,9 @@ def tokens_from_edi_file(
|
|||
fields = record.split("*")
|
||||
if fields[0] in {
|
||||
"ISA",
|
||||
"GS",
|
||||
"ST",
|
||||
"BPT",
|
||||
"N1",
|
||||
"PTD",
|
||||
"REF",
|
||||
}:
|
||||
continue
|
||||
yield fields
|
||||
|
@ -111,15 +155,53 @@ def process_file(edi_filename: pathlib.Path):
|
|||
"""
|
||||
Convert a specific EDI file into an import file.
|
||||
"""
|
||||
shipping_date = ''
|
||||
previous_picking_number = ''
|
||||
warehouse_shipment = WarehouseShipment()
|
||||
for fields in tokens_from_edi_file(edi_filename):
|
||||
if fields[0] == "GS":
|
||||
control_number = fields[5]
|
||||
warehouse_shipment.header.ylicplate = f'{control_number}'
|
||||
if fields[0] == "DTM":
|
||||
date_field = fields[2]
|
||||
warehouse_shipment.header.shidat = datetime.datetime.strptime(
|
||||
date_field, "%Y%m%d")
|
||||
shipping_date = fields[2]
|
||||
if fields[0] == "PTD" and len(fields) > 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.
|
||||
|
|
Loading…
Reference in New Issue