From eb0cd0005e406677e46bad58dca5f4ea8f353111 Mon Sep 17 00:00:00 2001 From: Dries Peeters Date: Sat, 3 Jan 2026 20:27:54 +0100 Subject: [PATCH] feat: enhance inventory management features - Update stock movement model with improved functionality - Enhance inventory routes and API endpoints - Improve inventory templates for movements, reports, and stock items - Add better history tracking and valuation reporting --- app/models/stock_movement.py | 8 +++++++- app/routes/inventory.py | 7 ++++++- app/templates/inventory/movements/form.html | 1 + app/templates/inventory/movements/list.html | 1 + app/templates/inventory/reports/movement_history.html | 1 + app/templates/inventory/reports/valuation.html | 4 ++-- app/templates/inventory/stock_items/history.html | 1 + 7 files changed, 19 insertions(+), 4 deletions(-) diff --git a/app/models/stock_movement.py b/app/models/stock_movement.py index 9951beb..6f87881 100644 --- a/app/models/stock_movement.py +++ b/app/models/stock_movement.py @@ -13,7 +13,7 @@ class StockMovement(db.Model): id = db.Column(db.Integer, primary_key=True) movement_type = db.Column( db.String(20), nullable=False, index=True - ) # 'adjustment', 'transfer', 'sale', 'purchase', 'return', 'waste' + ) # 'adjustment', 'transfer', 'sale', 'rent', 'purchase', 'return', 'waste' stock_item_id = db.Column(db.Integer, db.ForeignKey("stock_items.id"), nullable=False, index=True) warehouse_id = db.Column(db.Integer, db.ForeignKey("warehouses.id"), nullable=False, index=True) quantity = db.Column(db.Numeric(10, 2), nullable=False) # Positive for additions, negative for removals @@ -307,6 +307,12 @@ class StockMovement(db.Model): return # Outbound: consume FIFO (oldest first). Prefer a specific lot if provided (used after devaluation). + # Special case: "rent" movements keep value in stock (don't consume from lots) for accounting purposes + if qty < 0 and movement.movement_type == "rent": + # For rent, we don't consume from lots - this keeps the value in inventory + # while removing physical quantity from warehouse + return + qty_to_consume = abs(qty) allow_negative = movement.movement_type == "adjustment" diff --git a/app/routes/inventory.py b/app/routes/inventory.py index f2e7c92..6047952 100644 --- a/app/routes/inventory.py +++ b/app/routes/inventory.py @@ -1906,7 +1906,12 @@ def reports_valuation(): stock_item_id=item_detail["item_id"], warehouse_id=item_detail["warehouse_id"] ).first() if stock: - items_with_value.append({"stock": stock, "value": item_detail["value"]}) + items_with_value.append({ + "stock": stock, + "value": item_detail["value"], + "quantity": item_detail.get("quantity"), + "cost": item_detail.get("cost") + }) return render_template( "inventory/reports/valuation.html", diff --git a/app/templates/inventory/movements/form.html b/app/templates/inventory/movements/form.html index 4866b56..02c54e5 100644 --- a/app/templates/inventory/movements/form.html +++ b/app/templates/inventory/movements/form.html @@ -25,6 +25,7 @@ + diff --git a/app/templates/inventory/movements/list.html b/app/templates/inventory/movements/list.html index 9693a64..db38853 100644 --- a/app/templates/inventory/movements/list.html +++ b/app/templates/inventory/movements/list.html @@ -24,6 +24,7 @@ + diff --git a/app/templates/inventory/reports/movement_history.html b/app/templates/inventory/reports/movement_history.html index ee258a7..b0553e3 100644 --- a/app/templates/inventory/reports/movement_history.html +++ b/app/templates/inventory/reports/movement_history.html @@ -42,6 +42,7 @@ + diff --git a/app/templates/inventory/reports/valuation.html b/app/templates/inventory/reports/valuation.html index 4590f8d..0d3952d 100644 --- a/app/templates/inventory/reports/valuation.html +++ b/app/templates/inventory/reports/valuation.html @@ -78,8 +78,8 @@ {{ item_data.stock.stock_item.sku }} {{ item_data.stock.stock_item.category or '—' }} - {{ item_data.stock.quantity_on_hand }} - {{ "%.2f"|format(item_data.stock.stock_item.default_cost or 0) }} EUR + {{ "%.2f"|format(item_data.quantity) if item_data.quantity is not none else item_data.stock.quantity_on_hand }} + {{ "%.2f"|format(item_data.cost) if item_data.cost is not none else (item_data.stock.stock_item.default_cost or 0) }} EUR {{ "%.2f"|format(item_data.value) }} EUR {% else %} diff --git a/app/templates/inventory/stock_items/history.html b/app/templates/inventory/stock_items/history.html index ddba3e3..ddbf44c 100644 --- a/app/templates/inventory/stock_items/history.html +++ b/app/templates/inventory/stock_items/history.html @@ -34,6 +34,7 @@ +