464 lines
18 KiB
Python
464 lines
18 KiB
Python
import flet as ft
|
|
from dbActions.orders import Orders
|
|
from dbActions.products import Products
|
|
from helpers.default_user import DefaultUser
|
|
|
|
class ProductPage:
|
|
def __init__(self, page: ft.Page, shop=''):
|
|
self.page = page
|
|
self.shop = shop
|
|
self.orders = Orders()
|
|
self.product = self.page.session.get('product')
|
|
print(self.product)
|
|
|
|
self.product_main_image = ft.Image(
|
|
src = self.product['image'],
|
|
width=300,
|
|
height=250,
|
|
border_radius=10,
|
|
fit=ft.ImageFit.COVER
|
|
)
|
|
|
|
self.product_name = ft.Text(
|
|
value = self.product['name'],
|
|
size=20,
|
|
weight=ft.FontWeight.BOLD
|
|
)
|
|
self.old_price = ft.Text(
|
|
value=f"{self.product['price']} Lei" if self.product['discount'] > 0 else '',
|
|
size=12,
|
|
color=ft.Colors.GREY,
|
|
style=ft.TextStyle(decoration=ft.TextDecoration.LINE_THROUGH)
|
|
)
|
|
self.price = ft.Text(
|
|
value=f"{round(self.product['price'] - self.product['price']*self.product['discount']/100, 2)} Lei",
|
|
size=17 if self.product['discount'] > 0 else None,
|
|
color=ft.Colors.RED if self.product['discount'] > 0 else None,
|
|
weight=ft.FontWeight.BOLD
|
|
)
|
|
|
|
self.description = ft.Text(
|
|
value=self.product['description'],
|
|
width=600
|
|
)
|
|
|
|
self.details = ft.Text(
|
|
value=self.product['details'],
|
|
width=600
|
|
)
|
|
|
|
self.quantity = ft.TextField(label="", value="1", width=60)
|
|
self.quantify_group = ft.Row(
|
|
[
|
|
ft.IconButton(ft.Icons.ARROW_CIRCLE_LEFT, on_click=self.remove_quantity),
|
|
self.quantity,
|
|
ft.IconButton(ft.Icons.ARROW_CIRCLE_RIGHT, on_click=self.add_quantity),
|
|
]
|
|
)
|
|
|
|
aviab = {
|
|
'in_stock': "In stoc",
|
|
'in_provider_stock': "In stoc la furnizor",
|
|
'not_available': "Indisponibil"
|
|
}
|
|
|
|
self.availability = ft.Text(aviab[self.product['aviability']])
|
|
self.stock_quantity = ft.Text(self.product['quantity'])
|
|
|
|
self.similar_products = ft.Row(width=1000, scroll=ft.ScrollMode.ADAPTIVE)
|
|
for sp in self.get_similar_porducts():
|
|
product = ft.Card(
|
|
content=ft.Container(
|
|
content=ft.Column(
|
|
[
|
|
ft.Stack(
|
|
[
|
|
ft.Image(
|
|
src=f"images/{sp['image']}",
|
|
fit=ft.ImageFit.COVER,
|
|
repeat=ft.ImageRepeat.NO_REPEAT,
|
|
border_radius=ft.border_radius.all(5),
|
|
width=220,
|
|
height=220
|
|
),
|
|
|
|
ft.Container(
|
|
content=ft.Column(
|
|
[
|
|
ft.Text(f"{sp['name']}", size=12),
|
|
ft.Row(
|
|
[
|
|
ft.Row(
|
|
[
|
|
ft.Text(
|
|
f"{sp['price']} Lei/{sp['quantity']}" if sp['discount']>0 else '',
|
|
size=12,
|
|
color=ft.Colors.GREY,
|
|
style=ft.TextStyle(decoration=ft.TextDecoration.LINE_THROUGH)
|
|
),
|
|
ft.Text(
|
|
f"{sp['price'] - sp['price']*sp['discount']/100} Lei/{sp['quantity']}",
|
|
size=14,
|
|
weight=ft.FontWeight.BOLD
|
|
),
|
|
],
|
|
alignment=ft.MainAxisAlignment.CENTER
|
|
),
|
|
ft.IconButton(ft.Icons.ADD_SHOPPING_CART, on_click=lambda e, i=sp: self.on_sp_add_to_cart_click(i))
|
|
],
|
|
width=200,
|
|
alignment=ft.MainAxisAlignment.SPACE_BETWEEN
|
|
)
|
|
|
|
],
|
|
horizontal_alignment=ft.CrossAxisAlignment.CENTER
|
|
),
|
|
bgcolor=ft.Colors.WHITE,
|
|
bottom=0,
|
|
border_radius=ft.border_radius.only(bottom_left=5, bottom_right=5),
|
|
padding=10
|
|
)
|
|
],
|
|
),
|
|
],
|
|
horizontal_alignment=ft.CrossAxisAlignment.CENTER,
|
|
alignment=ft.MainAxisAlignment.SPACE_BETWEEN
|
|
|
|
),
|
|
padding=10,
|
|
ink=True,
|
|
on_click=lambda e, i=sp: self.on_sp_product_click(i)
|
|
),
|
|
width=250,
|
|
height=250,
|
|
)
|
|
self.similar_products.controls.append(product)
|
|
|
|
self.product_content_image = ft.Column(
|
|
[
|
|
ft.Card(
|
|
content=ft.Container(
|
|
self.product_main_image,
|
|
padding=10
|
|
)
|
|
)
|
|
]
|
|
)
|
|
self.product_content_details = ft.Column(
|
|
[
|
|
|
|
ft.Row(
|
|
[
|
|
ft.Text("Pret:", weight=ft.FontWeight.BOLD),
|
|
self.old_price,
|
|
self.price
|
|
]
|
|
),
|
|
ft.Text("Descriere", weight=ft.FontWeight.BOLD),
|
|
self.description,
|
|
ft.Text("Detalii", weight=ft.FontWeight.BOLD),
|
|
self.details,
|
|
ft.Row(
|
|
[
|
|
ft.Text("Disponibilitate", weight=ft.FontWeight.BOLD),
|
|
self.availability
|
|
]
|
|
),
|
|
ft.Row(
|
|
[
|
|
ft.Text('Cantitate (g)', weight=ft.FontWeight.BOLD),
|
|
self.stock_quantity
|
|
]
|
|
),
|
|
ft.Row(
|
|
[
|
|
self.quantify_group,
|
|
ft.FilledButton(
|
|
"Adauga in cos",
|
|
icon=ft.Icons.SHOPPING_CART,
|
|
width=150,
|
|
on_click= lambda e, i=self.product: self.on_add_to_cart_btn_click(i)
|
|
)
|
|
]
|
|
)
|
|
],
|
|
alignment=ft.MainAxisAlignment.START
|
|
)
|
|
|
|
self.desktop_container = ft.Row(alignment=ft.MainAxisAlignment.CENTER)
|
|
self.mobile_container = ft.Column()
|
|
|
|
if self.page.width < 600:
|
|
self.mobile_container.controls.append(self.product_content_image)
|
|
self.mobile_container.controls.append(self.product_content_details)
|
|
else:
|
|
self.desktop_container.controls.append(self.product_content_image)
|
|
self.desktop_container.controls.append(self.product_content_details)
|
|
|
|
self.confirm_dialog = ft.AlertDialog(
|
|
title=ft.Text('Adauga in cos?'),
|
|
content=ft.Column(
|
|
[
|
|
ft.Icon(ft.Icons.SHOPPING_CART, size=100)
|
|
],
|
|
height=100,
|
|
alignment=ft.MainAxisAlignment.CENTER,
|
|
horizontal_alignment=ft.CrossAxisAlignment.CENTER
|
|
),
|
|
actions=[
|
|
ft.FilledButton(
|
|
"Anuleaza",
|
|
bgcolor=ft.Colors.GREY,
|
|
on_click=self.on_cancel_btn_click),
|
|
ft.FilledButton(
|
|
"Confirma",
|
|
on_click=self.on_confirm_btn_click)
|
|
]
|
|
)
|
|
self.page.add(self.confirm_dialog)
|
|
|
|
self.searchbar = ft.TextField(
|
|
label="Cauta produsul in toate categoriile",
|
|
expand=True,
|
|
on_submit=self.on_search_btn_click
|
|
)
|
|
|
|
self.ask_for_login_dialog = ft.AlertDialog(
|
|
title=ft.Text("Va rugam sa va autentificati!"),
|
|
content=ft.Column(
|
|
[
|
|
ft.Text("Daca nu aveti un cont activ, puteti crea unul."),
|
|
ft.Text("Dupa confirmare, selectati din nou produsul.")
|
|
],
|
|
height=50
|
|
),
|
|
actions=[
|
|
ft.FilledButton(
|
|
"Continua fara cont",
|
|
bgcolor=ft.Colors.GREY,
|
|
on_click=self.on_cancel_go_to_login_btn_click),
|
|
ft.FilledButton(
|
|
"Autentificare",
|
|
on_click=self.on_confirm_go_to_login_btn_click)
|
|
]
|
|
)
|
|
|
|
self.selected_item = None
|
|
|
|
self.profile_placeholder = ft.Column()
|
|
self.profile_btn = ft.IconButton(
|
|
icon=ft.Icons.ACCOUNT_CIRCLE_OUTLINED,
|
|
on_click=self.on_profile_btn_click,
|
|
bgcolor=ft.Colors.BROWN,
|
|
icon_color=ft.Colors.WHITE
|
|
)
|
|
self.login_btn = ft.IconButton(
|
|
icon=ft.Icons.LOGIN,
|
|
on_click=self.on_login_btn_click,
|
|
bgcolor=ft.Colors.BROWN,
|
|
icon_color=ft.Colors.WHITE
|
|
)
|
|
if self.page.session.get("user") is not None and '@default.com' not in self.page.session.get("user")['email']:
|
|
self.profile_placeholder.controls.append(self.profile_btn)
|
|
else:
|
|
self.profile_placeholder.controls.append(self.login_btn)
|
|
|
|
def on_login_btn_click(self, e):
|
|
self.page.go('/auth')
|
|
|
|
def on_cancel_go_to_login_btn_click(self, e):
|
|
self.page.close(self.ask_for_login_dialog)
|
|
self.user = DefaultUser(self.page)
|
|
#print(self.user.default_user)
|
|
self.page.session.set("user", self.user.default_user)
|
|
# print(self.page.session.get("user"))
|
|
# try:
|
|
# quantity = int(self.quantity.value)
|
|
# if quantity > 0:
|
|
# self.page.open(self.confirm_dialog)
|
|
# self._product = self.selected_item
|
|
# except Exception as e:
|
|
# print(e)
|
|
|
|
def on_confirm_go_to_login_btn_click(self, e):
|
|
self.page.close(self.ask_for_login_dialog)
|
|
self.page.go('/auth')
|
|
|
|
def on_search_btn_click(self, e):
|
|
self.page.session.set("search_for", self.searchbar.value)
|
|
self.page.go('/')
|
|
|
|
def on_profile_btn_click(self, e):
|
|
self.page.go('/profil')
|
|
|
|
def on_cart_btn_click(self, e):
|
|
if self.page.session.get('user') == None:
|
|
self.page.go("/pre_load_cos")
|
|
else:
|
|
self.page.go("/cos")
|
|
|
|
def on_cancel_btn_click(self, e):
|
|
self.page.close(self.confirm_dialog)
|
|
|
|
def on_confirm_btn_click(self, e):
|
|
item = self.product
|
|
self.page.close(self.confirm_dialog)
|
|
user = self.page.session.get('user')
|
|
print("user:", user)
|
|
if user:
|
|
_cart = self.orders.get_on_hold_order(user['id'])
|
|
if not _cart:
|
|
self.orders.add_order(user['id'])
|
|
_cart = self.orders.get_on_hold_order(user['id'])
|
|
self.add_product_if_not_exists(item, _cart)
|
|
|
|
def add_product_if_not_exists(self, product, cart):
|
|
user = self.page.session.get('user')
|
|
self.on_hold_orders = self.orders.get_on_hold_order(user['id'])
|
|
self.order_products = self.orders.get_order_products(self.on_hold_orders['id'])
|
|
found = False
|
|
for order_product in self.order_products:
|
|
if str(product['id']) == str(order_product['prdouct_id']):
|
|
quantity = order_product['quantity'] + int(self.quantity.value)
|
|
self.orders.update_order_map_quantity(order_product['id'], quantity)
|
|
found = True
|
|
break
|
|
if not found:
|
|
self.orders.add_product_to_order(product['id'], cart['id'], int(self.quantity.value))
|
|
|
|
def get_similar_porducts(self):
|
|
productsDB = Products()
|
|
similar_products = productsDB.get_all_by_category(self.product['category_id'])
|
|
products = []
|
|
|
|
for product in similar_products:
|
|
if product['id'] != self.product['id']:
|
|
products.append(product)
|
|
return products
|
|
|
|
def remove_quantity(self, e):
|
|
buffer = int(self.quantity.value)
|
|
if buffer > 0:
|
|
self.quantity.value = str(buffer-1)
|
|
self.quantity.update()
|
|
self.product['quantity'] -=1
|
|
|
|
def add_quantity(self, e):
|
|
buffer = int(self.quantity.value)
|
|
self.quantity.value = str(buffer+1)
|
|
self.quantity.update()
|
|
self.product['quantity'] +=1
|
|
|
|
def on_chanage_image_click(self, item):
|
|
self.product_main_image.src = 'images/'+item
|
|
self.product_main_image.update()
|
|
print(self.product_main_image.src)
|
|
|
|
def on_home_btn_click(self, e):
|
|
self.page.go('/')
|
|
|
|
def on_sp_product_click(self, product):
|
|
self.page.session.set('product', product)
|
|
|
|
def ask_for_create_user(self):
|
|
self.page.open(self.ask_for_login_dialog)
|
|
|
|
def on_add_to_cart_btn_click(self, item):
|
|
self.selected_item = item
|
|
user = self.page.session.get('user')
|
|
print(user)
|
|
if not user:
|
|
self.ask_for_create_user()
|
|
else:
|
|
try:
|
|
quantity = int(self.quantity.value)
|
|
if quantity > 0:
|
|
self.page.open(self.confirm_dialog)
|
|
self._product = self.selected_item
|
|
except Exception as e:
|
|
print(e)
|
|
|
|
def on_sp_add_to_cart_click(self, item):
|
|
user = self.page.session.get('user')
|
|
if not user:
|
|
self.page.go('/login')
|
|
self.page.client_storage.remove("remembered_token")
|
|
self.page.client_storage.remove("remembered_user")
|
|
self.page.session.remove('user')
|
|
_cart = self.orders.get_on_hold_order(user['id'])
|
|
if not _cart:
|
|
self.orders.add_order(user['id'])
|
|
_cart = self.orders.get_on_hold_order(user['id'])
|
|
self.orders.add_product_to_order(item['id'], _cart['id'], 1)
|
|
|
|
def build(self):
|
|
return ft.Container(
|
|
content=ft.Column(
|
|
[
|
|
ft.Row(
|
|
[
|
|
self.searchbar,
|
|
ft.IconButton(
|
|
icon=ft.Icons.SEARCH,
|
|
on_click=self.on_search_btn_click,
|
|
bgcolor=ft.Colors.BROWN,
|
|
icon_color=ft.Colors.WHITE
|
|
),
|
|
ft.VerticalDivider(),
|
|
self.profile_placeholder,
|
|
ft.IconButton(
|
|
icon=ft.Icons.SHOPPING_CART_OUTLINED,
|
|
bgcolor=ft.Colors.BROWN,
|
|
icon_color=ft.Colors.WHITE,
|
|
on_click=self.on_cart_btn_click
|
|
)
|
|
],
|
|
width=1000
|
|
),
|
|
ft.Row(
|
|
[
|
|
ft.IconButton(
|
|
on_click=self.on_home_btn_click,
|
|
icon=ft.Icons.HOME
|
|
),
|
|
self.product_name,
|
|
],
|
|
alignment=ft.MainAxisAlignment.START,
|
|
expand=True,
|
|
width=1000
|
|
),
|
|
ft.Container(
|
|
content= ft.Column(
|
|
[
|
|
self.desktop_container,
|
|
self.mobile_container,
|
|
],
|
|
alignment=ft.CrossAxisAlignment.START,
|
|
width=1000
|
|
),
|
|
padding=10
|
|
),
|
|
ft.Container(
|
|
content=ft.Column(
|
|
[
|
|
ft.Text("Produse similare", size=17, weight=ft.FontWeight.BOLD),
|
|
self.similar_products,
|
|
]
|
|
),
|
|
padding=10
|
|
),
|
|
ft.Row(
|
|
[
|
|
ft.Text()
|
|
],
|
|
expand=True
|
|
)
|
|
],
|
|
scroll=ft.ScrollMode.ADAPTIVE,
|
|
horizontal_alignment=ft.CrossAxisAlignment.CENTER,
|
|
width=1000
|
|
),
|
|
expand=True,
|
|
bgcolor=ft.Colors.WHITE,
|
|
padding=ft.padding.only(left=10, right=10)
|
|
) |