mod(regional,italy): adjusted calculation logic for charges
validation for missing code on mode of payment
UOM from settings
Replace str with cstr
diff --git a/erpnext/regional/italy/e-invoice.xml b/erpnext/regional/italy/e-invoice.xml
index 84b7fff..1c416ee 100644
--- a/erpnext/regional/italy/e-invoice.xml
+++ b/erpnext/regional/italy/e-invoice.xml
@@ -153,7 +153,7 @@
{%- endif %}
</DatiGenerali>
<DatiBeniServizi>
- {%- for item in doc.items %}
+ {%- for item in doc.e_invoice_items %}
<DettaglioLinee>
<NumeroLinea>{{ item.idx }}</NumeroLinea>
<CodiceArticolo>
diff --git a/erpnext/regional/italy/utils.py b/erpnext/regional/italy/utils.py
index 69f7b46..85f7447 100644
--- a/erpnext/regional/italy/utils.py
+++ b/erpnext/regional/italy/utils.py
@@ -1,5 +1,7 @@
+from __future__ import unicode_literals
+
import frappe, json, os
-from frappe.utils import flt
+from frappe.utils import flt, cstr
from erpnext.controllers.taxes_and_totals import get_itemised_tax
from frappe import _
from frappe.utils.file_manager import save_file, remove_file
@@ -66,7 +68,8 @@
else:
invoice.transmission_format_code = "FPR12"
- tax_data = get_invoice_summary(invoice.items, invoice.taxes)
+ invoice.e_invoice_items = [item for item in invoice.items]
+ tax_data = get_invoice_summary(invoice.e_invoice_items, invoice.taxes)
invoice.tax_data = tax_data
#Check if stamp duty (Bollo) of 2 EUR exists.
@@ -74,8 +77,8 @@
if stamp_duty_charge_row:
invoice.stamp_duty = stamp_duty_charge_row.tax_amount
- for item in invoice.items:
- if item.tax_rate == 0.0:
+ for item in invoice.e_invoice_items:
+ if item.tax_rate == 0.0 and item.tax_amount == 0.0:
item.tax_exemption_reason = tax_data["0.0"]["tax_exemption_reason"]
return invoice
@@ -121,12 +124,34 @@
if tax.charge_type == "Actual":
continue
+ #Charges to appear as items in the e-invoice.
+ if tax.charge_type in ["On Previous Row Total", "On Previous Row Amount"]:
+ reference_row = next((row for row in taxes if row.idx == int(tax.row_id or 0)), None)
+ if reference_row:
+ items.append(
+ frappe._dict(
+ idx=len(items)+1,
+ item_code=reference_row.description,
+ item_name=reference_row.description,
+ rate=reference_row.tax_amount,
+ qty=1.0,
+ amount=reference_row.tax_amount,
+ stock_uom=frappe.db.get_single_value("Stock Settings", "stock_uom") or _("Nos"),
+ tax_rate=tax.rate,
+ tax_amount=(reference_row.tax_amount * tax.rate) / 100,
+ net_amount=reference_row.tax_amount,
+ taxable_amount=reference_row.tax_amount,
+ item_tax_rate="{}",
+ charges=True
+ )
+ )
+
#Check item tax rates if tax rate is zero.
if tax.rate == 0:
for item in items:
item_tax_rate = json.loads(item.item_tax_rate)
if tax.account_head in item_tax_rate:
- key = str(item_tax_rate[tax.account_head])
+ key = cstr(item_tax_rate[tax.account_head])
summary_data.setdefault(key, {"tax_amount": 0.0, "taxable_amount": 0.0, "tax_exemption_reason": "", "tax_exemption_law": ""})
summary_data[key]["tax_amount"] += item.tax_amount
summary_data[key]["taxable_amount"] += item.net_amount
@@ -141,11 +166,17 @@
else:
item_wise_tax_detail = json.loads(tax.item_wise_tax_detail)
for rate_item in [tax_item for tax_item in item_wise_tax_detail.items() if tax_item[1][0] == tax.rate]:
- key = str(tax.rate)
+ key = cstr(tax.rate)
if not summary_data.get(key): summary_data.setdefault(key, {"tax_amount": 0.0, "taxable_amount": 0.0})
summary_data[key]["tax_amount"] += rate_item[1][1]
summary_data[key]["taxable_amount"] += sum([item.net_amount for item in items if item.item_code == rate_item[0]])
+ for item in items:
+ key = cstr(tax.rate)
+ if item.get("charges"):
+ if not summary_data.get(key): summary_data.setdefault(key, {"taxable_amount": 0.0})
+ summary_data[key]["taxable_amount"] += item.taxable_amount
+
return summary_data
#Preflight for successful e-invoice export.
@@ -196,6 +227,9 @@
if not schedule.mode_of_payment:
frappe.throw(_("Row {0}: Please set the Mode of Payment in Payment Schedule".format(schedule.idx)),
title=_("E-Invoicing Information Missing"))
+ elif not frappe.db.get_value("Mode of Payment", schedule.mode_of_payment, "mode_of_payment_code"):
+ frappe.throw(_("Row {0}: Please set the correct code on Mode of Payment {1}".format(schedule.idx, schedule.mode_of_payment)),
+ title=_("E-Invoicing Information Missing"))
prepare_and_attach_invoice(doc)