From 74abccd5ad07af901238c3788c45e416ff1bab1f Mon Sep 17 00:00:00 2001 From: Simone Rubino Date: Fri, 6 Sep 2024 15:45:58 +0200 Subject: [PATCH] [FIX] l10n_it_fatturapa_in: Let the move line compute its account In `16.0` the field `account.move.line.account_id` is computed based on many factors, for instance the most used account by the supplier. This also allows other modules like `account_invoice_line_default_account` to work as expected. --- .../tests/test_import_fatturapa_xml.py | 20 +-- .../wizard/wizard_import_fatturapa.py | 129 +++++++++--------- 2 files changed, 65 insertions(+), 84 deletions(-) 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 9f2d36ccde2c..a4f03478045e 100644 --- a/l10n_it_fatturapa_in/tests/test_import_fatturapa_xml.py +++ b/l10n_it_fatturapa_in/tests/test_import_fatturapa_xml.py @@ -208,31 +208,15 @@ def test_08_xml_import_no_account(self): journal_account = journal.default_account_id journal.default_account_id = False - expense_default_property = self.env["ir.property"]._get_property( - "property_account_expense_categ_id", - "product.category", - res_id=False, - ) - # Setting res_id disables the property from acting as default value - expense_default_property.res_id = 1 - with self.assertRaises(UserError) as ue: + with self.assertRaises(UserError) as ue, mute_logger("odoo.sql_db"): res = self.run_wizard("test8_no_account", "IT05979361218_005.xml") # allow following code to reuse the same XML file invoice_id = res.get("domain")[0][2][0] invoice = self.invoice_model.browse(invoice_id) invoice.ref = invoice.payment_reference = "14082" self.assertIn(journal.display_name, ue.exception.args[0]) - self.assertIn(company.display_name, ue.exception.args[0]) - - # Restore the property and import the invoice - expense_default_property.res_id = False - res = self.run_wizard("test8_with_property", "IT05979361218_005.xml") - invoice_id = res.get("domain")[0][2][0] - invoice = self.invoice_model.browse(invoice_id) - # allow following code to reuse the same XML file - invoice.ref = invoice.payment_reference = "14083" - # Restore the property and import the invoice + # Restore the journal account and import the invoice journal.default_account_id = journal_account res = self.run_wizard("test8_with_journal", "IT05979361218_005.xml") invoice_id = res.get("domain")[0][2][0] diff --git a/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py b/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py index c765d94878ac..6abbfe7f1c12 100644 --- a/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py +++ b/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py @@ -4,8 +4,11 @@ import logging import re +import warnings from datetime import datetime +import psycopg2 + from odoo import api, fields, models from odoo.exceptions import UserError from odoo.fields import first @@ -614,14 +617,9 @@ def get_line_product(self, line, partner): return product def adjust_accounting_data(self, product, line_vals): - account = self.get_credit_account(product) - line_vals["account_id"] = account.id - new_tax = None if len(product.product_tmpl_id.supplier_taxes_id) == 1: new_tax = product.product_tmpl_id.supplier_taxes_id[0] - elif len(account.tax_ids) == 1: - new_tax = account.tax_ids[0] line_tax = self.env["account.tax"] if ( line_vals.get("tax_ids") @@ -651,10 +649,16 @@ def adjust_accounting_data(self, product, line_vals): # move_line.tax_ids # move_line.name # move_line.sequence - # move_line.account_id # move_line.price_unit # move_line.quantity def _prepareInvoiceLineAliquota(self, credit_account_id, line, nline): + if credit_account_id: + warnings.warn( + "The `credit_account_id` argument is deprecated " + "because the account is automatically computed from the move line.", + DeprecationWarning, + stacklevel=2, + ) retLine = {} account_taxes = self.get_account_taxes(line.AliquotaIVA, line.Natura) if account_taxes: @@ -666,7 +670,6 @@ def _prepareInvoiceLineAliquota(self, credit_account_id, line, nline): { "name": f"Riepilogo Aliquota {line.AliquotaIVA}", "sequence": nline, - "account_id": credit_account_id, "price_unit": float(abs(line.ImponibileImporto)), } ) @@ -674,19 +677,24 @@ def _prepareInvoiceLineAliquota(self, credit_account_id, line, nline): # move_line.name # move_line.sequence - # move_line.account_id # move_line.price_unit # move_line.quantity # move_line.discount # move_line.admin_ref # move_line.invoice_line_tax_wt_ids def _prepareInvoiceLine(self, credit_account_id, line, wt_founds=False): + if credit_account_id: + warnings.warn( + "The `credit_account_id` argument is deprecated " + "because the account is automatically computed from the move line.", + DeprecationWarning, + stacklevel=2, + ) retLine = self._prepare_generic_line_data(line) retLine.update( { "name": line.Descrizione, "sequence": int(line.NumeroLinea), - "account_id": credit_account_id, "price_unit": float(line.PrezzoUnitario), "display_type": "product", } @@ -1029,52 +1037,13 @@ def create_e_invoice_line(self, line): return einvoiceline def get_credit_account(self, product=None): - """ - Try to get default credit account for invoice line looking in - - 1) product (if provided) - 2) journal - 3) company default. - - :param product: Product whose expense account will be used - :return: The account found - """ - credit_account = self.env["account.account"].browse() - - # If there is a product, get its default expense account - if product: - template = product.product_tmpl_id - accounts_dict = template.get_product_accounts() - credit_account = accounts_dict["expense"] - - company = self.env.company - # Search in journal - journal = self.get_journal(company) - if not credit_account: - credit_account = journal.default_account_id - - # Search in company defaults - if not credit_account: - credit_account = ( - self.env["ir.property"] - .with_company(company) - ._get("property_account_expense_categ_id", "product.category") - ) - - if not credit_account: - raise UserError( - _( - "Please configure Default Credit Account " - "in Journal '{journal}' " - "or check default expense account " - "for company '{company}'." - ).format( - journal=journal.display_name, - company=company.display_name, - ) - ) - - return credit_account + warnings.warn( + "The `get_credit_account` method is deprecated " + "because the account is automatically computed from the move line.", + DeprecationWarning, + stacklevel=2, + ) + return self.env["account.account"].browse() def _get_currency(self, FatturaBody): # currency 2.1.1.2 @@ -1207,14 +1176,13 @@ def invoiceCreate(self, fatt, fatturapa_attachment, FatturaBody, partner_id): found_withholding_taxes = self.set_withholding_tax(FatturaBody, invoice_data) invoice = self.env["account.move"].create(invoice_data) - credit_account = self.get_credit_account() invoice_lines = [] # 2.2.1 invoice_lines.extend( self.set_invoice_line_ids( FatturaBody, - credit_account.id, + False, partner, found_withholding_taxes, invoice, @@ -1223,9 +1191,7 @@ def invoiceCreate(self, fatt, fatturapa_attachment, FatturaBody, partner_id): # 2.1.1.7 invoice_lines.extend( - self.set_welfares_fund( - FatturaBody, credit_account.id, invoice, found_withholding_taxes - ) + self.set_welfares_fund(FatturaBody, False, invoice, found_withholding_taxes) ) # 2.1.1.10 @@ -1600,6 +1566,13 @@ def set_withholding_tax(self, FatturaBody, invoice_data): return found_withholding_taxes def set_welfares_fund(self, FatturaBody, credit_account_id, invoice, wt_founds): + if credit_account_id: + warnings.warn( + "The `credit_account_id` argument is deprecated " + "because the account is automatically computed from the move line.", + DeprecationWarning, + stacklevel=2, + ) invoice_line_model = self.env["account.move.line"] invoice_line_ids = [] if self.e_invoice_detail_level == "2": @@ -1621,7 +1594,6 @@ def set_welfares_fund(self, FatturaBody, credit_account_id, invoice, wt_founds): "name": _("Welfare Fund: %s") % welfareLine.TipoCassa, "price_unit": float(welfareLine.ImportoContributoCassa), "move_id": invoice.id, - "account_id": credit_account_id, "quantity": 1, } ) @@ -1735,6 +1707,13 @@ def _set_invoice_lines( def set_invoice_line_ids( self, FatturaBody, credit_account_id, partner, wt_founds, invoice ): + if credit_account_id: + warnings.warn( + "The `credit_account_id` argument is deprecated " + "because the account is automatically computed from the move line.", + DeprecationWarning, + stacklevel=2, + ) invoice_lines = [] invoice_line_model = self.env["account.move.line"] if self.e_invoice_detail_level == "1": @@ -1779,11 +1758,29 @@ def check_invoice_amount(self, invoice, FatturaElettronicaBody): ) def create_and_get_line_id(self, invoice_line_ids, invoice_line_model, upd_vals): - invoice_line_id = ( - invoice_line_model.with_context(check_move_validity=False) - .create(upd_vals) - .id - ) + try: + with self.env.cr.savepoint(): + invoice_line_id = ( + invoice_line_model.with_context(check_move_validity=False) + .create(upd_vals) + .id + ) + except psycopg2.errors.CheckViolation as cv: + if ( + cv.diag.constraint_name + == "account_move_line_check_accountable_required_fields" + ): + move = self.env["account.move"].browse(upd_vals["move_id"]) + journal = move.journal_id + if journal: + raise UserError( + _( + "Please configure Default Credit Account " + "in Journal %(journal)s'.", + journal=journal.display_name, + ) + ) from cv + raise cv invoice_line_ids.append(invoice_line_id) def _set_decimal_precision(self, precision_name, field_name, attachments):