class Income: def __init__(self, app): """ фрейм с поиском товаров """ self.app = app self.win = Frame(self.app.win) self.frame = LabelFrame(self.win, text='Что ищем?') self.frame.pack(fill=BOTH, expand=1, padx=5, pady=5) self.search = Entry(self.frame, width=20, cursor='xterm') self.search.grid(row=0, column=0, padx=5, pady=5) self.search.bind('<KeyRelease>', self.callback) self.lab_var = StringVar() Label(self.frame, textvariable=self.lab_var).grid(row=0, column=1, padx=20) self.lst = MultiListbox(self.win, (('Дата', 10), ('Время', 10), ('Отдел', 2), ('Товар', 50), ('Сумма', 5), ('Кол.во', 5), ('Продавец', 10)), font=('normal', 9), height=15) self.lst.pack(fill=BOTH, expand=1, padx=5, pady=5) def callback(self, event=None): """ вызывается при изменении содержимого entry """ txt = '%%%s%%' % self.search.get().lower() self.lst.delete(0, END) if len(txt) < 3: self.lab_var.set('') return self.lab_var.set('Поиск....') self.win.update() self.app.app.app.db.execute( 'select date,time,dep,article,sum,rate,name,art_id,edit from income where myLower(article) like ?', (txt, )) k = 0 all_sum = 0 for x in self.app.app.app.db.fetchall(): x = list(x) x[0] = norm_date(x[0]) if x[8] <> 0: x[2] = str(x[2]) + ' (≈)' if x[7] <> -1: x[2] = str(x[2]) + ' →' all_sum += x[4] * x[5] self.lst.insert(END, x) k += 1 self.lab_var.set('Найдено %s совпадений, на сумму %s' % (k, all_sum))
class TabPredictWordFreq(Frame): def __init__(self, parentFrame, db, **kwargs): Frame.__init__(self, parentFrame, **kwargs) self.parent = parentFrame self.__db = db self.__selectedStock = None Button(parentFrame, text="Calculate", command=self.calculate_wordFrequencies).pack() self.listBox_words = MultiListbox(parentFrame, None, (('word', 20), ('Occ. Total', 20), ('% total', 20), ('% Pos', 20), ('% Neg', 20))) self.listBox_words.pack(side=LEFT,anchor=W, fill=BOTH, expand=YES) def calculate_wordFrequencies(self): if self.__selectedStock != None: start = datetime.now() allStocks = self.__db.getAllStocks(self.__selectedStock) stop = datetime.now() print "db query getAllStocks: #stockentries:", len(allStocks), " in ", stop-start start = datetime.now() pos, neg = SignificantDateCalculator.CalculateSignificantDates(sorted(allStocks.itervalues()), 'date', 'shareprice_closing', interestDatesThreshold, interestingDatesTimeDeltaList) stop = datetime.now() print "calculate significant dates: #stockentries:", len(pos) + len(neg), " in ", stop-start wf = WordFrequency.WordFrequency(self.__db, pos, neg) words = wf.getInterestingWords() start = datetime.now() self.listBox_words.delete(0, END) for word in sorted(words, key=words.get, reverse=True): self.listBox_words.insert(END, (word, words[word]['nr-webpages-with-occurance'], "{0:.2f}".format(words[word]['%-webpages-with-occurance']), "{0:.2f}".format(words[word]['%-pos-webpages-with-occurance']), "{0:.2f}".format(words[word]['%-neg-webpages-with-occurance']))) stop = datetime.now() print "populate listbox: #words:", len(words), " in ", stop-start def setSelectedStock(self, stock): self.__selectedStock = stock
class Income: def __init__(self,app): """ фрейм с поиском товаров """ self.app=app self.win=Frame(self.app.win) self.frame=LabelFrame(self.win,text='Что ищем?') self.frame.pack(fill=BOTH,expand=1,padx=5,pady=5) self.search=Entry(self.frame,width=20,cursor='xterm') self.search.grid(row=0,column=0,padx=5,pady=5) self.search.bind('<KeyRelease>',self.callback) self.lab_var=StringVar() Label(self.frame,textvariable=self.lab_var).grid(row=0,column=1,padx=20) self.lst=MultiListbox(self.win, (('Дата', 10), ('Время', 10),('Отдел',2), ('Товар', 50),('Сумма',5),('Кол.во',5),('Продавец',10)),font=('normal',9),height=15) self.lst.pack(fill=BOTH,expand=1,padx=5,pady=5) def callback(self,event=None): """ вызывается при изменении содержимого entry """ txt='%%%s%%'%self.search.get().lower() self.lst.delete(0,END) if len(txt)<3: self.lab_var.set('') return self.lab_var.set('Поиск....') self.win.update() self.app.app.app.db.execute('select date,time,dep,article,sum,rate,name,art_id,edit from income where myLower(article) like ?',(txt,)) k=0 all_sum=0 for x in self.app.app.app.db.fetchall(): x=list(x) x[0]=norm_date(x[0]) if x[8]<>0: x[2]=str(x[2])+' (≈)' if x[7]<>-1: x[2]=str(x[2])+' →' all_sum+=x[4]*x[5] self.lst.insert(END,x) k+=1 self.lab_var.set('Найдено %s совпадений, на сумму %s'%(k,all_sum))
class Plugin: def __init__(self, app): self.app = app def run(self): self.win = Toplevel(self.app.app.win) self.win.title(name) x, y = 800, 450 pos = self.win.wm_maxsize()[0] / 2 - x / 2, self.win.wm_maxsize( )[1] / 2 - y / 2 self.win.geometry('%sx%s+%s+%s' % (x, y, pos[0], pos[1] - 25)) self.win.maxsize(width=x, height=y) self.win.minsize(width=x, height=y) if sys.platform == 'win32': self.win.iconbitmap('app/images/icon.ico') year, month = time.localtime()[0:2] self.date_t = StringVar() self.date_t.set(date_now()) self.c_date = date_now() self.cal = TkCalendar(self.win, year, month, self.date_t, command=self.calend_handler) self.cal.grid(row=0, column=0, padx=5, pady=10, sticky=N) self.content_frame = Frame(self.win) self.content_frame.grid(row=0, column=1, rowspan=3, sticky=N) self.tool_frame = Labelframe(self.win, text='Итог') self.tool_frame.grid(row=1, column=0, sticky=N + W) Label(self.content_frame, text='Приход:', font=('normal', 12)).pack(fill=BOTH) self.lst = MultiListbox(self.content_frame, (('Время', 8), ('Отдел', 5), ('Товар', 32), ('Сумма', 5), ('Кол.во', 1), ('Итог', 5), ('Продавец', 12)), font=('normal', 10), height=15) self.lst.pack(fill=BOTH, expand=1) Label(self.content_frame, text='Расход:', font=('normal', 12)).pack(fill=BOTH) self.lst2 = MultiListbox(self.content_frame, (('Время', 8), ('Причина', 35), ('Сумма', 5), ('Продавец', 12)), font=('normal', 10), height=6) self.lst2.pack(fill=BOTH, expand=1) s = 'За дату: %s' % (norm_date(date_now())) self.d_label = Label(self.tool_frame, text=s, font=('bold', 12)) self.d_label.grid(row=0, columnspan=2, sticky=N + W) s = 'Доход: 0' self.in_label = Label(self.tool_frame, text=s, font=('bold', 12)) self.in_label.grid(row=1, columnspan=2, sticky=N + W) s = 'Расход: 0' self.out_label = Label(self.tool_frame, text=s, font=('bold', 12)) self.out_label.grid(row=2, columnspan=2, sticky=N + W) s = 'Остаток: 0' self.all_label = Label(self.tool_frame, text=s, font=('bold', 12)) self.all_label.grid(row=3, columnspan=2, sticky=N + W) self.scr1 = Scrollbar(self.tool_frame, orient=VERTICAL) self.scr1.grid(row=4, column=1, sticky=N + S, pady=5) self.list_1 = Listbox(self.tool_frame, width=27, height=5, font=("normal", 9), yscrollcommand=self.scr1.set) self.list_1.grid(row=4, column=0, pady=5) self.scr1['command'] = self.list_1.yview self.pdf_but = Button(self.win, text='В pdf', image=self.app.app.img['pdf'], compound='left', command=self.generate_pdf) self.pdf_but.grid(row=2, column=0, sticky=N) self.update_lists() def calend_handler(self, date): """ при щелчке на дату в календаре """ self.c_date = date self.update_lists() def update_lists(self): """ заполняем таблицы """ self.lst.delete(0, END) self.app.app.db.execute( 'select time,dep,article,sum,rate,name,art_id,edit from income where date=?', (self.c_date, )) income_all = 0 for x in self.app.app.db.fetchall(): out = list(x) if out[7] <> 0: out[1] = str(out[1]) + ' (≈)' if out[6] <> -1: out[1] = str(out[1]) + ' →' out.insert(5, round(x[3] * x[4], 2)) income_all += x[3] * x[4] self.lst.insert(END, out) self.lst.see(END) outcome_all = 0 self.lst2.delete(0, END) self.app.app.db.execute( 'select time,article,sum,name,art_id,edit from outcome where date=?', (self.c_date, )) for x in self.app.app.db.fetchall(): out = list(x) if out[5] <> 0: out[1] = u'(≈) ' + out[1] self.lst2.insert(END, out) outcome_all += out[2] self.lst2.see(END) self.in_label['text'] = 'Доход: %s' % (income_all) self.out_label['text'] = 'Расход: %s' % (outcome_all) self.all_label['text'] = 'Остаток: %s' % (income_all - outcome_all) s = 'За дату: %s' % (norm_date(self.c_date)) self.d_label['text'] = s deps = {} deps_sum = {} self.app.app.db.execute('select name from dep') self.deps = [] for n, name in enumerate(self.app.app.db.fetchall()): if name: deps_sum[n + 1] = 0 self.deps.append('%s' % (name[0])) self.app.app.db.execute('select dep,sum,rate from income where date=?', (self.c_date, )) out = self.app.app.db.fetchall() in_all = 0 for x in out: in_all += float(x[1]) * float(x[2]) deps_sum[x[0]] += float(x[1]) * float(x[2]) self.list_1.delete(0, END) for x in deps_sum: if deps_sum[x]: self.list_1.insert( END, str(x) + ' ' + self.deps[x - 1] + u'→ ' + str(deps_sum[x])) def generate_pdf(self): """ генерация pdf. Ваш К.О. """ try: path = self.app.app.sets.save_pdf except: path = '' filename = 'Продажи за %s.pdf' % (norm_date(self.c_date)) f = tkFileDialog.asksaveasfilename(initialdir=path, initialfile=filename) if not f: return f = f.replace('\\', '/') self.app.app.sets.save_pdf = '/'.join(f.split('/')[:-1]) doc = pdf.Pdf(title='Продажи за %s' % (norm_date(self.c_date)), fname=f) doc.string('Доходы:') doc.table([('Время', 45), ('Отд', 35), ('Товар', 220), ('Сум.', 40), ('К-во', 30), ('Итого', 40), ('Продавец', 90)]) self.app.app.db.execute( 'select time,dep,article,sum,rate,name,art_id,edit from income where date=?', (self.c_date, )) income_all = 0 for x in self.app.app.db.fetchall(): out = list(x) if out[7] <> 0: out[1] = str(out[1]) + u' (≈)' if out[6] <> -1: out[1] = str(out[1]) + u' →' out.insert(5, x[3] * x[4]) income_all += x[3] * x[4] doc.table([(out[0], 45), (out[1], 35), (out[2], 220), (out[3], 40), (out[4], 30), (out[5], 40), (out[6], 90)], font=10) doc.enter() doc.string('Расходы:') outcome_all = 0 doc.table([('Время', 45), ('Причина', 220), ('Сум.', 40), ('Продавец', 90)]) self.app.app.db.execute( 'select time,article,sum,name,art_id,edit from outcome where date=?', (self.c_date, )) for x in self.app.app.db.fetchall(): out = list(x) if out[5] <> 0: out[1] = u'(≈) ' + out[1] doc.table([(out[0], 45), (out[1], 220), (out[2], 40), (out[3], 90)], font=10) outcome_all += out[2] doc.enter() doc.string('Всего доходов: %s' % (income_all)) doc.string('Всего расходов: %s' % (outcome_all)) doc.string('Остаток: %s' % (income_all - outcome_all)) doc.end() self.win.deiconify()
class Plugin: def __init__(self, app): self.app = app def run(self): self.log = Log(self.app.app) self.win = Toplevel(self.app.app.win) self.win.title(name) self.win.protocol("WM_DELETE_WINDOW", self.exit) x, y = 800, 450 pos = self.win.wm_maxsize()[0] / 2 - x / 2, self.win.wm_maxsize( )[1] / 2 - y / 2 self.win.geometry('%sx%s+%s+%s' % (x, y, pos[0], pos[1] - 25)) self.win.maxsize(width=x, height=y) self.win.minsize(width=x, height=y) if sys.platform == 'win32': self.win.iconbitmap('app/images/icon.ico') year, month = time.localtime()[0:2] self.date_t = StringVar() self.date_t.set(date_now()) self.c_date = date_now() self.cal = TkCalendar(self.win, year, month, self.date_t, command=self.calend_handler) self.cal.grid(row=0, column=0, padx=5, pady=10, sticky=N) self.content_frame = Frame(self.win) self.content_frame.grid(row=0, column=1, rowspan=3, sticky=N) self.tool_frame = Frame(self.win) self.tool_frame.grid(row=1, column=0, sticky=N + W) Label(self.content_frame, text='Приход:', font=('normal', 12)).pack(fill=BOTH) self.lst = MultiListbox(self.content_frame, (('Время', 8), ('Отдел', 5), ('Товар', 40), ('Сумма', 5), ('Кол.во', 1), ('Итог', 5), ('Продавец', 12)), font=('normal', 10), height=6, command=self.lst1select) self.lst.pack(fill=BOTH, expand=1) Label(self.content_frame, text='Расход:', font=('normal', 12)).pack(fill=BOTH) self.lst2 = MultiListbox(self.content_frame, (('Время', 8), ('Причина', 35), ('Сумма', 5), ('Продавец', 12)), font=('normal', 10), height=6, command=self.lst2select) self.lst2.pack(fill=BOTH, expand=1) s = 'За дату: %s' % (norm_date(date_now())) self.d_label = Label(self.tool_frame, text=s, font=('bold', 12)) self.d_label.grid(row=0, columnspan=2, sticky=N + W) self.edit_frame_parrent = Labelframe(self.content_frame, text='Редактировать', width=50, height=100) self.edit_frame_parrent.pack(fill=BOTH, expand=1) self.delete_frame_parrent = Labelframe(self.content_frame, text='Удалить', width=50, height=50) self.delete_frame_parrent.pack(fill=BOTH, expand=1) self.edit_frame = Frame(self.edit_frame_parrent, height=63) self.edit_frame.pack() self.delete_frame = Frame(self.delete_frame_parrent, height=46) self.delete_frame.pack() self.update_lists() def exit(self, event=None): """ при выходе обновляем главное окно """ self.app.update_list() self.app.update_tools() self.win.destroy() def calend_handler(self, date): """ вызывается при щелчке на дату """ self.c_date = date self.edit_frame.destroy() self.edit_frame = Frame(self.edit_frame_parrent, height=63) self.edit_frame.pack(fill=BOTH, expand=1) self.delete_frame.destroy() self.delete_frame = Frame(self.delete_frame_parrent, height=46) self.delete_frame.pack(fill=BOTH, expand=1) self.update_lists() def update_lists(self): """ наполняем таблицы """ self.current_income = [] self.current_outcome = [] self.lst.delete(0, END) self.app.app.db.execute( 'select time,dep,article,sum,rate,name,art_id,date,edit from income where date=?', (self.c_date, )) income_all = 0 for x in self.app.app.db.fetchall(): out = list(x) if out[8] <> 0: out[1] = str(out[1]) + ' (≈)' if out[6] <> -1: out[1] = str(out[1]) + ' →' out.insert(5, round(x[3] * x[4], 2)) income_all += x[3] * x[4] self.lst.insert(END, out) self.current_income.append(x) self.lst.see(END) outcome_all = 0 self.lst2.delete(0, END) self.app.app.db.execute( 'select time,article,sum,name,art_id,date,edit from outcome where date=?', (self.c_date, )) for x in self.app.app.db.fetchall(): out = list(x) if out[6] <> 0: out[1] = u'(≈) ' + out[1] self.lst2.insert(END, out) self.current_outcome.append(x) outcome_all += out[2] self.lst2.see(END) s = 'За дату: %s' % (norm_date(self.c_date)) self.d_label['text'] = s def lst1select(self): """ при щелчке на продаже """ if self.lst2.curselection(): self.lst2.selection_clear(self.lst2.curselection()) self.edit_frame.destroy() self.edit_frame = Frame(self.edit_frame_parrent, height=63) self.edit_frame.pack(fill=BOTH, expand=1) self.delete_frame.destroy() self.delete_frame = Frame(self.delete_frame_parrent, height=46) self.delete_frame.pack(fill=BOTH, expand=1) Label(self.delete_frame, text='Причина удаления').grid(row=0, column=0, padx=10, pady=5) self.delete_entry = Entry(self.delete_frame, width=35, cursor='xterm', font=('normal', 12)) self.delete_entry.grid(row=0, column=1, pady=10) self.delete_button = Button(self.delete_frame, text='Удалить', image=self.app.app.img['delete'], compound='left', command=self.delete_income) self.delete_button.grid(row=0, column=2, padx=5) Label(self.edit_frame, text='Отдел').grid(row=0, column=0, padx=2, pady=2) self.otd_ent = Entry(self.edit_frame, width=3, cursor='xterm', font=('normal', 12)) self.otd_ent.grid(row=0, column=1, padx=2, pady=2) Label(self.edit_frame, text='Товар').grid(row=0, column=2, padx=2, pady=2) self.tov_ent = Entry(self.edit_frame, width=30, cursor='xterm', font=('normal', 12)) self.tov_ent.grid(row=0, column=3, padx=2, pady=2) Label(self.edit_frame, text='Кол-во').grid(row=0, column=4, padx=2, pady=2) self.kvo_ent = Entry(self.edit_frame, width=4, cursor='xterm', font=('normal', 12)) self.kvo_ent.grid(row=0, column=5, padx=2, pady=2) Label(self.edit_frame, text='Сумма').grid(row=0, column=6, padx=2, pady=2) self.sum_ent = Entry(self.edit_frame, width=7, cursor='xterm', font=('normal', 12)) self.sum_ent.grid(row=0, column=7, padx=2, pady=2) self.save_but = Button(self.edit_frame, text='Сохранить', image=self.app.app.img['save'], compound='left', command=self.save_income) self.save_but.grid(row=1, column=6, columnspan=2, pady=2) if not self.lst.curselection(): return c = self.current_income[int(self.lst.curselection()[0])] self.otd_ent.delete(0, END) self.otd_ent.insert(0, c[1]) self.tov_ent.delete(0, END) self.tov_ent.insert(0, c[2]) self.kvo_ent.delete(0, END) self.kvo_ent.insert(0, c[4]) self.sum_ent.delete(0, END) self.sum_ent.insert(0, c[3]) def lst2select(self): """ при щелчке на расходе """ if self.lst.curselection(): self.lst.selection_clear(self.lst.curselection()) self.edit_frame.destroy() self.edit_frame = Frame(self.edit_frame_parrent, height=63) self.edit_frame.pack(fill=BOTH, expand=1) self.delete_frame.destroy() self.delete_frame = Frame(self.delete_frame_parrent, height=46) self.delete_frame.pack(fill=BOTH, expand=1) Label(self.delete_frame, text='Причина удаления').grid(row=0, column=0, padx=10, pady=5) self.delete_entry = Entry(self.delete_frame, width=35, cursor='xterm', font=('normal', 12)) self.delete_entry.grid(row=0, column=1, pady=10) self.delete_button = Button(self.delete_frame, text='Удалить', image=self.app.app.img['delete'], compound='left', command=self.delete_outcome) self.delete_button.grid(row=0, column=2, padx=5) Label(self.edit_frame, text='Причина').grid(row=0, column=0, padx=2, pady=2) self.pr_ent = Entry(self.edit_frame, width=48, cursor='xterm', font=('normal', 12)) self.pr_ent.grid(row=0, column=1, padx=2, pady=2) Label(self.edit_frame, text='Сумма').grid(row=0, column=2, padx=2, pady=2) self.sum_ent = Entry(self.edit_frame, width=7, cursor='xterm', font=('normal', 12)) self.sum_ent.grid(row=0, column=3, padx=2, pady=2) self.save_but = Button(self.edit_frame, text='Сохранить', image=self.app.app.img['save'], compound='left', command=self.save_outcome) self.save_but.grid(row=1, column=2, columnspan=2, pady=2, sticky=E) if not self.lst2.curselection(): return c = self.current_outcome[int(self.lst2.curselection()[0])] self.pr_ent.delete(0, END) self.pr_ent.insert(0, c[1]) self.sum_ent.delete(0, END) self.sum_ent.insert(0, c[2]) def delete_income(self): """ удаление продажи """ if not self.lst.curselection(): return text = self.delete_entry.get() if len(text) < 3: box.showerror(title='Ошибка', message='Вы должны ввести причину удаления!') self.win.deiconify() return c = self.current_income[int(self.lst.curselection()[0])] self.app.app.db.execute('delete from income where time=? and date=?', (c[0], c[7])) self.app.app.con.commit() self.delete_entry.delete(0, END) self.update_lists() self.log.del_income(c[7], c[0], c[1], c[2], text, c[3], c[4], self.app.app.user.decode('utf-8')) def delete_outcome(self): """ Удаление расхода """ if not self.lst2.curselection(): return text = self.delete_entry.get() if len(text) < 3: box.showerror(title='Ошибка', message='Вы должны ввести причину удаления!') self.win.deiconify() return c = self.current_outcome[int(self.lst2.curselection()[0])] self.app.app.db.execute('delete from outcome where time=? and date=?', (c[0], c[5])) self.app.app.con.commit() self.delete_entry.delete(0, END) self.update_lists() self.log.del_outcome(c[5], c[0], c[1], c[2], c[3], self.app.app.user.decode('utf-8'), text) def save_income(self): """ сохранение отредактированной продажи """ if not self.lst.curselection(): return dep = self.otd_ent.get() art = self.tov_ent.get() self.app.app.db.execute('select * from dep where id=?', (dep, )) if not self.app.app.db.fetchall(): box.showerror(title='Ошибка', message='Не верный отдел!') self.win.deiconify() return dep = int(dep) try: kvo = int(self.kvo_ent.get()) except: box.showerror(title='Ошибка', message='Не верное количество!') self.win.deiconify() return try: summa = float(self.sum_ent.get().replace(',', '.')) if summa <= 0: s = 1 / 0 except: box.showerror(title='Ошибка', message='Не верная сумма!') self.win.deiconify() return c = self.current_income[int(self.lst.curselection()[0])] i = int(self.lst.curselection()[0]) self.app.app.db.execute( 'update income set dep=?,article=?,rate=?,sum=?,edit=1 where date=? and time=?', (dep, art, kvo, summa, c[7], c[0])) self.app.app.con.commit() self.update_lists() self.lst.selection_set(i) self.log.edit_income(c[7], c[0], [c[1], c[2], c[4], c[3]], [dep, art, kvo, summa], self.app.app.user.decode('utf-8'), c[5]) def save_outcome(self): """ сохранение отредактированного расхода """ if not self.lst2.curselection(): return text = self.pr_ent.get() if len(text) < 3: box.showerror( title='Ошибка', message='Причина удаления не может быть удалена! (как то так)') self.win.deiconify() return c = self.current_outcome[int(self.lst2.curselection()[0])] try: summa = float(self.sum_ent.get().replace(',', '.')) if summa <= 0: s = 1 / 0 except: box.showerror(title='Ошибка', message='Не верная сумма!') self.win.deiconify() return i = int(self.lst2.curselection()[0]) self.app.app.db.execute( 'update outcome set article=?,sum=?,edit=1 where date=? and time=?', (text, summa, c[5], c[0])) self.app.app.con.commit() self.update_lists() self.lst2.selection_set(i) self.log.edit_outcome(c[5], c[0], [c[1], c[2]], [text, summa], self.app.app.user.decode('utf-8'), c[3])
class Income: def __init__(self, app): """ класс с фреймом приходов товара """ self.app = app self.win = Frame(self.app.win, width=20, height=50) self.lst = MultiListbox(self.win, (('Дата', 8), ('Время', 5), ('Приход', 50), ('Пользователь', 10)), font=('normal', 10), height=7, command=self.l_command) self.lst.pack(fill=BOTH, expand=1, padx=5, pady=5) self.lst2 = MultiListbox(self.win, (('Отдел', 3), ('Товар', 73), ('Количество', 5)), font=('normal', 10), height=10) self.lst2.pack(fill=BOTH, expand=1, padx=5, pady=5) self.pdf_but = Button(self.win, text='В pdf', image=self.app.app.app.img['pdf'], compound='left', command=self.generate_pdf) self.pdf_but.pack(anchor=W) self.app.app.app.db.execute( 'select id,date,time,rate,user from in_art') rez = self.app.app.app.db.fetchall() self.sums = {} self.ids = {} self.naim = {} self.user = {} for x in rez: self.ids[x[0]] = [norm_date(x[1]), x[2], x[4]] self.sums[x[0]] = self.sums.setdefault(x[0], 0) + x[3] self.naim[x[0]] = self.naim.setdefault(x[0], 0) + 1 k = self.ids.keys() k.sort() self.c_id = k for x in k: self.lst.insert(END, [ self.ids[x][0], self.ids[x][1], 'Наименований товаров %s шт., общее количество %s шт.' % (self.naim[x], self.sums[x]), self.ids[x][2] ]) self.lst.see(END) def l_command(self): """ при выборе прихода, показываем список товаров """ if not self.lst.curselection(): return sel = int(self.lst.curselection()[0]) id = self.c_id[sel] self.lst2.delete(0, END) self.app.app.app.db.execute( 'select dep,name,rate from in_art where id=?', (id, )) for x in self.app.app.app.db.fetchall(): self.lst2.insert(END, x) def generate_pdf(self): """ генерация pdf c выбранным приходом """ if not self.lst.curselection(): return sel = int(self.lst.curselection()[0]) id = self.c_id[sel] self.app.app.app.db.execute('select date,time from in_art where id=?', (id, )) rez = self.app.app.app.db.fetchall()[0] try: path = self.app.app.app.sets.save_pdf except: path = '' print rez filename = ('Приход товара за %s %s.pdf' % (norm_date(rez[0]), str(rez[1]))).replace(':', '-') f = tkFileDialog.asksaveasfilename(initialdir=path, initialfile=filename) if not f: return f = f.replace('\\', '/') self.app.app.app.sets.save_pdf = '/'.join(f.split('/')[:-1]) doc = pdf.Pdf(title='Приход товара', fname=f) doc.string('Приход товара за %s %s' % (norm_date(rez[0]), str(rez[1]))) self.app.app.app.db.execute( 'select dep,name,rate from in_art where id=?', (id, )) doc.table([('Отдел', 45), ('Товар', 350), ('Кол.во', 50)]) n = 0 s = 0 for x in self.app.app.app.db.fetchall(): n += 1 doc.table([(x[0], 45), (x[1], 350), (x[2], 50)], font=10) s += x[2] doc.enter() doc.string('Наименований: %s' % (n)) doc.string('Количество: %s' % (s)) doc.end() self.app.win.deiconify()
class Income: def __init__(self,app): """ класс с фреймом приходов товара """ self.app=app self.win=Frame(self.app.win,width=20,height=50) self.lst=MultiListbox(self.win, (('Дата', 8), ('Время', 5), ('Приход', 50),('Пользователь',10)),font=('normal',10),height=7,command=self.l_command) self.lst.pack(fill=BOTH,expand=1,padx=5,pady=5) self.lst2=MultiListbox(self.win, (('Отдел', 3),('Товар', 73), ('Количество', 5)),font=('normal',10),height=10) self.lst2.pack(fill=BOTH,expand=1,padx=5,pady=5) self.pdf_but=Button(self.win,text='В pdf',image=self.app.app.app.img['pdf'],compound='left',command=self.generate_pdf) self.pdf_but.pack(anchor=W) self.app.app.app.db.execute('select id,date,time,rate,user from in_art') rez=self.app.app.app.db.fetchall() self.sums={} self.ids={} self.naim={} self.user={} for x in rez: self.ids[x[0]]=[norm_date(x[1]),x[2],x[4]] self.sums[x[0]]=self.sums.setdefault(x[0],0)+x[3] self.naim[x[0]]=self.naim.setdefault(x[0],0)+1 k=self.ids.keys() k.sort() self.c_id=k for x in k: self.lst.insert(END,[self.ids[x][0],self.ids[x][1],'Наименований товаров %s шт., общее количество %s шт.'%(self.naim[x],self.sums[x]),self.ids[x][2]]) self.lst.see(END) def l_command(self): """ при выборе прихода, показываем список товаров """ if not self.lst.curselection():return sel=int(self.lst.curselection()[0]) id=self.c_id[sel] self.lst2.delete(0,END) self.app.app.app.db.execute('select dep,name,rate from in_art where id=?',(id,)) for x in self.app.app.app.db.fetchall(): self.lst2.insert(END,x) def generate_pdf(self): """ генерация pdf c выбранным приходом """ if not self.lst.curselection():return sel=int(self.lst.curselection()[0]) id=self.c_id[sel] self.app.app.app.db.execute('select date,time from in_art where id=?',(id,)) rez=self.app.app.app.db.fetchall()[0] try:path=self.app.app.app.sets.save_pdf except:path='' print rez filename=('Приход товара за %s %s.pdf'%(norm_date(rez[0]),str(rez[1]))).replace(':','-') f=tkFileDialog.asksaveasfilename(initialdir=path,initialfile=filename) if not f:return f=f.replace('\\','/') self.app.app.app.sets.save_pdf='/'.join(f.split('/')[:-1]) doc=pdf.Pdf(title='Приход товара',fname=f) doc.string('Приход товара за %s %s'%(norm_date(rez[0]),str(rez[1]))) self.app.app.app.db.execute('select dep,name,rate from in_art where id=?',(id,)) doc.table([('Отдел',45),('Товар',350),('Кол.во',50)]) n=0 s=0 for x in self.app.app.app.db.fetchall(): n+=1 doc.table([(x[0],45),(x[1],350),(x[2],50)],font=10) s+=x[2] doc.enter() doc.string('Наименований: %s'%(n)) doc.string('Количество: %s'%(s)) doc.end() self.app.win.deiconify()
class Plugin: def __init__(self,app): self.app=app def run(self): self.log=Log(self.app.app) self.win=Toplevel(self.app.app.win) self.win.title(name) self.win.protocol("WM_DELETE_WINDOW", self.exit) x,y=800,450 pos=self.win.wm_maxsize()[0]/2-x/2,self.win.wm_maxsize()[1]/2-y/2 self.win.geometry('%sx%s+%s+%s'%(x,y,pos[0],pos[1]-25)) self.win.maxsize(width=x,height=y) self.win.minsize(width=x,height=y) if sys.platform=='win32':self.win.iconbitmap('app/images/icon.ico') year,month = time.localtime()[0:2] self.date_t=StringVar() self.date_t.set(date_now()) self.c_date=date_now() self.cal=TkCalendar(self.win,year, month, self.date_t,command=self.calend_handler) self.cal.grid(row=0,column=0,padx=5,pady=10,sticky=N) self.content_frame=Frame(self.win) self.content_frame.grid(row=0,column=1,rowspan=3,sticky=N) self.tool_frame=Frame(self.win) self.tool_frame.grid(row=1,column=0,sticky=N+W) Label(self.content_frame,text='Приход:',font=('normal',12)).pack(fill=BOTH) self.lst=MultiListbox(self.content_frame, (('Время', 8), ('Отдел', 5), ('Товар', 40),('Сумма',5),('Кол.во',1),('Итог',5),('Продавец',12)),font=('normal',10),height=6,command=self.lst1select) self.lst.pack(fill=BOTH,expand=1) Label(self.content_frame,text='Расход:',font=('normal',12)).pack(fill=BOTH) self.lst2=MultiListbox(self.content_frame, (('Время', 8), ('Причина', 35),('Сумма',5),('Продавец',12)),font=('normal',10),height=6,command=self.lst2select) self.lst2.pack(fill=BOTH,expand=1) s='За дату: %s'%(norm_date(date_now())) self.d_label=Label(self.tool_frame,text=s,font=('bold',12)) self.d_label.grid(row=0,columnspan=2,sticky=N+W) self.edit_frame_parrent=Labelframe(self.content_frame,text='Редактировать', width=50,height=100) self.edit_frame_parrent.pack(fill=BOTH,expand=1) self.delete_frame_parrent=Labelframe(self.content_frame,text='Удалить', width=50,height=50) self.delete_frame_parrent.pack(fill=BOTH,expand=1) self.edit_frame=Frame(self.edit_frame_parrent,height=63) self.edit_frame.pack() self.delete_frame=Frame(self.delete_frame_parrent,height=46) self.delete_frame.pack() self.update_lists() def exit(self,event=None): """ при выходе обновляем главное окно """ self.app.update_list() self.app.update_tools() self.win.destroy() def calend_handler(self,date): """ вызывается при щелчке на дату """ self.c_date=date self.edit_frame.destroy() self.edit_frame=Frame(self.edit_frame_parrent,height=63) self.edit_frame.pack(fill=BOTH,expand=1) self.delete_frame.destroy() self.delete_frame=Frame(self.delete_frame_parrent,height=46) self.delete_frame.pack(fill=BOTH,expand=1) self.update_lists() def update_lists(self): """ наполняем таблицы """ self.current_income=[] self.current_outcome=[] self.lst.delete(0,END) self.app.app.db.execute('select time,dep,article,sum,rate,name,art_id,date,edit from income where date=?',(self.c_date,)) income_all=0 for x in self.app.app.db.fetchall(): out=list(x) if out[8]<>0: out[1]=str(out[1])+' (≈)' if out[6]<>-1: out[1]=str(out[1])+' →' out.insert(5,round(x[3]*x[4],2)) income_all+=x[3]*x[4] self.lst.insert(END,out) self.current_income.append(x) self.lst.see(END) outcome_all=0 self.lst2.delete(0,END) self.app.app.db.execute('select time,article,sum,name,art_id,date,edit from outcome where date=?',(self.c_date,)) for x in self.app.app.db.fetchall(): out=list(x) if out[6]<>0: out[1]=u'(≈) '+out[1] self.lst2.insert(END,out) self.current_outcome.append(x) outcome_all+=out[2] self.lst2.see(END) s='За дату: %s'%(norm_date(self.c_date)) self.d_label['text']=s def lst1select(self): """ при щелчке на продаже """ if self.lst2.curselection(): self.lst2.selection_clear(self.lst2.curselection()) self.edit_frame.destroy() self.edit_frame=Frame(self.edit_frame_parrent,height=63) self.edit_frame.pack(fill=BOTH,expand=1) self.delete_frame.destroy() self.delete_frame=Frame(self.delete_frame_parrent,height=46) self.delete_frame.pack(fill=BOTH,expand=1) Label(self.delete_frame,text='Причина удаления').grid(row=0,column=0,padx=10,pady=5) self.delete_entry=Entry(self.delete_frame,width=35,cursor='xterm',font=('normal',12)) self.delete_entry.grid(row=0,column=1,pady=10) self.delete_button=Button(self.delete_frame,text='Удалить',image=self.app.app.img['delete'],compound='left',command=self.delete_income) self.delete_button.grid(row=0,column=2,padx=5) Label(self.edit_frame,text='Отдел').grid(row=0,column=0,padx=2,pady=2) self.otd_ent=Entry(self.edit_frame,width=3,cursor='xterm',font=('normal',12)) self.otd_ent.grid(row=0,column=1,padx=2,pady=2) Label(self.edit_frame,text='Товар').grid(row=0,column=2,padx=2,pady=2) self.tov_ent=Entry(self.edit_frame,width=30,cursor='xterm',font=('normal',12)) self.tov_ent.grid(row=0,column=3,padx=2,pady=2) Label(self.edit_frame,text='Кол-во').grid(row=0,column=4,padx=2,pady=2) self.kvo_ent=Entry(self.edit_frame,width=4,cursor='xterm',font=('normal',12)) self.kvo_ent.grid(row=0,column=5,padx=2,pady=2) Label(self.edit_frame,text='Сумма').grid(row=0,column=6,padx=2,pady=2) self.sum_ent=Entry(self.edit_frame,width=7,cursor='xterm',font=('normal',12)) self.sum_ent.grid(row=0,column=7,padx=2,pady=2) self.save_but=Button(self.edit_frame,text='Сохранить',image=self.app.app.img['save'],compound='left',command=self.save_income) self.save_but.grid(row=1,column=6,columnspan=2,pady=2) if not self.lst.curselection():return c=self.current_income[int(self.lst.curselection()[0])] self.otd_ent.delete(0,END) self.otd_ent.insert(0,c[1]) self.tov_ent.delete(0,END) self.tov_ent.insert(0,c[2]) self.kvo_ent.delete(0,END) self.kvo_ent.insert(0,c[4]) self.sum_ent.delete(0,END) self.sum_ent.insert(0,c[3]) def lst2select(self): """ при щелчке на расходе """ if self.lst.curselection(): self.lst.selection_clear(self.lst.curselection()) self.edit_frame.destroy() self.edit_frame=Frame(self.edit_frame_parrent,height=63) self.edit_frame.pack(fill=BOTH,expand=1) self.delete_frame.destroy() self.delete_frame=Frame(self.delete_frame_parrent,height=46) self.delete_frame.pack(fill=BOTH,expand=1) Label(self.delete_frame,text='Причина удаления').grid(row=0,column=0,padx=10,pady=5) self.delete_entry=Entry(self.delete_frame,width=35,cursor='xterm',font=('normal',12)) self.delete_entry.grid(row=0,column=1,pady=10) self.delete_button=Button(self.delete_frame,text='Удалить',image=self.app.app.img['delete'],compound='left',command=self.delete_outcome) self.delete_button.grid(row=0,column=2,padx=5) Label(self.edit_frame,text='Причина').grid(row=0,column=0,padx=2,pady=2) self.pr_ent=Entry(self.edit_frame,width=48,cursor='xterm',font=('normal',12)) self.pr_ent.grid(row=0,column=1,padx=2,pady=2) Label(self.edit_frame,text='Сумма').grid(row=0,column=2,padx=2,pady=2) self.sum_ent=Entry(self.edit_frame,width=7,cursor='xterm',font=('normal',12)) self.sum_ent.grid(row=0,column=3,padx=2,pady=2) self.save_but=Button(self.edit_frame,text='Сохранить',image=self.app.app.img['save'],compound='left',command=self.save_outcome) self.save_but.grid(row=1,column=2,columnspan=2,pady=2,sticky=E) if not self.lst2.curselection():return c=self.current_outcome[int(self.lst2.curselection()[0])] self.pr_ent.delete(0,END) self.pr_ent.insert(0,c[1]) self.sum_ent.delete(0,END) self.sum_ent.insert(0,c[2]) def delete_income(self): """ удаление продажи """ if not self.lst.curselection():return text=self.delete_entry.get() if len(text)<3: box.showerror(title='Ошибка',message='Вы должны ввести причину удаления!') self.win.deiconify() return c=self.current_income[int(self.lst.curselection()[0])] self.app.app.db.execute('delete from income where time=? and date=?',(c[0],c[7])) self.app.app.con.commit() self.delete_entry.delete(0,END) self.update_lists() self.log.del_income(c[7],c[0],c[1],c[2],text,c[3],c[4],self.app.app.user.decode('utf-8')) def delete_outcome(self): """ Удаление расхода """ if not self.lst2.curselection():return text=self.delete_entry.get() if len(text)<3: box.showerror(title='Ошибка',message='Вы должны ввести причину удаления!') self.win.deiconify() return c=self.current_outcome[int(self.lst2.curselection()[0])] self.app.app.db.execute('delete from outcome where time=? and date=?',(c[0],c[5])) self.app.app.con.commit() self.delete_entry.delete(0,END) self.update_lists() self.log.del_outcome(c[5],c[0],c[1],c[2],c[3],self.app.app.user.decode('utf-8'),text) def save_income(self): """ сохранение отредактированной продажи """ if not self.lst.curselection():return dep=self.otd_ent.get() art=self.tov_ent.get() self.app.app.db.execute('select * from dep where id=?',(dep,)) if not self.app.app.db.fetchall(): box.showerror(title='Ошибка',message='Не верный отдел!') self.win.deiconify() return dep=int(dep) try: kvo=int(self.kvo_ent.get()) except: box.showerror(title='Ошибка',message='Не верное количество!') self.win.deiconify() return try: summa=float(self.sum_ent.get().replace(',','.')) if summa<=0:s=1/0 except: box.showerror(title='Ошибка',message='Не верная сумма!') self.win.deiconify() return c=self.current_income[int(self.lst.curselection()[0])] i=int(self.lst.curselection()[0]) self.app.app.db.execute('update income set dep=?,article=?,rate=?,sum=?,edit=1 where date=? and time=?',(dep,art,kvo,summa,c[7],c[0])) self.app.app.con.commit() self.update_lists() self.lst.selection_set(i) self.log.edit_income(c[7],c[0],[c[1],c[2],c[4],c[3]],[dep,art,kvo,summa],self.app.app.user.decode('utf-8'),c[5]) def save_outcome(self): """ сохранение отредактированного расхода """ if not self.lst2.curselection():return text=self.pr_ent.get() if len(text)<3: box.showerror(title='Ошибка',message='Причина удаления не может быть удалена! (как то так)') self.win.deiconify() return c=self.current_outcome[int(self.lst2.curselection()[0])] try: summa=float(self.sum_ent.get().replace(',','.')) if summa<=0:s=1/0 except: box.showerror(title='Ошибка',message='Не верная сумма!') self.win.deiconify() return i=int(self.lst2.curselection()[0]) self.app.app.db.execute('update outcome set article=?,sum=?,edit=1 where date=? and time=?',(text,summa,c[5],c[0])) self.app.app.con.commit() self.update_lists() self.lst2.selection_set(i) self.log.edit_outcome(c[5],c[0],[c[1],c[2]],[text,summa],self.app.app.user.decode('utf-8'),c[3])
class Art: def __init__(self, app): """ поиск по товарам """ self.app = app self.win = Frame(self.app.win) self.frame = LabelFrame(self.win, text='Что ищем?') self.frame.pack(fill=BOTH, expand=1, padx=5, pady=5) self.search = Entry(self.frame, width=20, cursor='xterm') self.search.grid(row=0, column=0, padx=5, pady=5) self.search.bind('<KeyRelease>', self.callback) self.lab_var = StringVar() Label(self.frame, textvariable=self.lab_var).grid(row=0, column=1, padx=20) self.lst = MultiListbox(self.win, (('Товар', 70), ('Остаток', 10), ('Стоимость', 10)), font=('normal', 10), height=15) self.lst.pack(fill=BOTH, expand=1, padx=5, pady=5) def callback(self, event=None): """ вызывается при смене содержимого entry """ txt = '%%%s%%' % self.search.get().lower() self.lst.delete(0, END) if len(txt) < 3: self.lab_var.set('') return self.lab_var.set('Поиск....') self.win.update() self.app.app.app.db.execute( 'select id,rate,sum from article where myLower(name) like ? order by name', (txt, )) k = 0 for x in self.app.app.app.db.fetchall(): x = list(x) t = [] flag = True self.app.app.app.db.execute( 'select name,edit,sum,parent,type from article where id=?', (x[0], )) s = self.app.app.app.db.fetchall()[0] par = s[3] t.append(s[0]) if s[4] == 'stick': is_cat = True else: is_cat = False if par == -1: flag = 0 while flag: self.app.app.app.db.execute( 'select name,parent from article where id=?', (par, )) rez = self.app.app.app.db.fetchall()[0] if rez[1] == -1: t.append(rez[0]) flag = False else: t.append(rez[0]) par = rez[1] cat_lst = ' > '.join(t[::-1]) if is_cat: x[1] = '' x[2] = '[категория]' self.lst.insert(END, [cat_lst, x[1], x[2]]) k += 1 self.lab_var.set('Найдено %s совпадений' % (k))
class Application(tk.Frame): """Main application class. Author: Pavel""" def __init__(self, master=None): super().__init__(master) self.pack() self.create_widgets() def create_widgets(self): """A method to draw the interface Should be only called in class constructor Author: Pavel""" self.toolbar = Frame(self.master, bg=Frame_color, bd=1, relief=RAISED) #A button to add new song add_button = Button(self.toolbar, bg=Button_color, fg=Text_color, command=self.add_item) add_button["text"] = "+" add_button.pack(side=LEFT, padx=2, pady=2) #A button to remove a song remove_button = Button(self.toolbar, bg=Button_color, fg=Text_color, command=self.remove_items) remove_button["text"] = "-" remove_button.pack(side=LEFT, padx=2, pady=2) edit_button = Button(self.toolbar, bg=Button_color, fg=Text_color, command=self.edit_item) edit_button["text"] = "Edit" edit_button.pack(side=LEFT, padx=2, pady=2) search_button = Button(self.toolbar, bg=Button_color, fg=Text_color, command=self.create_filters) search_button["text"] = "Search" search_button.pack(side=LEFT, padx=2, pady=2) stats_button = Button(self.toolbar, bg=Button_color, fg=Text_color, command=self.stats) stats_button["text"] = "Stats" stats_button.pack(side=LEFT, padx=2, pady=2) self.reset_button = Button(self.toolbar, bg=Button_color, fg=Text_color, command=self.reset_db) self.reset_button["text"] = "Reset filters" self.reset_button.pack(side=LEFT, padx=2, pady=2) #Idk what it is for exit_button = Button(self.toolbar, bg=Button_color, fg="red", command=ROOT.destroy) exit_button["text"] = "Quit" exit_button.pack(side=RIGHT, padx=2, pady=2) self.toolbar.pack(side=BOTTOM, fill=X) self.keys = db_get_keys() keys_tmp = ((i, 0) for i in self.keys) self.table = MultiListbox(ROOT, keys_tmp) del keys_tmp self.apply_db(DB, True) self.table.pack(expand=YES, fill=BOTH, side=BOTTOM) def remove_items(self): """A method to delete item then - button is pressed Author: Pavel""" items = self.table.curselection() for index in items: item = self.table.get(index) del item[-1] items_in_db = db_find_strict(DB, dict(zip(db_get_keys(DB), item))) for item_in_db in items_in_db: db_delete_entry(DB, item_in_db) #search and delete in db self.table.delete(index) def edit_item(self): """A method to open "Edit entry" dialog Author: Pavel""" edit_indexes = self.table.curselection() if not edit_indexes: return self.edit_index = edit_indexes[0] item = self.table.get(self.edit_index) time = item[-1] del item[-1] #DURATION item = list( db_find_strict(DB, dict(zip(db_get_keys(DB), item))).values())[0] item['duration'] = time t = tk.Toplevel(self) t.wm_title("Add track to DB") l = InsertionFrame(t, self, DB, item) l.pack(side="top", fill="both", expand=True) def add_item(self): """A simple method to add entry Author: Andrew""" t = tk.Toplevel(self) t.wm_title("Add track to DB") l = InsertionFrame(t, self, DB) l.pack(side="top", fill="both", expand=True) def stats(self): """Statistics Author: Pavel""" stats_window = tk.Toplevel(self) stats_window.wm_title("Stats") stats_frame = StatsFrame(stats_window, self.filtered_db) stats_frame.pack(side=TOP, fill=BOTH, expand=True) def insert_item(self, item, prev_item): """A so-called slot to insert item as soon as it is created Author: Andrew""" where = END if prev_item: to_delete = list(db_find_strict(DB, prev_item))[0] db_delete_entry(DB, to_delete) self.table.delete(self.edit_index) where = self.edit_index res = [] for key in self.keys: res.append(item[key]) self.table.insert(where, res) secs = 0 for a, b in enumerate(reversed(item['duration'].split(':'))): secs += 60**int(a) * int(b) item['duration'] = secs db_add_entry(DB, item) def create_filters(self): """Create filter Author: Pavel """ filter_window = tk.Toplevel(self) filter_window.wm_title("Add filters") filter_frame = FilterFrame(filter_window, self, DB) filter_frame.pack(side=TOP, fill=BOTH, expand=True) def apply_db(self, data, clear=False): """Display db Author: Pavel""" if clear: self.reset_button['state'] = DISABLED else: self.reset_button['state'] = NORMAL self.filtered_db = data self.table.delete(0, END) for i in data.values(): try: j = i.copy() m, s = divmod(int(i['duration']), 60) h, m = divmod(m, 60) j['duration'] = "%d:%02d:%02d" % (h, m, s) except ValueError: i['duration'] = 0 j['duration'] = 0 res = [] for key in self.keys: res.append(j[key]) self.table.insert(END, res) def reset_db(self): self.filtered_db = DB self.apply_db(self.filtered_db, True)
class Plugin: def __init__(self,app): self.app=app def run(self): self.win=Toplevel(self.app.app.win) self.win.title(name) x,y=600,500 pos=self.win.wm_maxsize()[0]/2-x/2,self.win.wm_maxsize()[1]/2-y/2 self.win.geometry('%sx%s+%s+%s'%(x,y,pos[0],pos[1]-25)) self.win.maxsize(width=x,height=y) self.win.minsize(width=x,height=y) if sys.platform=='win32':self.win.iconbitmap('app/images/icon.ico') self.add_f=LabelFrame(self.win,text='Остатки товара по отделу...') self.add_f.pack(expand=YES,fill=X,anchor=N,padx=5,pady=5) self.init_deps() self.rb_var=IntVar() self.rb=Radiobutton(self.add_f,text='Показать все',value=0,variable=self.rb_var,command=self.callback) self.rb.grid(row=0,column=1,sticky=W,padx=5,pady=5) self.rb2=Radiobutton(self.add_f,text='Показать меньше ',value=1,variable=self.rb_var,command=self.callback) self.rb2.grid(row=0,column=2,sticky=W,padx=5,pady=5) self.rate_ent=Entry(self.add_f,width=5,cursor='xterm') self.rate_ent.grid(row=0,column=3) self.rate_ent.insert(END,'3') self.rate_ent.bind('<KeyRelease>',self.callback1) self.lst=MultiListbox(self.win, (('Товар', 50), ('Остаток', 5),('Стоимость',6)),font=('normal',11),height=19) self.lst.pack(fill=BOTH,expand=1,padx=5,pady=5) self.lab_var=StringVar() self.all_label=Label(self.win,textvariable=self.lab_var,font=('bold',12)) self.all_label.pack(padx=5) self.pdf_but=Button(self.win,text='В pdf',image=self.app.app.img['pdf'],compound='left',command=self.generate_pdf) self.pdf_but.pack(side='left',padx=5,pady=5,anchor=W) self.csv_but=Button(self.win,text='В csv',image=self.app.app.img['csv'],compound='left',command=self.generate_csv) self.csv_but.pack(side='left',padx=5,pady=5,anchor=W) self.callback() def init_deps(self): """ меня с отделами, как мне надоело это писать """ self.deps=[] self.app.app.db.execute('select name from dep') for n,name in enumerate(self.app.app.db.fetchall()): self.deps.append('%s %s'%(n+1,name[0])) self.cur_dep=0 self.dep_str=StringVar() self.dep_str.set(self.deps[0]) Style().configure("TMenubutton",font=('bold',13)) self.otd=Menubutton(self.add_f,textvariable=self.dep_str, width=19,image=self.app.app.img['deps'],compound='left') self.otd.grid(row=0,column=0,pady=5,padx=5) self.otd.menu=Menu(self.otd, font=("bold",13),bg='white',relief='flat', tearoff=0) for n,x in enumerate(self.deps): if len(x)>3: self.otd.menu.add_command(label=x.ljust(25),command=lambda z=n:self.deps_hand(z)) self.otd['menu']=self.otd.menu def deps_hand(self,n): """ вызывается при выборе отдела """ self.cur_dep=n self.dep_str.set(self.deps[n]) self.cat_id=-1 self.callback() def callback1(self,event=None): """ при смене количества """ self.rb_var.set(1) self.callback() def callback(self,event=None): """ при смене чекбатонна, заполняем таблицу заново """ self.lst.delete(0,END) r=self.rb_var.get() rate=self.rate_ent.get() if r==0: self.app.app.db.execute('select id,rate,sum,type from article where dep=?',(self.cur_dep+1,)) else: try:rate=int(rate) except:return self.app.app.db.execute('select id,rate,sum,type from article where dep=? and rate<?',(self.cur_dep+1,rate)) rez1=self.app.app.db.fetchall() all_rate=0 all_sum=0 for x in rez1: t=[] flag=True self.app.app.db.execute('select name,edit,sum,parent from article where id=?',(x[0],)) s=self.app.app.db.fetchall()[0] par=s[3] t.append(s[0]) if par==-1:flag=0 while flag: self.app.app.db.execute('select name,parent from article where id=?',(par,)) rez=self.app.app.db.fetchall()[0] if rez[1]==-1: t.append(rez[0]) flag=False else: t.append(rez[0]) par=rez[1] cat_lst=' > '.join(t[::-1]) if x[3]=='item': self.lst.insert(END,[cat_lst,x[1],x[2]]) all_rate+=x[1] all_sum+=x[1]*x[2] self.lab_var.set('Наименований: %s, количество: %s, на сумму %s'%(len(rez1),all_rate,all_sum)) def generate_pdf(self): """ генерация pdf """ try:path=self.app.app.sets.save_pdf except:path='' filename='Остатки по отделу %s на %s.pdf'%(self.cur_dep+1,norm_date(date_now())) f=tkFileDialog.asksaveasfilename(initialdir=path,initialfile=filename) if not f:return f=f.replace('\\','/') self.app.app.sets.save_pdf='/'.join(f.split('/')[:-1]) doc=pdf.Pdf(title='Остатки товара',fname=f) r=self.rb_var.get() rate=self.rate_ent.get() self.app.app.db.execute('select name from dep where id=?',(self.cur_dep+1,)) dep_name=self.app.app.db.fetchall()[0][0] if r==0: self.app.app.db.execute('select id,rate,sum,type from article where dep=?',(self.cur_dep+1,)) doc.string(u'Все остатки по отделу %s %s'%(self.cur_dep+1,dep_name)) else: try:rate=int(rate) except:return self.app.app.db.execute('select id,rate,sum,type from article where dep=? and rate<?',(self.cur_dep+1,rate)) doc.string(u'Остатки по отделу %s %s, количество товара меньше %s'%(self.cur_dep+1,dep_name,rate)) rez1=self.app.app.db.fetchall() all_rate=0 all_sum=0 doc.table([('Товар',300),('Остаток',80),('Стоимость',80)]) for x in rez1: t=[] flag=True self.app.app.db.execute('select name,edit,sum,parent from article where id=?',(x[0],)) s=self.app.app.db.fetchall()[0] par=s[3] t.append(s[0]) if par==-1:flag=0 while flag: self.app.app.db.execute('select name,parent from article where id=?',(par,)) rez=self.app.app.db.fetchall()[0] if rez[1]==-1: t.append(rez[0]) flag=False else: t.append(rez[0]) par=rez[1] cat_lst=' > '.join(t[::-1]) if x[3]=='item': doc.table([(cat_lst,300),(x[1],80),(x[2],80)],font=10) all_rate+=x[1] all_sum+=x[1]*x[2] self.lab_var.set('Наименований: %s, количество: %s, на сумму %s'%(len(rez1),all_rate,all_sum)) doc.enter() doc.string('Всего наименований: %s'%(len(rez1))) doc.string('Всего количество: %s, на сумму %s'%(all_rate,all_sum)) doc.end() self.win.deiconify() def generate_csv(self): """ генерация csv """ try:path=self.app.app.sets.save_pdf except:path='' filename='Остатки по отделу %s на %s.csv'%(self.cur_dep+1,norm_date(date_now())) f=tkFileDialog.asksaveasfilename(initialdir=path,initialfile=filename) if not f:return f=f.replace('\\','/') self.app.app.sets.save_pdf='/'.join(f.split('/')[:-1]) doc=csv.writer(open(f,'w'),delimiter=';',lineterminator='\n',quoting=csv.QUOTE_ALL) doc.writerow([u'Товар'.encode('cp1251'),u'Остаток'.encode('cp1251'),u'Стоимость'.encode('cp1251')]) r=self.rb_var.get() rate=self.rate_ent.get() self.app.app.db.execute('select name from dep where id=?',(self.cur_dep+1,)) dep_name=self.app.app.db.fetchall()[0][0] if r==0: self.app.app.db.execute('select id,rate,sum,type from article where dep=?',(self.cur_dep+1,)) else: try:rate=int(rate) except:return self.app.app.db.execute('select id,rate,sum,type from article where dep=? and rate<?',(self.cur_dep+1,rate)) rez1=self.app.app.db.fetchall() all_rate=0 all_sum=0 for x in rez1: t=[] flag=True self.app.app.db.execute('select name,edit,sum,parent from article where id=?',(x[0],)) s=self.app.app.db.fetchall()[0] par=s[3] t.append(s[0]) if par==-1:flag=0 while flag: self.app.app.db.execute('select name,parent from article where id=?',(par,)) rez=self.app.app.db.fetchall()[0] if rez[1]==-1: t.append(rez[0]) flag=False else: t.append(rez[0]) par=rez[1] cat_lst=' > '.join(t[::-1]) if x[3]=='item': doc.writerow([cat_lst.encode('cp1251'),x[1],x[2]]) all_rate+=x[1] all_sum+=x[1]*x[2] self.lab_var.set('Наименований: %s, количество: %s, на сумму %s'%(len(rez1),all_rate,all_sum)) self.win.deiconify()
class Plugin: def __init__(self,app): self.app=app def run(self): self.win=Toplevel(self.app.app.win) self.win.title(name) x,y=800,450 pos=self.win.wm_maxsize()[0]/2-x/2,self.win.wm_maxsize()[1]/2-y/2 self.win.geometry('%sx%s+%s+%s'%(x,y,pos[0],pos[1]-25)) self.win.maxsize(width=x,height=y) self.win.minsize(width=x,height=y) if sys.platform=='win32':self.win.iconbitmap('app/images/icon.ico') year,month = time.localtime()[0:2] self.date_t=StringVar() self.date_t.set(date_now()) self.c_date=date_now() self.cal=TkCalendar(self.win,year, month, self.date_t,command=self.calend_handler) self.cal.grid(row=0,column=0,padx=5,pady=10,sticky=N) self.content_frame=Frame(self.win) self.content_frame.grid(row=0,column=1,rowspan=3,sticky=N) self.tool_frame=Labelframe(self.win,text='Итог') self.tool_frame.grid(row=1,column=0,sticky=N+W) Label(self.content_frame,text='Приход:',font=('normal',12)).pack(fill=BOTH) self.lst=MultiListbox(self.content_frame, (('Время', 8), ('Отдел', 5), ('Товар', 32),('Сумма',5),('Кол.во',1),('Итог',5),('Продавец',12)),font=('normal',10),height=15) self.lst.pack(fill=BOTH,expand=1) Label(self.content_frame,text='Расход:',font=('normal',12)).pack(fill=BOTH) self.lst2=MultiListbox(self.content_frame, (('Время', 8), ('Причина', 35),('Сумма',5),('Продавец',12)),font=('normal',10),height=6) self.lst2.pack(fill=BOTH,expand=1) s='За дату: %s'%(norm_date(date_now())) self.d_label=Label(self.tool_frame,text=s,font=('bold',12)) self.d_label.grid(row=0,columnspan=2,sticky=N+W) s='Доход: 0' self.in_label=Label(self.tool_frame,text=s,font=('bold',12)) self.in_label.grid(row=1,columnspan=2,sticky=N+W) s='Расход: 0' self.out_label=Label(self.tool_frame,text=s,font=('bold',12)) self.out_label.grid(row=2,columnspan=2,sticky=N+W) s='Остаток: 0' self.all_label=Label(self.tool_frame,text=s,font=('bold',12)) self.all_label.grid(row=3,columnspan=2,sticky=N+W) self.scr1=Scrollbar(self.tool_frame,orient=VERTICAL) self.scr1.grid(row=4,column=1,sticky=N+S,pady=5) self.list_1=Listbox(self.tool_frame,width=27,height=5, font=("normal",9), yscrollcommand=self.scr1.set) self.list_1.grid(row=4,column=0,pady=5) self.scr1['command']=self.list_1.yview self.pdf_but=Button(self.win,text='В pdf',image=self.app.app.img['pdf'],compound='left',command=self.generate_pdf) self.pdf_but.grid(row=2,column=0,sticky=N) self.update_lists() def calend_handler(self,date): """ при щелчке на дату в календаре """ self.c_date=date self.update_lists() def update_lists(self): """ заполняем таблицы """ self.lst.delete(0,END) self.app.app.db.execute('select time,dep,article,sum,rate,name,art_id,edit from income where date=?',(self.c_date,)) income_all=0 for x in self.app.app.db.fetchall(): out=list(x) if out[7]<>0: out[1]=str(out[1])+' (≈)' if out[6]<>-1: out[1]=str(out[1])+' →' out.insert(5,round(x[3]*x[4],2)) income_all+=x[3]*x[4] self.lst.insert(END,out) self.lst.see(END) outcome_all=0 self.lst2.delete(0,END) self.app.app.db.execute('select time,article,sum,name,art_id,edit from outcome where date=?',(self.c_date,)) for x in self.app.app.db.fetchall(): out=list(x) if out[5]<>0: out[1]=u'(≈) '+out[1] self.lst2.insert(END,out) outcome_all+=out[2] self.lst2.see(END) self.in_label['text']='Доход: %s'%(income_all) self.out_label['text']='Расход: %s'%(outcome_all) self.all_label['text']='Остаток: %s'%(income_all-outcome_all) s='За дату: %s'%(norm_date(self.c_date)) self.d_label['text']=s deps={} deps_sum={} self.app.app.db.execute('select name from dep') self.deps=[] for n,name in enumerate(self.app.app.db.fetchall()): if name: deps_sum[n+1]=0 self.deps.append('%s'%(name[0])) self.app.app.db.execute('select dep,sum,rate from income where date=?',(self.c_date,)) out=self.app.app.db.fetchall() in_all=0 for x in out: in_all+=float(x[1])*float(x[2]) deps_sum[x[0]]+=float(x[1])*float(x[2]) self.list_1.delete(0,END) for x in deps_sum: if deps_sum[x]: self.list_1.insert(END,str(x)+' '+self.deps[x-1]+u'→ '+str(deps_sum[x])) def generate_pdf(self): """ генерация pdf. Ваш К.О. """ try:path=self.app.app.sets.save_pdf except:path='' filename='Продажи за %s.pdf'%(norm_date(self.c_date)) f=tkFileDialog.asksaveasfilename(initialdir=path,initialfile=filename) if not f:return f=f.replace('\\','/') self.app.app.sets.save_pdf='/'.join(f.split('/')[:-1]) doc=pdf.Pdf(title='Продажи за %s'%(norm_date(self.c_date)),fname=f) doc.string('Доходы:') doc.table([('Время',45),('Отд',35),('Товар',220),('Сум.',40),('К-во',30),('Итого',40),('Продавец',90)]) self.app.app.db.execute('select time,dep,article,sum,rate,name,art_id,edit from income where date=?',(self.c_date,)) income_all=0 for x in self.app.app.db.fetchall(): out=list(x) if out[7]<>0: out[1]=str(out[1])+u' (≈)' if out[6]<>-1: out[1]=str(out[1])+u' →' out.insert(5,x[3]*x[4]) income_all+=x[3]*x[4] doc.table([(out[0],45),(out[1],35),(out[2],220),(out[3],40),(out[4],30),(out[5],40),(out[6],90)],font=10) doc.enter() doc.string('Расходы:') outcome_all=0 doc.table([('Время',45),('Причина',220),('Сум.',40),('Продавец',90)]) self.app.app.db.execute('select time,article,sum,name,art_id,edit from outcome where date=?',(self.c_date,)) for x in self.app.app.db.fetchall(): out=list(x) if out[5]<>0: out[1]=u'(≈) '+out[1] doc.table([(out[0],45),(out[1],220),(out[2],40),(out[3],90)],font=10) outcome_all+=out[2] doc.enter() doc.string('Всего доходов: %s'%(income_all)) doc.string('Всего расходов: %s'%(outcome_all)) doc.string('Остаток: %s'%(income_all-outcome_all)) doc.end() self.win.deiconify()
class Art: def __init__(self,app): """ поиск по товарам """ self.app=app self.win=Frame(self.app.win) self.frame=LabelFrame(self.win,text='Что ищем?') self.frame.pack(fill=BOTH,expand=1,padx=5,pady=5) self.search=Entry(self.frame,width=20,cursor='xterm') self.search.grid(row=0,column=0,padx=5,pady=5) self.search.bind('<KeyRelease>',self.callback) self.lab_var=StringVar() Label(self.frame,textvariable=self.lab_var).grid(row=0,column=1,padx=20) self.lst=MultiListbox(self.win, (('Товар', 70), ('Остаток', 10),('Стоимость', 10)),font=('normal',10),height=15) self.lst.pack(fill=BOTH,expand=1,padx=5,pady=5) def callback(self,event=None): """ вызывается при смене содержимого entry """ txt='%%%s%%'%self.search.get().lower() self.lst.delete(0,END) if len(txt)<3: self.lab_var.set('') return self.lab_var.set('Поиск....') self.win.update() self.app.app.app.db.execute('select id,rate,sum from article where myLower(name) like ? order by name',(txt,)) k=0 for x in self.app.app.app.db.fetchall(): x=list(x) t=[] flag=True self.app.app.app.db.execute('select name,edit,sum,parent,type from article where id=?',(x[0],)) s=self.app.app.app.db.fetchall()[0] par=s[3] t.append(s[0]) if s[4]=='stick':is_cat=True else:is_cat=False if par==-1: flag=0 while flag: self.app.app.app.db.execute('select name,parent from article where id=?',(par,)) rez=self.app.app.app.db.fetchall()[0] if rez[1]==-1: t.append(rez[0]) flag=False else: t.append(rez[0]) par=rez[1] cat_lst=' > '.join(t[::-1]) if is_cat: x[1]='' x[2]='[категория]' self.lst.insert(END,[cat_lst,x[1],x[2]]) k+=1 self.lab_var.set('Найдено %s совпадений'%(k))
class Main: def __init__(self, app): self.app = app self.cat_id = -1 self.init_add() self.init_tools() self.lst = MultiListbox(self.app.win, (('Время', 8), ('Отдел', 5), ('Товар', 60), ('Сумма', 5), ('Кол.во', 1), ('Итог', 5), ('Продавец', 12)), font=('bold', 13)) self.lst.pack(fill=BOTH, expand=1) self.update_list() self.build_tree() self.init_plugins() def init_add(self): """Верхняя панель с добавлением продажи """ self.add_f = LabelFrame(self.app.win, text='Продажа') self.add_f.pack(expand=YES, fill=X, anchor=N) self.init_deps() Style().configure("mini2.TButton", font=('bold', 11)) Style().configure("mini.TButton", font=('bold', 7)) self.cat_but = Button(self.add_f, style='mini.TButton', image=self.app.img['dep_db'], compound='top', text='Товары', command=self.cat_handler) self.cat_but.pack(side='left') Style().configure("TButton", font=('bold', 13)) self.clear_but = Button(self.add_f, image=self.app.img['clear'], compound='image', command=self.clear_handler) self.clear_but.pack(side='right') self.add_but = Button(self.add_f, text='Добавить', image=self.app.img['add'], compound='left', command=self.add_handler) self.add_but.pack(side='right') self.rate_v = Combobox(self.add_f, width=6, font=('bold', 16)) self.rate_v.set('1') self.rate_v.pack(side='right', padx=10) self.rate_v['values'] = range(1, 21) self.sum_ent = Entry(self.add_f, width=6, font=('bold', 20), cursor='xterm') self.sum_ent.pack(side='right') self.dep_name = Text(self.add_f, height=2, font=(15)) self.dep_name.pack(side='left', padx=10, fill=BOTH, pady=5) def init_deps(self): """Инициализация меню с отделами """ self.deps = [] self.app.db.execute('select name from dep') for n, name in enumerate(self.app.db.fetchall()): self.deps.append('%s %s' % (n + 1, name[0])) self.cur_dep = 0 self.dep_str = StringVar() self.dep_str.set(self.deps[0]) Style().configure("TMenubutton", font=('bold', 13)) self.otd = Menubutton(self.add_f, textvariable=self.dep_str, width=19, image=self.app.img['deps'], compound='left') self.otd.pack(pady=10, side='left', padx=10) self.otd.menu = Menu(self.otd, font=("bold", 13), bg='white', relief='flat', tearoff=0) for n, x in enumerate(self.deps): if len(x) > 3: self.otd.menu.add_command( label=x.ljust(25), command=lambda z=n: self.deps_hand(z)) self.otd['menu'] = self.otd.menu def deps_hand(self, n): """Вызывается при щелчке на отдел """ self.cur_dep = n self.dep_str.set(self.deps[n]) self.cat_id = -1 self.build_tree() def update_list(self): """ Обновляется список текущих продаж """ self.lst.delete(0, END) self.app.db.execute( 'select time,dep,article,sum,rate,name,art_id,edit from income where date=?', (date_now(), )) for x in self.app.db.fetchall(): out = list(x) if out[7] <> 0: out[1] = str(out[1]) + ' (≈)' if out[6] <> -1: out[1] = str(out[1]) + ' →' out.insert(5, round(x[3] * x[4], 2)) self.lst.insert(END, out) self.lst.see(END) def clear_handler(self): """ Вызывается при нажатии "очистить" """ self.dep_name['state'] = 'normal' self.sum_ent['state'] = 'normal' self.dep_name.delete(0.0, END) self.sum_ent.delete(0, END) self.rate_v.set('1') self.cat_id = -1 def add_handler(self): """ Добавление продажи """ try: razves = eval(self.app.sets.razves)[self.cur_dep] except AttributeError: razves = 0 try: sum = float(self.sum_ent.get().replace(',', '.')) except: box.showerror(title='Ошибка', message='Не верная сумма!') return try: if razves: rate = float(self.rate_v.get().replace(',', '.')) else: rate = int(self.rate_v.get().replace(',', '.')) except: box.showerror(title='Ошибка', message='Не верное количество!') return if sum <= 0: box.showerror(title='Ошибка', message='Не верная сумма!') return if rate <= 0: box.showerror(title='Ошибка', message='Не верное количество!') return txt = self.dep_name.get('0.0', END).replace('\r', '').replace( '\n', ' ').replace('\t', ' ') if self.cat_id <> -1: self.app.db.execute('select warning from dep where id=?', (int(self.cur_dep) + 1, )) k = self.app.db.fetchall()[0][0] if k > 0: self.app.db.execute('select rate from article where id=?', (self.cat_id, )) if self.app.db.fetchall()[0][0] - rate < 0: if k == 1: if not box.askyesno( title='Внимание!', message= 'Количества товара не достаточно для продажи.\nСохранить продажу все равно?' ): return else: box.showerror( title='Ошибка', message='Товара в наличии недостаточно для продажи' ) return dt, tm = date_now(), time_now() self.app.db.execute('insert into income values (?,?,?,?,?,?,?,?,0)', (dt, tm, int(self.cur_dep) + 1, txt, self.cat_id, sum, rate, self.app.user.decode('utf-8'))) if self.cat_id <> -1: self.app.db.execute('select rate from article where id=?', (self.cat_id, )) rate = self.app.db.fetchall()[0][0] - rate self.app.db.execute('update article set rate=? where id=?', ( rate, self.cat_id, )) self.app.con.commit() self.clear_handler() self.update_list() self.build_tree() self.update_tools() self.init_add_plugins(dt, tm) def build_tree(self): """ Рекурсивное построение дерева товаров """ self.popup = Menu(self.app.win, tearoff=0, font=('normal', 12)) def get_menu(id): self.app.db.execute( 'select id,name,type from article where dep=? and parent=? order by name', ( self.cur_dep + 1, id, )) popup = Menu(self.app.win, tearoff=0, font=('normal', 12)) for x in self.app.db.fetchall(): if x[2] == 'item': popup.add_command( label=x[1], command=lambda z=x[0]: self.command_handler(z)) else: popup.add_cascade(label=x[1], menu=get_menu(x[0])) return popup # Сначала проходимся по товарам в корне self.app.db.execute( 'select id,name,type from article where dep=? and parent=-1 order by name', (self.cur_dep + 1, )) for x in self.app.db.fetchall(): if x[2] == 'item': self.popup.add_command( label=x[1], command=lambda z=x[0]: self.command_handler(z)) else: self.popup.add_cascade(label=x[1], menu=get_menu(x[0])) def command_handler(self, id): """ Вызывается при щелчке на наименование товара """ self.cat_id = id t = [] flag = True # строится полное название товара, включая подкатегории self.app.db.execute( 'select name,edit,sum,parent from article where id=?', (id, )) s = self.app.db.fetchall()[0] par = s[3] t.append(s[0]) if par == -1: flag = 0 while flag: self.app.db.execute('select name,parent from article where id=?', (par, )) rez = self.app.db.fetchall()[0] if rez[1] == -1: t.append(rez[0]) flag = False else: t.append(rez[0]) par = rez[1] # и заполняются поля в продаже cat_lst = ' > '.join(t[::-1]) self.dep_name['state'] = 'normal' self.dep_name.delete(0.0, END) self.dep_name.insert(0.0, cat_lst) if s[1] == 0: self.dep_name['state'] = 'disable' self.sum_ent['state'] = 'normal' self.sum_ent.delete(0, END) self.sum_ent.insert(0, s[2]) if s[1] == 0: self.sum_ent['state'] = 'disable' def cat_handler(self): self.popup.tk_popup(self.cat_but.winfo_rootx() + 30, self.cat_but.winfo_rooty() + 55, 0) def init_tools(self): """ Формируется нижняя панель с подитогом """ self.tools_f = Frame(self.app.win) self.tools_f.pack(fill=BOTH, side='bottom', expand=1) self.k = LabelFrame(self.tools_f, text='Подитог') self.k.pack(side='left') self.income_all = StringVar() self.income_all.set('Доход') self.outcome_all = StringVar() self.outcome_all.set('Расход') self.all_all = StringVar() self.all_all.set('Остаток') Label(self.k, textvariable=self.income_all, font=('bold', 12)).grid(row=0, column=0, columnspan=2, sticky=NW) Label(self.k, textvariable=self.outcome_all, font=('bold', 12)).grid(row=1, column=0, columnspan=2, sticky=NW) Label(self.k, textvariable=self.all_all, font=('bold', 12)).grid(row=2, column=0, columnspan=2, sticky=NW) self.scr1 = Scrollbar(self.k, orient=VERTICAL) self.scr1.grid(row=3, column=1, sticky=N + S) self.list_1 = Listbox(self.k, width=30, height=5, font=("Arial", 10, "bold"), yscrollcommand=self.scr1.set) self.list_1.grid(row=3, column=0) self.scr1['command'] = self.list_1.yview self.update_tools() def update_tools(self): """ Считается подитог """ deps = {} deps_sum = {} self.app.db.execute('select name from dep') for n, name in enumerate(self.app.db.fetchall()): if name: deps_sum[n + 1] = 0 self.app.db.execute('select dep,sum,rate from income where date=?', (date_now(), )) out = self.app.db.fetchall() in_all = 0 for x in out: in_all += float(x[1]) * float(x[2]) deps_sum[x[0]] += float(x[1]) * float(x[2]) self.income_all.set('Доход: %s' % (in_all)) self.list_1.delete(0, END) for x in deps_sum: if deps_sum[x]: self.list_1.insert(END, self.deps[x - 1] + u'→ ' + str(deps_sum[x])) self.app.db.execute('select sum from outcome where date=?', (date_now(), )) out = self.app.db.fetchall() out_all = 0 for x in out: out_all += float(x[0]) self.outcome_all.set('Расход: %s' % (out_all)) self.all_all.set('Остаток: %s' % (in_all - out_all)) def init_plugins(self): """ Панель с плагинами """ self.plugin_list = [] self.t_plugins_frame = LabelFrame(self.tools_f, text='Действия') self.t_plugins_frame.pack(fill=BOTH, side='left', expand=1) self.nb = Notebook(self.t_plugins_frame) self.nb.pack(fill=BOTH, expand=1, pady=5) self.plugins_frame = range(3) # 3 вкладки imgs = ['sale', 'dep_db', 'misc'] for x, name in enumerate(['Продажи', 'Товар', 'Прочее']): self.plugins_frame[x] = Frame(self.t_plugins_frame) self.plugins_frame[x].pack(fill=BOTH, side='left', expand=1) self.nb.add(self.plugins_frame[x], text=name, padding=3, image=self.app.img[imgs[x]], compound='left') self.end_frame = Frame(self.tools_f) self.end_frame.pack(side='left') self.end_button = Button(self.tools_f, style='mini.TButton', text=' Сменить\nпользователя', image=self.app.img['people'], compound='top', command=self.app.change_user, cursor='hand2') self.end_button.pack(side='bottom', pady=10, padx=5) self.app.db.execute('select caps from users where name=?', (self.app.user.decode('utf-8'), )) caps = eval(self.app.db.fetchall()[0][0]) # тут начинается самое интересное :) s = os.listdir('app/plugins/frames') row = [0, 0, 0] column = [0, 0, 0] self.pl_buttons = {} for x in s: if x.endswith('.py'): # испортируем, и получаем имя, название иконки, номер вкладки obj = __import__(x[:-3]) name = getattr(obj, 'name') fr = getattr(obj, 'frame') self.plugin_list.append(name) if hasattr(obj, 'icon'): icon = getattr(obj, 'icon') else: icon = 'plugins' # проверяем, есть ли допуск юзера к плагину, или "Администратор" if name in caps or self.app.user == 'Администратор': # собственно добавляем кнопку self.pl_buttons[(row[fr], column[fr])] = Button( self.plugins_frame[fr], text=name.ljust(100), style='mini2.TButton', image=self.app.img[icon], compound='left', width=23) self.pl_buttons[(row[fr], column[fr])].grid(row=row[fr], column=column[fr], sticky=NW, padx=5, pady=2) self.pl_buttons[( row[fr], column[fr] )]['command'] = lambda pl=obj: self.show_plugin(pl) column[fr] = column[fr] + 1 if column[fr] > 2: column[fr] = 0 row[fr] = row[fr] + 1 def show_plugin(self, obj): """ Вызывается при нажитию на кнопку плагина. Запускаем метод run плагина """ cl = getattr(obj, 'Plugin')(self) cl.run() def init_add_plugins(self, dt, tm): """ Вызывается после добавления """ s = os.listdir('app/plugins/income') for x in s: if x.endswith('.py'): obj = __import__(x[:-3]) cl = getattr(obj, 'Plugin')(self, dt, tm)
class Plugin: def __init__(self, app): self.app = app def run(self): self.win = Toplevel(self.app.app.win) self.win.title(name) x, y = 800, 350 pos = self.win.wm_maxsize()[0] / 2 - x / 2, self.win.wm_maxsize( )[1] / 2 - y / 2 self.win.geometry('%sx%s+%s+%s' % (x, y, pos[0], pos[1] - 25)) self.win.maxsize(width=x, height=y) self.win.minsize(width=x, height=y) if sys.platform == 'win32': self.win.iconbitmap('app/images/icon.ico') self.cur_list = [] self.add_f = LabelFrame(self.win, text='Товар') self.add_f.pack(expand=YES, fill=X, anchor=N) self.init_add() self.lst = MultiListbox(self.win, (('Отдел', 3), ('Товар', 60), ('Количество', 3)), font=('normal', 12)) self.lst.pack(fill=BOTH, expand=1, padx=5) def init_add(self): """ фрейм с добавлением товара """ self.init_deps() self.cat_but = Button(self.add_f, style='mini.TButton', image=self.app.app.img['dep_db'], compound='top', text='Товар', command=self.cat_handler) self.cat_but.pack(side='left') self.add_but = Button(self.add_f, text='Добавить', image=self.app.app.img['add'], compound='left', command=self.add_handler) self.add_but.pack(side='right') self.rate_v = Combobox(self.add_f, width=6, font=('bold', 16)) self.rate_v.set('1') self.rate_v.pack(side='right', padx=10) self.rate_v['values'] = range(1, 21) self.dep_name = Text(self.add_f, height=2, font=(15)) self.dep_name.pack(side='left', padx=10, fill=BOTH, pady=5) self.dep_name['state'] = 'disable' self.build_tree() self.tools_f = Frame(self.win) self.tools_f.pack(fill=BOTH, side='bottom', expand=1) self.del_but = Button(self.tools_f, text='Удалить текущий', image=self.app.app.img['delete'], compound='left', command=self.del_handler) self.del_but.pack(side='left', padx=15, pady=10) self.save_but = Button(self.tools_f, text='Сохранить приход', image=self.app.app.img['save'], compound='left', command=self.save_all) self.save_but.pack(side='right', padx=15, pady=10) self.lab_var = StringVar() self.lab_var.set('Позиций: 0 шт.\n Товара: 0 шт.') Label(self.tools_f, textvariable=self.lab_var, font=('normal', 12)).pack(side='top') def init_deps(self): """ меню с отделами """ self.deps = [] self.app.app.db.execute('select name from dep') for n, name in enumerate(self.app.app.db.fetchall()): self.deps.append('%s %s' % (n + 1, name[0])) self.cur_dep = 0 self.dep_str = StringVar() self.dep_str.set(self.deps[0]) Style().configure("TMenubutton", font=('bold', 13)) self.otd = Menubutton(self.add_f, textvariable=self.dep_str, width=19, image=self.app.app.img['deps'], compound='left') self.otd.pack(pady=10, side='left', padx=10) self.otd.menu = Menu(self.otd, font=("bold", 13), bg='white', relief='flat', tearoff=0) for n, x in enumerate(self.deps): if len(x) > 3: self.otd.menu.add_command( label=x.ljust(25), command=lambda z=n: self.deps_hand(z)) self.otd['menu'] = self.otd.menu def deps_hand(self, n): """ вызывается при смене отдела """ self.cur_dep = n self.dep_str.set(self.deps[n]) self.cat_id = -1 self.build_tree() def build_tree(self): """ построение дерева товаров """ self.popup = Menu(self.win, tearoff=0, font=('normal', 12)) def get_menu(id): self.app.app.db.execute( 'select id,name,type from article where dep=? and parent=? order by name', ( self.cur_dep + 1, id, )) popup = Menu(self.win, tearoff=0, font=('normal', 12)) for x in self.app.app.db.fetchall(): if x[2] == 'item': popup.add_command( label=x[1], command=lambda z=x[0]: self.command_handler(z)) else: popup.add_cascade(label=x[1], menu=get_menu(x[0])) return popup self.app.app.db.execute( 'select id,name,type from article where dep=? and parent=-1 order by name', (self.cur_dep + 1, )) for x in self.app.app.db.fetchall(): if x[2] == 'item': self.popup.add_command( label=x[1], command=lambda z=x[0]: self.command_handler(z)) else: self.popup.add_cascade(label=x[1], menu=get_menu(x[0])) def cat_handler(self): self.popup.tk_popup(self.cat_but.winfo_rootx() + 30, self.cat_but.winfo_rooty() + 55, 0) def command_handler(self, id): """ при щелчке на товар """ self.cat_id = id t = [] flag = True self.app.app.db.execute( 'select name,edit,sum,parent from article where id=?', (id, )) s = self.app.app.db.fetchall()[0] par = s[3] t.append(s[0]) if par == -1: flag = 0 # построение длинного названия товара, включая подкатегории while flag: self.app.app.db.execute( 'select name,parent from article where id=?', (par, )) rez = self.app.app.db.fetchall()[0] if rez[1] == -1: t.append(rez[0]) flag = False else: t.append(rez[0]) par = rez[1] cat_lst = ' > '.join(t[::-1]) self.dep_name['state'] = 'normal' self.dep_name.delete(0.0, END) self.dep_name.insert(0.0, cat_lst) self.dep_name['state'] = 'disable' def add_handler(self): """ добавление товара во временный список """ txt = self.dep_name.get('0.0', END).replace('\r', '').replace( '\n', ' ').replace('\t', ' ') try: razves = eval(self.app.app.sets.razves)[self.cur_dep] except AttributeError: razves = 0 if len(txt) < 2: box.showerror(title='Ошибка', message='Не выбран товар!') self.win.deiconify() return try: if razves: rate = float(self.rate_v.get().replace(',', '.')) else: rate = int(self.rate_v.get().replace(',', '.')) except: box.showerror(title='Ошибка', message='Не верное количество!') self.win.deiconify() return if rate <= 0: box.showerror(title='Ошибка', message='Не верное количество!') self.win.deiconify() return self.cur_list.append([self.cur_dep + 1, txt, rate, self.cat_id]) self.update_list() self.dep_name['state'] = 'normal' self.dep_name.delete(0.0, END) self.dep_name['state'] = 'disable' self.rate_v.set('1') def update_list(self): """ обновление таблицы со списком прихода """ self.lst.delete(0, END) for x in self.cur_list: self.lst.insert(END, x) self.lst.see(END) s1 = len(self.cur_list) s2 = 0 for x in self.cur_list: s2 += x[2] self.lab_var.set('Позиций: %s шт.\n Товара: %s шт.' % (s1, s2)) def del_handler(self): """ удаление товара из временного списка """ sel = self.lst.curselection() if not sel: return sel = int(sel[0]) del self.cur_list[sel] self.update_list() def save_all(self): """ Сохрание прихода и записть в таблицу приходов """ date = date_now() tm = time_now() user = self.app.app.user.decode('utf-8') self.app.app.db.execute('select max(id) from in_art') try: id = self.app.app.db.fetchall()[0][0] + 1 except: id = 1 for x in self.cur_list: self.app.app.db.execute( 'insert into in_art values (?,?,?,?,?,?,?)', (id, date, tm, x[0], x[1], x[2], user)) self.app.app.db.execute('select rate from article where id=?', (x[3], )) rate = self.app.app.db.fetchall()[0][0] + x[2] self.app.app.db.execute('update article set rate=? where id=?', (rate, x[3])) self.app.app.con.commit() self.win.destroy()
class Plugin: def __init__(self,app): self.app=app def run(self): self.win=Toplevel(self.app.app.win) self.win.title(name) x,y=800,450 pos=self.win.wm_maxsize()[0]/2-x/2,self.win.wm_maxsize()[1]/2-y/2 self.win.geometry('%sx%s+%s+%s'%(x,y,pos[0],pos[1]-25)) self.win.maxsize(width=x,height=y) self.win.minsize(width=x,height=y) if sys.platform=='win32':self.win.iconbitmap('app/images/icon.ico') year,month = time.localtime()[0:2] self.date_t=StringVar() self.date_t.set(date_now()) self.c_date=date_now() self.cal=TkCalendar(self.win,year, month, self.date_t,command=self.calend_handler) self.cal.grid(row=0,column=0,padx=5,pady=10,sticky=N) self.content_frame=Frame(self.win) self.content_frame.grid(row=0,column=1,rowspan=3,sticky=N) self.tool_frame=Frame(self.win) self.tool_frame.grid(row=1,column=0,sticky=N+W) Label(self.content_frame,text='Список:',font=('normal',12)).pack(fill=BOTH) self.lst=MultiListbox(self.content_frame, (('Дата', 10), ('Время', 9), ('Действие', 45)),font=('normal',12),height=15,command=self.command_handler) self.lst.pack(fill=BOTH,expand=1) Label(self.content_frame,text='Правка:',font=('normal',12)).pack(fill=BOTH) self.scroll = Scrollbar(self.content_frame) self.txt=Text(self.content_frame,width=68,height=5,font=('normal',12)) self.scroll.pack(side=RIGHT, fill=Y) self.txt.pack(side=LEFT, fill=Y) self.scroll.config(command=self.txt.yview) self.txt.config(yscrollcommand=self.scroll.set) s='За дату: %s'%('.'.join(date_now().split('-')[::-1])) self.d_label=Label(self.tool_frame,text=s,font=('bold',12)) self.d_label.grid(row=0,columnspan=2,sticky=N+W) self.all_button=Button(self.tool_frame,text='Смотреть все',command=self.show_all,width=15) self.all_button.grid(row=1,column=0,sticky=N,pady=5) self.update_lists() def calend_handler(self,date): """при выборе даты """ self.c_date=date self.update_lists() self.txt.delete(0.0,END) def update_lists(self): """ обновляем списки """ self.all_data=[] self.lst.delete(0,END) if self.c_date=='Все': self.app.app.db.execute('select date,time,title,event from edit_log') else:self.app.app.db.execute('select date,time,title,event from edit_log where date=?',(self.c_date,)) for x in self.app.app.db.fetchall(): x=list(x) x[0]=norm_date(x[0]) self.lst.insert(END,x) self.all_data.append(x) self.lst.see(END) if self.c_date=='Все': self.d_label['text']='За дату: ВСЕ' else: s='За дату: %s'%(norm_date(self.c_date)) self.d_label['text']=s def command_handler(self): """ при выборе пункта в таблице, показываем полный текст изменения """ if not self.lst.curselection():return c=int(self.lst.curselection()[0]) txt=self.all_data[c][3] self.txt.delete(0.0,END) self.txt.insert(0.0,txt) def show_all(self): """ по кнопке "смотреть все" """ self.c_date='Все' self.update_lists() self.txt.delete(0.0,END)
class Plugin: def __init__(self, app): self.app = app def run(self): self.win = Toplevel(self.app.app.win) self.win.title(name) x, y = 600, 500 pos = self.win.wm_maxsize()[0] / 2 - x / 2, self.win.wm_maxsize( )[1] / 2 - y / 2 self.win.geometry('%sx%s+%s+%s' % (x, y, pos[0], pos[1] - 25)) self.win.maxsize(width=x, height=y) self.win.minsize(width=x, height=y) if sys.platform == 'win32': self.win.iconbitmap('app/images/icon.ico') self.add_f = LabelFrame(self.win, text='Остатки товара по отделу...') self.add_f.pack(expand=YES, fill=X, anchor=N, padx=5, pady=5) self.init_deps() self.rb_var = IntVar() self.rb = Radiobutton(self.add_f, text='Показать все', value=0, variable=self.rb_var, command=self.callback) self.rb.grid(row=0, column=1, sticky=W, padx=5, pady=5) self.rb2 = Radiobutton(self.add_f, text='Показать меньше ', value=1, variable=self.rb_var, command=self.callback) self.rb2.grid(row=0, column=2, sticky=W, padx=5, pady=5) self.rate_ent = Entry(self.add_f, width=5, cursor='xterm') self.rate_ent.grid(row=0, column=3) self.rate_ent.insert(END, '3') self.rate_ent.bind('<KeyRelease>', self.callback1) self.lst = MultiListbox(self.win, (('Товар', 50), ('Остаток', 5), ('Стоимость', 6)), font=('normal', 11), height=19) self.lst.pack(fill=BOTH, expand=1, padx=5, pady=5) self.lab_var = StringVar() self.all_label = Label(self.win, textvariable=self.lab_var, font=('bold', 12)) self.all_label.pack(padx=5) self.pdf_but = Button(self.win, text='В pdf', image=self.app.app.img['pdf'], compound='left', command=self.generate_pdf) self.pdf_but.pack(side='left', padx=5, pady=5, anchor=W) self.csv_but = Button(self.win, text='В csv', image=self.app.app.img['csv'], compound='left', command=self.generate_csv) self.csv_but.pack(side='left', padx=5, pady=5, anchor=W) self.callback() def init_deps(self): """ меня с отделами, как мне надоело это писать """ self.deps = [] self.app.app.db.execute('select name from dep') for n, name in enumerate(self.app.app.db.fetchall()): self.deps.append('%s %s' % (n + 1, name[0])) self.cur_dep = 0 self.dep_str = StringVar() self.dep_str.set(self.deps[0]) Style().configure("TMenubutton", font=('bold', 13)) self.otd = Menubutton(self.add_f, textvariable=self.dep_str, width=19, image=self.app.app.img['deps'], compound='left') self.otd.grid(row=0, column=0, pady=5, padx=5) self.otd.menu = Menu(self.otd, font=("bold", 13), bg='white', relief='flat', tearoff=0) for n, x in enumerate(self.deps): if len(x) > 3: self.otd.menu.add_command( label=x.ljust(25), command=lambda z=n: self.deps_hand(z)) self.otd['menu'] = self.otd.menu def deps_hand(self, n): """ вызывается при выборе отдела """ self.cur_dep = n self.dep_str.set(self.deps[n]) self.cat_id = -1 self.callback() def callback1(self, event=None): """ при смене количества """ self.rb_var.set(1) self.callback() def callback(self, event=None): """ при смене чекбатонна, заполняем таблицу заново """ self.lst.delete(0, END) r = self.rb_var.get() rate = self.rate_ent.get() if r == 0: self.app.app.db.execute( 'select id,rate,sum,type from article where dep=?', (self.cur_dep + 1, )) else: try: rate = int(rate) except: return self.app.app.db.execute( 'select id,rate,sum,type from article where dep=? and rate<?', (self.cur_dep + 1, rate)) rez1 = self.app.app.db.fetchall() all_rate = 0 all_sum = 0 for x in rez1: t = [] flag = True self.app.app.db.execute( 'select name,edit,sum,parent from article where id=?', (x[0], )) s = self.app.app.db.fetchall()[0] par = s[3] t.append(s[0]) if par == -1: flag = 0 while flag: self.app.app.db.execute( 'select name,parent from article where id=?', (par, )) rez = self.app.app.db.fetchall()[0] if rez[1] == -1: t.append(rez[0]) flag = False else: t.append(rez[0]) par = rez[1] cat_lst = ' > '.join(t[::-1]) if x[3] == 'item': self.lst.insert(END, [cat_lst, x[1], x[2]]) all_rate += x[1] all_sum += x[1] * x[2] self.lab_var.set('Наименований: %s, количество: %s, на сумму %s' % (len(rez1), all_rate, all_sum)) def generate_pdf(self): """ генерация pdf """ try: path = self.app.app.sets.save_pdf except: path = '' filename = 'Остатки по отделу %s на %s.pdf' % (self.cur_dep + 1, norm_date(date_now())) f = tkFileDialog.asksaveasfilename(initialdir=path, initialfile=filename) if not f: return f = f.replace('\\', '/') self.app.app.sets.save_pdf = '/'.join(f.split('/')[:-1]) doc = pdf.Pdf(title='Остатки товара', fname=f) r = self.rb_var.get() rate = self.rate_ent.get() self.app.app.db.execute('select name from dep where id=?', (self.cur_dep + 1, )) dep_name = self.app.app.db.fetchall()[0][0] if r == 0: self.app.app.db.execute( 'select id,rate,sum,type from article where dep=?', (self.cur_dep + 1, )) doc.string(u'Все остатки по отделу %s %s' % (self.cur_dep + 1, dep_name)) else: try: rate = int(rate) except: return self.app.app.db.execute( 'select id,rate,sum,type from article where dep=? and rate<?', (self.cur_dep + 1, rate)) doc.string( u'Остатки по отделу %s %s, количество товара меньше %s' % (self.cur_dep + 1, dep_name, rate)) rez1 = self.app.app.db.fetchall() all_rate = 0 all_sum = 0 doc.table([('Товар', 300), ('Остаток', 80), ('Стоимость', 80)]) for x in rez1: t = [] flag = True self.app.app.db.execute( 'select name,edit,sum,parent from article where id=?', (x[0], )) s = self.app.app.db.fetchall()[0] par = s[3] t.append(s[0]) if par == -1: flag = 0 while flag: self.app.app.db.execute( 'select name,parent from article where id=?', (par, )) rez = self.app.app.db.fetchall()[0] if rez[1] == -1: t.append(rez[0]) flag = False else: t.append(rez[0]) par = rez[1] cat_lst = ' > '.join(t[::-1]) if x[3] == 'item': doc.table([(cat_lst, 300), (x[1], 80), (x[2], 80)], font=10) all_rate += x[1] all_sum += x[1] * x[2] self.lab_var.set('Наименований: %s, количество: %s, на сумму %s' % (len(rez1), all_rate, all_sum)) doc.enter() doc.string('Всего наименований: %s' % (len(rez1))) doc.string('Всего количество: %s, на сумму %s' % (all_rate, all_sum)) doc.end() self.win.deiconify() def generate_csv(self): """ генерация csv """ try: path = self.app.app.sets.save_pdf except: path = '' filename = 'Остатки по отделу %s на %s.csv' % (self.cur_dep + 1, norm_date(date_now())) f = tkFileDialog.asksaveasfilename(initialdir=path, initialfile=filename) if not f: return f = f.replace('\\', '/') self.app.app.sets.save_pdf = '/'.join(f.split('/')[:-1]) doc = csv.writer(open(f, 'w'), delimiter=';', lineterminator='\n', quoting=csv.QUOTE_ALL) doc.writerow([ u'Товар'.encode('cp1251'), u'Остаток'.encode('cp1251'), u'Стоимость'.encode('cp1251') ]) r = self.rb_var.get() rate = self.rate_ent.get() self.app.app.db.execute('select name from dep where id=?', (self.cur_dep + 1, )) dep_name = self.app.app.db.fetchall()[0][0] if r == 0: self.app.app.db.execute( 'select id,rate,sum,type from article where dep=?', (self.cur_dep + 1, )) else: try: rate = int(rate) except: return self.app.app.db.execute( 'select id,rate,sum,type from article where dep=? and rate<?', (self.cur_dep + 1, rate)) rez1 = self.app.app.db.fetchall() all_rate = 0 all_sum = 0 for x in rez1: t = [] flag = True self.app.app.db.execute( 'select name,edit,sum,parent from article where id=?', (x[0], )) s = self.app.app.db.fetchall()[0] par = s[3] t.append(s[0]) if par == -1: flag = 0 while flag: self.app.app.db.execute( 'select name,parent from article where id=?', (par, )) rez = self.app.app.db.fetchall()[0] if rez[1] == -1: t.append(rez[0]) flag = False else: t.append(rez[0]) par = rez[1] cat_lst = ' > '.join(t[::-1]) if x[3] == 'item': doc.writerow([cat_lst.encode('cp1251'), x[1], x[2]]) all_rate += x[1] all_sum += x[1] * x[2] self.lab_var.set('Наименований: %s, количество: %s, на сумму %s' % (len(rez1), all_rate, all_sum)) self.win.deiconify()
class Plugin: def __init__(self, app): self.app = app def run(self): self.win = Toplevel(self.app.app.win) self.win.title(name) x, y = 800, 450 pos = self.win.wm_maxsize()[0] / 2 - x / 2, self.win.wm_maxsize( )[1] / 2 - y / 2 self.win.geometry('%sx%s+%s+%s' % (x, y, pos[0], pos[1] - 25)) self.win.maxsize(width=x, height=y) self.win.minsize(width=x, height=y) if sys.platform == 'win32': self.win.iconbitmap('app/images/icon.ico') year, month = time.localtime()[0:2] self.date_t = StringVar() self.date_t.set(date_now()) self.c_date = date_now() self.cal = TkCalendar(self.win, year, month, self.date_t, command=self.calend_handler) self.cal.grid(row=0, column=0, padx=5, pady=10, sticky=N) self.content_frame = Frame(self.win) self.content_frame.grid(row=0, column=1, rowspan=3, sticky=N) self.tool_frame = Frame(self.win) self.tool_frame.grid(row=1, column=0, sticky=N + W) Label(self.content_frame, text='Список:', font=('normal', 12)).pack(fill=BOTH) self.lst = MultiListbox(self.content_frame, (('Дата', 10), ('Время', 9), ('Действие', 45)), font=('normal', 12), height=15, command=self.command_handler) self.lst.pack(fill=BOTH, expand=1) Label(self.content_frame, text='Правка:', font=('normal', 12)).pack(fill=BOTH) self.scroll = Scrollbar(self.content_frame) self.txt = Text(self.content_frame, width=68, height=5, font=('normal', 12)) self.scroll.pack(side=RIGHT, fill=Y) self.txt.pack(side=LEFT, fill=Y) self.scroll.config(command=self.txt.yview) self.txt.config(yscrollcommand=self.scroll.set) s = 'За дату: %s' % ('.'.join(date_now().split('-')[::-1])) self.d_label = Label(self.tool_frame, text=s, font=('bold', 12)) self.d_label.grid(row=0, columnspan=2, sticky=N + W) self.all_button = Button(self.tool_frame, text='Смотреть все', command=self.show_all, width=15) self.all_button.grid(row=1, column=0, sticky=N, pady=5) self.update_lists() def calend_handler(self, date): """при выборе даты """ self.c_date = date self.update_lists() self.txt.delete(0.0, END) def update_lists(self): """ обновляем списки """ self.all_data = [] self.lst.delete(0, END) if self.c_date == 'Все': self.app.app.db.execute( 'select date,time,title,event from edit_log') else: self.app.app.db.execute( 'select date,time,title,event from edit_log where date=?', (self.c_date, )) for x in self.app.app.db.fetchall(): x = list(x) x[0] = norm_date(x[0]) self.lst.insert(END, x) self.all_data.append(x) self.lst.see(END) if self.c_date == 'Все': self.d_label['text'] = 'За дату: ВСЕ' else: s = 'За дату: %s' % (norm_date(self.c_date)) self.d_label['text'] = s def command_handler(self): """ при выборе пункта в таблице, показываем полный текст изменения """ if not self.lst.curselection(): return c = int(self.lst.curselection()[0]) txt = self.all_data[c][3] self.txt.delete(0.0, END) self.txt.insert(0.0, txt) def show_all(self): """ по кнопке "смотреть все" """ self.c_date = 'Все' self.update_lists() self.txt.delete(0.0, END)
class Main: def __init__(self,app): self.app=app self.cat_id=-1 self.init_add() self.init_tools() self.lst=MultiListbox(self.app.win, (('Время', 8), ('Отдел', 5), ('Товар', 60),('Сумма',5),('Кол.во',1),('Итог',5),('Продавец',12)),font=('bold',13)) self.lst.pack(fill=BOTH,expand=1) self.update_list() self.build_tree() self.init_plugins() def init_add(self): """Верхняя панель с добавлением продажи """ self.add_f=LabelFrame(self.app.win,text='Продажа') self.add_f.pack(expand=YES,fill=X,anchor=N) self.init_deps() Style().configure("mini2.TButton",font=('bold',11)) Style().configure("mini.TButton",font=('bold',7)) self.cat_but=Button(self.add_f,style='mini.TButton',image=self.app.img['dep_db'],compound='top',text='Товары',command=self.cat_handler) self.cat_but.pack(side='left') Style().configure("TButton",font=('bold',13)) self.clear_but=Button(self.add_f,image=self.app.img['clear'],compound='image',command=self.clear_handler) self.clear_but.pack(side='right') self.add_but=Button(self.add_f,text='Добавить',image=self.app.img['add'],compound='left',command=self.add_handler) self.add_but.pack(side='right') self.rate_v=Combobox(self.add_f,width=6,font=('bold',16)) self.rate_v.set('1') self.rate_v.pack(side='right',padx=10) self.rate_v['values']=range(1,21) self.sum_ent=Entry(self.add_f,width=6,font=('bold',20),cursor='xterm') self.sum_ent.pack(side='right') self.dep_name=Text(self.add_f,height=2,font=(15)) self.dep_name.pack(side='left',padx=10,fill=BOTH,pady=5) def init_deps(self): """Инициализация меню с отделами """ self.deps=[] self.app.db.execute('select name from dep') for n,name in enumerate(self.app.db.fetchall()): self.deps.append('%s %s'%(n+1,name[0])) self.cur_dep=0 self.dep_str=StringVar() self.dep_str.set(self.deps[0]) Style().configure("TMenubutton",font=('bold',13)) self.otd=Menubutton(self.add_f,textvariable=self.dep_str, width=19,image=self.app.img['deps'],compound='left') self.otd.pack(pady=10,side='left',padx=10) self.otd.menu=Menu(self.otd, font=("bold",13),bg='white',relief='flat', tearoff=0) for n,x in enumerate(self.deps): if len(x)>3: self.otd.menu.add_command(label=x.ljust(25),command=lambda z=n:self.deps_hand(z)) self.otd['menu']=self.otd.menu def deps_hand(self,n): """Вызывается при щелчке на отдел """ self.cur_dep=n self.dep_str.set(self.deps[n]) self.cat_id=-1 self.build_tree() def update_list(self): """ Обновляется список текущих продаж """ self.lst.delete(0,END) self.app.db.execute('select time,dep,article,sum,rate,name,art_id,edit from income where date=?',(date_now(),)) for x in self.app.db.fetchall(): out=list(x) if out[7]<>0: out[1]=str(out[1])+' (≈)' if out[6]<>-1: out[1]=str(out[1])+' →' out.insert(5,round(x[3]*x[4],2)) self.lst.insert(END,out) self.lst.see(END) def clear_handler(self): """ Вызывается при нажатии "очистить" """ self.dep_name['state']='normal' self.sum_ent['state']='normal' self.dep_name.delete(0.0,END) self.sum_ent.delete(0,END) self.rate_v.set('1') self.cat_id=-1 def add_handler(self): """ Добавление продажи """ try:razves=eval(self.app.sets.razves)[self.cur_dep] except AttributeError:razves=0 try:sum=float(self.sum_ent.get().replace(',','.')) except: box.showerror(title='Ошибка',message='Не верная сумма!') return try: if razves: rate=float(self.rate_v.get().replace(',','.')) else: rate=int(self.rate_v.get().replace(',','.')) except: box.showerror(title='Ошибка',message='Не верное количество!') return if sum<=0: box.showerror(title='Ошибка',message='Не верная сумма!') return if rate<=0: box.showerror(title='Ошибка',message='Не верное количество!') return txt=self.dep_name.get('0.0',END).replace('\r','').replace('\n',' ').replace('\t',' ') if self.cat_id<>-1: self.app.db.execute('select warning from dep where id=?',(int(self.cur_dep)+1,)) k=self.app.db.fetchall()[0][0] if k>0: self.app.db.execute('select rate from article where id=?',(self.cat_id,)) if self.app.db.fetchall()[0][0]-rate<0: if k==1: if not box.askyesno(title='Внимание!',message='Количества товара не достаточно для продажи.\nСохранить продажу все равно?'):return else: box.showerror(title='Ошибка',message='Товара в наличии недостаточно для продажи') return dt,tm=date_now(),time_now() self.app.db.execute('insert into income values (?,?,?,?,?,?,?,?,0)',(dt,tm,int(self.cur_dep)+1,txt,self.cat_id,sum,rate,self.app.user.decode('utf-8'))) if self.cat_id<>-1: self.app.db.execute('select rate from article where id=?',(self.cat_id,)) rate=self.app.db.fetchall()[0][0]-rate self.app.db.execute('update article set rate=? where id=?',(rate,self.cat_id,)) self.app.con.commit() self.clear_handler() self.update_list() self.build_tree() self.update_tools() self.init_add_plugins(dt,tm) def build_tree(self): """ Рекурсивное построение дерева товаров """ self.popup = Menu(self.app.win, tearoff=0,font=('normal',12)) def get_menu(id): self.app.db.execute('select id,name,type from article where dep=? and parent=? order by name',(self.cur_dep+1,id,)) popup = Menu(self.app.win, tearoff=0,font=('normal',12)) for x in self.app.db.fetchall(): if x[2]=='item': popup.add_command(label=x[1],command=lambda z=x[0]:self.command_handler(z)) else:popup.add_cascade(label=x[1],menu=get_menu(x[0])) return popup # Сначала проходимся по товарам в корне self.app.db.execute('select id,name,type from article where dep=? and parent=-1 order by name',(self.cur_dep+1,)) for x in self.app.db.fetchall(): if x[2]=='item': self.popup.add_command(label=x[1],command=lambda z=x[0]:self.command_handler(z)) else: self.popup.add_cascade(label=x[1],menu=get_menu(x[0])) def command_handler(self,id): """ Вызывается при щелчке на наименование товара """ self.cat_id=id t=[] flag=True # строится полное название товара, включая подкатегории self.app.db.execute('select name,edit,sum,parent from article where id=?',(id,)) s=self.app.db.fetchall()[0] par=s[3] t.append(s[0]) if par==-1:flag=0 while flag: self.app.db.execute('select name,parent from article where id=?',(par,)) rez=self.app.db.fetchall()[0] if rez[1]==-1: t.append(rez[0]) flag=False else: t.append(rez[0]) par=rez[1] # и заполняются поля в продаже cat_lst=' > '.join(t[::-1]) self.dep_name['state']='normal' self.dep_name.delete(0.0,END) self.dep_name.insert(0.0,cat_lst) if s[1]==0:self.dep_name['state']='disable' self.sum_ent['state']='normal' self.sum_ent.delete(0,END) self.sum_ent.insert(0,s[2]) if s[1]==0:self.sum_ent['state']='disable' def cat_handler(self): self.popup.tk_popup(self.cat_but.winfo_rootx()+30, self.cat_but.winfo_rooty()+55, 0) def init_tools(self): """ Формируется нижняя панель с подитогом """ self.tools_f=Frame(self.app.win) self.tools_f.pack(fill=BOTH,side='bottom',expand=1) self.k=LabelFrame(self.tools_f,text='Подитог') self.k.pack(side='left') self.income_all=StringVar() self.income_all.set('Доход') self.outcome_all=StringVar() self.outcome_all.set('Расход') self.all_all=StringVar() self.all_all.set('Остаток') Label(self.k,textvariable=self.income_all,font=('bold',12)).grid(row=0,column=0,columnspan=2,sticky=NW) Label(self.k,textvariable=self.outcome_all,font=('bold',12)).grid(row=1,column=0,columnspan=2,sticky=NW) Label(self.k,textvariable=self.all_all,font=('bold',12)).grid(row=2,column=0,columnspan=2,sticky=NW) self.scr1=Scrollbar(self.k,orient=VERTICAL) self.scr1.grid(row=3,column=1,sticky=N+S) self.list_1=Listbox(self.k,width=30,height=5, font=("Arial", 10, "bold"), yscrollcommand=self.scr1.set) self.list_1.grid(row=3,column=0) self.scr1['command']=self.list_1.yview self.update_tools() def update_tools(self): """ Считается подитог """ deps={} deps_sum={} self.app.db.execute('select name from dep') for n,name in enumerate(self.app.db.fetchall()): if name:deps_sum[n+1]=0 self.app.db.execute('select dep,sum,rate from income where date=?',(date_now(),)) out=self.app.db.fetchall() in_all=0 for x in out: in_all+=float(x[1])*float(x[2]) deps_sum[x[0]]+=float(x[1])*float(x[2]) self.income_all.set('Доход: %s'%(in_all)) self.list_1.delete(0,END) for x in deps_sum: if deps_sum[x]: self.list_1.insert(END,self.deps[x-1]+u'→ '+str(deps_sum[x])) self.app.db.execute('select sum from outcome where date=?',(date_now(),)) out=self.app.db.fetchall() out_all=0 for x in out: out_all+=float(x[0]) self.outcome_all.set('Расход: %s'%(out_all)) self.all_all.set('Остаток: %s'%(in_all-out_all)) def init_plugins(self): """ Панель с плагинами """ self.plugin_list=[] self.t_plugins_frame=LabelFrame(self.tools_f,text='Действия') self.t_plugins_frame.pack(fill=BOTH,side='left',expand=1) self.nb=Notebook(self.t_plugins_frame) self.nb.pack(fill=BOTH,expand=1,pady=5) self.plugins_frame=range(3) # 3 вкладки imgs=['sale','dep_db','misc'] for x,name in enumerate(['Продажи','Товар','Прочее']): self.plugins_frame[x]=Frame(self.t_plugins_frame) self.plugins_frame[x].pack(fill=BOTH,side='left',expand=1) self.nb.add(self.plugins_frame[x], text=name, padding=3,image=self.app.img[imgs[x]],compound='left') self.end_frame=Frame(self.tools_f) self.end_frame.pack(side='left') self.end_button=Button(self.tools_f,style='mini.TButton',text=' Сменить\nпользователя',image=self.app.img['people'],compound='top',command=self.app.change_user,cursor='hand2') self.end_button.pack(side='bottom',pady=10,padx=5) self.app.db.execute('select caps from users where name=?',(self.app.user.decode('utf-8'),)) caps=eval(self.app.db.fetchall()[0][0]) # тут начинается самое интересное :) s=os.listdir('app/plugins/frames') row=[0,0,0] column=[0,0,0] self.pl_buttons={} for x in s: if x.endswith('.py'): # испортируем, и получаем имя, название иконки, номер вкладки obj=__import__(x[:-3]) name=getattr(obj,'name') fr=getattr(obj,'frame') self.plugin_list.append(name) if hasattr(obj,'icon'): icon=getattr(obj,'icon') else: icon='plugins' # проверяем, есть ли допуск юзера к плагину, или "Администратор" if name in caps or self.app.user=='Администратор': # собственно добавляем кнопку self.pl_buttons[(row[fr],column[fr])]=Button(self.plugins_frame[fr], text=name.ljust(100),style='mini2.TButton',image=self.app.img[icon],compound='left',width=23) self.pl_buttons[(row[fr],column[fr])].grid(row=row[fr],column=column[fr],sticky=NW,padx=5,pady=2) self.pl_buttons[(row[fr],column[fr])]['command']=lambda pl=obj:self.show_plugin(pl) column[fr]=column[fr]+1 if column[fr]>2: column[fr]=0 row[fr]=row[fr]+1 def show_plugin(self,obj): """ Вызывается при нажитию на кнопку плагина. Запускаем метод run плагина """ cl=getattr (obj, 'Plugin')(self) cl.run() def init_add_plugins(self,dt,tm): """ Вызывается после добавления """ s=os.listdir('app/plugins/income') for x in s: if x.endswith('.py'): obj=__import__(x[:-3]) cl=getattr (obj, 'Plugin')(self,dt,tm)
class TabStockBrowser(): def __init__(self, frame, db): self.frame = frame self.__db = db self._histogramRange = (10*365) self.histogram_stock = Pmw.Blt.Graph(self.frame, height=100) self.histogram_stock.xaxis_configure(stepsize=self._histogramRange/20, command=StockHistogram_formatXaxisLabel) self.histogram_stock.grid_on() self.histogram_stock.pack(side=BOTTOM, anchor=S, fill=X) self.graph_stock = StockGraph(self.frame, height=200) self.graph_stock.bind(sequence="<ButtonPress-1>", func=self.graph_stock_mouseSelect) self.graph_stock.pack(side=BOTTOM, anchor=S, fill=X) self.label_graph_stock = Label(self.frame, text="StockEntry:") self.label_graph_stock.pack(side=BOTTOM, anchor=SW) self.listbox_stocks = Pmw.ScrolledListBox(self.frame, labelpos='nw', label_text='Stocks:', usehullsize=1, hull_width=200, vscrollmode='static', selectioncommand=self.listbox_stocks_SingleClick) self.listbox_stocks.pack(side=LEFT, anchor=W, fill=Y, padx=5, pady=5) self.listBox_webpages = MultiListbox(self.frame, 'Webpages:', (('Date', 10), ('Title', 40))) self.listBox_webpages.bind("<Double-Button-1>", self.listBox_webpagesDoubleClick) self.listBox_webpages.pack(side=LEFT,anchor=W, fill=BOTH, expand=YES) self.listbox_stocks_populate() def listbox_stocks_populate(self): self._allStockNames = self.__db.getAllStockNames() self.listbox_stocks.setlist(self._allStockNames) def graph_stock_populate(self, stockname): self.__allStocks = self.__db.getAllStocks(stockname) vector_x = [] vector_y = [] for stock in sorted(self.__allStocks.itervalues()): vector_x.append(stock['date'].toordinal()) vector_y.append(int(stock['shareprice_closing']*100)) self.graph_stock.line_create(stockname, xdata=vector_x, ydata=vector_y, symbol='') self.graph_stock.legend_configure(self.graph_stock.legend_get(0), hide=True) (nValues, bins) = numpy.histogram(vector_y, bins=range(self._histogramRange)) # filter out small numbers so that trimming is fairly efficient numpy.putmask(nValues, nValues<=3, 0) trimmedN = numpy.trim_zeros(nValues) histvector_x = bins.astype(int)[0:len(trimmedN)].tolist() histvector_y = trimmedN.astype(int).tolist() self.histogram_stock.bar_create(stockname, xdata=histvector_x, ydata=histvector_y, barwidth=3.0) self.histogram_stock.legend_configure(self.histogram_stock.legend_get(0), hide=True) def populate_webpages(self, stock): self.listBox_webpages.delete(0, END) self._selectedWebpages = self.__db.getWebpages(stock['date']-timedelta(3), stock['date']) for webpage in self._selectedWebpages: self.listBox_webpages.insert(END, (str(webpage.date), str(webpage.title))) def listbox_stocks_SingleClick(self): stockname = self._allStockNames[int(self.listbox_stocks.curselection()[0])] self.graph_stock_populate(stockname) def listBox_webpagesDoubleClick(self, event): webpage = self._selectedWebpages[int(self.listBox_webpages.curselection()[0])] webbrowser.open(webpage.url, new=0, autoraise=True) def graph_stock_mouseSelect(self, event): dicto = self.graph_stock.element_closest(event.x, event.y, halo=1000, interpolate=0) if dicto != None: stock = self.__allStocks[date.fromordinal(int(dicto['x']))] labelText = "StockEntry: " + str(stock['date']) + " value: " + str(stock['shareprice_closing']) + " SEK" self.label_graph_stock.config(text=labelText) (Y0, Y1) = self.graph_stock.yaxis_limits() self.graph_stock.marker_create("line", name="marking line", dashes="", linewidth=2, coords=(dicto['x'], Y0, dicto['x'], Y1)) self.populate_webpages(stock)
class Plugin: def __init__(self,app): self.app=app def run(self): self.win=Toplevel(self.app.app.win) self.win.title(name) x,y=800,350 pos=self.win.wm_maxsize()[0]/2-x/2,self.win.wm_maxsize()[1]/2-y/2 self.win.geometry('%sx%s+%s+%s'%(x,y,pos[0],pos[1]-25)) self.win.maxsize(width=x,height=y) self.win.minsize(width=x,height=y) if sys.platform=='win32':self.win.iconbitmap('app/images/icon.ico') self.cur_list=[] self.add_f=LabelFrame(self.win,text='Товар') self.add_f.pack(expand=YES,fill=X,anchor=N) self.init_add() self.lst=MultiListbox(self.win, (('Отдел', 3), ('Товар', 60), ('Количество', 3)),font=('normal',12)) self.lst.pack(fill=BOTH,expand=1,padx=5) def init_add(self): """ фрейм с добавлением товара """ self.init_deps() self.cat_but=Button(self.add_f,style='mini.TButton',image=self.app.app.img['dep_db'],compound='top',text='Товар',command=self.cat_handler) self.cat_but.pack(side='left') self.add_but=Button(self.add_f,text='Добавить',image=self.app.app.img['add'],compound='left',command=self.add_handler) self.add_but.pack(side='right') self.rate_v=Combobox(self.add_f,width=6,font=('bold',16)) self.rate_v.set('1') self.rate_v.pack(side='right',padx=10) self.rate_v['values']=range(1,21) self.dep_name=Text(self.add_f,height=2,font=(15)) self.dep_name.pack(side='left',padx=10,fill=BOTH,pady=5) self.dep_name['state']='disable' self.build_tree() self.tools_f=Frame(self.win) self.tools_f.pack(fill=BOTH,side='bottom',expand=1) self.del_but=Button(self.tools_f,text='Удалить текущий',image=self.app.app.img['delete'],compound='left',command=self.del_handler) self.del_but.pack(side='left',padx=15,pady=10) self.save_but=Button(self.tools_f,text='Сохранить приход',image=self.app.app.img['save'],compound='left',command=self.save_all) self.save_but.pack(side='right',padx=15,pady=10) self.lab_var=StringVar() self.lab_var.set('Позиций: 0 шт.\n Товара: 0 шт.') Label(self.tools_f,textvariable=self.lab_var,font=('normal',12)).pack(side='top') def init_deps(self): """ меню с отделами """ self.deps=[] self.app.app.db.execute('select name from dep') for n,name in enumerate(self.app.app.db.fetchall()): self.deps.append('%s %s'%(n+1,name[0])) self.cur_dep=0 self.dep_str=StringVar() self.dep_str.set(self.deps[0]) Style().configure("TMenubutton",font=('bold',13)) self.otd=Menubutton(self.add_f,textvariable=self.dep_str, width=19,image=self.app.app.img['deps'],compound='left') self.otd.pack(pady=10,side='left',padx=10) self.otd.menu=Menu(self.otd, font=("bold",13),bg='white',relief='flat', tearoff=0) for n,x in enumerate(self.deps): if len(x)>3: self.otd.menu.add_command(label=x.ljust(25),command=lambda z=n:self.deps_hand(z)) self.otd['menu']=self.otd.menu def deps_hand(self,n): """ вызывается при смене отдела """ self.cur_dep=n self.dep_str.set(self.deps[n]) self.cat_id=-1 self.build_tree() def build_tree(self): """ построение дерева товаров """ self.popup = Menu(self.win, tearoff=0,font=('normal',12)) def get_menu(id): self.app.app.db.execute('select id,name,type from article where dep=? and parent=? order by name',(self.cur_dep+1,id,)) popup = Menu(self.win, tearoff=0,font=('normal',12)) for x in self.app.app.db.fetchall(): if x[2]=='item': popup.add_command(label=x[1],command=lambda z=x[0]:self.command_handler(z)) else:popup.add_cascade(label=x[1],menu=get_menu(x[0])) return popup self.app.app.db.execute('select id,name,type from article where dep=? and parent=-1 order by name',(self.cur_dep+1,)) for x in self.app.app.db.fetchall(): if x[2]=='item': self.popup.add_command(label=x[1],command=lambda z=x[0]:self.command_handler(z)) else: self.popup.add_cascade(label=x[1],menu=get_menu(x[0])) def cat_handler(self): self.popup.tk_popup(self.cat_but.winfo_rootx()+30, self.cat_but.winfo_rooty()+55, 0) def command_handler(self,id): """ при щелчке на товар """ self.cat_id=id t=[] flag=True self.app.app.db.execute('select name,edit,sum,parent from article where id=?',(id,)) s=self.app.app.db.fetchall()[0] par=s[3] t.append(s[0]) if par==-1:flag=0 # построение длинного названия товара, включая подкатегории while flag: self.app.app.db.execute('select name,parent from article where id=?',(par,)) rez=self.app.app.db.fetchall()[0] if rez[1]==-1: t.append(rez[0]) flag=False else: t.append(rez[0]) par=rez[1] cat_lst=' > '.join(t[::-1]) self.dep_name['state']='normal' self.dep_name.delete(0.0,END) self.dep_name.insert(0.0,cat_lst) self.dep_name['state']='disable' def add_handler(self): """ добавление товара во временный список """ txt=self.dep_name.get('0.0',END).replace('\r','').replace('\n',' ').replace('\t',' ') try:razves=eval(self.app.app.sets.razves)[self.cur_dep] except AttributeError:razves=0 if len(txt)<2: box.showerror(title='Ошибка',message='Не выбран товар!') self.win.deiconify() return try: if razves:rate=float(self.rate_v.get().replace(',','.')) else:rate=int(self.rate_v.get().replace(',','.')) except: box.showerror(title='Ошибка',message='Не верное количество!') self.win.deiconify() return if rate<=0: box.showerror(title='Ошибка',message='Не верное количество!') self.win.deiconify() return self.cur_list.append([self.cur_dep+1,txt,rate,self.cat_id]) self.update_list() self.dep_name['state']='normal' self.dep_name.delete(0.0,END) self.dep_name['state']='disable' self.rate_v.set('1') def update_list(self): """ обновление таблицы со списком прихода """ self.lst.delete(0,END) for x in self.cur_list: self.lst.insert(END,x) self.lst.see(END) s1=len(self.cur_list) s2=0 for x in self.cur_list: s2+=x[2] self.lab_var.set('Позиций: %s шт.\n Товара: %s шт.'%(s1,s2)) def del_handler(self): """ удаление товара из временного списка """ sel=self.lst.curselection() if not sel:return sel=int(sel[0]) del self.cur_list[sel] self.update_list() def save_all(self): """ Сохрание прихода и записть в таблицу приходов """ date=date_now() tm=time_now() user=self.app.app.user.decode('utf-8') self.app.app.db.execute('select max(id) from in_art') try:id=self.app.app.db.fetchall()[0][0]+1 except:id=1 for x in self.cur_list: self.app.app.db.execute('insert into in_art values (?,?,?,?,?,?,?)',(id,date,tm,x[0],x[1],x[2],user)) self.app.app.db.execute('select rate from article where id=?',(x[3],)) rate=self.app.app.db.fetchall()[0][0]+x[2] self.app.app.db.execute('update article set rate=? where id=?',(rate,x[3])) self.app.app.con.commit() self.win.destroy()