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
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()
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
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 }
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
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
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
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()
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)
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
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)
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()
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
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)
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()
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
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
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)
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()
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()
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
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()
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
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")