Beispiel #1
0
 def perform_invoice(self, db: DBManager, order_id):
     """
     perform invoice PDF file in directory invoices
     :param db:
     :param order_id:
     :return:
     """
     if config.is_company_info():
         info = config.company_info()
         invoice = ReportInvoice()
         invoice.company_info(info)
         order = db.get_order_info(order_id=order_id)
         client = db.get_client(order.client_id)
         invoice.set_order(date=order.order_date,
                           number=order_id,
                           payer=client.title,
                           address=client.address,
                           delivery=order.delivery_cost)
         order_items = db.get_order_items(order_id)
         for item in order_items:
             product = db.select_single_product(item.product_id)
             invoice.add_item(name=product.name,
                              code=product.title,
                              unit='шт.',
                              quantity=item.quantity,
                              price=product.price)
         invoice.make()
         _send_invoice_mail(client, order_id)
 def save(self, db: DBManager):
     if self._id:
         order = db.get_order(self._id)
         order.is_current = self.is_current
         order.product_id = self.product_id
         order.quantity = self.quantity
         db.save_element(order)
     else:
         db.save_element(self.get_order())
Beispiel #3
0
 def change_status(db: DBManager, order_id, order_status):
     """
     change status of order
     :param db:
     :param order_id:
     :param order_status:
     :return:
     """
     order: OrderInfo = db.get_order_info(order_id=order_id)
     order.status = order_status
     db.save_element(order)
Beispiel #4
0
 def dialog_store_save(self, db: DBManager):
     """
     save info about store from dialog to database
     :return:
     """
     store = Store()
     store.title = self._dialog.store['title']
     store.address = self._dialog.store['address']
     store.longitude = self._dialog.store['longitude']
     store.latitude = self._dialog.store['latitude']
     store.price_km = self._dialog.store['price']
     db.save_element(store)
 def save(self, db: DBManager):
     if self._id:
         order = db.get_order_info(self._id)
         order.is_current = self._current
         order.client_id = self._client
         order.delivery_cost = self._delivery_cost
         order.order_date = self._date
         order.status = self._status
         order.store_id = self._store
         db.save_element(order)
     else:
         self._date = datetime.now()
         order = self._get_order_info()
         self._id = db.save_element(order)
     return order
Beispiel #6
0
 def __init__(self, bot):
     # получаем нашего бота
     self.bot = bot
     # инициализируем разметку кнопок в меню и экрана
     self.keybords = Keyboards()
     # инициализация менеджера для работы с БД
     self.BD = DBManager()
Beispiel #7
0
 def get_orders(self, db: DBManager):
     """
     get a list of orders with status like self._order_status
     from order_info table
     :param db:
     :return orders: list of order objects
     """
     orders = db.get_orders_status(status=self._order_status)
     return orders
 def load(self, db: DBManager, order_id):
     self._id = order_id
     order_info = db.get_order_info(order_id)
     self._client = order_info.client_id
     self._current = order_info.is_current
     self._date = order_info.order_date
     self._delivery_cost = order_info.delivery_cost
     self._status = order_info.status
     self._store = order_info.store_id
 def get_orders(self, db: DBManager):
     """
     get list of orders from order_info table or get only one current order
     """
     order = self._load_current_order(db=db)
     if order:
         return [order]
     else:
         orders = db.get_orders_info(self._id)
         return orders
 def _load(self, db: DBManager, order_spec):
     products = db.get_order_items(order_spec.id)
     number = 0
     for order in products:
         number += 1
         order_item = OrderItem(order_spec=order_spec,
                                number=number,
                                is_current=order.is_current,
                                product_id=order.product_id,
                                quantity=order.quantity,
                                item_id=order.id)
         order_item.order_id = order.order_id
         self._orders[order_item.product_id] = order_item
 def _get_store_near(self, db: DBManager):
     client = db.get_client(self._client)
     stores = db.get_stores()
     client_distance = 0.0
     store_distance = 0.0
     store_id = 0
     price_km = 0.0
     client_location = (client.latitude, client.longitude)
     for store in stores:
         store_location = (store.latitude, store.longitude)
         if client_distance == 0.0:
             client_distance = distance(client_location,
                                        store_location).kilometers
             store_id = store.id
             price_km = store.price_km
             continue
         store_distance = distance(client_location,
                                   store_location).kilometers
         if store_distance < client_distance:
             client_distance = store_distance
             store_id = store.id
             price_km = store.price_km
     return client_distance, store_id, price_km
 def dec_item(self, db: DBManager, product_id, quantity=1):
     """
     decrease number of order item
     :param db: link to DBManager
     :param product_id:
     :param quantity:
     :return:
     """
     if self.order.id > 0:
         # return quantity of product to store
         if self.order_items._dec(product_id=product_id, quantity=quantity):
             if db.increase_product(product_id=product_id,
                                    quantity=quantity):
                 self.order_items._save(db)
 def add_item(self, db: DBManager, product_id, quantity=1):
     """
     add item to order, if enough product quantity
     :param db: link to DBManager
     :param product_id:
     :param quantity:
     :return True: if enough products, False: otherwise
     """
     if self.order.id == 0:
         self.order.save(db)
     # check if product quantity enough
     if db.decrease_product(product_id=product_id, quantity=quantity):
         self.order_items._add(order_spec=self.order,
                               product_id=product_id,
                               quantity=quantity)
         self.order_items._save(db)
         return True
     else:
         return False
 def _del(self, db: DBManager, order_spec, product_id):
     """
     delete order item position
     :param db:
     :param product_id:
     :return:
     """
     if product_id in self._orders:
         order_item = self._orders[product_id]
         numbers = self.number_positions
         if db.increase_product(product_id=product_id,
                                quantity=order_item.quantity):
             if numbers > 1:
                 if 1 < order_item.number < numbers or order_item.number == numbers:
                     self.current_prev(db)
                 elif order_item.number == 1:
                     self.current_next(db)
             order_item.delete(db)
             self._orders = OrderedDict()
             self._load(db=db, order_spec=order_spec)
