Initial commit. Loads XLSX file from accounting into sqlite database. Sends HTML email. Started adding variable parts to body pulled from database.

This commit is contained in:
Dan Dembinski
2021-03-19 02:22:53 -04:00
commit 12c4722fe9
5 changed files with 281 additions and 0 deletions

97
InvoiceDatabase.py Normal file
View File

@@ -0,0 +1,97 @@
from openpyxl import load_workbook
from sqlalchemy import create_engine, Column, Integer, String, REAL
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
engine = create_engine('sqlite:///cffInvoice.db')
engine.connect()
Base = declarative_base()
class Invoice(Base):
__tablename__ = 'Invoice'
rowid = Column(Integer, primary_key=True, autoincrement=True)
OrderID = Column(String)
InvoiceNumber = Column(String)
DateCreated = Column(String)
ProductionCharges = Column(REAL)
ShippingCharges = Column(REAL)
AdjustmentsBalance = Column(REAL)
DuePayment = Column(REAL)
ChargeCode = Column(String)
UserLogon = Column(String)
UserProfileFirstName = Column(String)
UserProfileLastName = Column(String)
InvoiceEmailAddress = Column(String)
ShippingCompany = Column(String)
ShippingFirstName = Column(String)
ShippingLastName = Column(String)
ShippingAddress1 = Column(String)
ShippingAddress2 = Column(String)
ShippingCity = Column(String)
ShippingState = Column(String)
ShippingPostalCode = Column(String)
class ItemDetail(Base):
__tablename__ = 'ItemDetail'
rowid = Column(Integer, primary_key=True, autoincrement=True)
OrderID = Column(String)
DocumentID = Column(String)
GLIJobNumber = Column(String)
ProductName = Column(String)
Quantity = Column(String)
ItemPrice = Column(REAL)
Session = sessionmaker(bind=engine)
session = Session()
def load_sheet(invoiceNumber):
# starting invoice sub-number
count = 2
#open the xlsx file from accounting and name the two sheets required
wb = load_workbook('1.xlsx', data_only=True)
shtInvoice = wb.get_sheet_by_name('Invoice')
shtItemDetail = wb.get_sheet_by_name('Item Detail')
#loop through each row in the Invoice sheet except for the first and last
#write each row to the database
for row in shtInvoice.iter_rows(min_row=2, max_row=shtInvoice.max_row-1):
session.add(Invoice(OrderID=row[0].value, InvoiceNumber=invoiceNumber + '-' + str(count), DateCreated=row[2].value,
ProductionCharges=row[4].value, ShippingCharges=row[5].value, AdjustmentsBalance=row[6].value,
DuePayment=row[7].value, ChargeCode=row[8].value, UserLogon=row[9].value, UserProfileFirstName=row[10].value,
UserProfileLastName=row[11].value, InvoiceEmailAddress=row[12].value, ShippingCompany=row[13].value,
ShippingFirstName=row[14].value, ShippingLastName=row[15].value, ShippingAddress1=row[16].value,
ShippingAddress2=row[17].value, ShippingCity=row[18].value, ShippingState=row[19].value,
ShippingPostalCode=row[20].value))
count = count + 1
session.commit()
for row in shtItemDetail.iter_rows(min_row=2, max_row=shtItemDetail.max_row-1):
session.add(ItemDetail(OrderID=row[0].value, DocumentID=row[1].value, GLIJobNumber=row[4].value, ProductName=row[5].value, Quantity=row[6].value, ItemPrice=row[7].value))
session.commit()
def just_work():
orders = []
for order in session.query(Invoice).all():
orders.append(order.OrderID)
return orders
def record_lookup(record):
result = []
for lookup in session.query(Invoice).filter(Invoice.OrderID == record):
result.append(lookup.OrderID)
result.append(lookup.DateCreated)
result.append(lookup.UserLogon)
result.append(lookup.UserProfileFirstName)
result.append(lookup.UserProfileLastName)
result.append(lookup.ChargeCode)
result.append(lookup.InvoiceNumber)
result.append(lookup.InvoiceEmailAddress)
return result

32
TableSetup Normal file
View File

@@ -0,0 +1,32 @@
create table Invoice(
OrderID TEXT NOT NULL,
InvoiceNumber TEXT NOT NULL,
DateCreated TEXT NOT NULL,
ProductionCharges REAL NOT NULL,
ShippingCharges REAL NOT NULL,
AdjustmentsBalance REAL NOT NULL,
DuePayment REAL NOT NULL,
ChargeCode TEXT,
UserLogon TEXT NOT NULL,
UserProfileFirstName TEXT NOT NULL,
UserProfileLastName TEXT NOT NULL,
InvoiceEmailAddress TEXT NOT NULL,
ShippingCompany TEXT,
ShippingFirstName TEXT NOT NULL,
ShippingLastName TEXT NOT NULL,
ShippingAddress1 TEXT NOT NULL,
ShippingAddress2 TEXT,
ShippingCity TEXT NOT NULL,
ShippingState TEXT NOT NULL,
ShippingPostalCode TEXT NOT NULL
);
create table ItemDetail(
OrderID TEXT NOT NULL,
DocumentID TEXT NOT NULL,
GLIJobNumber TEXT NOT NULL,
ProductName TEXT NOT NULL,
Quantity INT NOT NULL,
ItemPrice REAL NOT NULL
);

20
main.py Normal file
View File

