feat(report): add Agricultural goods stock report
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) <noreply@anthropic.com>
This commit is contained in:
parent
cd34b4ca87
commit
878d2bac83
|
|
@ -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()
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
}]
|
||||||
Loading…
Reference in New Issue