Beispiel #15
0
class Keyboards:
    """ Класс Keyboards предназначен для создания и
    разметки клавиатуры бота

    """

    # инициализация разметки
    def __init__(self):
        self.markup = None
        # инициализация менеджера для работы с БД
        self.BD = DBManager()

    def set_btn(self, name, step=0, quantity=0):
        """ Создает и возвращает кнопку по входным параметрам """
        if name == "AMOUNT_ORDERS":
            config.KEYBOARD["AMOUNT_ORDERS"] = "{} {} {}".format(
                step + 1, ' из ', str(self.BD.count_rows_order()))

        if name == "AMOUNT_PRODUCT":
            config.KEYBOARD["AMOUNT_PRODUCT"] = "{}".format(quantity)

        if name == "APPLY":
            # создает кнопку оформить с данными о стоимости товара
            # округленного до 2 - го знака после запятой
            config.KEYBOARD["APPLY"] = "{}({}) руб".format(
                '✅ Оформить', round(utility.get_total_cost(self.BD), 2))

        return KeyboardButton(config.KEYBOARD[name])

    @staticmethod
    def set_inline_btn(name):
        """ Создает и возвращает инлайн кнопку по входным параметрам """
        return InlineKeyboardButton(str(name), callback_data=str(name.id))

    @staticmethod
    def remove_menu():
        """ Удаляет данны кнопки и возвращает ее """
        return ReplyKeyboardRemove()

    def info_menu(self):
        """
        Создает разметку кнопок в меню info
        """
        self.markup = ReplyKeyboardMarkup(True, True)
        itm_btn_1 = self.set_btn('<<')
        # расположение кнопок в меню
        self.markup.row(itm_btn_1)
        return self.markup

    def settings_menu(self):
        """
        Создает разметку кнопок в меню settings
        """
        self.markup = ReplyKeyboardMarkup(True, True)
        itm_btn_1 = self.set_btn('<<')
        # расположение кнопок в меню
        self.markup.row(itm_btn_1)
        return self.markup

    def start_menu(self):
        """ Создает разметку кнопок в основном меню и возвращает разметку """
        self.markup = ReplyKeyboardMarkup(True, True)
        itm_btn_1 = self.set_btn('CHOOSE_GOODS')
        itm_btn_2 = self.set_btn('INFO')
        itm_btn_3 = self.set_btn('SETTINGS')
        # рассположение кнопок в меню
        self.markup.row(itm_btn_1)
        self.markup.row(itm_btn_2, itm_btn_3)
        return self.markup

    def category_menu(self):
        """ Создает разметку кнопок в меню категорий товара и
        возвращает разметку

        """
        self.markup = ReplyKeyboardMarkup(True, True, row_width=1)
        self.markup.add(self.set_btn('SEMIPRODUCT'))
        self.markup.add(self.set_btn('GROCERY'))
        self.markup.add(self.set_btn('ICE_CREAM'))
        self.markup.row(self.set_btn('<<'), self.set_btn('ORDER'))
        return self.markup

    def set_select_category(self, category):
        """ Создает разметку инлайн кнопок в выбранной категории товара и
        возвращает разметку

        """
        self.markup = InlineKeyboardMarkup(row_width=1)
        # загружаем в название инлайн кнопок данные с БД
        # в соответствие с категорией товара
        for item in self.BD.select_all_products_category(category):
            self.markup.add(self.set_inline_btn(item))

        return self.markup

    def orders_menu(self, step, quantity):
        """
        Создает разметку кнопок в заказе товара и возвращает разметку
        """
        self.markup = ReplyKeyboardMarkup(True, True)
        itm_btn_1 = self.set_btn('X', step, quantity)
        itm_btn_2 = self.set_btn('DOWN', step, quantity)
        itm_btn_3 = self.set_btn('AMOUNT_PRODUCT', step, quantity)
        itm_btn_4 = self.set_btn('UP', step, quantity)

        itm_btn_5 = self.set_btn('BACK_STEP', step, quantity)
        itm_btn_6 = self.set_btn('AMOUNT_ORDERS', step, quantity)
        itm_btn_7 = self.set_btn('NEXT_STEP', step, quantity)
        itm_btn_8 = self.set_btn('APPLY', step, quantity)
        itm_btn_9 = self.set_btn('<<', step, quantity)
        # рассположение кнопок в меню
        self.markup.row(itm_btn_1, itm_btn_2, itm_btn_3, itm_btn_4)
        self.markup.row(itm_btn_5, itm_btn_6, itm_btn_7)
        self.markup.row(itm_btn_9, itm_btn_8)

        return self.markup
