diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 56b5daca9032..b812585c2a77 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,7 +20,8 @@ exclude: | (l10n_it_fatturapa/data/fatturaordinaria_v1.2.1.xsl)| (l10n_it_fatturapa/data/FoglioStileAssoSoftware_v1.1.xsl)| # XML tests should not be reformatted - ^l10n_it_fatturapa_out/tests/data + ^l10n_it_fatturapa_out/tests/data| + ^l10n_it_fatturapa_in/tests/data default_language_version: python: python3 node: "14.13.0" @@ -134,6 +135,7 @@ repos: args: - --rcfile=.pylintrc - --exit-zero + - --ignore=l10n_it_fatturapa_in/tests/data/ verbose: true additional_dependencies: &pylint_deps - pylint-odoo==3.5.0 @@ -141,4 +143,5 @@ repos: name: pylint with mandatory checks args: - --rcfile=.pylintrc-mandatory + - --ignore=l10n_it_fatturapa_in/tests/data/ additional_dependencies: *pylint_deps diff --git a/l10n_it_fatturapa_in/__init__.py b/l10n_it_fatturapa_in/__init__.py index 12a86766001a..0182fc47ed18 100644 --- a/l10n_it_fatturapa_in/__init__.py +++ b/l10n_it_fatturapa_in/__init__.py @@ -1,4 +1,3 @@ - from . import models from . import tests from . import wizard diff --git a/l10n_it_fatturapa_in/__manifest__.py b/l10n_it_fatturapa_in/__manifest__.py index 4cb79225af3c..6f8b249018bd 100644 --- a/l10n_it_fatturapa_in/__manifest__.py +++ b/l10n_it_fatturapa_in/__manifest__.py @@ -5,35 +5,29 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). { - 'name': 'ITA - Fattura elettronica - Ricezione', - 'version': '12.0.2.1.3', + "name": "ITA - Fattura elettronica - Ricezione", + "version": "12.0.2.1.3", "development_status": "Beta", - 'category': 'Localization/Italy', - 'summary': 'Ricezione fatture elettroniche', - 'author': 'Agile Business Group, Innoviu, ' - 'Odoo Community Association (OCA)', - 'website': 'https://github.com/OCA/l10n-italy/tree/12.0/' - 'l10n_it_fatturapa_in', - 'license': 'AGPL-3', + "category": "Localization/Italy", + "summary": "Ricezione fatture elettroniche", + "author": "Agile Business Group, Innoviu, " "Odoo Community Association (OCA)", + "website": "https://github.com/OCA/l10n-italy" "l10n_it_fatturapa_in", + "license": "AGPL-3", "depends": [ - 'l10n_it_fatturapa', - 'l10n_it_withholding_tax_causali', - ], + "l10n_it_fatturapa", + "l10n_it_withholding_tax_causali", + ], "data": [ - 'views/account_view.xml', - 'views/partner_view.xml', - 'wizard/wizard_import_fatturapa_view.xml', - 'wizard/link_to_existing_invoice.xml', - 'views/company_view.xml', - 'security/ir.model.access.csv', - 'security/rules.xml', + "views/account_view.xml", + "views/partner_view.xml", + "wizard/wizard_import_fatturapa_view.xml", + "wizard/link_to_existing_invoice.xml", + "views/company_view.xml", + "security/ir.model.access.csv", + "security/rules.xml", ], "installable": True, - 'external_dependencies': { - 'python': [ - 'elementpath', - 'xmlschema', - 'asn1crypto' - ], - } + "external_dependencies": { + "python": ["elementpath", "xmlschema", "asn1crypto"], + }, } diff --git a/l10n_it_fatturapa_in/migrations/12.0.1.15.0/post-migration.py b/l10n_it_fatturapa_in/migrations/12.0.1.15.0/post-migration.py index 58573b763ac1..d5df47ab78ed 100644 --- a/l10n_it_fatturapa_in/migrations/12.0.1.15.0/post-migration.py +++ b/l10n_it_fatturapa_in/migrations/12.0.1.15.0/post-migration.py @@ -1,4 +1,4 @@ -from odoo import api, SUPERUSER_ID +from odoo import SUPERUSER_ID, api def migrate(cr, version): @@ -6,7 +6,7 @@ def migrate(cr, version): return with api.Environment.manage(): env = api.Environment(cr, SUPERUSER_ID, {}) - invoices = env['account.invoice'].search([]) + invoices = env["account.invoice"].search([]) # in order to prevent error messages in old invoices, # where ftpa_withholding_amount is 0 for invoice in invoices: diff --git a/l10n_it_fatturapa_in/migrations/12.0.2.0.0/post-migration.py b/l10n_it_fatturapa_in/migrations/12.0.2.0.0/post-migration.py index 864774d86616..631822f92a7d 100644 --- a/l10n_it_fatturapa_in/migrations/12.0.2.0.0/post-migration.py +++ b/l10n_it_fatturapa_in/migrations/12.0.2.0.0/post-migration.py @@ -10,31 +10,37 @@ def create_withholding_data_lines(env): Create ftpa_withholding_ids from ftpa_withholding_type and ftpa_withholding_amount """ - column_wht_amount = openupgrade.get_legacy_name('ftpa_withholding_amount') - column_wht_type = openupgrade.get_legacy_name('ftpa_withholding_type') - exists = openupgrade.column_exists(env.cr, 'account_invoice', column_wht_amount) + column_wht_amount = openupgrade.get_legacy_name("ftpa_withholding_amount") + column_wht_type = openupgrade.get_legacy_name("ftpa_withholding_type") + exists = openupgrade.column_exists(env.cr, "account_invoice", column_wht_amount) mapping = { - 'name': 'ai.{ftpa_withholding_type}'.format( - ftpa_withholding_type=column_wht_type), - 'invoice_id': 'ai.id', - 'create_uid': 'ai.create_uid', - 'create_date': 'ai.create_date', - 'write_date': 'ai.write_date', - 'write_uid': 'ai.write_uid', + "name": "ai.{ftpa_withholding_type}".format( + ftpa_withholding_type=column_wht_type + ), + "invoice_id": "ai.id", + "create_uid": "ai.create_uid", + "create_date": "ai.create_date", + "write_date": "ai.write_date", + "write_uid": "ai.write_uid", } if exists: mapping.update( - {'amount': 'ai.{ftpa_withholding_amount}'.format( - ftpa_withholding_amount=column_wht_amount)}) + { + "amount": "ai.{ftpa_withholding_amount}".format( + ftpa_withholding_amount=column_wht_amount + ) + } + ) query = """ INSERT INTO withholding_data_line ({columns}) SELECT {values} FROM account_invoice AS ai WHERE ai.{ftpa_withholding_type} IS NOT NULL;""".format( - columns=','.join(mapping.keys()), - values=','.join(mapping.values()), - ftpa_withholding_type=column_wht_type) + columns=",".join(mapping.keys()), + values=",".join(mapping.values()), + ftpa_withholding_type=column_wht_type, + ) openupgrade.logged_query(env.cr, sql.SQL(query)) diff --git a/l10n_it_fatturapa_in/migrations/12.0.2.0.0/pre-migration.py b/l10n_it_fatturapa_in/migrations/12.0.2.0.0/pre-migration.py index 365897dc432c..a18e99f45f8a 100644 --- a/l10n_it_fatturapa_in/migrations/12.0.2.0.0/pre-migration.py +++ b/l10n_it_fatturapa_in/migrations/12.0.2.0.0/pre-migration.py @@ -5,14 +5,20 @@ @openupgrade.migrate() def migrate(env, version): cr = env.cr - if openupgrade.column_exists(env.cr, 'account_invoice', 'ftpa_withholding_amount'): - openupgrade.copy_columns(cr, { - 'account_invoice': [ - ('ftpa_withholding_amount', None, None), + if openupgrade.column_exists(env.cr, "account_invoice", "ftpa_withholding_amount"): + openupgrade.copy_columns( + cr, + { + "account_invoice": [ + ("ftpa_withholding_amount", None, None), + ], + }, + ) + openupgrade.copy_columns( + cr, + { + "account_invoice": [ + ("ftpa_withholding_type", None, None), ], - }) - openupgrade.copy_columns(cr, { - 'account_invoice': [ - ('ftpa_withholding_type', None, None), - ], - }) + }, + ) diff --git a/l10n_it_fatturapa_in/models/__init__.py b/l10n_it_fatturapa_in/models/__init__.py index d9de15be6c73..4eca7ddaf65a 100644 --- a/l10n_it_fatturapa_in/models/__init__.py +++ b/l10n_it_fatturapa_in/models/__init__.py @@ -1,4 +1,3 @@ - from . import attachment from . import account from . import partner diff --git a/l10n_it_fatturapa_in/models/account.py b/l10n_it_fatturapa_in/models/account.py index 350f92811955..e5a97431f61f 100644 --- a/l10n_it_fatturapa_in/models/account.py +++ b/l10n_it_fatturapa_in/models/account.py @@ -1,7 +1,7 @@ - -from odoo import fields, models, api, _ -from odoo.exceptions import ValidationError, UserError +from odoo import _, api, fields, models +from odoo.exceptions import UserError, ValidationError from odoo.tools import float_compare + import odoo.addons.decimal_precision as dp @@ -9,59 +9,70 @@ class AccountInvoice(models.Model): _inherit = "account.invoice" fatturapa_attachment_in_id = fields.Many2one( - 'fatturapa.attachment.in', 'E-bill Import File', - ondelete='restrict', copy=False) - inconsistencies = fields.Text('Import Inconsistencies', copy=False) + "fatturapa.attachment.in", "E-bill Import File", ondelete="restrict", copy=False + ) + inconsistencies = fields.Text("Import Inconsistencies", copy=False) e_invoice_line_ids = fields.One2many( - "einvoice.line", "invoice_id", string="Lines Detail", - readonly=True, copy=False) + "einvoice.line", "invoice_id", string="Lines Detail", readonly=True, copy=False + ) e_invoice_amount_untaxed = fields.Monetary( - string='E-Invoice Untaxed Amount', readonly=True) - e_invoice_amount_tax = fields.Monetary(string='E-Invoice Tax Amount', - readonly=True) - e_invoice_amount_total = fields.Monetary(string='E-Invoice Total Amount', - readonly=True) + string="E-Invoice Untaxed Amount", readonly=True + ) + e_invoice_amount_tax = fields.Monetary(string="E-Invoice Tax Amount", readonly=True) + e_invoice_amount_total = fields.Monetary( + string="E-Invoice Total Amount", readonly=True + ) e_invoice_reference = fields.Char( - string="E-invoice vendor reference", - readonly=True) + string="E-invoice vendor reference", readonly=True + ) - e_invoice_date_invoice = fields.Date( - string="E-invoice date", - readonly=True) + e_invoice_date_invoice = fields.Date(string="E-invoice date", readonly=True) e_invoice_validation_error = fields.Boolean( - compute='_compute_e_invoice_validation_error') + compute="_compute_e_invoice_validation_error" + ) e_invoice_validation_message = fields.Text( - compute='_compute_e_invoice_validation_error') + compute="_compute_e_invoice_validation_error" + ) - e_invoice_force_validation = fields.Boolean( - string='Force E-Invoice Validation') + e_invoice_force_validation = fields.Boolean(string="Force E-Invoice Validation") - e_invoice_received_date = fields.Date( - string='E-Bill Received Date') + e_invoice_received_date = fields.Date(string="E-Bill Received Date") @api.multi - @api.depends('invoice_line_ids.price_subtotal', 'tax_line_ids.amount', - 'tax_line_ids.amount_rounding', 'currency_id', 'company_id', - 'date_invoice', 'type', 'efatt_rounding') + @api.depends( + "invoice_line_ids.price_subtotal", + "tax_line_ids.amount", + "tax_line_ids.amount_rounding", + "currency_id", + "company_id", + "date_invoice", + "type", + "efatt_rounding", + ) def _compute_amount(self): super(AccountInvoice, self)._compute_amount() for inv in self: if inv.efatt_rounding != 0: inv.amount_total += inv.efatt_rounding amount_total_company_signed = inv.amount_total - if inv.currency_id and inv.company_id and \ - inv.currency_id != inv.company_id.currency_id: + if ( + inv.currency_id + and inv.company_id + and inv.currency_id != inv.company_id.currency_id + ): currency_id = inv.currency_id amount_total_company_signed = currency_id._convert( - inv.amount_total, inv.company_id.currency_id, - inv.company_id, inv.date_invoice or fields.Date.today()) - sign = inv.type in ['in_refund', 'out_refund'] and -1 or 1 - inv.amount_total_company_signed = \ - amount_total_company_signed * sign + inv.amount_total, + inv.company_id.currency_id, + inv.company_id, + inv.date_invoice or fields.Date.today(), + ) + sign = inv.type in ["in_refund", "out_refund"] and -1 or 1 + inv.amount_total_company_signed = amount_total_company_signed * sign inv.amount_total_signed = inv.amount_total * sign @api.model @@ -71,124 +82,155 @@ def invoice_line_move_line_get(self): if self.efatt_rounding != 0: if self.efatt_rounding > 0: - arrotondamenti_account_id = self.env.user.company_id.\ - arrotondamenti_passivi_account_id + arrotondamenti_account_id = ( + self.env.user.company_id.arrotondamenti_passivi_account_id + ) if not arrotondamenti_account_id: - raise UserError(_("Round down account is not set " - "in Accounting Settings")) + raise UserError( + _("Round down account is not set " "in Accounting Settings") + ) name = _("Rounding down") else: - arrotondamenti_account_id = self.env.user.company_id.\ - arrotondamenti_attivi_account_id + arrotondamenti_account_id = ( + self.env.user.company_id.arrotondamenti_attivi_account_id + ) if not arrotondamenti_account_id: - raise UserError(_("Round up account is not set " - "in Accounting Settings")) + raise UserError( + _("Round up account is not set " "in Accounting Settings") + ) name = _("Rounding up") - res.append({ - 'type': 'global_rounding', - 'name': name, - 'price_unit': self.efatt_rounding, - 'quantity': 1, - 'price': self.efatt_rounding, - 'account_id': arrotondamenti_account_id.id, - 'invoice_id': self.id, - }) + res.append( + { + "type": "global_rounding", + "name": name, + "price_unit": self.efatt_rounding, + "quantity": 1, + "price": self.efatt_rounding, + "account_id": arrotondamenti_account_id.id, + "invoice_id": self.id, + } + ) return res @api.multi def invoice_validate(self): for invoice in self: - if (invoice.e_invoice_validation_error and - not invoice.e_invoice_force_validation): + if ( + invoice.e_invoice_validation_error + and not invoice.e_invoice_force_validation + ): raise ValidationError( - _("The invoice '%s' doesn't match the related e-invoice") % - invoice.display_name) + _("The invoice '%s' doesn't match the related e-invoice") + % invoice.display_name + ) return super(AccountInvoice, self).invoice_validate() def e_inv_check_amount_untaxed(self): - error_message = '' - if (self.e_invoice_amount_untaxed and - float_compare(self.amount_untaxed, - # Using abs because odoo invoice total can't be negative, - # while XML total can. - # See process_negative_lines method - abs(self.e_invoice_amount_untaxed), - precision_rounding=self.currency_id - .rounding) != 0): - error_message = ( - _("Untaxed amount ({bill_amount_untaxed}) " - "does not match with " - "e-bill untaxed amount ({e_bill_amount_untaxed})") - .format( - bill_amount_untaxed=self.amount_untaxed or 0, - e_bill_amount_untaxed=self.e_invoice_amount_untaxed - )) + error_message = "" + if ( + self.e_invoice_amount_untaxed + and float_compare( + self.amount_untaxed, + # Using abs because odoo invoice total can't be negative, + # while XML total can. + # See process_negative_lines method + abs(self.e_invoice_amount_untaxed), + precision_rounding=self.currency_id.rounding, + ) + != 0 + ): + error_message = _( + "Untaxed amount ({bill_amount_untaxed}) " + "does not match with " + "e-bill untaxed amount ({e_bill_amount_untaxed})" + ).format( + bill_amount_untaxed=self.amount_untaxed or 0, + e_bill_amount_untaxed=self.e_invoice_amount_untaxed, + ) return error_message def e_inv_check_amount_tax(self): - error_message = '' - if (self.e_invoice_amount_tax and - float_compare(self.amount_tax, - abs(self.e_invoice_amount_tax), - precision_rounding=self.currency_id - .rounding) != 0): - error_message = ( - _("Taxed amount ({bill_amount_tax}) " - "does not match with " - "e-bill taxed amount ({e_bill_amount_tax})") - .format( - bill_amount_tax=self.amount_tax or 0, - e_bill_amount_tax=self.e_invoice_amount_tax - )) + error_message = "" + if ( + self.e_invoice_amount_tax + and float_compare( + self.amount_tax, + abs(self.e_invoice_amount_tax), + precision_rounding=self.currency_id.rounding, + ) + != 0 + ): + error_message = _( + "Taxed amount ({bill_amount_tax}) " + "does not match with " + "e-bill taxed amount ({e_bill_amount_tax})" + ).format( + bill_amount_tax=self.amount_tax or 0, + e_bill_amount_tax=self.e_invoice_amount_tax, + ) return error_message def e_inv_check_amount_total(self): - error_message = '' - if (self.e_invoice_amount_total and - float_compare(self.amount_total, - abs(self.e_invoice_amount_total), - precision_rounding=self.currency_id - .rounding) != 0): - error_message = ( - _("Total amount ({bill_amount_total}) " - "does not match with " - "e-bill total amount ({e_bill_amount_total})") - .format( - bill_amount_total=self.amount_total or 0, - e_bill_amount_total=self.e_invoice_amount_total - )) + error_message = "" + if ( + self.e_invoice_amount_total + and float_compare( + self.amount_total, + abs(self.e_invoice_amount_total), + precision_rounding=self.currency_id.rounding, + ) + != 0 + ): + error_message = _( + "Total amount ({bill_amount_total}) " + "does not match with " + "e-bill total amount ({e_bill_amount_total})" + ).format( + bill_amount_total=self.amount_total or 0, + e_bill_amount_total=self.e_invoice_amount_total, + ) return error_message def e_inv_dati_ritenuta(self): - error_message = '' + error_message = "" # ftpa_withholding_type is set when DatiRitenuta is set, # withholding_tax is not set if no lines with Ritenuta = SI are found if self.ftpa_withholding_ids and not self.withholding_tax: - error_message += (_( + error_message += _( "E-bill contains DatiRitenuta but no lines subjected to Ritenuta was " "found. Please manually check Withholding tax Amount\n" - )) - if sum(self.ftpa_withholding_ids.mapped('amount'))\ - != self.withholding_tax_amount: - error_message += (_( + ) + if ( + sum(self.ftpa_withholding_ids.mapped("amount")) + != self.withholding_tax_amount + ): + error_message += _( "E-bill contains ImportoRitenuta %s but created invoice has got" - " %s\n" % ( - sum(self.ftpa_withholding_ids.mapped('amount')), - self.withholding_tax_amount + " %s\n" + % ( + sum(self.ftpa_withholding_ids.mapped("amount")), + self.withholding_tax_amount, ) - )) + ) return error_message - @api.depends('type', 'state', 'fatturapa_attachment_in_id', - 'amount_untaxed', 'amount_tax', 'amount_total', - 'reference', 'date_invoice') + @api.depends( + "type", + "state", + "fatturapa_attachment_in_id", + "amount_untaxed", + "amount_tax", + "amount_total", + "reference", + "date_invoice", + ) def _compute_e_invoice_validation_error(self): bills_to_check = self.filtered( - lambda inv: - inv.type in ['in_invoice', 'in_refund'] and - inv.state in ['draft', 'open', 'paid'] and - inv.fatturapa_attachment_in_id) + lambda inv: inv.type in ["in_invoice", "in_refund"] + and inv.state in ["draft", "open", "paid"] + and inv.fatturapa_attachment_in_id + ) for bill in bills_to_check: error_messages = list() @@ -208,33 +250,37 @@ def _compute_e_invoice_validation_error(self): if error_message: error_messages.append(error_message) - if (bill.e_invoice_reference and - bill.reference != bill.e_invoice_reference): + if bill.e_invoice_reference and bill.reference != bill.e_invoice_reference: error_messages.append( - _("Vendor reference ({bill_vendor_ref}) " - "does not match with " - "e-bill vendor reference ({e_bill_vendor_ref})") - .format( + _( + "Vendor reference ({bill_vendor_ref}) " + "does not match with " + "e-bill vendor reference ({e_bill_vendor_ref})" + ).format( bill_vendor_ref=bill.reference or "", - e_bill_vendor_ref=bill.e_invoice_reference - )) + e_bill_vendor_ref=bill.e_invoice_reference, + ) + ) - if (bill.e_invoice_date_invoice and - bill.e_invoice_date_invoice != bill.date_invoice): + if ( + bill.e_invoice_date_invoice + and bill.e_invoice_date_invoice != bill.date_invoice + ): error_messages.append( - _("Invoice date ({bill_date_invoice}) " - "does not match with " - "e-bill invoice date ({e_bill_date_invoice})") - .format( + _( + "Invoice date ({bill_date_invoice}) " + "does not match with " + "e-bill invoice date ({e_bill_date_invoice})" + ).format( bill_date_invoice=bill.date_invoice or "", - e_bill_date_invoice=bill.e_invoice_date_invoice - )) + e_bill_date_invoice=bill.e_invoice_date_invoice, + ) + ) if not error_messages: continue bill.e_invoice_validation_error = True - bill.e_invoice_validation_message = \ - ",\n".join(error_messages) + "." + bill.e_invoice_validation_message = ",\n".join(error_messages) + "." @api.multi def name_get(self): @@ -242,14 +288,15 @@ def name_get(self): res = [] for tup in result: invoice = self.browse(tup[0]) - if invoice.type in ('in_invoice', 'in_refund'): - name = "%s, %s" % (tup[1], invoice.partner_id.name) + if invoice.type in ("in_invoice", "in_refund"): + name = "{}, {}".format(tup[1], invoice.partner_id.name) if invoice.amount_total_signed: - name += ', %s %s' % ( - invoice.amount_total_signed, invoice.currency_id.symbol + name += ", {} {}".format( + invoice.amount_total_signed, + invoice.currency_id.symbol, ) if invoice.origin: - name += ', %s' % invoice.origin + name += ", %s" % invoice.origin res.append((invoice.id, name)) else: res.append(tup) @@ -259,7 +306,7 @@ def name_get(self): def remove_attachment_link(self): self.ensure_one() self.fatturapa_attachment_in_id = False - return {'type': 'ir.actions.client', 'tag': 'reload'} + return {"type": "ir.actions.client", "tag": "reload"} @api.model def compute_xml_amount_untaxed(self, FatturaBody): @@ -271,8 +318,8 @@ def compute_xml_amount_untaxed(self, FatturaBody): @api.model def compute_xml_amount_total(self, FatturaBody, amount_untaxed, amount_tax): rounding = float( - FatturaBody.DatiGenerali.DatiGeneraliDocumento.Arrotondamento - or 0.0) + FatturaBody.DatiGenerali.DatiGeneraliDocumento.Arrotondamento or 0.0 + ) return amount_untaxed + amount_tax + rounding @api.model @@ -285,21 +332,24 @@ def compute_xml_amount_tax(self, DatiRiepilogo): def set_einvoice_data(self, fattura): self.ensure_one() amount_untaxed = self.compute_xml_amount_untaxed(fattura) - amount_tax = self.compute_xml_amount_tax( - fattura.DatiBeniServizi.DatiRiepilogo) + amount_tax = self.compute_xml_amount_tax(fattura.DatiBeniServizi.DatiRiepilogo) amount_total = self.compute_xml_amount_total( - fattura, amount_untaxed, amount_tax) + fattura, amount_untaxed, amount_tax + ) reference = fattura.DatiGenerali.DatiGeneraliDocumento.Numero date_invoice = fields.Date.from_string( - fattura.DatiGenerali.DatiGeneraliDocumento.Data) - - self.update({ - 'e_invoice_amount_untaxed': amount_untaxed, - 'e_invoice_amount_tax': amount_tax, - 'e_invoice_amount_total': amount_total, - 'e_invoice_reference': reference, - 'e_invoice_date_invoice': date_invoice, - }) + fattura.DatiGenerali.DatiGeneraliDocumento.Data + ) + + self.update( + { + "e_invoice_amount_untaxed": amount_untaxed, + "e_invoice_amount_tax": amount_tax, + "e_invoice_amount_total": amount_total, + "e_invoice_reference": reference, + "e_invoice_date_invoice": date_invoice, + } + ) def process_negative_lines(self): self.ensure_one() @@ -315,12 +365,12 @@ def process_negative_lines(self): class FatturapaArticleCode(models.Model): # _position = ['2.2.1.3'] _name = "fatturapa.article.code" - _description = 'E-bill Article Code' + _description = "E-bill Article Code" - name = fields.Char('Code Type') - code_val = fields.Char('Code Value') + name = fields.Char("Code Type") + code_val = fields.Char("Code Value") e_invoice_line_id = fields.Many2one( - 'einvoice.line', 'Related E-bill Line', readonly=True + "einvoice.line", "Related E-bill Line", readonly=True ) @@ -332,43 +382,46 @@ class AccountInvoiceLine(models.Model): _inherit = "account.invoice.line" fatturapa_attachment_in_id = fields.Many2one( - 'fatturapa.attachment.in', 'E-bill Import File', - readonly=True, related='invoice_id.fatturapa_attachment_in_id') + "fatturapa.attachment.in", + "E-bill Import File", + readonly=True, + related="invoice_id.fatturapa_attachment_in_id", + ) class DiscountRisePrice(models.Model): _inherit = "discount.rise.price" e_invoice_line_id = fields.Many2one( - 'einvoice.line', 'Related E-bill Line', readonly=True + "einvoice.line", "Related E-bill Line", readonly=True ) class EInvoiceLine(models.Model): - _name = 'einvoice.line' - _description = 'E-invoice line' + _name = "einvoice.line" + _description = "E-invoice line" invoice_id = fields.Many2one( - "account.invoice", "Bill", readonly=True, ondelete='cascade') - line_number = fields.Integer('Line Number', readonly=True) - service_type = fields.Char('Sale Provision Type', readonly=True) + "account.invoice", "Bill", readonly=True, ondelete="cascade" + ) + line_number = fields.Integer("Line Number", readonly=True) + service_type = fields.Char("Sale Provision Type", readonly=True) cod_article_ids = fields.One2many( - 'fatturapa.article.code', 'e_invoice_line_id', - 'Articles Code', readonly=True + "fatturapa.article.code", "e_invoice_line_id", "Articles Code", readonly=True ) name = fields.Char("Description", readonly=True) qty = fields.Float( - "Quantity", readonly=True, - digits=dp.get_precision('Product Unit of Measure') + "Quantity", readonly=True, digits=dp.get_precision("Product Unit of Measure") ) uom = fields.Char("Unit of measure", readonly=True) period_start_date = fields.Date("Period Start Date", readonly=True) period_end_date = fields.Date("Period End Date", readonly=True) unit_price = fields.Float( - "Unit Price", readonly=True, - digits=dp.get_precision('Product Price') + "Unit Price", readonly=True, digits=dp.get_precision("Product Price") ) discount_rise_price_ids = fields.One2many( - 'discount.rise.price', 'e_invoice_line_id', - 'Discount and Supplement Details', readonly=True + "discount.rise.price", + "e_invoice_line_id", + "Discount and Supplement Details", + readonly=True, ) total_price = fields.Float("Total Price", readonly=True) tax_amount = fields.Float("VAT Rate", readonly=True) @@ -376,16 +429,19 @@ class EInvoiceLine(models.Model): tax_kind = fields.Char("Nature", readonly=True) admin_ref = fields.Char("Administration Reference", readonly=True) other_data_ids = fields.One2many( - "einvoice.line.other.data", "e_invoice_line_id", - string="Other Administrative Data", readonly=True) + "einvoice.line.other.data", + "e_invoice_line_id", + string="Other Administrative Data", + readonly=True, + ) class EInvoiceLineOtherData(models.Model): - _name = 'einvoice.line.other.data' - _description = 'E-invoice line other data' + _name = "einvoice.line.other.data" + _description = "E-invoice line other data" e_invoice_line_id = fields.Many2one( - 'einvoice.line', 'Related E-bill Line', readonly=True + "einvoice.line", "Related E-bill Line", readonly=True ) name = fields.Char("Data Type", readonly=True) text_ref = fields.Char("Text Reference", readonly=True) diff --git a/l10n_it_fatturapa_in/models/attachment.py b/l10n_it_fatturapa_in/models/attachment.py index 2751c788f4ee..0125d3bf6f18 100644 --- a/l10n_it_fatturapa_in/models/attachment.py +++ b/l10n_it_fatturapa_in/models/attachment.py @@ -1,54 +1,65 @@ - import base64 -from odoo import fields, models, api, _ + +from odoo import _, api, fields, models from odoo.tools import format_date class FatturaPAAttachmentIn(models.Model): _name = "fatturapa.attachment.in" _description = "E-bill import file" - _inherits = {'ir.attachment': 'ir_attachment_id'} - _inherit = ['mail.thread'] - _order = 'id desc' + _inherits = {"ir.attachment": "ir_attachment_id"} + _inherit = ["mail.thread"] + _order = "id desc" ir_attachment_id = fields.Many2one( - 'ir.attachment', 'Attachment', required=True, ondelete="cascade") + "ir.attachment", "Attachment", required=True, ondelete="cascade" + ) att_name = fields.Char( - string="E-bill file name", - related='ir_attachment_id.name', - store=True) + string="E-bill file name", related="ir_attachment_id.name", store=True + ) in_invoice_ids = fields.One2many( - 'account.invoice', 'fatturapa_attachment_in_id', - string="In Bills", readonly=True) + "account.invoice", + "fatturapa_attachment_in_id", + string="In Bills", + readonly=True, + ) xml_supplier_id = fields.Many2one( - "res.partner", string="Supplier", compute="_compute_xml_data", - store=True) + "res.partner", string="Supplier", compute="_compute_xml_data", store=True + ) invoices_number = fields.Integer( - "Bills Number", compute="_compute_xml_data", store=True) + "Bills Number", compute="_compute_xml_data", store=True + ) invoices_total = fields.Float( - "Bills Total", compute="_compute_xml_data", store=True, + "Bills Total", + compute="_compute_xml_data", + store=True, help="If specified by supplier, total amount of the document net of " - "any discount and including tax charged to the buyer/ordered" + "any discount and including tax charged to the buyer/ordered", ) invoices_date = fields.Char( - string="Invoices date", compute="_compute_xml_data", store=True) - registered = fields.Boolean( - "Registered", compute="_compute_registered", store=True) + string="Invoices date", compute="_compute_xml_data", store=True + ) + registered = fields.Boolean("Registered", compute="_compute_registered", store=True) - e_invoice_received_date = fields.Datetime(string='E-Bill Received Date') + e_invoice_received_date = fields.Datetime(string="E-Bill Received Date") e_invoice_validation_error = fields.Boolean( - compute='_compute_e_invoice_validation_error') + compute="_compute_e_invoice_validation_error" + ) e_invoice_validation_message = fields.Text( - compute='_compute_e_invoice_validation_error') + compute="_compute_e_invoice_validation_error" + ) - _sql_constraints = [( - 'ftpa_attachment_in_name_uniq', - 'unique(att_name)', - 'The name of the e-bill file must be unique!')] + _sql_constraints = [ + ( + "ftpa_attachment_in_name_uniq", + "unique(att_name)", + "The name of the e-bill file must be unique!", + ) + ] - @api.depends('in_invoice_ids.e_invoice_validation_error') + @api.depends("in_invoice_ids.e_invoice_validation_error") def _compute_e_invoice_validation_error(self): for att in self: bills_with_error = att.in_invoice_ids.filtered( @@ -62,11 +73,12 @@ def _compute_e_invoice_validation_error(self): for bill in bills_with_error: error_messages.append( errors_message_template.format( - bill=bill.display_name, - errors=bill.e_invoice_validation_message)) + bill=bill.display_name, errors=bill.e_invoice_validation_message + ) + ) att.e_invoice_validation_message = "\n\n".join(error_messages) - @api.onchange('datas_fname') + @api.onchange("datas_fname") def onchagne_datas_fname(self): self.name = self.datas_fname @@ -74,11 +86,12 @@ def get_xml_string(self): return self.ir_attachment_id.get_xml_string() @api.multi - @api.depends('ir_attachment_id.datas') + @api.depends("ir_attachment_id.datas") def _compute_xml_data(self): for att in self: - wiz_obj = self.env['wizard.import.fatturapa'] \ - .with_context(from_attachment=att) + wiz_obj = self.env["wizard.import.fatturapa"].with_context( + from_attachment=att + ) fatt = wiz_obj.get_invoice_obj(att) cedentePrestatore = fatt.FatturaElettronicaHeader.CedentePrestatore partner_id = wiz_obj.getCedPrest(cedentePrestatore) @@ -87,32 +100,29 @@ def _compute_xml_data(self): att.invoices_total = 0 invoices_date = [] for invoice_body in fatt.FatturaElettronicaBody: - att.invoices_total += float( - invoice_body.DatiGenerali.DatiGeneraliDocumento. - ImportoTotaleDocumento or 0 - ) + dgd = invoice_body.DatiGenerali.DatiGeneraliDocumento + att.invoices_total += float(dgd.ImportoTotaleDocumento or 0) invoice_date = format_date( - att.with_context( - lang=att.env.user.lang).env, fields.Date.from_string( - invoice_body.DatiGenerali.DatiGeneraliDocumento.Data)) + att.with_context(lang=att.env.user.lang).env, + fields.Date.from_string( + dgd.DatiGenerali.DatiGeneraliDocumento.Data + ), + ) if invoice_date not in invoices_date: invoices_date.append(invoice_date) - att.invoices_date = ' '.join(invoices_date) + att.invoices_date = " ".join(invoices_date) @api.multi - @api.depends('in_invoice_ids') + @api.depends("in_invoice_ids") def _compute_registered(self): for att in self: - if ( - att.in_invoice_ids and - len(att.in_invoice_ids) == att.invoices_number - ): + if att.in_invoice_ids and len(att.in_invoice_ids) == att.invoices_number: att.registered = True else: att.registered = False def extract_attachments(self, AttachmentsData, invoice_id): - AttachModel = self.env['fatturapa.attachments'] + AttachModel = self.env["fatturapa.attachments"] for attach in AttachmentsData: if not attach.NomeAttachment: name = _("Attachment without name") @@ -120,12 +130,12 @@ def extract_attachments(self, AttachmentsData, invoice_id): name = attach.NomeAttachment content = attach.Attachment.encode() _attach_dict = { - 'name': name, - 'datas': base64.b64encode(content), - 'datas_fname': name, - 'description': attach.DescrizioneAttachment or '', - 'compression': attach.AlgoritmoCompressione or '', - 'format': attach.FormatoAttachment or '', - 'invoice_id': invoice_id, + "name": name, + "datas": base64.b64encode(content), + "datas_fname": name, + "description": attach.DescrizioneAttachment or "", + "compression": attach.AlgoritmoCompressione or "", + "format": attach.FormatoAttachment or "", + "invoice_id": invoice_id, } AttachModel.create(_attach_dict) diff --git a/l10n_it_fatturapa_in/models/company.py b/l10n_it_fatturapa_in/models/company.py index 5054eee3075c..a25218af7459 100644 --- a/l10n_it_fatturapa_in/models/company.py +++ b/l10n_it_fatturapa_in/models/company.py @@ -1,65 +1,66 @@ - from odoo import fields, models class ResCompany(models.Model): - _inherit = 'res.company' + _inherit = "res.company" cassa_previdenziale_product_id = fields.Many2one( - 'product.product', 'Welfare Fund Data Product', - help="Product used to model DatiCassaPrevidenziale XML element " - "on bills." + "product.product", + "Welfare Fund Data Product", + help="Product used to model DatiCassaPrevidenziale XML element " "on bills.", ) sconto_maggiorazione_product_id = fields.Many2one( - 'product.product', 'Discount Supplement Product', - help="Product used to model ScontoMaggiorazione XML element on bills." + "product.product", + "Discount Supplement Product", + help="Product used to model ScontoMaggiorazione XML element on bills.", ) arrotondamenti_attivi_account_id = fields.Many2one( - 'account.account', 'Round Up Account', - domain=[('deprecated', '=', False)], - help="Account used to round up bills amount." + "account.account", + "Round Up Account", + domain=[("deprecated", "=", False)], + help="Account used to round up bills amount.", ) arrotondamenti_passivi_account_id = fields.Many2one( - 'account.account', 'Round Down Account', - domain=[('deprecated', '=', False)], - help="Account used to round down bills amount." + "account.account", + "Round Down Account", + domain=[("deprecated", "=", False)], + help="Account used to round down bills amount.", ) arrotondamenti_tax_id = fields.Many2one( - 'account.tax', 'Rounding Tax', - domain=[('type_tax_use', '=', 'purchase'), ('amount', '=', 0.0)], - help="Tax used to both round up and down bills amount." + "account.tax", + "Rounding Tax", + domain=[("type_tax_use", "=", "purchase"), ("amount", "=", 0.0)], + help="Tax used to both round up and down bills amount.", + ) + in_invoice_registration_date = fields.Selection( + [ + ("inv_date", "Invoice Date"), + ("rec_date", "Received Date"), + ], + string="Vendor invoice registration default date", + default="inv_date", ) - in_invoice_registration_date = fields.Selection([ - ('inv_date', 'Invoice Date'), - ('rec_date', 'Received Date'), - ], string='Vendor invoice registration default date', - default='inv_date') class AccountConfigSettings(models.TransientModel): - _inherit = 'res.config.settings' + _inherit = "res.config.settings" cassa_previdenziale_product_id = fields.Many2one( - related='company_id.cassa_previdenziale_product_id', - readonly=False + related="company_id.cassa_previdenziale_product_id", readonly=False ) sconto_maggiorazione_product_id = fields.Many2one( - related='company_id.sconto_maggiorazione_product_id', - readonly=False + related="company_id.sconto_maggiorazione_product_id", readonly=False ) arrotondamenti_attivi_account_id = fields.Many2one( - related='company_id.arrotondamenti_attivi_account_id', - readonly=False + related="company_id.arrotondamenti_attivi_account_id", readonly=False ) arrotondamenti_passivi_account_id = fields.Many2one( - related='company_id.arrotondamenti_passivi_account_id', - readonly=False + related="company_id.arrotondamenti_passivi_account_id", readonly=False ) arrotondamenti_tax_id = fields.Many2one( - related='company_id.arrotondamenti_tax_id', - readonly=False + related="company_id.arrotondamenti_tax_id", readonly=False ) in_invoice_registration_date = fields.Selection( - related='company_id.in_invoice_registration_date', readonly=False + related="company_id.in_invoice_registration_date", readonly=False ) diff --git a/l10n_it_fatturapa_in/models/partner.py b/l10n_it_fatturapa_in/models/partner.py index 96bbd6c5487b..a5912f0ec657 100644 --- a/l10n_it_fatturapa_in/models/partner.py +++ b/l10n_it_fatturapa_in/models/partner.py @@ -1,28 +1,30 @@ - -from odoo import models, fields +from odoo import fields, models class Partner(models.Model): - _inherit = 'res.partner' + _inherit = "res.partner" e_invoice_default_product_id = fields.Many2one( - comodel_name='product.product', - string='E-bill Default Product', + comodel_name="product.product", + string="E-bill Default Product", help="Used by electronic invoice XML import. " - "If filled in, generated bill lines will use this product when " - "no other possible product is found." + "If filled in, generated bill lines will use this product when " + "no other possible product is found.", ) - e_invoice_detail_level = fields.Selection([ - ('0', 'Minimum'), - ('1', 'Tax Rate'), - ('2', 'Maximum'), - ], string="E-bills Detail Level", + e_invoice_detail_level = fields.Selection( + [ + ("0", "Minimum"), + ("1", "Tax Rate"), + ("2", "Maximum"), + ], + string="E-bills Detail Level", help="Minimum level: Bill is created with no lines; " - "User will have to create them, according to what specified in " - "the electronic bill.\n" - "Tax rate level: Rate level: an invoice line is created for each " - "rate present in the electronic invoice\n" - "Maximum level: every line contained in the electronic bill " - "will create a line in the bill.", - default='2', required=True + "User will have to create them, according to what specified in " + "the electronic bill.\n" + "Tax rate level: Rate level: an invoice line is created for each " + "rate present in the electronic invoice\n" + "Maximum level: every line contained in the electronic bill " + "will create a line in the bill.", + default="2", + required=True, ) diff --git a/l10n_it_fatturapa_in/readme/CONFIGURE.rst b/l10n_it_fatturapa_in/readme/CONFIGURE.rst index 0aa2fce20989..2b412e5a29de 100644 --- a/l10n_it_fatturapa_in/readme/CONFIGURE.rst +++ b/l10n_it_fatturapa_in/readme/CONFIGURE.rst @@ -21,7 +21,7 @@ See also the README file of l10n_it_fatturapa module. For every supplier, it is possible to set the 'E-bills Detail Level': - - Minimum level: Bill is created with no lines; User will have to create them, according to what specified in the electronic bill + - Minimum level: Bill is created with no lines; User will have to create them, according to what specified in the electronic bill - Maximum level: Every line contained in electronic bill will create a line in bill Moreover, in supplier form you can set the 'E-bill Default Product': this product will be used, during generation of bills, when no other possible product is found. Tax and account of bill line will be set according to what configured in the product. diff --git a/l10n_it_fatturapa_in/security/rules.xml b/l10n_it_fatturapa_in/security/rules.xml index d4ee92bb4934..6d4bc882d501 100644 --- a/l10n_it_fatturapa_in/security/rules.xml +++ b/l10n_it_fatturapa_in/security/rules.xml @@ -1,11 +1,15 @@ - + - Fatturapa in fatturapa_in_multi_company_rule multi company rule - - - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + Fatturapa in fatturapa_in_multi_company_rule multi company rule + + + ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] diff --git a/l10n_it_fatturapa_in/tests/__init__.py b/l10n_it_fatturapa_in/tests/__init__.py index 3c7d2e8e2e7a..04aa630c98ef 100644 --- a/l10n_it_fatturapa_in/tests/__init__.py +++ b/l10n_it_fatturapa_in/tests/__init__.py @@ -1,3 +1,2 @@ - from . import fatturapa_common from . import test_import_fatturapa_xml diff --git a/l10n_it_fatturapa_in/tests/fatturapa_common.py b/l10n_it_fatturapa_in/tests/fatturapa_common.py index fccf324eecf1..74a5a2a5bf08 100644 --- a/l10n_it_fatturapa_in/tests/fatturapa_common.py +++ b/l10n_it_fatturapa_in/tests/fatturapa_common.py @@ -1,179 +1,231 @@ import base64 import tempfile + from odoo.modules import get_module_resource from odoo.tests.common import SingleTransactionCase class FatturapaCommon(SingleTransactionCase): - def getFile(self, filename, module_name=None): if module_name is None: - module_name = 'l10n_it_fatturapa_in' - path = get_module_resource(module_name, 'tests', 'data', filename) - with open(path, 'rb') as test_data: + module_name = "l10n_it_fatturapa_in" + path = get_module_resource(module_name, "tests", "data", filename) + with open(path, "rb") as test_data: with tempfile.TemporaryFile() as out: base64.encode(test_data, out) out.seek(0) return path, out.read() def create_wt(self): - return self.env['withholding.tax'].create({ - 'name': '1040', - 'code': '1040', - 'account_receivable_id': self.payable_account_id, - 'account_payable_id': self.payable_account_id, - 'payment_term': self.env.ref('account.account_payment_term').id, - 'rate_ids': [(0, 0, {'tax': 20.0})], - 'causale_pagamento_id': - self.env.ref('l10n_it_causali_pagamento.a').id, - }) + return self.env["withholding.tax"].create( + { + "name": "1040", + "code": "1040", + "account_receivable_id": self.payable_account_id, + "account_payable_id": self.payable_account_id, + "payment_term": self.env.ref("account.account_payment_term").id, + "rate_ids": [(0, 0, {"tax": 20.0})], + "causale_pagamento_id": self.env.ref("l10n_it_causali_pagamento.a").id, + } + ) def create_wt_23_20(self): - return self.env['withholding.tax'].create({ - 'name': '2320', - 'code': '2320', - 'account_receivable_id': self.payable_account_id, - 'account_payable_id': self.payable_account_id, - 'payment_term': self.env.ref('account.account_payment_term').id, - 'rate_ids': [(0, 0, {'tax': 23.0, 'base': 0.2})], - 'causale_pagamento_id': - self.env.ref('l10n_it_causali_pagamento.a').id, - }) + return self.env["withholding.tax"].create( + { + "name": "2320", + "code": "2320", + "account_receivable_id": self.payable_account_id, + "account_payable_id": self.payable_account_id, + "payment_term": self.env.ref("account.account_payment_term").id, + "rate_ids": [(0, 0, {"tax": 23.0, "base": 0.2})], + "causale_pagamento_id": self.env.ref("l10n_it_causali_pagamento.a").id, + } + ) def create_wt_23_50(self): - return self.env['withholding.tax'].create({ - 'name': '2320', - 'code': '2320', - 'account_receivable_id': self.payable_account_id, - 'account_payable_id': self.payable_account_id, - 'payment_term': self.env.ref('account.account_payment_term').id, - 'rate_ids': [(0, 0, {'tax': 23.0, 'base': 0.5})], - 'causale_pagamento_id': - self.env.ref('l10n_it_causali_pagamento.a').id, - }) + return self.env["withholding.tax"].create( + { + "name": "2320", + "code": "2320", + "account_receivable_id": self.payable_account_id, + "account_payable_id": self.payable_account_id, + "payment_term": self.env.ref("account.account_payment_term").id, + "rate_ids": [(0, 0, {"tax": 23.0, "base": 0.5})], + "causale_pagamento_id": self.env.ref("l10n_it_causali_pagamento.a").id, + } + ) def create_wt_26_20q(self): - return self.env['withholding.tax'].create({ - 'name': '2620q', - 'code': '2620q', - 'account_receivable_id': self.payable_account_id, - 'account_payable_id': self.payable_account_id, - 'payment_term': self.env.ref('account.account_payment_term').id, - 'rate_ids': [(0, 0, {'tax': 26.0, 'base': 0.2})], - 'causale_pagamento_id': - self.env.ref('l10n_it_causali_pagamento.q').id, - }) + return self.env["withholding.tax"].create( + { + "name": "2620q", + "code": "2620q", + "account_receivable_id": self.payable_account_id, + "account_payable_id": self.payable_account_id, + "payment_term": self.env.ref("account.account_payment_term").id, + "rate_ids": [(0, 0, {"tax": 26.0, "base": 0.2})], + "causale_pagamento_id": self.env.ref("l10n_it_causali_pagamento.q").id, + } + ) def create_wt_26_40q(self): - return self.env['withholding.tax'].create({ - 'name': '2640q', - 'code': '2640q', - 'account_receivable_id': self.payable_account_id, - 'account_payable_id': self.payable_account_id, - 'payment_term': self.env.ref('account.account_payment_term').id, - 'rate_ids': [(0, 0, {'tax': 26.0, 'base': 0.4})], - 'causale_pagamento_id': - self.env.ref('l10n_it_causali_pagamento.q').id, - }) + return self.env["withholding.tax"].create( + { + "name": "2640q", + "code": "2640q", + "account_receivable_id": self.payable_account_id, + "account_payable_id": self.payable_account_id, + "payment_term": self.env.ref("account.account_payment_term").id, + "rate_ids": [(0, 0, {"tax": 26.0, "base": 0.4})], + "causale_pagamento_id": self.env.ref("l10n_it_causali_pagamento.q").id, + } + ) def create_wt_27_20q(self): - return self.env['withholding.tax'].create({ - 'name': '2720q', - 'code': '2720q', - 'account_receivable_id': self.payable_account_id, - 'account_payable_id': self.payable_account_id, - 'payment_term': self.env.ref('account.account_payment_term').id, - 'rate_ids': [(0, 0, {'tax': 27.0, 'base': 0.2})], - 'causale_pagamento_id': - self.env.ref('l10n_it_causali_pagamento.q').id, - }) + return self.env["withholding.tax"].create( + { + "name": "2720q", + "code": "2720q", + "account_receivable_id": self.payable_account_id, + "account_payable_id": self.payable_account_id, + "payment_term": self.env.ref("account.account_payment_term").id, + "rate_ids": [(0, 0, {"tax": 27.0, "base": 0.2})], + "causale_pagamento_id": self.env.ref("l10n_it_causali_pagamento.q").id, + } + ) def create_wt_4q(self): - return self.env['withholding.tax'].create({ - 'name': '4q', - 'code': '4q', - 'wt_types': 'enasarco', - 'account_receivable_id': self.payable_account_id, - 'account_payable_id': self.payable_account_id, - 'payment_term': self.env.ref('account.account_payment_term').id, - 'rate_ids': [(0, 0, {'tax': 4.0, 'base': 1.0})], - 'causale_pagamento_id': - self.env.ref('l10n_it_causali_pagamento.q').id, - }) + return self.env["withholding.tax"].create( + { + "name": "4q", + "code": "4q", + "wt_types": "enasarco", + "account_receivable_id": self.payable_account_id, + "account_payable_id": self.payable_account_id, + "payment_term": self.env.ref("account.account_payment_term").id, + "rate_ids": [(0, 0, {"tax": 4.0, "base": 1.0})], + "causale_pagamento_id": self.env.ref("l10n_it_causali_pagamento.q").id, + } + ) def create_res_bank(self): - return self.env['res.bank'].create({ - 'name': 'Banca generica', - 'bic': 'BCITITMM', - }) + return self.env["res.bank"].create( + { + "name": "Banca generica", + "bic": "BCITITMM", + } + ) - def run_wizard(self, name, file_name, datas_fname=None, - mode='import', wiz_values=None, module_name=None): + def run_wizard( + self, + name, + file_name, + datas_fname=None, + mode="import", + wiz_values=None, + module_name=None, + ): if module_name is None: - module_name = 'l10n_it_fatturapa_in' + module_name = "l10n_it_fatturapa_in" if datas_fname is None: datas_fname = file_name attach_id = self.attach_model.create( { - 'name': name, - 'datas': self.getFile(file_name, module_name=module_name)[1], - 'datas_fname': datas_fname - }).id - if mode == 'import': + "name": name, + "datas": self.getFile(file_name, module_name=module_name)[1], + "datas_fname": datas_fname, + } + ).id + if mode == "import": wizard = self.wizard_model.with_context( - active_ids=[attach_id], active_model='fatturapa.attachment.in' + active_ids=[attach_id], active_model="fatturapa.attachment.in" ).create(wiz_values or {}) return wizard.importFatturaPA() - if mode == 'link': + if mode == "link": wizard = self.wizard_link_model.with_context( - active_ids=[attach_id], active_model='fatturapa.attachment.in' + active_ids=[attach_id], active_model="fatturapa.attachment.in" ).create(wiz_values or {}) return wizard.link() def run_wizard_multi(self, file_name_list, module_name=None): if module_name is None: - module_name = 'l10n_it_fatturapa_in' + module_name = "l10n_it_fatturapa_in" active_ids = [] for file_name in file_name_list: - active_ids.append(self.attach_model.create( - { - 'name': file_name, - 'datas': self.getFile(file_name, module_name)[1], - 'datas_fname': file_name - }).id) - wizard = self.wizard_model.with_context( - active_ids=active_ids).create({}) + active_ids.append( + self.attach_model.create( + { + "name": file_name, + "datas": self.getFile(file_name, module_name)[1], + "datas_fname": file_name, + } + ).id + ) + wizard = self.wizard_model.with_context(active_ids=active_ids).create({}) return wizard.importFatturaPA() def setUp(self): super(FatturapaCommon, self).setUp() - self.wizard_model = self.env['wizard.import.fatturapa'] - self.wizard_link_model = self.env['wizard.link.to.invoice'] - self.data_model = self.env['ir.model.data'] - self.attach_model = self.env['fatturapa.attachment.in'] - self.invoice_model = self.env['account.invoice'] - self.payable_account_id = self.env['account.account'].search([ - ('user_type_id', '=', self.env.ref( - 'account.data_account_type_payable').id) - ], limit=1).id - self.headphones = self.env.ref( - 'product.product_product_7_product_template') - self.imac = self.env.ref( - 'product.product_product_8_product_template') - self.service = self.env.ref('product.product_product_1') - arrotondamenti_attivi_account_id = self.env['account.account'].\ - search([('user_type_id', '=', self.env.ref( - 'account.data_account_type_other_income').id)], limit=1).id - arrotondamenti_passivi_account_id = self.env['account.account'].\ - search([('user_type_id', '=', self.env.ref( - 'account.data_account_type_direct_costs').id)], limit=1).id - arrotondamenti_tax_id = self.env['account.tax'].search( - [('type_tax_use', '=', 'purchase'), - ('amount', '=', 0.0)], order='sequence', limit=1) + self.wizard_model = self.env["wizard.import.fatturapa"] + self.wizard_link_model = self.env["wizard.link.to.invoice"] + self.data_model = self.env["ir.model.data"] + self.attach_model = self.env["fatturapa.attachment.in"] + self.invoice_model = self.env["account.invoice"] + self.payable_account_id = ( + self.env["account.account"] + .search( + [ + ( + "user_type_id", + "=", + self.env.ref("account.data_account_type_payable").id, + ) + ], + limit=1, + ) + .id + ) + self.headphones = self.env.ref("product.product_product_7_product_template") + self.imac = self.env.ref("product.product_product_8_product_template") + self.service = self.env.ref("product.product_product_1") + arrotondamenti_attivi_account_id = ( + self.env["account.account"] + .search( + [ + ( + "user_type_id", + "=", + self.env.ref("account.data_account_type_other_income").id, + ) + ], + limit=1, + ) + .id + ) + arrotondamenti_passivi_account_id = ( + self.env["account.account"] + .search( + [ + ( + "user_type_id", + "=", + self.env.ref("account.data_account_type_direct_costs").id, + ) + ], + limit=1, + ) + .id + ) + arrotondamenti_tax_id = self.env["account.tax"].search( + [("type_tax_use", "=", "purchase"), ("amount", "=", 0.0)], + order="sequence", + limit=1, + ) self.env.user.company_id.arrotondamenti_attivi_account_id = ( - arrotondamenti_attivi_account_id) + arrotondamenti_attivi_account_id + ) self.env.user.company_id.arrotondamenti_passivi_account_id = ( - arrotondamenti_passivi_account_id) - self.env.user.company_id.arrotondamenti_tax_id = ( - arrotondamenti_tax_id) - self.env['res.lang'].load_lang('it_IT') + arrotondamenti_passivi_account_id + ) + self.env.user.company_id.arrotondamenti_tax_id = arrotondamenti_tax_id + self.env["res.lang"].load_lang("it_IT") diff --git a/l10n_it_fatturapa_in/tests/test_import_fatturapa_xml.py b/l10n_it_fatturapa_in/tests/test_import_fatturapa_xml.py index 86ebbb46f5aa..d0815e773aa8 100644 --- a/l10n_it_fatturapa_in/tests/test_import_fatturapa_xml.py +++ b/l10n_it_fatturapa_in/tests/test_import_fatturapa_xml.py @@ -1,14 +1,14 @@ -from psycopg2 import IntegrityError - from datetime import date +from psycopg2 import IntegrityError + +from odoo.exceptions import UserError from odoo.tools import mute_logger + from .fatturapa_common import FatturapaCommon -from odoo.exceptions import UserError class TestDuplicatedAttachment(FatturapaCommon): - def test_duplicated_attachment(self): """Attachment name must be unique""" # This test breaks the current transaction @@ -16,37 +16,34 @@ def test_duplicated_attachment(self): # same transaction would fail. # Note that all the tests in TestFatturaPAXMLValidation # are executed in the same transaction. - self.run_wizard('test_duplicated', 'IT02780790107_11005.xml') + self.run_wizard("test_duplicated", "IT02780790107_11005.xml") with self.assertRaises(IntegrityError) as ie: - with mute_logger('odoo.sql_db'): - self.run_wizard('test_duplicated', 'IT02780790107_11005.xml') - self.assertEqual(ie.exception.pgcode, '23505') + with mute_logger("odoo.sql_db"): + self.run_wizard("test_duplicated", "IT02780790107_11005.xml") + self.assertEqual(ie.exception.pgcode, "23505") class TestFatturaPAXMLValidation(FatturapaCommon): - def setUp(self): super(TestFatturaPAXMLValidation, self).setUp() self.wt = self.create_wt_4q() self.wtq = self.create_wt_27_20q() self.wt4q = self.create_wt_26_40q() self.wt2q = self.create_wt_26_20q() - self.invoice_model = self.env['account.invoice'] + self.invoice_model = self.env["account.invoice"] def test_00_xml_import(self): - self.env.user.company_id.cassa_previdenziale_product_id = ( - self.service.id) - res = self.run_wizard('test0', 'IT05979361218_001.xml') - invoice_id = res.get('domain')[0][2][0] + self.env.user.company_id.cassa_previdenziale_product_id = self.service.id + res = self.run_wizard("test0", "IT05979361218_001.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) - self.assertEqual(invoice.partner_id.register_code, 'TO1258B') - self.assertEqual( - invoice.partner_id.register_fiscalpos.code, 'RF02') - self.assertEqual(invoice.reference, 'FT/2015/0006') + self.assertEqual(invoice.partner_id.register_code, "TO1258B") + self.assertEqual(invoice.partner_id.register_fiscalpos.code, "RF02") + self.assertEqual(invoice.reference, "FT/2015/0006") self.assertEqual(invoice.amount_total, 57.00) self.assertEqual(invoice.gross_weight, 0.00) self.assertEqual(invoice.net_weight, 0.00) - self.assertEqual(invoice.welfare_fund_ids[0].kind_id.code, 'N4') + self.assertEqual(invoice.welfare_fund_ids[0].kind_id.code, "N4") self.assertFalse(invoice.art73) welfare_found = False for line in invoice.invoice_line_ids: @@ -56,115 +53,99 @@ def test_00_xml_import(self): self.assertTrue(welfare_found) self.assertTrue(len(invoice.e_invoice_line_ids) == 1) self.assertEqual( - invoice.e_invoice_line_ids[0].name, 'Prodotto di test al giorno') - self.assertEqual( - invoice.e_invoice_line_ids[0].qty, 15) - self.assertEqual( - invoice.e_invoice_line_ids[0].uom, 'Giorno(i)') - self.assertEqual( - invoice.e_invoice_line_ids[0].unit_price, 3.6) - self.assertEqual( - invoice.e_invoice_line_ids[0].total_price, 54) - self.assertEqual( - invoice.e_invoice_line_ids[0].tax_amount, 0) - self.assertEqual( - invoice.e_invoice_line_ids[0].tax_kind, 'N4') + invoice.e_invoice_line_ids[0].name, "Prodotto di test al giorno" + ) + self.assertEqual(invoice.e_invoice_line_ids[0].qty, 15) + self.assertEqual(invoice.e_invoice_line_ids[0].uom, "Giorno(i)") + self.assertEqual(invoice.e_invoice_line_ids[0].unit_price, 3.6) + self.assertEqual(invoice.e_invoice_line_ids[0].total_price, 54) + self.assertEqual(invoice.e_invoice_line_ids[0].tax_amount, 0) + self.assertEqual(invoice.e_invoice_line_ids[0].tax_kind, "N4") self.assertTrue(len(invoice.e_invoice_line_ids[0].other_data_ids) == 2) self.assertEqual( - invoice.e_invoice_line_ids[0].other_data_ids[0].text_ref, - 'Riferimento') + invoice.e_invoice_line_ids[0].other_data_ids[0].text_ref, "Riferimento" + ) def test_01_xml_import(self): - res = self.run_wizard('test1', 'IT02780790107_11004.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test1", "IT02780790107_11004.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) - self.assertEqual(invoice.reference, '123') + self.assertEqual(invoice.reference, "123") self.assertEqual(invoice.amount_untaxed, 34.00) self.assertEqual(invoice.amount_tax, 7.48) + self.assertEqual(len(invoice.invoice_line_ids[0].invoice_line_tax_ids), 1) self.assertEqual( - len(invoice.invoice_line_ids[0].invoice_line_tax_ids), 1) - self.assertEqual( - invoice.invoice_line_ids[0].invoice_line_tax_ids[0].name, - '22% e-bill') - self.assertEqual( - invoice.fatturapa_summary_ids[0].amount_untaxed, 34.00) - self.assertEqual( - invoice.fatturapa_summary_ids[0].amount_tax, 7.48) - self.assertEqual( - invoice.fatturapa_summary_ids[0].payability, 'D') + invoice.invoice_line_ids[0].invoice_line_tax_ids[0].name, "22% e-bill" + ) + self.assertEqual(invoice.fatturapa_summary_ids[0].amount_untaxed, 34.00) + self.assertEqual(invoice.fatturapa_summary_ids[0].amount_tax, 7.48) + self.assertEqual(invoice.fatturapa_summary_ids[0].payability, "D") self.assertEqual(invoice.partner_id.name, "SOCIETA' ALPHA SRL") self.assertEqual(invoice.partner_id.street, "VIALE ROMA 543") self.assertEqual(invoice.partner_id.state_id.code, "SS") self.assertEqual(invoice.partner_id.country_id.code, "IT") - self.assertEqual( - invoice.tax_representative_id.name, "Rappresentante fiscale") + self.assertEqual(invoice.tax_representative_id.name, "Rappresentante fiscale") self.assertEqual(invoice.welfare_fund_ids[0].welfare_rate_tax, 0.04) order_related_doc = invoice.related_documents.filtered( - lambda rd: rd.type == 'order' + lambda rd: rd.type == "order" ) self.assertTrue(order_related_doc) - self.assertEqual(order_related_doc.cig, '456def') - self.assertEqual(order_related_doc.cup, '123abc') - self.assertEqual( - invoice.welfare_fund_ids[0].welfare_amount_tax, 9) + self.assertEqual(order_related_doc.cig, "456def") + self.assertEqual(order_related_doc.cup, "123abc") + self.assertEqual(invoice.welfare_fund_ids[0].welfare_amount_tax, 9) self.assertFalse(invoice.welfare_fund_ids[0].welfare_taxable) - self.assertEqual(invoice.unit_weight, 'KGM') - self.assertEqual(invoice.ftpa_incoterms, 'DAP') - self.assertEqual(invoice.fiscal_document_type_id.code, 'TD01') + self.assertEqual(invoice.unit_weight, "KGM") + self.assertEqual(invoice.ftpa_incoterms, "DAP") + self.assertEqual(invoice.fiscal_document_type_id.code, "TD01") self.assertTrue(invoice.art73) def test_02_xml_import(self): - res = self.run_wizard('test02', 'IT05979361218_011.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test02", "IT05979361218_011.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) - self.assertEqual(invoice.intermediary.vat, 'IT03339130126') + self.assertEqual(invoice.intermediary.vat, "IT03339130126") def test_04_xml_import(self): - res = self.run_wizard('test4', 'IT02780790107_11005.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test4", "IT02780790107_11005.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) - self.assertEqual(invoice.reference, '124') + self.assertEqual(invoice.reference, "124") self.assertEqual(invoice.partner_id.name, "SOCIETA' ALPHA SRL") self.assertEqual( - invoice.invoice_line_ids[0].invoice_line_tax_ids[0].name, - '22% e-bill') - self.assertEqual( - invoice.invoice_line_ids[1].invoice_line_tax_ids[0].name, - '22% e-bill') - self.assertEqual( - invoice.invoice_line_ids[0].invoice_line_tax_ids[0].amount, 22) - self.assertEqual( - invoice.invoice_line_ids[1].invoice_line_tax_ids[0].amount, 22) + invoice.invoice_line_ids[0].invoice_line_tax_ids[0].name, "22% e-bill" + ) self.assertEqual( - invoice.invoice_line_ids[1].price_unit, 2) + invoice.invoice_line_ids[1].invoice_line_tax_ids[0].name, "22% e-bill" + ) + self.assertEqual(invoice.invoice_line_ids[0].invoice_line_tax_ids[0].amount, 22) + self.assertEqual(invoice.invoice_line_ids[1].invoice_line_tax_ids[0].amount, 22) + self.assertEqual(invoice.invoice_line_ids[1].price_unit, 2) self.assertTrue(len(invoice.e_invoice_line_ids) == 2) for e_line in invoice.e_invoice_line_ids: self.assertTrue(e_line.line_number in (1, 2)) if e_line.line_number == 1: - self.assertEqual( - e_line.cod_article_ids[0].name, 'EAN') - self.assertEqual( - e_line.cod_article_ids[0].code_val, '12345') + self.assertEqual(e_line.cod_article_ids[0].name, "EAN") + self.assertEqual(e_line.cod_article_ids[0].code_val, "12345") self.assertEqual( invoice.inconsistencies, - u"Company Name field contains 'Societa\' " - u"Alpha SRL'. Your System contains 'SOCIETA\' ALPHA SRL'\n\n") + u"Company Name field contains 'Societa' " + u"Alpha SRL'. Your System contains 'SOCIETA' ALPHA SRL'\n\n", + ) def test_05_xml_import(self): - res = self.run_wizard('test5', 'IT05979361218_003.xml') - invoice_id = res.get('domain')[0][2][0] - invoice = self.invoice_model.browse(invoice_id) - self.assertEqual(invoice.reference, 'FT/2015/0008') - self.assertEqual(invoice.sender, 'TZ') - self.assertEqual(invoice.intermediary.name, 'MARIO ROSSI') - self.assertEqual(invoice.intermediary.firstname, 'MARIO') - self.assertEqual(invoice.intermediary.lastname, 'ROSSI') + res = self.run_wizard("test5", "IT05979361218_003.xml") + invoice_id = res.get("domain")[0][2][0] + invoice = self.invoice_model.browse(invoice_id) + self.assertEqual(invoice.reference, "FT/2015/0008") + self.assertEqual(invoice.sender, "TZ") + self.assertEqual(invoice.intermediary.name, "MARIO ROSSI") + self.assertEqual(invoice.intermediary.firstname, "MARIO") + self.assertEqual(invoice.intermediary.lastname, "ROSSI") self.assertEqual( - invoice.e_invoice_line_ids[0].discount_rise_price_ids[0].name, - 'SC') + invoice.e_invoice_line_ids[0].discount_rise_price_ids[0].name, "SC" + ) self.assertEqual( - invoice.e_invoice_line_ids[0].discount_rise_price_ids[0]. - percentage, 10 + invoice.e_invoice_line_ids[0].discount_rise_price_ids[0].percentage, 10 ) self.assertEqual(invoice.amount_untaxed, 9) self.assertEqual(invoice.amount_tax, 0) @@ -172,38 +153,43 @@ def test_05_xml_import(self): def test_06_import_except(self): # File not exist Exception - self.assertRaises( - Exception, self.run_wizard, 'test6_Exception', '') + self.assertRaises(Exception, self.run_wizard, "test6_Exception", "") # fake Signed file is passed , generate orm_exception self.assertRaises( - UserError, self.run_wizard, 'test6_orm_exception', - 'IT05979361218_fake.xml.p7m' + UserError, + self.run_wizard, + "test6_orm_exception", + "IT05979361218_fake.xml.p7m", ) def test_07_xml_import(self): # 2 lines with quantity != 1 and discounts - res = self.run_wizard('test7', 'IT05979361218_004.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test7", "IT05979361218_004.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) - self.assertEqual(invoice.reference, 'FT/2015/0009') + self.assertEqual(invoice.reference, "FT/2015/0009") self.assertAlmostEqual(invoice.amount_untaxed, 1173.60) self.assertEqual(invoice.amount_tax, 258.19) self.assertEqual(invoice.amount_total, 1431.79) self.assertAlmostEqual( - invoice.e_invoice_amount_untaxed, invoice.amount_untaxed, - places=invoice.currency_id.decimal_places) + invoice.e_invoice_amount_untaxed, + invoice.amount_untaxed, + places=invoice.currency_id.decimal_places, + ) self.assertAlmostEqual( - invoice.e_invoice_amount_tax, invoice.amount_tax, - places=invoice.currency_id.decimal_places) + invoice.e_invoice_amount_tax, + invoice.amount_tax, + places=invoice.currency_id.decimal_places, + ) self.assertEqual(invoice.e_invoice_validation_error, False) - self.assertEqual(invoice.invoice_line_ids[0].admin_ref, 'D122353') + self.assertEqual(invoice.invoice_line_ids[0].admin_ref, "D122353") def test_08_xml_import(self): # using ImportoTotaleDocumento - res = self.run_wizard('test8', 'IT05979361218_005.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test8", "IT05979361218_005.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) - self.assertEqual(invoice.reference, 'FT/2015/0010') + self.assertEqual(invoice.reference, "FT/2015/0010") self.assertAlmostEqual(invoice.amount_total, 1288.61) self.assertFalse(invoice.inconsistencies) @@ -211,101 +197,100 @@ def test_09_xml_import(self): # using DatiGeneraliDocumento.ScontoMaggiorazione without # ImportoTotaleDocumento # add test file name case sensitive - res = self.run_wizard('test9', 'IT05979361218_006.XML') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test9", "IT05979361218_006.XML") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) - self.assertEqual(invoice.reference, 'FT/2015/0011') + self.assertEqual(invoice.reference, "FT/2015/0011") self.assertAlmostEqual(invoice.amount_total, 1288.61) self.assertEqual( invoice.inconsistencies, - 'Computed amount untaxed 1030.42 is different from' - ' summary data 1173.6') + "Computed amount untaxed 1030.42 is different from" " summary data 1173.6", + ) def test_10_xml_import(self): # Fix Date format - res = self.run_wizard('test6', 'IT05979361218_007.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test6", "IT05979361218_007.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) - self.assertEqual(invoice.reference, 'FT/2015/0009') - self.assertEqual( - invoice.date_invoice, date(2015, 3, 16)) + self.assertEqual(invoice.reference, "FT/2015/0009") + self.assertEqual(invoice.date_invoice, date(2015, 3, 16)) self.assertEqual( invoice.fatturapa_payments[0].payment_methods[0].payment_due_date, - date(2015, 6, 3) + date(2015, 6, 3), ) self.assertEqual( - invoice.fatturapa_payments[0].payment_methods[0]. - fatturapa_pm_id.code, - 'MP18' + invoice.fatturapa_payments[0].payment_methods[0].fatturapa_pm_id.code, + "MP18", ) def test_11_xml_import(self): # DatiOrdineAcquisto with RiferimentoNumeroLinea referring to # not existing invoice line - res = self.run_wizard('test11', 'IT02780790107_11006.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test11", "IT02780790107_11006.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) - self.assertEqual( - len(invoice.invoice_line_ids[0].related_documents), 0) - self.assertEqual( - invoice.invoice_line_ids[0].sequence, 1) - self.assertEqual( - invoice.related_documents[0].type, "order") - self.assertEqual( - invoice.related_documents[0].lineRef, 60) + self.assertEqual(len(invoice.invoice_line_ids[0].related_documents), 0) + self.assertEqual(invoice.invoice_line_ids[0].sequence, 1) + self.assertEqual(invoice.related_documents[0].type, "order") + self.assertEqual(invoice.related_documents[0].lineRef, 60) def test_12_xml_import(self): - res = self.run_wizard('test12', 'IT05979361218_008.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test12", "IT05979361218_008.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) - self.assertEqual(invoice.reference, 'FT/2015/0012') - self.assertEqual(invoice.sender, 'TZ') - self.assertEqual(invoice.intermediary.name, 'MARIO ROSSI') - self.assertEqual(invoice.intermediary.firstname, 'MARIO') - self.assertEqual(invoice.intermediary.lastname, 'ROSSI') + self.assertEqual(invoice.reference, "FT/2015/0012") + self.assertEqual(invoice.sender, "TZ") + self.assertEqual(invoice.intermediary.name, "MARIO ROSSI") + self.assertEqual(invoice.intermediary.firstname, "MARIO") + self.assertEqual(invoice.intermediary.lastname, "ROSSI") def test_13_xml_import(self): # inconsistencies must not be duplicated - res = self.run_wizard_multi([ - 'IT02780790107_11005.xml', - 'IT02780790107_11006.xml', - ]) - invoice1_id = res.get('domain')[0][2][0] - invoice2_id = res.get('domain')[0][2][1] + res = self.run_wizard_multi( + [ + "IT02780790107_11005.xml", + "IT02780790107_11006.xml", + ] + ) + invoice1_id = res.get("domain")[0][2][0] + invoice2_id = res.get("domain")[0][2][1] invoice1 = self.invoice_model.browse(invoice1_id) invoice2 = self.invoice_model.browse(invoice2_id) self.assertEqual( invoice1.inconsistencies, - u"Company Name field contains 'Societa\' " - u"Alpha SRL'. Your System contains 'SOCIETA\' ALPHA SRL'\n\n") + u"Company Name field contains 'Societa' " + u"Alpha SRL'. Your System contains 'SOCIETA' ALPHA SRL'\n\n", + ) self.assertEqual( invoice2.inconsistencies, - u"Company Name field contains 'Societa\' " - u"Alpha SRL'. Your System contains 'SOCIETA\' ALPHA SRL'\n\n") + u"Company Name field contains 'Societa' " + u"Alpha SRL'. Your System contains 'SOCIETA' ALPHA SRL'\n\n", + ) def test_14_xml_import(self): # check: no tax code found , write inconsisteance and anyway # create draft - res = self.run_wizard('test14', 'IT02780790107_11007.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test14", "IT02780790107_11007.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) - self.assertEqual(invoice.reference, '136') - self.assertEqual(invoice.partner_id.name, 'SOCIETA\' ALPHA SRL') + self.assertEqual(invoice.reference, "136") + self.assertEqual(invoice.partner_id.name, "SOCIETA' ALPHA SRL") self.assertEqual(invoice.amount_untaxed, 25.00) self.assertEqual(invoice.amount_tax, 0.0) self.assertEqual( invoice.inconsistencies, - u"Company Name field contains 'Societa\' " - "Alpha SRL'. Your System contains 'SOCIETA\' ALPHA SRL'\n\n" + u"Company Name field contains 'Societa' " + "Alpha SRL'. Your System contains 'SOCIETA' ALPHA SRL'\n\n" u"XML contains tax with percentage '15.55'" " but it does not exist in your system\n" "XML contains tax with percentage '15.55'" - " but it does not exist in your system") + " but it does not exist in your system", + ) def test_15_xml_import(self): self.wt = self.create_wt() - res = self.run_wizard('test15', 'IT05979361218_009.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test15", "IT05979361218_009.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) self.assertAlmostEquals(invoice.withholding_tax_amount, 1) self.assertAlmostEquals(invoice.amount_total, 6.1) @@ -314,55 +299,55 @@ def test_15_xml_import(self): def test_16_xml_import(self): # file B2B downloaded from # http://www.fatturapa.gov.it/export/fatturazione/it/a-3.htm - res = self.run_wizard('test16a', 'IT01234567890_FPR03.xml') - invoice_ids = res.get('domain')[0][2] + res = self.run_wizard("test16a", "IT01234567890_FPR03.xml") + invoice_ids = res.get("domain")[0][2] invoices = self.invoice_model.browse(invoice_ids) self.assertEqual(len(invoices), 2) for invoice in invoices: - self.assertEqual(invoice.inconsistencies, '') + self.assertEqual(invoice.inconsistencies, "") self.assertEqual(invoice.partner_id.name, "SOCIETA' ALPHA SRL") - self.assertTrue(invoice.reference in ('456', '123')) - if invoice.reference == '123': + self.assertTrue(invoice.reference in ("456", "123")) + if invoice.reference == "123": self.assertTrue(len(invoice.invoice_line_ids) == 2) for line in invoice.invoice_line_ids: self.assertFalse(line.product_id) self.assertEqual(invoice.date_due, date(2015, 1, 30)) - if invoice.reference == '456': + if invoice.reference == "456": self.assertTrue(len(invoice.invoice_line_ids) == 1) for line in invoice.invoice_line_ids: self.assertFalse(line.product_id) self.assertEqual(invoice.date_due, date(2015, 1, 28)) partner = invoice.partner_id - partner.e_invoice_default_product_id = ( - self.imac.product_variant_ids[0].id) + partner.e_invoice_default_product_id = self.imac.product_variant_ids[0].id # I create a supplier code to be matched in XML - self.env['product.supplierinfo'].create({ - 'name': partner.id, - 'product_tmpl_id': self.headphones.id, - 'product_code': 'ART123', - }) - res = self.run_wizard('test16b', 'IT01234567890_FPR03.xml') - invoice_ids = res.get('domain')[0][2] + self.env["product.supplierinfo"].create( + { + "name": partner.id, + "product_tmpl_id": self.headphones.id, + "product_code": "ART123", + } + ) + res = self.run_wizard("test16b", "IT01234567890_FPR03.xml") + invoice_ids = res.get("domain")[0][2] invoices = self.invoice_model.browse(invoice_ids) for invoice in invoices: - self.assertTrue(invoice.reference in ('456', '123')) - if invoice.reference == '123': + self.assertTrue(invoice.reference in ("456", "123")) + if invoice.reference == "123": self.assertEqual( invoice.invoice_line_ids[0].product_id.id, - self.headphones.product_variant_ids[0].id + self.headphones.product_variant_ids[0].id, ) else: for line in invoice.invoice_line_ids: self.assertEqual( - line.product_id.id, - self.imac.product_variant_ids[0].id + line.product_id.id, self.imac.product_variant_ids[0].id ) # change Livello di dettaglio Fatture elettroniche to Minimo - partner.e_invoice_detail_level = '0' - res = self.run_wizard('test16c', 'IT01234567890_FPR03.xml') - invoice_ids = res.get('domain')[0][2] + partner.e_invoice_detail_level = "0" + res = self.run_wizard("test16c", "IT01234567890_FPR03.xml") + invoice_ids = res.get("domain")[0][2] invoices = self.invoice_model.browse(invoice_ids) self.assertTrue(len(invoices) == 2) for invoice in invoices: @@ -370,120 +355,127 @@ def test_16_xml_import(self): def test_03_xml_import(self): # Testing CAdES signature - res = self.run_wizard('test18', 'IT01234567890_FPR03.xml.p7m') - invoice_ids = res.get('domain')[0][2] + res = self.run_wizard("test18", "IT01234567890_FPR03.xml.p7m") + invoice_ids = res.get("domain")[0][2] invoices = self.invoice_model.browse(invoice_ids) self.assertEqual(len(invoices), 2) for invoice in invoices: - self.assertEqual(invoice.inconsistencies, '') + self.assertEqual(invoice.inconsistencies, "") self.assertEqual(invoice.partner_id.name, "SOCIETA' ALPHA SRL") - self.assertTrue(invoice.reference in ('456', '123')) - if invoice.reference == '123': + self.assertTrue(invoice.reference in ("456", "123")) + if invoice.reference == "123": self.assertTrue(len(invoice.invoice_line_ids) == 2) - if invoice.reference == '456': + if invoice.reference == "456": self.assertTrue(len(invoice.invoice_line_ids) == 1) def test_17_xml_import(self): - res = self.run_wizard('test17', 'IT05979361218_010.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test17", "IT05979361218_010.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) - self.assertEqual( - invoice.related_documents[0].type, "invoice") + self.assertEqual(invoice.related_documents[0].type, "invoice") def test_19_xml_import(self): # Testing CAdES signature, base64 encoded res = self.run_wizard( - 'test19', 'IT01234567890_FPR03.base64.xml.p7m', - 'IT01234567890_FPR03.xml.p7m') - invoice_ids = res.get('domain')[0][2] + "test19", + "IT01234567890_FPR03.base64.xml.p7m", + "IT01234567890_FPR03.xml.p7m", + ) + invoice_ids = res.get("domain")[0][2] invoices = self.invoice_model.browse(invoice_ids) self.assertEqual(len(invoices), 2) for invoice in invoices: self.assertEqual(invoice.partner_id.name, "SOCIETA' ALPHA SRL") - self.assertEqual(invoice.partner_id.e_invoice_detail_level, '0') - self.assertTrue(invoice.reference in ('456', '123')) - if invoice.reference == '123': + self.assertEqual(invoice.partner_id.e_invoice_detail_level, "0") + self.assertTrue(invoice.reference in ("456", "123")) + if invoice.reference == "123": self.assertEqual( invoice.inconsistencies, - 'Computed amount untaxed 0.0 is different from summary ' - 'data 25.0') - if invoice.reference == '456': + "Computed amount untaxed 0.0 is different from summary " + "data 25.0", + ) + if invoice.reference == "456": self.assertEqual( invoice.inconsistencies, - 'Computed amount untaxed 0.0 is different from summary ' - 'data 2000.0') + "Computed amount untaxed 0.0 is different from summary " + "data 2000.0", + ) def test_20_xml_import(self): # Testing xml without xml declaration (sent by Amazon) - res = self.run_wizard('test20', 'IT05979361218_no_decl.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test20", "IT05979361218_no_decl.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) self.assertEqual(invoice.partner_id.name, "SOCIETA' ALPHA SRL") def test_21_xml_import(self): - supplier = self.env['res.partner'].search( - [('vat', '=', 'IT02780790107')])[0] + supplier = self.env["res.partner"].search([("vat", "=", "IT02780790107")])[0] # in order to make the system create the invoice lines - supplier.e_invoice_detail_level = '2' - res = self.run_wizard('test21', 'IT01234567890_FPR04.xml') - invoice_id = res.get('domain')[0][2][0] + supplier.e_invoice_detail_level = "2" + res = self.run_wizard("test21", "IT01234567890_FPR04.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) - self.assertEqual(invoice.inconsistencies, '') + self.assertEqual(invoice.inconsistencies, "") self.assertEqual(invoice.invoice_line_ids[2].price_unit, 0.0) self.assertEqual(invoice.invoice_line_ids[2].discount, 0.0) def test_22_xml_import(self): - res = self.run_wizard('test22', 'IT02780790107_11004_xml_doctor.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test22", "IT02780790107_11004_xml_doctor.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) self.assertEqual(invoice.partner_id.name, "SOCIETA' ALPHA SRL") - self.assertIn('removed timezone information', invoice.inconsistencies) + self.assertIn("removed timezone information", invoice.inconsistencies) # DatiGeneraliDocumento/Causale - self.assertIn(' ', invoice.comment) + self.assertIn(" ", invoice.comment) # DatiGeneraliDocumento/Data self.assertEqual(invoice.date_invoice, date(2014, 12, 18)) # DatiTrasporto/IndirizzoResa/NumeroCivico - self.assertEqual(invoice.delivery_address, - 'strada dei test, \n12042 - Bra\nCN IT') + self.assertEqual( + invoice.delivery_address, "strada dei test, \n12042 - Bra\nCN IT" + ) # DatiTrasporto/DataOraConsegna self.assertFalse(invoice.delivery_datetime) # DatiBeniServizi/DettaglioLinee/Descrizione - self.assertEqual(invoice.invoice_line_ids[0].name, ' ') + self.assertEqual(invoice.invoice_line_ids[0].name, " ") # DatiPagamento/DettaglioPagamento/DataDecorrenzaPenale - payment_data = self.env['fatturapa.payment.data'].search( - [('invoice_id', '=', invoice.id)]) - self.assertEqual(payment_data[0].payment_methods[0].penalty_date, - date(2015, 5, 1)) + payment_data = self.env["fatturapa.payment.data"].search( + [("invoice_id", "=", invoice.id)] + ) + self.assertEqual( + payment_data[0].payment_methods[0].penalty_date, date(2015, 5, 1) + ) def test_23_xml_import(self): # Testing CAdES signature, base64 encoded with newlines res = self.run_wizard( - 'test23', 'IT01234567890_FPR04.base64.xml.p7m', - 'IT01234567890_FPR04.xml.p7m') - invoice_ids = res.get('domain')[0][2] + "test23", + "IT01234567890_FPR04.base64.xml.p7m", + "IT01234567890_FPR04.xml.p7m", + ) + invoice_ids = res.get("domain")[0][2] invoices = self.invoice_model.browse(invoice_ids) self.assertEqual(len(invoices), 2) def test_24_xml_import(self): - res = self.run_wizard('test24', 'IT05979361218_012.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test24", "IT05979361218_012.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) self.assertEqual( invoice.inconsistencies, - 'Computed amount untaxed 34.32 is different from' - ' summary data 34.67') + "Computed amount untaxed 34.32 is different from" " summary data 34.67", + ) def test_25_xml_import(self): - res = self.run_wizard('test25', 'IT05979361218_013.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test25", "IT05979361218_013.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) self.assertAlmostEqual(invoice.e_invoice_amount_untaxed, 34.67) self.assertEqual(invoice.e_invoice_amount_tax, 0.0) @@ -492,39 +484,42 @@ def test_25_xml_import(self): invoice.action_invoice_open() move_line = False for line in invoice.move_id.line_ids: - if line.account_id.id == self.env.user.\ - company_id.arrotondamenti_attivi_account_id.id: + if ( + line.account_id.id + == self.env.user.company_id.arrotondamenti_attivi_account_id.id + ): move_line = True self.assertTrue(move_line) def test_26_xml_import(self): - res = self.run_wizard('test26', 'IT05979361218_015.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test26", "IT05979361218_015.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) self.assertAlmostEqual(invoice.e_invoice_amount_untaxed, 34.32) self.assertEqual(invoice.e_invoice_amount_tax, 0.0) self.assertEqual(invoice.e_invoice_amount_total, 34.32) def test_30_xml_import(self): - self.env.user.company_id.cassa_previdenziale_product_id = ( - self.service.id) - res = self.run_wizard('test30', 'IT05979361218_001.xml') - invoice_id = res.get('domain')[0][2][0] + self.env.user.company_id.cassa_previdenziale_product_id = self.service.id + res = self.run_wizard("test30", "IT05979361218_001.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) partner_id = invoice.partner_id - partner_id.write({ - 'street': 'Viale Repubblica, 34', - 'electronic_invoice_no_contact_update': True, - }) - res = self.run_wizard('test30a', 'IT05979361218_002.xml') - invoice_id = res.get('domain')[0][2][0] + partner_id.write( + { + "street": "Viale Repubblica, 34", + "electronic_invoice_no_contact_update": True, + } + ) + res = self.run_wizard("test30a", "IT05979361218_002.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) self.assertEqual(invoice.partner_id.id, partner_id.id) - self.assertEqual(invoice.partner_id.street, 'Viale Repubblica, 34') + self.assertEqual(invoice.partner_id.street, "Viale Repubblica, 34") def test_31_xml_import(self): - res = self.run_wizard('test31', 'IT01234567890_FPR05.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test31", "IT01234567890_FPR05.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) self.assertEqual(invoice.invoice_line_ids[1].discount, 100) self.assertEqual(invoice.invoice_line_ids[1].price_subtotal, 0) @@ -532,10 +527,10 @@ def test_31_xml_import(self): def test_32_xml_import(self): # Refund with positive total - res = self.run_wizard('test32', 'IT01234567890_FPR06.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test32", "IT01234567890_FPR06.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) - self.assertEqual(invoice.type, 'in_refund') + self.assertEqual(invoice.type, "in_refund") self.assertEqual(invoice.amount_total, 18.3) self.assertEqual(invoice.invoice_line_ids[0].price_unit, 2.0) self.assertEqual(invoice.invoice_line_ids[0].quantity, 10.0) @@ -546,10 +541,10 @@ def test_32_xml_import(self): def test_33_xml_import(self): # Refund with negative total - res = self.run_wizard('test33', 'IT01234567890_FPR07.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test33", "IT01234567890_FPR07.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) - self.assertEqual(invoice.type, 'in_refund') + self.assertEqual(invoice.type, "in_refund") self.assertEqual(invoice.amount_total, 24.4) self.assertEqual(invoice.invoice_line_ids[0].price_unit, 2.0) self.assertEqual(invoice.invoice_line_ids[0].quantity, 10.0) @@ -559,15 +554,15 @@ def test_33_xml_import(self): def test_34_xml_import(self): # No Ritenuta lines set - res = self.run_wizard('test34', 'IT01234567890_FPR08.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test34", "IT01234567890_FPR08.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) self.assertTrue(invoice.e_invoice_validation_error) self.assertEqual( invoice.e_invoice_validation_message, "E-bill contains DatiRitenuta but no lines subjected to Ritenuta was " "found. Please manually check Withholding tax Amount\nE-bill contains " - "ImportoRitenuta 360.0 but created invoice has got 0.0\n." + "ImportoRitenuta 360.0 but created invoice has got 0.0\n.", ) def test_35_xml_import(self): @@ -575,62 +570,65 @@ def test_35_xml_import(self): # contains 2320: error message must appear self.create_wt_23_50() self.create_wt_23_20() - res = self.run_wizard('test35', 'IT01234567890_FPR09.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test35", "IT01234567890_FPR09.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) self.assertTrue(invoice.e_invoice_validation_error) self.assertEqual( invoice.e_invoice_validation_message, "E-bill contains ImportoRitenuta 30.16 but created invoice has got " - "75.41\n." + "75.41\n.", ) def test_36_xml_import(self): # creating a res.bank and importing an XML without "IstitutoFinanziario" self.create_res_bank() - res = self.run_wizard('test36', 'IT01234567890_FPR10.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test36", "IT01234567890_FPR10.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) self.assertEqual( invoice.fatturapa_payments[0].payment_methods[0].payment_bank.bank_id.bic, - 'BCITITMM') + "BCITITMM", + ) self.assertEqual( invoice.fatturapa_payments[0].payment_methods[0].payment_bank.bank_id.name, - 'Banca generica') + "Banca generica", + ) def test_37_xml_import_dates(self): - self.env.user.lang = 'it_IT' - res = self.run_wizard('test37', 'IT02780790107_11004.xml') - invoice_id = res.get('domain')[0][2][0] + self.env.user.lang = "it_IT" + res = self.run_wizard("test37", "IT02780790107_11004.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) - self.assertEqual(invoice.fatturapa_attachment_in_id.invoices_date, - '18/12/2014') + self.assertEqual(invoice.fatturapa_attachment_in_id.invoices_date, "18/12/2014") def test_38_xml_import_dates(self): # file B2B downloaded from # http://www.fatturapa.gov.it/export/fatturazione/it/a-3.htm - self.env.user.lang = 'it_IT' - res = self.run_wizard('test38', 'IT01234567890_FPR03.xml') - invoice_ids = res.get('domain')[0][2] + self.env.user.lang = "it_IT" + res = self.run_wizard("test38", "IT01234567890_FPR03.xml") + invoice_ids = res.get("domain")[0][2] invoices = self.invoice_model.browse(invoice_ids) self.assertEqual(len(invoices), 2) - self.assertEqual(invoices[0].fatturapa_attachment_in_id.invoices_date, - '18/12/2014 20/12/2014') + self.assertEqual( + invoices[0].fatturapa_attachment_in_id.invoices_date, + "18/12/2014 20/12/2014", + ) def test_40_xml_import_withholding(self): - res = self.run_wizard('test40', 'IT01234567890_FPR11.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test40", "IT01234567890_FPR11.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) self.assertTrue(invoice.e_invoice_validation_error) self.assertEqual( invoice.e_invoice_validation_message, "E-bill contains ImportoRitenuta 92.0 but created invoice has got " - "144.0\n." + "144.0\n.", ) def test_41_xml_import_withholding(self): - res = self.run_wizard('test41', 'IT01234567890_FPR12.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test41", "IT01234567890_FPR12.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) self.assertTrue(len(invoice.ftpa_withholding_ids), 2) self.assertAlmostEquals(invoice.amount_total, 1220.0) @@ -639,8 +637,8 @@ def test_41_xml_import_withholding(self): def test_42_xml_import_withholding(self): # cassa previdenziale sulla quale è applicata la ritenuta - res = self.run_wizard('test42', 'IT01234567890_FPR13.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test42", "IT01234567890_FPR13.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) self.assertEqual(invoice.amount_total, 19032.0) self.assertEqual(invoice.withholding_tax_amount, 3120.0) @@ -651,22 +649,22 @@ def test_42_xml_import_withholding(self): def test_43_xml_import_withholding(self): # Avvocato Mario Bianchi di Ferrara. # Imponibile di 100+15% spese - res = self.run_wizard('test43', 'ITBNCMRA80A01D548T_20001.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test43", "ITBNCMRA80A01D548T_20001.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) self.assertEqual(invoice.withholding_tax_amount, 23.0) self.assertTrue(len(invoice.ftpa_withholding_ids), 1) self.assertTrue(len(invoice.invoice_line_ids) == 3) def test_44_xml_import(self): - res = self.run_wizard('test44', 'ITBNCMRA80A01D548T_20005.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test44", "ITBNCMRA80A01D548T_20005.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) self.assertTrue(len(invoice.invoice_line_ids) == 3) def test_45_xml_many_zeros(self): - res = self.run_wizard('test45', 'IT05979361218_016.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test45", "IT05979361218_016.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) self.assertEqual(invoice.amount_total, 18.07) self.assertEqual(invoice.invoice_line_ids[0].price_unit, 18.07) @@ -682,31 +680,34 @@ def test_01_xml_link(self): Vendor Reference and Invoice Date are kept. """ - supplier = self.env['res.partner'].search( - [('vat', '=', 'IT02780790107')], limit=1) + supplier = self.env["res.partner"].search( + [("vat", "=", "IT02780790107")], limit=1 + ) invoice_values = { - 'partner_id': supplier.id, - 'type': 'in_invoice', - 'reference': 'original_ref', - 'date_invoice': date(2020, 1, 1), + "partner_id": supplier.id, + "type": "in_invoice", + "reference": "original_ref", + "date_invoice": date(2020, 1, 1), } orig_invoice = self.invoice_model.create(invoice_values) wiz_values = { - 'line_ids': [(0, 0, { - 'invoice_id': orig_invoice.id - })], + "line_ids": [(0, 0, {"invoice_id": orig_invoice.id})], } - self.run_wizard('test_link_01', 'IT01234567890_FPR04.xml', - mode='link', wiz_values=wiz_values) + self.run_wizard( + "test_link_01", + "IT01234567890_FPR04.xml", + mode="link", + wiz_values=wiz_values, + ) self.assertTrue(orig_invoice.e_invoice_line_ids) self.assertFalse(orig_invoice.invoice_line_ids) self.assertTrue(orig_invoice.e_invoice_validation_error) self.assertEqual( - invoice_values['reference'], + invoice_values["reference"], orig_invoice.reference, ) self.assertEqual( - invoice_values['date_invoice'], + invoice_values["date_invoice"], orig_invoice.date_invoice, ) @@ -716,20 +717,23 @@ def test_02_xml_link(self): Vendor Reference and Invoice Date are fetched from the XML. """ - supplier = self.env['res.partner'].search( - [('vat', '=', 'IT02780790107')], limit=1) + supplier = self.env["res.partner"].search( + [("vat", "=", "IT02780790107")], limit=1 + ) invoice_values = { - 'partner_id': supplier.id, - 'type': 'in_invoice', + "partner_id": supplier.id, + "type": "in_invoice", } orig_invoice = self.invoice_model.create(invoice_values) wiz_values = { - 'line_ids': [(0, 0, { - 'invoice_id': orig_invoice.id - })], + "line_ids": [(0, 0, {"invoice_id": orig_invoice.id})], } - self.run_wizard('test_link_02', 'IT02780790107_11004.xml', - mode='link', wiz_values=wiz_values) + self.run_wizard( + "test_link_02", + "IT02780790107_11004.xml", + mode="link", + wiz_values=wiz_values, + ) self.assertTrue(orig_invoice.e_invoice_line_ids) self.assertFalse(orig_invoice.invoice_line_ids) self.assertTrue(orig_invoice.e_invoice_validation_error) @@ -737,21 +741,19 @@ def test_02_xml_link(self): self.assertTrue(orig_invoice.date_invoice) def test_01_xml_zero_quantity_line(self): - res = self.run_wizard('test_zeroq_01', 'IT05979361218_q0.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test_zeroq_01", "IT05979361218_q0.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) self.assertEqual(invoice.invoice_line_ids[0].quantity, 0) self.assertEqual(invoice.invoice_line_ids[1].quantity, 1) def test_xml_import_summary_tax_rate(self): # Invoice with positive total. Detail Level: '1' -- Tax Rate - supplier = self.env['res.partner'].search( - [('vat', '=', 'IT02780790107')])[0] + supplier = self.env["res.partner"].search([("vat", "=", "IT02780790107")])[0] # in order to make the system create the invoice lines - supplier.e_invoice_detail_level = '1' - res = self.run_wizard('test_summary_tax_rate', - 'IT05979361218_ripilogoiva.xml') - invoice_id = res.get('domain')[0][2][0] + supplier.e_invoice_detail_level = "1" + res = self.run_wizard("test_summary_tax_rate", "IT05979361218_ripilogoiva.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) self.assertEqual(invoice.amount_total, 204.16) self.assertEqual(len(invoice.invoice_line_ids), 2) @@ -763,95 +765,121 @@ def test_xml_import_summary_tax_rate(self): class TestFatturaPAEnasarco(FatturapaCommon): - def setUp(self): super(TestFatturaPAEnasarco, self).setUp() - self.invoice_model = self.env['account.invoice'] + self.invoice_model = self.env["account.invoice"] def test_01_xml_import_enasarco(self): - account_payable = self.env['account.account'].create({ - 'name': 'Test WH tax', - 'code': 'whtaxpay2', - 'user_type_id': self.env.ref( - 'account.data_account_type_payable').id, - 'reconcile': True}) - account_receivable = self.env['account.account'].create({ - 'name': 'Test WH tax', - 'code': 'whtaxrec2', - 'user_type_id': self.env.ref( - 'account.data_account_type_receivable').id, - 'reconcile': True}) - misc_journal = self.env['account.journal']. \ - search([("code", "=", "MISC")]) - self.env['withholding.tax'].create({ - 'name': 'Enasarco', - 'code': 'TC07', - 'account_receivable_id': account_receivable.id, - 'account_payable_id': account_payable.id, - 'journal_id': misc_journal.id, - 'payment_term': self.env.ref( - 'account.account_payment_term_advance').id, - 'wt_types': 'enasarco', - 'causale_pagamento_id': self.env.ref( - 'l10n_it_causali_pagamento.r').id, - 'rate_ids': [(0, 0, { - 'tax': 1.57, - 'base': 1.0, - })] - }) - self.env['withholding.tax'].create({ - 'name': 'Enasarco 8,50', - 'code': 'TC07', - 'account_receivable_id': account_receivable.id, - 'account_payable_id': account_payable.id, - 'journal_id': misc_journal.id, - 'payment_term': self.env.ref( - 'account.account_payment_term_advance').id, - 'wt_types': 'enasarco', - 'causale_pagamento_id': self.env.ref( - 'l10n_it_causali_pagamento.r').id, - 'rate_ids': [(0, 0, { - 'tax': 8.5, - 'base': 1.0, - })] - }) - self.env['withholding.tax'].create({ - 'name': '1040/3', - 'code': '1040', - 'account_receivable_id': account_receivable.id, - 'account_payable_id': account_payable.id, - 'journal_id': misc_journal.id, - 'payment_term': self.env.ref( - 'account.account_payment_term_advance').id, - 'wt_types': 'ritenuta', - 'causale_pagamento_id': self.env.ref( - 'l10n_it_causali_pagamento.a').id, - 'rate_ids': [(0, 0, { - 'tax': 11.50, - 'base': 1.0, - })] - }) - self.env['withholding.tax'].create({ - 'name': '1040 R', - 'code': '1040R', - 'account_receivable_id': account_receivable.id, - 'account_payable_id': account_payable.id, - 'journal_id': misc_journal.id, - 'payment_term': self.env.ref( - 'account.account_payment_term_advance').id, - 'wt_types': 'ritenuta', - 'causale_pagamento_id': self.env.ref( - 'l10n_it_causali_pagamento.r').id, - 'rate_ids': [(0, 0, { - 'tax': 11.50, - 'base': 1.0, - })] - }) + account_payable = self.env["account.account"].create( + { + "name": "Test WH tax", + "code": "whtaxpay2", + "user_type_id": self.env.ref("account.data_account_type_payable").id, + "reconcile": True, + } + ) + account_receivable = self.env["account.account"].create( + { + "name": "Test WH tax", + "code": "whtaxrec2", + "user_type_id": self.env.ref("account.data_account_type_receivable").id, + "reconcile": True, + } + ) + misc_journal = self.env["account.journal"].search([("code", "=", "MISC")]) + self.env["withholding.tax"].create( + { + "name": "Enasarco", + "code": "TC07", + "account_receivable_id": account_receivable.id, + "account_payable_id": account_payable.id, + "journal_id": misc_journal.id, + "payment_term": self.env.ref("account.account_payment_term_advance").id, + "wt_types": "enasarco", + "causale_pagamento_id": self.env.ref("l10n_it_causali_pagamento.r").id, + "rate_ids": [ + ( + 0, + 0, + { + "tax": 1.57, + "base": 1.0, + }, + ) + ], + } + ) + self.env["withholding.tax"].create( + { + "name": "Enasarco 8,50", + "code": "TC07", + "account_receivable_id": account_receivable.id, + "account_payable_id": account_payable.id, + "journal_id": misc_journal.id, + "payment_term": self.env.ref("account.account_payment_term_advance").id, + "wt_types": "enasarco", + "causale_pagamento_id": self.env.ref("l10n_it_causali_pagamento.r").id, + "rate_ids": [ + ( + 0, + 0, + { + "tax": 8.5, + "base": 1.0, + }, + ) + ], + } + ) + self.env["withholding.tax"].create( + { + "name": "1040/3", + "code": "1040", + "account_receivable_id": account_receivable.id, + "account_payable_id": account_payable.id, + "journal_id": misc_journal.id, + "payment_term": self.env.ref("account.account_payment_term_advance").id, + "wt_types": "ritenuta", + "causale_pagamento_id": self.env.ref("l10n_it_causali_pagamento.a").id, + "rate_ids": [ + ( + 0, + 0, + { + "tax": 11.50, + "base": 1.0, + }, + ) + ], + } + ) + self.env["withholding.tax"].create( + { + "name": "1040 R", + "code": "1040R", + "account_receivable_id": account_receivable.id, + "account_payable_id": account_payable.id, + "journal_id": misc_journal.id, + "payment_term": self.env.ref("account.account_payment_term_advance").id, + "wt_types": "ritenuta", + "causale_pagamento_id": self.env.ref("l10n_it_causali_pagamento.r").id, + "rate_ids": [ + ( + 0, + 0, + { + "tax": 11.50, + "base": 1.0, + }, + ) + ], + } + ) # case with ENASARCO only in DatiCassaPrevidenziale and not in DatiRitenuta. # This should not happen, but it is valid for SDI - res = self.run_wizard('test01', 'IT05979361218_014.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test01", "IT05979361218_014.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) self.assertEqual(invoice.partner_id.name, "SOCIETA' ALPHA SRL") self.assertEqual(invoice.amount_untaxed, 2470.00) @@ -859,22 +887,18 @@ def test_01_xml_import_enasarco(self): self.assertEqual(invoice.amount_total, 3013.40) self.assertEqual(invoice.amount_net_pay, 2729.35) self.assertEqual(invoice.withholding_tax_amount, 284.05) - self.assertEqual(invoice.welfare_fund_ids[0].kind_id.code, 'N2') + self.assertEqual(invoice.welfare_fund_ids[0].kind_id.code, "N2") self.assertTrue(len(invoice.e_invoice_line_ids) == 1) - self.assertEqual( - invoice.e_invoice_line_ids[0].name, 'ACCONTO PROVVIGIONI') - self.assertEqual( - invoice.e_invoice_line_ids[0].qty, 1.0) - self.assertEqual( - invoice.e_invoice_line_ids[0].unit_price, 2470.0) - self.assertEqual( - invoice.e_invoice_line_ids[0].total_price, 2470.0) + self.assertEqual(invoice.e_invoice_line_ids[0].name, "ACCONTO PROVVIGIONI") + self.assertEqual(invoice.e_invoice_line_ids[0].qty, 1.0) + self.assertEqual(invoice.e_invoice_line_ids[0].unit_price, 2470.0) + self.assertEqual(invoice.e_invoice_line_ids[0].total_price, 2470.0) def test_02_xml_import_enasarco(self): # Giacomo Neri, agente di commercio di Firenze. # Imponibile 10 - res = self.run_wizard('test02', 'ITNREGCM80H30D612D_20003.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test02", "ITNREGCM80H30D612D_20003.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) self.assertEqual(invoice.amount_untaxed, 10.0) self.assertEqual(invoice.amount_tax, 2.2) @@ -884,11 +908,12 @@ def test_02_xml_import_enasarco(self): def test_03_xml_import_enasarco(self): # Come sopra, ma senza "SI" in riga fattura - res = self.run_wizard('test03', 'ITNREGCM80H30D612D_20004.xml') - invoice_id = res.get('domain')[0][2][0] + res = self.run_wizard("test03", "ITNREGCM80H30D612D_20004.xml") + invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) self.assertTrue( - 'E-bill contains DatiRitenuta but no lines subjected to Ritenuta was found' - in invoice.e_invoice_validation_message) + "E-bill contains DatiRitenuta but no lines subjected to Ritenuta was found" + in invoice.e_invoice_validation_message + ) self.assertEqual(invoice.amount_total, 12.2) self.assertEqual(invoice.amount_net_pay, 12.2) diff --git a/l10n_it_fatturapa_in/views/account_view.xml b/l10n_it_fatturapa_in/views/account_view.xml index e5453e1f1f98..9e7e2cdd5a34 100644 --- a/l10n_it_fatturapa_in/views/account_view.xml +++ b/l10n_it_fatturapa_in/views/account_view.xml @@ -1,4 +1,4 @@ - + @@ -6,61 +6,93 @@ fatturapa.attachment.in
-