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 1aa1c94..e46f82c 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 @@ -71,6 +71,20 @@ def get_columns(filters=None): "fieldname": "trade_markup_vat", "fieldtype": "Currency", "width": 200 + }, + # TEMPORARY: source documents behind each figure (for tracing). + { + "label": _("Source type"), + "fieldname": "source_type", + "fieldtype": "Data", + "width": 150 + }, + { + "label": _("Source document"), + "fieldname": "source_document", + "fieldtype": "Dynamic Link", + "options": "source_type", + "width": 200 } ] @@ -181,6 +195,58 @@ def _sold_sale_price(company, from_date, to_date): return flt(result[0][0]) if result else 0.0 +def _detail_rows(company, from_date, to_date): + """TEMPORARY: one row per source document so figures can be traced. + + Lists the Stock Ledger entries of agricultural items up to the period end + (entries before the period are marked "(opening)") with a clickable link + to the source voucher, and the sale price for outgoing sales. + """ + params = {} + conditions = "sle.is_cancelled = 0 AND it.agricultural_goods = 1" + conditions += _company_cond(company, params, "sle") + if to_date: + conditions += " AND sle.posting_date <= %(to_date)s" + params["to_date"] = to_date + + sle_rows = frappe.db.sql(f""" + SELECT + sle.posting_date, sle.voucher_type, sle.voucher_no, sle.item_code, + sle.actual_qty, sle.stock_value_difference, sle.stock_value + FROM `tabStock Ledger Entry` sle + INNER JOIN `tabItem` it ON it.name = sle.item_code + WHERE {conditions} + ORDER BY sle.posting_date, sle.posting_time, sle.creation + """, params, as_dict=1) + + # Sale price per (Sales Invoice, item) for outgoing sale rows. + si_names = [r.voucher_no for r in sle_rows if r.voucher_type == "Sales Invoice"] + sale_map = {} + if si_names: + for d in frappe.db.sql(""" + SELECT parent, item_code, SUM(net_amount) AS amt + FROM `tabSales Invoice Item` + WHERE parent IN %(names)s + GROUP BY parent, item_code + """, {"names": tuple(si_names)}, as_dict=1): + sale_map[(d.parent, d.item_code)] = flt(d.amt) + + rows = [] + for r in sle_rows: + diff = flt(r.stock_value_difference) + before = from_date and getdate(r.posting_date) < from_date + rows.append({ + "period": f"{r.posting_date}" + (" (opening)" if before else ""), + "purchased": diff if diff > 0 else None, + "sold_purchase_price": -diff if diff < 0 else None, + "sold": sale_map.get((r.voucher_no, r.item_code)) if diff < 0 else None, + "closing_balance": flt(r.stock_value), + "source_type": r.voucher_type, + "source_document": r.voucher_no, + }) + return rows + + def get_data(filters=None): """Single row for the selected period, sourced from the Stock Ledger. @@ -215,7 +281,7 @@ def get_data(filters=None): else: period = _("All time") - return [{ + summary = { "period": period, "opening_balance": opening_balance, "purchased": purchased, @@ -223,8 +289,12 @@ def get_data(filters=None): "sold_purchase_price": cogs, "closing_balance": closing_balance, "trade_markup": trade_markup, - "trade_markup_vat": trade_markup_vat - }] + "trade_markup_vat": trade_markup_vat, + "source_type": "TOTAL", + } + + # TEMPORARY: append source-document rows for tracing. + return [summary] + _detail_rows(company, from_date, to_date) def _day_before(d):