intrgrating suggestions after betta 1

This commit is contained in:
2025-09-08 18:06:00 +03:00
parent eb262451ad
commit 106045d72a
34 changed files with 1549 additions and 146 deletions

View File

@@ -129,6 +129,7 @@ class OrdersInPage:
)
self.ldm_quantity = ft.TextField(
value='13.6',
expand=True,
keyboard_type=ft.KeyboardType.NUMBER,
input_filter=ft.InputFilter(allow=True, regex_string=r"^[0-9]*\.?[0-9]*$", replacement_string="")
@@ -159,7 +160,12 @@ class OrdersInPage:
)
self.received_price = ft.TextField(
label="Price Received - visible only to you!",
label="Price Received",
keyboard_type=ft.KeyboardType.NUMBER,
input_filter=ft.InputFilter(allow=True, regex_string=r"^[0-9]*\.?[0-9]*$", replacement_string="")
)
self.expenses = ft.TextField(
label="Expenses",
keyboard_type=ft.KeyboardType.NUMBER,
input_filter=ft.InputFilter(allow=True, regex_string=r"^[0-9]*\.?[0-9]*$", replacement_string="")
)
@@ -193,6 +199,130 @@ class OrdersInPage:
),
)
self.file_picker = ft.FilePicker(on_result=self.on_file_result)
self.page.overlay.append(self.file_picker)
# --- Persistent date & time pickers (must be on page.overlay) ---
self.loading_date_picker = ft.DatePicker(
first_date=datetime.datetime(year=2000, month=10, day=1),
last_date=datetime.datetime(year=2025, month=10, day=1),
on_change=self.on_loading_date_click,
)
self.unloading_date_picker = ft.DatePicker(
first_date=datetime.datetime(year=2000, month=10, day=1),
last_date=datetime.datetime(year=2025, month=10, day=1),
on_change=self.on_unloading_date_click,
)
self.loading_time_picker_start = ft.TimePicker(
confirm_text="Confirm",
error_invalid_text="Time out of range",
help_text="Pick your time slot",
on_change=self.on_loading_hour_click,
time_picker_entry_mode=ft.TimePickerEntryMode.INPUT_ONLY,
)
self.loading_time_picker_end = ft.TimePicker(
confirm_text="Confirm",
error_invalid_text="Time out of range",
help_text="Pick your time slot",
on_change=self.on_loading_hour_click,
time_picker_entry_mode=ft.TimePickerEntryMode.INPUT_ONLY,
)
self.unloading_time_picker_start = ft.TimePicker(
confirm_text="Confirm",
error_invalid_text="Time out of range",
help_text="Pick your time slot",
on_change=self.on_unloading_hour_click,
time_picker_entry_mode=ft.TimePickerEntryMode.INPUT_ONLY,
)
self.unloading_time_picker_end = ft.TimePicker(
confirm_text="Confirm",
error_invalid_text="Time out of range",
help_text="Pick your time slot",
on_change=self.on_unloading_hour_click,
time_picker_entry_mode=ft.TimePickerEntryMode.INPUT_ONLY,
)
# Attach to overlay
self.page.overlay.extend([
self.loading_date_picker,
self.unloading_date_picker,
self.loading_time_picker_start,
self.loading_time_picker_end,
self.unloading_time_picker_start,
self.unloading_time_picker_end,
])
#self.page.update()
self.upload_order_btn = ft.Button(
"Upload",
icon=ft.Icons.UPLOAD_FILE,
width=150,
on_click=self.on_upload_document_btn_click
)
self.filename = ft.Text()
def _open_date_picker(self, picker):
# Works on both newer and older Flet
if hasattr(picker, "pick_date"):
picker.pick_date()
else:
picker.open = True
self.page.update()
def _open_time_picker(self, picker):
# Works on both newer and older Flet
if hasattr(picker, "pick_time"):
picker.pick_time()
else:
picker.open = True
self.page.update()
def on_upload_document_btn_click(self, e):
# Ensure FilePicker is attached to the page (Portainer/Flet sometimes reuses page objects)
if self.file_picker not in getattr(self.page.overlay, "controls", []):
self.page.overlay.append(self.file_picker)
self.page.update()
self.file_picker.pick_files(
allow_multiple=False,
allowed_extensions=["png", "jpg", "jpeg", "pdf"]
)
def on_file_result(self, e: ft.FilePickerResultEvent):
if not e.files:
return
file = e.files[0]
# Build a safe filename: order_in_YYYYmmdd_HHMMSS_userid_originalname
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
user_id = self.page.session.get("user_id")
new_filename = f"order_in_{timestamp}_{user_id}_{file.name}"
upload_url = self.page.get_upload_url(new_filename, 1000)
self.file_picker.upload([ft.FilePickerUploadFile(file.name, upload_url=upload_url)])
self.filename.value = new_filename
self.filename.update()
#import os
#import shutil
#source_path = os.path.join("uploads", new_filename)
# destination_path = os.path.join("assets/images", new_filename)
# try:
# time.sleep(2)
# shutil.move(source_path, destination_path)
# self.logo.src = f"images/{new_filename}"
# self.logo.update()
# self.logo_field.value = new_filename
# self.page.update()
# self.page.client_storage.set("logo_filename", new_filename)
# self.dashboard.logo.src = f"images/{new_filename}"
# self.dashboard.logo.update()
# except Exception as err:
# self.message.value = f"Upload error: {err}"
# self.message.color = ft.Colors.RED
# self.page.update()
def on_location_btn_click(self, destination):
query = destination["address"].replace(", ", "+")
maps_url = f"https://www.google.com/maps/search/?api=1&query={query}"
@@ -266,7 +396,7 @@ class OrdersInPage:
#print(self.loading_date.value)
def on_loading_hour_click(self, e):
if len(self.loading_hour.value) != None and len(self.loading_hour.value)==0:
if not self.loading_hour.value:
self.loading_hour.value = str(e.control.value)
else:
self.loading_hour.value += f' - {e.control.value}'
@@ -322,10 +452,10 @@ class OrdersInPage:
self.loading_error_message.value = "Please select loading point!"
self.loading_error_message.update()
return
if self.loading_informations.value == None or len(self.loading_informations.value) == 0:
self.loading_error_message.value = "Add loading informations!"
self.loading_error_message.update()
return
# if self.loading_informations.value == None or len(self.loading_informations.value) == 0:
# self.loading_error_message.value = "Add loading informations!"
# self.loading_error_message.update()
# return
if self.loading_date.value == None or len(str(self.loading_date.value)) == 0:
self.loading_error_message.value = "Add loading date!"
self.loading_error_message.update()
@@ -391,7 +521,7 @@ class OrdersInPage:
self.unloading_date.update()
def on_unloading_hour_click(self, e):
if len(self.unloading_hour.value) != None and len(self.unloading_hour.value)==0:
if not self.unloading_hour.value:
self.unloading_hour.value = str(e.control.value)
else:
self.unloading_hour.value += f' - {e.control.value}'
@@ -440,10 +570,10 @@ class OrdersInPage:
self.unloading_error_message.value = "Please select unloading point!"
self.unloading_error_message.update()
return
if self.unloading_informations.value == None or len(self.unloading_informations.value) == 0:
self.unloading_error_message.value = "Add unloading informations!"
self.unloading_error_message.update()
return
# if self.unloading_informations.value == None or len(self.unloading_informations.value) == 0:
# self.unloading_error_message.value = "Add unloading informations!"
# self.unloading_error_message.update()
# return
if self.unloading_date.value == None or len(str(self.unloading_date.value)) == 0:
self.unloading_error_message.value = "Add unloading date!"
self.unloading_error_message.update()
@@ -684,7 +814,9 @@ class OrdersInPage:
'trailer_reg_number': self.trailer_reg_number.value,
'received_price': self.received_price.value,
'loading_addresses': loading_addresses,
'unloading_addresses': unloading_addresses
'unloading_addresses': unloading_addresses,
'file':self.filename.value,
'expenses': self.expenses.value,
}
#print(saved_data)
if self.order_number.value == None or len(self.order_number.value)==0:
@@ -762,6 +894,18 @@ class OrdersInPage:
except Exception as ex:
self.error_message.value = f"Error: {str(ex)}"
self.error_message.update()
def get_client_access(self):
token = self.page.client_storage.get("token")
headers = {"Authorization": f"Bearer {token}"}
response = requests.get(f"{API_BASE_URL}/profile/", headers=headers, timeout=10)
user = response.json()
if user['user_role'] == 'user':
return True
else:
id = self.page.session.get("user_id")
response = requests.get(f"{API_BASE_URL}/company_user/access/{id}", headers=headers)
return True if response.json()['orders_in'] == 1 else False
def build(self):
self.save_btn = ft.FilledButton(
@@ -785,7 +929,9 @@ class OrdersInPage:
ft.Row(
[
ft.Text("Number", size=18, weight=ft.FontWeight.BOLD),
self.order_number
self.order_number,
self.upload_order_btn,
self.filename
]
)
],
@@ -882,11 +1028,12 @@ class OrdersInPage:
[
ft.Row(
[
ft.Text("Price", size=18, weight=ft.FontWeight.BOLD)
ft.Text("Price / Expenses", size=18, weight=ft.FontWeight.BOLD)
],
alignment=ft.MainAxisAlignment.START
),
self.received_price,
self.expenses
],
expand=2.5
)
@@ -926,15 +1073,9 @@ class OrdersInPage:
[
self.loading_date,
ft.ElevatedButton(
"Pick date",
"Select date",
icon=ft.Icons.CALENDAR_MONTH,
on_click=lambda e: self.page.open(
ft.DatePicker(
first_date=datetime.datetime(year=2000, month=10, day=1),
last_date=datetime.datetime(year=2025, month=10, day=1),
on_change=self.on_loading_date_click,
)
),
on_click=lambda e: self._open_date_picker(self.loading_date_picker),
)
],
expand=True
@@ -943,30 +1084,14 @@ class OrdersInPage:
[
self.loading_hour,
ft.ElevatedButton(
"Pick hour - Start",
"Select hour - Start",
icon=ft.Icons.CALENDAR_MONTH,
on_click=lambda e: self.page.open(
ft.TimePicker(
confirm_text="Confirm",
error_invalid_text="Time out of range",
help_text="Pick your time slot",
on_change=self.on_loading_hour_click,
time_picker_entry_mode = ft.TimePickerEntryMode.INPUT_ONLY
)
),
on_click=lambda e: self._open_time_picker(self.loading_time_picker_start),
),
ft.ElevatedButton(
"Pick hour - End",
"Select hour - End",
icon=ft.Icons.CALENDAR_MONTH,
on_click=lambda e: self.page.open(
ft.TimePicker(
confirm_text="Confirm",
error_invalid_text="Time out of range",
help_text="Pick your time slot",
on_change=self.on_loading_hour_click,
time_picker_entry_mode = ft.TimePickerEntryMode.INPUT_ONLY
)
),
on_click=lambda e: self._open_time_picker(self.loading_time_picker_end),
),
ft.ElevatedButton(
"Reset",
@@ -1019,15 +1144,9 @@ class OrdersInPage:
[
self.unloading_date,
ft.ElevatedButton(
"Pick date",
"Select date",
icon=ft.Icons.CALENDAR_MONTH,
on_click=lambda e: self.page.open(
ft.DatePicker(
first_date=datetime.datetime(year=2000, month=10, day=1),
last_date=datetime.datetime(year=2025, month=10, day=1),
on_change=self.on_unloading_date_click,
)
),
on_click=lambda e: self._open_date_picker(self.unloading_date_picker),
)
],
expand=True
@@ -1036,30 +1155,14 @@ class OrdersInPage:
[
self.unloading_hour,
ft.ElevatedButton(
"Pick hour - Start",
"Select hour - Start",
icon=ft.Icons.CALENDAR_MONTH,
on_click=lambda e: self.page.open(
ft.TimePicker(
confirm_text="Confirm",
error_invalid_text="Time out of range",
help_text="Pick your time slot",
on_change=self.on_unloading_hour_click,
time_picker_entry_mode = ft.TimePickerEntryMode.INPUT_ONLY
)
),
on_click=lambda e: self._open_time_picker(self.unloading_time_picker_start),
),
ft.ElevatedButton(
"Pick hour - End",
"Select hour - End",
icon=ft.Icons.CALENDAR_MONTH,
on_click=lambda e: self.page.open(
ft.TimePicker(
confirm_text="Confirm",
error_invalid_text="Time out of range",
help_text="Pick your time slot",
on_change=self.on_unloading_hour_click,
time_picker_entry_mode = ft.TimePickerEntryMode.INPUT_ONLY
)
),
on_click=lambda e: self._open_time_picker(self.unloading_time_picker_end),
),
ft.ElevatedButton(
"Reset",
@@ -1101,5 +1204,31 @@ class OrdersInPage:
scroll=ft.ScrollMode.ADAPTIVE,
spacing=20
)
) if self.get_client_access() else ft.Container(
content=ft.Column(
[
ft.Row(
[
ft.Text("Create Order In", size=24, weight=ft.FontWeight.BOLD),
],
alignment=ft.MainAxisAlignment.SPACE_BETWEEN
),
ft.Row(
[
ft.Text(
"You do not have access to this page content",
size=24,
weight=ft.FontWeight.BOLD,
color=ft.Colors.RED
)
],
alignment=ft.MainAxisAlignment.CENTER
),
ft.Text("")
],
alignment=ft.MainAxisAlignment.SPACE_BETWEEN,
expand=True
),
expand=True
)