From f906536b7f6bb98c425076f3aca1ff1f94ea5d71 Mon Sep 17 00:00:00 2001 From: Ali <010109ali@gmail.com> Date: Wed, 24 Jun 2026 17:27:26 +0000 Subject: [PATCH] fix(report): cost-based opening balance in agricultural stock report Opening balance now subtracts sales before the period at their COGS (via the company's FIFO/Moving Average method) instead of at sale price. This keeps it consistent with the cost-based closing balance, so each period's opening equals the previous period's closing and the value can no longer go negative while stock remains. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../agricultural_goods_stock_report.py | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/taxes_az/taxes_az/report/agricultural_goods_stock_report/agricultural_goods_stock_report.py b/taxes_az/taxes_az/report/agricultural_goods_stock_report/agricultural_goods_stock_report.py index 4c622bd..e32821c 100644 --- a/taxes_az/taxes_az/report/agricultural_goods_stock_report/agricultural_goods_stock_report.py +++ b/taxes_az/taxes_az/report/agricultural_goods_stock_report/agricultural_goods_stock_report.py @@ -237,24 +237,30 @@ def get_data(filters=None): purchases = _fetch_rows("Purchase Invoice", "Purchase Invoice Item", company, to_date) sales = _fetch_rows("Sales Invoice", "Sales Invoice Item", company, to_date) - # Opening balance = cumulative (purchases - sales) before the period start. + # Pick the cost-of-goods-sold method from the company's Default Stock + # Valuation Method. Moving Average -> weighted average, otherwise FIFO. + valuation_method = _get_valuation_method(company) + + def cogs(start, end): + if valuation_method == "Moving Average": + return _avg_sold_purchase_price(purchases, sales, start, end) + return _fifo_sold_purchase_price(purchases, sales, start, end) + + # Opening balance = cost (purchase price) of stock still on hand at the + # start of the period = all purchases before the period minus the COST of + # all goods sold before it. Subtracting sales at COGS (not sale price) + # keeps it consistent with the closing balance, so each period's opening + # equals the previous period's closing. if from_date: opening_purchases = _sum_gross(purchases, end=_day_before(from_date)) - opening_sales = _sum_gross(sales, end=_day_before(from_date)) - opening_balance = opening_purchases - opening_sales + opening_cogs = cogs(None, _day_before(from_date)) + opening_balance = opening_purchases - opening_cogs else: opening_balance = 0.0 purchased = _sum_gross(purchases, start=from_date, end=to_date) sold = _sum_gross(sales, start=from_date, end=to_date) - - # Pick the cost-of-goods-sold method from the company's Default Stock - # Valuation Method. Moving Average -> weighted average, otherwise FIFO. - valuation_method = _get_valuation_method(company) - if valuation_method == "Moving Average": - sold_purchase_price = _avg_sold_purchase_price(purchases, sales, from_date, to_date) - else: - sold_purchase_price = _fifo_sold_purchase_price(purchases, sales, from_date, to_date) + sold_purchase_price = cogs(from_date, to_date) # Closing balance at purchase price = opening + purchased - cost of goods # sold (COGS, valued per the company's stock valuation method).