From b30a9b1869033f8e21e141adb55405425aa19ac7 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Fri, 1 Mar 2019 12:33:19 +0530 Subject: [PATCH 1/2] fix(regional,italy): bank details, custom button on sales invoice Updates to Bank details in e-invoice XML Additional fields on Payment Schedule Button to Generate E-Invoice on Sales Invoice (generates and replaces attached e-invoice) Replaced `x.decode('utf-8')` with `frappe.safe_decode(x, encoding='utf-8')` in setup.py Updated italian localisation patch line in patches.txt --- .../doctype/sales_invoice/regional/italy.js | 3 ++ erpnext/patches.txt | 2 +- erpnext/regional/italy/e-invoice.xml | 10 ++++++- erpnext/regional/italy/sales_invoice.js | 19 +++++++++++++ erpnext/regional/italy/setup.py | 19 +++++++------ erpnext/regional/italy/utils.py | 28 ++++++++++++++++--- erpnext/startup/boot.py | 2 +- 7 files changed, 68 insertions(+), 15 deletions(-) create mode 100644 erpnext/accounts/doctype/sales_invoice/regional/italy.js create mode 100644 erpnext/regional/italy/sales_invoice.js diff --git a/erpnext/accounts/doctype/sales_invoice/regional/italy.js b/erpnext/accounts/doctype/sales_invoice/regional/italy.js new file mode 100644 index 0000000000..1c47d3ab9f --- /dev/null +++ b/erpnext/accounts/doctype/sales_invoice/regional/italy.js @@ -0,0 +1,3 @@ +{% include "erpnext/regional/italy/sales_invoice.js" %} + +erpnext.setup_e_invoice_button('Sales Invoice') \ No newline at end of file diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 1f104be112..433141cdf6 100755 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -587,4 +587,4 @@ erpnext.patches.v11_1.setup_guardian_role execute:frappe.delete_doc('DocType', 'Notification Control') erpnext.patches.v11_0.remove_barcodes_field_from_copy_fields_to_variants erpnext.patches.v10_0.item_barcode_childtable_migrate # 16-02-2019 -erpnext.patches.v11_0.make_italian_localization_fields # 26-02-2019 +erpnext.patches.v11_0.make_italian_localization_fields # 01-03-2019 diff --git a/erpnext/regional/italy/e-invoice.xml b/erpnext/regional/italy/e-invoice.xml index c0ef4af549..c886ee9aa8 100644 --- a/erpnext/regional/italy/e-invoice.xml +++ b/erpnext/regional/italy/e-invoice.xml @@ -199,7 +199,15 @@ {{ payment_term.mode_of_payment_code.split("-")[0] }} {{ payment_term.due_date }} {{ format_float(payment_term.payment_amount) }} - {%- if payment_term.bank_account_iban %}{{ payment_term.bank_account_iban }}{%- endif %} + {{ payment_term.bank_account_name }} + {%- if payment_term.bank_account_iban %} + {{ payment_term.bank_account_iban }} + {{ payment_term.bank_account_iban[5:10] }} + {{ payment_term.bank_account_iban[10:15] }} + {%- endif %} + {%- if payment_term.bank_account_swift_number %} + {{ payment_term.bank_account_swift_number }} + {%- endif %} {%- endfor %} diff --git a/erpnext/regional/italy/sales_invoice.js b/erpnext/regional/italy/sales_invoice.js new file mode 100644 index 0000000000..686b0f9d2c --- /dev/null +++ b/erpnext/regional/italy/sales_invoice.js @@ -0,0 +1,19 @@ +erpnext.setup_e_invoice_button = (doctype) => { + frappe.ui.form.on(doctype, { + refresh: (frm) => { + if(frm.doc.docstatus == 1) { + frm.add_custom_button('Generate E-Invoice', () => { + var w = window.open( + frappe.urllib.get_full_url( + "/api/method/erpnext.regional.italy.utils.generate_single_invoice?" + + "docname=" + frm.doc.name + ) + ) + if (!w) { + frappe.msgprint(__("Please enable pop-ups")); return; + } + }); + } + } + }); +}; diff --git a/erpnext/regional/italy/setup.py b/erpnext/regional/italy/setup.py index 1bbc7226a1..2b6e3af52a 100644 --- a/erpnext/regional/italy/setup.py +++ b/erpnext/regional/italy/setup.py @@ -32,12 +32,12 @@ def make_custom_fields(update=True): 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: x.decode('utf-8'), fiscal_regimes))), + 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: x.decode('utf-8'), vat_collectability_options))), + 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), @@ -57,7 +57,7 @@ def make_custom_fields(update=True): 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: x.decode('utf-8'), tax_exemption_reasons))), + 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') @@ -80,30 +80,33 @@ def make_custom_fields(update=True): '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: x.decode('utf-8'), mode_of_payment_codes))) + 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: x.decode('utf-8'), mode_of_payment_codes)), + 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 Account Name', + dict(fieldname='bank_account_name', label='Bank Name', fieldtype='Data', insert_after='bank_account', print_hide=1, - fetch_from="bank_account.account_name", read_only=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: x.decode('utf-8'), vat_collectability_options)), + 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='pos_total_qty', print_hide=1), diff --git a/erpnext/regional/italy/utils.py b/erpnext/regional/italy/utils.py index edf66d78a3..30280e20ad 100644 --- a/erpnext/regional/italy/utils.py +++ b/erpnext/regional/italy/utils.py @@ -252,15 +252,29 @@ def sales_invoice_on_submit(doc, method): prepare_and_attach_invoice(doc) -def prepare_and_attach_invoice(doc): - progressive_name, progressive_number = get_progressive_name_and_number(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) invoice_xml = frappe.render_template('erpnext/regional/italy/e-invoice.xml', context={"doc": invoice}, is_path=True) invoice_xml = invoice_xml.replace("&", "&") xml_filename = progressive_name + ".xml" - save_file(xml_filename, invoice_xml, dt=doc.doctype, dn=doc.name, is_private=True) + return save_file(xml_filename, invoice_xml, dt=doc.doctype, dn=doc.name, is_private=True) + +@frappe.whitelist() +def generate_single_invoice(docname): + doc = frappe.get_doc("Sales Invoice", docname) + + e_invoice = prepare_and_attach_invoice(doc, True) + + content = None + with open(frappe.get_site_path('private', 'files', e_invoice.file_name), "r") as f: + content = f.read() + + frappe.local.response.filename = e_invoice.file_name + frappe.local.response.filecontent = content + frappe.local.response.type = "download" #Delete e-invoice attachment on cancel. def sales_invoice_on_cancel(doc, method): @@ -305,7 +319,13 @@ def get_unamended_name(doc): else: return doc.name -def get_progressive_name_and_number(doc): +def get_progressive_name_and_number(doc, replace=False): + if replace: + for attachment in get_e_invoice_attachments(doc): + remove_file(attachment.name, attached_to_doctype=doc.doctype, attached_to_name=doc.name) + 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 progressive_name = frappe.model.naming.make_autoname(company_tax_id + "_.#####") progressive_number = progressive_name.split("_")[1] diff --git a/erpnext/startup/boot.py b/erpnext/startup/boot.py index 62c9e7b90c..8a164f9d13 100644 --- a/erpnext/startup/boot.py +++ b/erpnext/startup/boot.py @@ -33,7 +33,7 @@ def boot_session(bootinfo): tabCompany limit 1""") and 'Yes' or 'No' bootinfo.docs += frappe.db.sql("""select name, default_currency, cost_center, default_terms, - default_letter_head, default_bank_account, enable_perpetual_inventory from `tabCompany`""", + default_letter_head, default_bank_account, enable_perpetual_inventory, country from `tabCompany`""", as_dict=1, update={"doctype":":Company"}) party_account_types = frappe.db.sql(""" select name, ifnull(account_type, '') from `tabParty Type`""") From 6a4625b94ccaf0ad16854875caefa3c81baac4d6 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Fri, 1 Mar 2019 13:58:39 +0530 Subject: [PATCH 2/2] fix(regional,italy): codacy fixes in regional sales_invoice js --- erpnext/regional/italy/sales_invoice.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/erpnext/regional/italy/sales_invoice.js b/erpnext/regional/italy/sales_invoice.js index 686b0f9d2c..3457f7161e 100644 --- a/erpnext/regional/italy/sales_invoice.js +++ b/erpnext/regional/italy/sales_invoice.js @@ -3,15 +3,15 @@ erpnext.setup_e_invoice_button = (doctype) => { refresh: (frm) => { if(frm.doc.docstatus == 1) { frm.add_custom_button('Generate E-Invoice', () => { - var w = window.open( - frappe.urllib.get_full_url( - "/api/method/erpnext.regional.italy.utils.generate_single_invoice?" - + "docname=" + frm.doc.name - ) - ) - if (!w) { - frappe.msgprint(__("Please enable pop-ups")); return; - } + var w = window.open( + frappe.urllib.get_full_url( + "/api/method/erpnext.regional.italy.utils.generate_single_invoice?" + + "docname=" + frm.doc.name + ) + ) + if (!w) { + frappe.msgprint(__("Please enable pop-ups")); return; + } }); } }