''' Attempting to automatically close invoices in the AS400 using data from Jomar.. weee... Created on: 2017-11-20 @author: Wes ''' import pyodbc, time, logging, sys, os, StringIO, csv, sqlite3 from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker from FTP.alert import send_alert_html RECIPIENTS = ['admin@example.com', 'user1@example.com'] SUBJECT = 'AS400 Invoice Inteface Exceptions' MESSAGE = None AS400_LIB = 'STMDATA' logger = None LOG_LEVEL = logging.DEBUG INVOICE = 0 INVOICE_LINE = 1 TICKET = 2 U_NUMBER = 3 INV_YARDS = 4 FIN_YARDS =5 SHIP_DATE = 6 INV_DATE = 7 #engine = create_engine("mssql+pyodbc://jsisbprod", echo=False) for row in sqlite3.connect('D:\\FTP\\ftp.db').execute("SELECT * FROM connection_strings WHERE code = 'wfa'"): engine = create_engine(row[1], echo=False) Base = declarative_base(engine) metadata = Base.metadata 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:\\' + name + '.log') handler.setLevel(LOG_LEVEL) formatter = logging.Formatter('%(asctime)s - %(name)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.DEBUG) 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 loadSession(): global engine Session = sessionmaker(bind=engine) session = Session() return session def build_extract_query(d): q = ("SELECT r1rnr,r1lfn,RIGHT(rtrnr, 5) rtrnr,urbpo,rtilg,rtpglg,lsdat,'***DATE***' as invdte " "FROM txuyre01 " "LEFT JOIN invoice_rolls ON rtbnr=r1bnr AND rtplt=r1plt AND rtinv=r1rnr AND r1lfn=rtafn " "LEFT JOIN TXUYUV00 ON RTALN = UBLN " "LEFT JOIN TXUYLS00 ON RTDLN = LSNR " "WHERE r1rnr IN (SELECT RRNR FROM TXUYRE00 WHERE RDATLS = '***DATE***') " "AND R1ANR NOT LIKE 'FREIGHT' AND R1ART NOT LIKE 'SR'" "ORDER BY r1lfn,r1rnr") return q.replace('***DATE***',d) def build_insert_statement(r): q = 'INSERT INTO ' + AS400_LIB + '.JSIINV VALUES (INVNUM,INVLIN,TICK#,\'ORDERA\',INVYDS,FINYDS,SHPDTE,INVDTE)' q = q.replace('INVNUM',r[INVOICE]) q = q.replace('INVLIN',str(r[INVOICE_LINE])) q = q.replace('TICK#',r[TICKET]) q = q.replace('ORDERA',r[U_NUMBER]) q = q.replace('INVYDS',str(r[INV_YARDS])) q = q.replace('FINYDS',str(r[FIN_YARDS])) q = q.replace('SHPDTE',str(r[SHIP_DATE])) q = q.replace('INVDTE',str(r[INV_DATE])) return q def AII_main(d): os.chdir('D:\\') initializeLogger('AS400_Invoice_Interface') logger.info('Connecting to JSISBPROD...') session = loadSession() extract = [] logger.info('Running extract query for: %s', d) logger.debug(build_extract_query(d)) for row in session.execute(build_extract_query(d)): extract.append(row) logger.debug('Disconnecting from JSISBPROD...') session.close() logger.info('Opening connection with AS400...') connection = pyodbc.connect( driver='{iSeries Access ODBC Driver}', system='SUNBURY', uid=os.environ['AS400_UID'], pwd=os.environ['AS400_PWD'], autocommit=True) c1 = connection.cursor() if 'STMDATA' in AS400_LIB: try: logger.info('Backing up rows from STMDATA.JSIINV --> WES.JSIINV_BAK') c1.execute('INSERT INTO WES.JSIINV_BAK SELECT * FROM STMDATA.JSIINV') except: logger.warn('***Failed to backup rows currently in STMDATA.JSIINV***') logger.info('Deleting old rows from %s.JSIINV', AS400_LIB) c1.execute('DELETE FROM ' + AS400_LIB + '.JSIINV') exceptions = [] logger.info('Inserting rows into %s.JSIINV', AS400_LIB) for row in extract: # Ticket will be null for credits if row[TICKET] and row[U_NUMBER] and row[TICKET].isdigit(): #print build_insert_statement(row) c1.execute(build_insert_statement(row)) else: exceptions.append(row) logger.debug('Disconnecting from AS400...') c1.close() if len(exceptions) > 0: #Open file for writing logger.debug('Dumping exceptions to csv file...') fname = "AII_ERRORS_" + d + ".csv" logger.debug('Creating %s. Using \'excel\' dialect for csv writer.', fname) f = open(fname, 'wb') writer = csv.writer(f, dialect='excel') writer.writerow(['Invoice #', 'Invoice Line', 'Ticket', 'AS400 Order', 'Invoiced Yards', 'Ship Date', 'Invoice Date']) for row in exceptions: writer.writerow(row) f.close() try: logger.debug('Sending e-mail...') send_alert_html(RECIPIENTS, (SUBJECT + " - " + d), attachments=[fname], message=MESSAGE.getvalue()) except: logger.error('Unable to send e-mail. Is the internet out?') logger.debug('Deleting %s', fname) os.remove(fname) if __name__ == '__main__': AII_main(sys.argv[1]) #print build_extract_query(sys.argv[1])