feat(vat): auto-fill VAT declaration appendices from reports
On selecting İl + Ay, the Declaration of value added tax fills three appendices from the source reports' get_data: - Əlavə 1 <- Purchase YGB VAT report - Əlavə 2 Hissə 1 <- Purchase invoice info report (act_type mapped to AZ) - Əlavə 2 Hissə 2 <- Agricultural goods stock report Adds a whitelisted populate_vat_tables method + form trigger, and a company filter to the purchase invoice info report. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8a430ae1b0
commit
d6488a68cf
|
|
@ -0,0 +1,52 @@
|
|||
// Copyright (c) 2025, Your Company and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on("Declaration of value added tax", {
|
||||
il: function (frm) {
|
||||
fill_from_reports(frm);
|
||||
},
|
||||
ay: function (frm) {
|
||||
fill_from_reports(frm);
|
||||
},
|
||||
});
|
||||
|
||||
// Pull Əlavə 1 / Əlavə 2 Hissə 1 / Əlavə 2 Hissə 2 from the three source
|
||||
// reports once both the year (İl) and month (Ay) are selected.
|
||||
function fill_from_reports(frm) {
|
||||
if (!frm.doc.il || !frm.doc.ay) {
|
||||
return;
|
||||
}
|
||||
|
||||
frappe.dom.freeze(__("Hesabatlardan doldurulur..."));
|
||||
frappe.call({
|
||||
method: "taxes_az.taxes_az.doctype.declaration_of_value_added_tax.declaration_of_value_added_tax.populate_vat_tables",
|
||||
args: { year: frm.doc.il, month: frm.doc.ay },
|
||||
callback: function (r) {
|
||||
frappe.dom.unfreeze();
|
||||
if (!r.message || !r.message.success) {
|
||||
frappe.msgprint(__("Doldurma alınmadı: {0}", [(r.message && r.message.error) || ""]));
|
||||
return;
|
||||
}
|
||||
|
||||
set_table(frm, "əlavə_1", r.message.elave_1);
|
||||
set_table(frm, "əlavə_2", r.message.elave_2);
|
||||
set_table(frm, "əlavə_2_2", r.message.elave_2_2);
|
||||
|
||||
frm.refresh_fields();
|
||||
frappe.show_alert({ message: __("Əlavələr hesabatlardan dolduruldu"), indicator: "green" });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// Replace a child table's rows with the supplied data.
|
||||
function set_table(frm, fieldname, rows) {
|
||||
frm.clear_table(fieldname);
|
||||
(rows || []).forEach(function (data) {
|
||||
const child = frm.add_child(fieldname);
|
||||
Object.keys(data).forEach(function (key) {
|
||||
if (data[key] !== null && data[key] !== undefined) {
|
||||
child[key] = data[key];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -10,3 +10,99 @@ import calendar
|
|||
|
||||
class Declarationofvalueaddedtax(Document):
|
||||
pass
|
||||
|
||||
|
||||
# Azərbaycan month names (matches the `ay` Select field), index 0 -> January.
|
||||
MONTHS_AZ = [
|
||||
"Yanvar", "Fevral", "Mart", "Aprel", "May", "İyun",
|
||||
"İyul", "Avqust", "Sentyabr", "Oktyabr", "Noyabr", "Dekabr",
|
||||
]
|
||||
|
||||
# Report act_type -> the declaration's "sənəd növü" Select option.
|
||||
ACT_TYPE_MAP = {
|
||||
"EQF": "EQF",
|
||||
"Purchase Act": "Alış aktı",
|
||||
"Import": "İdxal",
|
||||
}
|
||||
|
||||
|
||||
def _period_filters(year, month):
|
||||
"""Build report filters (company + month date range) from year + month."""
|
||||
from frappe.utils import get_last_day
|
||||
|
||||
company = (frappe.defaults.get_user_default("Company")
|
||||
or frappe.db.get_single_value("Global Defaults", "default_company"))
|
||||
|
||||
month_idx = MONTHS_AZ.index(month) + 1
|
||||
from_date = f"{cint(year):04d}-{month_idx:02d}-01"
|
||||
to_date = str(get_last_day(from_date))
|
||||
|
||||
return {"company": company, "from_date": from_date, "to_date": to_date}
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def populate_vat_tables(year, month):
|
||||
"""Build the VAT declaration appendix rows from the three source reports.
|
||||
|
||||
Returns row dicts for:
|
||||
- Əlavə 1 (əlavə_1) <- Purchase YGB VAT report
|
||||
- Əlavə 2 Hissə 1 (əlavə_2) <- Purchase invoice info report
|
||||
- Əlavə 2 Hissə 2 (əlavə_2_2) <- Agricultural goods stock report
|
||||
"""
|
||||
from taxes_az.taxes_az.report.purchase_ygb_vat_report.purchase_ygb_vat_report import (
|
||||
get_data as ygb_get_data,
|
||||
)
|
||||
from taxes_az.taxes_az.report.purchase_invoice_info_report.purchase_invoice_info_report import (
|
||||
get_data as purchase_info_get_data,
|
||||
)
|
||||
from taxes_az.taxes_az.report.agricultural_goods_stock_report.agricultural_goods_stock_report import (
|
||||
get_data as agri_get_data,
|
||||
)
|
||||
|
||||
if not month or not year:
|
||||
return {"success": False, "error": "Year and month are required"}
|
||||
|
||||
filters = _period_filters(year, month)
|
||||
|
||||
# Əlavə 1 — one row per YGB purchase document.
|
||||
# (ygbnintarixi is a Float field on the declaration, so the date is not
|
||||
# mapped here — see the note returned to the client.)
|
||||
elave_1 = []
|
||||
for r in (ygb_get_data(filters) or []):
|
||||
elave_1.append({
|
||||
"sətirkodu": r.get("line_code"),
|
||||
"ygbninnömrəsi": r.get("ygb"),
|
||||
"ygbüzrəalınmışmalınədvsizdəyərimanatla": r.get("amount_without_vat"),
|
||||
"ygbüzrəalınmışmalınədvməbləğimanatla": r.get("vat_amount"),
|
||||
})
|
||||
|
||||
# Əlavə 2 Hissə 1 — one row per agricultural purchase document.
|
||||
elave_2 = []
|
||||
for r in (purchase_info_get_data(filters) or []):
|
||||
elave_2.append({
|
||||
"malalışınıtəsdiqedənsənədnövününadı": ACT_TYPE_MAP.get(r.get("act_type"), r.get("act_type")),
|
||||
"adı": r.get("counterparty"),
|
||||
"vöen": r.get("voen") or None,
|
||||
"fin": r.get("fin"),
|
||||
"hesabatdövrüərzindəalınmışmallarınalışqiymətiiləməbləği": r.get("amount"),
|
||||
})
|
||||
|
||||
# Əlavə 2 Hissə 2 — single summary row (agricultural goods movement).
|
||||
elave_2_2 = []
|
||||
for r in (agri_get_data(filters) or []):
|
||||
elave_2_2.append({
|
||||
"hesabatdövrününəvvəlinəsatılmamışmallarınalışqiymətiiləməbləği": r.get("opening_balance"),
|
||||
"dövrərzindəalınmışmallarınalışqiymətiiləməbləği": r.get("purchased"),
|
||||
"dövrərzindəsatılmışmallarınsatışqiymətiiləməbləği": r.get("sold"),
|
||||
"dövrsonunamallarınalışqiymətiiləqalıqməbləği": r.get("closing_balance"),
|
||||
"carihesabatdövründəsatılmışmallaragörəticarətəlavəsi": r.get("trade_markup"),
|
||||
"hesabatdövründəsatılmışmallaragörəticarətəlavəsininədvməbləği": r.get("trade_markup_vat"),
|
||||
})
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"elave_1": elave_1,
|
||||
"elave_2": elave_2,
|
||||
"elave_2_2": elave_2_2,
|
||||
"period": filters,
|
||||
}
|
||||
|
|
@ -61,6 +61,9 @@ def get_data(filters=None):
|
|||
filters = filters or {}
|
||||
conditions = ""
|
||||
|
||||
if filters.get("company"):
|
||||
conditions += " AND pi.company = %(company)s"
|
||||
|
||||
if filters.get("from_date"):
|
||||
conditions += " AND pi.posting_date >= %(from_date)s"
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue