Esempio n. 1
0
class SubCategory(Base):
    __tablename__ = "sub_category"

    sub_category_id = Column(Integer, primary_key=True)
    name = Column(String(50), unique=True, nullable=False)
    category_id = Column(Integer,
                         ForeignKey("category.category_id"),
                         index=True,
                         nullable=False)
    category = relationship("Category", backref="sub_category")

    def __repr__(self):
        return self.name

    def __call__(self, name, category):
        try:
            self.name = name
            self.category = category
            session.add(self)
            session.commit()
            return True

        except Exception as e:
            print("Adding subcategory error: ", e)
            session.rollback()
            return False

    def serialize(self):
        return {
            "sub_category_id": self.sub_category_id,
            "name": self.name,
            "category_id": self.category_id
        }

    @classmethod
    def read_sub_cat(cls):
        try:
            return [sub.serialize() for sub in cls.query.all()]
        except:
            session.rollback()

    @classmethod
    def read_drink_sub_categories(cls):
        try:
            return session.query(cls).join(
                cls.category).filter_by(name="Drinks").all()
        except:
            session.rollback()

    @classmethod
    def read_all_subcategories_filter_by(cls, *args, **kwargs) -> list:
        """
            returns tuple objects
            tuples are made of attributes specified as args
        """
        query = session.query(*[getattr(cls, i)
                                for i in args]).filter_by(**kwargs).all()
        if len(args) == 1 and query:
            query = [i[0] for i in query]
        return query
Esempio n. 2
0
class CashOnDelivery(Base):
    __tablename__ = "cash_on_delivery"

    transaction_id = Column(Integer, primary_key=True)
    payment_id = Column(Integer,
                        ForeignKey("payment.payment_id"),
                        index=True,
                        nullable=False)
    payment = relationship("Payment", backref="cash_on_delivery")
    transaction_ref = Column(String(50), nullable=False)
    status = Column(Enum("pending", "failed", "confirmed", "cancelled"),
                    nullable=False)

    def __call__(self, **kwargs):
        try:
            self.payment_id = kwargs.get("payment_id")
            self.transaction_ref = kwargs.get("transaction_ref")
            self.status = "pending"

            session.add(self)
            session.commit()
            return True

        except Exception as e:
            print("Error whilst recording transaction: ", e)
            session.rollback()
            return False

    @classmethod
    def read_cash_on_delivery(cls, **kwargs):
        return cls.query.filter_by(**kwargs).first()
Esempio n. 3
0
class Category(Base):
    __tablename__ = "category"

    category_id = Column(Integer, primary_key=True)
    name = Column(String(50), unique=True, nullable=False)

    def __repr__(self):
        return self.name

    def __call__(self, name):
        try:
            self.name = name
            session.add(self)
            session.commit()
            return True

        except Exception as e:
            print("Adding Category error: ", e)
            session.rollback()
            return False

    def read_category(self, id):
        return session.query(self).filter_by(category_id=id).first()

    @classmethod
    def read_categories(cls):
        return session.query(cls).all()

    @classmethod
    def read_all_categories_by_attr(cls, *args) -> list:
        query = session.query(*[getattr(cls, i) for i in args]).all()
        if len(args) == 1 and query:
            query = [i[0] for i in query]
        return query
Esempio n. 4
0
class PaymentMethods(Base):
    __tablename__ = "payments_methods"

    id = Column(Integer, primary_key=True)
    method = Column(String(20), nullable=False, unique=True)
    is_available = Column(Boolean, nullable=False)

    def __repr__(self):
        return self.method

    @classmethod
    def read_method(cls, **kwargs):
        _method = cls.query.filter_by(**kwargs).first()
        return _method

    @classmethod
    def read_all_methods(cls, **kwargs):
        return cls.query.fliter_by(**kwargs).all()

    def serialize(self):
        return {
            "id": self.id,
            "method": self.method,
            "is_available": self.is_available
        }
Esempio n. 5
0
class Payment(Base):
    __tablename__ = "payment"

    payment_id = Column(Integer, primary_key=True)
    payment_date = Column(DateTime, default=datetime.now(), nullable=False)
    payment_method_id = Column(Integer,
                               ForeignKey("payments_methods.id"),
                               index=True,
                               nullable=False)
    payment_method = relationship("PaymentMethods", backref="payment")
    order_id = Column(Integer,
                      ForeignKey("order.id"),
                      index=True,
                      nullable=False)
    order = relationship("Order", uselist=False, backref="payment")

    def __call__(self, **kwargs):
        try:
            self.payment_method_id = kwargs.get("payment_method_id")
            self.order_id = kwargs.get("order_id")

            session.add(self)
            session.commit()
            return True

        except Exception as e:
            print("Error whilst adding payment record: ", e)
            session.rollback()
            return False
Esempio n. 6
0
class CouponPayment(Base):
    __tablename__ = "coupon_payment"

    transaction_id = Column(Integer, primary_key=True)
    payment_id = Column(Integer,
                        ForeignKey("payment.payment_id"),
                        index=True,
                        nullable=False)
    payment = relationship("Payment", backref="coupon_payment")
    transaction_ref = Column(String(50), nullable=False)
    status = Column(Enum("pending", "failed", "confirmed", "cancelled"),
                    nullable=False)

    def __repr__(self):
        return self.transaction_id

    def __call__(self, **kwargs):
        try:
            self.payment_id = kwargs.get("payment_id")
            self.transaction_ref = kwargs.get("transaction_ref")
            self.status = "pending"

            session.add(self)
            session.commit()
            return True

        except Exception as e:
            print("Error whilst recording transaction: ", e)
            session.rollback()
            return False
Esempio n. 7
0
class TrackProducts(Base):
    __tablename__ = "trackprodcuts"

    id = Column(Integer, primary_key=True)
    quantity = Column(BigInteger, nullable=False)
    date = Column(DateTime, default=datetime.now, nullable=False)
    product_id = Column(Integer, ForeignKey("products.product_id"),index=True, nullable=False)
    product = relationship("Products", backref="trackproducts")

    def __repr__(self):
        """ String representation """
        return self.product_id

    def __call__(self, **kwargs):
        try:
            self.quantity = kwargs.get("quantity")
            self.product_id = kwargs.get("product_id")
            session.add(self)
            session.commit()
            return True

        except Exception as e:
            print("Error whilst adding tracking product detail: ", e)
            session.rollback()
            return False
Esempio n. 8
0
class DeliveryDetails(Base):
    __tablename__ = "delivery_details"

    id = Column(Integer, primary_key=True)
    county = Column(String(50), nullable=False)
    sub_county = Column(String(50), nullable=False)
    village = Column(String(50), nullable=False)
    other_details = Column(String(500), nullable=False)
    courier_id = Column(Integer,
                        ForeignKey("courier.id"),
                        index=True,
                        nullable=True)
    courier = relationship("Courier", backref="delivery_details")
    customer_id = Column(Integer,
                         ForeignKey("customer.id"),
                         index=True,
                         nullable=False)
    customer = relationship("Customer", backref="delivery_details")
    order_id = Column(Integer,
                      ForeignKey("order.id"),
                      index=True,
                      nullable=False)
    order = relationship("Order", uselist=False, backref="delivery_details")
    date = Column(DateTime, default=datetime.now())

    def __call__(self, **kwargs):
        try:
            self.county = kwargs.get("county")
            self.sub_county = kwargs.get("sub_county")
            self.village = kwargs.get("village")
            self.other_details = kwargs.get("other_details")
            self.order_id = kwargs.get("order_id")
            self.customer_id = kwargs.get("customer_id")

            session.add(self)
            session.commit()
            return True

        except Exception as e:
            print("Error whilst recording delivery details: ", e)
            session.rollback()
            return False

    @classmethod
    def assign_courier(cls, courier_id, order_id):
        order = cls.query.filter_by(order_id=order_id).first()
        order.courier_id = courier_id
        session.commit()

    @classmethod
    def get_order_delivery_address(cls, order_id):
        return cls.query.filter_by(order_id=order_id).first()
class HomeImages(Base):
    __tablename__ = "home_images"

    image_id = Column(Integer, primary_key=True)
    info_type = Column(String(100), nullable=False)
    image_name = Column(String(100), nullable=False)
    image_desc = Column(String(500), nullable=True)

    def serialize(self):
        return {
            "id": self.image_id,
            "info_type": self.info_type,
            "image_name": self.image_name,
            "image_desc": self.image_desc
        }

    @classmethod
    def home_images(cls):
        try:
            images = cls.query.all()
            return [image.serialize() for image in images]

        except:
            session.rollback()

    @classmethod
    def read_image(cls, id):
        try:
            image = cls.query.filter_by(image_id=id).first()
            return image.serialize()
        except:
            session.rollback()

    @classmethod
    def delete_image(cls, id):
        try:
            image = cls.query.filter_by(image_id=id).first()
            if image:
                session.query(cls).filter_by(image_id=id).delete()
                session.commit()
                return True
            else:
                return False
        except:
            session.rollback()
Esempio n. 10
0
class Sales(Base):
    __tablename__ = "sales"

    sales_id = Column(Integer, primary_key=True)
    product_id = Column(Integer,
                        ForeignKey("products.product_id"),
                        index=True,
                        nullable=False)
    products = relationship("Products", backref="sales")
    quantity = Column(BigInteger, nullable=False)
    amount = Column(BigInteger, nullable=False)
    commision_amount = Column(BigInteger, nullable=False)
    date = Column(DateTime, default=datetime.now(), nullable=False)

    def __repr__(self):
        return str(self.product_id)

    def __call__(self, **kwargs):
        try:
            self.product_id = kwargs.get("product_id")
            self.quantity = kwargs.get("quantity")
            self.amount = kwargs.get("amount")
            self.commision_amount = kwargs.get("commission_amount", 0)
            session.add(self)
            return True

        except Exception as e:
            session.rollback()
            print("Error whilst adding a sale :", e)
            return False

    @classmethod
    def read_sales_sum(cls, attr, *args):
        sales_sum = session.query(func.sum(attr)).filter(*args).scalar()
        return sales_sum if sales_sum else 0

    @hybrid_property
    def sales_day(self):
        return self.date.day

    @sales_day.expression
    def sales_day(cls):
        return extract("day", cls.date)

    @hybrid_property
    def sales_month(self):
        return self.date.month

    @sales_month.expression
    def sales_month(cls):
        return extract("month", cls.date)

    @hybrid_property
    def sales_year(self):
        return self.date.year

    @sales_year.expression
    def sales_year(cls):
        return extract("year", cls.date)
Esempio n. 11
0
class Brand(Base):
    __tablename__ = "brand"

    brand_id = Column(Integer, primary_key=True)
    name = Column(String(50), unique=True, nullable=False)

    def __repr__(self):
        return self.name

    def __call__(self, name):
        try:
            self.name = name
            session.add(self)
            session.commit()

        except Exception as e:
            print("Adding brand error: ", e)
            session.rollback()
            raise

    @classmethod
    def read_brand(cls, **kwargs):
        return session.query(cls).filter_by(**kwargs).first()

    @classmethod
    def read_brand_filter(cls, *args):
        return session.query(cls).filter(*args).first()

    @classmethod
    def read_all_bandss_filter_by(cls,*args, **kwargs)->list:
        """
            returns tuple objects
            tuples are made of attributes specified as args
        """
        query = session.query(*[getattr(cls,i) for i in args]).filter_by(**kwargs).all()
        if len(args) == 1 and query:
            query = [i[0] for i in query]
        return query
Esempio n. 12
0
class MobileMoney(Base):
    __tablename__ = "mobile_money"

    transaction_id = Column(Integer, primary_key=True)
    payment_id = Column(Integer,
                        ForeignKey("payment.payment_id"),
                        index=True,
                        nullable=False)
    payment = relationship("Payment", backref="mobile_money")
    name = Column(String(50), nullable=False)
    email = Column(String(50), nullable=False)
    amount = Column(BigInteger, nullable=False)
    contact = Column(String(13), nullable=False)
    status = Column(Enum("pending", "failed", "confirmed", "cancelled"),
                    nullable=False)
    transaction_ref = Column(String(50), nullable=False)
Esempio n. 13
0
class AccountType(Base):
    __tablename__ = "account_type"

    id = Column(Integer, primary_key=True)
    type_name = Column(String(50), nullable=False, unique=True)

    def __call__(self, **kwargs):
        try:
            self.type_name = kwargs.get("type_name")

            session.add(self)
            session.commit()
            return self

        except Exception as e:
            print("Error whilst adding account_type: ", e)
            session.rollback()
            return False

    def __repr__(self):
        return self.type_name

    def get_employee(self):
        return self.query.filter_by(type_name="Employee").first()
Esempio n. 14
0
class DeliveryMethods(Base):
    __tablename__ = "delivery_methods"

    id = Column(Integer, primary_key=True)
    method = Column(String(30), nullable=False)
    availability_period = Column(Integer, nullable=False)
    is_available = Column(Boolean, default=False, nullable=False)

    def __repr__(self):
        return self.id

    def __call__(self, **kwargs):
        try:
            self.method = kwargs.get("method")
            self.availability_period = kwargs.get("availability_period")

            session.add(self)
            session.commit()
            return True

        except Exception as e:
            print("Error whilst adding delivery method: ", e)
            session.rollback()
            return False
Esempio n. 15
0
class PlacePrices(Base):
    __tablename__ = "place_prices"

    id = Column(Integer, primary_key=True)
    district_name = Column(String(100), nullable=False)
    parish_name  = Column(String(100), nullable=True, default='Arua city')
    sub_county_name = Column(String(100), nullable=False)
    village = Column(String(100), nullable=False)
    fee = Column(Integer, nullable=False, default=0)

    def __repr__(self):
        return self.village

    def __call__(self, **kwargs):
        try:
            self.district_name = kwargs.get("county_name")
            self.parish_name = kwargs.get("parish_name", "Arua city")
            self.sub_county_name = kwargs.get("sub_county_name")
            self.village = kwargs.get("village")
            self.fee = kwargs.get("fee")

            session.add(self)
            session.commit()
            return True

        except Exception as e:
            print("Adding Place fee error: ", e)
            session.rollback()
            return False

    def serialize(self):
        return {
            "village": self.village,
            "fee": self.fee,
            "sub_county_name": self.sub_county_name,
            "county_name": self.district_name
        }

    @classmethod
    def read_place_prices(cls):
        try:
            return [place.serialize() for place in cls.query.all()]
        except Exception as e:
            print("Error Whilst retriving places: ", e)
Esempio n. 16
0
class Rate(Base):
    __tablename__ = "rate"

    id = Column(Integer, primary_key=True)
    rate = Column(BigInteger, nullable=False)
    customer_id = Column(Integer,
                         ForeignKey("customer.id"),
                         index=True,
                         nullable=False)
    product_id = Column(Integer,
                        ForeignKey("products.product_id"),
                        index=True,
                        nullable=False)
    customer = relationship("Customer", backref="rate")
    products = relationship("Products", backref="rate")

    def __repr__(self):
        return str(self.product_id)

    def __call__(self, **kwargs):
        try:
            self.rate = kwargs.get("rate")
            self.customer_id = kwargs.get("customer_id")
            self.product_id = kwargs.get("product_id")
            session.add(self)
            session.commit()
            return True

        except Exception as e:
            print("Error while rating a product :", e)
            session.rollback()
            return False

    @classmethod
    def read_product_rate(cls, product_id):
        try:
            pdt_ratings = session.query(func.count(cls.rate), cls.rate)\
                .group_by(cls.rate).filter_by(product_id=product_id).all()

            numerator = 0
            denomenator = 0

            for rate in pdt_ratings:
                denomenator += rate[0]

                if rate[1] == 5:
                    numerator += rate[0] * 100

                elif rate[1] == 4:
                    numerator += rate[0] * 80

                elif rate[1] == 3:
                    numerator += rate[0] * 60

                elif rate[1] == 2:
                    numerator += rate[0] * 40

                elif rate[1] == 1:
                    numerator += rate[0] * 20

            if pdt_ratings:
                return int(((numerator / denomenator) / 100) * 5)
            else:
                return 0
        except:
            session.rollback()
