Пример #1
0
class Entity(BaseModel):
    __tablename__ = "entities"

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    code = db.Column(db.String(50), unique=True)
    name = db.Column(db.String(50), unique=False, default='')

    query: sql.select

    @classmethod
    async def get(cls, code: str):
        item = await cls.query.where(cls.code == code.lower()).gino.first()
        return item

    @classmethod
    async def add(cls, code: str, name: str = ''):
        try:
            obj = cls(code=code, name=name)
            await obj.create()
        except UniqueViolationError:
            pass

    @classmethod
    async def get_all(cls):
        objs = await cls.query.gino.all()
        return objs
Пример #2
0
class EntityType(BaseModel):
    __tablename__ = "entities_types"

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    code = db.Column(db.String(50), unique=True)
    entity_id = db.Column(db.Integer,
                          db.ForeignKey('entities.id'),
                          nullable=False)
    name = db.Column(db.String(150), unique=False)

    @classmethod
    async def add(cls, code: str, name: str = '', entity_id: int = 0):
        try:
            obj = cls(code=code, name=name, entity_id=entity_id)
            await obj.create()
        except UniqueViolationError:
            pass

    @classmethod
    async def get(cls, code: str):
        item = await cls.query.where(cls.code == code.lower()).gino.first()
        return item

    @classmethod
    async def get_all(cls, entity_id: int = 0):
        if entity_id:
            items = await cls.query.where(cls.entity_id == entity_id
                                          ).gino.all()
        else:
            items = await cls.query.where().gino.all()
        return items
Пример #3
0
class Status(BaseModel):
    __tablename__ = 'statuses'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    status_name = db.Column(db.String(50), unique=True)
    comment = db.Column(db.String(255), default='')

    query: sql.Select
Пример #4
0
class Phone(TimedBaseModel):
    __tablename__ = "phones"

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    customer_id = db.Column(db.BigInteger, db.ForeignKey('customers.id'))

    source_number = db.Column(db.String(150))
    number = db.Column(db.String(50))
    region = db.Column(db.String(100))
    operator = db.Column(db.String(50))
    old_operator = db.Column(db.String(50))

    @classmethod
    async def add(cls, customer_id: int, source_number: str):
        import requests
        from phonenumbers import parse
        try:
            phone_obj = parse(number=source_number, region="RU")
        except NumberParseException.NOT_A_NUMBER:
            return {
                'info':
                f"Неверный формат номера: <pre>{source_number}</pre>",
                'example':
                ["+74959898533", "74959898533", "84959898533", "4959898533"]
            }

        url = "http://num.voxlink.ru/get/"

        querystring = {
            "num": f"+{phone_obj.country_code}{phone_obj.national_number}"
        }

        payload = ""
        response = requests.request("GET",
                                    url,
                                    data=payload,
                                    params=querystring)
        phone_obj = json.loads(response.text)

        if phone_obj.get('info'):
            return phone_obj.get('info',
                                 '') + " - разрешенный формат: " + ", ".join(
                                     phone_obj.get('example', ''))
        else:
            obj = cls(customer_id=customer_id,
                      source_number=source_number,
                      number=phone_obj.get('full_num'),
                      region=phone_obj.get('region'),
                      operator=phone_obj.get('operator'),
                      old_operator=phone_obj.get('old_operator'))
            await obj.create()
Пример #5
0
class Bill(TimedBaseModel):
    __tablename__ = "bills"

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    uid = db.Column(db.String(36), unique=True)
    customer_id = db.Column(db.BigInteger, db.ForeignKey("customers.id"))
    order_id = db.Column(db.Integer, db.ForeignKey("orders.id"))
    amount = db.Column(db.Integer)
    status_id = db.Column(db.Integer, db.ForeignKey("statuses.id"))
    date_expire = db.Column(db.TIMESTAMP)
    comment = db.Column(db.String(255), default='')

    query: sql.Select

    @classmethod
    async def add(cls, order: Order, minutes=10, comment=''):
        try:
            if order.total >= 1:
                uid = str(uuid.uuid4())

                date_expire = datetime.now() + timedelta(minutes=minutes)

                if not comment:
                    comment = f"Заказ #{order.id}"

                obj = Bill(uid=uid, customer_id=order.customer_id, order_id=order.id, amount=order.total,
                           status_id=1, date_expire=date_expire, comment=comment)
                await obj.create()
                return obj
        except UniqueViolationError:
            pass

    @classmethod
    async def get_or_add(cls, order: Order, minutes=10, comment=''):
        obj = await cls.get(order)
        if not obj:
            obj = await cls.add(order=order, minutes=minutes, comment=comment)
        return obj

    @classmethod
    async def get(cls, order: Order):
        obj = await cls.query.where(
            and_(
                cls.order_id == order.id,
                cls.date_expire < datetime.utcnow()
            )
        ).gino.first()

        return obj
