From db8c27ae3c03a26309a8ba4e84759d9e23f4b297 Mon Sep 17 00:00:00 2001 From: A R R R Associates Date: Sat, 12 Sep 2026 15:43:43 +0530 Subject: [PATCH] Fix opening balance inventory movement schema compatibility --- .../erp_local_agent/commands.py | 131 +++++++++++++++++- 1 file changed, 125 insertions(+), 6 deletions(-) diff --git a/app/modules/documents/local_agent_runtime/erp_local_agent/commands.py b/app/modules/documents/local_agent_runtime/erp_local_agent/commands.py index ffd95f0..73ba1d3 100644 --- a/app/modules/documents/local_agent_runtime/erp_local_agent/commands.py +++ b/app/modules/documents/local_agent_runtime/erp_local_agent/commands.py @@ -801,15 +801,134 @@ class AgentCommandProcessor: closing_qty = opening_qty closing_value = opening_value if previous_year: + # Accounting Mirror schema compatibility: + # + # Current ODBC mirrors store inventory quantity in + # signed_qty / billed_qty / actual_qty rather than the + # legacy quantity column. Older mirrors may still contain + # direction + quantity + value. + # + # Resolve the available schema at runtime so historical + # mirrors and current mirrors can both be reviewed without + # changing the .act database. + inventory_columns = { + str(info["name"] or "").strip().casefold() + for info in db.execute( + "PRAGMA table_info(inventory_movement)" + ).fetchall() + } + + if "signed_qty" in inventory_columns: + qty_sql = "COALESCE(SUM(signed_qty),0)" + elif "quantity" in inventory_columns and "direction" in inventory_columns: + qty_sql = """ + COALESCE( + SUM( + CASE + WHEN UPPER(direction)='INWARD' + THEN ABS(quantity) + WHEN UPPER(direction)='OUTWARD' + THEN -ABS(quantity) + ELSE 0 + END + ), + 0 + ) + """ + elif "actual_qty" in inventory_columns and "direction" in inventory_columns: + qty_sql = """ + COALESCE( + SUM( + CASE + WHEN UPPER(direction)='INWARD' + THEN ABS(actual_qty) + WHEN UPPER(direction)='OUTWARD' + THEN -ABS(actual_qty) + ELSE 0 + END + ), + 0 + ) + """ + elif "billed_qty" in inventory_columns and "direction" in inventory_columns: + qty_sql = """ + COALESCE( + SUM( + CASE + WHEN UPPER(direction)='INWARD' + THEN ABS(billed_qty) + WHEN UPPER(direction)='OUTWARD' + THEN -ABS(billed_qty) + ELSE 0 + END + ), + 0 + ) + """ + else: + qty_sql = "0" + + if "signed_value" in inventory_columns: + value_sql = "COALESCE(SUM(signed_value),0)" + elif "inventory_amount" in inventory_columns and "signed_qty" in inventory_columns: + value_sql = """ + COALESCE( + SUM( + CASE + WHEN signed_qty > 0 + THEN ABS(inventory_amount) + WHEN signed_qty < 0 + THEN -ABS(inventory_amount) + ELSE 0 + END + ), + 0 + ) + """ + elif "amount" in inventory_columns and "signed_qty" in inventory_columns: + value_sql = """ + COALESCE( + SUM( + CASE + WHEN signed_qty > 0 + THEN ABS(amount) + WHEN signed_qty < 0 + THEN -ABS(amount) + ELSE 0 + END + ), + 0 + ) + """ + elif "value" in inventory_columns and "direction" in inventory_columns: + value_sql = """ + COALESCE( + SUM( + CASE + WHEN UPPER(direction)='INWARD' + THEN ABS(value) + WHEN UPPER(direction)='OUTWARD' + THEN -ABS(value) + ELSE 0 + END + ), + 0 + ) + """ + else: + value_sql = "0" + movement = db.execute( - """SELECT - COALESCE(SUM(CASE WHEN UPPER(direction)='INWARD' THEN ABS(quantity) - WHEN UPPER(direction)='OUTWARD' THEN -ABS(quantity) ELSE 0 END),0), - COALESCE(SUM(CASE WHEN UPPER(direction)='INWARD' THEN ABS(value) - WHEN UPPER(direction)='OUTWARD' THEN -ABS(value) ELSE 0 END),0) - FROM inventory_movement WHERE stock_item_guid=?""", + f""" + SELECT + {qty_sql}, + {value_sql} + FROM inventory_movement + WHERE stock_item_guid=? + """, (row["stock_item_guid"],), ).fetchone() + closing_qty = opening_qty + float(movement[0] or 0) closing_value = opening_value + float(movement[1] or 0) stocks.append({