feat(report): add Purchase VAT offset report (Cədvəl 22)
Lists submitted Purchase Invoices flagged for VAT offset that have a VAT offset line code: line code, VOEN/Name, e-taxes invoice series/number, total, VAT (only the 521.3 ƏDV tax account), paid total (Grand Total - Outstanding, Purchase Register logic) and proportional paid VAT. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
93d7be9ee1
commit
71d9e303ce
|
|
@ -0,0 +1,26 @@
|
||||||
|
// Copyright (c) 2026, Company and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.query_reports["Purchase VAT offset 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-29 12:00:00",
|
||||||
|
"disabled": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Report",
|
||||||
|
"filters": [],
|
||||||
|
"idx": 0,
|
||||||
|
"is_standard": "Yes",
|
||||||
|
"letterhead": null,
|
||||||
|
"modified": "2026-06-29 12:00:00",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Taxes Az",
|
||||||
|
"name": "Purchase VAT offset report",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"prepared_report": 0,
|
||||||
|
"ref_doctype": "Purchase Invoice",
|
||||||
|
"report_name": "Purchase VAT offset report",
|
||||||
|
"report_type": "Script Report",
|
||||||
|
"roles": [],
|
||||||
|
"timeout": 0
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,158 @@
|
||||||
|
# Copyright (c) 2026, Company and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
from frappe import _
|
||||||
|
from frappe.utils import flt
|
||||||
|
|
||||||
|
|
||||||
|
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 (Cədvəl 22 — ƏDV - Əvəzləşdirmə hesabatı)."""
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
"label": _("Purchase Invoice"),
|
||||||
|
"fieldname": "purchase_invoice",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Purchase Invoice",
|
||||||
|
"width": 160
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Sətir kodu
|
||||||
|
"label": _("Line Code"),
|
||||||
|
"fieldname": "line_code",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"width": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# VÖEN / Adı
|
||||||
|
"label": _("VOEN / Name"),
|
||||||
|
"fieldname": "voen_name",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"width": 240
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Qaimənin seriyası
|
||||||
|
"label": _("Invoice Series"),
|
||||||
|
"fieldname": "invoice_series",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"width": 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Qaimənin nömrəsi
|
||||||
|
"label": _("Invoice Number"),
|
||||||
|
"fieldname": "invoice_number",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"width": 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Ümumi məbləğ, manatla
|
||||||
|
"label": _("Total Amount"),
|
||||||
|
"fieldname": "total_amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# ƏDV məbləği, manatla
|
||||||
|
"label": _("VAT Amount"),
|
||||||
|
"fieldname": "vat_amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 130
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Ödənilmiş ümumi məbləğ, manatla
|
||||||
|
"label": _("Paid Total"),
|
||||||
|
"fieldname": "paid_total",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Ödənilmiş ƏDV məbləği, manatla
|
||||||
|
"label": _("Paid VAT"),
|
||||||
|
"fieldname": "paid_vat",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 140
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def get_data(filters=None):
|
||||||
|
"""Submitted Purchase Invoices flagged for VAT offset with a line code.
|
||||||
|
|
||||||
|
Paid amounts follow the Purchase Register logic: Grand Total minus the
|
||||||
|
Outstanding amount. Paid VAT is taken proportionally to the paid share.
|
||||||
|
"""
|
||||||
|
filters = filters or {}
|
||||||
|
|
||||||
|
conditions = (
|
||||||
|
"pi.docstatus = 1 AND pi.vat_offset = 1 "
|
||||||
|
"AND pi.vat_offset_line_code IS NOT NULL AND pi.vat_offset_line_code != ''"
|
||||||
|
)
|
||||||
|
params = {}
|
||||||
|
|
||||||
|
if filters.get("company"):
|
||||||
|
conditions += " AND pi.company = %(company)s"
|
||||||
|
params["company"] = filters["company"]
|
||||||
|
if filters.get("from_date"):
|
||||||
|
conditions += " AND pi.posting_date >= %(from_date)s"
|
||||||
|
params["from_date"] = filters["from_date"]
|
||||||
|
if filters.get("to_date"):
|
||||||
|
conditions += " AND pi.posting_date <= %(to_date)s"
|
||||||
|
params["to_date"] = filters["to_date"]
|
||||||
|
|
||||||
|
rows = frappe.db.sql(f"""
|
||||||
|
SELECT
|
||||||
|
pi.name AS purchase_invoice,
|
||||||
|
pi.vat_offset_line_code AS line_code,
|
||||||
|
pi.supplier_name,
|
||||||
|
sup.tax_id,
|
||||||
|
pi.etaxes_invoice_series,
|
||||||
|
pi.etaxes_invoice_number,
|
||||||
|
pi.grand_total,
|
||||||
|
pi.outstanding_amount,
|
||||||
|
COALESCE(SUM(CASE
|
||||||
|
WHEN ptc.account_head = '521.3 - ƏDV' OR acc.account_number = '521.3'
|
||||||
|
THEN ptc.tax_amount ELSE 0
|
||||||
|
END), 0) AS vat_amount
|
||||||
|
FROM
|
||||||
|
`tabPurchase Invoice` pi
|
||||||
|
LEFT JOIN `tabSupplier` sup ON sup.name = pi.supplier
|
||||||
|
LEFT JOIN `tabPurchase Taxes and Charges` ptc ON ptc.parent = pi.name
|
||||||
|
LEFT JOIN `tabAccount` acc ON acc.name = ptc.account_head
|
||||||
|
WHERE
|
||||||
|
{conditions}
|
||||||
|
GROUP BY
|
||||||
|
pi.name, pi.vat_offset_line_code, pi.supplier_name, sup.tax_id,
|
||||||
|
pi.etaxes_invoice_series, pi.etaxes_invoice_number,
|
||||||
|
pi.grand_total, pi.outstanding_amount, pi.posting_date
|
||||||
|
ORDER BY
|
||||||
|
pi.posting_date, pi.name
|
||||||
|
""", params, as_dict=1)
|
||||||
|
|
||||||
|
data = []
|
||||||
|
for r in rows:
|
||||||
|
grand_total = flt(r.grand_total)
|
||||||
|
vat_amount = flt(r.vat_amount)
|
||||||
|
paid_total = grand_total - flt(r.outstanding_amount)
|
||||||
|
paid_vat = vat_amount * (paid_total / grand_total) if grand_total else 0.0
|
||||||
|
|
||||||
|
data.append({
|
||||||
|
"purchase_invoice": r.purchase_invoice,
|
||||||
|
"line_code": r.line_code,
|
||||||
|
"voen_name": f"{(r.tax_id or '').strip()} / {(r.supplier_name or '').strip()}",
|
||||||
|
"invoice_series": r.etaxes_invoice_series,
|
||||||
|
"invoice_number": r.etaxes_invoice_number,
|
||||||
|
"total_amount": grand_total,
|
||||||
|
"vat_amount": vat_amount,
|
||||||
|
"paid_total": paid_total,
|
||||||
|
"paid_vat": paid_vat,
|
||||||
|
})
|
||||||
|
|
||||||
|
return data
|
||||||
Loading…
Reference in New Issue