Esempio n. 17
0
class Resturant(Base):
    __tablename__ = "resturant"

    id = Column(Integer, primary_key=True)
    business_name = Column(String(100), nullable=False)
    business_profile_picture = Column(String(100), nullable=False)
    deals_in = Column(Enum("drinks", "food", "Vegetables$Fruits"))
    address = Column(String(255), nullable=False)
    email = Column(String(50), nullable=False)
    contact = Column(String(13), unique=True, nullable=False)
    second_contact = Column(String(13), unique=True, nullable=False)
    location = Column(String(200), nullable=False)
    description = Column(String(500), nullable=False)
    admin_names = Column(String(50), unique=True, nullable=False)
    admin_username = Column(String(50), unique=True, nullable=False)
    admin_email = Column(String(50), nullable=False)
    admin_telephone = Column(String(13), unique=True, nullable=False)
    date_of_registration = Column(DateTime,
                                  default=datetime.now(),
                                  nullable=False)
    favourite = Column(Boolean, nullable=False, default=False)
    approved = Column(Boolean, nullable=False, default=False)
    operation_start_time = Column(DateTime,
                                  default=datetime.now(),
                                  nullable=False)
    operation_stop_time = Column(DateTime,
                                 default=datetime.now(),
                                 nullable=False)

    #standard_delivery_fee = Column(Float, nullable=False, default=0.0)

    def __repr__(self):
        return self.business_name

    def __call__(self, **kwargs):
        try:
            self.business_name = kwargs.get("business_name")
            self.business_profile_picture = kwargs.get(
                "business_profile_picture")
            self.address = kwargs.get("address")
            self.email = kwargs.get("email")
            self.contact = kwargs.get("contact")
            self.second_contact = kwargs.get("second_contact")
            self.location = kwargs.get("location")
            self.description = kwargs.get("description")
            self.admin_names = kwargs.get("admin_names")
            self.admin_username = kwargs.get("admin_user")
            self.admin_email = kwargs.get("admin_email")
            self.admin_telephone = kwargs.get("admin_telephone")

            session.add(self)
            session.commit()
            return True

        except Exception as e:
            print("Adding resturant error: ", e)
            session.rollback()
            return False

    def serialize(self):
        start_hour = ""
        start_mins = ""
        stop_hour = ""
        stop_mins = ""
        if len(str(self.operation_start_time.hour)) == 1:
            start_hour = "0" + str(self.operation_start_time.hour)
        else:
            start_hour = self.operation_start_time.hour

        if len(str(self.operation_start_time.minute)) == 1:
            start_mins = "0" + str(self.operation_start_time.minute)
        else:
            start_mins = self.operation_start_time.minute

        if len(str(self.operation_stop_time.hour)) == 1:
            stop_hour = "0" + str(self.operation_stop_time.hour)
        else:
            stop_hour = self.operation_stop_time.hour

        if len(str(self.operation_stop_time.minute)) == 1:
            stop_mins = "0" + str(self.operation_stop_time.minute)
        else:
            stop_mins = self.operation_stop_time.minute

        return {
            "id":
            self.id,
            "business_name":
            self.business_name,
            "business_profile_picture":
            self.business_profile_picture,
            "address":
            self.address,
            "email":
            self.email,
            "contact":
            self.contact,
            "second_contact":
            self.second_contact,
            "location":
            self.location,
            "description":
            self.description,
            "admin_names":
            self.admin_names,
            "admin_username":
            self.admin_username,
            "admin_email":
            self.admin_email,
            "admin_telephone":
            self.admin_telephone,
            "operation_start_time":
            "{hour}:{minute} AM".format(hour=start_hour, minute=start_mins),
            "operation_stop_time":
            "{hour}:{minute} PM".format(hour=stop_hour, minute=stop_mins),
            "operational_status":
            False
        }

    @property
    def read_rest_total_products_count(self):
        total = session.query(func.count(pdts.Products.product_id))\
            .filter(pdts.Products.resturant_id==self.id).scalar()
        return total if total else 0

    @property
    def approved_products_count(self):
        total = session.query(func.count(pdts.Products.product_id))\
            .filter(pdts.Products.resturant_id==self.id, pdts.Products.approved==True).scalar()
        return total if total else 0

    @property
    def not_approved_products_count(self):
        total = session.query(func.count(pdts.Products.product_id))\
                .filter(pdts.Products.resturant_id==self.id, pdts.Products.approved==False).scalar()
        return total if total else 0

    @property
    def suspended_products_count(self):
        total = session.query(func.count(pdts.Products.product_id))\
                .filter(pdts.Products.resturant_id==self.id, pdts.Products.suspend==True).scalar()
        return total if total else 0

    @property
    def read_all_rest_products(self):
        products = session.query(
            pdts.Products).filter_by(resturant_id=self.id).all()
        return products

    @property
    def read_all_approved_products(self):
        products = session.query(pdts.Products).filter(
            pdts.Products.resturant_id == self.id,
            pdts.Products.approved == True).all()
        return products

    @property
    def read_all_non_approved_products(self):
        products = session.query(pdts.Products).filter(
            pdts.Products.resturant_id == self.id,
            pdts.Products.approved == False).all()
        return products

    @property
    def read_all_suspended_products(self):
        products = session.query(pdts.Products).filter(
            pdts.Products.resturant_id == self.id,
            pdts.Products.suspend == True).all()
        return products

    @classmethod
    def read_restaurant(cls, id):
        try:
            return cls.query.filter_by(id=id).first()
        except:
            session.rollback()

    @classmethod
    def read_restaurants(cls):
        try:
            # rest = []
            # restaurants = cls.query.all()
            # for restaurant in restaurants:
            #     if restaurant.deals_in != "drinks":
            #         if restaurant.approved:
            #             rest.append(restaurant)
            return list(rest_generator(cls.query.all()))
        except:
            session.rollback()

    @classmethod
    def read_all_rests(cls):
        try:
            return cls.query.all()
        except Exception as e:
            session.rollback()

    @classmethod
    def read_restaurants_count(cls):
        try:
            return session.query(func.count(cls.id)).scalar()
        except:
            session.rollback()

    @classmethod
    def read_all_restaurants_filter_by(cls, *args, **kwargs) -> list:
        """
            returns tuple objects
            tuples are made of attributes specified as args
        """
        query = session.query(*[getattr(cls, i)
                                for i in args]).filter_by(**kwargs).all()
        if len(args) == 1 and query:
            query = [i[0] for i in query]
        return query
Esempio n. 18
0
class Courier(Base):
    __tablename__ = "courier"

    id = Column(Integer, primary_key=True)
    courier_name = Column(String(100), nullable=False)
    driver_license_number = Column(String(30), unique=True, nullable=False)
    contact = Column(String(13), unique=True, nullable=False)
    second_contact = Column(String(13), unique=True, nullable=False)
    email = Column(String(30), nullable=False)
    address = Column(String(500), nullable=False)
    district = Column(String(50), nullable=False)
    vehicle_type = Column(String(20), nullable=False)
    vehicle_license_plate_number = Column(String(20), nullable=False)
    courier_pic = Column(String(50), nullable=False)
    local_council_1_letter = Column(String(50), nullable=False)
    agreement_letter = Column(String(50), nullable=False)
    national_id_number = Column(String(20), nullable=False)
    registration_date = Column(DateTime,
                               default=datetime.now(),
                               nullable=False)
    is_available = Column(Boolean, default=True, nullable=False)

    def __repr__(self):
        return self.id

    def __call__(self, **kwargs):
        try:
            self.courier_name = kwargs.get("courier_name")
            self.driver_license_number = kwargs.get("driver_license_number")
            self.contact = kwargs.get("contact")
            self.second_contact = kwargs.get("second_contact")
            self.email = kwargs.get("email")
            self.address = kwargs.get("address")
            self.district = kwargs.get("district")
            self.vehicle_type = kwargs.get("vehicle_type")
            self.vehicle_license_plate_number = kwargs.get(
                "vehicle_license_plate_number")
            self.courier_pic = kwargs.get("courier_pic")
            self.local_council_1_letter = kwargs.get("local_council_1_letter")
            self.agreement_letter = kwargs.get("agreement_letter")
            self.national_id_number = kwargs.get("national_id_number")

            session.add(self)
            session.commit()
            return True

        except Exception as e:
            print("Error whilst adding courier: ", e)
            session.rollback()
            return False

    def serialize(self):
        return {
            "courier_id": self.id,
            "courier_name": self.courier_name,
            "driver_license_number": self.driver_license_number,
            "vehicle_reg": self.vehicle_license_plate_number,
            "vehicle_type": self.vehicle_type,
            "contact": self.contact,
            "email": self.email,
            "address": self.address,
            "NIN": self.national_id_number
        }

    @classmethod
    def read_courier(cls, **kwargs):
        return cls.query.filter_by(**kwargs).first()

    @classmethod
    def read_courier_districts(cls):
        return session.query(cls.district).group_by(cls.district).all()

    @classmethod
    def read_district_couriers(cls, district):
        return cls.query.filter_by(district=district, is_available=True).all()

    @classmethod
    def read_couriers(cls):
        return cls.query.all()

    @property
    def deliveries_count(self):
        count = session.query(func.count(dd.DeliveryDetails.id))\
            .filter(dd.DeliveryDetails.courier_id == self.id).scalar()

        return count if count else 0