@@ -0,0 +1,20 @@
import sendEmail
import InvoiceDatabase
running = True
while running is True:
print('1. load new excel file\n2. Send Test emails\n3. Send Invoices\n4. Quit')
option = int(input())
if option == 1:
print('Enter invoice number')
invoiceNumber = str(input())
InvoiceDatabase.load_sheet(invoiceNumber)
elif option == 2:
sendEmail.send_email(True,'ALL')
elif option == 3:
sendEmail.send_email()
elif option == 4:
running = False
else:
print('not an option')

7
requirements Normal file
View File

@@ -0,0 +1,7 @@
et-xmlfile==1.0.1
greenlet==1.0.0
importlib-metadata==3.7.3
openpyxl==3.0.7
SQLAlchemy==1.4.1
typing-extensions==3.7.4.3
zipp==3.4.1

125
sendEmail.py Normal file
View File

@@ -0,0 +1,125 @@
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from datetime import datetime
import InvoiceDatabase
def send_email(test, record):
port = 25
smtp_server = "gll-com.mail.protection.outlook.com"
orders = InvoiceDatabase.just_work()
for each in orders:
info = InvoiceDatabase.record_lookup(each)
print(info)
OrderNumber = info[0]
OrderDate = info[1]
UserLogon = info[2]
Name = info[3] + ' ' + info[4]
ChargeCode = info[5]
InvoiceNumber = info[6]
InvoiceEmailAddress = info[7]
InvoiceDate = datetime.today().strftime('%m/%d/%Y')
body = '''
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE>CFF Order Invoice</TITLE>
<META content="text/html; charset=utf-8" http-equiv=Content-Type>
<META name=GENERATOR content="MSHTML 11.00.9600.18525">
<META name=Author content="">
<META name=Keywords content="">
<META name=Description content="">
<STYLE type=text/css>
p,
span,
a,
table,
td,
input,
textarea,
select,
option {{
font-family: Verdana, Tahoma, Geneva, Arial, Helvetica, sans-serif;
font-weight: normal;
font-size: 13px;
margin: 0;
}}
</STYLE>
</HEAD>
<BODY>
<TABLE style="BORDER-COLLAPSE: collapse" width="600">
<TR>
<TD style="BORDER-BOTTOM: #000000 1px solid" width="300"><IMG src="http://cff.gli.us.com/store/custom/images/GLIHeader.png"></TD>
<TD style="BORDER-BOTTOM: #000000 1px solid" width="300" align="right"><P style="FONT-SIZE: 18px; FONT-WEIGHT: normal; MARGIN-TOP: 10px"><I>INVOICE</I></P></TD>
</TR>
<TR vAlign="top">
<TD style="VERTICAL-ALIGN: top" vAlign="top" width="300">
<SPAN contentEditable=false style="" PFVar="AddressBlock">Address Block</SPAN></TD>
<TD style="VERTICAL-ALIGN: top" vAlign="top" width="300">&nbsp;<BR><P><B>Make Checks Payable To:</B> <BR>Great Lakes Integrated <BR>4246 Hudson Dr.<BR>Stow, Ohio 44224<BR>&nbsp;</P></TD>
</TR>
<TR vAlign="top">
<TD style="VERTICAL-ALIGN: top" vAlign="top" width="300">
<P>
<B>Order Number:</B> {OrderNumber}&nbsp;
<BR><B>Order Date:</B> {OrderDate}&nbsp;
<BR><B>User Logon:</B> {UserLogon}&nbsp;
<BR><B>Name:</B> {Name}&nbsp;
<BR><B>Charge Code:</B> {ChargeCode}&nbsp;
</P>
</TD>
<TD style="VERTICAL-ALIGN: top" vAlign="top" width="300">
<P>
<B>Invoice Number:</B> {InvoiceNumber}&nbsp;
<BR><B>Invoice Date:</B> {InvoiceDate}&nbsp;
<BR><B>Customer Number:</B> 1925&nbsp;
<BR><B>Terms:</B>Due in 30 days&nbsp;
</P>
</TD>
</TR>
<TR>
<TD width="600" colSpan="2"><P style="MARGIN-TOP: 20px"><B>The order consists of the following items:</B> </P>
<SPAN contentEditable=false style="" PFVar="OrderDetail"></SPAN>
</TD>
</TR>
</TBODY>
</TABLE>
</BODY>
</HTML>
'''
HTMLpart = body.format(OrderNumber=OrderNumber, OrderDate=OrderDate, UserLogon=UserLogon, Name=Name,
ChargeCode=ChargeCode, InvoiceDate=InvoiceDate, InvoiceNumber=InvoiceNumber)
bodyHTML = MIMEText(HTMLpart, "html")
f = open("sample.html", 'w')
f.write(HTMLpart)
f.close()
msg = MIMEMultipart()
msg['Subject'] = 'INVOICE ' + InvoiceNumber
if test is True:
msg['To'] = 'ddembinski@gll.com'
else:
# msg['To'] = InvoiceEmailAddress
msg['To'] = 'ddembinski@gll.com'
msg['From'] = 'ddembinski@gll.com'
msg.add_header('Content-Type', 'text/html')
msg.attach(bodyHTML)
try:
with smtplib.SMTP(smtp_server, port, timeout=120) as server:
server.sendmail(msg['From'], msg['To'], msg.as_string())
except Exception as e:
print(e)