226 lines
6.6 KiB
Python
226 lines
6.6 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Process entries in the staging database put there by
|
|
edi_867 and prepare them for X3 batch importing
|
|
"""
|
|
import pathlib
|
|
import datetime
|
|
import pprint
|
|
import shutil
|
|
|
|
import records # type: ignore
|
|
import yamamotoyama # type: ignore
|
|
import yamamotoyama.x3_imports # type: ignore
|
|
import simple_email_notification
|
|
|
|
THIS_DIRECTORY = pathlib.Path(__file__).parent
|
|
IMPORTS_DIRECTORY = THIS_DIRECTORY / 'x3_imports'
|
|
|
|
UNVALIDATED_STATEMENT = """
|
|
select
|
|
sdhnum
|
|
from staging.dbo.shandex_receipts
|
|
left join x3.PROD.SDELIVERY SDH
|
|
on shandex_receipts.sdhnum = SDH.SDHNUM_0
|
|
where
|
|
is_sent = 0
|
|
and SDH.CFMFLG_0 = 1
|
|
"""
|
|
|
|
SELECT_STATEMENT = """
|
|
select
|
|
sdhnum
|
|
from staging.dbo.shandex_receipts
|
|
left join x3.PROD.SDELIVERY SDH
|
|
on shandex_receipts.sdhnum = SDH.SDHNUM_0
|
|
where
|
|
is_sent = 0
|
|
and SDH.CFMFLG_0 = 2
|
|
"""
|
|
|
|
|
|
HEADER_STATEMENT = """
|
|
select
|
|
[sdhnum]
|
|
,[E]
|
|
,[prhfcy]
|
|
,[rcpdat]
|
|
,[pthnum]
|
|
,[bpsnum]
|
|
,[cur]
|
|
,[star71]
|
|
,[star72]
|
|
,[star81]
|
|
,[star82]
|
|
,[is_sent]
|
|
from staging.dbo.shandex_receipts
|
|
where sdhnum = :sdhnum
|
|
"""
|
|
|
|
DETAIL_STATEMENT = """
|
|
select
|
|
[L]
|
|
,[sdhnum]
|
|
,[sddlin]
|
|
,[itmref]
|
|
,[uom]
|
|
,[qtyuom]
|
|
,[pjt]
|
|
,[star65]
|
|
,[star91]
|
|
,[star92]
|
|
FROM [staging].[dbo].[shandex_receipt_details]
|
|
where sdhnum = :sdhnum
|
|
group by
|
|
[L]
|
|
,[sdhnum]
|
|
,[sddlin]
|
|
,[itmref]
|
|
,[uom]
|
|
,[qtyuom]
|
|
,[pjt]
|
|
,[star65]
|
|
,[star91]
|
|
,[star92]
|
|
"""
|
|
|
|
SUBDETAIL_STATEMENT = """
|
|
select
|
|
'S' [S],
|
|
'A' [sta],
|
|
[STJ].[PCU_0] [pcu],
|
|
cast(cast(-1*[STJ].[QTYSTU_0] as int) as nvarchar) [qtypcu],
|
|
[STJ].[LOT_0] [lot],
|
|
'' [bpslot],
|
|
'' [sernum]
|
|
from [staging].[dbo].[shandex_receipt_details]
|
|
left join x3.PROD.STOJOU STJ
|
|
on STJ.VCRNUM_0 = [shandex_receipt_details].sdhnum
|
|
and STJ.ITMREF_0 = [shandex_receipt_details].itmref
|
|
and STJ.LOT_0 = [shandex_receipt_details].lot
|
|
and STJ.VCRLIN_0 = [shandex_receipt_details].sddlin
|
|
where sdhnum = :sdhnum
|
|
and itmref = :itmref
|
|
"""
|
|
|
|
UPDATE_STATEMENT = """
|
|
update [staging].[dbo].[shandex_receipts]
|
|
set is_sent = 1
|
|
where sdhnum = :sdhnum
|
|
"""
|
|
|
|
HEADER_NAMES = ['E','prhfcy','rcpdat','pthnum','bpsnum','cur','star71','star72','star81','star82']
|
|
|
|
DETAIL_NAMES = ['L','sdhnum','sddlin','itmref','uom','qtyuom','pjt','star65','star91','star92']
|
|
|
|
SUBDETAIL_NAMES = ['S','sta','pcu','qtypcu','lot','bpslot','sernum']
|
|
|
|
|
|
def unvalidated_shipments_alert(unvalidated_shipments):
|
|
to_addresses = ['bleeson@stashtea.com','icortes@yamamotoyama.com','mdelacruz@yamamotoyama.com',
|
|
'dalmanza@yamamotoyama.com','jpena@yamamotoyama.com']
|
|
subject = 'Shandex: Unvalidated shipments awaiting receipt'
|
|
body_text = ['Shipments pending validation:']
|
|
for record in unvalidated_shipments:
|
|
body_text.append(record['sdhnum'])
|
|
simple_email_notification.email_noticication(to_addresses, subject, body_text)
|
|
|
|
def get_receipts(database):
|
|
with database.transaction():
|
|
result = database.query(SELECT_STATEMENT).all()
|
|
return result
|
|
|
|
def get_unvalidated_shipments(database):
|
|
with database.transaction():
|
|
result = database.query(UNVALIDATED_STATEMENT).all()
|
|
return result
|
|
|
|
def get_receipt_headers(database, sdhnum):
|
|
result = database.query(
|
|
HEADER_STATEMENT,
|
|
sdhnum=sdhnum
|
|
).first()
|
|
return result
|
|
|
|
def get_receipt_details(database, sdhnum):
|
|
result = database.query(
|
|
DETAIL_STATEMENT,
|
|
sdhnum=sdhnum
|
|
).all()
|
|
return result
|
|
|
|
def get_receipt_subdetails(database, sdhnum, itmref):
|
|
result = database.query(
|
|
SUBDETAIL_STATEMENT,
|
|
sdhnum=sdhnum,
|
|
itmref=itmref
|
|
).all()
|
|
return result
|
|
|
|
def create_imports(receipts, database):
|
|
for receipt in receipts:
|
|
time_stamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
with open(
|
|
IMPORTS_DIRECTORY / f"ZPTHI_{receipt['sdhnum']}_{time_stamp}.dat", 'w', encoding='utf-8', newline='\n'
|
|
) as import_file:
|
|
headers = get_receipt_headers(database, receipt['sdhnum'])
|
|
details = get_receipt_details(database, receipt['sdhnum'])
|
|
for name in HEADER_NAMES:
|
|
import_file.write(headers[name])
|
|
import_file.write(chr(31))
|
|
import_file.write('\n')
|
|
for record in details:
|
|
for name in DETAIL_NAMES:
|
|
import_file.write(record[name])
|
|
import_file.write(chr(31))
|
|
import_file.write('\n')
|
|
subdetails = get_receipt_subdetails(database, receipt['sdhnum'], record['itmref'])
|
|
for subrecord in subdetails:
|
|
for name in SUBDETAIL_NAMES:
|
|
import_file.write(subrecord[name])
|
|
import_file.write(chr(31))
|
|
import_file.write('\n')
|
|
|
|
def combine_imports():
|
|
archive_directory = IMPORTS_DIRECTORY / "archive"
|
|
archive_directory.mkdir(exist_ok=True)
|
|
with (IMPORTS_DIRECTORY / "ZPTHI.dat").open(
|
|
"w", encoding="utf-8", newline="\n"
|
|
) as combined_import_file:
|
|
for individual_import_filename in IMPORTS_DIRECTORY.glob(
|
|
"ZPTHI_*.dat"
|
|
):
|
|
with individual_import_filename.open(
|
|
"r", encoding="utf-8", newline="\n"
|
|
) as individual_import_file:
|
|
for line in individual_import_file:
|
|
combined_import_file.write(line)
|
|
shutil.move(
|
|
individual_import_filename,
|
|
archive_directory / individual_import_filename.name,
|
|
)
|
|
|
|
def mark_sent(database, receipts):
|
|
with database.transaction():
|
|
for receipt in receipts:
|
|
result = database.query(
|
|
UPDATE_STATEMENT,
|
|
sdhnum=receipt['sdhnum']
|
|
)
|
|
|
|
def main():
|
|
with yamamotoyama.get_connection() as database:
|
|
#retrieve everything that has a valid customer and hasn't already been sent to X3
|
|
receipts = get_receipts(database)
|
|
#TODO check for validation problems, report on them, and don't try to process them
|
|
unvalidateds = get_unvalidated_shipments(database)
|
|
if unvalidateds:
|
|
unvalidated_shipments_alert(unvalidateds)
|
|
#turn each shipment into a X3 import file
|
|
create_imports(receipts, database)
|
|
combine_imports()
|
|
#udate the is_sent field so they are not processed again
|
|
mark_sent(database, receipts)
|
|
|
|
if __name__ == "__main__":
|
|
main() |