style: format code with black
diff --git a/erpnext/regional/italy/__init__.py b/erpnext/regional/italy/__init__.py
index eb20f65..643e955 100644
--- a/erpnext/regional/italy/__init__.py
+++ b/erpnext/regional/italy/__init__.py
@@ -1,77 +1,172 @@
fiscal_regimes = [
- "RF01-Ordinario",
- "RF02-Contribuenti minimi (art.1, c.96-117, L. 244/07)",
- "RF04-Agricoltura e attività connesse e pesca (artt.34 e 34-bis, DPR 633/72)",
- "RF05-Vendita sali e tabacchi (art.74, c.1, DPR. 633/72)",
- "RF06-Commercio fiammiferi (art.74, c.1, DPR 633/72)",
- "RF07-Editoria (art.74, c.1, DPR 633/72)",
- "RF08-Gestione servizi telefonia pubblica (art.74, c.1, DPR 633/72)",
- "RF09-Rivendita documenti di trasporto pubblico e di sosta (art.74, c.1, DPR 633/72)",
- "RF10-Intrattenimenti, giochi e altre attività di cui alla tariffa allegata al DPR 640/72 (art.74, c.6, DPR 633/72)",
- "RF11-Agenzie viaggi e turismo (art.74-ter, DPR 633/72)",
- "RF12-Agriturismo (art.5, c.2, L. 413/91)",
- "RF13-Vendite a domicilio (art.25-bis, c.6, DPR 600/73)",
- "RF14-Rivendita beni usati, oggetti d’arte, d’antiquariato o da collezione (art.36, DL 41/95)",
- "RF15-Agenzie di vendite all’asta di oggetti d’arte, antiquariato o da collezione (art.40-bis, DL 41/95)",
- "RF16-IVA per cassa P.A. (art.6, c.5, DPR 633/72)",
- "RF17-IVA per cassa (art. 32-bis, DL 83/2012)",
- "RF18-Altro",
- "RF19-Regime forfettario (art.1, c.54-89, L. 190/2014)"
+ "RF01-Ordinario",
+ "RF02-Contribuenti minimi (art.1, c.96-117, L. 244/07)",
+ "RF04-Agricoltura e attività connesse e pesca (artt.34 e 34-bis, DPR 633/72)",
+ "RF05-Vendita sali e tabacchi (art.74, c.1, DPR. 633/72)",
+ "RF06-Commercio fiammiferi (art.74, c.1, DPR 633/72)",
+ "RF07-Editoria (art.74, c.1, DPR 633/72)",
+ "RF08-Gestione servizi telefonia pubblica (art.74, c.1, DPR 633/72)",
+ "RF09-Rivendita documenti di trasporto pubblico e di sosta (art.74, c.1, DPR 633/72)",
+ "RF10-Intrattenimenti, giochi e altre attività di cui alla tariffa allegata al DPR 640/72 (art.74, c.6, DPR 633/72)",
+ "RF11-Agenzie viaggi e turismo (art.74-ter, DPR 633/72)",
+ "RF12-Agriturismo (art.5, c.2, L. 413/91)",
+ "RF13-Vendite a domicilio (art.25-bis, c.6, DPR 600/73)",
+ "RF14-Rivendita beni usati, oggetti d’arte, d’antiquariato o da collezione (art.36, DL 41/95)",
+ "RF15-Agenzie di vendite all’asta di oggetti d’arte, antiquariato o da collezione (art.40-bis, DL 41/95)",
+ "RF16-IVA per cassa P.A. (art.6, c.5, DPR 633/72)",
+ "RF17-IVA per cassa (art. 32-bis, DL 83/2012)",
+ "RF18-Altro",
+ "RF19-Regime forfettario (art.1, c.54-89, L. 190/2014)",
]
tax_exemption_reasons = [
- "N1-Escluse ex art. 15",
- "N2-Non Soggette",
- "N3-Non Imponibili",
- "N4-Esenti",
- "N5-Regime del margine / IVA non esposta in fattura",
- "N6-Inversione Contabile",
- "N7-IVA assolta in altro stato UE"
+ "N1-Escluse ex art. 15",
+ "N2-Non Soggette",
+ "N3-Non Imponibili",
+ "N4-Esenti",
+ "N5-Regime del margine / IVA non esposta in fattura",
+ "N6-Inversione Contabile",
+ "N7-IVA assolta in altro stato UE",
]
mode_of_payment_codes = [
- "MP01-Contanti",
- "MP02-Assegno",
- "MP03-Assegno circolare",
- "MP04-Contanti presso Tesoreria",
- "MP05-Bonifico",
- "MP06-Vaglia cambiario",
- "MP07-Bollettino bancario",
- "MP08-Carta di pagamento",
- "MP09-RID",
- "MP10-RID utenze",
- "MP11-RID veloce",
- "MP12-RIBA",
- "MP13-MAV",
- "MP14-Quietanza erario",
- "MP15-Giroconto su conti di contabilità speciale",
- "MP16-Domiciliazione bancaria",
- "MP17-Domiciliazione postale",
- "MP18-Bollettino di c/c postale",
- "MP19-SEPA Direct Debit",
- "MP20-SEPA Direct Debit CORE",
- "MP21-SEPA Direct Debit B2B",
- "MP22-Trattenuta su somme già riscosse"
+ "MP01-Contanti",
+ "MP02-Assegno",
+ "MP03-Assegno circolare",
+ "MP04-Contanti presso Tesoreria",
+ "MP05-Bonifico",
+ "MP06-Vaglia cambiario",
+ "MP07-Bollettino bancario",
+ "MP08-Carta di pagamento",
+ "MP09-RID",
+ "MP10-RID utenze",
+ "MP11-RID veloce",
+ "MP12-RIBA",
+ "MP13-MAV",
+ "MP14-Quietanza erario",
+ "MP15-Giroconto su conti di contabilità speciale",
+ "MP16-Domiciliazione bancaria",
+ "MP17-Domiciliazione postale",
+ "MP18-Bollettino di c/c postale",
+ "MP19-SEPA Direct Debit",
+ "MP20-SEPA Direct Debit CORE",
+ "MP21-SEPA Direct Debit B2B",
+ "MP22-Trattenuta su somme già riscosse",
]
-vat_collectability_options = [
- "I-Immediata",
- "D-Differita",
- "S-Scissione dei Pagamenti"
-]
+vat_collectability_options = ["I-Immediata", "D-Differita", "S-Scissione dei Pagamenti"]
-state_codes = {'Siracusa': 'SR', 'Bologna': 'BO', 'Grosseto': 'GR', 'Caserta': 'CE', 'Alessandria': 'AL', 'Ancona': 'AN', 'Pavia': 'PV',
- 'Benevento or Beneventum': 'BN', 'Modena': 'MO', 'Lodi': 'LO', 'Novara': 'NO', 'Avellino': 'AV', 'Verona': 'VR', 'Forli-Cesena': 'FC',
- 'Caltanissetta': 'CL', 'Brescia': 'BS', 'Rieti': 'RI', 'Treviso': 'TV', 'Ogliastra': 'OG', 'Olbia-Tempio': 'OT', 'Bergamo': 'BG',
- 'Napoli': 'NA', 'Campobasso': 'CB', 'Fermo': 'FM', 'Roma': 'RM', 'Lucca': 'LU', 'Rovigo': 'RO', 'Piacenza': 'PC', 'Monza and Brianza': 'MB',
- 'La Spezia': 'SP', 'Pescara': 'PE', 'Vercelli': 'VC', 'Enna': 'EN', 'Nuoro': 'NU', 'Medio Campidano': 'MD', 'Trieste': 'TS', 'Aosta': 'AO',
- 'Firenze': 'FI', 'Trapani': 'TP', 'Messina': 'ME', 'Teramo': 'TE', 'Udine': 'UD', 'Verbano-Cusio-Ossola': 'VB', 'Padua': 'PD',
- 'Reggio Emilia': 'RE', 'Frosinone': 'FR', 'Taranto': 'TA', 'Catanzaro': 'CZ', 'Belluno': 'BL', 'Pordenone': 'PN', 'Viterbo': 'VT',
- 'Gorizia': 'GO', 'Vatican City': 'SCV', 'Ferrara': 'FE', 'Chieti': 'CH', 'Crotone': 'KR', 'Foggia': 'FG', 'Perugia': 'PG', 'Bari': 'BA',
- 'Massa-Carrara': 'MS', 'Pisa': 'PI', 'Latina': 'LT', 'Salerno': 'SA', 'Turin': 'TO', 'Lecco': 'LC', 'Lecce': 'LE', 'Pistoia': 'PT', 'Como': 'CO',
- 'Barletta-Andria-Trani': 'BT', 'Mantua': 'MN', 'Ragusa': 'RG', 'Macerata': 'MC', 'Imperia': 'IM', 'Palermo': 'PA', 'Matera': 'MT', "L'Aquila": 'AQ',
- 'Milano': 'MI', 'Catania': 'CT', 'Pesaro e Urbino': 'PU', 'Potenza': 'PZ', 'Republic of San Marino': 'RSM', 'Genoa': 'GE', 'Brindisi': 'BR',
- 'Cagliari': 'CA', 'Siena': 'SI', 'Vibo Valentia': 'VV', 'Reggio Calabria': 'RC', 'Ascoli Piceno': 'AP', 'Carbonia-Iglesias': 'CI', 'Oristano': 'OR',
- 'Asti': 'AT', 'Ravenna': 'RA', 'Vicenza': 'VI', 'Savona': 'SV', 'Biella': 'BI', 'Rimini': 'RN', 'Agrigento': 'AG', 'Prato': 'PO', 'Cuneo': 'CN',
- 'Cosenza': 'CS', 'Livorno or Leghorn': 'LI', 'Sondrio': 'SO', 'Cremona': 'CR', 'Isernia': 'IS', 'Trento': 'TN', 'Terni': 'TR', 'Bolzano/Bozen': 'BZ',
- 'Parma': 'PR', 'Varese': 'VA', 'Venezia': 'VE', 'Sassari': 'SS', 'Arezzo': 'AR'}
+state_codes = {
+ "Siracusa": "SR",
+ "Bologna": "BO",
+ "Grosseto": "GR",
+ "Caserta": "CE",
+ "Alessandria": "AL",
+ "Ancona": "AN",
+ "Pavia": "PV",
+ "Benevento or Beneventum": "BN",
+ "Modena": "MO",
+ "Lodi": "LO",
+ "Novara": "NO",
+ "Avellino": "AV",
+ "Verona": "VR",
+ "Forli-Cesena": "FC",
+ "Caltanissetta": "CL",
+ "Brescia": "BS",
+ "Rieti": "RI",
+ "Treviso": "TV",
+ "Ogliastra": "OG",
+ "Olbia-Tempio": "OT",
+ "Bergamo": "BG",
+ "Napoli": "NA",
+ "Campobasso": "CB",
+ "Fermo": "FM",
+ "Roma": "RM",
+ "Lucca": "LU",
+ "Rovigo": "RO",
+ "Piacenza": "PC",
+ "Monza and Brianza": "MB",
+ "La Spezia": "SP",
+ "Pescara": "PE",
+ "Vercelli": "VC",
+ "Enna": "EN",
+ "Nuoro": "NU",
+ "Medio Campidano": "MD",
+ "Trieste": "TS",
+ "Aosta": "AO",
+ "Firenze": "FI",
+ "Trapani": "TP",
+ "Messina": "ME",
+ "Teramo": "TE",
+ "Udine": "UD",
+ "Verbano-Cusio-Ossola": "VB",
+ "Padua": "PD",
+ "Reggio Emilia": "RE",
+ "Frosinone": "FR",
+ "Taranto": "TA",
+ "Catanzaro": "CZ",
+ "Belluno": "BL",
+ "Pordenone": "PN",
+ "Viterbo": "VT",
+ "Gorizia": "GO",
+ "Vatican City": "SCV",
+ "Ferrara": "FE",
+ "Chieti": "CH",
+ "Crotone": "KR",
+ "Foggia": "FG",
+ "Perugia": "PG",
+ "Bari": "BA",
+ "Massa-Carrara": "MS",
+ "Pisa": "PI",
+ "Latina": "LT",
+ "Salerno": "SA",
+ "Turin": "TO",
+ "Lecco": "LC",
+ "Lecce": "LE",
+ "Pistoia": "PT",
+ "Como": "CO",
+ "Barletta-Andria-Trani": "BT",
+ "Mantua": "MN",
+ "Ragusa": "RG",
+ "Macerata": "MC",
+ "Imperia": "IM",
+ "Palermo": "PA",
+ "Matera": "MT",
+ "L'Aquila": "AQ",
+ "Milano": "MI",
+ "Catania": "CT",
+ "Pesaro e Urbino": "PU",
+ "Potenza": "PZ",
+ "Republic of San Marino": "RSM",
+ "Genoa": "GE",
+ "Brindisi": "BR",
+ "Cagliari": "CA",
+ "Siena": "SI",
+ "Vibo Valentia": "VV",
+ "Reggio Calabria": "RC",
+ "Ascoli Piceno": "AP",
+ "Carbonia-Iglesias": "CI",
+ "Oristano": "OR",
+ "Asti": "AT",
+ "Ravenna": "RA",
+ "Vicenza": "VI",
+ "Savona": "SV",
+ "Biella": "BI",
+ "Rimini": "RN",
+ "Agrigento": "AG",
+ "Prato": "PO",
+ "Cuneo": "CN",
+ "Cosenza": "CS",
+ "Livorno or Leghorn": "LI",
+ "Sondrio": "SO",
+ "Cremona": "CR",
+ "Isernia": "IS",
+ "Trento": "TN",
+ "Terni": "TR",
+ "Bolzano/Bozen": "BZ",
+ "Parma": "PR",
+ "Varese": "VA",
+ "Venezia": "VE",
+ "Sassari": "SS",
+ "Arezzo": "AR",
+}
diff --git a/erpnext/regional/italy/setup.py b/erpnext/regional/italy/setup.py
index 531f10d..1f66b36 100644
--- a/erpnext/regional/italy/setup.py
+++ b/erpnext/regional/italy/setup.py
@@ -7,213 +7,489 @@
from frappe import _
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
from frappe.permissions import add_permission, update_permission_property
-from erpnext.regional.italy import fiscal_regimes, tax_exemption_reasons, mode_of_payment_codes, vat_collectability_options
+from erpnext.regional.italy import (
+ fiscal_regimes,
+ tax_exemption_reasons,
+ mode_of_payment_codes,
+ vat_collectability_options,
+)
+
def setup(company=None, patch=True):
make_custom_fields()
setup_report()
add_permissions()
+
def make_custom_fields(update=True):
invoice_item_fields = [
- dict(fieldname='tax_rate', label='Tax Rate',
- fieldtype='Float', insert_after='description',
- print_hide=1, hidden=1, read_only=1),
- dict(fieldname='tax_amount', label='Tax Amount',
- fieldtype='Currency', insert_after='tax_rate',
- print_hide=1, hidden=1, read_only=1, options="currency"),
- dict(fieldname='total_amount', label='Total Amount',
- fieldtype='Currency', insert_after='tax_amount',
- print_hide=1, hidden=1, read_only=1, options="currency")
+ dict(
+ fieldname="tax_rate",
+ label="Tax Rate",
+ fieldtype="Float",
+ insert_after="description",
+ print_hide=1,
+ hidden=1,
+ read_only=1,
+ ),
+ dict(
+ fieldname="tax_amount",
+ label="Tax Amount",
+ fieldtype="Currency",
+ insert_after="tax_rate",
+ print_hide=1,
+ hidden=1,
+ read_only=1,
+ options="currency",
+ ),
+ dict(
+ fieldname="total_amount",
+ label="Total Amount",
+ fieldtype="Currency",
+ insert_after="tax_amount",
+ print_hide=1,
+ hidden=1,
+ read_only=1,
+ options="currency",
+ ),
]
customer_po_fields = [
- dict(fieldname='customer_po_details', label='Customer PO',
- fieldtype='Section Break', insert_after='image'),
- dict(fieldname='customer_po_no', label='Customer PO No',
- fieldtype='Data', insert_after='customer_po_details',
- fetch_from = 'sales_order.po_no',
- print_hide=1, allow_on_submit=1, fetch_if_empty= 1, read_only=1, no_copy=1),
- dict(fieldname='customer_po_clm_brk', label='',
- fieldtype='Column Break', insert_after='customer_po_no',
- print_hide=1, read_only=1),
- dict(fieldname='customer_po_date', label='Customer PO Date',
- fieldtype='Date', insert_after='customer_po_clm_brk',
- fetch_from = 'sales_order.po_date',
- print_hide=1, allow_on_submit=1, fetch_if_empty= 1, read_only=1, no_copy=1)
+ dict(
+ fieldname="customer_po_details",
+ label="Customer PO",
+ fieldtype="Section Break",
+ insert_after="image",
+ ),
+ dict(
+ fieldname="customer_po_no",
+ label="Customer PO No",
+ fieldtype="Data",
+ insert_after="customer_po_details",
+ fetch_from="sales_order.po_no",
+ print_hide=1,
+ allow_on_submit=1,
+ fetch_if_empty=1,
+ read_only=1,
+ no_copy=1,
+ ),
+ dict(
+ fieldname="customer_po_clm_brk",
+ label="",
+ fieldtype="Column Break",
+ insert_after="customer_po_no",
+ print_hide=1,
+ read_only=1,
+ ),
+ dict(
+ fieldname="customer_po_date",
+ label="Customer PO Date",
+ fieldtype="Date",
+ insert_after="customer_po_clm_brk",
+ fetch_from="sales_order.po_date",
+ print_hide=1,
+ allow_on_submit=1,
+ fetch_if_empty=1,
+ read_only=1,
+ no_copy=1,
+ ),
]
custom_fields = {
- 'Company': [
- dict(fieldname='sb_e_invoicing', label='E-Invoicing',
- fieldtype='Section Break', insert_after='date_of_establishment', print_hide=1),
- dict(fieldname='fiscal_regime', label='Fiscal Regime',
- fieldtype='Select', insert_after='sb_e_invoicing', print_hide=1,
- options="\n".join(map(lambda x: frappe.safe_decode(x, encoding='utf-8'), fiscal_regimes))),
- dict(fieldname='fiscal_code', label='Fiscal Code', fieldtype='Data', insert_after='fiscal_regime', print_hide=1,
- description=_("Applicable if the company is an Individual or a Proprietorship")),
- dict(fieldname='vat_collectability', label='VAT Collectability',
- fieldtype='Select', insert_after='fiscal_code', print_hide=1,
- options="\n".join(map(lambda x: frappe.safe_decode(x, encoding='utf-8'), vat_collectability_options))),
- dict(fieldname='cb_e_invoicing1', fieldtype='Column Break', insert_after='vat_collectability', print_hide=1),
- dict(fieldname='registrar_office_province', label='Province of the Registrar Office',
- fieldtype='Data', insert_after='cb_e_invoicing1', print_hide=1, length=2),
- dict(fieldname='registration_number', label='Registration Number',
- fieldtype='Data', insert_after='registrar_office_province', print_hide=1, length=20),
- dict(fieldname='share_capital_amount', label='Share Capital',
- fieldtype='Currency', insert_after='registration_number', print_hide=1,
- description=_('Applicable if the company is SpA, SApA or SRL')),
- dict(fieldname='no_of_members', label='No of Members',
- fieldtype='Select', insert_after='share_capital_amount', print_hide=1,
- options="\nSU-Socio Unico\nSM-Piu Soci", description=_("Applicable if the company is a limited liability company")),
- dict(fieldname='liquidation_state', label='Liquidation State',
- fieldtype='Select', insert_after='no_of_members', print_hide=1,
- options="\nLS-In Liquidazione\nLN-Non in Liquidazione")
+ "Company": [
+ dict(
+ fieldname="sb_e_invoicing",
+ label="E-Invoicing",
+ fieldtype="Section Break",
+ insert_after="date_of_establishment",
+ print_hide=1,
+ ),
+ dict(
+ fieldname="fiscal_regime",
+ label="Fiscal Regime",
+ fieldtype="Select",
+ insert_after="sb_e_invoicing",
+ print_hide=1,
+ options="\n".join(map(lambda x: frappe.safe_decode(x, encoding="utf-8"), fiscal_regimes)),
+ ),
+ dict(
+ fieldname="fiscal_code",
+ label="Fiscal Code",
+ fieldtype="Data",
+ insert_after="fiscal_regime",
+ print_hide=1,
+ description=_("Applicable if the company is an Individual or a Proprietorship"),
+ ),
+ dict(
+ fieldname="vat_collectability",
+ label="VAT Collectability",
+ fieldtype="Select",
+ insert_after="fiscal_code",
+ print_hide=1,
+ options="\n".join(
+ map(lambda x: frappe.safe_decode(x, encoding="utf-8"), vat_collectability_options)
+ ),
+ ),
+ dict(
+ fieldname="cb_e_invoicing1",
+ fieldtype="Column Break",
+ insert_after="vat_collectability",
+ print_hide=1,
+ ),
+ dict(
+ fieldname="registrar_office_province",
+ label="Province of the Registrar Office",
+ fieldtype="Data",
+ insert_after="cb_e_invoicing1",
+ print_hide=1,
+ length=2,
+ ),
+ dict(
+ fieldname="registration_number",
+ label="Registration Number",
+ fieldtype="Data",
+ insert_after="registrar_office_province",
+ print_hide=1,
+ length=20,
+ ),
+ dict(
+ fieldname="share_capital_amount",
+ label="Share Capital",
+ fieldtype="Currency",
+ insert_after="registration_number",
+ print_hide=1,
+ description=_("Applicable if the company is SpA, SApA or SRL"),
+ ),
+ dict(
+ fieldname="no_of_members",
+ label="No of Members",
+ fieldtype="Select",
+ insert_after="share_capital_amount",
+ print_hide=1,
+ options="\nSU-Socio Unico\nSM-Piu Soci",
+ description=_("Applicable if the company is a limited liability company"),
+ ),
+ dict(
+ fieldname="liquidation_state",
+ label="Liquidation State",
+ fieldtype="Select",
+ insert_after="no_of_members",
+ print_hide=1,
+ options="\nLS-In Liquidazione\nLN-Non in Liquidazione",
+ ),
],
- 'Sales Taxes and Charges': [
- dict(fieldname='tax_exemption_reason', label='Tax Exemption Reason',
- fieldtype='Select', insert_after='included_in_print_rate', print_hide=1,
+ "Sales Taxes and Charges": [
+ dict(
+ fieldname="tax_exemption_reason",
+ label="Tax Exemption Reason",
+ fieldtype="Select",
+ insert_after="included_in_print_rate",
+ print_hide=1,
depends_on='eval:doc.charge_type!="Actual" && doc.rate==0.0',
- options="\n" + "\n".join(map(lambda x: frappe.safe_decode(x, encoding='utf-8'), tax_exemption_reasons))),
- dict(fieldname='tax_exemption_law', label='Tax Exempt Under',
- fieldtype='Text', insert_after='tax_exemption_reason', print_hide=1,
- depends_on='eval:doc.charge_type!="Actual" && doc.rate==0.0')
+ options="\n"
+ + "\n".join(map(lambda x: frappe.safe_decode(x, encoding="utf-8"), tax_exemption_reasons)),
+ ),
+ dict(
+ fieldname="tax_exemption_law",
+ label="Tax Exempt Under",
+ fieldtype="Text",
+ insert_after="tax_exemption_reason",
+ print_hide=1,
+ depends_on='eval:doc.charge_type!="Actual" && doc.rate==0.0',
+ ),
],
- 'Customer': [
- dict(fieldname='fiscal_code', label='Fiscal Code', fieldtype='Data', insert_after='tax_id', print_hide=1),
- dict(fieldname='recipient_code', label='Recipient Code',
- fieldtype='Data', insert_after='fiscal_code', print_hide=1, default="0000000"),
- dict(fieldname='pec', label='Recipient PEC',
- fieldtype='Data', insert_after='fiscal_code', print_hide=1),
- dict(fieldname='is_public_administration', label='Is Public Administration',
- fieldtype='Check', insert_after='is_internal_customer', print_hide=1,
+ "Customer": [
+ dict(
+ fieldname="fiscal_code",
+ label="Fiscal Code",
+ fieldtype="Data",
+ insert_after="tax_id",
+ print_hide=1,
+ ),
+ dict(
+ fieldname="recipient_code",
+ label="Recipient Code",
+ fieldtype="Data",
+ insert_after="fiscal_code",
+ print_hide=1,
+ default="0000000",
+ ),
+ dict(
+ fieldname="pec",
+ label="Recipient PEC",
+ fieldtype="Data",
+ insert_after="fiscal_code",
+ print_hide=1,
+ ),
+ dict(
+ fieldname="is_public_administration",
+ label="Is Public Administration",
+ fieldtype="Check",
+ insert_after="is_internal_customer",
+ print_hide=1,
description=_("Set this if the customer is a Public Administration company."),
- depends_on='eval:doc.customer_type=="Company"'),
- dict(fieldname='first_name', label='First Name', fieldtype='Data',
- insert_after='salutation', print_hide=1, depends_on='eval:doc.customer_type!="Company"'),
- dict(fieldname='last_name', label='Last Name', fieldtype='Data',
- insert_after='first_name', print_hide=1, depends_on='eval:doc.customer_type!="Company"')
+ depends_on='eval:doc.customer_type=="Company"',
+ ),
+ dict(
+ fieldname="first_name",
+ label="First Name",
+ fieldtype="Data",
+ insert_after="salutation",
+ print_hide=1,
+ depends_on='eval:doc.customer_type!="Company"',
+ ),
+ dict(
+ fieldname="last_name",
+ label="Last Name",
+ fieldtype="Data",
+ insert_after="first_name",
+ print_hide=1,
+ depends_on='eval:doc.customer_type!="Company"',
+ ),
],
- 'Mode of Payment': [
- dict(fieldname='mode_of_payment_code', label='Code',
- fieldtype='Select', insert_after='included_in_print_rate', print_hide=1,
- options="\n".join(map(lambda x: frappe.safe_decode(x, encoding='utf-8'), mode_of_payment_codes)))
+ "Mode of Payment": [
+ dict(
+ fieldname="mode_of_payment_code",
+ label="Code",
+ fieldtype="Select",
+ insert_after="included_in_print_rate",
+ print_hide=1,
+ options="\n".join(
+ map(lambda x: frappe.safe_decode(x, encoding="utf-8"), mode_of_payment_codes)
+ ),
+ )
],
- 'Payment Schedule': [
- dict(fieldname='mode_of_payment_code', label='Code',
- fieldtype='Select', insert_after='mode_of_payment', print_hide=1,
- options="\n".join(map(lambda x: frappe.safe_decode(x, encoding='utf-8'), mode_of_payment_codes)),
- fetch_from="mode_of_payment.mode_of_payment_code", read_only=1),
- dict(fieldname='bank_account', label='Bank Account',
- fieldtype='Link', insert_after='mode_of_payment_code', print_hide=1,
- options="Bank Account"),
- dict(fieldname='bank_account_name', label='Bank Name',
- fieldtype='Data', insert_after='bank_account', print_hide=1,
- fetch_from="bank_account.bank", read_only=1),
- dict(fieldname='bank_account_no', label='Bank Account No',
- fieldtype='Data', insert_after='bank_account_name', print_hide=1,
- fetch_from="bank_account.bank_account_no", read_only=1),
- dict(fieldname='bank_account_iban', label='IBAN',
- fieldtype='Data', insert_after='bank_account_name', print_hide=1,
- fetch_from="bank_account.iban", read_only=1),
- dict(fieldname='bank_account_swift_number', label='Swift Code (BIC)',
- fieldtype='Data', insert_after='bank_account_iban', print_hide=1,
- fetch_from="bank_account.swift_number", read_only=1),
+ "Payment Schedule": [
+ dict(
+ fieldname="mode_of_payment_code",
+ label="Code",
+ fieldtype="Select",
+ insert_after="mode_of_payment",
+ print_hide=1,
+ options="\n".join(
+ map(lambda x: frappe.safe_decode(x, encoding="utf-8"), mode_of_payment_codes)
+ ),
+ fetch_from="mode_of_payment.mode_of_payment_code",
+ read_only=1,
+ ),
+ dict(
+ fieldname="bank_account",
+ label="Bank Account",
+ fieldtype="Link",
+ insert_after="mode_of_payment_code",
+ print_hide=1,
+ options="Bank Account",
+ ),
+ dict(
+ fieldname="bank_account_name",
+ label="Bank Name",
+ fieldtype="Data",
+ insert_after="bank_account",
+ print_hide=1,
+ fetch_from="bank_account.bank",
+ read_only=1,
+ ),
+ dict(
+ fieldname="bank_account_no",
+ label="Bank Account No",
+ fieldtype="Data",
+ insert_after="bank_account_name",
+ print_hide=1,
+ fetch_from="bank_account.bank_account_no",
+ read_only=1,
+ ),
+ dict(
+ fieldname="bank_account_iban",
+ label="IBAN",
+ fieldtype="Data",
+ insert_after="bank_account_name",
+ print_hide=1,
+ fetch_from="bank_account.iban",
+ read_only=1,
+ ),
+ dict(
+ fieldname="bank_account_swift_number",
+ label="Swift Code (BIC)",
+ fieldtype="Data",
+ insert_after="bank_account_iban",
+ print_hide=1,
+ fetch_from="bank_account.swift_number",
+ read_only=1,
+ ),
],
"Sales Invoice": [
- dict(fieldname='vat_collectability', label='VAT Collectability',
- fieldtype='Select', insert_after='taxes_and_charges', print_hide=1,
- options="\n".join(map(lambda x: frappe.safe_decode(x, encoding='utf-8'), vat_collectability_options)),
- fetch_from="company.vat_collectability"),
- dict(fieldname='sb_e_invoicing_reference', label='E-Invoicing',
- fieldtype='Section Break', insert_after='against_income_account', print_hide=1),
- dict(fieldname='company_fiscal_code', label='Company Fiscal Code',
- fieldtype='Data', insert_after='sb_e_invoicing_reference', print_hide=1, read_only=1,
- fetch_from="company.fiscal_code"),
- dict(fieldname='company_fiscal_regime', label='Company Fiscal Regime',
- fieldtype='Data', insert_after='company_fiscal_code', print_hide=1, read_only=1,
- fetch_from="company.fiscal_regime"),
- dict(fieldname='cb_e_invoicing_reference', fieldtype='Column Break',
- insert_after='company_fiscal_regime', print_hide=1),
- dict(fieldname='customer_fiscal_code', label='Customer Fiscal Code',
- fieldtype='Data', insert_after='cb_e_invoicing_reference', read_only=1,
- fetch_from="customer.fiscal_code"),
- dict(fieldname='type_of_document', label='Type of Document',
- fieldtype='Select', insert_after='customer_fiscal_code',
- options='\nTD01\nTD02\nTD03\nTD04\nTD05\nTD06\nTD16\nTD17\nTD18\nTD19\nTD20\nTD21\nTD22\nTD23\nTD24\nTD25\nTD26\nTD27'),
- ],
- 'Purchase Invoice Item': invoice_item_fields,
- 'Sales Order Item': invoice_item_fields,
- 'Delivery Note Item': invoice_item_fields,
- 'Sales Invoice Item': invoice_item_fields + customer_po_fields,
- 'Quotation Item': invoice_item_fields,
- 'Purchase Order Item': invoice_item_fields,
- 'Purchase Receipt Item': invoice_item_fields,
- 'Supplier Quotation Item': invoice_item_fields,
- 'Address': [
- dict(fieldname='country_code', label='Country Code',
- fieldtype='Data', insert_after='country', print_hide=1, read_only=0,
- fetch_from="country.code"),
- dict(fieldname='state_code', label='State Code',
- fieldtype='Data', insert_after='state', print_hide=1)
- ],
- 'Purchase Invoice': [
- dict(fieldname='document_type', label='Document Type',
- fieldtype='Data', insert_after='company', print_hide=1, read_only=1
+ dict(
+ fieldname="vat_collectability",
+ label="VAT Collectability",
+ fieldtype="Select",
+ insert_after="taxes_and_charges",
+ print_hide=1,
+ options="\n".join(
+ map(lambda x: frappe.safe_decode(x, encoding="utf-8"), vat_collectability_options)
),
- dict(fieldname='destination_code', label='Destination Code',
- fieldtype='Data', insert_after='company', print_hide=1, read_only=1
- ),
- dict(fieldname='imported_grand_total', label='Imported Grand Total',
- fieldtype='Data', insert_after='update_auto_repeat_reference', print_hide=1, read_only=1
- )
+ fetch_from="company.vat_collectability",
+ ),
+ dict(
+ fieldname="sb_e_invoicing_reference",
+ label="E-Invoicing",
+ fieldtype="Section Break",
+ insert_after="against_income_account",
+ print_hide=1,
+ ),
+ dict(
+ fieldname="company_fiscal_code",
+ label="Company Fiscal Code",
+ fieldtype="Data",
+ insert_after="sb_e_invoicing_reference",
+ print_hide=1,
+ read_only=1,
+ fetch_from="company.fiscal_code",
+ ),
+ dict(
+ fieldname="company_fiscal_regime",
+ label="Company Fiscal Regime",
+ fieldtype="Data",
+ insert_after="company_fiscal_code",
+ print_hide=1,
+ read_only=1,
+ fetch_from="company.fiscal_regime",
+ ),
+ dict(
+ fieldname="cb_e_invoicing_reference",
+ fieldtype="Column Break",
+ insert_after="company_fiscal_regime",
+ print_hide=1,
+ ),
+ dict(
+ fieldname="customer_fiscal_code",
+ label="Customer Fiscal Code",
+ fieldtype="Data",
+ insert_after="cb_e_invoicing_reference",
+ read_only=1,
+ fetch_from="customer.fiscal_code",
+ ),
+ dict(
+ fieldname="type_of_document",
+ label="Type of Document",
+ fieldtype="Select",
+ insert_after="customer_fiscal_code",
+ options="\nTD01\nTD02\nTD03\nTD04\nTD05\nTD06\nTD16\nTD17\nTD18\nTD19\nTD20\nTD21\nTD22\nTD23\nTD24\nTD25\nTD26\nTD27",
+ ),
],
- 'Purchase Taxes and Charges': [
- dict(fieldname='tax_rate', label='Tax Rate',
- fieldtype='Data', insert_after='parenttype', print_hide=1, read_only=0
- )
+ "Purchase Invoice Item": invoice_item_fields,
+ "Sales Order Item": invoice_item_fields,
+ "Delivery Note Item": invoice_item_fields,
+ "Sales Invoice Item": invoice_item_fields + customer_po_fields,
+ "Quotation Item": invoice_item_fields,
+ "Purchase Order Item": invoice_item_fields,
+ "Purchase Receipt Item": invoice_item_fields,
+ "Supplier Quotation Item": invoice_item_fields,
+ "Address": [
+ dict(
+ fieldname="country_code",
+ label="Country Code",
+ fieldtype="Data",
+ insert_after="country",
+ print_hide=1,
+ read_only=0,
+ fetch_from="country.code",
+ ),
+ dict(
+ fieldname="state_code",
+ label="State Code",
+ fieldtype="Data",
+ insert_after="state",
+ print_hide=1,
+ ),
],
- 'Supplier': [
- dict(fieldname='fiscal_code', label='Fiscal Code',
- fieldtype='Data', insert_after='tax_id', print_hide=1, read_only=1
- ),
- dict(fieldname='fiscal_regime', label='Fiscal Regime',
- fieldtype='Select', insert_after='fiscal_code', print_hide=1, read_only=1,
- options= "\nRF01\nRF02\nRF04\nRF05\nRF06\nRF07\nRF08\nRF09\nRF10\nRF11\nRF12\nRF13\nRF14\nRF15\nRF16\nRF17\nRF18\nRF19"
- )
- ]
+ "Purchase Invoice": [
+ dict(
+ fieldname="document_type",
+ label="Document Type",
+ fieldtype="Data",
+ insert_after="company",
+ print_hide=1,
+ read_only=1,
+ ),
+ dict(
+ fieldname="destination_code",
+ label="Destination Code",
+ fieldtype="Data",
+ insert_after="company",
+ print_hide=1,
+ read_only=1,
+ ),
+ dict(
+ fieldname="imported_grand_total",
+ label="Imported Grand Total",
+ fieldtype="Data",
+ insert_after="update_auto_repeat_reference",
+ print_hide=1,
+ read_only=1,
+ ),
+ ],
+ "Purchase Taxes and Charges": [
+ dict(
+ fieldname="tax_rate",
+ label="Tax Rate",
+ fieldtype="Data",
+ insert_after="parenttype",
+ print_hide=1,
+ read_only=0,
+ )
+ ],
+ "Supplier": [
+ dict(
+ fieldname="fiscal_code",
+ label="Fiscal Code",
+ fieldtype="Data",
+ insert_after="tax_id",
+ print_hide=1,
+ read_only=1,
+ ),
+ dict(
+ fieldname="fiscal_regime",
+ label="Fiscal Regime",
+ fieldtype="Select",
+ insert_after="fiscal_code",
+ print_hide=1,
+ read_only=1,
+ options="\nRF01\nRF02\nRF04\nRF05\nRF06\nRF07\nRF08\nRF09\nRF10\nRF11\nRF12\nRF13\nRF14\nRF15\nRF16\nRF17\nRF18\nRF19",
+ ),
+ ],
}
- create_custom_fields(custom_fields, ignore_validate = frappe.flags.in_patch, update=update)
+ create_custom_fields(custom_fields, ignore_validate=frappe.flags.in_patch, update=update)
+
def setup_report():
- report_name = 'Electronic Invoice Register'
+ report_name = "Electronic Invoice Register"
frappe.db.set_value("Report", report_name, "disabled", 0)
- if not frappe.db.get_value('Custom Role', dict(report=report_name)):
- frappe.get_doc(dict(
- doctype='Custom Role',
- report=report_name,
- roles= [
- dict(role='Accounts User'),
- dict(role='Accounts Manager')
- ]
- )).insert()
+ if not frappe.db.get_value("Custom Role", dict(report=report_name)):
+ frappe.get_doc(
+ dict(
+ doctype="Custom Role",
+ report=report_name,
+ roles=[dict(role="Accounts User"), dict(role="Accounts Manager")],
+ )
+ ).insert()
+
def add_permissions():
- doctype = 'Import Supplier Invoice'
- add_permission(doctype, 'All', 0)
+ doctype = "Import Supplier Invoice"
+ add_permission(doctype, "All", 0)
- for role in ('Accounts Manager', 'Accounts User','Purchase User', 'Auditor'):
+ for role in ("Accounts Manager", "Accounts User", "Purchase User", "Auditor"):
add_permission(doctype, role, 0)
- update_permission_property(doctype, role, 0, 'print', 1)
- update_permission_property(doctype, role, 0, 'report', 1)
+ update_permission_property(doctype, role, 0, "print", 1)
+ update_permission_property(doctype, role, 0, "report", 1)
- if role in ('Accounts Manager', 'Accounts User'):
- update_permission_property(doctype, role, 0, 'write', 1)
- update_permission_property(doctype, role, 0, 'create', 1)
+ if role in ("Accounts Manager", "Accounts User"):
+ update_permission_property(doctype, role, 0, "write", 1)
+ update_permission_property(doctype, role, 0, "create", 1)
- update_permission_property(doctype, 'Accounts Manager', 0, 'delete', 1)
- add_permission(doctype, 'Accounts Manager', 1)
- update_permission_property(doctype, 'Accounts Manager', 1, 'write', 1)
- update_permission_property(doctype, 'Accounts Manager', 1, 'create', 1)
+ update_permission_property(doctype, "Accounts Manager", 0, "delete", 1)
+ add_permission(doctype, "Accounts Manager", 1)
+ update_permission_property(doctype, "Accounts Manager", 1, "write", 1)
+ update_permission_property(doctype, "Accounts Manager", 1, "create", 1)
diff --git a/erpnext/regional/italy/utils.py b/erpnext/regional/italy/utils.py
index c82557b..f5b2e2d 100644
--- a/erpnext/regional/italy/utils.py
+++ b/erpnext/regional/italy/utils.py
@@ -11,41 +11,41 @@
def update_itemised_tax_data(doc):
- if not doc.taxes: return
+ if not doc.taxes:
+ return
- if doc.doctype == "Purchase Invoice": return
+ if doc.doctype == "Purchase Invoice":
+ return
itemised_tax = get_itemised_tax(doc.taxes)
for row in doc.items:
tax_rate = 0.0
if itemised_tax.get(row.item_code):
- tax_rate = sum([tax.get('tax_rate', 0) for d, tax in itemised_tax.get(row.item_code).items()])
+ tax_rate = sum([tax.get("tax_rate", 0) for d, tax in itemised_tax.get(row.item_code).items()])
row.tax_rate = flt(tax_rate, row.precision("tax_rate"))
row.tax_amount = flt((row.net_amount * tax_rate) / 100, row.precision("net_amount"))
row.total_amount = flt((row.net_amount + row.tax_amount), row.precision("total_amount"))
+
@frappe.whitelist()
def export_invoices(filters=None):
- frappe.has_permission('Sales Invoice', throw=True)
+ frappe.has_permission("Sales Invoice", throw=True)
invoices = frappe.get_all(
- "Sales Invoice",
- filters=get_conditions(filters),
- fields=["name", "company_tax_id"]
+ "Sales Invoice", filters=get_conditions(filters), fields=["name", "company_tax_id"]
)
attachments = get_e_invoice_attachments(invoices)
- zip_filename = "{0}-einvoices.zip".format(
- frappe.utils.get_datetime().strftime("%Y%m%d_%H%M%S"))
+ zip_filename = "{0}-einvoices.zip".format(frappe.utils.get_datetime().strftime("%Y%m%d_%H%M%S"))
download_zip(attachments, zip_filename)
def prepare_invoice(invoice, progressive_number):
- #set company information
+ # set company information
company = frappe.get_doc("Company", invoice.company)
invoice.progressive_number = progressive_number
@@ -54,15 +54,17 @@
company_address = frappe.get_doc("Address", invoice.company_address)
invoice.company_address_data = company_address
- #Set invoice type
+ # Set invoice type
if not invoice.type_of_document:
if invoice.is_return and invoice.return_against:
- invoice.type_of_document = "TD04" #Credit Note (Nota di Credito)
- invoice.return_against_unamended = get_unamended_name(frappe.get_doc("Sales Invoice", invoice.return_against))
+ invoice.type_of_document = "TD04" # Credit Note (Nota di Credito)
+ invoice.return_against_unamended = get_unamended_name(
+ frappe.get_doc("Sales Invoice", invoice.return_against)
+ )
else:
- invoice.type_of_document = "TD01" #Sales Invoice (Fattura)
+ invoice.type_of_document = "TD01" # Sales Invoice (Fattura)
- #set customer information
+ # set customer information
invoice.customer_data = frappe.get_doc("Customer", invoice.customer)
customer_address = frappe.get_doc("Address", invoice.customer_address)
invoice.customer_address_data = customer_address
@@ -79,8 +81,10 @@
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.
- stamp_duty_charge_row = next((tax for tax in invoice.taxes if tax.charge_type == "Actual" and tax.tax_amount == 2.0 ), None)
+ # Check if stamp duty (Bollo) of 2 EUR exists.
+ stamp_duty_charge_row = next(
+ (tax for tax in invoice.taxes if tax.charge_type == "Actual" and tax.tax_amount == 2.0), None
+ )
if stamp_duty_charge_row:
invoice.stamp_duty = stamp_duty_charge_row.tax_amount
@@ -90,24 +94,28 @@
customer_po_data = {}
for d in invoice.e_invoice_items:
- if (d.customer_po_no and d.customer_po_date
- and d.customer_po_no not in customer_po_data):
+ if d.customer_po_no and d.customer_po_date and d.customer_po_no not in customer_po_data:
customer_po_data[d.customer_po_no] = d.customer_po_date
invoice.customer_po_data = customer_po_data
return invoice
+
def get_conditions(filters):
filters = json.loads(filters)
conditions = {"docstatus": 1, "company_tax_id": ("!=", "")}
- if filters.get("company"): conditions["company"] = filters["company"]
- if filters.get("customer"): conditions["customer"] = filters["customer"]
+ if filters.get("company"):
+ conditions["company"] = filters["company"]
+ if filters.get("customer"):
+ conditions["customer"] = filters["customer"]
- if filters.get("from_date"): conditions["posting_date"] = (">=", filters["from_date"])
- if filters.get("to_date"): conditions["posting_date"] = ("<=", filters["to_date"])
+ if filters.get("from_date"):
+ conditions["posting_date"] = (">=", filters["from_date"])
+ if filters.get("to_date"):
+ conditions["posting_date"] = ("<=", filters["to_date"])
if filters.get("from_date") and filters.get("to_date"):
conditions["posting_date"] = ("between", [filters.get("from_date"), filters.get("to_date")])
@@ -119,10 +127,9 @@
import zipfile
zip_stream = io.BytesIO()
- with zipfile.ZipFile(zip_stream, 'w', zipfile.ZIP_DEFLATED) as zip_file:
+ with zipfile.ZipFile(zip_stream, "w", zipfile.ZIP_DEFLATED) as zip_file:
for file in files:
- file_path = frappe.utils.get_files_path(
- file.file_name, is_private=file.is_private)
+ file_path = frappe.utils.get_files_path(file.file_name, is_private=file.is_private)
zip_file.write(file_path, arcname=file.file_name)
@@ -131,20 +138,21 @@
frappe.local.response.type = "download"
zip_stream.close()
+
def get_invoice_summary(items, taxes):
summary_data = frappe._dict()
for tax in taxes:
- #Include only VAT charges.
+ # Include only VAT charges.
if tax.charge_type == "Actual":
continue
- #Charges to appear as items in the e-invoice.
+ # 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,
+ idx=len(items) + 1,
item_code=reference_row.description,
item_name=reference_row.description,
description=reference_row.description,
@@ -157,11 +165,11 @@
net_amount=reference_row.tax_amount,
taxable_amount=reference_row.tax_amount,
item_tax_rate={tax.account_head: tax.rate},
- charges=True
+ charges=True,
)
)
- #Check item tax rates if tax rate is zero.
+ # Check item tax rates if tax rate is zero.
if tax.rate == 0:
for item in items:
item_tax_rate = item.item_tax_rate
@@ -171,8 +179,15 @@
if item_tax_rate and tax.account_head in item_tax_rate:
key = cstr(item_tax_rate[tax.account_head])
if key not in summary_data:
- summary_data.setdefault(key, {"tax_amount": 0.0, "taxable_amount": 0.0,
- "tax_exemption_reason": "", "tax_exemption_law": ""})
+ 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
@@ -180,93 +195,138 @@
summary_data[key]["tax_exemption_reason"] = tax.tax_exemption_reason
summary_data[key]["tax_exemption_law"] = tax.tax_exemption_law
- if summary_data.get("0.0") and tax.charge_type in ["On Previous Row Total",
- "On Previous Row Amount"]:
+ if summary_data.get("0.0") and tax.charge_type in [
+ "On Previous Row Total",
+ "On Previous Row Amount",
+ ]:
summary_data[key]["taxable_amount"] = tax.total
- if summary_data == {}: #Implies that Zero VAT has not been set on any item.
- summary_data.setdefault("0.0", {"tax_amount": 0.0, "taxable_amount": tax.total,
- "tax_exemption_reason": tax.tax_exemption_reason, "tax_exemption_law": tax.tax_exemption_law})
+ if summary_data == {}: # Implies that Zero VAT has not been set on any item.
+ summary_data.setdefault(
+ "0.0",
+ {
+ "tax_amount": 0.0,
+ "taxable_amount": tax.total,
+ "tax_exemption_reason": tax.tax_exemption_reason,
+ "tax_exemption_law": tax.tax_exemption_law,
+ },
+ )
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]:
+ for rate_item in [
+ tax_item for tax_item in item_wise_tax_detail.items() if tax_item[1][0] == tax.rate
+ ]:
key = cstr(tax.rate)
- if not summary_data.get(key): summary_data.setdefault(key, {"tax_amount": 0.0, "taxable_amount": 0.0})
+ 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]])
+ 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})
+ 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.
+
+# Preflight for successful e-invoice export.
def sales_invoice_validate(doc):
- #Validate company
- if doc.doctype != 'Sales Invoice':
+ # Validate company
+ if doc.doctype != "Sales Invoice":
return
if not doc.company_address:
- frappe.throw(_("Please set an Address on the Company '%s'" % doc.company), title=_("E-Invoicing Information Missing"))
+ frappe.throw(
+ _("Please set an Address on the Company '%s'" % doc.company),
+ title=_("E-Invoicing Information Missing"),
+ )
else:
validate_address(doc.company_address)
- company_fiscal_regime = frappe.get_cached_value("Company", doc.company, 'fiscal_regime')
+ company_fiscal_regime = frappe.get_cached_value("Company", doc.company, "fiscal_regime")
if not company_fiscal_regime:
- frappe.throw(_("Fiscal Regime is mandatory, kindly set the fiscal regime in the company {0}")
- .format(doc.company))
+ frappe.throw(
+ _("Fiscal Regime is mandatory, kindly set the fiscal regime in the company {0}").format(
+ doc.company
+ )
+ )
else:
doc.company_fiscal_regime = company_fiscal_regime
- doc.company_tax_id = frappe.get_cached_value("Company", doc.company, 'tax_id')
- doc.company_fiscal_code = frappe.get_cached_value("Company", doc.company, 'fiscal_code')
+ doc.company_tax_id = frappe.get_cached_value("Company", doc.company, "tax_id")
+ doc.company_fiscal_code = frappe.get_cached_value("Company", doc.company, "fiscal_code")
if not doc.company_tax_id and not doc.company_fiscal_code:
- frappe.throw(_("Please set either the Tax ID or Fiscal Code on Company '%s'" % doc.company), title=_("E-Invoicing Information Missing"))
+ frappe.throw(
+ _("Please set either the Tax ID or Fiscal Code on Company '%s'" % doc.company),
+ title=_("E-Invoicing Information Missing"),
+ )
- #Validate customer details
+ # Validate customer details
customer = frappe.get_doc("Customer", doc.customer)
if customer.customer_type == "Individual":
doc.customer_fiscal_code = customer.fiscal_code
if not doc.customer_fiscal_code:
- frappe.throw(_("Please set Fiscal Code for the customer '%s'" % doc.customer), title=_("E-Invoicing Information Missing"))
+ frappe.throw(
+ _("Please set Fiscal Code for the customer '%s'" % doc.customer),
+ title=_("E-Invoicing Information Missing"),
+ )
else:
if customer.is_public_administration:
doc.customer_fiscal_code = customer.fiscal_code
if not doc.customer_fiscal_code:
- frappe.throw(_("Please set Fiscal Code for the public administration '%s'" % doc.customer), title=_("E-Invoicing Information Missing"))
+ frappe.throw(
+ _("Please set Fiscal Code for the public administration '%s'" % doc.customer),
+ title=_("E-Invoicing Information Missing"),
+ )
else:
doc.tax_id = customer.tax_id
if not doc.tax_id:
- frappe.throw(_("Please set Tax ID for the customer '%s'" % doc.customer), title=_("E-Invoicing Information Missing"))
+ frappe.throw(
+ _("Please set Tax ID for the customer '%s'" % doc.customer),
+ title=_("E-Invoicing Information Missing"),
+ )
if not doc.customer_address:
- frappe.throw(_("Please set the Customer Address"), title=_("E-Invoicing Information Missing"))
+ frappe.throw(_("Please set the Customer Address"), title=_("E-Invoicing Information Missing"))
else:
validate_address(doc.customer_address)
if not len(doc.taxes):
- frappe.throw(_("Please set at least one row in the Taxes and Charges Table"), title=_("E-Invoicing Information Missing"))
+ frappe.throw(
+ _("Please set at least one row in the Taxes and Charges Table"),
+ title=_("E-Invoicing Information Missing"),
+ )
else:
for row in doc.taxes:
if row.rate == 0 and row.tax_amount == 0 and not row.tax_exemption_reason:
- frappe.throw(_("Row {0}: Please set at Tax Exemption Reason in Sales Taxes and Charges").format(row.idx),
- title=_("E-Invoicing Information Missing"))
+ frappe.throw(
+ _("Row {0}: Please set at Tax Exemption Reason in Sales Taxes and Charges").format(row.idx),
+ title=_("E-Invoicing Information Missing"),
+ )
for schedule in doc.payment_schedule:
if schedule.mode_of_payment and not schedule.mode_of_payment_code:
- schedule.mode_of_payment_code = frappe.get_cached_value('Mode of Payment',
- schedule.mode_of_payment, 'mode_of_payment_code')
+ schedule.mode_of_payment_code = frappe.get_cached_value(
+ "Mode of Payment", schedule.mode_of_payment, "mode_of_payment_code"
+ )
-#Ensure payment details are valid for e-invoice.
+
+# Ensure payment details are valid for e-invoice.
def sales_invoice_on_submit(doc, method):
- #Validate payment details
- if get_company_country(doc.company) not in ['Italy',
- 'Italia', 'Italian Republic', 'Repubblica Italiana']:
+ # Validate payment details
+ if get_company_country(doc.company) not in [
+ "Italy",
+ "Italia",
+ "Italian Republic",
+ "Repubblica Italiana",
+ ]:
return
if not len(doc.payment_schedule):
@@ -274,38 +334,53 @@
else:
for schedule in doc.payment_schedule:
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"))
+ 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)
+
def prepare_and_attach_invoice(doc, replace=False):
progressive_name, progressive_number = get_progressive_name_and_number(doc, replace)
invoice = prepare_invoice(doc, progressive_number)
item_meta = frappe.get_meta("Sales Invoice Item")
- invoice_xml = frappe.render_template('erpnext/regional/italy/e-invoice.xml',
- context={"doc": invoice, "item_meta": item_meta}, is_path=True)
+ invoice_xml = frappe.render_template(
+ "erpnext/regional/italy/e-invoice.xml",
+ context={"doc": invoice, "item_meta": item_meta},
+ is_path=True,
+ )
invoice_xml = invoice_xml.replace("&", "&")
xml_filename = progressive_name + ".xml"
- _file = frappe.get_doc({
- "doctype": "File",
- "file_name": xml_filename,
- "attached_to_doctype": doc.doctype,
- "attached_to_name": doc.name,
- "is_private": True,
- "content": invoice_xml
- })
+ _file = frappe.get_doc(
+ {
+ "doctype": "File",
+ "file_name": xml_filename,
+ "attached_to_doctype": doc.doctype,
+ "attached_to_name": doc.name,
+ "is_private": True,
+ "content": invoice_xml,
+ }
+ )
_file.save()
return _file
+
@frappe.whitelist()
def generate_single_invoice(docname):
doc = frappe.get_doc("Sales Invoice", docname)
@@ -314,17 +389,24 @@
e_invoice = prepare_and_attach_invoice(doc, True)
return e_invoice.file_url
+
# Delete e-invoice attachment on cancel.
def sales_invoice_on_cancel(doc, method):
- if get_company_country(doc.company) not in ['Italy',
- 'Italia', 'Italian Republic', 'Repubblica Italiana']:
+ if get_company_country(doc.company) not in [
+ "Italy",
+ "Italia",
+ "Italian Republic",
+ "Repubblica Italiana",
+ ]:
return
for attachment in get_e_invoice_attachments(doc):
remove_file(attachment.name, attached_to_doctype=doc.doctype, attached_to_name=doc.name)
+
def get_company_country(company):
- return frappe.get_cached_value('Company', company, 'country')
+ return frappe.get_cached_value("Company", company, "country")
+
def get_e_invoice_attachments(invoices):
if not isinstance(invoices, list):
@@ -338,16 +420,14 @@
invoice.company_tax_id
if invoice.company_tax_id.startswith("IT")
else "IT" + invoice.company_tax_id
- ) for invoice in invoices
+ )
+ for invoice in invoices
}
attachments = frappe.get_all(
"File",
fields=("name", "file_name", "attached_to_name", "is_private"),
- filters= {
- "attached_to_name": ('in', tax_id_map),
- "attached_to_doctype": 'Sales Invoice'
- }
+ filters={"attached_to_name": ("in", tax_id_map), "attached_to_doctype": "Sales Invoice"},
)
out = []
@@ -355,21 +435,24 @@
if (
attachment.file_name
and attachment.file_name.endswith(".xml")
- and attachment.file_name.startswith(
- tax_id_map.get(attachment.attached_to_name))
+ and attachment.file_name.startswith(tax_id_map.get(attachment.attached_to_name))
):
out.append(attachment)
return out
+
def validate_address(address_name):
fields = ["pincode", "city", "country_code"]
data = frappe.get_cached_value("Address", address_name, fields, as_dict=1) or {}
for field in fields:
if not data.get(field):
- frappe.throw(_("Please set {0} for address {1}").format(field.replace('-',''), address_name),
- title=_("E-Invoicing Information Missing"))
+ frappe.throw(
+ _("Please set {0} for address {1}").format(field.replace("-", ""), address_name),
+ title=_("E-Invoicing Information Missing"),
+ )
+
def get_unamended_name(doc):
attributes = ["naming_series", "amended_from"]
@@ -382,6 +465,7 @@
else:
return doc.name
+
def get_progressive_name_and_number(doc, replace=False):
if replace:
for attachment in get_e_invoice_attachments(doc):
@@ -389,24 +473,30 @@
filename = attachment.file_name.split(".xml")[0]
return filename, filename.split("_")[1]
- company_tax_id = doc.company_tax_id if doc.company_tax_id.startswith("IT") else "IT" + doc.company_tax_id
+ company_tax_id = (
+ doc.company_tax_id if doc.company_tax_id.startswith("IT") else "IT" + doc.company_tax_id
+ )
progressive_name = frappe.model.naming.make_autoname(company_tax_id + "_.#####")
progressive_number = progressive_name.split("_")[1]
return progressive_name, progressive_number
+
def set_state_code(doc, method):
- if doc.get('country_code'):
+ if doc.get("country_code"):
doc.country_code = doc.country_code.upper()
- if not doc.get('state'):
+ if not doc.get("state"):
return
- if not (hasattr(doc, "state_code") and doc.country in ["Italy", "Italia", "Italian Republic", "Repubblica Italiana"]):
+ if not (
+ hasattr(doc, "state_code")
+ and doc.country in ["Italy", "Italia", "Italian Republic", "Repubblica Italiana"]
+ ):
return
- state_codes_lower = {key.lower():value for key,value in state_codes.items()}
+ state_codes_lower = {key.lower(): value for key, value in state_codes.items()}
- state = doc.get('state','').lower()
+ state = doc.get("state", "").lower()
if state_codes_lower.get(state):
doc.state_code = state_codes_lower.get(state)