Esempio n. 19
0
class StaffAccounts(Base, UserMixin):
    __tablename__ = "staff_accounts"

    id = Column(Integer, primary_key=True)
    username = Column(String(50), nullable=False, unique=True)
    password = Column(String(255), nullable=False)
    email = Column(String(50), unique=True, nullable=False)
    name = Column(String(100), nullable=False)
    contact = Column(String(13), nullable=False, unique=True)
    address = Column(String(255), nullable=False)
    account_active = Column(Boolean, default=True, nullable=False)
    account_type_id = Column(Integer,
                             ForeignKey("account_type.id"),
                             index=True,
                             nullable=False)
    account_type = relationship("AccountType", backref="staff_accounts")

    # def __repr__(self):
    #     return self.username

    def __call__(self, **kwargs):
        try:
            self.username = kwargs.get("username")
            self.hash_password(kwargs.get("password"))
            self.email = kwargs.get("email")
            self.name = kwargs.get("name")
            self.contact = kwargs.get("contact")
            self.address = kwargs.get("address")
            self.account_type_id = kwargs.get("account_type_id")

            session.add(self)
            session.commit()
            return True

        except Exception as e:
            print("Error whilst adding user account: ", e)
            session.rollback()
            return False

    def update_employee_details(self, **kwargs):
        try:
            self.email = kwargs.get("email", self.email)
            self.name = kwargs.get("name", self.name)
            self.contact = kwargs.get("contact", self.contact)
            self.address = kwargs.get("address", self.address)
            session.commit()
        except Exception as e:
            session.rollback()
            raise Exception(f"Updating user error: {e}")

    def verify_password(self, password):
        return pwd_context.verify(password, self.password)

    @property
    def is_employee(self):
        return True

    @classmethod
    def read_user(cls, **kwargs):
        return cls.query.filter_by(**kwargs).first()

    @classmethod
    def admin_exists(cls):
        return session.query(cls).join("account_type").filter(
            AccountType.type_name == "administrator").first()

    def hash_password(self, password):
        self.password = pwd_context.hash(password)
Esempio n. 20
0
class Products(Base):
    __tablename__ = "products"

    product_id = Column(Integer, primary_key=True)
    name = Column(String(50), nullable=False)
    product_picture = Column(String(100), nullable=False)
    description = Column(String(1000), nullable=False)
    price = Column(BigInteger, nullable=False)
    buying_price = Column(BigInteger, nullable=False, default=0)
    selling_price = Column(BigInteger, nullable=False, default=0)
    served_with = Column(String(1000), nullable=False, default="none")
    # promotional_price = Column(BigInteger, nullable=True)
    promotional_price_set = Column(Boolean, default=False, nullable=False)
    commission_fee = Column(Float, default=0.0)
    resturant_id = Column(Integer, ForeignKey("resturant.id"), nullable=True)
    resturant = relationship("Resturant", backref="products")
    brand_id = Column(Integer,
                      ForeignKey("brand.brand_id"),
                      index=True,
                      nullable=False)
    brand = relationship("Brand", backref="products")
    sub_category_id = Column(Integer,
                             ForeignKey("sub_category.sub_category_id"),
                             index=True,
                             nullable=False)
    sub_category = relationship("SubCategory", backref="products")
    approved = Column(Boolean, nullable=False, default=False)
    suspend = Column(Boolean, nullable=False, default=False)
    headsup = Column(String(100), nullable=False, default="clickEat")
    free_delivery = Column(Boolean, nullable=False, default=False)

    def __repr__(self):
        return str(self.name)

    def __call__(self, **kwargs):
        try:
            self.name = kwargs.get("name")
            self.product_picture = kwargs.get("product_picture")
            self.description = kwargs.get("description")
            self.price = kwargs.get("price")
            self.resturant_id = kwargs.get("resturant_id")
            brand_name = kwargs.get("brand")
            self.sub_category_id = kwargs.get("sub_category_id")
            brand_exists = brnd.Brand.read_brand_filter(
                brnd.Brand.name.like("%{}%".format(brand_name)))
            if brand_exists:
                self.brand = brand_exists
            else:
                brand = brnd.Brand(name=brand_name)
                self.brand = brand

            self.buying_price = kwargs.get("buying_price", 0)
            self.selling_price = kwargs.get("selling_price", 0)
            self.served_with = kwargs.get("served_with", 'none')
            self.commission_fee = kwargs.get("commission_fee", 0.0)
            self.headsup = kwargs.get("headsup", "clickEat")

            session.add(self)
            session.commit()
            return True

        except Exception as e:
            print("Error while adding product: ", e)
            session.rollback()
            return False

    def serialize(self):
        return {
            "product_id": self.product_id,
            "name": self.name,
            "product_picture": self.product_picture,
            "description": self.description,
            "price": self.product_price,
            "resturant_id": self.resturant_id,
            "resturant": self.resturant.business_name,
            "brand_id": self.brand_id,
            "brand": self.brand.name,
            "sub_category_id": self.sub_category_id,
            "sub_category": self.sub_category.name,
            "promotional_price_set": self.promotional_price_set,
            "promotional_price": self.promotional_price,
            "headsup": self.headsup,
            "served_with": self.served_with,
            "free_delivery": self.free_delivery,
            "available": False
        }

    @property
    def product_price(self):
        if self.commission_fee != 0.0:
            product_price = self.commission_amount + self.price
            return product_price
        else:
            return self.price

    @property
    def promotional_price(self):
        if self.promotional_price_set:
            price = session.query(pdtds.ProductDiscounts).filter_by(
                product_id=self.product_id).first()
            return (price.price + self.commission_amount) if price else None
        else:
            return None

    @property
    def commission_amount(self):
        commission_amount = ((self.commission_fee) / 100) * self.price
        return math.ceil(commission_amount)

    @classmethod
    def read_products(cls):
        try:
            return cls.query.all()
        except:
            session.rollback()

    @classmethod
    def read_product(cls, id):
        try:
            product = cls.query.filter_by(product_id=id).first()
            if product:
                return product
        except:
            session.rollback()

    @classmethod
    def read_product_by_sub_cat(cls, sub_category_id):
        try:
            product = cls.query.filter_by(
                sub_category_id=sub_category_id).first()
            if product.approved and product.suspend != True:
                return product
            else:
                return None
        except:
            session.rollback()

    @classmethod
    def read_products_based_on_sub_cat(cls, sub_category_id):
        try:
            return cls.query.filter_by(sub_category_id=sub_category_id).all()
        except:
            session.rollback()

    @classmethod
    def read_products_count(cls):
        try:
            return session.query(func.count(cls.product_id)).scalar()
        except:
            session.rollback()

    @classmethod
    def home_products(cls):
        try:
            home_products = []
            home_products.append({
                "id":
                1,
                "title":
                "Favorite Food & Snacks",
                "products":
                sample(list(food_snacks_generator(cls.query.all())), 2)
            })
            home_products.append({
                "id":
                2,
                "title":
                "Drinks & Beverages",
                "products":
                sample(
                    list(
                        drinks_generator(
                            cls.query.filter_by(sub_category_id=6).all())), 2)
            })

            return home_products

        except:
            session.rollback()

    @classmethod
    def read_all_products(cls, return_query=False, **kwargs):
        """
            if return_query is set to True, will return query object,
            otherwise returns list.
        """
        if return_query:
            try:
                return cls.query.filter_by(**kwargs).first()
            except:
                session.rollback()
        else:
            try:
                _date = datetime.now(ni_timezone)
                current_time = _date.astimezone(timezone)
                products_based_on_sub_cat_dict = {}
                product_based_on_sub_cat_list = []
                restaurant_products = [
                    product for product in cls.query.filter_by(**kwargs).all()
                ]

                for product in restaurant_products:
                    if product.resturant.approved:
                        _start_date = ni_timezone.localize(
                            product.resturant.operation_start_time)
                        _end_date = ni_timezone.localize(
                            product.resturant.operation_stop_time)
                        operation_start_time = _start_date.astimezone(timezone)
                        operation_stop_time = _end_date.astimezone(timezone)
                        if product.approved and product.suspend != True:
                            if f"{product.sub_category}" in products_based_on_sub_cat_dict:
                                if product not in products_based_on_sub_cat_dict[
                                        f"{product.sub_category}"]:  #Avoid duplicates
                                    if current_time.hour >= operation_start_time.hour and current_time.hour <= operation_stop_time.hour:
                                        pdt = product.serialize()
                                        pdt["available"] = True
                                        products_based_on_sub_cat_dict[
                                            f"{product.sub_category}"] += [
                                                pdt
                                            ]  #Add the product to this group
                                    else:
                                        products_based_on_sub_cat_dict[
                                            f"{product.sub_category}"] += [
                                                product.serialize()
                                            ]
                            else:
                                if current_time.hour >= operation_start_time.hour and current_time.hour <= operation_stop_time.hour:
                                    pdt = product.serialize()
                                    pdt["available"] = True
                                    products_based_on_sub_cat_dict[
                                        f"{product.sub_category}"] = [pdt]
                                else:
                                    products_based_on_sub_cat_dict[
                                        f"{product.sub_category}"] = [
                                            product.serialize()
                                        ]

                for sub_cat, products in products_based_on_sub_cat_dict.items(
                ):
                    banch = {"sub_category": sub_cat, "products": products}
                    product_based_on_sub_cat_list.append(banch)

                return product_based_on_sub_cat_list

            except:
                session.rollback()
