diff --git a/l10n_it_fatturapa_out_welfare/__manifest__.py b/l10n_it_fatturapa_out_welfare/__manifest__.py index 2515ada3fe2..6f51dad04eb 100644 --- a/l10n_it_fatturapa_out_welfare/__manifest__.py +++ b/l10n_it_fatturapa_out_welfare/__manifest__.py @@ -4,7 +4,7 @@ "name": "ITA - Fattura elettronica - Cassa previdenziale", "summary": "Registrazione della cassa previdenziale " "nelle fatture elettroniche in uscita", - "version": "12.0.1.0.1", + "version": "16.0.1.0.0", "development_status": "Beta", "category": "Localization/Italy", "website": "https://github.com/OCA/l10n-italy", @@ -12,14 +12,13 @@ "license": "AGPL-3", "depends": [ "account", - "l10n_it_fatturapa", - "l10n_it_fatturapa_out", "l10n_it_fatturapa_out_wt", + "l10n_it_payment_reason", ], "data": [ "security/ir.model.access.csv", - "views/account_invoice_line_views.xml", - "views/account_invoice_views.xml", + "views/account_move_views.xml", + "views/invoice_it_template.xml", "views/welfare_fund_type_amount_views.xml", ], } diff --git a/l10n_it_fatturapa_out_welfare/models/__init__.py b/l10n_it_fatturapa_out_welfare/models/__init__.py index 9164da3c28e..342a58d49ec 100644 --- a/l10n_it_fatturapa_out_welfare/models/__init__.py +++ b/l10n_it_fatturapa_out_welfare/models/__init__.py @@ -1,5 +1,5 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -from . import account_invoice -from . import account_invoice_line +from . import account_move +from . import account_move_line from . import welfare_fund_type_amount diff --git a/l10n_it_fatturapa_out_welfare/models/account_invoice.py b/l10n_it_fatturapa_out_welfare/models/account_move.py similarity index 93% rename from l10n_it_fatturapa_out_welfare/models/account_invoice.py rename to l10n_it_fatturapa_out_welfare/models/account_move.py index 10179af2a8c..f555af96e54 100644 --- a/l10n_it_fatturapa_out_welfare/models/account_invoice.py +++ b/l10n_it_fatturapa_out_welfare/models/account_move.py @@ -5,8 +5,8 @@ from odoo.exceptions import UserError -class AccountInvoice(models.Model): - _inherit = "account.invoice" +class AccountMove(models.Model): + _inherit = "account.move" should_regenerate_welfare_lines = fields.Boolean( compute="_compute_should_regenerate_welfare_lines", @@ -51,10 +51,9 @@ def button_regenerate_welfare_lines(self): welfare_grouping_lines = self.env[invoice_lines._name].create( welfare_grouping_lines_values, ) - self.compute_taxes() return welfare_grouping_lines - def action_invoice_open(self): + def action_post(self): need_welfare_invoices = self.filtered("should_regenerate_welfare_lines") if need_welfare_invoices: raise UserError( @@ -64,4 +63,4 @@ def action_invoice_open(self): ) ) ) - return super().action_invoice_open() + return super().action_post() diff --git a/l10n_it_fatturapa_out_welfare/models/account_invoice_line.py b/l10n_it_fatturapa_out_welfare/models/account_move_line.py similarity index 92% rename from l10n_it_fatturapa_out_welfare/models/account_invoice_line.py rename to l10n_it_fatturapa_out_welfare/models/account_move_line.py index 6bed8f136e7..16d89c6e720 100644 --- a/l10n_it_fatturapa_out_welfare/models/account_invoice_line.py +++ b/l10n_it_fatturapa_out_welfare/models/account_move_line.py @@ -4,8 +4,8 @@ from odoo import fields, models -class AccountInvoiceLine(models.Model): - _inherit = "account.invoice.line" +class AccountMoveLine(models.Model): + _inherit = "account.move.line" welfare_fund_type_amount_ids = fields.Many2many( comodel_name="welfare.fund.type.amount", @@ -18,7 +18,7 @@ class AccountInvoiceLine(models.Model): help="Welfare Amount represented by this Invoice Line.", ) welfare_grouping_invoice_line_ids = fields.Many2many( - comodel_name="account.invoice.line", + comodel_name="account.move.line", relation="welfare_group_invoice_line_rel", column1="grouping_line", column2="grouped_line", @@ -26,7 +26,7 @@ class AccountInvoiceLine(models.Model): help="Invoice Lines that represent this Line's Welfare Amount.", ) welfare_grouped_invoice_line_ids = fields.Many2many( - comodel_name="account.invoice.line", + comodel_name="account.move.line", relation="welfare_group_invoice_line_rel", column1="grouped_line", column2="grouping_line", diff --git a/l10n_it_fatturapa_out_welfare/models/welfare_fund_type_amount.py b/l10n_it_fatturapa_out_welfare/models/welfare_fund_type_amount.py index fd0dcd0b1c8..d12741686cc 100644 --- a/l10n_it_fatturapa_out_welfare/models/welfare_fund_type_amount.py +++ b/l10n_it_fatturapa_out_welfare/models/welfare_fund_type_amount.py @@ -65,10 +65,10 @@ def _prepare_grouping_invoice_line(self, invoice_lines): return { "name": self.display_name, "account_id": first_line.account_id.id, - "invoice_line_tax_ids": [ - (6, 0, first_line.invoice_line_tax_ids.ids), + "tax_ids": [ + (6, 0, first_line.tax_ids.ids), ], - "invoice_id": first_line.invoice_id.id, + "move_id": first_line.move_id.id, "welfare_grouping_fund_type_amount_id": self.id, "welfare_grouped_invoice_line_ids": [ (6, 0, invoice_lines.ids), diff --git a/l10n_it_fatturapa_out_welfare/tests/data/IT06363391001_random.xml b/l10n_it_fatturapa_out_welfare/tests/data/IT06363391001_random.xml index d879942d19e..7b7097a4b72 100644 --- a/l10n_it_fatturapa_out_welfare/tests/data/IT06363391001_random.xml +++ b/l10n_it_fatturapa_out_welfare/tests/data/IT06363391001_random.xml @@ -64,11 +64,11 @@ TD01 EUR - 2023-01-01 - INV/2023/0001 + 2024-01-01 + INV/2024/00001 RT02 - 20.00 + 40.00 20.00 A @@ -94,8 +94,8 @@ 1 Cabinet with Doors - 1.000 - Unit(s) + 1.00 + Units 100.00000 100.00 22.00 @@ -103,8 +103,8 @@ 2 Cabinet with Doors - 1.000 - Unit(s) + 1.00 + Units 100.00000 100.00 22.00 @@ -113,11 +113,12 @@ 3 Cabinet with Doors - 1.000 - Unit(s) + 1.00 + Units 100.00000 100.00 22.00 + SI 22.00 @@ -125,5 +126,13 @@ 74.80 + + TP02 + + MP05 + 2024-02-29 + 374.80 + + diff --git a/l10n_it_fatturapa_out_welfare/tests/test_fatturapa_out_welfare.py b/l10n_it_fatturapa_out_welfare/tests/test_fatturapa_out_welfare.py index 295b1ae1c86..115599b64ef 100644 --- a/l10n_it_fatturapa_out_welfare/tests/test_fatturapa_out_welfare.py +++ b/l10n_it_fatturapa_out_welfare/tests/test_fatturapa_out_welfare.py @@ -4,13 +4,14 @@ import base64 from odoo.exceptions import UserError -from odoo.tests import Form +from odoo.tests import Form, tagged from odoo.addons.l10n_it_fatturapa_out.tests.fatturapa_common import ( FatturaPACommon, ) +@tagged("post_install", "-at_install") class TestFatturaPAOUTWelfare(FatturaPACommon): def _get_welfare_amount(self, welfare, amount): """ @@ -30,9 +31,7 @@ def _get_payable_account(self): payable_account_form = Form(account_model) payable_account_form.name = "Withholding Credit" payable_account_form.code = "WTPAY" - payable_account_form.user_type_id = self.env.ref( - "account.data_account_type_payable" - ) + payable_account_form.account_type = "liability_payable" payable_account = payable_account_form.save() return payable_account @@ -46,8 +45,8 @@ def _get_withholding_tax(self, payable_account, receivable_account): withholding_tax_form.code = "TWT" withholding_tax_form.account_receivable_id = receivable_account withholding_tax_form.account_payable_id = payable_account - withholding_tax_form.causale_pagamento_id = self.env.ref( - "l10n_it_causali_pagamento.a" + withholding_tax_form.payment_reason_id = self.env.ref( + "l10n_it_payment_reason.a" ) withholding_tax_form.payment_term = self.env.ref( "account.account_payment_term_immediate" @@ -71,68 +70,92 @@ def _get_invoice(self): ("state", "=", "open"), ], ) - journals = open_invoices.mapped("journal_id") - journals.update( + open_invoices.button_cancel() + + invoice = self.invoice_model.create( { - "update_posted": True, + "invoice_date": "2024-01-01", + "partner_id": self.res_partner_fatturapa_0.id, + "journal_id": self.sales_journal.id, + "invoice_payment_term_id": self.account_payment_term.id, + "user_id": self.user_demo.id, + "move_type": "out_invoice", + "currency_id": self.EUR.id, + "invoice_line_ids": [ + ( + 0, + 0, + { + "product_id": self.product_product_10.id, + "price_unit": 100, + "tax_ids": [(6, 0, [self.tax_22.id])], + "welfare_fund_type_amount_ids": [(5, 0, 0)], + }, + ), + ( + 0, + 0, + { + "product_id": self.product_product_10.id, + "price_unit": 100, + "tax_ids": [(6, 0, [self.tax_22.id])], + "invoice_line_tax_wt_ids": [ + (6, 0, [self.withholding_tax.id]) + ], + "welfare_fund_type_amount_ids": [ + (6, 0, [self.welfare_amount_INPS_10.id]) + ], + }, + ), + ( + 0, + 0, + { + "product_id": self.product_product_10.id, + "price_unit": 100, + "tax_ids": [(6, 0, [self.tax_22.id])], + "invoice_line_tax_wt_ids": [ + (6, 0, [self.withholding_tax.id]) + ], + "welfare_fund_type_amount_ids": [ + ( + 6, + 0, + [ + self.welfare_amount_ENPAM_20.id, + self.welfare_amount_INPS_10.id, + ], + ) + ], + }, + ), + ], } ) - open_invoices.action_cancel() - - date_invoice = "2023-01-01" - self.set_sequences(1, date_invoice) - # Explicitly request the customer invoice form view, - # otherwise the supplier form view is automatically picked up - invoice_form = Form( - self.invoice_model, - "account.invoice_form", - ) - invoice_form.partner_id = self.res_partner_fatturapa_0 - invoice_form.date_invoice = date_invoice - with invoice_form.invoice_line_ids.new() as invoice_line: - invoice_line.product_id = self.product_product_10 - invoice_line.price_unit = 100 - invoice_line.invoice_line_tax_ids.clear() - invoice_line.invoice_line_tax_ids.add( - self.tax_22, - ) - invoice_line.welfare_fund_type_amount_ids.clear() - - with invoice_form.invoice_line_ids.new() as invoice_line: - invoice_line.product_id = self.product_product_10 - invoice_line.price_unit = 100 - invoice_line.invoice_line_tax_ids.clear() - invoice_line.invoice_line_tax_ids.add( - self.tax_22, - ) - invoice_line.welfare_fund_type_amount_ids.clear() - invoice_line.welfare_fund_type_amount_ids.add( - self.welfare_amount_INPS_10, - ) - invoice_line.invoice_line_tax_wt_ids.clear() - invoice_line.invoice_line_tax_wt_ids.add( - self.withholding_tax, - ) - - with invoice_form.invoice_line_ids.new() as invoice_line: - invoice_line.product_id = self.product_product_10 - invoice_line.price_unit = 100 - invoice_line.invoice_line_tax_ids.clear() - invoice_line.invoice_line_tax_ids.add( - self.tax_22, - ) - invoice_line.welfare_fund_type_amount_ids.clear() - invoice_line.welfare_fund_type_amount_ids.add( - self.welfare_amount_ENPAM_20, - ) - invoice_line.welfare_fund_type_amount_ids.add( - self.welfare_amount_INPS_10, - ) - invoice = invoice_form.save() return invoice def setUp(self): super().setUp() + self.company = self.env.company = self.sales_journal.company_id + + # XXX - a company named "YourCompany" alread exists + # we move it out of the way but we should do better here + self.env.company.sudo().search([("name", "=", "YourCompany")]).write( + {"name": "YourCompany_"} + ) + self.env.company.name = "YourCompany" + self.env.company.vat = "IT06363391001" + self.env.company.fatturapa_art73 = True + self.env.company.partner_id.street = "Via Milano, 1" + self.env.company.partner_id.city = "Roma" + self.env.company.partner_id.state_id = self.env.ref("base.state_us_2").id + self.env.company.partner_id.zip = "00100" + self.env.company.partner_id.phone = "06543534343" + self.env.company.email = "info@yourcompany.example.com" + self.env.company.partner_id.country_id = self.env.ref("base.it").id + self.env.company.fatturapa_fiscal_position_id = self.env.ref( + "l10n_it_fatturapa.fatturapa_RF01" + ).id self.welfare_amount_INPS_10 = self._get_welfare_amount( self.env.ref("l10n_it_fatturapa.21"), 10, @@ -158,14 +181,15 @@ def test_export_welfare_withholding(self): # Check that Welfare Lines have to be generated # before validating the invoice with self.assertRaises(UserError) as ue: - invoice.action_invoice_open() + invoice.action_post() exc_message = ue.exception.args[0] self.assertIn("regenerate Welfare Lines", exc_message) self.assertIn(invoice.display_name, exc_message) # Export the Electronic Invoice + invoice._onchange_invoice_line_wt_ids() invoice.button_regenerate_welfare_lines() - invoice.action_invoice_open() + invoice.action_post() res = self.run_wizard(invoice.id) attachment = self.attach_model.browse(res["res_id"]) self.set_e_invoice_file_id(attachment, "IT06363391001_random.xml") diff --git a/l10n_it_fatturapa_out_welfare/views/account_invoice_line_views.xml b/l10n_it_fatturapa_out_welfare/views/account_invoice_line_views.xml deleted file mode 100644 index 8a077da4762..00000000000 --- a/l10n_it_fatturapa_out_welfare/views/account_invoice_line_views.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - Add Welfare Fund Type Amount to Invoice Line Form View - account.invoice.line - - - - - - - - - - Add Welfare Fund Type Amount to Invoice Line Tree View - account.invoice.line - - - - - - - - diff --git a/l10n_it_fatturapa_out_welfare/views/account_invoice_views.xml b/l10n_it_fatturapa_out_welfare/views/account_move_views.xml similarity index 65% rename from l10n_it_fatturapa_out_welfare/views/account_invoice_views.xml rename to l10n_it_fatturapa_out_welfare/views/account_move_views.xml index 8adde1998f4..b7d03f55904 100644 --- a/l10n_it_fatturapa_out_welfare/views/account_invoice_views.xml +++ b/l10n_it_fatturapa_out_welfare/views/account_move_views.xml @@ -5,10 +5,12 @@ --> - - Add Welfare Fund Type Amount to Invoice Form View - account.invoice - + + Add Welfare Fund Type Amount to Invoice Line Form View + account.move + + + + Add Welfare Fund Type Amount to Invoice Line Tree View + account.move.line + + + + + + + diff --git a/l10n_it_fatturapa_out_welfare/views/invoice_it_template.xml b/l10n_it_fatturapa_out_welfare/views/invoice_it_template.xml new file mode 100644 index 00000000000..5dc538509fa --- /dev/null +++ b/l10n_it_fatturapa_out_welfare/views/invoice_it_template.xml @@ -0,0 +1,52 @@ + + + + + + + + + diff --git a/l10n_it_fatturapa_out_welfare/wizards/wizard_export_fatturapa.py b/l10n_it_fatturapa_out_welfare/wizards/wizard_export_fatturapa.py index 2bc19ca349a..193d4e5c277 100644 --- a/l10n_it_fatturapa_out_welfare/wizards/wizard_export_fatturapa.py +++ b/l10n_it_fatturapa_out_welfare/wizards/wizard_export_fatturapa.py @@ -5,10 +5,6 @@ from odoo.fields import first from odoo.tools.float_utils import float_is_zero, float_round -from odoo.addons.l10n_it_fatturapa.bindings.fatturapa import ( - DatiCassaPrevidenzialeType, -) - def formatRateType(amount): return "%.2f" % float_round(abs(amount), 2) @@ -21,7 +17,7 @@ def formatAmount2DecimalType(amount): class WizardExportFatturapa(models.TransientModel): _inherit = "wizard.export.fatturapa" - def _get_DatiCassaPrevidenziale(self, invoice_line): + def get_dati_cassa_previdenziale(self, invoice_line): """ Return node DatiCassaPrevidenziale, its values are based on `invoice_line`. @@ -30,61 +26,64 @@ def _get_DatiCassaPrevidenziale(self, invoice_line): welfare_amount = invoice_line.welfare_grouping_fund_type_amount_id if welfare_amount: # Mandatory fields - tax = first(invoice_line.invoice_line_tax_ids) - DatiCassaPrevidenziale = DatiCassaPrevidenzialeType( - TipoCassa=welfare_amount.welfare_fund_type_id.name, - AlCassa=formatRateType(welfare_amount.amount), - ImportoContributoCassa=formatAmount2DecimalType( + tax = first(invoice_line.tax_ids) + DatiCassaPrevidenziale = { + "TipoCassa": welfare_amount.welfare_fund_type_id.name, + "AlCassa": formatRateType(welfare_amount.amount), + "ImportoContributoCassa": formatAmount2DecimalType( invoice_line.price_subtotal, ), - AliquotaIVA=formatRateType(tax.amount), - ) + "AliquotaIVA": formatRateType(tax.amount), + } # Optional fields grouped_lines = invoice_line.welfare_grouped_invoice_line_ids grouped_lines_subtotal = sum(grouped_lines.mapped("price_subtotal")) + DatiCassaPrevidenziale["ImponibileCassa"] = False if not float_is_zero(grouped_lines_subtotal, 2): grouped_lines_subtotal = formatAmount2DecimalType( grouped_lines_subtotal ) - DatiCassaPrevidenziale.ImponibileCassa = grouped_lines_subtotal + DatiCassaPrevidenziale["ImponibileCassa"] = grouped_lines_subtotal + DatiCassaPrevidenziale["Ritenuta"] = False withholding_taxes = invoice_line.invoice_line_tax_wt_ids if withholding_taxes: - DatiCassaPrevidenziale.Ritenuta = "SI" + DatiCassaPrevidenziale["Ritenuta"] = True + DatiCassaPrevidenziale["Natura"] = False tax_kind = tax.kind_id if tax_kind: - DatiCassaPrevidenziale.Natura = tax_kind.code + DatiCassaPrevidenziale["Natura"] = tax_kind.code + DatiCassaPrevidenziale["RiferimentoAmministrazione"] = False administration_reference = welfare_amount.administration_reference if administration_reference: - DatiCassaPrevidenziale.RiferimentoAmministrazione = ( - administration_reference - ) + DatiCassaPrevidenziale[ + "RiferimentoAmministrazione" + ] = administration_reference + return DatiCassaPrevidenziale - def setDatiCassaPrevidenziale(self, invoice, body): - """ - Set in `body` and return all the nodes DatiCassaPrevidenziale, - their values are based on `invoice`. - """ - DatiCassaPrevidenziale_list = list() - for invoice_line in invoice.invoice_line_ids: - DatiCassaPrevidenziale = self._get_DatiCassaPrevidenziale( - invoice_line, - ) - if DatiCassaPrevidenziale: - DatiCassaPrevidenziale_list.append(DatiCassaPrevidenziale) - body.DatiGenerali.DatiGeneraliDocumento.DatiCassaPrevidenziale = ( - DatiCassaPrevidenziale_list - ) - return body.DatiGenerali.DatiGeneraliDocumento.DatiCassaPrevidenziale - - def setDatiGeneraliDocumento(self, invoice, body): - res = super(WizardExportFatturapa, self).setDatiGeneraliDocumento(invoice, body) - self.setDatiCassaPrevidenziale(invoice, body) - return res + @api.model + def getTemplateValues(self, template_values): + def set_dati_cassa_previdenziale(invoice): + """ + Set in `body` and return all the nodes DatiCassaPrevidenziale, + their values are based on `invoice`. + """ + DatiCassaPrevidenziale_list = list() + for invoice_line in invoice.invoice_line_ids: + DatiCassaPrevidenziale = self.get_dati_cassa_previdenziale( + invoice_line, + ) + if DatiCassaPrevidenziale: + DatiCassaPrevidenziale_list.append(DatiCassaPrevidenziale) + return DatiCassaPrevidenziale_list + + template_values = super().getTemplateValues(template_values) + template_values["set_dati_cassa_previdenziale"] = set_dati_cassa_previdenziale + return template_values @api.model def _get_e_invoice_lines(self, invoice):