From 878d2bac83bc2f35803cc55aad0946248000446d Mon Sep 17 00:00:00 2001 From: Ali <010109ali@gmail.com> Date: Wed, 24 Jun 2026 10:52:28 +0000 Subject: [PATCH] feat(report): add Agricultural goods stock report MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Period-based VAT agricultural goods movement report (Cədvəl 18(1)): opening balance, purchased (Purchase Invoices), sold (Sales Invoices) and closing balance for agricultural_goods documents. Amounts incl. VAT (grand_total); closing = opening + purchased - sold. Formula-editor friendly with Company/From/To filters. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../__init__.py | 0 .../agricultural_goods_stock_report.js | 26 ++++ .../agricultural_goods_stock_report.json | 23 ++++ .../agricultural_goods_stock_report.py | 122 ++++++++++++++++++ 4 files changed, 171 insertions(+) create mode 100644 taxes_az/taxes_az/report/agricultural_goods_stock_report/__init__.py create mode 100644 taxes_az/taxes_az/report/agricultural_goods_stock_report/agricultural_goods_stock_report.js create mode 100644 taxes_az/taxes_az/report/agricultural_goods_stock_report/agricultural_goods_stock_report.json create mode 100644 taxes_az/taxes_az/report/agricultural_goods_stock_report/agricultural_goods_stock_report.py diff --git a/taxes_az/taxes_az/report/agricultural_goods_stock_report/__init__.py b/taxes_az/taxes_az/report/agricultural_goods_stock_report/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/taxes_az/taxes_az/report/agricultural_goods_stock_report/agricultural_goods_stock_report.js b/taxes_az/taxes_az/report/agricultural_goods_stock_report/agricultural_goods_stock_report.js new file mode 100644 index 0000000..b4a5c91 --- /dev/null +++ b/taxes_az/taxes_az/report/agricultural_goods_stock_report/agricultural_goods_stock_report.js @@ -0,0 +1,26 @@ +// Copyright (c) 2026, Company and contributors +// For license information, please see license.txt + +frappe.query_reports["Agricultural goods stock report"] = { + "filters": [ + { + "fieldname": "company", + "label": __("Company"), + "fieldtype": "Link", + "options": "Company", + "default": frappe.defaults.get_user_default("Company") + }, + { + "fieldname": "from_date", + "label": __("From Date"), + "fieldtype": "Date", + "default": frappe.datetime.month_start() + }, + { + "fieldname": "to_date", + "label": __("To Date"), + "fieldtype": "Date", + "default": frappe.datetime.month_end() + } + ] +}; diff --git a/taxes_az/taxes_az/report/agricultural_goods_stock_report/agricultural_goods_stock_report.json b/taxes_az/taxes_az/report/agricultural_goods_stock_report/agricultural_goods_stock_report.json new file mode 100644 index 0000000..18f562d --- /dev/null +++ b/taxes_az/taxes_az/report/agricultural_goods_stock_report/agricultural_goods_stock_report.json @@ -0,0 +1,23 @@ +{ + "add_total_row": 0, + "columns": [], + "creation": "2026-06-24 12:00:00", + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "filters": [], + "idx": 0, + "is_standard": "Yes", + "letterhead": null, + "modified": "2026-06-24 12:00:00", + "modified_by": "Administrator", + "module": "Taxes Az", + "name": "Agricultural goods stock report", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "Purchase Invoice", + "report_name": "Agricultural goods stock report", + "report_type": "Script Report", + "roles": [], + "timeout": 0 +} 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 new file mode 100644 index 0000000..ffa9f3a --- /dev/null +++ b/taxes_az/taxes_az/report/agricultural_goods_stock_report/agricultural_goods_stock_report.py @@ -0,0 +1,122 @@ +# Copyright (c) 2026, Company and contributors +# For license information, please see license.txt + +import frappe +from frappe import _ + + +def execute(filters=None): + """Main function for report execution""" + columns = get_columns(filters) + data = get_data(filters) + + return columns, data + + +def get_columns(filters=None): + """Get report columns definition""" + return [ + { + "label": _("Period"), + "fieldname": "period", + "fieldtype": "Data", + "width": 200 + }, + { + # Hesabat dövrünün əvvəlinə satılmamış malların (alış qiyməti ilə) məbləği + "label": _("Opening balance (purchase price)"), + "fieldname": "opening_balance", + "fieldtype": "Currency", + "width": 200 + }, + { + # Hesabat dövrü ərzində alınmış malların (alış qiyməti ilə) məbləği + "label": _("Purchased in period (purchase price)"), + "fieldname": "purchased", + "fieldtype": "Currency", + "width": 200 + }, + { + # Dövr ərzində satılmış malların (satış qiyməti ilə) məbləği + "label": _("Sold in period (sale price)"), + "fieldname": "sold", + "fieldtype": "Currency", + "width": 200 + }, + { + # Dövrün sonuna malların (alış qiyməti ilə) qalıq məbləği + "label": _("Closing balance (purchase price)"), + "fieldname": "closing_balance", + "fieldtype": "Currency", + "width": 200 + } + ] + + +def _sum(doctype, company, date_field_from=None, date_field_to=None, before=None): + """Sum grand_total of submitted agricultural-goods documents of a doctype.""" + conditions = "docstatus = 1 AND agricultural_goods = 1" + params = {} + + if company: + conditions += " AND company = %(company)s" + params["company"] = company + + if before: + conditions += " AND posting_date < %(before)s" + params["before"] = before + else: + if date_field_from: + conditions += " AND posting_date >= %(from_date)s" + params["from_date"] = date_field_from + if date_field_to: + conditions += " AND posting_date <= %(to_date)s" + params["to_date"] = date_field_to + + result = frappe.db.sql( + f"SELECT COALESCE(SUM(grand_total), 0) FROM `tab{doctype}` WHERE {conditions}", + params + ) + return float(result[0][0]) if result else 0.0 + + +def get_data(filters=None): + """Get report data (single row for the selected period).""" + filters = filters or {} + + company = filters.get("company") + from_date = filters.get("from_date") + to_date = filters.get("to_date") + + # Opening balance = cumulative (purchases - sales) of agricultural goods + # before the start of the period, at purchase/sale price incl. VAT. + if from_date: + opening_purchases = _sum("Purchase Invoice", company, before=from_date) + opening_sales = _sum("Sales Invoice", company, before=from_date) + opening_balance = opening_purchases - opening_sales + else: + opening_balance = 0.0 + + # Purchased during the period (purchase price, incl. VAT) + purchased = _sum("Purchase Invoice", company, from_date, to_date) + + # Sold during the period (sale price, incl. VAT) + sold = _sum("Sales Invoice", company, from_date, to_date) + + # Simplified closing balance: opening + purchased - sold + closing_balance = opening_balance + purchased - sold + + if from_date and to_date: + period = f"{from_date} — {to_date}" + elif to_date: + period = f"... — {to_date}" + else: + period = _("All time") + + return [{ + "period": period, + "opening_balance": opening_balance, + "purchased": purchased, + "sold": sold, + "closing_balance": closing_balance + }]