From 9d0cc5b221eea503841c405dd457daabfb15ee0b Mon Sep 17 00:00:00 2001 From: Marius Robert Macamete Date: Mon, 10 Nov 2025 14:49:00 +0200 Subject: [PATCH] add packageing module --- UI_V2/admin/inventory/goods_reception.py | 304 +++++++++++----------- UI_V2/admin/inventory/inventory.py | 21 +- UI_V2/admin/inventory/packing.py | 310 +++++++++++++++++++++++ UI_V2/dbActions/bulk_products.py | 127 ++++++++++ UI_V2/dbActions/packing_products.py | 123 +++++++++ UI_V2/dbActions/provider_bills.py | 112 ++++++++ 6 files changed, 847 insertions(+), 150 deletions(-) create mode 100644 UI_V2/admin/inventory/packing.py create mode 100644 UI_V2/dbActions/bulk_products.py create mode 100644 UI_V2/dbActions/packing_products.py create mode 100644 UI_V2/dbActions/provider_bills.py diff --git a/UI_V2/admin/inventory/goods_reception.py b/UI_V2/admin/inventory/goods_reception.py index d15bca9..6f66401 100644 --- a/UI_V2/admin/inventory/goods_reception.py +++ b/UI_V2/admin/inventory/goods_reception.py @@ -1,211 +1,217 @@ import flet as ft -from dbActions.products import Products -from dbActions.categories import Categories +from dbActions.provider_bills import ProviderBills +from dbActions.providers import Providers +from dbActions.bulk_products import BulkProducts class GoodsReception: def __init__(self, page: ft.Page, dashboard, inventory): self.page = page - self.dashboard = dashboard - self.inventory = inventory + self.bill_manager = ProviderBills() + self.provider_manager = Providers() + self.bulk_products_manager = BulkProducts() - self.product_id = None - self.products_manager = Products() - self.category_manager = Categories() - self.all_products = self.products_manager.get_all() - self.categories = self.category_manager.get_categories() - self.list_products = ft.ListView( - controls=self.create_list(self.all_products, self.on_products_btn_click), - expand=True, - spacing=10, - width=350, - height=450 - ) - self.name = ft.TextField(label="Denumire") - self.category = ft.Dropdown( - label="Categorie", - options=self.get_categories(), + self.product_name = ft.TextField(label="Denumire") + #self.product_mesure_unit = ft.RadioGroup() + self.product_quantity = ft.TextField(label="Cantitate") + self.product_price = ft.TextField(label="Pret") + self.product_vat = ft.TextField(label="TVA (0 pentru neplatitor de TVA)", value="0") + + self.bill_number = ft.TextField(label="Serie si numar") + self.bill_date = ft.TextField(label="Data", read_only=True, expand=True) + self.provider = ft.Dropdown( + label="Furnizor", + options=self.get_providers(), expand=True ) - self.quantity = ft.TextField(label="Grame/buc") - self.init_stock = ft.TextField(label = "Stoc initial") - self.masure = ft.Dropdown( - label="Unitate de masura", - options=self.get_masure_unit(), - expand=True - ) - self.new_stock = ft.TextField(label="Stoc nou") - self.total_units = ft.TextField(label="Cantitate totala", read_only=True) - self.enter_price = ft.TextField(label="Pret intrare") - self.exit_price = ft.TextField(label = "Pret vanzare") - self.stock_min = ft.TextField(label = "Stoc minim") - self.stock_max = ft.TextField(label = "Stoc maxim") - self.search_bar = ft.TextField(label="Cauta", on_submit=self.on_search_btn_click) - self.search_btn = ft.IconButton( - icon=ft.Icons.SEARCH, - on_click=self.on_search_btn_click, - bgcolor=ft.Colors.BROWN, - icon_color=ft.Colors.WHITE - ) - - self.add_new_item_dialog = ft.AlertDialog( - title=ft.Text("Adauga intrare noua"), + self.add_bill_dialog = ft.AlertDialog( + title=ft.Text("Adauga factura"), content=ft.Column( [ + self.bill_number, ft.Row( [ - ft.Column( - [ - ft.Row( - [ - self.search_bar, - self.search_btn - ], - ), - self.list_products, - ft.Button( - "Adauga produs", - on_click=self.on_add_produt_btn_click, - icon=ft.Icons.ADD, - width=350 - ), - - ], - width=350 - ), - ft.VerticalDivider(width=2) , - ft.Column( - [ - self.name, - self.category, - self.quantity, - self.init_stock, - self.new_stock, - self.masure, - self.total_units, - self.enter_price, - self.exit_price, - self.stock_min, - self.stock_max - ], - width=320, - height=550, - scroll=ft.ScrollMode.AUTO + self.bill_date, + ft.ElevatedButton( + "Selecteaza", + icon=ft.Icons.CALENDAR_MONTH, + on_click=lambda e: page.open( + ft.DatePicker( + on_change=self.on_date_selected, + ) + ), ) ], - vertical_alignment=ft.CrossAxisAlignment.START, - spacing=10 - ) + width=400 + ), + self.provider ], - width=700, - height=650, - alignment=ft.MainAxisAlignment.START + width=400, + height=200 ), actions=[ - ft.FilledButton("Salveaza", on_click=self.on_save_btn_click), - ft.Button("Anuleaza", on_click=self.on_cancel_btn_click) + ft.Button( + "Salveaza", + on_click=self.on_save_bill_btn_click, + icon=ft.Icons.SAVE + ), + ft.Button( + "Anuleaza", + on_click=self.on_cancel_bill_btn_click, + icon=ft.Icons.CANCEL, + bgcolor=ft.Colors.GREY, + color=ft.Colors.WHITE + ) ] ) - def on_add_produt_btn_click(self, e): + self.all_bills = self.bill_manager.get_all() + + self.bills_list = ft.ListView( + controls=self.create_bill_list( + self.all_bills, + self.on_add_product_btn_click, + self.on_edit_provider_bill_btn_click, + self.on_delete_provider_bill_btn_click + ), + spacing=10, + expand=True + ) + + self.search_bar = ft.TextField(label="Cauta", expand=True, on_submit=self.on_search_btn_click) + self.search_btn = ft.IconButton( + icon=ft.Icons.SEARCH, + bgcolor=ft.Colors.BROWN, + icon_color=ft.Colors.WHITE, + on_click=self.on_search_btn_click + ) + + def on_add_product_btn_click(self, item): pass - def on_save_btn_click(self, e): + def on_edit_provider_bill_btn_click(self, item): pass - def on_cancel_btn_click(self, e): + def on_delete_provider_bill_btn_click(self, id): pass - def on_search_btn_click(self, e): - pass + def get_provider_name(self, id): + for provider in self.provider_manager.get_all_providers(): + if provider['id'] == id: + return provider['provider_name'] - def get_categories(self): - return [ - ft.dropdown.Option(key=cat['id'], text=cat['name']) - for cat in self.categories - ] - - def get_masure_unit(self): - return [ - ft.dropdown.Option(key='buc', text='BUC'), - ft.dropdown.Option(key='kg', text='KG') - ] - - def on_products_btn_click(self, item): - self.name.value = item['name'] - self.name.update() - self.category.value = item['category_id'] - self.category.update() - self.quantity.value = item['quantity'] - self.quantity.update() - # self.init_stock.value = '' - # self.new_stock.value = '' - self.masure.value = 'buc' - self.masure.update() - # self.total_units.value = '' - # self.enter_price.value = '' - self.exit_price.value = item['price'] - self.exit_price.update() - # self.stock_min.value = '' - # self.stock_max.value = '' - - - def get_category_name(self, id): - for category in self.categories: - if int(category['id']) == int(id): - return category['name'] - - def create_list(self, items, on_click_handler): + def create_bill_list(self, items, on_click_handler, on_click_handler2, on_click_handler3): """Helper to create list items for a column.""" return [ ft.Container( content=ft.Row( [ + + ft.Column( + [ + ft.Text(value=f"Factura: {item['number']} {item['date']}", weight=ft.FontWeight.BOLD), + ft.Text(value=f"Din: {item['date']}", size=12), + ft.Text(value=f"Furnizor: {self.get_provider_name(item['provider_id'])}", size=12) + ] + ), + ft.Row( [ - ft.Image( - src=item['image'], - width=50, - height=50, - fit=ft.ImageFit.COVER, - border_radius=5 + ft.FilledButton( + icon=ft.Icons.ADD, + text = 'Adauga Produs', + on_click=lambda e, id=item: on_click_handler3(id), ), - ft.Column( - [ - ft.Text(value=item['name'], weight=ft.FontWeight.BOLD, size=15), - ft.Text(value=f"Categorie: {self.get_category_name(item['category_id'])}", size=12) - ] + ft.IconButton( + icon=ft.Icons.EDIT, + on_click=lambda e, id=item: on_click_handler(id), + ), + ft.IconButton( + icon=ft.Icons.DELETE, + on_click=lambda e, id=item['id']: on_click_handler2(id), + icon_color=ft.Colors.RED, ), ] ) + ], alignment=ft.MainAxisAlignment.SPACE_BETWEEN, ), width=300, bgcolor=ft.Colors.BROWN_50, + border = ft.border.all(1, ft.Colors.GREY), padding=10, border_radius=8, - border = ft.border.all(1, ft.Colors.GREY), - ink=True, - on_click=lambda e, id=item: on_click_handler(id) ) for item in items ] - def on_add_btn_click(self, e): - self.page.open(self.add_new_item_dialog) + def on_date_selected(self, e): + self.bill_date.value = e.control.value.strftime('%d/%m/%Y') + self.bill_date.update() + + def on_add_bill_btn_click(self, e): + self.page.open(self.add_bill_dialog) + + def get_providers(self): + providers = self.provider_manager.get_all_providers() + return [ + ft.dropdown.Option(key=provider['id'], text=provider['provider_name']) + for provider in providers + ] + + def on_save_bill_btn_click(self, e): + if self.bill_number.value == None or len(self.bill_number.value)<2: + return + self.bill_manager.add_provider_bills( + self.bill_number.value, + self.bill_date.value, + self.provider.value + ) + self.on_cancel_bill_btn_click('e') + + def on_cancel_bill_btn_click(self, e): + self.bill_number.value = '' + self.bill_number.update() + self.bill_date.value = '' + self.bill_date.update() + self.provider.value = '' + self.provider.update() + self.page.close(self.add_bill_dialog) + + def on_search_btn_click(self, e): + search = self.search_bar.value + buffer = [] + for bill in self.all_bills: + if search.lower() in bill['number'].lower(): + buffer.append(bill) + + self.bills_list.controls=self.create_bill_list( + buffer, + self.on_add_product_btn_click, + self.on_edit_provider_bill_btn_click, + self.on_delete_provider_bill_btn_click + ) + self.bills_list.update() def build(self): return ft.Container( - ft.Column( + content=ft.Column( [ ft.Row( [ ft.Text("Receptie Marfa", weight=ft.FontWeight.BOLD, size=18), - ft.Button("Adauga", icon=ft.Icons.ADD, on_click=self.on_add_btn_click) + ft.Button("Adauga Factura", icon=ft.Icons.ADD, on_click=self.on_add_bill_btn_click) ], alignment=ft.MainAxisAlignment.SPACE_BETWEEN - ) + ), + ft.Row( + [ + self.search_bar, + self.search_btn + ] + ), + self.bills_list ] ) ) \ No newline at end of file diff --git a/UI_V2/admin/inventory/inventory.py b/UI_V2/admin/inventory/inventory.py index 1768c6c..ed855c3 100644 --- a/UI_V2/admin/inventory/inventory.py +++ b/UI_V2/admin/inventory/inventory.py @@ -2,6 +2,7 @@ import flet as ft from dbActions.products import Products from admin.inventory.providers import Providers from admin.inventory.goods_reception import GoodsReception +from admin.inventory.packing import Packing class Inventory: def __init__(self, page: ft.Page, dashboard): @@ -19,6 +20,11 @@ class Inventory: self.dashboard.placeholder.content = goods.build() self.dashboard.placeholder.update() + def on_packing_btn_click(self, e): + pack = Packing(self.page, self.dashboard, self) + self.dashboard.placeholder.content = pack.build() + self.dashboard.placeholder.update() + def build(self): return ft.Container( content=ft.Column( @@ -42,7 +48,7 @@ class Inventory: content=ft.Container( content=ft.Column( [ - ft.Icon(name=ft.Icons.INPUT, size=100), + ft.Icon(name=ft.Icons.TABLE_VIEW, size=100), ft.Text("Receptie Marfa", size=16, weight=ft.FontWeight.BOLD), ft.Button("Marfa", icon=ft.Icons.FORWARD, on_click=self.on_goods_btn_click) ], @@ -50,6 +56,19 @@ class Inventory: ), padding=10 ) + ), + ft.Card( + content=ft.Container( + content=ft.Column( + [ + ft.Icon(name=ft.Icons.MOVE_TO_INBOX, size=100), + ft.Text("Ambalare Produse", size=16, weight=ft.FontWeight.BOLD), + ft.Button("Ambalare", icon=ft.Icons.FORWARD, on_click=self.on_packing_btn_click) + ], + horizontal_alignment=ft.CrossAxisAlignment.CENTER + ), + padding=10 + ) ) ], spacing=10, diff --git a/UI_V2/admin/inventory/packing.py b/UI_V2/admin/inventory/packing.py new file mode 100644 index 0000000..f4c630c --- /dev/null +++ b/UI_V2/admin/inventory/packing.py @@ -0,0 +1,310 @@ +import flet as ft +from dbActions.products import Products +from dbActions.categories import Categories +from admin.products import ProductsPage +from dbActions.packing_products import PackingProducts + +class Packing: + def __init__(self, page: ft.Page, dashboard, inventory): + self.page = page + self.dashboard = dashboard + self.inventory = inventory + + self.product_id = None + self.products_manager = Products() + self.category_manager = Categories() + self.products_page = ProductsPage(self.page) + self.packing_product_manager = PackingProducts() + self.all_products = self.products_manager.get_all() + self.categories = self.category_manager.get_categories() + self.list_products = ft.ListView( + controls=self.create_list(self.all_products, self.on_products_btn_click), + expand=True, + spacing=10, + width=350, + height=450 + ) + self.name = ft.TextField(label="Denumire", read_only=True, disabled=True) + self.category = ft.TextField(label="Categorie", read_only=True, disabled=True) + self.quantity = ft.TextField(label="Grame/buc", read_only=True, disabled=True) + self.init_stock = ft.TextField(label = "Stoc initial", read_only=True, disabled=True) + self.masure = ft.TextField(label="Unitate de masura", value="BUC", read_only=True, disabled=True) + self.new_stock = ft.TextField(label="Stoc nou") + self.enter_price = ft.TextField(label="Pret intrare") + self.exit_price = ft.TextField(label = "Pret vanzare", read_only=True, disabled=True) + self.stock_min = ft.TextField(label = "Stoc minim") + self.stock_max = ft.TextField(label = "Stoc maxim") + + self.search_bar = ft.TextField(label="Cauta", on_submit=self.on_search_btn_click) + self.search_btn = ft.IconButton( + icon=ft.Icons.SEARCH, + on_click=self.on_search_btn_click, + bgcolor=ft.Colors.BROWN, + icon_color=ft.Colors.WHITE + ) + + self.add_new_item_dialog = ft.AlertDialog( + title=ft.Text("Adauga intrare noua"), + content=ft.Column( + [ + ft.Row( + [ + ft.Column( + [ + ft.Row( + [ + self.search_bar, + self.search_btn + ], + ), + self.list_products, + ft.Button( + "Adauga produs", + on_click=self.on_add_produt_btn_click, + icon=ft.Icons.ADD, + width=350 + ), + + ], + width=350 + ), + ft.VerticalDivider(width=2) , + ft.Column( + [ + self.name, + self.category, + self.quantity, + self.init_stock, + self.new_stock, + self.masure, + self.enter_price, + self.exit_price, + self.stock_min, + self.stock_max + ], + width=320, + height=550, + scroll=ft.ScrollMode.AUTO + ) + ], + vertical_alignment=ft.CrossAxisAlignment.START, + spacing=10 + ) + ], + width=700, + height=650, + alignment=ft.MainAxisAlignment.START + ), + actions=[ + ft.FilledButton("Salveaza", on_click=self.on_save_btn_click), + ft.Button("Anuleaza", on_click=self.on_cancel_btn_click) + ] + ) + + self.selected_product_id = None + + self.all_packed_products = self.packing_product_manager.get_all() + self.data_table = ft.DataTable( + columns=[ + ft.DataColumn(label=ft.Text("Denumire")), + ft.DataColumn(label=ft.Text("Categorie")), + ft.DataColumn(label=ft.Text("Gramaj / Buc")), + ft.DataColumn(label=ft.Text("Stoc")), + ft.DataColumn(label=ft.Text("Unitatea de masura")), + ft.DataColumn(label=ft.Text("Pret intrare")), + ft.DataColumn(label=ft.Text("Pret vanzare")), + ft.DataColumn(label=ft.Text("Stoc minim")), + ft.DataColumn(label=ft.Text("Stoc maxim")) + ], + rows=[], + expand=True + ) + for pack_product in self.all_packed_products: + for product in self.all_products: + if pack_product['product_id'] == product['id']: + categorie = self.get_category_name(product['category_id']) + print(categorie) + row = ft.DataRow( + cells=[ + ft.DataCell(ft.Text(product['name'])), + ft.DataCell(ft.Text(categorie)), + ft.DataCell(ft.Text(product['quantity'])), + ft.DataCell(ft.Text(pack_product['stock'])), + ft.DataCell(ft.Text("BUC")), + ft.DataCell(ft.Text(pack_product['enter_price'])), + ft.DataCell(ft.Text(product['price'])), + ft.DataCell(ft.Text(pack_product['stock_min'])), + ft.DataCell(ft.Text(pack_product['stock_max'])) + ], + ) + self.data_table.rows.append(row) + + def on_add_produt_btn_click(self, e): + self.page.close(self.add_new_item_dialog) + self.dashboard.placeholder.content = self.products_page.build() + self.dashboard.placeholder.update() + + def on_save_btn_click(self, e): + product_id = self.selected_product_id + init_stock = self.init_stock.value + new_stock = self.new_stock.value + stock = 0 + try: + stock = int(init_stock) + int(new_stock) + except Exception as e: + print(e) + return + enter_price = self.enter_price.value + stock_min = self.stock_min.value + stock_max = self.stock_max.value + self.page.close(self.add_new_item_dialog) + self.product_data = self.packing_product_manager.get_packing_product_by_product_id(product_id) + if self.product_data: + self.packing_product_manager.update_packing_products( + id = self.product_data['id'], + product_id = product_id, + stock = stock, + enter_price=enter_price, + stock_min=stock_min, + stock_max=stock_max + ) + else: + self.packing_product_manager.add_packing_product( + product_id = product_id, + stock = stock, + enter_price=enter_price, + stock_min=stock_min, + stock_max=stock_max + ) + self.selected_product_id = None + + self.reset_filed() + + def on_cancel_btn_click(self, e): + print("cancel dialog") + self.page.close(self.add_new_item_dialog) + + def on_search_btn_click(self, e): + buffer = [] + search = self.search_bar.value + for product in self.all_products: + if search.lower() in product['name'].lower(): + buffer.append(product) + self.list_products.controls = self.create_list(buffer, self.on_products_btn_click) + self.list_products.update() + + def get_total(self, update = False): + try: + print("calculating total") + init = float(self.init_stock.value) if self.init_stock.value else 0 + new = float(self.new_stock.value) if self.new_stock.value else 0 + return init + new + except Exception as e: + print(e) + + def on_products_btn_click(self, item): + #product data + self.product_data = self.packing_product_manager.get_packing_product_by_product_id(item['id']) + print(self.product_data) + self.selected_product_id = item['id'] + + self.name.value = item['name'] + self.name.update() + self.category.value = self.get_category_name(item['category_id']) + self.category.update() + self.quantity.value = item['quantity'] + self.quantity.update() + self.exit_price.value = item['price'] + self.exit_price.update() + #new order data + self.init_stock.value = self.product_data['stock'] if self.product_data else '0' + self.init_stock.update() + self.new_stock.value = '' + self.new_stock.update() + self.enter_price.value = self.product_data['enter_price'] if self.product_data else '' + self.enter_price.update() + self.stock_min.value = self.product_data['stock_min'] if self.product_data else '' + self.stock_min.update() + self.stock_max.value = self.product_data['stock_max'] if self.product_data else '' + self.stock_max.update() + + def reset_filed(self): + self.name.value = None + self.name.update() + self.category.value = None + self.category.update() + self.quantity.value = None + self.quantity.update() + self.exit_price.value = None + self.exit_price.update() + self.init_stock.value = None + self.init_stock.update() + self.new_stock.value = None + self.new_stock.update() + self.enter_price.value = None + self.enter_price.update() + self.stock_min.value = None + self.stock_min.update() + self.stock_max.value = None + self.stock_max.update() + + def get_category_name(self, id): + for category in self.categories: + if int(category['id']) == int(id): + return category['name'] + + def create_list(self, items, on_click_handler): + """Helper to create list items for a column.""" + return [ + ft.Container( + content=ft.Row( + [ + ft.Row( + [ + ft.Image( + src=item['image'], + width=50, + height=50, + fit=ft.ImageFit.COVER, + border_radius=5 + ), + ft.Column( + [ + ft.Text(value=item['name'], weight=ft.FontWeight.BOLD, size=15), + ft.Text(value=f"Categorie: {self.get_category_name(item['category_id'])}", size=12) + ] + ), + ] + ) + ], + 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), + ink=True, + on_click=lambda e, id=item: on_click_handler(id) + ) + for item in items + ] + + def on_add_btn_click(self, e): + self.page.open(self.add_new_item_dialog) + + def build(self): + return ft.Container( + ft.Column( + [ + ft.Row( + [ + ft.Text("Ambalare Produse", weight=ft.FontWeight.BOLD, size=18), + ft.Button("Adauga", icon=ft.Icons.ADD, on_click=self.on_add_btn_click) + ], + alignment=ft.MainAxisAlignment.SPACE_BETWEEN + ), + self.data_table + ] + ) + ) \ No newline at end of file diff --git a/UI_V2/dbActions/bulk_products.py b/UI_V2/dbActions/bulk_products.py new file mode 100644 index 0000000..0894f16 --- /dev/null +++ b/UI_V2/dbActions/bulk_products.py @@ -0,0 +1,127 @@ +import sqlite3 +from typing import Optional + +class BulkProducts: + def __init__(self, db_path="instance/app_database.db"): + self.db_path = db_path + self._create_bulk_products_table() + + def _create_bulk_products_table(self): + with sqlite3.connect(self.db_path) as conn: + cursor = conn.cursor() + cursor.execute(""" + CREATE TABLE IF NOT EXISTS bulk_products ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + bill_id INTEGER, + name TEXT, + mesure_unit TEXT, + quantity DOUBLE, + price DOUBLE, + vat INTEGER default 0, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP + ); + """) + conn.commit() + + def add_bulk_products_product(self, bill_id, name, mesure_unit, quantity, price, vat): + try: + with sqlite3.connect(self.db_path) as conn: + cursor = conn.cursor() + cursor.execute(""" + INSERT INTO bulk_products (bill_id, name, mesure_unit, quantity, price, vat) + VALUES (?, ?, ?, ?, ?, ?) + """, (bill_id, name, mesure_unit, quantity, price, vat)) + conn.commit() + return True + except sqlite3.IntegrityError: + return False + + def get_all(self): + with sqlite3.connect(self.db_path) as conn: + cursor = conn.cursor() + cursor.execute(""" + SELECT * FROM bulk_products + """,) + rows = cursor.fetchall() + result = [] + if rows: + for row in rows: + buffer = { + "id": row[0], + "bill_id": row[1], + "name": row[2], + "mesure_unit": row[3], + "quantity": row[4], + "price": row[5], + "vat": row[6], + "created_at": row[7] + } + result.append(buffer) + return result + return [] + + def get_one(self, id): + with sqlite3.connect(self.db_path) as conn: + cursor = conn.cursor() + cursor.execute(""" + SELECT * FROM bulk_products WHERE id = ? + """,(id, )) + row = cursor.fetchone() + result = [] + if row: + result = { + "id": row[0], + "bill_id": row[1], + "name": row[2], + "mesure_unit": row[3], + "quantity": row[4], + "price": row[5], + "vat": row[6], + "created_at": row[7] + } + return result + return None + + def get_product_by_bill_id(self, bill_id): + with sqlite3.connect(self.db_path) as conn: + cursor = conn.cursor() + cursor.execute(""" + SELECT * FROM bulk_products WHERE bill_id = ? + """,(bill_id, )) + row = cursor.fetchone() + result = [] + if row: + result = { + "id": row[0], + "bill_id": row[1], + "name": row[2], + "mesure_unit": row[3], + "quantity": row[4], + "price": row[5], + "vat": row[6], + "created_at": row[7] + } + return result + return None + + def remove(self, id): + with sqlite3.connect(self.db_path) as conn: + cursor = conn.cursor() + cursor.execute(''' + DELETE FROM bulk_products WHERE id=?; + ''', (id,)) + conn.commit() + + def update(self, id, bill_id, name, mesure_unit, quantity, price, vat): + try: + with sqlite3.connect(self.db_path) as conn: + cursor = conn.cursor() + cursor.execute(""" + UPDATE bulk_products + SET bill_id = ?, name = ?, mesure_unit = ?, quantity = ?, price = ?, vat = ? + WHERE id = ? + """, (bill_id, name, mesure_unit, quantity, price, vat, id)) + conn.commit() + return True + except Exception: + return False \ No newline at end of file diff --git a/UI_V2/dbActions/packing_products.py b/UI_V2/dbActions/packing_products.py new file mode 100644 index 0000000..c7842dc --- /dev/null +++ b/UI_V2/dbActions/packing_products.py @@ -0,0 +1,123 @@ +import sqlite3 +from typing import Optional + +class PackingProducts: + def __init__(self, db_path="instance/app_database.db"): + self.db_path = db_path + self._create_packing_products_table() + + def _create_packing_products_table(self): + with sqlite3.connect(self.db_path) as conn: + cursor = conn.cursor() + cursor.execute(""" + CREATE TABLE IF NOT EXISTS packing_products ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + product_id INTEGER, + stock INTEGER DEFAULT 0, + enter_price DOUBLE, + stock_min INTEGER, + stock_max INTEGER, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP + ); + """) + conn.commit() + + def add_packing_product(self, product_id, stock, enter_price, stock_min, stock_max): + try: + with sqlite3.connect(self.db_path) as conn: + cursor = conn.cursor() + cursor.execute(""" + INSERT INTO packing_products (product_id, stock, enter_price, stock_min, stock_max) + VALUES (?, ?, ?, ?, ?) + """, (product_id, stock, enter_price, stock_min, stock_max)) + conn.commit() + return True + except sqlite3.IntegrityError: + return False + + def get_all(self): + with sqlite3.connect(self.db_path) as conn: + cursor = conn.cursor() + cursor.execute(""" + SELECT * FROM packing_products + """,) + rows = cursor.fetchall() + result = [] + if rows: + for row in rows: + buffer = { + "id": row[0], + "product_id": row[1], + "stock": row[2], + "enter_price": row[3], + "stock_min": row[4], + "stock_max": row[5], + "created_at": row[6] + } + result.append(buffer) + return result + return [] + + def get_packing_product(self, id): + with sqlite3.connect(self.db_path) as conn: + cursor = conn.cursor() + cursor.execute(""" + SELECT * FROM packing_products WHERE id = ? + """,(id, )) + row = cursor.fetchone() + result = [] + if row: + result = { + "id": row[0], + "product_id": row[1], + "stock": row[2], + "enter_price": row[3], + "stock_min": row[4], + "stock_max": row[5], + "created_at": row[6] + } + return result + return None + + def get_packing_product_by_product_id(self, product_id): + with sqlite3.connect(self.db_path) as conn: + cursor = conn.cursor() + cursor.execute(""" + SELECT * FROM packing_products WHERE product_id = ? + """,(product_id, )) + row = cursor.fetchone() + result = [] + if row: + result = { + "id": row[0], + "product_id": row[1], + "stock": row[2], + "enter_price": row[3], + "stock_min": row[4], + "stock_max": row[5], + "created_at": row[6] + } + return result + return None + + def remove_packing_product(self, id): + with sqlite3.connect(self.db_path) as conn: + cursor = conn.cursor() + cursor.execute(''' + DELETE FROM packing_products WHERE id=?; + ''', (id,)) + conn.commit() + + def update_packing_products(self, id, product_id, stock, enter_price, stock_min, stock_max): + try: + with sqlite3.connect(self.db_path) as conn: + cursor = conn.cursor() + cursor.execute(""" + UPDATE packing_products + SET product_id = ?, stock = ?, enter_price = ?, stock_min = ?, stock_max = ? + WHERE id = ? + """, (product_id, stock, enter_price, stock_min, stock_max, id)) + conn.commit() + return True + except Exception: + return False \ No newline at end of file diff --git a/UI_V2/dbActions/provider_bills.py b/UI_V2/dbActions/provider_bills.py new file mode 100644 index 0000000..88ed6c2 --- /dev/null +++ b/UI_V2/dbActions/provider_bills.py @@ -0,0 +1,112 @@ +import sqlite3 +from typing import Optional + +class ProviderBills: + def __init__(self, db_path="instance/app_database.db"): + self.db_path = db_path + self._create_provider_bills_table() + + def _create_provider_bills_table(self): + with sqlite3.connect(self.db_path) as conn: + cursor = conn.cursor() + cursor.execute(""" + CREATE TABLE IF NOT EXISTS provider_bills ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + number TEXT, + date TEXT, + provider_id INTEGER + ); + """) + conn.commit() + + def add_provider_bills(self, number, date, provider_id): + try: + with sqlite3.connect(self.db_path) as conn: + cursor = conn.cursor() + cursor.execute(""" + INSERT INTO provider_bills (number, date, provider_id) + VALUES (?, ?, ?) + """, (number, date, provider_id)) + conn.commit() + return True + except sqlite3.IntegrityError: + return False + + def get_all(self): + with sqlite3.connect(self.db_path) as conn: + cursor = conn.cursor() + cursor.execute(""" + SELECT * FROM provider_bills + """,) + rows = cursor.fetchall() + result = [] + if rows: + for row in rows: + buffer = { + "id": row[0], + "number": row[1], + "date": row[2], + "provider_id": row[3] + } + result.append(buffer) + return result + return [] + + def get_one(self, id): + with sqlite3.connect(self.db_path) as conn: + cursor = conn.cursor() + cursor.execute(""" + SELECT * FROM provider_bills WHERE id = ? + """,(id, )) + row = cursor.fetchone() + result = [] + if row: + result = { + "id": row[0], + "number": row[1], + "date": row[2], + "provider_id": row[3] + } + return result + return None + + def get_bill_by_provider_id(self, provider_id): + with sqlite3.connect(self.db_path) as conn: + cursor = conn.cursor() + cursor.execute(""" + SELECT * FROM provider_bills WHERE provider_id = ? + """,(provider_id, )) + row = cursor.fetchone() + result = [] + if row: + result = { + "id": row[0], + "number": row[1], + "date": row[2], + "provider_id": row[3], + "created_at": row[4] + } + return result + return None + + def remove(self, id): + with sqlite3.connect(self.db_path) as conn: + cursor = conn.cursor() + cursor.execute(''' + DELETE FROM provider_bills WHERE id=?; + ''', (id,)) + conn.commit() + + def update(self, id, number, date, provider_id): + try: + with sqlite3.connect(self.db_path) as conn: + cursor = conn.cursor() + cursor.execute(""" + UPDATE provider_bills + SET number = ?, date = ?, provider_id = ? + WHERE id = ? + """, (number, date, provider_id, id)) + conn.commit() + return True + except Exception: + return False \ No newline at end of file