Пример #6
0
class User(BaseModel):
    __tablename__ = 'users'

    query: sql.Select

    user_id = Column(db.BigInteger, primary_key=True)
    username = Column(db.String(20))
    full_name = Column(db.String(40))
    balance = Column(db.Numeric(precision=9, scale=2, decimal_return_scale=2),
                     default=0)

    phone = Column(db.String(15), default=None)
    shipping_info = Column(db.String(100))

    referral = Column(db.BigInteger)
Пример #7
0
class ProductsCategories(BaseModel):
    __tablename__ = 'products_categories'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(100))

    query: sql.Select
Пример #8
0
class Course(db.Model):
    __tablename__ = 'courses'
    query: sql.Select

    # Уникальный идентификатор товара
    id = Column(Integer, Sequence('plate_id_seq'), primary_key=True)

    # Название блюда (для отображения в колбек дате)
    name = Column(db.String(50))

    # Тип меню (для отображения в кнопке)
    menu_type = Column(String(50))

    # Тип блюда (для отображения в кнопке)
    course_type = Column(String(50))

    price = Column(Integer)

    # Описание блюда
    description = Column(String(255))

    # Название ресторана (для отображения в кнопке)
    rest = Column(String(50))

    course_code = Column(String(50))
Пример #9
0
class Item(BaseModel):
    __tablename__ = "items"

    query: sql.Select

    id = Column(db.Integer, Sequence("item_id_seq"), primary_key=True)
    name = Column(db.String(20))
    photo_id = Column(db.String(100))
    small_photo = Column(db.String(50))
    description = Column(db.String(250))
    price: Decimal = Column(
        Numeric(precision=9, scale=2, decimal_return_scale=2))

    def __repr__(self):
        return \
            f"""
Пример #10
0
class User(db.Model):
    __tablename__ = 'users'
    query: sql.Select

    id = db.Column(db.Integer, Sequence('user_id_seq'), primary_key=True)
    user_name = db.Column(db.String(50))
    user_tg_id = db.Column(db.Integer, unique=True, index=True)
    date_of_create = db.Column(DateTime, default=datetime.utcnow)

    def __repr__(self):
        return f'''
Пример #11
0
class Weight(db.Model):
    __tablename__ = 'weight'
    query: sql.Select

    id = db.Column(db.Integer, primary_key=True)
    user_weight = db.Column(db.String(10))
    date_of_update = db.Column(DateTime, default=datetime.utcnow)
    users_id = db.Column(db.Integer, db.ForeignKey('users.user_tg_id'))

    def __repr__(self):
        return f'''
Пример #12
0
class Promocode(BaseModel):
    __tablename__ = "promocodes"

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    code = db.Column(db.String(50), unique=True)
    day_expire = db.Column(db.Integer, default=0)
    start = db.Column(db.Date, default='2020-01-01')
    finish = db.Column(db.Date, default='2099-12-31')

    @classmethod
    async def get(cls, code: str):
        item = await cls.query.where(cls.code == code.upper()).gino.first()
        return item
Пример #13
0
class MenuOptions(db.Model):
    __tablename__ = 'menuoptions'
    query: sql.Select

    id = Column(db.Integer, Sequence("user_id_seq"), primary_key=True)
    category_code = Column(db.String(20))
    category_name = Column(db.String(50))

    subcategory_code = Column(db.String(20))
    subcategory_name = Column(db.String(50))

    name = Column(db.String(50))
    photo = Column(db.String(250))
Пример #14
0
class Rest(db.Model):
    __tablename__ = 'restaurants'
    query: sql.Select

    # Уникальный идентификатор товара
    id = Column(Integer, Sequence('rest_id_seq'), primary_key=True)

    # Имя ресторана (для отображения в колбек дате)
    rest_name = Column(db.String(50))

    # Уникальный код ресторана (для отображения в колбек дате)
    rest_code = Column(String(20))

    # Логин владельца (для отображения в кнопке)
    login = Column(String(50))

    # Пароль владельца (для отображения в колбек дате)
    password = Column(String(50))

    # Номер телефона ресторана (для отображения в кнопке)
    phone = Column(String(50))

    # Описание ресторана
    description = Column(String(255))
Пример #15
0
class Order(TimedBaseModel):
    __tablename__ = 'orders'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    customer_id = db.Column(db.BigInteger,
                            db.ForeignKey('customers.id'),
                            nullable=False)
    status_id = db.Column(db.Integer,
                          db.ForeignKey('statuses.id'),
                          nullable=False)
    discount_percent = db.Column(db.Integer, default=0)

    subtotal = db.Column(db.Integer, default=0)
    customer_discount = db.Column(db.Integer, default=0)
    promocode_discount = db.Column(db.Integer, default=0)
    bonuses = db.Column(db.Integer, default=0)
    noncash = db.Column(db.Integer, default=0)
    total = db.Column(db.Integer, default=0)

    comment = db.Column(db.String(255), default='')

    query: sql.Select

    async def add_product(self, product: Product, price: int):
        try:
            from utils.db_api.models.orders_lines import OrderLine
            await OrderLine.add(order=self,
                                product=product,
                                price=price,
                                quantity=1)
            await self.recalculate()
            return self
        except UniqueViolationError:
            pass

    async def recalculate(self):
        from utils.db_api.models.orders_lines import OrderLine
        items = await OrderLine.query.where(OrderLine.order_id == self.id
                                            ).gino.all()
        subtotal = 0
        customer_discount = 0
        promocode_discount = 0
        bonuses = 0
        noncash = 0

        self_update = {}

        for item in items:
            item_update = dict()
            if item.deleted_at:
                if not item.customer_discount == 0:
                    item_update.update({'customer_discount': 0})
                if not item.promocode_discount == 0:
                    item_update.update({'promocode_discount': 0})
                if not item.bonuses == 0:
                    item_update.update({'bonuses': 0})
                if not item.noncash == 0:
                    item_update.update({'noncash': 0})
            else:
                subtotal += item.price * item.quantity
                customer_discount += int(item.price * item.quantity *
                                         self.discount_percent / 100)
                if item.customer_discount != int(
                        item.price * self.discount_percent / 100):
                    item_update.update({
                        'customer_discount':
                        int(item.price * item.quantity *
                            self.discount_percent / 100)
                    })

            if item_update:
                await item.update(**item_update).apply()

        total = subtotal - customer_discount - promocode_discount - bonuses - noncash

        if self.subtotal != subtotal:
            self_update.update({'subtotal': subtotal})
        if self.customer_discount != customer_discount:
            self_update.update({'customer_discount': customer_discount})
        if self.promocode_discount != promocode_discount:
            self_update.update({'promocode_discount': promocode_discount})
        if self.bonuses != bonuses:
            self_update.update({'bonuses': bonuses})
        if self.noncash != noncash:
            self_update.update({'noncash': noncash})
        if self.total != total:
            self_update.update({'total': total})
        if self_update:
            await self.update(**self_update).apply()

    async def get_lines(self, include_deleted=False):
        from utils.db_api.models.orders_lines import OrderLine
        if include_deleted:
            items = await OrderLine.query.where(OrderLine.order_id == self.id
                                                ).gino.all()
        else:
            items = await OrderLine.query.where(
                and_(OrderLine.order_id == self.id,
                     OrderLine.deleted_at == None)).gino.all()

        return items

    async def set_satus(self, new_status_id: int):
        if new_status_id == 2:
            await self.update(status_id=new_status_id).apply()

    async def get_description(self, need_recalculate: bool = False):

        if need_recalculate:
            await self.recalculate()

        result = f"Заказ №{self.id}\n"
        result += f"-" * 50 + "\n\n"
        order_lines = await self.get_lines()

        for line_number, order_line in enumerate(order_lines, 1):
            result += f"{line_number}. " + await order_line.get_description(
            ) + "\n"

        result += f"-" * 50 + "\n"
        result += "\n"
        if self.subtotal:
            result += f"Сумма товаров: {self.subtotal}{currency_symbol}\n"
        if self.customer_discount:
            result += f"Скидка {self.discount_percent}%: {self.customer_discount}{currency_symbol}\n"
        if self.noncash:
            result += f"Оплачено: {self.noncash}{currency_symbol}\n"
        if self.total:
            result += f"К оплате: {self.total} \n"
        return result

    @classmethod
    async def add(cls, tg_user: types.User):
        try:
            obj = Order(customer_id=tg_user.id, status_id=1)
            await obj.create()
            return obj
        except UniqueViolationError:
            pass

    @classmethod
    async def get_or_add(cls, tg_user: types.User):
        obj = await cls.get(tg_user=tg_user, status_id=1)
        if not obj:
            obj = await cls.add(tg_user=tg_user)
        return obj

    @classmethod
    async def get(cls,
                  order_id: int = None,
                  tg_user: types.User = None,
                  status_id: int = 1):
        if order_id:
            obj = await cls.query.where(cls.id == order_id).gino.first()
        else:
            obj = await cls.query.where(
                and_(cls.customer_id == tg_user.id,
                     cls.status_id == status_id)).gino.first()

        return obj