Esempio n. 21
0
class Customer(Base, UserMixin):
    __tablename__ = "customer"

    id = Column(Integer, primary_key=True)
    name = Column(String(50), nullable=False)
    email = Column(String(50), nullable=True, unique=True)
    contact = Column(String(13), nullable=False, unique=True)
    second_contact = Column(String(13), nullable=True, unique=True)
    profile_picture = Column(String(50), default="click_eat.png")
    _password = Column(String(255), nullable=False)                                         
    date_of_registration = Column(DateTime, nullable=False, default=datetime.now())
    account_active = Column(Boolean, nullable=False, default=True)

    def __repr__(self):
        return self.name

    def __call__(self, **kwargs):
        try:
            self.name = kwargs.get("name")
            self.email = kwargs.get("email")
            self.contact = kwargs.get("contact")
            self.second_contact = kwargs.get("second_contact")
            self.profile_picture = kwargs.get("profile_picture")
            self.password = kwargs.get("password")
            session.add(self)
            session.commit()
            return True

        except Exception as e:
            print("Add customer Error: ", e)
            session.rollback()
            return False

    @property
    def password(self):
        return self._password

    @password.setter
    def password(self, password):
        self._password = pwd_context.hash(password)

    def verify_password(self, password):
        return pwd_context.verify(password, self.password)

    def change_password(self, old_password, new_password):
        if(self.verify_password(old_password)):
            new_password = pwd_context.hash(new_password)
            self._password = new_password
            session.commit()
            return True
        else:
            session.rollback()
            return False

    def update_customer(self, **kwargs):
        try:
            self.name = kwargs.get("name", self.name)
            self.email = kwargs.get("email", self.email)
            self.contact = kwargs.get("contact", self.contact)
            self.second_contact = kwargs.get("second_contact", self.second_contact)
            session.commit()
            return True

        except Exception as e:
            print("Update customer Error:", e)
            session.rollback()
            return False 

    def serializer(self):
        if self.cart:
            return {
                "customer_id": self.id,
                "names": self.name,
                "email": self.email,
                "contact": self.contact,
                "second_contact": self.second_contact,
                "date_of_reg": self.date_of_registration.strftime('%m/%d/%Y'),
                "account_active": self.account_active,
                "cart_size": int(self.cart[0].cart_total_quantity_or_item_count(self.id))
            }

        else:
            return {
                "customer_id": self.id,
                "names": self.name,
                "email": self.email,
                "contact": self.contact,
                "second_contact": self.second_contact,
                "date_of_reg": self.date_of_registration.strftime('%m/%d/%Y'),
                "account_active": self.account_active,
                "cart_size": 0
            }

    def delete_customer(self, id):
        try:
            self.query.filter_by(id=id).delete()
            session.commit()
        except:
            session.rollback()

    @classmethod
    def google_sign_in(cls, email):
        try:
            user = cls.query.filter_by(email=email).first()

            if user:
                token = TokenGenerator(user).generate_api_token()
                user = user.serializer()
                user["token"] = token
                return user
            else:
                return False
        except Exception as e:
            print("An error occured while saving customer google sigin details: ",e)

    @classmethod
    def check_user(cls,telephone,password):
        try:
            user = cls.query.filter_by(contact=telephone).first()
        
            if user and user.verify_password(password):
                token = TokenGenerator(user).generate_api_token()
                user = user.serializer()
                user["token"] = token
                return user
            elif not user:
                user = cls.query.filter_by(email=telephone).first()
                if user and user.verify_password(password):
                    token = TokenGenerator(user).generate_api_token()
                    user = user.serializer()
                    user["token"] = token
                    return user
            
            elif not user or not user.verify_password(password):
                return False

            else:
                return False
                
        except Exception as e:
            print(">>>>>>>>>>>>", e)
            session.rollback()

    @classmethod
    def read_customer_by_contact(cls, **kwargs):
        try:
            customer = cls.query.filter_by(contact=kwargs.get("telephone")).first()

            return customer
        except:
            session.rollback()

    @classmethod
    def read_customer(cls, **kwargs):
        try:
            customer = cls.query.filter_by(**kwargs).first()
            return customer
        except:
            session.rollback()

    @classmethod
    def read_customer_count(cls):
        try:
            return session.query(func.count(cls.id)).scalar()
        except:
            session.rollback()



            
Esempio n. 22
0
class Cart(Base):
    __tablename__ = "cart"

    id = Column(Integer, primary_key=True)
    product_id = Column(Integer)
    product_image = Column(String(50), nullable=False)
    product_name = Column(String(50), nullable=False)
    quantity = Column(BigInteger, nullable=False)
    unit_price = Column(BigInteger, nullable=False)
    commision_amount = Column(BigInteger, nullable=True)
    served_with = Column(String(1000), nullable=False, default="none")
    date = Column(DateTime, default=datetime.now(), nullable=False)
    is_ordered = Column(Boolean, default=False, nullable=False)
    customer_id = Column(Integer, ForeignKey("customer.id"), index=True, nullable=False)
    customer = relationship("Customer", backref="cart")
    order_id = Column(Integer, ForeignKey("order.id"), index=True)
    order = relationship("Order", backref="cart")
    free_delivery = Column(Boolean, nullable=False, default=False)
    restaurant = Column(String(100), nullable=False, default="clickEat")

    def __repr__(self):
        return self.product_name

    def __call__(self, **kwargs):
        try:
            self.product_id = kwargs.get("product_id")
            self.customer_id = kwargs.get("customer_id")
            self.product_name = kwargs.get("product_name")
            self.product_image = kwargs.get("product_image")
            self.unit_price = kwargs.get("unit_price")
            self.quantity = kwargs.get("quantity")
            self.served_with = kwargs.get("served_with", "none")
            self.free_delivery = kwargs.get("free_delivery", False)
            self.restaurant = kwargs.get("restaurant", "clickEat")
            item_exists = self.query.filter_by(
                customer_id = self.customer_id,
                product_id = self.product_id,
                is_ordered = False
            ).first()
            if item_exists:
                item_exists.quantity += int(self.quantity)
                session.commit()
                # if item_exists.quantity > product.quantity:
                #     session.rollback()
                #     print("Product already exists on cart and quantity you are specifying is more than what is available.")
                #     return False
                # else:
                #     session.commit()
            else:
                session.add(self)
                session.commit()

            return True

        except Exception as e:
            print("Error While adding to Cart: ", e)
            session.rollback()
            return False

    def serialize(self):
        return {
            "product_id": self.product_id,
            "product_name": self.product_name,
            "product_image": self.product_image,
            "unit_price": self.unit_price,
            "quantity": self.quantity,
            "served_with": self.served_with,
            "total": self.total,
            "total_quantity": int(self.cart_total_quantity_or_item_count(self.customer_id)),
            "cart_total_amount": int(self.cart_total_amount(self.customer_id)),
            "free_delivery": self.free_delivery,
            "restaurant": self.restaurant
        }

    @hybrid_property
    def total(self):
        return self.quantity * self.unit_price
        
    @classmethod
    def customer_order_items_total(cls, order_id):
        total = session.query(func.sum(cls.total))\
            .filter_by(
                order_id=order_id
                ).scalar()
        return total if total else 0

    @classmethod
    def read_customer_cart_items(cls, customer_id):
        try:
            cart_items = cls.query.filter_by(
                customer_id=customer_id,
                is_ordered=False
            ).all()

            return cls.update_cart_items_prices(cart_items)
        except:
            session.rollback()

    @classmethod
    def update_cart_items_prices(cls, cart_items):
        try:
            for item in cart_items:
                product = pdts.Products.read_all_products(return_query=True, product_id=item.product_id)
                if product.promotional_price_set:
                    if product.promotional_price:
                        item.unit_price = product.promotional_price
                    else:
                        item.unit_price = product.price
                else:
                    item.unit_price = product.price
            session.commit()

            customer_cart_items = {"cart_items": [cart_item.serialize() for cart_item in cart_items]}

            return customer_cart_items
        except:
            session.rollback()

    @classmethod
    def update_cart_item(cls, **kwargs):
        item = cls.query.filter_by(
                customer_id = kwargs.get("customer_id"),
                product_id = kwargs.get("product_id"),
                is_ordered = False
            ).first()

        if item:
            item.quantity = kwargs.get("quantity")
            session.commit()

            return cls.read_customer_cart_items(kwargs.get("customer_id"))

        else:
            return False


    @classmethod
    def cart_total_quantity_or_item_count(cls, customer_id):
        total = session.query(func.sum(cls.quantity))\
            .filter_by(
                customer_id=customer_id,
                is_ordered=False
            ).scalar()
        
        return total if total else 0

    @classmethod
    def cart_total_amount(cls, customer_id):
        total = session.query(func.sum(cls.total))\
            .filter_by(
                customer_id=customer_id,
                is_ordered=False
            ).scalar()
        
        return total if total else 0

    @classmethod
    def customer_order_items_total(cls, order_id):
        total = session.query(func.sum(cls.total))\
            .filter_by(
                order_id=order_id
                ).scalar()
        return total if total else 0

    @property
    def read_item_shop_details(self):
        shop_details = session.query(shp.Resturant.business_name, shp.Resturant.address, shp.Resturant.contact, shp.Resturant.second_contact).join(
            "products"
        ).filter(pdts.Products.product_id == self.product_id).first()
        shop_details = Markup(f"{shop_details[0]}.<br> <b>Location:</b> {shop_details[1]} <br><b>Contact: </b>{shop_details[2]}/ {shop_details[3]}") if shop_details else "Unkown"
        return shop_details


    @classmethod 
    def delete_cart_item(cls, id):
        try:
            product = cls.query.filter_by(product_id=id).first()
            cls.query.filter_by(product_id=id).delete()
            session.commit()
            return cls.read_customer_cart_items(product.customer_id)

        except Exception as e:
            print("Error whilst deleting cart item!!.", e)
            session.rollback()
            return False