Beispiel #16
0
class Keyboards:
    """
    Класс Keyboards предназначен для создания и разметки клавиатуры бота
    """

    # инициализация разметки
    def __init__(self):
        self.markup = None
        # инициализация менеджера для работы с БД
        self.BD = DBManager()

    def set_btn(self, name, step='', quantity=0):
        """ 
        Создает и возвращает кнопку по входным параметрам 
        """
        if name == "AMOUNT_ORDERS":
            config.KEYBOARD["AMOUNT_ORDERS"] = step

        if name == "AMOUNT_PRODUCT":
            config.KEYBOARD["AMOUNT_PRODUCT"] = "{}".format(quantity)

        if name == "APPLY":
            # создает кнопку оформить с данными о стоимости товара округленного до 2 - го знака после запятой
            config.KEYBOARD["APPLY"] = "{}({}) руб".format('✅ Оформить', step)

        return KeyboardButton(config.KEYBOARD[name])

    def set_inline_btn(self, name, data=''):
        """ 
        Создает и возвращает инлайн кнопку по входным параметрам 
        """
        if len(data) == 0:
            data = str(name.id)
        return InlineKeyboardButton(str(name), callback_data=data)

    def remove_menu(self):
        """ 
        Удаляет данны кнопки и возвращает ее 
        """
        return ReplyKeyboardRemove()

    def info_menu(self):
        """ 
        Создает разметку кнопок в меню info 
        """
        self.markup = ReplyKeyboardMarkup(True, True)
        itm_btn_1 = self.set_btn('<<')
        # рассположение кнопок в меню
        self.markup.row(itm_btn_1)
        return self.markup

    def settings_menu(self):
        """ 
        Создает разметку кнопок в меню settings 
        """
        self.markup = ReplyKeyboardMarkup(True, True)
        itm_btn_1 = self.set_btn('<<')
        # рассположение кнопок в меню
        self.markup.row(itm_btn_1)
        return self.markup

    def start_menu(self):
        """ 
        Создает разметку кнопок в основном меню и возвращает разметку 
        """
        self.markup = ReplyKeyboardMarkup(True, True)
        itm_btn_1 = self.set_btn('CHOOSE_ORDER')
        itm_btn_2 = self.set_btn('CHOOSE_GOODS')
        itm_btn_3 = self.set_btn('INFO')
        itm_btn_4 = self.set_btn('SETTINGS')
        # рассположение кнопок в меню
        self.markup.row(itm_btn_1, itm_btn_2)
        self.markup.row(itm_btn_3, itm_btn_4)
        return self.markup

    def current_order_menu(self):
        """
        making markup for work with order
        :return:
        """
        self.markup = ReplyKeyboardMarkup(True, True)
        itm_btn_1 = self.set_btn('CHOOSE_ORDER')
        itm_btn_2 = self.set_btn('CHOOSE_GOODS')
        itm_btn_3 = self.set_btn('<<')
        itm_btn_4 = self.set_btn('ORDER')
        # рассположение кнопок в меню
        self.markup.row(itm_btn_1, itm_btn_2)
        self.markup.row(itm_btn_3, itm_btn_4)
        return self.markup

    def category_menu(self):
        """ 
        Создает разметку кнопок в меню категорий товара и возвращает разметку 
        """
        self.markup = ReplyKeyboardMarkup(True, True, row_width=1)
        self.markup.add(self.set_btn('SEMIPRODUCT'))
        self.markup.add(self.set_btn('GROCERY'))
        self.markup.add(self.set_btn('ICE_CREAM'))
        self.markup.row(self.set_btn('<<'), self.set_btn('ORDER'))
        return self.markup

    def select_role_menu(self):
        """
        markup for role selection
        """
        self.markup = ReplyKeyboardMarkup(True, True, row_width=1)
        itm_btn_1 = self.set_btn('TRADER')
        itm_btn_2 = self.set_btn('KEEPER')
        itm_btn_3 = self.set_btn('ADMIN')
        self.markup.row(itm_btn_1, itm_btn_2, itm_btn_3)
        return self.markup

    def set_select_category(self, trader, category):
        """ 
        Создает разметку инлайн кнопок в выбранной категории товара и возвращает разметку 
        """
        self.markup = InlineKeyboardMarkup(row_width=1)
        # загружаем в название инлайн кнопок данные с БД в соответствие с категорией товара
        order_current = self.BD.get_order_current(trader_id=trader.id)
        if order_current is None:
            order_current = trader.order.save(self.BD)
        for itm in self.BD.select_all_products_category(category):
            # dump a data to json string
            # keys & values are: 'm' - menu: 'p' - products (add one product)
            #                    't' - trader id
            #                    'o' - current order id
            #                    'p' - product id
            data = json.dumps(
                {
                    'm': 'p',
                    't': trader.id,
                    'o': order_current.id,
                    'p': itm.id
                },
                separators=(',', ':'))
            self.markup.add(self.set_inline_btn(str(itm), data))
        return self.markup

    def orders_info_menu(self, trader_user: TraderUser):
        """
        create inline-menu of trader's orders
        :param trader_user:
        :return: markup
        """
        orders = trader_user.get_orders(self.BD)
        self.markup = InlineKeyboardMarkup(row_width=1)
        if len(orders):
            for order in orders:
                # dump a data to json string
                # keys & values are: 'm' - menu: 'o' - orders (choose one order to work with)
                #                    't' - trader id
                #                    'o' - current order id
                data = json.dumps(
                    {
                        'm': 'o',
                        't': trader_user.id,
                        'o': order.id
                    },
                    separators=(',', ':'))
                self.markup.add(self.set_inline_btn(str(order), data))
            return self.markup

    def set_select_client(self, trader: TraderUser):
        """
        set menu of list of clients
        :param trader:
        :return markup: inline buttons
        """
        clients = self.BD.get_clients()
        if len(clients):
            self.markup = InlineKeyboardMarkup(row_width=1)
            for client in clients:
                # dump a data to json string
                # keys & values are: 'm' - menu: 'c' - clients (choose one client for order)
                #                    't' - trader id
                #                    'o' - order id
                #                    'c' - client id
                data = json.dumps({
                    'm': 'c',
                    't': trader.id,
                    'o': trader.order.id,
                    'c': client.id
                })
                self.markup.add(self.set_inline_btn(str(client), data))
            return self.markup

    def orders_menu(self, step):
        """ 
        Создает разметку кнопок в заказе товара и возвращает разметку
        :param step: json with parameters: number, quantity, positions, total_price
        :return: markup
        """
        parameters = json.loads(step)
        self.markup = ReplyKeyboardMarkup(True, True)
        itm_btn_1 = self.set_btn('X')
        itm_btn_2 = self.set_btn('DOWN')
        itm_btn_3 = self.set_btn('AMOUNT_PRODUCT',
                                 quantity=parameters['quantity'])
        itm_btn_4 = self.set_btn('UP')

        itm_btn_5 = self.set_btn('BACK_STEP')
        itm_btn_6 = self.set_btn('AMOUNT_ORDERS',
                                 step='{} из {}'.format(
                                     parameters['number'],
                                     parameters['positions']))
        itm_btn_7 = self.set_btn('NEXT_STEP')
        itm_btn_8 = self.set_btn('APPLY', step=parameters['total_price'])
        itm_btn_9 = self.set_btn('<<')
        # рассположение кнопок в меню
        self.markup.row(itm_btn_1, itm_btn_2, itm_btn_3, itm_btn_4)
        self.markup.row(itm_btn_5, itm_btn_6, itm_btn_7)
        self.markup.row(itm_btn_9, itm_btn_8)

        return self.markup
Beispiel #17
0
 def __init__(self):
     self.markup = None
     # инициализация менеджера для работы с БД
     self.BD = DBManager()
 def delete(self, db: DBManager):
     if self._id:
         order = db.get_order(self._id)
         db.delete_element(order)
 def _load_current_order(self, db: DBManager):
     return db.get_order_current(trader_id=self._id)
 def _load(self, db: DBManager):
     user = db.get_user_id(self._id)
     if user:
         self._chat_id = user.chat_id
 def total_price(self, db: DBManager):
     price = 0
     for order_item in self._orders.values():
         product = db.select_single_product(rownum=order_item.product_id)
         price += product.price * order_item.quantity
     return round(price, 2)