diff --git a/edi_846.py b/edi_846.py index 8b6c954..00eb74e 100644 --- a/edi_846.py +++ b/edi_846.py @@ -1,19 +1,11 @@ #!/usr/bin/env python3 """ Consume a 846 file from 3PLs, and translate into a -inventory comparison report that could be used as a stock count? +inventory comparison report For Shadex we also need to reply with a 997 -947 is warehouse advice, to alert us of damages or amount changes from something -like a count + """ -#what about serial numbers? -#status on L line? -#remove negative line, needs to look up stocou? not sure. -# pylint: disable=too-many-instance-attributes -import dataclasses import datetime -import decimal -import functools import pathlib import re import shutil @@ -22,6 +14,7 @@ import smtplib import pprint from email.mime.multipart import MIMEMultipart +from email.mime.application import MIMEApplication from email.mime.text import MIMEText import records # type: ignore @@ -33,9 +26,11 @@ THIS_DIRECTORY = pathlib.Path(__file__).parent X12_DIRECTORY = THIS_DIRECTORY / "incoming" IMPORTS_DIRECTORY = THIS_DIRECTORY / "x3_imports" EDI_997_DIRECTORY = THIS_DIRECTORY / "997_processing" +EDI_846_ATTACHMENTS = THIS_DIRECTORY / "846_reports" +EDI_846_ATTACHMENTS_ARCHIVE = EDI_846_ATTACHMENTS / "archive" SHANDEX_846_FILENAME_RE = re.compile( - r"\A 846_YAMAMOTOYAMA_ \S+ [.]edi \Z", re.X | re.M | re.S + r"\A 846_STASH-YAMAMOTOYAMA_ \S+ [.]edi \Z", re.X | re.M | re.S ) SHANDEX_STATUS = { @@ -49,11 +44,61 @@ def main(): """ Do it! """ + #read in the information from Shandex and store it for edi_filename in X12_DIRECTORY.iterdir(): if SHANDEX_846_FILENAME_RE.match(edi_filename.name): - process_file(edi_filename) + shandex_inventory=process_file(edi_filename) # file moved to 997 processing folder to be sent later - shutil.move(edi_filename, EDI_997_DIRECTORY / edi_filename.name) + #shutil.move(edi_filename, EDI_997_DIRECTORY / edi_filename.name) + #get stock information about WON and store it + #pass date from EDI so we can subtract newer stock movements? + x3_won_inventory=get_x3_won_inventory() + #write out an excel file with the stock from Shandex with X3 next to it, then include anything missing + compare_inventory(shandex_inventory, x3_won_inventory) + stock_count_alert() + + +def compare_inventory(shandex_inventory, x3_inventory): + today = datetime.datetime.today() + today = today.strftime('%Y-%m-%d') + with open(EDI_846_ATTACHMENTS / f'inventory_comparison_{today}.csv', 'w', newline='') as outfile: + outfile.write(','.join(['Site','Item','Description','Lot','X3 qty','Shandex qty']))#header + outfile.write('\n') + for record in x3_inventory: + site = record["STOFCY_0"] + item = record["ITMREF_0"] + des = record["ITMDES1_0"] + lot = record["LOT_0"] + qty = str(record["QTY"]) + outfile.write(','.join([site, item, des, lot, qty])) + outfile.write(',') + if item in shandex_inventory: + if lot in shandex_inventory[item]: + outfile.write(str(shandex_inventory[item][lot])) + # pprint.pprint(shandex_inventory[item]) + del shandex_inventory[item][lot] + # pprint.pprint(shandex_inventory[item]) + if len(shandex_inventory[item]) == 0: + # pprint.pprint('entire del') + # pprint.pprint(shandex_inventory[item]) + del shandex_inventory[item] + # pprint.pprint(shandex_inventory[item]) + else: + outfile.write('0')#lot not found + else: + outfile.write('0')#item not found + outfile.write('\n') + #write the rest of shandex inventory + if len(shandex_inventory) > 0: + outfile.write('Shandex only') + outfile.write('\n') + for item in shandex_inventory: + # pprint.pprint(item) + for lot in shandex_inventory[item]: + # pprint.pprint(lot) + qty = str(shandex_inventory[item][lot]) + outfile.write(','.join([item, lot, qty])) + outfile.write('\n') def tokens_from_edi_file( @@ -68,9 +113,8 @@ def tokens_from_edi_file( if fields[0] in { "ISA", "GS" - "N1", - "N9", - "SE", + "ST", + "RED", "GE", "IEA" }: @@ -78,34 +122,107 @@ def tokens_from_edi_file( yield fields -def gtin_lookup(gtin): - with yamamotoyama.get_connection('test') as db_connection:#todo remove 'test' - return db_connection.query( - """ +def get_x3_won_inventory(): + #TODO correct the dates used in stock_issues? + with yamamotoyama.get_connection() as db_connection: + return db_connection.query( + """ + with stock_issues as ( + select + STJ.STOFCY_0, + STJ.ITMREF_0, + STJ.LOT_0, + sum(STJ.QTYSTU_0) [QTYSTU_0] + from PROD.STOJOU STJ + where + STJ.STOFCY_0 = 'WON' + and STJ.IPTDAT_0 between getdate()-1 and getdate() + group by + STJ.STOFCY_0, + STJ.ITMREF_0, + STJ.LOT_0 + ) select - [ITM].[ITMREF_0], - [ITM].[ITMDES1_0], - [ITM].[EANCOD_0], - [ITM].[ZCASEUPC_0] - from [FY23TEST].[ITMMASTER] [ITM]--TODO change back to [PROD] - join [FY23TEST].[ITMFACILIT] [ITF] - on [ITM].[ITMREF_0] = [ITF].[ITMREF_0] - and [ITF].[STOFCY_0] = 'WON' - where - [ITM].[ZCASEUPC_0] = :zcaseupc - """, - zcaseupc=gtin, - ).first()["ITMREF_0"] + SLF.STOFCY_0, + SLF.ITMREF_0, + ITM.ITMDES1_0, + SLF.LOT_0, + cast(sum(SLF.AAACUMQTY_0 + SLF.QQQCUMQTY_0 + SLF.RRRCUMQTY_0 - coalesce(stock_issues.QTYSTU_0,0)) as integer) as QTY, + SLF.AVC_0 + from PROD.STOLOTFCY SLF + join PROD.ITMMASTER ITM on + SLF.ITMREF_0 = ITM.ITMREF_0 + left join stock_issues + on SLF.ITMREF_0 = stock_issues.ITMREF_0 + and SLF.STOFCY_0 = stock_issues.STOFCY_0 + and SLF.LOT_0 = stock_issues.LOT_0 + where + SLF.STOFCY_0 = 'WON' + group by + SLF.STOFCY_0, + SLF.ITMREF_0, + ITM.ITMDES1_0, + SLF.LOT_0, + SLF.AVC_0 + order by 1, 2 + """, + #startdate=edi_date, + ).all() + +def gtin_lookup(gtin): + with yamamotoyama.get_connection() as db_connection: + itmref = db_connection.query( + """ + select + [ITM].[ITMREF_0], + [ITM].[ITMDES1_0], + [ITM].[EANCOD_0], + [ITM].[ZCASEUPC_0] + from [PROD].[ITMMASTER] [ITM] + join [PROD].[ITMFACILIT] [ITF] + on [ITM].[ITMREF_0] = [ITF].[ITMREF_0] + and [ITF].[STOFCY_0] = 'WON' + where + replace([ITM].[ZCASEUPC_0],' ','') = :zcaseupc + """, + zcaseupc=gtin, + ).first() + if itmref is None: + itmref = db_connection.query( + """ + select + [ITM].[ITMREF_0], + [ITM].[ITMDES1_0], + [ITM].[EANCOD_0], + [ITM].[ZCASEUPC_0] + from [PROD].[ITMMASTER] [ITM] + join [PROD].[ITMFACILIT] [ITF] + on [ITM].[ITMREF_0] = [ITF].[ITMREF_0] + and [ITF].[STOFCY_0] = 'WON' + where + replace([ITM].[EANCOD_0],' ','') = :zcaseupc + """, + zcaseupc=gtin, + ).first()["ITMREF_0"] + else: + itmref = itmref["ITMREF_0"] + return itmref -def stock_movement_alert(itmref, qty, lot, status): +def stock_count_alert(): msg = MIMEMultipart() - msg['Subject'] = 'New Stock Change from Shandex' + msg['Subject'] = 'New Stock Count from Shandex' msg['Precedence'] = 'bulk' msg['From'] = 'x3report@stashtea.com' msg['To'] = 'bleeson@stashtea.com'#TODO correct receipientscares - emailtext = f'Item: {itmref}\nQty: {qty}\nLot: {lot}\nStatus: {DAMAGE_CODE_MAPPING[status]}\nReason: {DAMAGE_CODE_DESCRIPTIONS_MAPPING[status]}' + emailtext = f'Attached.' msg.attach(MIMEText(emailtext, 'plain')) + for file in EDI_846_ATTACHMENTS.iterdir(): + if file.name.endswith('.csv'): + part = MIMEApplication(open(file, 'rb').read()) + part['Content-Disposition'] = f'attachment; filename="{file.name}"' + msg.attach(part) + shutil.move(file, EDI_846_ATTACHMENTS_ARCHIVE / file.name) with smtplib.SMTP_SSL("smtp.gmail.com", 465) as smtp: smtp.login(user='x3reportmk2@yamamotoyama.com', password=r'n typing.List[str]: - # """ - # Convert grouped lot quantities into individual STOJOU records to fit on stockchange - # """ - # with yamamotoyama.get_connection('test') as database: #todo remove 'test' - # details = ( - # database.query( - # """ - # select - # 'S', - # 'A', - # [STJ].[PCU_0], - # cast(cast(-1*[STJ].[QTYSTU_0] as int) as nvarchar), - # [STJ].[LOT_0], - # '', - # '' - # from [FY23TEST].[STOJOU] [STJ] --TODO change to PROD - # where - # [STJ].[VCRNUM_0] = :sdhnum - # and [STJ].[ITMREF_0] = :itmref - # and [STJ].[LOT_0] = :lot - # and [STJ].[TRSTYP_0] = 4 - # """, - # sdhnum=shipment, - # itmref=item, - # lot=self.lot, - # ) - # .all() - # ) - # return details - - - def convert_to_strings(self) -> typing.List[str]: - """ - Convert to strings for X3 import writing. - """ - def fix_uom(uom): - x3_uom = '' - if uom == 'CA': - x3_uom = 'CS' - else: - x3_uom = uom - return x3_uom - - return yamamotoyama.x3_imports.convert_to_strings( - [ - "S", - fix_uom(self.pcu), - self.qtypcu, - self.qtystu, - self.loc, - self.sta, - ] - ) - - -@dataclasses.dataclass -class StockChangeDetail: - """ - Information that goes on a stockchange detail line, taken from ZPTHI template. - """ - - vcrlin: int = 0 - itmref: str = "" - pcu: str = "" - pcustucoe: int = 1 #does this need a lookup? - sta: str = "A" #todo this needs to flip based on the transaction A > R, A > Q, what about Q > A? - loctyp: str = "" - loc: str = "" - lot: str = "" - slo: str = "" - sernum: str = "" - palnum: str = "" - ctrnum: str = "" - qlyctldem: str= "" - owner: str = "WON" - subdetails: typing.List[StockChangeSubDetail] = dataclasses.field( - default_factory=list - ) - - def palnum_lookup(self, itmref, lot, status): - """ - Pick a palnum from X3 using the lot, location, and status - It matters which one we use, best attempt is to get the largest one available - """ - with yamamotoyama.get_connection('test') as db_connection:#todo remove 'test' - return db_connection.query( - """ - select top 1 - [STO].[STOFCY_0], - [STO].[ITMREF_0], - [STO].[LOT_0], - [STO].[PALNUM_0], - [STO].[QTYSTU_0] - from [FY23TEST].[STOCK] [STO] --TODO change to PROD - where - [STO].[ITMREF_0] = :itmref - and [STO].[STOFCY_0] = 'WON' - and [STO].[LOT_0] = :lot - and [STO].[STA_0] = :status - order by - [STO].[QTYSTU_0] desc - """, - itmref=itmref, - lot=lot, - status=status - ).first()["PALNUM_0"] - - def gtin_lookup(self, gtin): - with yamamotoyama.get_connection('test') as db_connection:#todo remove 'test' - return db_connection.query( - """ - select - [ITM].[ITMREF_0], - [ITM].[ITMDES1_0], - [ITM].[EANCOD_0], - [ITM].[ZCASEUPC_0] - from [FY23TEST].[ITMMASTER] [ITM]--TODO change back to [PROD] - join [FY23TEST].[ITMFACILIT] [ITF] - on [ITM].[ITMREF_0] = [ITF].[ITMREF_0] - and [ITF].[STOFCY_0] = 'WON' - where - [ITM].[ZCASEUPC_0] = :zcaseupc - """, - zcaseupc=gtin, - ).first()["ITMREF_0"] - - def append(self, subdetail: StockChangeSubDetail): - """ - Add subdetail - """ - subdetail.pcu = self.pcu - self.subdetails.append(subdetail) - - def check_subdetail_qty(self): - """ - Check for shortages by totaling up subdetail quantities. - """ - total_cases = 0 - for subdetail in self.subdetails: - total_cases -= subdetail.qtypcu - return abs(total_cases) - - def convert_to_strings(self) -> typing.List[str]: - """ - Convert to strings for X3 import writing. - """ - def fix_uom(uom): - x3_uom = '' - if uom == 'CA': - x3_uom = 'CS' - else: - x3_uom = uom - return x3_uom - - self.qty = self.check_subdetail_qty() - return yamamotoyama.x3_imports.convert_to_strings( - [ - "L", - self.vcrlin, - self.itmref, - fix_uom(self.pcu), - self.pcustucoe, - self.sta, - self.loctyp, - self.loc, - self.lot, - self.slo, - self.sernum, - self.palnum_lookup(self.itmref, self.lot, self.sta), - self.ctrnum, - self.qlyctldem, - self.owner - ] - ) - - def __eq__(self, item: typing.Any) -> bool: - """ - Test for equality - """ - if isinstance(item, str): - return self.itmref == item - if isinstance(item, StockChangeDetail): - return self.itmref == item.itmref - return False - - # def fill(self):#not needed for stockchanges - # """ - # Set soplin & itmdes from itmref & sohnum - # """ - - # def get() -> records.Record: - # with yamamotoyama.get_connection() as database: - # how_many = ( - # database.query( - # """ - # select - # count(*) as [how_many] - # from [PROD].[SORDERP] as [SOP] - # where - # [SOP].[SOHNUM_0] = :sohnum - # and [SOP].[ITMREF_0] = :itmref - # """, - # sohnum=self.sohnum, - # itmref=self.itmref, - # ) - # .first() - # .how_many - # ) - # if how_many == 1: - # return database.query( - # """ - # select top 1 - # [SOP].[SOPLIN_0] - # ,[SOP].[ITMDES1_0] - # ,[SOP].[SAU_0] - # from [PROD].[SORDERP] as [SOP] - # where - # [SOP].[SOHNUM_0] = :sohnum - # and [SOP].[ITMREF_0] = :itmref - # order by - # [SOP].[SOPLIN_0] - # """, - # sohnum=self.sohnum, - # itmref=self.itmref, - # ).first() - - - # result = get() - # self.soplin = result.SOPLIN_0 - # self.itmdes = result.ITMDES1_0 - # self.sau = result.SAU_0 - - -@dataclasses.dataclass -class StockChangeHeader: - """ - Information that goes on a stockchange header, taken from ZSCS template. - """ - vcrnum: str = "" - stofcy: str = "WON" - iptdat: datetime.date = datetime.date(1753, 1, 1) - vcrdes: str = "" - pjt: str = "" - trsfam: str = "CHX" - - - def convert_to_strings(self) -> typing.List[str]: - """ - Convert to X3 import line - """ - return yamamotoyama.x3_imports.convert_to_strings( - [ - "E", - self.vcrnum, - self.stofcy, - self.iptdat.strftime("%Y%m%d"), - self.vcrdes, - self.pjt, - self.trsfam, - ] - ) - - -class StockChangeDetailList: - """ - List of stockchange details - """ - - _details: typing.List[StockChangeDetail] - _item_set: typing.Set[str] - - def __init__(self): - self._details = [] - self._item_set = set() - - def append( - self, - stockchange_detail: StockChangeDetail, - stockchange_subdetail: StockChangeSubDetail, - ): - """ - Append - """ - itmref = stockchange_detail.itmref - if itmref in self._item_set: - for detail in self._details: - if detail == itmref: - detail.subdetails.append(stockchange_subdetail) - return - self._item_set.add(itmref) - #stockchange_detail.fill() - stockchange_detail.append(stockchange_subdetail) - self._details.append(stockchange_detail) - - def __iter__(self): - return iter(self._details) - - -class StockChange: - """ - Warehouse stockchange, both header & details - """ - - header: StockChangeHeader - details: StockChangeDetailList - _sdhnum: str - - def __init__(self): - self.header = StockChangeHeader() - self._sdhnum = "" - self.details = StockChangeDetailList() - - def append( - self, - stockchange_detail: StockChangeDetail, - stockchange_subdetail: StockChangeSubDetail, - ): - """ - Add detail information. - """ - self.details.append(stockchange_detail, stockchange_subdetail) - - @property - def sdhnum(self): - """ - shipment number - """ - return self._sdhnum - - @sdhnum.setter - def sdhnum(self, value: str): - if self._sdhnum != value: - self._sdhnum = value - if value: - self._fill_info_from_shipment() - - # def _get_shipment_from_x3(self) -> records.Record: - # """ - # Fetch shipment from X3 database. - # """ - # with yamamotoyama.get_connection('test') as db_connection:#todo remove 'test' - # return db_connection.query( - # """ - # select - # [SDH].[STOFCY_0], - # [SDH].[SDHNUM_0], - # [SDH].[SALFCY_0], - # [SDH].[BPCORD_0], - # [SDH].[CUR_0], - # [SDH].[SOHNUM_0] - # from [FY23TEST].[SDELIVERY] [SDH]--TODO change back to [PROD] - # where - # [SDH].[SDHNUM_0] = :shipment - # """, - # shipment=self.sdhnum, - # ).first() - - # def _fill_info_from_shipment(self): - # """ - # When we learn the SOHNUM, we can copy information from the sales order. - # """ - # result = self._get_shipment_from_x3() - # self.header.stofcy = result.STOFCY_0 - # self.header.sdhnum = result.SDHNUM_0 - # self.header.salfcy = result.SALFCY_0 - # self.header.bpcord = result.BPCORD_0 - # self.header.cur = result.CUR_0 - # self.header.sohnum = result.SOHNUM_0 - - - def output(self, import_file: typing.TextIO): - """ - Output entire order to import_file. - """ - output = functools.partial( - yamamotoyama.x3_imports.output_with_file, import_file - ) - output(self.header.convert_to_strings()) - for detail in self.details: - output(detail.convert_to_strings()) - for subdetail in detail.subdetails: - #shipment = detail.sdhnum - #item = detail.itmref - output(subdetail.convert_to_strings()) - # for record in subdetail.stojous(shipment, item): - # output(subdetail.convert_to_strings()) - # output(record) + qty = 0 + if fields[0] == "QTY":#product should already exist + # QTY*33*0 + # QTY*20*16 + # QTY*QH*0 + qty += int(fields[2]) + if fields[0] == "SE":#end of file + # pprint.pprint('final add') + # pprint.pprint(shandex_inventory) + # pprint.pprint('product: ' + product) + # pprint.pprint('lot: ' + lot) + # pprint.pprint('qty: ' + str(qty)) + if product is not None: #check loop entry + if product not in shandex_inventory: #if we haven't seen the product yet add it + shandex_inventory[product] = {lot : qty} + else: #we've seen this product, have we seen the lot + if lot not in shandex_inventory[product]:#if not, add it + shandex_inventory[product][lot] = qty + else: + shandex_inventory[product][lot] += qty #if we have add to it + return shandex_inventory if __name__ == "__main__": diff --git a/edi_867.py b/edi_867.py index c84a8d4..d215063 100644 --- a/edi_867.py +++ b/edi_867.py @@ -69,6 +69,18 @@ X3_CUSTOMER_MAPPING = { 'JIVA1000_JIVABC' : 'JIVA0002', 'WELL1000_WELL' : 'WELL0002', 'WELL1000_WELCAL' : 'WELL0003', + 'AMAZ1200_YYC4' : 'AMAZ0210', + 'AMAZ1200_YVR2' : 'AMAZ0014', + 'AMAZ1200_YYZ4' : 'AMAZ0049', + 'AMAZ1200_YXU1' : 'AMAZ0189', + 'AMAZ1200_YOW3' : 'AMAZ0176', + 'PARA1100_0000' : 'PARA0004', + 'AMAZ1200_YVR4' : 'AMAZ0099', + 'AMAZ1200_YHM1' : 'AMAZ0169', + 'AMAZ1200_YYZ7' :'AMAZ0100', + 'PURI1000_PURIBC' : 'PURI0003', + 'PURI1000_PURIAB' : 'PURI0004', + 'AMAZ1200_YEG2' : 'AMAZ0179', } def main(): diff --git a/edi_943.py b/edi_943.py index 9c63368..a4cf740 100644 --- a/edi_943.py +++ b/edi_943.py @@ -42,7 +42,7 @@ def main(): """ Do it! """ - with yamamotoyama.get_connection() as database: + with yamamotoyama.get_connection('test') as database: shipments = list(get_shipments(database)) for shipment in shipments: write_943(database, shipment) @@ -127,7 +127,7 @@ def write_943(database: records.Connection, shipment: str): with database.transaction() as _: database.query( """ - update [PROD].[SDELIVERY] + update [FY23TEST].[SDELIVERY] set [XX4S_943RDY_0] = 1 where [SOHNUM_0] = :shipment """, @@ -136,7 +136,7 @@ def write_943(database: records.Connection, shipment: str): order = get_order_for_shipment(database, shipment) database.query( """ - update [PROD].[SORDER] + update [FY23TEST].[SORDER] set [XX4S_UDF2_0] = :sent_message where [SOHNUM_0] = :order """, @@ -153,7 +153,7 @@ def get_shipment_destination(database: records.Connection, shipment: str) -> str """ select [SDH].[BPCORD_0] - from [PROD].[SDELIVERY] as [SDH] + from [FY23TEST].[SDELIVERY] as [SDH] where [SDH].[SDHNUM_0] = :shipment """, @@ -172,7 +172,7 @@ def get_order_for_shipment(database: records.Connection, shipment: str) -> str: """ select [SDH].[SOHNUM_0] - from [PROD].[SDELIVERY] as [SDH] + from [FY23TEST].[SDELIVERY] as [SDH] where [SDH].[SDHNUM_0] = :shipment """, @@ -191,8 +191,8 @@ def get_shipments(database: records.Connection) -> typing.Iterator[str]: """ select [SDH].[SDHNUM_0] - from [PROD].[SDELIVERY] as [SDH] - join [PROD].[SORDER] as [SOH] + from [FY23TEST].[SDELIVERY] as [SDH] + join [FY23TEST].[SORDER] as [SOH] on [SOH].[SOHNUM_0] = [SDH].[SOHNUM_0] where ( @@ -267,7 +267,7 @@ def get_shipment( ,[GROWEI_0] ,[CFMFLG_0] ,[SHIDAT_0] - from [PROD].[zyumiddleware_shipment] as [SDH] + from [FY23TEST].[zyumiddleware_shipment] as [SDH] where [SDH].[SDHNUM_0] = :shipment """, diff --git a/edi_944.py b/edi_944.py index d529147..7460bf0 100644 --- a/edi_944.py +++ b/edi_944.py @@ -63,7 +63,7 @@ def validation_alert(sdhnum): msg['Subject'] = 'New Receipt from Shandex' msg['Precedence'] = 'bulk' msg['From'] = 'x3report@stashtea.com' - #msg['To'] = 'isenn@yamamotoyama.com' + msg['To'] = 'isenn@yamamotoyama.com' msg['CC'] = 'bleeson@stashtea.com' emailtext = f'A Shandex receipt for {sdhnum} could not be loaded into X3 because the shipment is not validated.' msg.attach(MIMEText(emailtext, 'plain')) diff --git a/edi_947.py b/edi_947.py index b14d4dc..9e78242 100644 --- a/edi_947.py +++ b/edi_947.py @@ -39,7 +39,7 @@ SHANDEX_947_FILENAME_RE = re.compile( ) #TODO remove this and have a single production name? why is this one different SHANDEX_947_FILENAME_RE = re.compile( - r"\A STASH_TEST_947 \S+ [.]edi \Z", re.X | re.M | re.S + r"\A 947_QTY_STASH-YAMAMOTOYAMA_ \S+ [.]edi \Z", re.X | re.M | re.S ) @@ -80,7 +80,7 @@ def main(): if SHANDEX_947_FILENAME_RE.match(edi_filename.name): process_file(edi_filename) # file moved to 997 processing folder to be sent later - shutil.move(edi_filename, EDI_997_DIRECTORY / edi_filename.name) + #shutil.move(edi_filename, EDI_997_DIRECTORY / edi_filename.name) combine_zscs() @@ -130,7 +130,7 @@ def tokens_from_edi_file( def gtin_lookup(gtin): - with yamamotoyama.get_connection('test') as db_connection:#todo remove 'test' + with yamamotoyama.get_connection() as db_connection: return db_connection.query( """ select @@ -138,8 +138,8 @@ def gtin_lookup(gtin): [ITM].[ITMDES1_0], [ITM].[EANCOD_0], [ITM].[ZCASEUPC_0] - from [FY23TEST].[ITMMASTER] [ITM]--TODO change back to [PROD] - join [FY23TEST].[ITMFACILIT] [ITF] + from [PROD].[ITMMASTER] [ITM] + join [PROD].[ITMFACILIT] [ITF] on [ITM].[ITMREF_0] = [ITF].[ITMREF_0] and [ITF].[STOFCY_0] = 'WON' where @@ -183,7 +183,7 @@ def process_file(edi_filename: pathlib.Path): product = gtin_lookup(gtin) stock_movement_alert(product, qty, lot, status) if status in EMAIL_ONLY_CODES: - return + continue warehouse_stockchange.header.vcrdes = DAMAGE_CODE_DESCRIPTIONS_MAPPING[status] subdetail = StockChangeSubDetail( qtypcu=int(qty), @@ -307,7 +307,7 @@ class StockChangeDetail: Pick a palnum from X3 using the lot, location, and status It matters which one we use, best attempt is to get the largest one available """ - with yamamotoyama.get_connection('test') as db_connection:#todo remove 'test' + with yamamotoyama.get_connection() as db_connection: result = db_connection.query( """ select top 1 @@ -316,7 +316,7 @@ class StockChangeDetail: [STO].[LOT_0], [STO].[PALNUM_0], [STO].[QTYSTU_0] - from [FY23TEST].[STOCK] [STO] --TODO change to PROD + from [PROD].[STOCK] [STO] where [STO].[ITMREF_0] = :itmref and [STO].[STOFCY_0] = 'WON' @@ -335,7 +335,7 @@ class StockChangeDetail: raise NotImplementedError def gtin_lookup(self, gtin): - with yamamotoyama.get_connection('test') as db_connection:#todo remove 'test' + with yamamotoyama.get_connection() as db_connection: return db_connection.query( """ select @@ -343,8 +343,8 @@ class StockChangeDetail: [ITM].[ITMDES1_0], [ITM].[EANCOD_0], [ITM].[ZCASEUPC_0] - from [FY23TEST].[ITMMASTER] [ITM]--TODO change back to [PROD] - join [FY23TEST].[ITMFACILIT] [ITF] + from [PROD].[ITMMASTER] [ITM] + join [PROD].[ITMFACILIT] [ITF] on [ITM].[ITMREF_0] = [ITF].[ITMREF_0] and [ITF].[STOFCY_0] = 'WON' where