def show_sales_goods(master, data): """Выводит третий из пяти управляющих фреймов, дающий возможность редактировать калькуляции акционных товаров.""" def choose_sales(event): """Функция, срабатывающая при выборе товара из списка товаров.""" select = listbox_sales.curselection() if select: index = int(select[0]) show_sales_goods.sales_index = index item = sales_assortiment[index] calc_fill(item) title.configure(text=item.name) date_fill(item) #--------------------------------------- def assortiment_fill(): """Функция заполнения списков товаров/ингредиентов""" for q in range(len(assortiment)): # Очищаем список товаров del(assortiment[0]) listbox_goods.delete(0, END) for cath in queries.cathegories(): if cath.name <> u'Акции': assortiment.append(None) listbox_goods.insert(END, '') assortiment.append(None) head = '-' * (CONTROL_5_WIDTH - len(cath.name) -1) + \ cath.name + u'-' listbox_goods.insert(END, head) for item in queries.non_sales_items_in_cathegory(cath): assortiment.append(item) listbox_goods.insert(END, ' ' + item.name) if not item.show: listbox_goods.itemconfig(END, {'fg':'grey'}) #--------------------------------------- def sales_fill(): """Функция заполнения списка акционных товаров""" for q in range(len(sales_assortiment)): # Очищаем список товаров del(sales_assortiment[0]) listbox_sales.delete(0, END) for item in queries.sales_items(): sales_assortiment.append(item) listbox_sales.insert(END, ' ' + item.name) if not queries.item_calculation(item): listbox_sales.itemconfig(END, {'fg':'red'}) elif queries.actual_sales_item(item): listbox_sales.itemconfig(END, {'fg':'#9900BB'}) #--------------------------------------- def calc_fill(item): """Функция заполнения списка калькуляций ингредиентами""" for q in range(len(calculation)): # Очищаем список калькуляций del(calculation[0]) listbox_calc.delete(0, END) for calc in queries.item_calculation(item): calculation.append(calc) string = u' %-' + unicode(CONTROL_6_WIDTH - 6) + 's %-5d' listbox_calc.insert(END, string % (calc.ingredient.name, calc.quantity)) if not calc.ingredient.show: listbox_calc.itemconfig(END, {'fg':'grey'}) #--------------------------------------- def date_fill(item): """Функция заполнения списка периодов действия акции""" for q in range(len(sales_list)): # Очищаем список калькуляций del(sales_list[0]) small_listbox.delete(0, END) for sales in queries.sales(item): sales_list.append(sales) small_listbox.insert(END, u' c ' + str(sales.from_date.strftime('%d.%m.%Y')) + u' по '+ str(sales.to_date.strftime('%d.%m.%Y')) + ' - %.2f' % queries.item_price_on_date(item, datetime.combine(sales.from_date, time(0,0,0)))) if sales.to_date < datetime.now().date(): small_listbox.itemconfig(END, {'fg':'grey'}) if (sales.to_date >= datetime.now().date()) and (sales.from_date <= datetime.now().date()): small_listbox.itemconfig(END, {'fg':'#9900BB'}) #--------------------------------------- def create_sales_item(): """Создает новый акционный товар.""" try: price = float(priceVar.get()) except: tkMessageBox.showerror(u'Ошибка!', u'Внимательно проверьте заполнение числового поля цены!') else: if not (cal_from.selection and cal_to.selection): tkMessageBox.showerror(u'Ошибка!', u'Вы не выбрали начальную/конечную дату периода') elif (cal_from.selection > cal_to.selection): tkMessageBox.showerror(u'Ошибка!', u'Начальный день акции больше конечного!') elif not nameVar.get(): tkMessageBox.showerror(u'Ошибка!', u'Укажите название сложного акционного товара!') elif tkMessageBox.askyesno(u'Внимание!', 'Вы действительно хотите создать акцию?'): item = queries.add_goods_sales(name=nameVar.get(), price=price, from_time=cal_from.selection, to_time=cal_to.selection) if item: sales_fill() listbox_sales.selection_set(sales_assortiment.index(item)) listbox_sales.see(sales_assortiment.index(item)) show_sales_goods.sales_index = sales_assortiment.index(item) date_fill(item) #--------------------------------------- def add_dates(): """Создает новый период действия для акционного товара.""" if show_sales_goods.sales_index <> None: item = sales_assortiment[show_sales_goods.sales_index] try: price = float(priceVar.get()) except: tkMessageBox.showerror(u'Ошибка!', u'Внимательно проверьте заполнение числового поля цены!') else: if not (cal_from.selection and cal_to.selection): tkMessageBox.showerror(u'Ошибка!', u'Вы не выбрали начальную/конечную дату периода') elif (cal_from.selection > cal_to.selection): tkMessageBox.showerror(u'Ошибка!', u'Начальный день акции больше конечного!') elif queries.cross_sales(item, cal_from.selection, cal_to.selection): tkMessageBox.showerror(u'Ошибка!', u'Перехлест акций недопустим!') elif tkMessageBox.askyesno(u'Внимание!', 'Вы действительно хотите добавить период к акции?'): if queries.add_sales(item=item, price=price, from_time=cal_from.selection, to_time=cal_to.selection): sales_fill() listbox_sales.selection_set( sales_assortiment.index(item)) listbox_sales.see(sales_assortiment.index(item)) date_fill(item) #--------------------------------------- def apply(): """Вносит изменения в калькуляцию текущего акционного товара, добавляя выбранный в списке товаров/ингредиентов товар в количестве, указанном в Entry""" select = listbox_goods.curselection() if select: index = int(select[0]) ingredient = assortiment[index] if ingredient and show_sales_goods.sales_index <> None: item = sales_assortiment[show_sales_goods.sales_index] try: quantity = int(quantVar.get()) except: quantity = 1 if quantity: item_old = None for q in calculation: if q.ingredient == ingredient: item_old = q if item_old: item_old.quantity = quantity if queries.update_calculation(item_old): calc_fill(item) quantVar.set('') else: calc = queries.add_calculation(item, ingredient, quantity) if calc: sales_fill() calc_fill(item) quantVar.set('') #--------------------------------------- def cut_sales(): """Обрезает периоды действия акционного товара по сегодняшний день""" if show_sales_goods.sales_index <> None: item = sales_assortiment[show_sales_goods.sales_index] if tkMessageBox.askyesno(u'Внимание!', u'Прерывание акции - нестандартная процедура,\n' + u'Все периоды сложного акционного товара \n' + u'удаляются либо устанавливаются таким образом,\n' + u'чтобы истечь по состоянию на день прерывания.\n\n' + u'Вы уверены в том, что хотите провести эту операцию\n' u'над акционным товаром "%s"?' % item.name): if queries.drop_sales_good(item): sales_fill() date_fill(item) #--------------------------------------- def remove(): """Вносит изменения в калькуляцию текущего акционного товара, убирая выбранный в списке товар/ингредиент""" if show_sales_goods.sales_index <> None: selected_ing = listbox_goods.curselection() selected_calc = listbox_calc.curselection() calc = None #Выбираем либо из ингредиентов, либо из калькуляций if selected_calc: calc = calculation[int(selected_calc[0])] elif selected_ing: ingredient = assortiment[int(selected_ing[0])] for q in calculation: if q.ingredient == ingredient: calc = q if calc: if queries.delete_calculation(calc): sales_fill() calc_fill(sales_assortiment[show_sales_goods.sales_index]) #=========================== СОЗДАНИЕ ИНТЕРФЕЙСА =========================== #------------------------------ ЛЕВЫЙ ФРЕЙМ -------------------------------- leftFrame = Frame(master, relief=GROOVE) leftFrame.pack(side=LEFT, fill=Y, pady=CONTROL_PAD, padx=CONTROL_PAD/2) Label(leftFrame, text=u'Товары:', font=('Lucida Console', LIST_FONT_SIZE)).pack() assortiment = [] miniFrameLeft = Frame(leftFrame, relief=GROOVE) miniFrameLeft.pack(side=BOTTOM, pady=5) quantVar = StringVar(leftFrame, value='') Button(miniFrameLeft, text=u'Добавить\nтовар', command=apply).pack(side=LEFT, padx=CONTROL_PAD, pady=CONTROL_PAD) Entry(miniFrameLeft, width=8, textvariable=quantVar).pack(side=LEFT, pady=5) Button(miniFrameLeft, text=u'Убрать\nтовар', command=remove).pack(side=LEFT, padx=CONTROL_PAD, pady=CONTROL_PAD) scrollbar_goods = Scrollbar(leftFrame) listbox_goods = Listbox(leftFrame, yscrollcommand=scrollbar_goods.set, width = CONTROL_5_WIDTH, activestyle='dotbox', font=('Lucida Console', LIST_FONT_SIZE)) listbox_goods.pack(side=LEFT, fill=BOTH) scrollbar_goods.config(command=listbox_goods.yview) scrollbar_goods.pack(side=LEFT, fill=Y) #------------------------------ СРЕДНИЙ ФРЕЙМ ------------------------------- middleFrame = Frame(master, relief=GROOVE) middleFrame.pack(side=LEFT, pady=CONTROL_PAD, padx=CONTROL_PAD/2, anchor='n', fill=Y) #-------------------------------------------------- middleFrame3 = Frame(middleFrame, relief=GROOVE) middleFrame3.pack() title = Label(middleFrame3, text=u'Состав акционного товара:', font=('Lucida Console', LIST_FONT_SIZE)) title.pack(pady=5) calculation = [] scrollbar_bottom = Scrollbar(middleFrame3) listbox_calc = Listbox(middleFrame3, yscrollcommand=scrollbar_bottom.set, width = CONTROL_6_WIDTH, activestyle='dotbox', font=('Lucida Console', LIST_FONT_SIZE), height=CONTROL_3_HEIGHT) listbox_calc.pack(side=LEFT, fill=BOTH) scrollbar_bottom.config(command=listbox_calc.yview) scrollbar_bottom.pack(side=LEFT, fill=Y) #-------------------------------------------------- middleFrame_name = Frame(middleFrame, relief=GROOVE) middleFrame_name.pack(pady=CONTROL_PAD/3*2, padx=CONTROL_PAD/3*2, fill=X) Label(middleFrame_name, text=u'Название акции:').pack(pady=CONTROL_PAD/3) nameVar = StringVar(middleFrame_name, value='') Entry(middleFrame_name, textvariable=nameVar).pack(fill=X) #-------------------------------------------------- middleFrame2 = Frame(middleFrame, relief=GROOVE) middleFrame2.pack(pady=CONTROL_PAD/2) Button(middleFrame2, text=u'Создать\nтовар', command=create_sales_item).pack(side=LEFT, padx=CONTROL_PAD) Button(middleFrame2, text=u'Изменить\nцену', state=DISABLED).pack(side=RIGHT, padx=CONTROL_PAD) Label(middleFrame2, text=u'Цена:').pack(pady=5) priceVar = StringVar(middleFrame2, value='') Entry(middleFrame2, width=8, textvariable=priceVar).pack(side=BOTTOM) #------------------------------------------------------------- middleFrame1 = Frame(middleFrame, relief=GROOVE) middleFrame1.pack(fill=Y, expand=YES) Label(middleFrame1, text=u'Акционные товары:', font=('Lucida Console', LIST_FONT_SIZE)).pack() sales_assortiment = [] show_sales_goods.sales_index = None scrollbar_sales = Scrollbar(middleFrame1) listbox_sales = Listbox(middleFrame1, yscrollcommand=scrollbar_sales.set, width = CONTROL_6_WIDTH, activestyle='dotbox', font=('Lucida Console', LIST_FONT_SIZE)) listbox_sales.pack(side=LEFT, fill=BOTH, expand=YES) scrollbar_sales.config(command=listbox_sales.yview) scrollbar_sales.pack(side=LEFT, fill=Y) listbox_sales.bind('<<ListboxSelect>>', choose_sales) #----------------------------- ПРАВЫЙ ФРЕЙМ -------------------------------- rightFrame = Frame(master, relief=GROOVE) rightFrame.pack(pady=CONTROL_PAD, padx=CONTROL_PAD/2, fill=Y, expand=YES) Label(rightFrame, text=u'Сегодня:\n' + unicode(datetime.now().date().strftime('%d.%m.%Y')), font = ('Verdana', FONT_SIZE_BIG)).pack(pady=5) rightFrame1 = Frame(rightFrame, relief=GROOVE) rightFrame1.pack(pady=CONTROL_PAD, padx=CONTROL_PAD) sales_list = [] small_scrollbar = Scrollbar(rightFrame1) small_listbox = Listbox(rightFrame1, yscrollcommand=small_scrollbar.set, width = CONTROL_DATE_WIDTH_2, height=CONTROL_DATE_HEIGHT_2, activestyle='dotbox', font=('Arial Narrow', LIST_FONT_SIZE, 'bold')) small_listbox.pack(side=LEFT, fill=BOTH) small_scrollbar.config(command=small_listbox.yview) small_scrollbar.pack(side=LEFT, fill=Y) #-------------------- rightFrame2 = Frame(rightFrame, relief=GROOVE) rightFrame2.pack(pady=CONTROL_PAD) Button(rightFrame2, text=u'Добавить\nпериод', command=add_dates).pack(side=LEFT, padx=CONTROL_PAD, pady=7) Button(rightFrame2, text=u'Сбросить\nпериоды', command=cut_sales).pack(side=RIGHT, padx=CONTROL_PAD, pady=7) date_from = Label(rightFrame, text=u'Начальная дата:', font = ('Verdana', FONT_SIZE)) date_from.pack() cal_from = Calendar(rightFrame, firstweekday=0) cal_from.pack(pady=CONTROL_PAD, padx=CONTROL_PAD) date_to = Label(rightFrame, text=u'Конечная дата\n(включительно):', font = ('Verdana', FONT_SIZE)) date_to.pack() cal_to = Calendar(rightFrame, firstweekday=0) cal_to.pack(pady=CONTROL_PAD, padx=CONTROL_PAD) #--------------------------------первый запуск----------------------------- assortiment_fill() sales_fill() show_sales_goods.renew = assortiment_fill #Для обновления при возврате ко вкладке
def _pressed(self, evt): """Clicked somewhere in the calendar.""" Calendar._pressed(self, evt) checks_fill()
def show_sales(master, data): """Выводим четвертый из пяти управляющих фреймов, дающий возможность устанавливать акционные цены на товары.""" def choose(event): """Функция, срабатывающая при выборе товара из списка.""" index = int(listbox.curselection()[0]) show_sales.i_index = index if assortiment[index]: small_listbox_fill(assortiment[index]) else: clear() def listbox_fill(): """Функция заполнения левого листа товарами""" for q in range(len(assortiment)): # Очищаем список del(assortiment[0]) listbox.delete(0, END) category_list = queries.cathegories() if not category_list: assortiment.append(None) listbox.insert(END, 'Список пуст.') else: for cath in category_list: if cath.name <> u'Акции': assortiment.append(None) listbox.insert(END, '') assortiment.append(None) head = '-' * (CONTROL_WIDTH - len(cath.name) -1) + cath.name + u'-' listbox.insert(END, head) for item in queries.items_in_cathegory(cath): if not item.sales: assortiment.append(item) listbox.insert(END, ' ' + item.name) if not item.show: listbox.itemconfig(END, {'fg':'grey'}) small_listbox.delete(0, END) def small_listbox_fill(item): """Функция заполнения правого листа ценами""" small_listbox.delete(0, END) for price in queries.get_prices_list(item): astrx = '*' if price.sales else ' ' string = astrx + price.from_time.strftime('%d.%m.%Y') + \ ' %8.2f' % price.price small_listbox.insert(END, string) def clear(): """Очищает поля правого фрейма""" small_listbox.delete(0, END) def cut_sales(): index = show_sales.i_index item = assortiment[index] if item and tkMessageBox.askyesno(u'Внимание!', u'Прерывание акции - нестандартная процедура,\n' + u'заключающаяся в том, что с момента прерывания\n' + u'устанавливается пост-акционная цена на товар.\n\n' + u'Вы уверены в том, что хотите провести эту операцию\n' u'над товаром "%s"?' % item.name): if queries.drop_sales_price(item): small_listbox_fill(item) def apply(): """Устанавливает акционную цену на основании полей правого фрейма""" index = show_sales.i_index item = assortiment[index] if item and tkMessageBox.askyesno(u'Внимание!', 'Вы действительно хотите установить акционную цену?'): try: i_price.get() except: tkMessageBox.showerror(u'Ошибка!', u'Внимательно проверьте заполнение числовых полей.') else: if not (cal_from.selection and cal_to.selection): tkMessageBox.showerror(u'Ошибка!', u'Вы не выбрали начальную/конечную дату') elif (cal_from.selection < datetime.now()) or (cal_to.selection < datetime.now()): tkMessageBox.showerror(u'Ошибка!', u'Установка акций задним числом не допускается!') elif (cal_from.selection > cal_to.selection): tkMessageBox.showerror(u'Ошибка!', u'Начальный день акции больше конечного!') elif queries.item_price_is_sales_on_date(item, cal_from.selection) or \ queries.item_price_is_sales_on_date(item,cal_to.selection): tkMessageBox.showerror(u'Ошибка!', u'Перехлест акций!') elif queries.add_sales_price(item=item, price=i_price.get(), from_time=cal_from.selection, to_time=cal_to.selection): small_listbox_fill(item) #------------------------------ ЛЕВЫЙ ФРЕЙМ -------------------------------- leftFrame = Frame(master, relief=GROOVE) leftFrame.pack(side=LEFT, fill=Y, pady=CONTROL_PAD, padx=CONTROL_PAD) assortiment = [] show_sales.i_index = 0 scrollbar = Scrollbar(leftFrame) listbox = Listbox(leftFrame, yscrollcommand=scrollbar.set, width = CONTROL_WIDTH, activestyle='dotbox', font=('Lucida Console', LIST_FONT_SIZE)) listbox.pack(side=LEFT, fill=BOTH) scrollbar.config(command=listbox.yview) scrollbar.pack(side=LEFT, fill=Y) listbox.bind('<<ListboxSelect>>', choose) #----------------------------- ПРАВЫЙ ФРЕЙМ -------------------------------- rightFrame = Frame(master, relief=GROOVE) rightFrame.pack(side=LEFT, fill=X, pady=CONTROL_PAD, padx=CONTROL_PAD, anchor='nw') rightFrame1 = Frame(rightFrame, relief=FLAT) rightFrame1.pack(side=LEFT, fill=Y, pady=CONTROL_PAD, padx=CONTROL_PAD) rightFrame2 = Frame(rightFrame, relief=FLAT) rightFrame2.pack(side=LEFT, fill=Y, pady=CONTROL_PAD, padx=CONTROL_PAD) #-------------------- История цен по товару в листбоксе --------- littleFrame = Frame(rightFrame1, relief=GROOVE) littleFrame.pack(pady=CONTROL_PAD, padx=CONTROL_PAD) small_scrollbar = Scrollbar(littleFrame) small_listbox = Listbox(littleFrame, yscrollcommand=small_scrollbar.set, width = CONTROL_DATE_WIDTH, height=CONTROL_DATE_HEIGHT, activestyle='dotbox', font=('Lucida Console', LIST_FONT_SIZE)) small_listbox.pack(side=LEFT, fill=BOTH) small_scrollbar.config(command=small_listbox.yview) small_scrollbar.pack(side=LEFT, fill=Y) #-------------------- Остальное --------- Label(rightFrame1, text=u'Акционная цена:', font = ('Verdana', FONT_SIZE) ).pack(pady=CONTROL_PAD, padx=CONTROL_PAD) i_price = DoubleVar(rightFrame, value=0) Entry(rightFrame1, textvariable=i_price, width=10,font=('Verdana', FONT_SIZE_BIG)).pack(pady=CONTROL_PAD, padx=CONTROL_PAD) Button(rightFrame1, text=u'Добавить\nакционную цену', command=apply).pack( ipadx=2, ipady=2, pady=CONTROL_PAD, padx=CONTROL_PAD) Button(rightFrame1, text=u'Прервать\nакции', command=cut_sales).pack( ipadx=2, ipady=2, pady=CONTROL_PAD, padx=CONTROL_PAD) date_from = Label(rightFrame2, text=u'Начальная дата:', font = ('Verdana', FONT_SIZE)) date_from.pack() cal_from = Calendar(rightFrame2, firstweekday=0) cal_from.pack(pady=CONTROL_PAD, padx=CONTROL_PAD) date_to = Label(rightFrame2, text=u'Конечная дата\n(включительно):', font = ('Verdana', FONT_SIZE)) date_to.pack() cal_to = Calendar(rightFrame2, firstweekday=0) cal_to.pack(pady=CONTROL_PAD, padx=CONTROL_PAD) Label(rightFrame2, text=u'Сегодня:\n' + unicode(datetime.now().date().strftime('%d.%m.%Y')), font = ('Verdana', FONT_SIZE_BIG)).pack(pady=CONTROL_PAD, padx=CONTROL_PAD) #--------------------------------первый запуск----------------------------- listbox_fill() show_sales.renew = listbox_fill #Для обновления при возврате ко вкладке