''' Created on May 12, 2015 Generate @author: Wes ''' from alert import send_alert_html from glob import glob import datetime import logging import sys import StringIO from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker from sqlalchemy.sql.expression import update RECIPIENTS = ['admin@example.com'] SUBJECT = 'Shipment Notices Transmitted to Maharam.' MESSAGE = None TEST_MODE = False LOG_LEVEL = logging.DEBUG ACC_NUMBERS = ['3439', '6590'] DROP_SHIP_WAREHOUSES = ['01', '06', '11', '16'] engine = create_engine("mssql+pyodbc://jsisbprod", echo=False) Base = declarative_base(engine) metadata = Base.metadata class CSPASN00(Base): __tablename__ = 'CSPASN00' __table_args__ = {'autoload':True} class CSPASN01(Base): __tablename__ = 'CSPASN01' __table_args__ = {'autoload':True} class CSPASN02(Base): __tablename__ = 'CSPASN02' __table_args__ = {'autoload':True} class CSPASN03(Base): __tablename__ = 'CSPASN03' __table_args__ = {'autoload':True} class CSPASN04(Base): __tablename__ = 'CSPASN04' __table_args__ = {'autoload':True} class XREF(Base): #Customer Xref Table __tablename__ = 'TXUYAT01' __table_args__ = {'autoload':True} class TXRYRT00(Base): #Roll/Tag Master (ticketfl) __tablename__ = 'TXRYRT00' __table_args__ = {'autoload':True} class TXMYAT03(Base): __tablename__ = 'TXMYAT03' __table_args__ = {'autoload':True} def loadSession(): global engine Session = sessionmaker(bind=engine) session = Session() return session def initializeLogger(name='log'): global logger global MESSAGE #logger = logging.getLogger(__name__) logger = logging.getLogger(name) if len(logger.handlers) > 0: return logger logger.setLevel(LOG_LEVEL) handler = logging.FileHandler('D:\\FTP\\logs\\' + name + '.log') handler.setLevel(LOG_LEVEL) formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) logger.addHandler(handler) #Also send logs > DEBUG to stdout ch = logging.StreamHandler(sys.stdout) ch.setLevel(logging.INFO) formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') ch.setFormatter(formatter) logger.addHandler(ch) #Capture log messages in a string for e-mail alert MESSAGE = StringIO.StringIO() sh = logging.StreamHandler(MESSAGE) sh.setLevel(logging.DEBUG) sh.setFormatter(formatter) logger.addHandler(sh) def createMaharamShipNotices(): global MESSAGE initializeLogger('MAH_856_GENERATE') session = loadSession() shipments_to_flag_processed = [] logger.info('Querying CSPASN0[0,1] for unprocessed shipments...') shipmentQ = session.query(CSPASN00,CSPASN01).order_by(CSPASN00.MSTBIL).filter(CSPASN00.CUSTNO.in_(ACC_NUMBERS)).filter(CSPASN00.ABNR == CSPASN01.ABNR, CSPASN00.APLT == CSPASN01.APLT, CSPASN00.CUSTNO == CSPASN01.CUSTNO, CSPASN00.MSTBIL == CSPASN01.MSTBIL) for shipment in shipmentQ: if(shipment[0].PROCSS == 'Y'): continue lines = [] bGroup = shipment[0].ABNR plant = shipment[0].APLT cust = shipment[0].CUSTNO shipmentNumber = shipment[0].MSTBIL shipmentDate = datetime.datetime.strptime(str(shipment[1].SHPDTE), "%Y%m%d") logger.info('Processing shipment number: ' + shipmentNumber) logger.info(' Shipped on: ' + shipmentDate.strftime('%m/%d/%Y')) shipments_to_flag_processed.append(shipmentNumber) logger.info('Querying CSPASN02 for packing lists on this shipment...') packingListQ = session.query(CSPASN02).order_by(CSPASN02.BOLNUM).filter(CSPASN02.ABNR == bGroup, CSPASN02.APLT == plant, CSPASN02.CUSTNO == cust, CSPASN02.MSTBIL == shipmentNumber) for packingList in packingListQ: plNumber = packingList.BOLNUM poNumber = packingList.PONUM stmOrder = packingList.ORDNUM #Build Header Record of transmission hRec = 'H' + plNumber + shipmentDate.strftime('%m%d%Y') + "\n" lines.append(hRec) detailQ = session.query(CSPASN03,CSPASN04).order_by(CSPASN04.LINE).filter(CSPASN03.ABNR == CSPASN04.ABNR, CSPASN03.APLT == CSPASN04.APLT, CSPASN03.CUSTNO == CSPASN04.CUSTNO, CSPASN03.MSTBIL == CSPASN04.MSTBIL, CSPASN03.BOLNUM == CSPASN04.BOLNUM, CSPASN03.CTN == CSPASN04.CTN).filter(CSPASN03.ABNR == bGroup, CSPASN03.APLT == plant, CSPASN03.CUSTNO == cust, CSPASN03.MSTBIL == shipmentNumber, CSPASN03.BOLNUM == plNumber) detailCount = detailQ.count() for detail in detailQ: poLine = detail[1].LINE mahStyle = detail[1].CUST_PATTERNAME.split('/')[0] mahColor = detail[1].CUST_COLORNAME.split('/')[0] if(detail[1].SQTY < 10): ydsShipped = "{0:.5f}".format(detail[1].SQTY) elif(detail[1].SQTY < 100): ydsShipped = "{0:.4f}".format(detail[1].SQTY) else: ydsShipped = "{0:.3f}".format(detail[1].SQTY) if(detail[0].WEIGHT < 10): weight = "{0:.3f}".format(detail[0].WEIGHT) elif(detail[0].WEIGHT < 100): weight = "{0:.2f}".format(detail[0].WEIGHT) else: weight = "{0:.1f}".format(detail[0].WEIGHT) pieceNum = detail[1].ROLNUM ourPattern = detail[1].SB_PATTERNAME.strip() ourColor = detail[1].SB_COLORNUM.strip() #@TODO: Need logic to determine proper ship code. # 01 = Shipped to Maharam # 02 = Shipped to Customer # 03 = Shipped to Finisher # 04 = Drop shipped from finisher # 99 = UNKNOWN shipCode = '99' if(detail[1].WHSE in DROP_SHIP_WAREHOUSES): shipCode = '04' #Drop shipped from finisher else: #if(shipment[1].SNAME in ['MAHARAM FABRICS']): if(shipment[1].SNAME.upper().find('MAHARAM') > -1): shipCode = '01' dRec = 'D'+"{:<12}".format(str(poNumber))+"{:<3}".format(poLine)+"{:<6}".format(mahStyle)+"{:<3}".format(mahColor)+str(ydsShipped)+str(weight)+str(stmOrder)+"{:<10}".format(pieceNum)+"{:<15}".format(ourPattern)+"{:<4}".format(ourColor)+shipCode+"\n" lines.append(dRec) logger.debug('D,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s', "{:<12}".format(str(poNumber)),"{:<3}".format(poLine),"{:<6}".format(mahStyle),"{:<3}".format(mahColor),ydsShipped,weight,stmOrder,"{:<10}".format(pieceNum),"{:<15}".format(ourPattern),"{:<4}".format(ourColor), shipCode) tRec = 'T' + str(detailCount) + "\n" lines.append(tRec) sRec = 'S' + str(len(lines)) #+ "\n" lines.append(sRec) #Write transmission data out to file here logger.info('Creating D:\\FTP\\SEND_MF\\STM_856_' + str(shipmentNumber) + '.txt') f = open('SEND_MF\\STM_856_' + str(shipmentNumber) + '.txt', 'w') f.writelines(lines) f.close() if(len(shipments_to_flag_processed) > 0 and not TEST_MODE): ex = update(CSPASN00.__table__).where(CSPASN00.MSTBIL.in_(shipments_to_flag_processed)).values(PROCSS=u"Y") session.execute(ex) ex = None logger.debug('Comitting changes to database...') session.commit() if(len(shipments_to_flag_processed) == 0): logger.info('Nothing to send!') else: try: logger.info('Sending e-mail alert...') send_alert_html(RECIPIENTS, SUBJECT, attachments=glob('D:\\FTP\\SEND_MF\\STM_856_*.txt'), message=MESSAGE.getvalue()) except: logger.error('Unable to send e-mail. Is the internet out?') logger.debug('Closing database connection...') session.close() MESSAGE.truncate(0) ''' 00 - List of shipments 01 - Contains shipment date for shipments in 01 02 - List of packing slips on each shipment ''' if __name__ == '__main__': createMaharamShipNotices()