Files
tainagustului/UI_V2/pages/shopping_cart/cart.py

627 lines
24 KiB
Python

import flet as ft
from dbActions.orders import Orders
from dbActions.products import Products
from dbActions.company import Company
from dbActions.users import Users
from helpers.emails import send_gmail
import re
class Cart:
def __init__(self, page: ft.Page):
self.page = page
self.user = self.page.session.get('user')
self.orders_manager = Orders()
self.productsDB = Products()
self.company_manager = Company()
self.user_manager = Users()
self.products = []
self.is_second_address = None
self.is_company = None
self.pret_total = ft.Text("Pret total: 0", weight=ft.FontWeight.BOLD)
self.delete_dialog = ft.AlertDialog(
title=ft.Text("Stergeti?"),
actions=[
ft.FilledButton("Da", on_click=self.on_confirm_delete_btn_click),
ft.FilledButton("Nu", on_click=self.on_cancel_delete_btn_click, bgcolor=ft.Colors.GREY)
]
)
self.on_hold_orders = self.orders_manager.get_on_hold_order(self.user['id'])
if self.on_hold_orders:
self.order_products = self.orders_manager.get_order_products(self.on_hold_orders['id'])
for product in self.order_products:
self.products.append(
{
'product':self.productsDB.get(product['prdouct_id']),
'quantity':product['quantity']
}
)
self.product_list = ft.ListView(
controls=self.create_list(self.products, self.on_delete_product_click),
spacing=10,
expand=5
)
self.payment = ft.RadioGroup(
content=ft.Row(
[
ft.Radio(value="ramburs", label="Ramburs la curier"),
ft.Radio(value="plata_online_cu_cardul", label="Plata online cu cardul", disabled=True),
]
),
on_change=self.on_payment_value_change
)
self.payment_message = ft.Text("")
self.error_message = ft.Text(
color=ft.Colors.RED
)
self.confirm_dialog = ft.AlertDialog(
title=ft.Text("Confirma"),
actions=[
ft.FilledButton(
"Da",
on_click=self.on_confim_btn_click
),
ft.FilledButton(
"Nu",
on_click=self.on_cancel_btn_click,
bgcolor=ft.Colors.GREY
)
]
)
self.all_orders = self.orders_manager.get_orders_for_user(self.page.session.get('user')['id'])
self.all_orders = self.all_orders[::-1]
self.orders_manager_list = ft.ListView(
controls=self.create_history_list(self.all_orders),
spacing=10,
expand=True
)
self.user = self.page.session.get("user")
self.company = self.company_manager.get_company(self.user['id'])
self.user_name = ft.TextField(
label="Nume si Prenume",
value=self.user['name'] if "@default.com" not in self.user['email'] else None
)
self.email = ft.TextField(
label="E-mail",
value=self.user['email'] if "@default.com" not in self.user['email'] else None,
read_only=True if "@default.com" not in self.user['email'] else False
)
self.phone = ft.TextField(
label="Telefon",
value=self.user['phone'] if "@default.com" not in self.user['email'] else None
)
self.address = ft.TextField(
label="Adresa",
multiline=True,
min_lines=3,
max_lines=5,
value = self.user['address'].split("~")[0] if self.user['address'] else ''
)
self.company_name = ft.TextField(
label="Denumire firma",
value=self.company['name'] if self.company else ''
)
self.vat = ft.TextField(
label="CUI",
value=self.company['vat'] if self.company else ''
)
self.register_number = ft.TextField(
label="Numar registru comert",
value=self.company['register_number'] if self.company else ''
)
self.company_address = ft.TextField(
label="Sediu",
multiline=True,
min_lines=3,
max_lines=5,
value=self.company['address'] if self.company else '')
self.second_address_placeholder = ft.Column()
self.second_address = ft.TextField(
label="Adresa de livrare",
multiline=True,
min_lines=3,
max_lines=5,
value=self.user['address'].split("~")[1] if self.user['address'] and len(self.user['address'].split("~"))>1 else ''
)
self.second_address_placeholder =ft.Column()
self.order_placeholder =ft.Column()
if self.user['address'] and len(self.user['address'].split("~"))>1 :
self.is_second_address = True
self.second_address_placeholder.controls.append(self.second_address)
if self.company:
self.is_company = True
self.order_placeholder.controls.append(self.company_name)
self.order_placeholder.controls.append(self.vat)
self.order_placeholder.controls.append(self.register_number)
self.order_placeholder.controls.append(self.company_address)
self.delivery_details = ft.Column(
[
ft.Text(
"Detaili de livrare",
weight=ft.FontWeight.BOLD
),
self.user_name,
self.email,
self.phone,
self.address,
ft.Divider(),
ft.Text("Adresa de livrare difera de adresa de domiciliu?", text_align=ft.TextAlign.CENTER),
ft.Button("Adauga adresa livrare", width=500, on_click=self.on_second_address_btn_click),
self.second_address_placeholder,
ft.Divider(),
ft.Button("Doriti Factura?", width=500, on_click=self.on_order_btn_click),
self.order_placeholder,
ft.Text(
"Metoda de plata",
weight=ft.FontWeight.BOLD
),
self.payment,
self.payment_message,
ft.Row([self.error_message],alignment=ft.MainAxisAlignment.CENTER),
ft.Row(
[
ft.FilledButton(
"Comanda",
width=150,
on_click=self.open_confirm_dialog
)
],
alignment=ft.MainAxisAlignment.CENTER
)
],
expand=5,
alignment=ft.MainAxisAlignment.START
)
if self.page.width < 600:
self.cart_placeholder = ft.Column(
[
self.product_list,
self.delivery_details
]
)
else:
self.cart_placeholder = ft.Row(
[
self.product_list,
self.delivery_details
],
vertical_alignment=ft.CrossAxisAlignment.START
)
self.order_list_placeholder = ft.Column()
self.order_list_placeholder.controls.append(self.orders_manager_list)
self.item_to_be_deleted = None
self.page.add(self.delete_dialog)
self.page.add(self.confirm_dialog)
def on_second_address_btn_click(self, e):
self.is_second_address = True
self.second_address_placeholder.controls.append(self.second_address)
self.second_address_placeholder.update()
def on_order_btn_click(self, e):
self.is_company = True
self.order_placeholder.controls.append(self.company_name)
self.order_placeholder.controls.append(self.vat)
self.order_placeholder.controls.append(self.register_number)
self.order_placeholder.controls.append(self.company_address)
self.order_placeholder.update()
def on_payment_value_change(self, e):
print(e.data)
if e.data == 'plata_online_cu_cardul':
pass
else:
pass
def get_order_products(self, id):
products = self.orders_manager.get_order_products(id)
total = 0
all_products = []
for product in products:
item = self.productsDB.get(product['prdouct_id'])
total += item['price']
name = item['name']
if name not in all_products:
all_products.append(name)
try:
self.pret_total.value = f'Pret total: {total}'
self.pret_total.update()
except:
pass
return ft.Text(
value=' '.join(all_products)
)
def on_go_back_button_click(self, e):
self.page.go("/")
def create_list(self, items, on_click_handler):
"""Helper to create list items for a column."""
return [
ft.Container(
content=ft.Row(
[
ft.Column(
[
ft.Row(
[
ft.Icon(ft.Icons.ARROW_RIGHT, size=20),
ft.Row(
[
ft.Image(
src=item['product']['image'],
width=100,
height=100,
fit=ft.ImageFit.COVER,
border_radius=10
),
ft.Column(
[
ft.Text(f"Denumire Produs: {item['product']['name']}", weight=ft.FontWeight.BOLD),
ft.Text(f"Cantitate: {item['quantity']}"),
ft.Text(f"Descriere: {item['product']['description']}", size=12 , color=ft.Colors.GREY),
]
)
]
)
]
),
]
),
ft.Row(
[
ft.FilledButton("Sterge",on_click=lambda e, id=item: on_click_handler(id), bgcolor=ft.Colors.RED),
]
)
],
alignment=ft.MainAxisAlignment.SPACE_BETWEEN,
),
width=300,
bgcolor=ft.Colors.BROWN_50,
padding=10,
border_radius=8,
border = ft.border.all(1, ft.Colors.GREY),
)
for item in items
]
def create_history_list(self, items):
status_value = {
'new':'Noua',
'on_hold':'In asteptare',
'in_progress': 'In lucru',
'completed':'Complete'
}
return [
ft.Container(
content=ft.Column(
[
ft.Row(
[
ft.Icon(ft.Icons.ARROW_RIGHT, size=20),
ft.Text(value="Numar comanda: "),
ft.Text(value=item['id'])
]
),
ft.Row(
[
ft.Text(
value='Status: '
),
ft.Text(
value=status_value[item['status']]
)
]
),
ft.Row(
[
ft.Text(
value='Produse: '
),
self.get_order_products(item['id'])
]
)
],
alignment=ft.MainAxisAlignment.START,
),
width=300,
bgcolor=ft.Colors.BROWN_50,
padding=10,
border_radius=8,
border = ft.border.all(1, ft.Colors.GREY),
)
for item in items
]
def on_delete_product_click(self, item):
print('Delte item', item)
self.page.open(self.delete_dialog)
self.page.update()
self.item_to_be_deleted = item['product']['id']
def on_confirm_delete_btn_click(self, e):
print("confirm delete item", self.item_to_be_deleted)
#remove item
self.orders_manager.remove_product_from_order(self.on_hold_orders['id'], self.item_to_be_deleted)
#update list
self.order_products = self.orders_manager.get_order_products(self.on_hold_orders['id'])
self.products = []
for product in self.order_products:
self.products.append(
{
'product':self.productsDB.get(product['prdouct_id']),
'quantity':product['quantity']
}
)
self.product_list.controls.clear()
self.product_list.controls = self.create_list(self.products, self.on_delete_product_click)
self.product_list.update()
self.item_to_be_deleted = None
self.page.close(self.delete_dialog)
def on_cancel_delete_btn_click(self, e):
print("cancel item deletion: ", self.item_to_be_deleted)
self.item_to_be_deleted = None
self.page.close(self.delete_dialog)
def open_confirm_dialog(self, e):
print('open dialog')
print(self.on_hold_orders)
if self.on_hold_orders:
self.error_message.value = ''
self.error_message.update()
self.page.open(self.confirm_dialog)
else:
self.error_message.value = "Nu aveti nici un produs in cos!"
self.error_message.update()
def on_cancel_btn_click(self, e):
self.page.close(self.confirm_dialog)
def check_second_address_inserted(self, address):
if address is None or len(address)< 1:
self.error_message.value = "Va rugam inserati adresa de livrare!"
self.error_message.color = ft.Colors.RED
self.error_message.update()
print('Second address found')
return True
print('Second address not found')
return False
def check_company_data_inserted(self, company_name, vat, register_number, company_address):
found = False
if company_name is None or len(company_name)< 1:
print("Comapny name not found")
found = True
if vat is None or len(vat)< 1:
print("Vat not found")
found = True
if register_number is None or len(register_number)< 1:
print("Register number not found")
found = True
if company_address is None or len(company_address)< 1:
print("Company address not found")
found = True
if found:
self.error_message.value = "Toate campurile sunt obligatori!"
self.error_message.color = ft.Colors.RED
self.error_message.update()
return found
def check_inserted_user_data(self, username, phone, address, email):
found = False
if username is None or len(username)< 1:
print('Username not found')
found = True
if phone is None or len(phone)< 1:
print("Phone not found")
found = True
if address is None or len(address)< 1:
print("Adress not found")
found = True
if email is None or len(email)<1:
print("email not found")
found = True
if found:
self.error_message.value = "Toate campurile sunt obligatori!"
self.error_message.color = ft.Colors.RED
self.error_message.update()
return found
def check_email_is_valid(self, email):
email_regex = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
if re.fullmatch(email_regex, email) is not None:
self.error_message.value = ""
self.error_message.update()
return True
else:
self.error_message.value = "Va rugam inserati un e-mail valid!"
self.error_message.update()
return False
def create_update_user_details(self):
username = self.user_name.value
phone = self.phone.value
address = self.address.value
email = self.email.value
if self.is_second_address:
print("Second address has been selected (button click)")
if self.check_second_address_inserted(self.second_address.value):
return False
address = self.address.value + '~' + self.second_address.value
if self.check_inserted_user_data(username, phone, address, email):
return False
if not self.check_email_is_valid(email):
return False
if '@default.com' in self.user['email']:
print("User is default @default.com in name")
try:
user_id = self.user_manager.invite_user(
email, username, phone, address
)
self.user = self.user_manager.get(user_id)
print("User invited")
self.page.session.set("user", self.user)
self.orders_manager.update_order_user_id(user_id, self.on_hold_orders['id'])
except:
print("Unable to create user, user already exists")
self.error_message.value = "Exita deja un utilizator cu aceasta adresa de email!"
return False
else:
self.user_manager.update_user_data(username, phone, address, self.user['id'])
if self.is_company:
print("Compani selected (company button has been pressed)")
if self.check_company_data_inserted(self.company_name.value, self.vat.value, self.register_number.value, self.company_address.value):
return
if self.company:
company['name'] = self.company_name.value
company['vat'] = self.vat.value
company['register_number'] = self.register_number.value
company['address'] = self.company_address.value
self.company_manager.update_company(company)
else:
company = {
'user_id' : self.user['id'],
'name': self.company_name.value,
'vat': self.vat.value,
'register_number': self.register_number.value,
'address': self.company_address.value
}
self.company_manager.add_company(company)
return True
def on_confim_btn_click(self, e):
self.error_message.color = ft.Colors.RED
self.error_message.update()
#create / update user details:
print("Confirm button Selected ")
self.page.close(self.confirm_dialog)
if self.create_update_user_details():
print('User details updated')
self.orders_manager.update_order_status("new", self.on_hold_orders['id'])
print('Order status is set to new')
self.products = []
self.on_hold_orders = self.orders_manager.get_on_hold_order(self.user['id'])
if self.on_hold_orders:
self.order_products = self.orders_manager.get_order_products(self.on_hold_orders['id'])
for product in self.order_products:
self.products.append(
{
'product':self.productsDB.get(product['prdouct_id']),
'quantity':product['quantity']
}
)
self.product_list.controls.clear()
self.product_list.controls = self.create_list(self.products, self.on_delete_product_click)
self.product_list.update()
#hiostory
if '@default.com' not in self.user['email']:
self.all_orders = self.orders_manager.get_orders_for_user(self.page.session.get('user')['id'])
self.all_orders = self.all_orders[::-1]
self.orders_manager_list.controls.clear()
self.orders_manager_list.controls = self.create_history_list(self.all_orders)
self.orders_manager_list.update()
#notify admin
users = self.user_manager.get_all()
admins = []
for user in users:
if user['role'] == 'admin':
admins.append(user)
for admin in admins:
send_gmail(
to_email=admin['email'],
subject="Comanda noua pe tainagustului.ro",
body=f'''
Ati primit o noua comanda de la {self.user['email']}.
Va rugam accesati wwww.tainagusutului.ro pentru detalii.
'''
)
send_gmail(
to_email=self.user['email'],
subject="Multumim pentru comanda!",
body=f'''
Buna ziua,
Comanda a fost primita si va fi livrata in cel mai scurt timp.
Va multumim,
Echipa tainagustului.ro
'''
)
self.error_message.value = "Comanda a fost trimisa cu success!"
self.error_message.color = ft.Colors.GREEN
self.error_message.update()
def build(self):
return ft.Container(
content=ft.Column(
[
ft.Row(
[
ft.Row(
[
ft.Icon(
ft.Icons.SHOPPING_CART_CHECKOUT,
size=40,
),
ft.Column(
[
self.pret_total,
ft.Text(
"Produse adugate:",
weight=ft.FontWeight.BOLD,
size=15
),
]
)
]
),
ft.FilledButton(
text="Inapoi",
icon=ft.Icons.ARROW_BACK,
on_click=self.on_go_back_button_click
)
],
alignment=ft.MainAxisAlignment.SPACE_BETWEEN
),
ft.Divider(),
self.cart_placeholder,
self.order_list_placeholder,
ft.Text()
],
expand=True,
scroll=ft.ScrollMode.ADAPTIVE
),
expand=True,
width=1000,
padding=10
)