Esempio n. 23
0
class Comments(Base):
    __tablename__ = "comments"

    id = Column(Integer, primary_key=True)
    comment = Column(String(500), nullable=False)
    date = Column(DateTime, default=datetime.now(), nullable=False)
    reply = Column(String(500))
    customer_id = Column(Integer,
                         ForeignKey("customer.id"),
                         index=True,
                         nullable=False)
    customer = relationship("Customer", backref="comments")
    product_id = Column(Integer,
                        ForeignKey("products.product_id"),
                        index=True,
                        nullable=False)
    products = relationship("Products", backref="comments")

    def __repr__(self):
        return str(self.id)

    def __call__(self, **kwargs):
        try:
            self.comment = kwargs.get("comment")
            self.customer_id = kwargs.get("customer_id")
            self.product_id = kwargs.get("product_id")
            session.add(self)
            session.commit()
            return True

        except Exception as e:
            print("Error whilst adding comment: ", e)
            session.rollback()
            return False

    def serialize(self):
        return {
            "product_id": self.product_id,
            "comment": self.comment,
            "date": self.date.strftime('%m/%d/%Y'),
            "reply": self.reply,
            "customerNames": self.customer.name
        }

    @classmethod
    def get_product_comments(cls, product_id):
        try:
            comments = cls.query.filter_by(product_id=product_id).order_by(
                desc(cls.date)).all()
            pdt_comments = (comment.serialize() for comment in comments)

            return pdt_comments
        except:
            session.rollback()

    @classmethod
    def product_comments(cls, product_id):
        try:
            comments = cls.query.filter_by(product_id=product_id).order_by(
                desc(cls.date)).all()

            return comments
        except:
            session.rollback()
Esempio n. 24
0
class CustomerAddress(Base):
    __tablename__ = "customer_addresses"

    id = Column(Integer, primary_key=True)
    county = Column(String(50), nullable=False)
    sub_county = Column(String(50), nullable=False)
    village = Column(String(50), nullable=False)
    other_details = Column(String(500), nullable=False)
    is_default = Column(Boolean)
    customer_id = Column(Integer,
                         ForeignKey("customer.id"),
                         index=True,
                         nullable=False)
    customer = relationship("Customer", backref="customer_addresses")

    def __call__(self, **kwargs):
        try:
            self.county = kwargs.get("county")
            self.sub_county = kwargs.get("sub_county")
            self.village = kwargs.get("village")
            self.other_details = kwargs.get("other_details")
            self.is_default = kwargs.get("is_default", self.is_default)
            self.customer_id = kwargs.get("customer_id")

            if self.is_default:
                self.query.filter_by(customer_id=self.customer_id).update(
                    {"is_default": False})

            if not self.query.filter_by(customer_id=self.customer_id).first():
                self.is_default = True

            session.add(self)
            session.commit()

            return True

        except Exception as e:
            print("Error whilst saving customer address: ", e)
            session.rollback()
            return None

    def serialize(self):
        return {
            "id": self.id,
            "county": self.county,
            "sub_county": self.sub_county,
            "village": self.village,
            "other_details": self.other_details,
            "is_default": self.is_default,
            "customer_id": self.customer_id
        }

    @classmethod
    def get_customer_addresses(cls, customer_id):
        try:
            customer_addresses = cls.query.filter_by(
                customer_id=customer_id).all()
            return [
                customer_address.serialize()
                for customer_address in customer_addresses
            ]
        except:
            session.rollback()

    @classmethod
    def update_customer_address(cls, **kwargs):
        try:
            address = cls.query.filter_by(id=kwargs.get("address_id")).first()
            address.county = kwargs.get("county")
            address.sub_county = kwargs.get("sub_county")
            address.village = kwargs.get("village")
            address.other_details = kwargs.get("other_details")
            session.commit()
            return True
        except Exception as e:
            print("Error: >>>>>>>>>>>>>>>>", e)
            session.rollback()
            return False

    @classmethod
    def delete_customer_address(cls, id):
        try:
            session.query(cls).filter_by(id=id).delete()
            session.commit()
            return True
        except Exception as e:
            print("Error: >>>>>>>>>>>>>", e)
            session.rollback()
            return False
Esempio n. 25
0
class Order(Base):
    __tablename__ = "order"

    id = Column(Integer, primary_key=True)
    order_ref = Column(String(50), unique=True, nullable=False)
    order_ref_simple_version = Column(String(50), unique=True, nullable=False)
    order_date = Column(DateTime, default=datetime.now(), nullable=False)
    delivery_contact = Column(String(13), unique=False, nullable=False)
    is_paid = Column(Boolean, default=False, nullable=False)
    is_prepared = Column(Boolean, default=False, nullable=False)
    is_terminated = Column(Boolean, default=False, nullable=False)
    termination_reason = Column(String(500))
    customer_received = Column(Boolean, default=False, nullable=False)
    delivery_fee = Column(BigInteger, default=0)
    customer_id = Column(Integer,
                         ForeignKey("customer.id"),
                         index=True,
                         nullable=False)
    customer = relationship("Customer", backref="orders")
    pre_order = Column(Boolean, default=False, nullable=False)
    pre_order_time = Column(DateTime,
                            default=datetime(2021, 1, 30, 00, 00, 00),
                            nullable=False)

    def __repr__(self):
        return self.order_ref_simple_version

    def __call__(self, **kwargs):
        try:
            self.order_ref = kwargs.get("order_ref")
            self.customer_id = kwargs.get("customer_id")
            session.add(self)
            session.commit()
            return True

        except Exception as e:
            print("Error whilst adding order record: ", e)
            session.rollback()
            return False

    def serialize(self):
        return {
            "id": self.id,
            "order_ref": self.order_ref,
            "order_ref_simple_version": self.order_ref_simple_version,
            "order_date": self.order_date.strftime('%m/%d/%Y'),
            "is_paid": self.is_paid,
            "is_prepared": self.is_prepared,
            "is_terminated": self.is_terminated,
            "termination_reason": self.termination_reason,
            "customer_received": self.customer_received,
            "delivery_fee": self.delivery_fee,
            "order_items": [item.serialize() for item in self.cart]
        }

    @property
    def delivery_address(self):
        try:
            return delivery_detials.DeliveryDetails.get_order_delivery_address(
                self.id)
        except:
            session.rollback()

    @property
    def read_order_total_amount(self):
        return cart.Cart.customer_order_items_total(self.id)

    @classmethod
    def customer_order_count(cls, customer_id):
        try:
            count = session.query(func.count(cls.id)).filter_by(
                is_paid=True, is_terminated=False).scalar()

            return count
        except:
            session.rollback()

    @classmethod
    def read_order(cls, **kwargs):
        try:
            return cls.query.filter_by(**kwargs).options(lazyload("*")).first()
        except:
            session.rollback()

    @classmethod
    def read_customer_orders(cls, customer_id):
        try:
            customer_orders = cls.query.filter_by(
                customer_id=customer_id).order_by(desc(cls.order_date)).all()
            return [item.serialize() for item in customer_orders]

        except:
            session.rollback()

    @classmethod
    def customer_order_exists(cls, customer_id):
        try:
            return session.query(cls).filter_by(customer_id=customer_id,
                                                is_paid=False,
                                                is_terminated=False).first()
        except:
            session.rollback()

    @classmethod
    def delete_order(self, id):
        try:
            self.query.filter_by(id=id).delete()
            session.commit()
        except:
            session.rollback()

    @classmethod
    def read_orders_count(cls):
        try:
            return session.query(func.count(cls.id)).filter_by(
                is_paid=False, is_terminated=False).scalar()
        except:
            session.rollback()

    @classmethod
    def read_all_orders(cls):
        try:
            return cls.query.order_by(Order.id.desc())
        except:
            session.rollback()

    @property
    def read_cart_items_total_amount(self):
        try:
            return pdts.Cart.customer_order_items_total(self.id)
        except:
            session.rollback()

    @classmethod
    def read_all_orders_filter(cls, *args):
        try:
            return cls.query.filter(*args).order_by(Order.id.desc()).all()
        except:
            session.rollback()

    @classmethod
    def read_all_orders_delivery_details_filter(cls, *args):
        try:
            return session.query(cls).join(cls.delivery_details)\
                .filter(
                    *args
                ).order_by(cls.id.desc()).options(
                    lazyload("*")).all()
        except:
            session.rollback()

    @classmethod
    def read_orders_not_prepared_count(cls):
        try:
            return session.query(func.count(cls.id))\
                .filter(
                    and_(
                        cls.is_prepared==False,
                        cls.is_terminated == False
                        )
                    ).scalar()
        except:
            session.rollback()

    def customer_care_terminate_order(self, reason):
        try:
            self.is_terminated = True
            self.termination_reason = reason
            cash_on_delivery = pym.CashOnDelivery.read_cash_on_delivery(
                payment_id=self.payment[0].payment_id)

            if cash_on_delivery:
                cash_on_delivery.status = "cancelled"

            if self.customer.email:
                mail_ = order_cancelled_email
                mail_.recipients = [self.customer.email]
                mail_.text = "We have cancelled the following order:{order}, because of the following reason: \n{reason}".format(
                    order=self.order_ref_simple_version, reason=reason)
                mail_.send()
                session.commit()
                return True

            else:
                session.commit()
                return True
        except Exception as e:
            session.rollback()
            print("Terminating order error: ", e)
            return False

    @classmethod
    def terminate_order(cls, **kwargs):
        try:
            order = cls.read_order(customer_id=kwargs.get("customer_id"),
                                   is_paid=False,
                                   is_prepared=False,
                                   is_terminated=False,
                                   customer_received=False)

            if order:
                order.is_terminated = True
                order.termination_reason = kwargs.get("reason")
                cash_on_delivery = pym.CashOnDelivery.read_cash_on_delivery(
                    payment_id=order.payment[0].payment_id)

                if cash_on_delivery:
                    cash_on_delivery.status = "cancelled"

                if order.customer.email:
                    mail_ = order_cancelled_email
                    mail_.recipients = [order.customer.email]
                    mail_.text = "You have cancelled the following order:{order}, because of this reason: \n{reason}".format(
                        order=order.order_ref_simple_version,
                        reason=kwargs.get("reason"))
                    mail_.send()
                    session.commit()
                    return True

                else:
                    session.commit()
                    return True
            else:
                return False

        except Exception as e:
            print("Terminating order error: ", e)
            session.rollback()
            return False

    @classmethod
    def place_customer_order(cls, **kwargs):
        with current_app.app_context():
            try:
                method = kwargs.get("payment_method")
                customer_id = kwargs.get("customer_id")
                delivery_contact = kwargs.get("delivery_contact")
                delivery_fee = kwargs.get("delivery_fee")
                pre_order = kwargs.get("pre_order")
                pre_order_time = kwargs.get("pre_order_time")
                county = kwargs.get("county"),
                sub_county = kwargs.get("sub_county"),
                village = kwargs.get("village"),
                other_details = kwargs.get("other_details"),
                customer_object = customer.Customer.read_customer(
                    id=customer_id)
                payment_method = pym.PaymentMethods.read_method(method=method)

                if payment_method:
                    new_ref = ReferenceGenerator()
                    order_ref = new_ref.unique_id
                    order_ref_simple_version = new_ref.simple_version

                    order_ = Order(
                        order_ref=order_ref,
                        order_ref_simple_version=order_ref_simple_version,
                        delivery_contact=delivery_contact,
                        delivery_fee=delivery_fee,
                        customer_id=customer_id,
                        pre_order=pre_order,
                        pre_order_time=pre_order_time)

                    items = session.query(pdts.Cart).filter_by(
                        customer_id=customer_id, is_ordered=False).all()

                    for item in items:
                        item.is_ordered = True
                        item.order = order_

                    delivery = delivery_detials.DeliveryDetails(
                        county=county,
                        sub_county=sub_county,
                        village=village,
                        other_details=other_details,
                        customer_id=customer_id,
                        order=order_)
                    session.add(delivery)

                    payment = pym.Payment(payment_method_id=payment_method.id,
                                          order=order_)

                    session.add(payment)
                    if payment_method.method == "Cash on delivery":
                        cash_on_delivery = pym.CashOnDelivery(
                            payment=payment,
                            transaction_ref=order_ref,
                            status="pending")
                        session.add(cash_on_delivery)

                    else:
                        session.rollback()
                        return False

                    #customer_care email
                    cart_items_total = []
                    items_str = ""
                    item_string = ""
                    for i in items:
                        item = i.serialize()
                        item_string = f"<li>Item: {item['product_name']} from {item['restaurant']} Quantity: {item['quantity']} <b>SubTotal: {'{:,} Ugx'.format(item['total'])}</b></li>"
                        items_str += item_string
                        cart_items_total.append(item['total'])
                    total = items[0].serialize()
                    items_total = sum(cart_items_total)
                    subject_customer_care = """
                                            <html>
                                                <p>The following customer: <b>{customer_name}</b> has placed an order with the following details:</p>
                                                <p>Order Reference: {order_ref}</p>
                                                <p>Order Date: {order_date}</p>
                                                <p>Contact: {contact}</p>
                                                <hr>
                                                <ul style='list-style-type: none;display: block;width: 100%;padding: 0px 10px;overflow: hidden;'>    
                                                    {items_str}
                                                </ul>
                                                <hr>
                                                <p>Items Total: {total}</p>
                                                <hr>
                                        
                                                <p>Payment Method: <b>{payment_method}</b></p>
                                                <p>Delivery Price: <b>{delivery_fee}</b></p>
                                                <p>Total: <b>{order_total}</b></p>
                                                <hr>
                                                <p>Delivery Address: {delivery_address}</p>
                                            </html>
                    """.format(
                        customer_name=customer_object.name,
                        order_ref=order_ref_simple_version,
                        order_date="{: %d/%m/%Y}".format(datetime.now()),
                        contact=customer_object.contact,
                        items_str=items_str,
                        total='{:,} Ugx'.format(items_total),
                        payment_method=payment_method.method,
                        delivery_fee='{:,} Ugx'.format(delivery_fee),
                        order_total='{:,} Ugx'.format(delivery_fee +
                                                      items_total),
                        delivery_address=
                        f"<br>County: {county}<br>,Sub County: {sub_county}<br>,Village: {village}<br>,Other_details: {other_details}<br>"
                    )
                    customer_care_mail_ = customer_care_email
                    customer_care_mail_.recipients = [
                        "*****@*****.**", "*****@*****.**",
                        "*****@*****.**"
                    ]
                    # customer_care_mail_.context = dict(
                    #     customer_name=customer_object.name,
                    #     customer_contact=customer_object.contact,
                    #     order_ref=order_ref_simple_version,
                    #     order_date="{: %d/%m/%Y}".format(datetime.now()),
                    #     items=[i.serialize() for i in items],
                    #     delivery_method="Home delivery",
                    #     delivery_fee=delivery_fee,
                    #     payment_method=payment_method.method,
                    #     delivery_address= f"County: {county}\n,Sub County: {sub_county}\n,Village: {village}\n,Other_details: {other_details}"
                    # )
                    customer_care_mail_.text = subject_customer_care
                    customer_care_mail_.send()

                    if customer_object.email:
                        subject_customer = """
                                        <html>
                                            <p>Written by: [email protected]<br>
                                                <b>Office Address:</b><br>
                                                Afra Road,<br>
                                                Near Hindu Temple,<br>
                                                Room 08,<br>
                                                Arua City, Uganda.
                                            </p>
                                            <p>You have successfully made an order for the following items.</p>
                                            <p>Order Reference: <b>{order_ref}</b></p>
                                            <p>Order Date: <b>{order_date}</b></p>
                                            <hr>
                                            <ul style='list-style-type: none;display: block;width: 100%;padding: 0px 10px;overflow: hidden;'>
                                                {items_str}
                                            </ul>
                                            <hr>
                                            <p>Items Total: <b>{total}</b></p>
                                            <hr>
                                            <p>Payment Method: <b>{payment_method}</b></p>
                                            <p>Delivery Price: <b>{delivery_fee}</b></p>
                                            <p>Total: <b>{order_total}</b></p>
                                            <p>Delivery Address: {delivery_address}</p>
                                            <hr>
                                            <p>You have received this email because you are a registered customer of ClickEat.</p>
                                            <p>For any help please contact us on: <b>0785857000/0777758880</b></p>
                                        </html>
                        """.format(
                            order_ref=order_ref_simple_version,
                            order_date="{: %d/%m/%Y}".format(datetime.now()),
                            items_str=items_str,
                            total='{:,} Ugx'.format(items_total),
                            payment_method=payment_method.method,
                            delivery_fee='{:,} Ugx'.format(delivery_fee),
                            order_total='{:,} Ugx'.format(delivery_fee +
                                                          items_total),
                            delivery_address=
                            f"<br>County: {county}<br>,Sub County: {sub_county}<br>,Village: {village}<br>,Other_details: {other_details}<br>"
                        )
                        mail_ = order_placed_email
                        mail_.recipients = [customer_object.email]
                        mail_.text = subject_customer
                        # mail_.context = dict(
                        #     customer_name=customer_object.name,
                        #     customer_contact=customer_object.contact,
                        #     order_ref=order_ref_simple_version,
                        #     order_date="{: %d/%m/%Y}".format(datetime.now()),
                        #     items=[i.serialize() for i in items],
                        #     delivery_method="Home delivery",
                        #     delivery_fee=delivery_fee,
                        #     payment_method=payment_method.method,
                        #     delivery_address= f"County: {county}\n,Sub County: {sub_county}\n,Village: {village}\n,Other_details: {other_details}"
                        # )
                        # mail_.text = "You have placed the following order with reference number: {order_ref_simple_version}".format(
                        #     order_ref_simple_version=order_ref_simple_version
                        # )
                        mail_.send()
                        session.commit()
                        return True

                    else:
                        session.commit()
                        return True

                else:
                    print("No payment method")
                    return False

            except Exception as e:
                print("Placing Order Error: ", e)
                session.rollback()
                return False

    @classmethod
    def customer_care_register_order_sales(cls, **kwargs):
        with current_app.app_context():
            try:
                order = kwargs.get("order")
                data = kwargs.get("data")

                if "order_id" not in data:
                    abort(403)
                if int(data["order_id"]) != int(order.id):
                    abort(403)

                if "customer_received" in data:
                    if order.is_prepared == False:
                        flash("Order has to first be prepared", "danger")
                        return jsonify()
                    if order.is_paid == False:
                        flash("Order has to first be paid", "danger")
                        return jsonify()
                    if data["customer_received"] == True and order.customer_received == False:
                        order.customer_received = True
                        session.commit()
                        flash("Order status 'Customer received' has been set",
                              "success")
                    else:
                        flash(
                            "Order status 'Customer received' was already set",
                            "info")

                elif "is_prepared" in data:
                    if data["is_prepared"] == True and order.is_prepared == False:
                        order.is_prepared = True
                        session.commit()
                        flash("Order status 'Prepared' has been set",
                              "success")
                    else:
                        flash("Order status 'Prepared' was already set",
                              "info")

                elif "courier_id" in data:
                    if order.is_prepared == False:
                        flash("Order has to be first prepared", "danger")
                        return jsonify()
                    delivery_detials.DeliveryDetails.assign_courier(
                        int(data["courier_id"]), int(order.id))
                    flash("Courier has been set for this order successfully",
                          "success")

                elif "is_paid" in data:
                    if order.is_prepared == False:
                        flash("Order has to first  be prepared", "danger")
                        return jsonify()
                    if data["is_paid"] == True and order.is_paid == False:
                        order.is_paid = True
                        cash_on_delivery = pym.CashOnDelivery.read_cash_on_delivery(
                            payment_id=order.payment[0].payment_id)
                        delivery_details = order.delivery_details[0]
                        if delivery_details.courier_id == None:
                            flash(
                                "Order paid can only be set when courier has been set.",
                                "danger")
                            session.rollback()
                            return jsonify()
                        if not cash_on_delivery:
                            flash(
                                "Order paid can only be set for cash on delivery items.",
                                "danger")
                            session.rollback()
                            return jsonify()
                        else:
                            cash_on_delivery.status = "confirmed"
                        for pdt_ in order.cart:
                            product = session.query(pdts.Products).filter_by(
                                product_id=pdt_.product_id).first()
                            if product:
                                sales.Sales()(
                                    product_id=pdt_.product_id,
                                    quantity=pdt_.quantity,
                                    amount=pdt_.total,
                                    commission_amount=product.commission_amount
                                    if product.commission_amount else 0)
                        if order.customer.email:
                            items = order.cart
                            cart_items_total = []
                            items_str = ""
                            item_string = ""
                            for i in items:
                                item = i.serialize()
                                item_string = f"<li>Item: {item['product_name']} from {item['restaurant']} Quantity: {item['quantity']} <b>SubTotal: {'{:,} Ugx'.format(item['total'])}</b></li>"
                                items_str += item_string
                                cart_items_total.append(item['total'])
                            total = items[0].serialize()
                            items_total = sum(cart_items_total)
                            subject_customer = """
                                        <html>
                                            <p>Written by [email protected]<br>
                                                Office Address:<br>
                                                Afra Road,<br>
                                                Near Hindu Temple,<br>
                                                Room 08,<br>
                                                Arua City, Uganda.
                                            </p>
                                            <p>Dear <b>{user_name}</b></p>,
                                            <p>You have made a payment for the following items.</p>
                                            <p>Order Reference: <b>{order_ref}</b></p>
                                            <p>Order Date: {order_date}</p>
                                            <hr>
                                            <ul style='list-style-type: none;display: block;width: 100%;padding: 0px 10px;overflow: hidden;'>
                                                {items_str}
                                            </ul>
                                            <hr>
                                            <p>Items Total: <b>{total}</b></p>
                                            <p>Payment Method: {payment_method}</p>
                                            <p>Delivery Price: {delivery_fee}</p>
                                            <p>Total: {order_total}</p>
                                            <p>Status: <b>Paid</b></p>
                                            <hr>

                                            <p><b>Thank you for buying on ClickEat, please come gain :)</b></p>
                                            <p>You have received this email because you are a member of ClickEat.</p>
                                            <p>For any help please contact us by clicking 0785857000/0777758880</p>
                                        </html>
                            """.format(
                                user_name=order.customer.name,
                                order_ref=order.order_ref_simple_version,
                                order_date="{: %d/%m/%Y}".format(
                                    order.order_date),
                                items_str=items_str,
                                total='{:,} Ugx'.format(items_total),
                                payment_method=order.payment[0].payment_method.
                                serialize(),
                                delivery_fee='{:,} Ugx'.format(
                                    order.delivery_fee),
                                order_total='{:,} Ugx'.format(
                                    order.delivery_fee + items_total))
                            mail_ = order_receipt_email
                            mail_.recipients = [order.customer.email]
                            mail_.text = subject_customer
                            # mail_.context = dict(
                            #     items = [i.serialize() for i in order.cart],
                            #     order_ref = order.order_ref_simple_version,
                            #     order_date="{: %d/%m/%Y}".format(order.order_date),
                            #     user_name = order.customer.name,
                            #     delivery_fees = order.delivery_fee,
                            #     payment_method = order.payment[0].payment_method.serialize(),
                            #     customer_received = order.customer_received
                            # )
                            mail_.send()
                            session.commit()
                            flash("Order status has been set to paid",
                                  "success")

                        else:
                            session.commit()
                            flash("Order status has been set to paid",
                                  "success")
                    else:
                        session.rollback()
                        flash("Order status already set to paid", "info")
            except Exception as e:
                session.rollback()
                print("Updating Order statuses error: ", e)
                flash(f"Error: {e}", "danger")