From e41f2f720df2d1f653d4f715fbefdbe49f9c6574 Mon Sep 17 00:00:00 2001 From: william-andre Date: Tue, 17 Jan 2023 12:35:30 +0000 Subject: [PATCH] [REF] account: merge repartition lines m2o field Part-of: odoo/odoo#110016 --- addons/account/models/account_account.py | 8 +- .../models/account_partial_reconcile.py | 2 +- addons/account/models/account_tax.py | 106 +++++++++--------- addons/l10n_eu_oss/models/res_company.py | 20 ++-- addons/point_of_sale/models/pos_session.py | 10 +- 5 files changed, 72 insertions(+), 74 deletions(-) diff --git a/addons/account/models/account_account.py b/addons/account/models/account_account.py index 8232efd9f7b..23c066b3703 100644 --- a/addons/account/models/account_account.py +++ b/addons/account/models/account_account.py @@ -365,9 +365,7 @@ class AccountAccount(models.Model): def _compute_related_taxes_amount(self): for record in self: record.related_taxes_amount = self.env['account.tax'].search_count([ - '|', - ('invoice_repartition_line_ids.account_id', '=', record.id), - ('refund_repartition_line_ids.account_id', '=', record.id), + ('repartition_line_ids.account_id', '=', record.id), ]) def _compute_opening_debit_credit(self): @@ -753,9 +751,7 @@ class AccountAccount(models.Model): def action_open_related_taxes(self): related_taxes_ids = self.env['account.tax'].search([ - '|', - ('invoice_repartition_line_ids.account_id', '=', self.id), - ('refund_repartition_line_ids.account_id', '=', self.id), + ('repartition_line_ids.account_id', '=', self.id), ]).ids return { 'type': 'ir.actions.act_window', diff --git a/addons/account/models/account_partial_reconcile.py b/addons/account/models/account_partial_reconcile.py index 0056815987c..bb5a74c5b7d 100644 --- a/addons/account/models/account_partial_reconcile.py +++ b/addons/account/models/account_partial_reconcile.py @@ -291,7 +291,7 @@ class AccountPartialReconcile(models.Model): account.move.line. ''' tax_ids = tax_line.tax_ids.filtered(lambda x: x.tax_exigibility == 'on_payment') - base_tags = tax_ids.get_tax_tags(tax_line.tax_repartition_line_id.refund_tax_id, 'base') + base_tags = tax_ids.get_tax_tags(tax_line.tax_repartition_line_id.filtered(lambda rl: rl.document_type == 'refund').tax_id, 'base') product_tags = tax_line.tax_tag_ids.filtered(lambda x: x.applicability == 'products') all_tags = base_tags + tax_line.tax_repartition_line_id.tag_ids + product_tags diff --git a/addons/account/models/account_tax.py b/addons/account/models/account_tax.py index dab9587751b..f098c514740 100644 --- a/addons/account/models/account_tax.py +++ b/addons/account/models/account_tax.py @@ -139,8 +139,27 @@ class AccountTax(models.Model): domain="[('deprecated', '=', False), ('company_id', '=', company_id)]", comodel_name='account.account', help="Account used to transition the tax amount for cash basis taxes. It will contain the tax amount as long as the original invoice has not been reconciled ; at reconciliation, this amount cancelled on this account and put on the regular tax account.") - invoice_repartition_line_ids = fields.One2many(string="Distribution for Invoices", comodel_name="account.tax.repartition.line", inverse_name="invoice_tax_id", copy=True, help="Distribution when the tax is used on an invoice") - refund_repartition_line_ids = fields.One2many(string="Distribution for Refund Invoices", comodel_name="account.tax.repartition.line", inverse_name="refund_tax_id", copy=True, help="Distribution when the tax is used on a refund") + invoice_repartition_line_ids = fields.One2many( + string="Distribution for Invoices", + comodel_name="account.tax.repartition.line", + inverse_name="tax_id", + domain=[('document_type', '=', 'invoice')], + help="Distribution when the tax is used on an invoice", + ) + refund_repartition_line_ids = fields.One2many( + string="Distribution for Refund Invoices", + comodel_name="account.tax.repartition.line", + inverse_name="tax_id", + domain=[('document_type', '=', 'refund')], + help="Distribution when the tax is used on a refund", + ) + repartition_line_ids = fields.One2many( + string="Distribution", + comodel_name="account.tax.repartition.line", + inverse_name="tax_id", + copy=True, + help="Distribution when the tax is used on a refund", + ) country_id = fields.Many2one(string="Country", comodel_name='res.country', required=True, help="The country for which this tax is applicable.") country_code = fields.Char(related='country_id.code', readonly=True) @@ -165,17 +184,14 @@ class AccountTax(models.Model): if 'country_id' in fields_list: rslt['country_id'] = company.account_fiscal_country_id.id - if 'refund_repartition_line_ids' in fields_list: - rslt['refund_repartition_line_ids'] = [ - (0, 0, {'repartition_type': 'base', 'tag_ids': [], 'company_id': company_id}), - (0, 0, {'repartition_type': 'tax', 'tag_ids': [], 'company_id': company_id}), - ] - - if 'invoice_repartition_line_ids' in fields_list: - rslt['invoice_repartition_line_ids'] = [ - (0, 0, {'repartition_type': 'base', 'tag_ids': [], 'company_id': company_id}), - (0, 0, {'repartition_type': 'tax', 'tag_ids': [], 'company_id': company_id}), - ] + repartition = rslt.setdefault('repartition_line_ids', []) + if 'repartition_line_ids' in fields_list and not repartition: + repartition.extend([ + Command.create({'document_type': 'invoice', 'repartition_type': 'base', 'tag_ids': [], 'company_id': company_id}), + Command.create({'document_type': 'invoice', 'repartition_type': 'tax', 'tag_ids': [], 'company_id': company_id}), + Command.create({'document_type': 'refund', 'repartition_type': 'base', 'tag_ids': [], 'company_id': company_id}), + Command.create({'document_type': 'refund', 'repartition_type': 'tax', 'tag_ids': [], 'company_id': company_id}), + ]) return rslt @@ -266,6 +282,20 @@ class AccountTax(models.Model): if self._cr.fetchone(): raise UserError(_("You can't change the company of your tax since there are some journal items linked to it.")) + @api.model_create_multi + def create(self, vals_list): + for vals in vals_list: + for doc_type in ('invoice', 'refund'): + fname = f"{doc_type}_repartition_line_ids" + if fname in vals: + repartition = vals.setdefault('repartition_line_ids', []) + repartition.extend([ + (command, id, {'document_type': doc_type, **v}) + for command, id, v in vals.pop(fname) + ]) + return super().create(vals_list) + + @api.returns('self', lambda value: value.id) def copy(self, default=None): default = dict(default or {}) @@ -400,8 +430,10 @@ class AccountTax(models.Model): return all_taxes def get_tax_tags(self, is_refund, repartition_type): - rep_lines = self.mapped(is_refund and 'refund_repartition_line_ids' or 'invoice_repartition_line_ids') - return rep_lines.filtered(lambda x: x.repartition_type == repartition_type).mapped('tag_ids') + return self.repartition_line_ids.filtered(lambda x: ( + x.repartition_type == repartition_type + and x.document_type == ('refund' if is_refund else 'invoice') + )).mapped('tag_ids') def compute_all(self, price_unit, currency=None, quantity=1.0, product=None, partner=None, is_refund=False, handle_price_include=True, include_caba_tags=False, fixed_multiplicator=1): """Compute all information required to apply taxes (in self + their children in case of a tax group). @@ -1234,30 +1266,15 @@ class AccountTaxRepartitionLine(models.Model): ) factor = fields.Float(string="Factor Ratio", compute="_compute_factor", help="Factor to apply on the account move lines generated from this distribution line") repartition_type = fields.Selection(string="Based On", selection=[('base', 'Base'), ('tax', 'of tax')], required=True, default='tax', help="Base on which the factor will be applied.") + document_type = fields.Selection(string="Related to", selection=[('invoice', 'Invoice'), ('refund', 'Refund')], required=True) account_id = fields.Many2one(string="Account", comodel_name='account.account', domain="[('deprecated', '=', False), ('company_id', '=', company_id), ('account_type', 'not in', ('asset_receivable', 'liability_payable'))]", check_company=True, help="Account on which to post the tax amount") tag_ids = fields.Many2many(string="Tax Grids", comodel_name='account.account.tag', domain=[('applicability', '=', 'taxes')], copy=True) - invoice_tax_id = fields.Many2one(comodel_name='account.tax', - ondelete='cascade', - check_company=True, - help="The tax set to apply this distribution on invoices. Mutually exclusive with refund_tax_id") - refund_tax_id = fields.Many2one(comodel_name='account.tax', - ondelete='cascade', - check_company=True, - help="The tax set to apply this distribution on refund invoices. Mutually exclusive with invoice_tax_id") - tax_id = fields.Many2one(comodel_name='account.tax', compute='_compute_tax_id') - document_type = fields.Selection( - selection=[ - ('invoice', 'Invoice'), - ('refund', 'Refund'), - ], - compute='_compute_document_type', - help="The type of documnet on which the repartition line should be applied", - ) - company_id = fields.Many2one(string="Company", comodel_name='res.company', compute="_compute_company", store=True, help="The company this distribution line belongs to.") + tax_id = fields.Many2one(comodel_name='account.tax', ondelete='cascade', check_company=True) + company_id = fields.Many2one(string="Company", comodel_name='res.company', related="tax_id.company_id", store=True, help="The company this distribution line belongs to.") sequence = fields.Integer(string="Sequence", default=1, help="The order in which distribution lines are displayed and matched. For refunds to work properly, invoice distribution lines should be arranged in the same order as the credit note distribution lines they correspond to.") use_in_tax_closing = fields.Boolean(string="Tax Closing Entry", default=True) @@ -1269,13 +1286,7 @@ class AccountTaxRepartitionLine(models.Model): else: self.use_in_tax_closing = self.account_id.internal_group not in ('income', 'expense') - @api.constrains('invoice_tax_id', 'refund_tax_id') - def validate_tax_template_link(self): - for record in self: - if record.invoice_tax_id and record.refund_tax_id: - raise ValidationError(_("Tax distribution lines should apply to either invoices or refunds, not both at the same time. invoice_tax_id and refund_tax_id should not be set together.")) - - @api.constrains('invoice_tax_id', 'refund_tax_id', 'tag_ids') + @api.constrains('tax_id', 'tag_ids') def validate_tags_country(self): for record in self: if record.tag_ids.country_id and record.tax_id.country_id != record.tag_ids.country_id: @@ -1286,21 +1297,6 @@ class AccountTaxRepartitionLine(models.Model): for record in self: record.factor = record.factor_percent / 100.0 - @api.depends('invoice_tax_id.company_id', 'refund_tax_id.company_id') - def _compute_company(self): - for record in self: - record.company_id = record.invoice_tax_id and record.invoice_tax_id.company_id.id or record.refund_tax_id.company_id.id - - @api.depends('invoice_tax_id', 'refund_tax_id') - def _compute_tax_id(self): - for record in self: - record.tax_id = record.invoice_tax_id or record.refund_tax_id - - @api.depends('invoice_tax_id', 'refund_tax_id') - def _compute_document_type(self): - for record in self: - record.document_type = 'invoice' if record.invoice_tax_id else 'refund' - @api.onchange('repartition_type') def _onchange_repartition_type(self): if self.repartition_type == 'base': diff --git a/addons/l10n_eu_oss/models/res_company.py b/addons/l10n_eu_oss/models/res_company.py index 1d5a1c22321..f008f48932a 100644 --- a/addons/l10n_eu_oss/models/res_company.py +++ b/addons/l10n_eu_oss/models/res_company.py @@ -89,16 +89,18 @@ class Company(models.Model): def _get_repartition_lines_oss(self): self.ensure_one() - defaults = self.env['account.tax'].with_company(self).default_get(['invoice_repartition_line_ids', 'refund_repartition_line_ids']) + defaults = self.env['account.tax'].with_company(self).default_get(['repartition_line_ids']) oss_account, oss_tags = self._get_oss_account(), self._get_oss_tags() - base_line, tax_line, vals = 0, 1, 2 - for doc_type in 'invoice', 'refund': - if oss_account: - defaults[f'{doc_type}_repartition_line_ids'][tax_line][vals]['account_id'] = oss_account.id - if oss_tags: - defaults[f'{doc_type}_repartition_line_ids'][base_line][vals]['tag_ids'] += [Command.link(tag.id) for tag in oss_tags[f'{doc_type}_base_tag']] - defaults[f'{doc_type}_repartition_line_ids'][tax_line][vals]['tag_ids'] += [Command.link(tag.id) for tag in oss_tags[f'{doc_type}_tax_tag']] - return defaults['invoice_repartition_line_ids'], defaults['refund_repartition_line_ids'] + invoice_base_line, invoice_tax_line, refund_base_line, refund_tax_line, vals = 0, 1, 2, 3, 2 + if oss_account: + defaults['repartition_line_ids'][invoice_tax_line][vals]['account_id'] = oss_account.id + defaults['repartition_line_ids'][refund_tax_line][vals]['account_id'] = oss_account.id + if oss_tags: + defaults['repartition_line_ids'][invoice_base_line][vals]['tag_ids'] += [Command.link(tag.id) for tag in oss_tags['invoice_base_tag']] + defaults['repartition_line_ids'][invoice_tax_line][vals]['tag_ids'] += [Command.link(tag.id) for tag in oss_tags['invoice_tax_tag']] + defaults['repartition_line_ids'][refund_base_line][vals]['tag_ids'] += [Command.link(tag.id) for tag in oss_tags['refund_base_tag']] + defaults['repartition_line_ids'][refund_tax_line][vals]['tag_ids'] += [Command.link(tag.id) for tag in oss_tags['refund_tax_tag']] + return defaults['repartition_line_ids'][0:2], defaults['repartition_line_ids'][2:4] def _get_oss_account(self): self.ensure_one() diff --git a/addons/point_of_sale/models/pos_session.py b/addons/point_of_sale/models/pos_session.py index 0363e667eb3..0f38acf9f75 100644 --- a/addons/point_of_sale/models/pos_session.py +++ b/addons/point_of_sale/models/pos_session.py @@ -1728,11 +1728,15 @@ class PosSession(models.Model): # Add the 'sum_repartition_factor' as needed in the compute_all # Note that the factor = factor_percent/100 groups = self.env['account.tax.repartition.line'].read_group( - domain=[('invoice_tax_id', 'in', tuple([t['id'] for t in taxes])), ('repartition_type', '=', 'tax')], + domain=[ + ('tax_id', 'in', tuple([t['id'] for t in taxes])), + ('document_type', '=', 'invoice'), + ('repartition_type', '=', 'tax'), + ], fields=["factor_percent:sum"], - groupby=["invoice_tax_id"], + groupby=["tax_id"], ) - tax_id_to_factor_sum = {g['invoice_tax_id'][0]: g['factor_percent']/100 for g in groups} + tax_id_to_factor_sum = {g['tax_id'][0]: g['factor_percent']/100 for g in groups} for tax in taxes: tax['sum_repartition_factor'] = tax_id_to_factor_sum[tax['id']]