Advertisement
Guest User

Untitled

a guest
Jun 6th, 2017
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 13.23 KB | None | 0 0
  1. import datetime
  2. import pandas as pd
  3. import pandas.io.sql
  4. import pymssql
  5. import _mssql
  6. import tkinter as tk
  7.  
  8. now = datetime.datetime.now()
  9. year = str(now.year)
  10.  
  11. def main():
  12.     global master
  13.     master = tk.Tk()
  14.     background = 'azure2'
  15.     font = "ISOCPEUR 12 underline"
  16.  
  17.     #Labels for GUI
  18.     tk.Label(master, text="Quote Number", background=background, font = font).grid(row=0)
  19.     tk.Label(master, text="Purchased Material %", background=background, font = font).grid(row=10)
  20.     tk.Label(master, text="Fabricated Material %", background=background, font = font).grid(row=11)
  21.     tk.Label(master, text="Labor Cost %", background=background, font = font).grid(row=12)
  22.     tk.Label(master, text="Burden Cost %", background=background, font = font).grid(row=13)
  23.     tk.Label(master, text="Service Cost %", background=background, font = font).grid(row=14)
  24.  
  25.     #build GUI
  26.     menubar = tk.Menu(master)
  27.     menubar.add_command(label="Update", command=combinedUpdate, font="ISOCPEUR 10")
  28.     menubar.add_command(label="Recalculate", command=combinedRecalc, font="ISOCPEUR 10")
  29.     menubar.add_command(label="Reset", command=resetFromMenu, font="ISOCPEUR 10")
  30.     menubar.add_command(label="Help", command=helpDoc, font="ISOCPEUR 10")
  31.     menubar.add_command(label="Restart", command=restart, font="ISOCPEUR 10")
  32.     menubar.add_command(label="Quit", command=master.quit, font="ISOCPEUR 10")
  33.     master.bind('<Escape>', close)
  34.     master.bind('<F2>', resetFromMenu)
  35.     master.bind('<Control-r>', combinedRecalc)
  36.     master.bind('<Control-u>', combinedUpdate)         
  37.     master.bind('<Control-h>', helpDoc)
  38.     master.bind('<Control-R>', combinedRecalc)
  39.     master.bind('<Control-U>', combinedUpdate)         
  40.     master.bind('<Control-H>', helpDoc)
  41.     master.bind('<F5>', restart)
  42.     master.config(menu=menubar)
  43.     master.title("Update Quote Rates")
  44.     master.minsize(width=350, height=100)
  45.     master.configure(background=background)
  46.  
  47.     #Entry boxes
  48.     global e
  49.     e = tk.Entry(master)
  50.     e.grid(row=0, column=1, sticky="NSEW", padx=10, pady=10)
  51.     global e2
  52.     e2 = tk.Entry(master)
  53.     e2.grid(row=10, column=1, sticky="NSEW", padx=2, pady=2)
  54.     global e3
  55.     e3 = tk.Entry(master)
  56.     e3.grid(row=11, column=1, sticky="NSEW", padx=2, pady=2)
  57.     global e4
  58.     e4 = tk.Entry(master)
  59.     e4.grid(row=12, column=1, sticky="NSEW", padx=2, pady=2)
  60.     global e5
  61.     e5 = tk.Entry(master)
  62.     e5.grid(row=13, column=1, sticky="NSEW", padx=2, pady=2)
  63.     global e6
  64.     e6 = tk.Entry(master)
  65.     e6.grid(row=14, column=1, sticky="NSEW", padx=2, pady=2)
  66.     e.focus_set()
  67.  
  68. #connect to the database
  69. conn = pymssql.connect(
  70.     host=r"host",
  71.     user=r"user",
  72.     password="password",
  73.     database="database"
  74. )
  75.  
  76. cursor = conn.cursor()
  77.  
  78. #function to update rates
  79. def updateRates():
  80.     #make sure the quote number exists in the database
  81.     verifySQL = "SELECT ID FROM QUOTE WHERE ID IN (SELECT ID FROM QUOTE WHERE ID = '" + e.get() + "')"
  82.     v = pandas.io.sql.read_sql(verifySQL, conn)
  83.     D = pd.DataFrame(v)
  84.     if D.empty:
  85.         global top
  86.         top = tk.Toplevel(master)
  87.         top.title('Error')
  88.         msg = tk.Message(top, text="Please Check Your Quote Number", width=750, font="ISOCPEUR 10")
  89.         msg.grid(row=0, column=1)
  90.         return
  91.     #prevent 2 from being calculated as 20 by forcing all percentages to be two digits long
  92.     elif len(e2.get()) != 2 or len(e3.get()) != 2 or len(e4.get()) != 2 or len(e5.get()) != 2 or len(e6.get()) != 2:
  93.             top = tk.Toplevel(master)
  94.             top.title('Error')
  95.             msg = tk.Message(top, text="All Percentages Must Be 2 Digits Long", width=750, font="ISOCPEUR 10")
  96.             msg.grid(row=0, column=1)
  97.             return
  98.     try:
  99.         top = tk.Toplevel(master)
  100.         top.title('Updating')
  101.         msg = tk.Message(top, text="Rates Successfully Updated         ", width=750, font="ISOCPEUR 10")
  102.         msg.grid(row=0, column=1)
  103.         #read in all lines from quote and store them in a dataframe
  104.         SQL = "SELECT LINE_NO FROM CR_QUOTE_LIN_PRICE WHERE QUOTE_ID = '" + e.get() + "'"
  105.         q = pandas.io.sql.read_sql(SQL, conn)
  106.         lines = pd.DataFrame(q)
  107.         #loop through the lines and get all estimated costs
  108.         for l in lines.values:
  109.             try:
  110.                 costQuery = """
  111.                 SELECT WORKORDER_LOT_ID, EST_MATERIAL_COST AS MATERIAL, EST_LABOR_COST AS LABOR,
  112.                 EST_BURDEN_COST AS BURDEN, EST_SERVICE_COST AS SERVICE
  113.                 FROM REQUIREMENT WHERE WORKORDER_BASE_ID =""" + e.get() + """
  114.                 AND WORKORDER_LOT_ID = """ + str(l)[1:-1] + """GROUP BY WORKORDER_LOT_ID
  115.                 """
  116.             except:
  117.                 pass
  118.         #read in all lines from quote and store them in a dataframe
  119.         lineSQL = "SELECT LINE_NO FROM CR_QUOTE_LIN_PRICE WHERE QUOTE_ID = '" + e.get() + "'"
  120.         q = pandas.io.sql.read_sql(lineSQL, conn)
  121.         lines = pd.DataFrame(q)
  122.         #loop through the lines and update percentage markups based on user input
  123.         for l in lines:
  124.             try:
  125.                 num = str(l)
  126.                 updatePercent = """UPDATE CR_QUOTE_LIN_PRICE SET PUR_MATL_PERCENT = """ + e2.get() + """,
  127.                 FAB_MATL_PERCENT = """ + e3.get() + """, LABOR_PERCENT = """ + e4.get() + """,
  128.                 BURDEN_PERCENT = """ + e5.get() + """, SERVICE_PERCENT = """ + e6.get() + """WHERE QUOTE_ID = '""" + e.get() + """'
  129.                 AND LINE_NO = """ + num
  130.                 try:
  131.                     #commit data to database
  132.                     cursor.execute(updatePercent)
  133.                     conn.commit()
  134.                 except:
  135.                     pass
  136.             except:
  137.                 pass
  138.     except:
  139.         pass
  140.  
  141. def Recalc():
  142.     #make sure the quote number exists in the database
  143.     verifySQL = "SELECT ID FROM QUOTE WHERE ID IN (SELECT ID FROM QUOTE WHERE ID = '" + e.get() + "')"
  144.     v = pandas.io.sql.read_sql(verifySQL, conn)
  145.     D = pd.DataFrame(v)
  146.     if D.empty:
  147.         global top
  148.         top = tk.Toplevel(master)
  149.         top.title('Error')
  150.         msg = tk.Message(top, text="Please Check Your Quote Number", width=750, font="ISOCPEUR 10")
  151.         msg.grid(row=0, column=1)
  152.         return
  153.     #prevent 2 from being calculated as 20 by forcing all percentages to be two digits long
  154.     if len(e2.get()) != 2 or len(e3.get()) != 2 or len(e4.get()) != 2 or len(e5.get()) != 2 or len(e6.get()) != 2:
  155.         top = tk.Toplevel(master)
  156.         top.title('Error')
  157.         msg = tk.Message(top, text="All Percentages Must Be 2 Digits Long", width=750, font="ISOCPEUR 10")
  158.         msg.grid(row=0, column=1)
  159.         return
  160.     #get line number and markups for quote
  161.     try:
  162.         top = tk.Toplevel(master)
  163.         top.title('Recalculating')
  164.         msg = tk.Message(top, text="Successfully Recalculated         ", width=750, font="ISOCPEUR 10")
  165.         msg.grid(row=0, column=1)
  166.         lineSQL = "SELECT LINE_NO FROM CR_QUOTE_LIN_PRICE WHERE QUOTE_ID = '" + e.get() + "'"
  167.         matSQL = "SELECT PUR_MATL_PERCENT FROM CR_QUOTE_LIN_PRICE WHERE QUOTE_ID = '" + e.get() + "'"
  168.         fabSQL = "SELECT FAB_MATL_PERCENT FROM CR_QUOTE_LIN_PRICE WHERE QUOTE_ID = '" + e.get() + "'"
  169.         labSQL = "SELECT LABOR_PERCENT FROM CR_QUOTE_LIN_PRICE WHERE QUOTE_ID = '" + e.get() + "'"
  170.         burSQL = "SELECT BURDEN_PERCENT FROM CR_QUOTE_LIN_PRICE WHERE QUOTE_ID = '" + e.get() + "'"
  171.         serSQL = "SELECT SERVICE_PERCENT FROM CR_QUOTE_LIN_PRICE WHERE QUOTE_ID = '" + e.get() + "'"
  172.         #read the queries into a dataframe
  173.         matQ = pandas.io.sql.read_sql(matSQL, conn).head(1).values
  174.         fabQ = pandas.io.sql.read_sql(fabSQL, conn).head(1).values
  175.         labQ = pandas.io.sql.read_sql(labSQL, conn).head(1).values
  176.         burQ = pandas.io.sql.read_sql(burSQL, conn).head(1).values
  177.         serQ = pandas.io.sql.read_sql(serSQL, conn).head(1).values
  178.         #remove ugly formatting
  179.         matQ = str(matQ).strip('[.]')
  180.         fabQ = str(fabQ).strip('[.]')
  181.         labQ = str(labQ).strip('[.]')
  182.         burQ = str(burQ).strip('[.]')
  183.         serQ = str(serQ).strip('[.]')
  184.         #put line data into dataframe
  185.         q = pandas.io.sql.read_sql(lineSQL, conn)
  186.         lines = pd.DataFrame(q).values
  187.         #loop through lines and mark up all rates based on inputs
  188.         for l in lines:
  189.             try:
  190.                 num = str(l)[1:-1]
  191.                 matMarkUpQuery = "SELECT 1." + e2.get() + "*EST_MATERIAL_COST FROM WORK_ORDER WHERE BASE_ID = '" + e.get() + "' AND LOT_ID = '" + num + "'"
  192.                 EPMC = str(pandas.io.sql.read_sql(matMarkUpQuery, conn).values).strip('[.]')
  193.                 updateMaterial = float(EPMC)
  194.                 roundMaterial = round(updateMaterial)
  195.  
  196.                 #couldn't find a use for this since we only use purchased materials in our quotes
  197.  
  198.                 # fabMarkUpQuery = "SELECT SUM(EST_MATERIAL_COST) FROM WORK_ORDER WHERE BASE_ID LIKE '%" + e.get() + "%' AND LOT_ID = '" + num + "' GROUP BY LOT_ID"
  199.                 # EFMC = str(pandas.io.sql.read_sql(fabMarkUpQuery, conn).head(1).values).strip('[.]')
  200.                 # updateFabricated = float('1.' + e.get()) * float(EPMC)
  201.                 # roundFabricated = round(updateFabricated)
  202.  
  203.                 labMarkUpQuery = "SELECT 1." + e4.get() + "*EST_LABOR_COST FROM WORK_ORDER WHERE BASE_ID = '" + e.get() + "' AND LOT_ID = '" + num + "'"
  204.                 ELC = str(pandas.io.sql.read_sql(labMarkUpQuery, conn).head(1).values).strip('[.]')
  205.                 updateLabor = float(ELC)
  206.                 roundLabor = round(updateLabor)
  207.  
  208.                 burMarkUpQuery = "SELECT 1." + e5.get() + "*EST_BURDEN_COST FROM WORK_ORDER WHERE BASE_ID = '" + e.get() + "' AND LOT_ID = '" + num + "'"
  209.                 EBC = str(pandas.io.sql.read_sql(burMarkUpQuery, conn).head(1).values).strip('[.]')
  210.                 updateBurden = float(EBC)
  211.                 roundBurden = round(updateBurden)
  212.  
  213.                 serMarkUpQuery = "SELECT 1." + e6.get() + "*EST_SERVICE_COST FROM WORK_ORDER WHERE BASE_ID = '" + e.get() + "' AND LOT_ID = '" + num + "'"
  214.                 ESC = str(pandas.io.sql.read_sql(serMarkUpQuery, conn).head(1).values).strip('[.]')
  215.                 updateService = float(ESC)
  216.                 roundService = round(updateService)
  217.  
  218.                 #calculate markups by adding all costs together, then rounding for neatness
  219.                 finalCalc = updateMaterial + updateLabor + updateBurden + updateService
  220.                 roundFinalCalc = round(finalCalc)
  221.                 strFinalCalc = str(finalCalc)
  222.                 strRoundFinalCalc = str(roundFinalCalc)
  223.  
  224.                 #update in quote by replacing costs with those calculated above
  225.                 updateCosts = """UPDATE CR_QUOTE_LIN_PRICE SET CALC_UNIT_PRICE = """ + strFinalCalc + """, UNIT_PRICE = """ + strRoundFinalCalc + """WHERE QUOTE_ID = '""" + e.get() + """'
  226.                                     AND LINE_NO = """ + num
  227.                 cursor.execute(updateCosts)
  228.                 conn.commit()
  229.             except:
  230.                 pass
  231.     except:
  232.         pass
  233.  
  234. def helpDoc(event=None):
  235.     global top
  236.     top = tk.Toplevel(master)
  237.     top.title('Help')
  238.     msg = tk.Message(
  239.                     top,
  240.                     text="This program updates the rates and recalculates all lines for a quote in Visual.\
  241.                     \n\nTo use:\n\nEnter the exact quote number you wish to update.\n\nEnter percentages as two digit numbers in each box, in the same order you would in the quote in Visual.\
  242.                     \n\nYou should always update before recalculating.\
  243.                     \nAfter you enter the correct quote number and the rates you wish to use,\nclick the update button on the menu bar.\
  244.                     \nIf the quote number or any rates are incorrect, you will get an error message.\
  245.                     \n\nAfter you have successfully updated the rates, do not clear the screen.\nClick the recalculate button.\
  246.                     \nThis program will recalculate based on the rates you have entered here, not based on the rates in Visual,\
  247.                     so it is important that the rates used to update are the same as the rates used to recalculate.\
  248.                     \n\nOnce you have updated and recalculated, you are all done. There is no need to save anything.\
  249.                     \nGo into Visual and refresh the quote.\nThe rates and prices will be updated and rounded to the nearest whole dollar.\
  250.                     \n\nShortcut keys:\n\nCtrl+R: Recalculate\nCtrl+U: Update\nF2: Reset\nF5: Restart\nEsc: Close Message\nCtrl+H: Help\nAlt+Q: Quit\
  251.                     ,
  252.                     width=750
  253.                             )
  254.     msg.pack()
  255.  
  256. #status popups
  257. def updateStatus():
  258.     global top
  259.     top = tk.Toplevel(master)
  260.     top.title('Running')
  261.     msg = tk.Message(top, text="Updating...                                     ", width=750, font="ISOCPEUR 10")
  262.     msg.grid(row=0, column=1)
  263.     master.after(4000, top.destroy)
  264.  
  265. def recalcStatus():
  266.    global top
  267.    top = tk.Toplevel(master)
  268.    top.title('Running')
  269.    msg = tk.Message(top, text="Recalculating...                                ", width=750, font="ISOCPEUR 10")
  270.    msg.grid(row=0, column=1)
  271.    master.after(4000, top.destroy)
  272.  
  273. #functions to combine multiple popups
  274. def combinedUpdate(event=None):
  275.     updateStatus()
  276.     master.after(3000, updateRates)
  277.  
  278. def combinedRecalc(event=None):
  279.     recalcStatus()
  280.     master.after(3000, Recalc)
  281.  
  282. #closes popups
  283. def close(event=None):
  284.    top.destroy()
  285.  
  286. #resets screen
  287. def resetFromMenu(event=None):
  288.   e.delete(0, 'end')
  289.   e2.delete(0, 'end')
  290.   e3.delete(0, 'end')
  291.   e4.delete(0, 'end')
  292.   e5.delete(0, 'end')
  293.   e6.delete(0, 'end')
  294.   e.focus_set()
  295.  
  296. def logIn(event=None):
  297.     usernames = []
  298.     passwords = []
  299.     if en2.get() in usernames and en3.get() in passwords:
  300.         main()
  301.         root.destroy()
  302.     else:
  303.         global top
  304.         top = tk.Toplevel(root)
  305.         top.title('Error')
  306.         msg = tk.Message(top, text="Incorrect Username or Password", width=750, font="ISOCPEUR 10")
  307.         msg.grid(row=0, column=1)
  308.         return
  309.  
  310. def restart(event=None):
  311.     master.destroy()
  312.     security()
  313.  
  314.  
  315. def security():
  316.     global root
  317.     root = tk.Tk()
  318.     background = 'azure2'
  319.     font = "ISOCPEUR 10"
  320.     global en2
  321.     en2 = tk.Entry(root)
  322.     en2.grid(row=1, column=1, sticky="NSEW", padx=2, pady=2)
  323.     en2.focus_set()
  324.     global en3
  325.     en3 = tk.Entry(root)
  326.     en3.grid(row=2, column=1, sticky="NSEW", padx=2, pady=2)
  327.     en3.config(show="*")
  328.     tk.Label(root, text="User", background=background, font = font).grid(row=1)
  329.     tk.Label(root, text="Password", background=background, font = font).grid(row=2)
  330.     tk.Button(root, text='Log in', command=logIn).grid(row=5, column=1)
  331.     root.bind('<Return>', logIn)
  332.     root.bind('<Escape>', close)
  333.     root.title("Log In")
  334.     root.configure(background=background)
  335.     root.mainloop()
  336.  
  337. if __name__ == "__main__":
  338.     security()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement