def set_report_location(): FILE_OPTS = dict( title = u'PDF save location.', initialdir = os.path.expanduser('~') + '/Desktop/', mustexist = True ) if settings.load().get(u'pdfpath'): FILE_OPTS['initialdir'] = settings.load()[u'pdfpath'] outdir = os.path.normpath(tkFileDialog.askdirectory(**FILE_OPTS)) settings.update(pdfpath=outdir)
def get_savename(_, initialfilename): FILE_OPTS = ___ = dict(title = u'PDF name and location.') ___['parent'] = _.po_frame ___['defaultextension'] = '.pdf' ___['initialdir'] = os.path.expanduser('~') + '/Desktop/' ___['initialfile'] = initialfilename if settings.load().get(u'pdfpath'): ___['initialdir'] = settings.load()[u'pdfpath'] outfile = os.path.normpath(tkFileDialog.asksaveasfilename(**FILE_OPTS)) return outfile
def execute(self, name): if name == 'new': return ['level'] elif name == 'join': return ['join'] elif name == 'save': return ['save'] elif name == 'quit': return ['quit'] elif name == 'reload_settings': settings.load() self.settings_reloaded = True self.timer.start() return [None]
def set_ip(self): '''Change server ip address. Interaction is done through the console. Stores the server ip address in the settings.json file. ''' json = settings.load(u'database') json.setdefault('ip', u'None') print u"Current ip address:{ip}".format(**json) retval = raw_input(u'Enter new server ip address:') json.update(ip=retval) settings.update(database=json) return True
def open_session(self): """Open a new database session. Uses default values for any not stored in the local settings.json file. """ json = settings.load(subdir=u'database') json.setdefault('name', u'admin') json.setdefault('pw', u'admin') json.setdefault('api', u'mysql+pymysql') json.setdefault('ip', u'000.0.0.000') json.setdefault('opt', u'?charset=utf8') json.setdefault('port', u':3306') json.setdefault('db', u'taimau') self.dbpath = u"{ip}{port}/{db}".format(**json) db_path = u"{api}://{name}:{pw}@{ip}{port}/{db}{opt}" db_path = db_path.format(**json) engine = get_database(db_path, echo=False ) self.session = sessionmaker(bind=engine)()
def create_qc_pdf(**kwargs): try: kwargs['company'] = kwargs.get('company', u'台茂化工儀器原料行') kwargs['product'] = kwargs.get('product', u'product name?') kwargs['ASE_pn'] = kwargs.get('ASE_pn', u'ASE PN?') if not kwargs.get('lot_no'): kwargs['make_date'] = date.today() kwargs['test_date'] = date.today() kwargs['lot_no'] = u'lot number?' else: year = 2000 + int(kwargs['lot_no'][1:3]) month = int(kwargs['lot_no'][3:5]) day = int(kwargs['lot_no'][5:7]) kwargs['make_date'] = date(year, month, day) kwargs['test_date'] = date(year, month, day) kwargs['exp_period'] = kwargs.get('exp_period', u'一年') kwargs['amount'] = kwargs.get('amount', u'amount?') kwargs['tester'] = kwargs.get('tester', u'tester?') kwargs['test_params'] = kwargs.get('test_params', []) except Exception as e: print e return # Set placement and style of values tm_branch = dict(x=30, y=25, w=178-30, h=10, align='C') product_name = dict(x=31, y=50, w=104-31, h=15, align='L') product_ASE_pn = dict(x=105, y=50, w=104-31, h=15, align='L') make_date = dict(x=31, y=65, w=104-31, h=8, align='L') test_date = dict(x=31, y=73, w=104-31, h=8, align='L') exp_period = dict(x=31, y=81, w=104-31, h=9, align='L') lot_no = dict(x=105, y=65, w=104-31, h=8, align='L') amount = dict(x=105, y=73, w=104-31, h=8, align='L') tester = dict(x=105, y=81, w=104-31, h=9, align='L') # Create PDF FPDF = myPDF('P','mm','A4') FPDF.set_compression(False) FPDF.set_creator('TM_2014') FPDF.set_title(u'Quality inspection report for lot# {}'.format(kwargs['lot_no'])) FPDF.set_author(u'Taimau Chemicals') FPDF.set_subject(kwargs['lot_no']) # FPDF.set_subject(u'{} {}'.format(kwargs['product'], kwargs['lot_no']), isUTF8=True) FPDF.alias_nb_pages() FPDF.add_page() # Adding a page also creates a page break from last page FPDF.add_font(family=u'SimHei', style='', fname=font, uni=True) # Only .ttf and not .ttc FPDF.set_font(family=u'SimHei', style='', size=16) FPDF.xycell(txt=kwargs['company'], **tm_branch) FPDF.set_font(family=u'SimHei', style='B', size=13) FPDF.xycell(txt=u'產品: {}'.format(kwargs['product']), **product_name) FPDF.xycell(txt=u'料號: {}'.format(kwargs['ASE_pn']), **product_ASE_pn) FPDF.xycell(txt=u'製造日期: {}'.format(kwargs['make_date']), **make_date) FPDF.xycell(txt=u'檢驗日期: {}'.format(kwargs['test_date']), **test_date) FPDF.xycell(txt=u'保存期間: {}'.format(kwargs['exp_period']), **exp_period) FPDF.xycell(txt=u'批號: {}'.format(kwargs['lot_no']), **lot_no) FPDF.xycell(txt=u'生產數量: {}'.format(kwargs['amount']), **amount) FPDF.xycell(txt=u'取樣人員: {}'.format(kwargs['tester']), **tester) FPDF.set_left_margin(30) FPDF.set_xy(x=30, y=105) for (a, b, c) in kwargs['test_params']: if a+b+c == u'': break FPDF.cell(49, 10, txt=a, align='C') FPDF.cell(49, 10, txt=b, align='C') FPDF.cell(49, 10, txt=c, align='C') FPDF.ln() FPDF.cell(49) FPDF.cell(49, 10, txt=u'以下空白', align='C') initialfilename = u'QC_{}_{}'.format(kwargs['product'], kwargs['lot_no']) FILE_OPTS = dict( title = u'PDF name and location.', defaultextension = '.pdf', initialdir = os.path.expanduser('~') + '/Desktop/', initialfile = initialfilename, ) if settings.load().get(u'pdfpath'): FILE_OPTS['initialdir'] = settings.load()[u'pdfpath'] outfile = os.path.normpath(tkFileDialog.asksaveasfilename(**FILE_OPTS)) if os.path.exists(outfile): os.remove(outfile) if outfile and not os.path.exists(outfile): FPDF.output(name=outfile) try: subprocess.call(['start', outfile], shell=True) return except: pass try: print u'Trying alternate subprocess command.' subprocess.call(['start', '/D'] + list(os.path.split(outfile)), shell=True) return except UnicodeEncodeError: pass try: os.startfile(outfile) return except: pass print u'Failed to autoload PDF after creation.' return else: head = u'Cancelled' body = u'Canceled PDF creation.' tkMessageBox.showinfo(head, body)
def create(_): """Creates the main purchase and sale window in the supplied frame.""" _.curr.cogroup = None # Store the current SQL CoGroup object _.curr.cogroupSV = Tix.StringVar() # Store the current CoGroup id ('name') _.curr.branchSV = Tix.StringVar() # Store the current Branch id ('name') _.edit_ID = None _.listbox = type(_)() _.poF = type(_)() # _state.settings.font = "NSimSun"#"PMingLiU" #### Set up left pane containing company names #### ################################################### left_pane = Tix.Frame(_.parent, width=260) left_pane.pack_propagate(0) left_pane.pack(side='left', fill='y', padx=2, pady=3) expandbox = Tix.Frame(left_pane) expandbox.pack(side='top', fill='x') #### Set up right pane containing company info and POs #### ########################################################### top_pane = Tix.Frame(_.po_frame) top_pane.pack(side='top', fill='x', padx=4, pady=5) right_top = Tix.Frame(top_pane) right_top.pack(side='top', fill='x') modebox = Tix.Frame(right_top) modebox.pack(side='left', fill='y') # Add branch selection buttons across top branchbox = Tix.Frame(right_top) branchbox.pack(side='left', fill='x') # Status bar at the bottom _.status = Tix.StringVar() Tix.Label(_.po_frame, textvariable=_.status)\ .pack(side='bottom', fill='x', anchor='s') # Set up mode switching buttons: Purchases, Sales def sc_switch(mode): _.sc_mode = mode settings.update(sc_mode=mode) # Ensure button is selected when invoked. if mode == 'c': cmodeRB.select() else: smodeRB.select() tds = lambda anchor, bg: Tix.DisplayStyle( anchor=anchor, bg=bg, itemtype='text', refwindow=_.co_tree.hlist, font=_.font ) for each in _.co_tree.hlist.info_children(''): hcolor = u'NavajoWhite4' if mode == 'c' and len(_.dbm.get_cogroup(each).sales): hcolor = u'gold' if mode == 's' and len(_.dbm.get_cogroup(each).purchases): hcolor = u'gold' _.co_tree.hlist.entryconfigure(each, style=tds('w', hcolor)) try: load_company() except NameError: pass # Pass on initialization. _.sc_switch = sc_switch # Mode here refers to supplier or customer records. options = dict(variable="modebuttons", indicatoron=False, bg="NavajoWhite4", font=(_.font, "15", "bold"), selectcolor="gold", activebackground="gold") smodeRB = Tix.Radiobutton(modebox, value="s", textvariable=_.loc("Supplier"), command=lambda:sc_switch("s"), **options) smodeRB.pack(side='top', expand=True, fill='both') cmodeRB = Tix.Radiobutton(modebox, value="c", textvariable=_.loc("Customer"), command=lambda:sc_switch("c"), **options) cmodeRB.pack(side='top', expand=True, fill='both') # Set up company switching buttons def select_cogroup(cog_name): _.curr.cogroupSV.set(cog_name) cogroup = _.dbm.get_cogroup(cog_name) _.curr.cogroup = cogroup settings.update(cogroup=cogroup.name) if _.debug: print(cogroup) load_company() tr = Tix.Button(left_pane, textvariable=_.loc(u"+ Add Company/Branch"), # command=lambda *args:add_cogroup.main(_), command=lambda *args:fr_branch.add_new(_), font=(_.font, "12", "bold"), bg="lawn green", activebackground="lime green") tr.pack(side='bottom', fill='x') if _.debug: print len(_.dbm.cogroups()), "company groups in database loaded." def refresh_colist(): try: _.colist.destroy() except KeyError: pass colist_frame = _.colist = Tix.Frame(left_pane) colist_frame.pack(side='left', fill='both', expand=1) tree = Tix.Tree(colist_frame, options='hlist.width 20') tree.pack(expand=1, fill='both', side='top') tree['opencmd'] = lambda dir=None, w=tree: opendir(w, dir) tree.hlist['separator'] = '~' # Default is gray tree.hlist.column_width(0, chars=35) '''Show_branch fires after the opendir method runs''' def show_branch(e): path = tree.hlist.info_selection()[0].decode("utf8") if u'~' in path: '''Doubleclick on Branch name''' branch_edit(path.split(u'~')[1]) else: '''Doubleclick on Company Group''' select_cogroup(path) tree.hlist.selection_set(path) tree.hlist.bind('<Double-ButtonRelease-1>', show_branch) def show_br_info(e): path = tree.hlist.info_selection()[0].decode("utf8") if u'~' in path and _.curr.cogroup.name in path: _.curr.branchSV.set(path.split('~')[1]) tree.hlist.bind('<ButtonRelease-1>', show_br_info) tds = lambda anchor, bg: Tix.DisplayStyle( anchor=anchor, bg=bg, itemtype='text', refwindow=tree.hlist, font=_.font ) tree.hlist.delete_all() for cog in _.dbm.cogroups(): tree.hlist.add(cog.name, text=cog.name + _.loc(u" (group)", 1), itemtype=Tix.TEXT, style=tds('w', u'gold') ) tree.setmode(cog.name, 'open') _.co_tree = tree _.refresh_colist = refresh_colist _.refresh_colist() '''Expands all companies in company selection list.''' def cogroup_expand(tree): opendir(tree, all=True) '''Closes all sublists in company selection list.''' def cogroup_contract(tree): for each in tree.hlist.info_children(''): tree.close(each) for subeach in tree.hlist.info_children(each): tree.hlist.hide_entry(subeach) tree.setmode(each, 'open') '''Expands currently selected company or all companies.''' def opendir(tree, path=None, all=False): if _.debug: print 'HList path:', path path = tree.hlist.info_selection() if all == True: path = tree.hlist.info_children('') for each in path: entries = tree.hlist.info_children(each) if entries: # Show previously loaded entries for entry in entries: tree.hlist.show_entry(entry) else: for br in _.dbm.get_cogroup(each).branches: hid = each.decode("utf8")+u'~'+br.name tree.hlist.add(hid, text=br.fullname if br.fullname else br.name, itemtype=Tix.TEXT) #============================================================================== # Add expand all and contract all for company list. #============================================================================== options = dict(bg="skyblue", font=(_.font, "15", "bold"), activebackground="gold") expand = Tix.Button(expandbox, textvariable=_.loc("Expand All"), command=lambda:cogroup_expand(_.co_tree), **options) expand.pack(side='left', fill='x', expand=1) contract = Tix.Button(expandbox, textvariable=_.loc("Close All"), command=lambda:cogroup_contract(_.co_tree), **options) contract.pack(side='left', fill='x', expand=1) #### PAGE BUTTONS: PO, MANIFEST, INVOICE, ALL PO #### ##################################################### page_buttons = Tix.Frame(top_pane, bg=u'SteelBlue3', pady=4) page_buttons.pack(side='top', fill='x', expand=True) def Radiobutton(value, textvariable): '''Pre-define a new radiobutton for reuse.''' return Tix.Radiobutton( master=page_buttons, variable="pagebuttons", indicatoron=False, font=(_.font, "16", "bold"), bg="medium purple", selectcolor="plum", padx=40, activebackground="plum", textvariable=textvariable, command=lambda x=value:change_view(x), value=value, ) tr = Radiobutton('prod pick', _.loc(u'Order Products')) tr.grid(row=0, column=0) text = u"Create new long-term PO's or one-time shipment (with one-time PO)." tr.bind('<Enter>', lambda a, t=text: _.status.set(_.loc(t,1))) tr = Radiobutton('shipped', _.loc(u'Manifests & Invoices')) tr.grid(row=0, column=2) text = u"Manage manifests and invoices." tr.bind('<Enter>', lambda a, t=text: _.status.set(_.loc(t,1))) tr = Radiobutton('po all', _.loc(u'All POs')) tr.grid(row=0, column=3) text = u"Manage current and archived POs." tr.bind('<Enter>', lambda a, t=text: _.status.set(_.loc(t,1))) tr = Radiobutton('po new', _.loc(u'Manage POs')) tr.grid(row=0, column=1) _.btn_manage_po = tr text = u"Ship items from open POs." tr.bind('<Enter>', lambda a, t=text: _.status.set(_.loc(t,1))) tr.select() _.view_mode = 'po new' page_buttons.columnconfigure(0,weight=1) page_buttons.columnconfigure(1,weight=1) page_buttons.columnconfigure(2,weight=1) page_buttons.columnconfigure(3,weight=1) po.all_frame(_) po.mi_frame(_) po.prodselectf(_) def change_view(mode): if _.view_mode == mode: return if _.debug: print 'VIEW MODE:', mode _.view_mode = mode if mode == 'prod pick': _.prodselectf.pack(side='left', fill='both', expand=1) _.prodselectf.refresh() else: _.prodselectf.pack_forget() if mode == 'po new': _.po_center.pack(side='left', fill='both', expand=1) else: _.po_center.pack_forget() if mode == 'po all': _.all_frame.pack(side='left', fill='both', expand=1) _.all_frame.refresh() else: _.all_frame.pack_forget() if mode == 'shipped': _.mi_frame.pack(side='left', fill='both', expand=1) _.mi_frame.refresh() else: _.mi_frame.pack_forget() # Add center pane for PO listing center_pane = _.po_center = Tix.Frame(_.po_frame) center_pane.pack(side='top', fill='both', expand=1) def branch_edit(name): fr_branch.edit(_, name) vcmd_int = center_pane.register(lambda x: x.isdigit()) def load_company(): try: cogroup = _.curr.cogroup except KeyError: return # Group not selected yet if cogroup == None or cogroup == u'': return try: branchbox.children.popitem()[1].destroy() except KeyError: pass branchbox_inner = Tix.Frame(branchbox) branchbox_inner.pack(side='left', fill='x') options = dict(variable=_.curr.branchSV, indicatoron=False, font=(_.font, "14", "bold"), bg="NavajoWhite4", selectcolor="gold", activebackground="gold") Tix.Label(branchbox_inner, textvariable=_.loc(u"Branch")).pack(side="left") branch_info = Tix.StringVar() def set_branch_info(): branch = _.dbm.get_branch(_.curr.branchSV.get()) text = u'{} {} : {}'.format(U_No, branch.tax_id, branch.fullname) text += u'\n{} {}'.format(U_PHONE, branch.phone) if branch.fax: text += u' {} {}'.format(U_FAX, branch.fax) text += u'\n{} {}'.format(U_ENVELOPE, branch.email) text += u'\n{} {}'.format(U_INFO, branch.note) branch_info.set(text) Tix.Label(branchbox_inner, textvariable=branch_info, anchor='w', justify='left', font=(_.font, 14, 'bold')).pack(side='right') _.curr.branchSV.trace('w', lambda a,b,c,: set_branch_info()) for i, branch in enumerate(cogroup.branches): tr = Tix.Radiobutton(branchbox_inner, text=branch.name, value=branch.name, **options) tr.pack(side="top", fill='both', expand=1) if i==0: tr.invoke() tr.bind('<Double-Button-1>', lambda e, bn=branch.name: branch_edit(bn)) #TODO: Load entry fields with company info for viewing/editing #TODO: Buttons for switching supplier/customer booleans #### Display open purchase orders that can ship #### #################################################### try: center_pane.children.popitem()[1].destroy() except KeyError: pass pobox = Tix.Frame(center_pane) pobox.pack(side=Tix.TOP, fill=Tix.X) activeOrders = [] _poIDs = [] _qtyVars = [] _unitsVars = [] _discountVars = [] _multiplier = [] # Convert SKU to units _poBs = [] # PO button # info.order.entryWs[row].icursor(Tk.END) # info.order.entryWs[row].selection_range(0, Tk.END) def fill_qty(i, amount): _qtyVars[i].set(amount) order_list = cogroup.openpurchases if _.sc_mode == "s" else cogroup.opensales TB = lambda _text, **kwargs: Tix.Button(pobox, text=_text, anchor='w', bg="moccasin", font=(_.font, 13, 'bold'), activebackground="moccasin", **kwargs) # Retrieve user designated PO ordering if it exists. minlen = 100 rows = settings.load().get('po_order', {}).get(cogroup.name, range(minlen)) # Increase 'rows' length in case more PO's are added. if len(rows) < minlen: rows = rows + range(max(rows)+1, max(rows)+minlen-len(rows)) # Place PO (purchase orders) in the designated 'rows' ordering. for row, order in zip(rows, order_list): if order.is_open: activeOrders.append(order) _poIDs.append(order.id) _prod = order.product if _.debug: print 'PRODUCT TYPE:', type(_prod) assert isinstance(_prod, _.dbm.Product), u"Product not attached to order." # PO start date _text=u'{d.month}月{d.day}日'.format(d=order.orderdate) lw = Tix.Label(pobox, text=_text, font=(_.font, 11, 'bold')) lw.grid(row=row*2, column=0) _id = order.orderID if order.orderID else None if _id: _text = u'PO {:<10}:'.format(_id) else: _text = u'' _text += u"{}".format(_prod.label()) tb = TB(_text) tb['command'] = lambda o=order: po.edit(_,o,load_company) tb.grid(row=row*2, column=1, sticky='nsew') _poBs.append(tb) # Price per sku/unit _Ptext = u' ${}/{} '.format( int(order.price) if order.price.is_integer() else order.price, _prod.UM if _prod.unitpriced else _prod.SKU ) # lw = Tix.Label(pobox, text=_text) # lw.grid(row=row*2, column=8) _text=u'{}:{}'.format(_prod.specs, _Ptext) lw = Tix.Label(pobox, text=_text, padx=10, font=("PMingLiU", 13, 'bold')) lw.grid(row=row*2, column=2, sticky='w') if order.ordernote: lw = Tix.Label(pobox, textvariable=_.loc(u'NOTE:'), bg='coral', font=(_.font, 9)) lw.grid(row=row*2+1, column=0, sticky='ew') lw = Tix.Label(pobox, text=order.ordernote, anchor='w', bg='lavender', font=(_.font, 9)) lw.grid(row=row*2+1, column=1, columnspan=10, sticky='ew') # PO remaining QTY amt = order.qty_remaining() if amt >= 1e9: amt = U_INFINITE # Infinity symbol for unlimited POs. _textvar = _.loc(u"(Avail:") lw = Tix.Label(pobox, textvariable=_textvar, anchor='w') lw.grid(row=row*2, column=3, sticky='ew') _sku = _prod.SKU if _prod.SKU != u"槽車" else "kg" _textvar2 = Tix.StringVar() _text = u'{} {})'.format(amt, _sku) _textvar2.set(_text) _btext = u'{} {})'.format(amt * _prod.units if isinstance(amt, int) else amt, _prod.UM) lw.bind('<Button-1>', lambda e, sv=_textvar2, a=_text, b=_btext: \ sv.set(b if sv.get() == a else a)) lw2 = Tix.Label(pobox, textvariable=_textvar2, anchor='e') lw2.grid(row=row*2, column=4, sticky='ew') lw2.bind('<Double-Button-1>', lambda e, a=amt, i=len(_qtyVars): fill_qty(i,a)) # If PO remainder is zero. Make red. if order.all_shipped(): lw.config(bg=u'tomato') lw2.config(bg=u'tomato') # Multiple entry option button tb = Tix.Button(pobox, text=u'{t} {t}'.format(t=U_TRUCK), font=(_.font, 11), bg="lawn green", activebackground="lime green") tb['command'] = lambda o=order: po.add_many(_,o,load_company) tb.grid(row=row*2, column=5, sticky='nsew') # QTY entry field def highlight_entry(row, widget, capamt=100): if _.debug: print "row=",row, " widget=",widget, " capamt=",capamt # Check if entry is a number and doesn't exceed PO max. if widget.get(): if widget.get().isdigit() and int(widget.get()) <= capamt: widget.config(bg=u'PaleTurquoise1') else: widget.config(bg=u'IndianRed1') else: widget.config(bg=u'moccasin') # Fill in total units reference and color the PO button if _qtyVars[row].get().isdigit(): _int = int(_qtyVars[row].get())*_multiplier[row] _poBs[row].config(bg=u'PaleTurquoise1') if _int.is_integer(): _int = int(_int) _unitsVars[row].set(u"{}".format(_int)) else: _poBs[row].config(bg=u'moccasin') _unitsVars[row].set(u"{}".format(0)) _qtyVars.append(Tix.StringVar()) ew = Tix.Entry(pobox, textvariable=_qtyVars[-1], width=7, justify="center", bg=u"moccasin", validate='key', validatecommand=(vcmd_int, '%S')) ew.grid(row=row*2, column=6) _qtyVars[-1].trace('w', lambda a,b,c,ew=ew,capamt=amt,row=len(_poIDs)-1: highlight_entry(row,ew,capamt) ) # SKU _text = u'{}:'.format(_prod.SKU) lw = Tix.Label(pobox, text=_text, anchor='w') lw.grid(row=row*2, column=7, sticky='w') # Total units StringVar _unitsVars.append(Tix.StringVar()) _multiplier.append(_prod.units) lw = Tix.Label(pobox, textvariable=_unitsVars[-1], anchor='e', bg=u'LightGoldenrod1') lw.grid(row=row*2, column=8, sticky='e') _unitsVars[-1].set("0") _text = u' {}'.format( _prod.UM #if _prod.unitpriced else _prod.SKU ) lw = Tix.Label(pobox, text=_text, anchor='w', bg=u'LightGoldenrod1') lw.grid(row=row*2, column=9, sticky='w') # Discount percentage # _discountVars.append(Tix.StringVar()) # ew = Tix.Entry(pobox, textvariable=_discountVars[-1], width=7, # justify="center", bg=u"moccasin") # ew.grid(row=row*2, column=9) # _discountVars[-1].set(order.discount) # _discountVars[-1].trace('w', lambda a,b,c,ew=ew,row=len(_poIDs)-1: highlight_entry(row,ew,100) ) # lw = Tix.Label(pobox, textvariable=_.loc(u"% discount"), anchor='w') # lw.grid(row=row*2, column=10, sticky='w') # Button for adding another product order. #TODO: Add command # tb = Tix.Button(pobox, textvariable=_.loc("+ PO"), # bg="lawn green", # command=lambda:po.new(_, load_company), # activebackground="lime green") # tb.grid(row=1000, column=1, sticky='ew') # Button for submitting new manifest. Goto date selection, etc. #TODO: Add command numbSVar = Tix.StringVar() if _poIDs: tl = Tix.Label(pobox, textvariable=_.loc(u'Manifest #:')) tl.grid(row=1000, column=2, columnspan=2, sticky='e') te = Tix.Entry(pobox, textvariable=numbSVar, width=9, justify="center", bg=u"moccasin") te.grid(row=1000, column=4, columnspan=2, sticky='ew') tb = Tix.Button(pobox, textvariable=_.loc(U_TRUCK+u" Create Manifest"), bg="lawn green", command=lambda:make_manifest(), activebackground="lime green") tb.grid(row=1000, column=6, columnspan=5, sticky='ew') def make_manifest(): manifest_list = [(a, b, c) for a,b,c in zip(activeOrders, _qtyVars, _unitsVars) if b.get()] if _.debug: print manifest_list if len(manifest_list) > 5: tkMessageBox.showwarning(_.loc(u"Maximum exceeded",True), _.loc(u"Only a maximum of five items allowed.",True)) return if len(manifest_list) < 1: return po.manifest(_, orders=[a for a,b,c in manifest_list], qtyVars=[b for a,b,c in manifest_list], unitVars=[c for a,b,c in manifest_list], refresh=load_company, numbSVar = numbSVar) # Load PO HList 'All POs' for each_method in _.refresh: each_method() # Make load_company available anywhere _.load_company = load_company # Load cogroup and mode from previous session on init. js = settings.load() if js.get('sc_mode'): try: _.curr.cogroup = _.dbm.get_cogroup(js.get('cogroup')) _.curr.cogroupSV.set(_.curr.cogroup.name) for key, val in _.colist.children.iteritems(): try: if _.curr.cogroup.name in val['value']: if _.debug: print _.curr.cogroup, val['value'] print _.colist.children[key] _.colist.children[key].select() except: pass except TypeError: pass except AttributeError: pass if js['sc_mode'] == 'c': cmodeRB.invoke() else: smodeRB.invoke() else: # Set "Supplier" button as active smodeRB.invoke() del js
def load_company(): try: cogroup = _.curr.cogroup except KeyError: return # Group not selected yet if cogroup == None or cogroup == u'': return try: branchbox.children.popitem()[1].destroy() except KeyError: pass branchbox_inner = Tix.Frame(branchbox) branchbox_inner.pack(side='left', fill='x') options = dict(variable=_.curr.branchSV, indicatoron=False, font=(_.font, "14", "bold"), bg="NavajoWhite4", selectcolor="gold", activebackground="gold") Tix.Label(branchbox_inner, textvariable=_.loc(u"Branch")).pack(side="left") branch_info = Tix.StringVar() def set_branch_info(): branch = _.dbm.get_branch(_.curr.branchSV.get()) text = u'{} {} : {}'.format(U_No, branch.tax_id, branch.fullname) text += u'\n{} {}'.format(U_PHONE, branch.phone) if branch.fax: text += u' {} {}'.format(U_FAX, branch.fax) text += u'\n{} {}'.format(U_ENVELOPE, branch.email) text += u'\n{} {}'.format(U_INFO, branch.note) branch_info.set(text) Tix.Label(branchbox_inner, textvariable=branch_info, anchor='w', justify='left', font=(_.font, 14, 'bold')).pack(side='right') _.curr.branchSV.trace('w', lambda a,b,c,: set_branch_info()) for i, branch in enumerate(cogroup.branches): tr = Tix.Radiobutton(branchbox_inner, text=branch.name, value=branch.name, **options) tr.pack(side="top", fill='both', expand=1) if i==0: tr.invoke() tr.bind('<Double-Button-1>', lambda e, bn=branch.name: branch_edit(bn)) #TODO: Load entry fields with company info for viewing/editing #TODO: Buttons for switching supplier/customer booleans #### Display open purchase orders that can ship #### #################################################### try: center_pane.children.popitem()[1].destroy() except KeyError: pass pobox = Tix.Frame(center_pane) pobox.pack(side=Tix.TOP, fill=Tix.X) activeOrders = [] _poIDs = [] _qtyVars = [] _unitsVars = [] _discountVars = [] _multiplier = [] # Convert SKU to units _poBs = [] # PO button # info.order.entryWs[row].icursor(Tk.END) # info.order.entryWs[row].selection_range(0, Tk.END) def fill_qty(i, amount): _qtyVars[i].set(amount) order_list = cogroup.openpurchases if _.sc_mode == "s" else cogroup.opensales TB = lambda _text, **kwargs: Tix.Button(pobox, text=_text, anchor='w', bg="moccasin", font=(_.font, 13, 'bold'), activebackground="moccasin", **kwargs) # Retrieve user designated PO ordering if it exists. minlen = 100 rows = settings.load().get('po_order', {}).get(cogroup.name, range(minlen)) # Increase 'rows' length in case more PO's are added. if len(rows) < minlen: rows = rows + range(max(rows)+1, max(rows)+minlen-len(rows)) # Place PO (purchase orders) in the designated 'rows' ordering. for row, order in zip(rows, order_list): if order.is_open: activeOrders.append(order) _poIDs.append(order.id) _prod = order.product if _.debug: print 'PRODUCT TYPE:', type(_prod) assert isinstance(_prod, _.dbm.Product), u"Product not attached to order." # PO start date _text=u'{d.month}月{d.day}日'.format(d=order.orderdate) lw = Tix.Label(pobox, text=_text, font=(_.font, 11, 'bold')) lw.grid(row=row*2, column=0) _id = order.orderID if order.orderID else None if _id: _text = u'PO {:<10}:'.format(_id) else: _text = u'' _text += u"{}".format(_prod.label()) tb = TB(_text) tb['command'] = lambda o=order: po.edit(_,o,load_company) tb.grid(row=row*2, column=1, sticky='nsew') _poBs.append(tb) # Price per sku/unit _Ptext = u' ${}/{} '.format( int(order.price) if order.price.is_integer() else order.price, _prod.UM if _prod.unitpriced else _prod.SKU ) # lw = Tix.Label(pobox, text=_text) # lw.grid(row=row*2, column=8) _text=u'{}:{}'.format(_prod.specs, _Ptext) lw = Tix.Label(pobox, text=_text, padx=10, font=("PMingLiU", 13, 'bold')) lw.grid(row=row*2, column=2, sticky='w') if order.ordernote: lw = Tix.Label(pobox, textvariable=_.loc(u'NOTE:'), bg='coral', font=(_.font, 9)) lw.grid(row=row*2+1, column=0, sticky='ew') lw = Tix.Label(pobox, text=order.ordernote, anchor='w', bg='lavender', font=(_.font, 9)) lw.grid(row=row*2+1, column=1, columnspan=10, sticky='ew') # PO remaining QTY amt = order.qty_remaining() if amt >= 1e9: amt = U_INFINITE # Infinity symbol for unlimited POs. _textvar = _.loc(u"(Avail:") lw = Tix.Label(pobox, textvariable=_textvar, anchor='w') lw.grid(row=row*2, column=3, sticky='ew') _sku = _prod.SKU if _prod.SKU != u"槽車" else "kg" _textvar2 = Tix.StringVar() _text = u'{} {})'.format(amt, _sku) _textvar2.set(_text) _btext = u'{} {})'.format(amt * _prod.units if isinstance(amt, int) else amt, _prod.UM) lw.bind('<Button-1>', lambda e, sv=_textvar2, a=_text, b=_btext: \ sv.set(b if sv.get() == a else a)) lw2 = Tix.Label(pobox, textvariable=_textvar2, anchor='e') lw2.grid(row=row*2, column=4, sticky='ew') lw2.bind('<Double-Button-1>', lambda e, a=amt, i=len(_qtyVars): fill_qty(i,a)) # If PO remainder is zero. Make red. if order.all_shipped(): lw.config(bg=u'tomato') lw2.config(bg=u'tomato') # Multiple entry option button tb = Tix.Button(pobox, text=u'{t} {t}'.format(t=U_TRUCK), font=(_.font, 11), bg="lawn green", activebackground="lime green") tb['command'] = lambda o=order: po.add_many(_,o,load_company) tb.grid(row=row*2, column=5, sticky='nsew') # QTY entry field def highlight_entry(row, widget, capamt=100): if _.debug: print "row=",row, " widget=",widget, " capamt=",capamt # Check if entry is a number and doesn't exceed PO max. if widget.get(): if widget.get().isdigit() and int(widget.get()) <= capamt: widget.config(bg=u'PaleTurquoise1') else: widget.config(bg=u'IndianRed1') else: widget.config(bg=u'moccasin') # Fill in total units reference and color the PO button if _qtyVars[row].get().isdigit(): _int = int(_qtyVars[row].get())*_multiplier[row] _poBs[row].config(bg=u'PaleTurquoise1') if _int.is_integer(): _int = int(_int) _unitsVars[row].set(u"{}".format(_int)) else: _poBs[row].config(bg=u'moccasin') _unitsVars[row].set(u"{}".format(0)) _qtyVars.append(Tix.StringVar()) ew = Tix.Entry(pobox, textvariable=_qtyVars[-1], width=7, justify="center", bg=u"moccasin", validate='key', validatecommand=(vcmd_int, '%S')) ew.grid(row=row*2, column=6) _qtyVars[-1].trace('w', lambda a,b,c,ew=ew,capamt=amt,row=len(_poIDs)-1: highlight_entry(row,ew,capamt) ) # SKU _text = u'{}:'.format(_prod.SKU) lw = Tix.Label(pobox, text=_text, anchor='w') lw.grid(row=row*2, column=7, sticky='w') # Total units StringVar _unitsVars.append(Tix.StringVar()) _multiplier.append(_prod.units) lw = Tix.Label(pobox, textvariable=_unitsVars[-1], anchor='e', bg=u'LightGoldenrod1') lw.grid(row=row*2, column=8, sticky='e') _unitsVars[-1].set("0") _text = u' {}'.format( _prod.UM #if _prod.unitpriced else _prod.SKU ) lw = Tix.Label(pobox, text=_text, anchor='w', bg=u'LightGoldenrod1') lw.grid(row=row*2, column=9, sticky='w') # Discount percentage # _discountVars.append(Tix.StringVar()) # ew = Tix.Entry(pobox, textvariable=_discountVars[-1], width=7, # justify="center", bg=u"moccasin") # ew.grid(row=row*2, column=9) # _discountVars[-1].set(order.discount) # _discountVars[-1].trace('w', lambda a,b,c,ew=ew,row=len(_poIDs)-1: highlight_entry(row,ew,100) ) # lw = Tix.Label(pobox, textvariable=_.loc(u"% discount"), anchor='w') # lw.grid(row=row*2, column=10, sticky='w') # Button for adding another product order. #TODO: Add command # tb = Tix.Button(pobox, textvariable=_.loc("+ PO"), # bg="lawn green", # command=lambda:po.new(_, load_company), # activebackground="lime green") # tb.grid(row=1000, column=1, sticky='ew') # Button for submitting new manifest. Goto date selection, etc. #TODO: Add command numbSVar = Tix.StringVar() if _poIDs: tl = Tix.Label(pobox, textvariable=_.loc(u'Manifest #:')) tl.grid(row=1000, column=2, columnspan=2, sticky='e') te = Tix.Entry(pobox, textvariable=numbSVar, width=9, justify="center", bg=u"moccasin") te.grid(row=1000, column=4, columnspan=2, sticky='ew') tb = Tix.Button(pobox, textvariable=_.loc(U_TRUCK+u" Create Manifest"), bg="lawn green", command=lambda:make_manifest(), activebackground="lime green") tb.grid(row=1000, column=6, columnspan=5, sticky='ew') def make_manifest(): manifest_list = [(a, b, c) for a,b,c in zip(activeOrders, _qtyVars, _unitsVars) if b.get()] if _.debug: print manifest_list if len(manifest_list) > 5: tkMessageBox.showwarning(_.loc(u"Maximum exceeded",True), _.loc(u"Only a maximum of five items allowed.",True)) return if len(manifest_list) < 1: return po.manifest(_, orders=[a for a,b,c in manifest_list], qtyVars=[b for a,b,c in manifest_list], unitVars=[c for a,b,c in manifest_list], refresh=load_company, numbSVar = numbSVar) # Load PO HList 'All POs' for each_method in _.refresh: each_method()
'platformer2') _save_path_requires_subpaths = ['log'] for sprs in _save_path_requires_subpaths: try: os.makedirs(os.path.join(save_path, sprs)) except FileExistsError: pass # Prepare path if getattr(sys, 'frozen', False): import time t = time.time_ns() path = sys._MEIPASS sys.stdout = open(os.path.join(save_path, 'log', f'{t}.log'), 'w') sys.stderr = sys.stdout else: path = os.path.dirname(__file__) # Create args args = a.Args(scale=1, path=path, save_path=save_path) # Load settings settings.default_try_get_delim = '.' settings.load(path=os.path.join(save_path, 'settings.json'), default_path=os.path.join(path, 'src', 'default_settings.json')) app.launch(args)
def __init__(self, parent, debug=False): Tix.Tk.__init__(self, parent) self.parent = parent self.option_add("*Font", "PMingLiU 13") ttk.Style().configure('.', font=tkFont.Font(family="PMingLiU", size=13)) self.tk_setPalette( background=u'AntiqueWhite1', foreground=u'black', selectColor='white', activeForeground='black', selectBackground='black', selectForeground='yellow', disabledForeground='gray', ) _ = Info() _.parent = self _.debug = debug # For console messages and English GUI _.font = u"NSimSun" _.loc = localize # Translation to Chinese _.dbm = dbm.db_manager() # Database API methods _.curr = Info() # For storage current company, list ID's, etc. _.getExtWin = getExtWin self._ = _ # SET LANGUAGE SELECTION self.lang_select = Tix.StringVar() def switch_language(*args): new_lang = self.lang_select.get() settings.update(language=new_lang) setLang(new_lang) self.lang_select.trace_variable('w', switch_language) self.lang_select.set(settings.load().get(u'language', u'English')) # SET AUTO UPDATE OPTION self.auto_update_check = Tix.BooleanVar() self.auto_update_check.set(settings.load().get(u'auto_update_check', True)) def switch_auto_update(*args): new_bool = not settings.load()[u'auto_update_check'] settings.update(auto_update_check=new_bool) self.auto_update_check.trace_variable('w', switch_auto_update) # # SET UP MENU BAR # menubar = Tix.Menu(self) # FILE MENU OPTIONS: LOAD, SAVE, EXIT... filemenu = Tix.Menu(menubar, tearoff=0) # filemenu.add_command(label=_.loc(u"Change Database", 1), command=self.change_db) filemenu.add_command(label=_.loc(u"Exit", 1), command=self.endsession) menubar.add_cascade(label=_.loc(u"Main", 1), menu=filemenu) # REPORT MENU OPTIONS reportmenu = Tix.Menu(menubar, tearoff=0) reportmenu.add_command(label=u"Change location for saving reports", command=set_report_location) reportmenu.add_command(label=u"Activity Report (PDF)", command=lambda:activity_report.main(_)) reportmenu.add_command(label=u"ASE Product QC (PDF)", command=lambda:product_QC_report.main(_)) reportmenu.add_command(label=u"Save client shipments to Excel (6 months).", command=lambda:sales_shipments_to_excel(_)) reportmenu.add_command(label=u"Save incoming shipments to Excel (6 months).", command=lambda:purchases_shipments_to_excel(_)) reportmenu.add_command(label=u"Save all products to Excel file.", command=lambda:save_products_to_excel(_)) reportmenu.add_command(label=u"Save all static data to an Excel file.", command=lambda:staticDB2excel(_)) reportmenu.add_command(label=u"Save all active data to an Excel file.", command=lambda:activeDB2excel(_)) # reportmenu.add_command(label="Report3", command=None, state=Tk.DISABLED) # reportmenu.add_command(label="Report4", command=None, state=Tk.DISABLED) menubar.add_cascade(label=_.loc(u"Reports", 1), menu=reportmenu) # FONT MENU OPTIONS # def setFont(): # self.option_add("*Font", fontsize.get()) # fontmenu = Tix.Menu(menubar, tearoff=0) # fontsize = Tix.StringVar() # fontmenu.add_radiobutton(label=u'Verdana 12', variable=fontsize, # command=setFont, value=u'Verdana 12') # fontmenu.add_radiobutton(label=u'PMingLiU 13', variable=fontsize, # command=setFont, value=u'PMingLiU 13') # fontmenu.add_radiobutton(label=u'NSimSun 13', variable=fontsize, # command=setFont, value=u'NSimSun 13') # menubar.add_cascade(label=_.loc(u"Font", 1), menu=fontmenu) # fontsize.set(u'NSimSun 13') # setFont() # SETTINGS MENU OPTIONS settingsmenu = Tix.Menu(menubar, tearoff=0) lang_menu = Tix.Menu(settingsmenu, tearoff=0) settingsmenu.add_cascade(label=_.loc(u"Language", 1), menu=lang_menu) update_menu = Tix.Menu(settingsmenu, tearoff=0) settingsmenu.add_cascade(label=_.loc(u"Update", 1), menu=update_menu) lang_menu.add_radiobutton(label=u'繁體中文', variable=self.lang_select, value=u'Chinese', selectcolor=u'black') lang_menu.add_radiobutton(label=u'English', variable=self.lang_select, value=u'English', selectcolor=u'black') update_menu.add_command(label=_.loc(u"Check for update", 1), command=self.version_update) update_menu.add_separator() update_menu.add_checkbutton(label=_.loc(u'Auto check for updates',1), onvalue=True, offvalue=False, variable=self.auto_update_check, selectcolor=u'black') settingsmenu.add_separator() settingsmenu.add_command(label=_.loc(u'PO List Ordering', 1), command=lambda: setPOorder(_)) menubar.add_cascade(label=_.loc(u"Settings", 1), menu=settingsmenu) # HELP MENU OPTIONS helpmenu = Tix.Menu(menubar, tearoff=0) helpmenu.add_command(label=_.loc(u"About", 1), command=about) menubar.add_cascade(label=_.loc(u"Help", 1), menu=helpmenu) # menubar.add_separator() menubar.add_separator() menubar.add_command(label=u'DATABASE={}'.format(_.dbm.dbpath), background=u'LightSkyBlue1') self.menubar = menubar # SET AND SHOW MENU self.config(menu=menubar) try: self.geometry(settings.load()['geometry']) except KeyError: #Default geometry self.geometry('1240x800') # SET MAIN NOTEBOOK nb = ttk.Notebook() #---------- Add PO (main) frame #XXX: merging Purchases & Sales frames to PO frame in version 0.3 _.po_frame = ttk.Frame(nb) frames.po_frame.create(_) nb.add(_.po_frame, text='PO') #---------- Add Product frame _.product_frame = ttk.Frame(nb) frames.product_frame.create(_) nb.add(_.product_frame, text=_.loc(u'Products',1)) #---------- Add Pending info frame # frame = ttk.Frame(nb) # frame_pending.get_pending_frame(frame, dmv2) # nb.add(frame, text='Pending', underline=2) #TODO:---------- Add In-Out Records info frame # frame = ttk.Frame(nb) # frame_pending.get_tablet_frame(frame, dmv2) # nb.add(frame, text='Tablet Data', underline=0) #TODO:---------- Add Company data edit frame # frame = ttk.Frame(nb) # frame_company_editor.get_company_editor(frame, dmv2) # nb.add(frame, text='Catalog', underline=0) #TODO:---------- Add Warehouse management frame #--------- Set arrangement of notebook frames nb.pack(side='right', fill='both', expand=1, padx=2, pady=3) if self.auto_update_check.get(): check_for_update.update(self._, settings, silent=True)
def setPOorder(_): cogroup = _.curr.cogroup order_list = cogroup.openpurchases if _.sc_mode == "s" else cogroup.opensales if not getExtWin(_, co_name=cogroup.name, title=u'PO ordering'): return ordering = [] for row, order in enumerate(order_list): ordering.append(Tix.StringVar()) options = ___ = dict(master=_.extwin) ___['font'] = (_.font, 14) ___['text'] = u'{}:{} {}'.format(order.orderID, order.product.name, order.product.specs) Tix.Label(**options).grid(row=row, column=0, sticky='w') options = ___ = dict(master=_.extwin) ___['bg'] = u'moccasin' ___['font'] = (_.font, 14) ___['width'] = 5 ___['textvariable'] = ordering[-1] Tix.Entry(**options).grid(row=row, column=1, sticky='w') options = ___ = dict(master=_.extwin) ___['bg'] = u'lawn green' ___['font'] = (_.font, 16, 'bold') ___['textvariable'] = _.loc(u"\u2713 Submit") ___['command'] = lambda *args: submit(ordering) Tix.Button(**options).grid(row=101, column=0) options = ___ = dict(master=_.extwin) ___['bg'] = u'tomato' ___['font'] = (_.font, 16, 'bold') ___['textvariable'] = _.loc(u'Clear') ___['command'] = lambda *args: [sv.set(u'') for sv in ordering] Tix.Button(**options).grid(row=101, column=1) # Get existing ordering if defined previously. po_order = settings.load().get('po_order', {}) nset = po_order.get(cogroup.name, None) if nset: for val, sv in zip(nset, ordering): sv.set(str(val)) def submit(ordering): try: unused = range(1,100) # Convert entries to integers or None. ordering = [int(sv.get()) if sv.get().isdigit() else None for sv in ordering] # Removed used integers from the unused list. [unused.remove(val) for val in ordering if isinstance(val, int)] # Fill in blank (None) entries with unused integers. ordering = [unused.pop(0) if val == None else val for val in ordering] # Save ordering. po_order[cogroup.name] = ordering settings.update(po_order = po_order) _.extwin.destroy() except ValueError: pass
def switch_auto_update(*args): new_bool = not settings.load()[u'auto_update_check'] settings.update(auto_update_check=new_bool)
def refresh(): for child in prodf.winfo_children(): child.destroy() prodrecs.__delslice__(0,1000) # Store product records _priceSV.__delslice__(0,1000) # Store stringvar for entered prices _qtySV.__delslice__(0,1000) # Store stringvar for entered quantity cog = None # Current cogroup scm = None # Current 's' or 'c' mode (supplier or customer view) try: cog = _.curr.cogroup scm = _.sc_mode except KeyError: return # Retrieve user designated PO ordering if it exists. minlen = 100 rows = settings.load().get(scm, {}).get(cog.name, range(minlen)) # Increase 'rows' length in case more prod are added. #XXX: Possibly unnecessary. Refresh if new products added. if len(rows) < minlen: rows = rows + range(max(rows)+1, max(rows)+minlen-len(rows)) # Get list of product records. query = _.dbm.session.query(_.dbm.Product) query = query.filter_by(group = cog.name) query = query.filter_by(discontinued = False) query = query.filter_by(is_supply=True if scm == u's' else False) query = query.order_by('inventory_name') [prodrecs.append(p) for p in query.all()] # Set default options for all widgets. OPTS = dict(master=prodf, justify="right")#, font=font) # Set entry widget defaults Eopts = dict(width=8, bg=u"moccasin", validate='key', **OPTS) _unitsVars = [] _multiplier = [] # Convert SKU to units for row, PR in zip(rows, prodrecs): col = 0 PrU = PR.UM if PR.unitpriced else PR.SKU w = [] # Container for one line of widgets # Product name and specs w.append(Tix.Label(text=PR.name, **OPTS)) w[-1].grid(row=row, column=col, sticky='nsw'); col += 1 w.append(Tix.Label(text=PR.specs, padx=20, **OPTS)) w[-1].grid(row=row, column=col, sticky='nsw'); col += 1 # Price entry _priceSV.append(Tix.StringVar()) _priceSV[-1].set(u'{}{}'.format(prefix, PR.price)) w.append(Tix.Entry(textvariable=_priceSV[-1], validatecommand=(vcmd_float, '%P'), **Eopts)) w[-1].grid(row=row, column=col); col += 1 # TWD per sku/unit w.append(Tix.Label(text=u'/{}'.format(PrU), padx=10, **OPTS)) w[-1].grid(row=row, column=col, sticky='nsw'); col += 1 # Number of units entry _qtySV.append(Tix.StringVar()) w.append(Tix.Entry(textvariable=_qtySV[-1], validatecommand=(vcmd_int, '%S'), **Eopts)) w[-1].grid(row=row, column=col); col += 1 # Show SKU after quantity number text = PR.SKU if text == u'槽車': text = PrU w.append(Tix.Label(text=text, padx=10, **OPTS)) w[-1].grid(row=row, column=col, sticky='nsw'); col += 1 def highlightrow(qtyi, widgets): val = _qtySV[qtyi].get() new_color = u'PaleTurquoise1' if len(val) else u'moccasin' for widget in widgets: if isinstance(widget, Tix.Entry): widget.config(bg=new_color) widgets[0].config(relief='raised' if len(val) else 'flat', bg='lawngreen' if len(val) else col_default) # Fill in total units reference if _qtySV[qtyi].get().isdigit(): _int = int(_qtySV[qtyi].get())*_multiplier[qtyi] # _poBs[qtyi].config(bg=u'PaleTurquoise1') if _int.is_integer(): _int = int(_int) _unitsVars[qtyi].set(u"{}".format(_int)) else: # _poBs[row].config(bg=u'moccasin') _unitsVars[qtyi].set(u"{}".format(0)) _qtySV[-1].trace('w', lambda a,b,c,i=len(_qtySV)-1, w=w: highlightrow(i, w)) # Total units StringVar _unitsVars.append(Tix.StringVar()) _multiplier.append(PR.units) lw = Tix.Label(textvariable=_unitsVars[-1], anchor='e', bg=u'LightGoldenrod1', **OPTS) lw.grid(row=row, column=col, sticky='e'); col += 1 _unitsVars[-1].set("0") _text = u' {}'.format( PR.UM #if _prod.unitpriced else _prod.SKU ) lw = Tix.Label(text=_text, anchor='w', bg=u'LightGoldenrod1', **OPTS) lw.grid(row=row, column=col, sticky='w'); col += 1