init commit
This commit is contained in:
389
transportmanager/client/pages/report_page.py
Normal file
389
transportmanager/client/pages/report_page.py
Normal file
@@ -0,0 +1,389 @@
|
||||
import flet as ft
|
||||
import requests
|
||||
from datetime import datetime
|
||||
from config import API_BASE_URL
|
||||
|
||||
class ReportPage:
|
||||
def __init__(self, page: ft.Page, dashboard):
|
||||
self.page = page
|
||||
self.dashboard = dashboard
|
||||
self.start_date = ft.Text()
|
||||
self.end_date = ft.Text()
|
||||
# self.client_filter = ft.TextField(label="Client", expand=True)
|
||||
# self.transporter_filter = ft.TextField(label="Transporter", expand=True)
|
||||
self.status_text = ft.Text("")
|
||||
self.results_text = ft.Text("")
|
||||
self.rows = []
|
||||
self.rows_copy = []
|
||||
self.total = ft.Text("Total: ", weight=ft.FontWeight.BOLD)
|
||||
|
||||
self.data_table = ft.DataTable(
|
||||
columns=[
|
||||
ft.DataColumn(label=ft.Text("Order #")),
|
||||
ft.DataColumn(label=ft.Text("Client")),
|
||||
ft.DataColumn(label=ft.Text("Transporter")),
|
||||
ft.DataColumn(label=ft.Text("Date")),
|
||||
ft.DataColumn(label=ft.Text("Paid (€)")),
|
||||
ft.DataColumn(label=ft.Text("Received (€)")),
|
||||
ft.DataColumn(label=ft.Text("Profit (€)")),
|
||||
],
|
||||
rows=[],
|
||||
border=ft.border.all(1, ft.Colors.GREY_300),
|
||||
expand=True
|
||||
)
|
||||
|
||||
self.all_clients = []
|
||||
self.all_transporters = []
|
||||
self.create_table_rows_data()
|
||||
|
||||
self.clients_filter = ft.Dropdown(
|
||||
options=[
|
||||
ft.dropdown.Option(text = client['name'], key=client['name']) for client in self.all_clients
|
||||
],
|
||||
width=250,
|
||||
label="Clients",
|
||||
hint_text= "Select client",
|
||||
on_change= self.filter_by_client
|
||||
)
|
||||
self.clients_filter_placeholder = ft.Container(content=self.clients_filter)
|
||||
|
||||
self.transporters_filter = ft.Dropdown(
|
||||
options=[
|
||||
ft.dropdown.Option(text = transporter['name'], key=transporter['name']) for transporter in self.all_transporters
|
||||
],
|
||||
width=250,
|
||||
label="Transporters",
|
||||
hint_text= "Select transporter",
|
||||
on_change= self.filter_by_transporter
|
||||
)
|
||||
self.transporters_filter_placeholder = ft.Container(content=self.transporters_filter)
|
||||
|
||||
def get_orders(self):
|
||||
try:
|
||||
token = self.page.client_storage.get("token")
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
response = requests.get(f"{API_BASE_URL}/orders/list", headers=headers)
|
||||
return response.json() if response.status_code == 200 else []
|
||||
except Exception as e:
|
||||
print("Error loading orders:", e)
|
||||
|
||||
def get_client(self, id):
|
||||
try:
|
||||
token = self.page.client_storage.get("token")
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
response = requests.get(f"{API_BASE_URL}/clients/{id}", headers=headers)
|
||||
if response.json() not in self.all_clients:
|
||||
self.all_clients.append(response.json())
|
||||
return response.json() if response.status_code == 200 else None
|
||||
except Exception as e:
|
||||
print("Error loading clients:", e)
|
||||
|
||||
def get_transporter(self, id):
|
||||
try:
|
||||
token = self.page.client_storage.get("token")
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
response = requests.get(f"{API_BASE_URL}/transporters/{id}", headers=headers)
|
||||
if response.json() not in self.all_transporters:
|
||||
self.all_transporters.append(response.json())
|
||||
return response.json() if response.status_code == 200 else None
|
||||
except Exception as e:
|
||||
print("Error loading transporters:", e)
|
||||
|
||||
def fetch_report(self, e):
|
||||
total = 0
|
||||
data = self.search_input.value
|
||||
self.rows_copy = self.rows
|
||||
self.data_table.rows.clear()
|
||||
buffer = []
|
||||
for r in self.rows_copy:
|
||||
if data in r[1]:
|
||||
row = ft.DataRow(
|
||||
cells=[
|
||||
ft.DataCell(ft.Text(r[0])),
|
||||
ft.DataCell(ft.Text(r[1])),
|
||||
ft.DataCell(ft.Text(r[2])),
|
||||
ft.DataCell(ft.Text(r[3])),
|
||||
ft.DataCell(ft.Text(r[4])),
|
||||
ft.DataCell(ft.Text(r[5])),
|
||||
ft.DataCell(ft.Text(r[6])),
|
||||
],
|
||||
)
|
||||
self.data_table.rows.append(row)
|
||||
buffer.append(r)
|
||||
total += r[6]
|
||||
self.rows_copy = buffer
|
||||
self.data_table.update()
|
||||
self.total.value = f"Total: {total}"
|
||||
self.total.update()
|
||||
|
||||
def create_table_rows_data(self):
|
||||
all_orders = self.get_orders()
|
||||
total = 0
|
||||
for order in all_orders:
|
||||
# Skip non-active orders from reports
|
||||
#print(order.get('status'))
|
||||
if order.get('status') != 'active':
|
||||
continue
|
||||
order_number = order['order_number']
|
||||
client_name = self.get_client(order['client_id'])['name']
|
||||
transporter_name = self.get_transporter(order['transporter_id'])['name']
|
||||
order_date = order['created_at'].split("T")[0]
|
||||
paid = order['paid_price']
|
||||
received = order['received_price']
|
||||
try:
|
||||
profit = round(float(received) - float(paid), 2)
|
||||
except:
|
||||
profit = 0.00
|
||||
|
||||
row = ft.DataRow(
|
||||
cells=[
|
||||
ft.DataCell(ft.Text(order_number)),
|
||||
ft.DataCell(ft.Text(client_name)),
|
||||
ft.DataCell(ft.Text(transporter_name)),
|
||||
ft.DataCell(ft.Text(order_date)),
|
||||
ft.DataCell(ft.Text(received)),
|
||||
ft.DataCell(ft.Text(paid)),
|
||||
ft.DataCell(ft.Text(profit)),
|
||||
],
|
||||
)
|
||||
row_data = [order_number, client_name, transporter_name, order_date, paid, received, profit]
|
||||
self.rows.append(row_data)
|
||||
self.data_table.rows.append(row)
|
||||
total += profit
|
||||
self.total.value = f"Total: {total}"
|
||||
self.rows_copy = self.rows
|
||||
|
||||
def on_reset_btn_click(self, e):
|
||||
# --- Recreate Clients dropdown to avoid sticky selection text on Flet 0.28.3 ---
|
||||
try:
|
||||
client_options = list(self.clients_filter.options)
|
||||
except Exception:
|
||||
client_options = []
|
||||
new_clients_dd = ft.Dropdown(
|
||||
options=client_options,
|
||||
width=250,
|
||||
label="Clients",
|
||||
hint_text="Select client",
|
||||
on_change=self.filter_by_client,
|
||||
value=None,
|
||||
)
|
||||
self.clients_filter = new_clients_dd
|
||||
self.clients_filter_placeholder.content = self.clients_filter
|
||||
self.clients_filter_placeholder.update()
|
||||
|
||||
# --- Recreate Transporters dropdown ---
|
||||
try:
|
||||
transporter_options = list(self.transporters_filter.options)
|
||||
except Exception:
|
||||
transporter_options = []
|
||||
new_transporters_dd = ft.Dropdown(
|
||||
options=transporter_options,
|
||||
width=250,
|
||||
label="Transporters",
|
||||
hint_text="Select transporter",
|
||||
on_change=self.filter_by_transporter,
|
||||
value=None,
|
||||
)
|
||||
self.transporters_filter = new_transporters_dd
|
||||
self.transporters_filter_placeholder.content = self.transporters_filter
|
||||
self.transporters_filter_placeholder.update()
|
||||
|
||||
self.page.update()
|
||||
self.rows_copy = list(self.rows)
|
||||
total = 0
|
||||
self.data_table.rows.clear()
|
||||
for r in self.rows_copy:
|
||||
row = ft.DataRow(
|
||||
cells=[
|
||||
ft.DataCell(ft.Text(r[0])),
|
||||
ft.DataCell(ft.Text(r[1])),
|
||||
ft.DataCell(ft.Text(r[2])),
|
||||
ft.DataCell(ft.Text(r[3])),
|
||||
ft.DataCell(ft.Text(r[4])),
|
||||
ft.DataCell(ft.Text(r[5])),
|
||||
ft.DataCell(ft.Text(r[6])),
|
||||
],
|
||||
)
|
||||
self.data_table.rows.append(row)
|
||||
total += r[6]
|
||||
self.data_table.update()
|
||||
self.total.value = f"Total: {total}"
|
||||
self.total.update()
|
||||
self.start_date.value = ""
|
||||
self.start_date.update()
|
||||
self.end_date.value = ""
|
||||
self.end_date.update()
|
||||
|
||||
def on_start_date_click(self, e):
|
||||
self.start_date.value = e.control.value.strftime('%Y-%m-%d')
|
||||
self.start_date.update()
|
||||
total = 0
|
||||
self.data_table.rows.clear()
|
||||
buffer = []
|
||||
data = datetime.strptime(self.start_date.value, '%Y-%m-%d')
|
||||
for r in self.rows_copy:
|
||||
obj_date = datetime.strptime(r[3], '%Y-%m-%d')
|
||||
if data <= obj_date:
|
||||
row = ft.DataRow(
|
||||
cells=[
|
||||
ft.DataCell(ft.Text(r[0])),
|
||||
ft.DataCell(ft.Text(r[1])),
|
||||
ft.DataCell(ft.Text(r[2])),
|
||||
ft.DataCell(ft.Text(r[3])),
|
||||
ft.DataCell(ft.Text(r[4])),
|
||||
ft.DataCell(ft.Text(r[5])),
|
||||
ft.DataCell(ft.Text(r[6])),
|
||||
],
|
||||
)
|
||||
self.data_table.rows.append(row)
|
||||
buffer.append(r)
|
||||
total += r[6]
|
||||
self.rows_copy = buffer
|
||||
self.data_table.update()
|
||||
self.total.value = f"Total: {total}"
|
||||
self.total.update()
|
||||
|
||||
def on_end_date_click(self, e):
|
||||
self.end_date.value = e.control.value.strftime('%Y-%m-%d')
|
||||
self.end_date.update()
|
||||
total = 0
|
||||
self.data_table.rows.clear()
|
||||
buffer = []
|
||||
data = datetime.strptime(self.end_date.value, '%Y-%m-%d')
|
||||
for r in self.rows_copy:
|
||||
obj_date = datetime.strptime(r[3], '%Y-%m-%d')
|
||||
if data >= obj_date:
|
||||
row = ft.DataRow(
|
||||
cells=[
|
||||
ft.DataCell(ft.Text(r[0])),
|
||||
ft.DataCell(ft.Text(r[1])),
|
||||
ft.DataCell(ft.Text(r[2])),
|
||||
ft.DataCell(ft.Text(r[3])),
|
||||
ft.DataCell(ft.Text(r[4])),
|
||||
ft.DataCell(ft.Text(r[5])),
|
||||
ft.DataCell(ft.Text(r[6])),
|
||||
],
|
||||
)
|
||||
self.data_table.rows.append(row)
|
||||
buffer.append(r)
|
||||
total += r[6]
|
||||
self.rows_copy = buffer
|
||||
self.data_table.update()
|
||||
self.total.value = f"Total: {total}"
|
||||
self.total.update()
|
||||
|
||||
def filter_by_client(self, e):
|
||||
total = 0
|
||||
self.data_table.rows.clear()
|
||||
buffer = []
|
||||
for r in self.rows_copy:
|
||||
#print(r[1])
|
||||
#print(self.clients_filter.value)
|
||||
if r[1] == self.clients_filter.value:
|
||||
row = ft.DataRow(
|
||||
cells=[
|
||||
ft.DataCell(ft.Text(r[0])),
|
||||
ft.DataCell(ft.Text(r[1])),
|
||||
ft.DataCell(ft.Text(r[2])),
|
||||
ft.DataCell(ft.Text(r[3])),
|
||||
ft.DataCell(ft.Text(r[4])),
|
||||
ft.DataCell(ft.Text(r[5])),
|
||||
ft.DataCell(ft.Text(r[6])),
|
||||
],
|
||||
)
|
||||
self.data_table.rows.append(row)
|
||||
buffer.append(r)
|
||||
total += r[6]
|
||||
self.rows_copy = buffer
|
||||
self.data_table.update()
|
||||
self.total.value = f"Total: {total}"
|
||||
self.total.update()
|
||||
|
||||
def filter_by_transporter(self, e):
|
||||
total = 0
|
||||
self.data_table.rows.clear()
|
||||
buffer = []
|
||||
for r in self.rows_copy:
|
||||
#print(r[2])
|
||||
#print(self.transporters_filter.value)
|
||||
if r[2] == self.transporters_filter.value:
|
||||
row = ft.DataRow(
|
||||
cells=[
|
||||
ft.DataCell(ft.Text(r[0])),
|
||||
ft.DataCell(ft.Text(r[1])),
|
||||
ft.DataCell(ft.Text(r[2])),
|
||||
ft.DataCell(ft.Text(r[3])),
|
||||
ft.DataCell(ft.Text(r[4])),
|
||||
ft.DataCell(ft.Text(r[5])),
|
||||
ft.DataCell(ft.Text(r[6])),
|
||||
],
|
||||
)
|
||||
self.data_table.rows.append(row)
|
||||
buffer.append(r)
|
||||
total += r[6]
|
||||
self.rows_copy = buffer
|
||||
self.data_table.update()
|
||||
self.total.value = f"Total: {total}"
|
||||
self.total.update()
|
||||
|
||||
def build(self):
|
||||
return ft.Container(
|
||||
content=ft.Column(
|
||||
[
|
||||
ft.Row(
|
||||
[
|
||||
ft.Text("Reports", size=24, weight=ft.FontWeight.BOLD),
|
||||
self.total
|
||||
],
|
||||
alignment=ft.MainAxisAlignment.SPACE_BETWEEN
|
||||
),
|
||||
ft.Row(
|
||||
[
|
||||
self.start_date,
|
||||
ft.ElevatedButton(
|
||||
"Start Date",
|
||||
on_click=lambda _: self.page.open(ft.DatePicker(
|
||||
first_date=datetime(year=2000, month=10, day=1),
|
||||
last_date=datetime(year=2025, month=10, day=1),
|
||||
on_change=self.on_start_date_click,
|
||||
)),
|
||||
width=120,
|
||||
icon=ft.Icons.CALENDAR_MONTH
|
||||
),
|
||||
self.end_date,
|
||||
ft.ElevatedButton(
|
||||
"End Date",
|
||||
on_click=lambda _: self.page.open(ft.DatePicker(
|
||||
first_date=datetime(year=2000, month=10, day=1),
|
||||
last_date=datetime(year=2025, month=10, day=1),
|
||||
on_change=self.on_end_date_click,
|
||||
)),
|
||||
width=120,
|
||||
icon=ft.Icons.CALENDAR_MONTH
|
||||
),
|
||||
ft.Text(),
|
||||
self.clients_filter_placeholder,
|
||||
self.transporters_filter_placeholder,
|
||||
ft.ElevatedButton("Reset", on_click=self.on_reset_btn_click, width=120),
|
||||
]
|
||||
),
|
||||
ft.Column(
|
||||
[
|
||||
ft.Row(
|
||||
[
|
||||
self.data_table,
|
||||
self.status_text,
|
||||
],
|
||||
expand=True,
|
||||
)
|
||||
],
|
||||
alignment=ft.MainAxisAlignment.START,
|
||||
scroll=ft.ScrollMode.ADAPTIVE,
|
||||
expand=True,
|
||||
)
|
||||
],
|
||||
expand=True,
|
||||
alignment=ft.MainAxisAlignment.START,
|
||||
),
|
||||
expand=True
|
||||
)
|
||||
Reference in New Issue
Block a user