diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index d5d346628c9..0470655af7b 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -413,6 +413,8 @@ class AccountMoveLine(models.Model): invoice_id = fields.Many2one('account.invoice', oldname="invoice") partner_id = fields.Many2one('res.partner', string='Partner', ondelete='restrict') user_type_id = fields.Many2one('account.account.type', related='account_id.user_type_id', index=True, store=True, oldname="user_type") + tax_exigible = fields.Boolean(string='Appears in VAT report', default=True, + help="Technical field used to mark a tax line as exigible in the vat report or not (only exigible journal items are displayed). By default all new journal items are directly exigible, but with the module account_tax_cash_basis, some will become exigible only when the payment is recorded.") _sql_constraints = [ ('credit_debit1', 'CHECK (credit*debit=0)', 'Wrong credit or debit value in accounting entry !'), diff --git a/addons/account_tax_cash_basis/models/account_move.py b/addons/account_tax_cash_basis/models/account_move.py index 1fac8221343..73b99952501 100644 --- a/addons/account_tax_cash_basis/models/account_move.py +++ b/addons/account_tax_cash_basis/models/account_move.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo import models, fields +from odoo import api, models, fields class AccountMoveCashBasis(models.Model): @@ -12,3 +12,18 @@ class AccountMoveCashBasis(models.Model): string='Tax Cash Basis Entry of', help="Technical field used to keep track of the tax cash basis reconciliation." "This is needed when cancelling the source: it will post the inverse journal entry to cancel that part too.") + + +class AccountMoveLine(models.Model): + _inherit = "account.move.line" + + @api.model + def create(self, vals, apply_taxes=True): + taxes = False + if vals.get('tax_line_id'): + taxes = [{'use_cash_basis': self.env['account.tax'].browse(vals['tax_line_id']).use_cash_basis}] + if vals.get('tax_ids'): + taxes = self.env['account.move.line'].resolve_2many_commands('tax_ids', vals['tax_ids']) + if taxes and any([tax['use_cash_basis'] for tax in taxes]) and not vals.get('tax_exigible'): + vals['tax_exigible'] = False + return super(AccountMoveLine, self).create(vals, apply_taxes=apply_taxes) diff --git a/addons/account_tax_cash_basis/models/account_partial_reconcile.py b/addons/account_tax_cash_basis/models/account_partial_reconcile.py index bb6bff7f53c..8cf22009c9e 100644 --- a/addons/account_tax_cash_basis/models/account_partial_reconcile.py +++ b/addons/account_tax_cash_basis/models/account_partial_reconcile.py @@ -12,25 +12,47 @@ class AccountPartialReconcileCashBasis(models.Model): # Search in account_move if we have any taxes account move lines tax_group = {} total_by_cash_basis_account = {} + line_to_create = [] for move in (self.debit_move_id.move_id, self.credit_move_id.move_id): for line in move.line_ids: - if line.tax_line_id and line.tax_line_id.use_cash_basis: + #TOCHECK: normal and cash basis taxes shoudn't be mixed together (on the same invoice line for example) as it will + #create reporting issues. Not sure of the behavior to implement in that case, though. + if not line.tax_exigible: # amount to write is the current cash_basis amount minus the one before the reconciliation matched_percentage = value_before_reconciliation[move.id] amount = (line.credit_cash_basis - line.debit_cash_basis) - (line.credit - line.debit) * matched_percentage - # group by line account - acc = line.account_id.id - if tax_group.get(acc, False): - tax_group[acc] += amount - else: - tax_group[acc] = amount - # Group by cash basis account - acc = line.tax_line_id.cash_basis_account.id - if total_by_cash_basis_account.get(acc, False): - total_by_cash_basis_account[acc] += amount - else: - total_by_cash_basis_account[acc] = amount - line_to_create = [] + if line.tax_line_id and line.tax_line_id.use_cash_basis: + # group by line account + acc = line.account_id.id + if tax_group.get(acc, False): + tax_group[acc] += amount + else: + tax_group[acc] = amount + + # Group by cash basis account and tax + acc = line.tax_line_id.cash_basis_account.id + key = (acc, line.tax_line_id.id) + if key in total_by_cash_basis_account: + total_by_cash_basis_account[key] += amount + else: + total_by_cash_basis_account[key] = amount + for tax in line.tax_ids: + if tax.use_cash_basis: + line_to_create.append((0, 0, { + 'name': '/', + 'debit': line.debit_cash_basis - line.debit * matched_percentage, + 'credit': line.credit_cash_basis - line.credit * matched_percentage, + 'account_id': line.account_id.id, + 'tax_ids': [(6, 0, [tax.id])], + 'tax_exigible': True, + })) + line_to_create.append((0, 0, { + 'name': '/', + 'credit': line.debit_cash_basis - line.debit * matched_percentage, + 'debit': line.credit_cash_basis - line.credit * matched_percentage, + 'account_id': line.account_id.id, + })) + for k, v in tax_group.items(): line_to_create.append((0, 0, { 'name': '/', @@ -40,12 +62,15 @@ class AccountPartialReconcileCashBasis(models.Model): })) # Create counterpart vals - for k, v in total_by_cash_basis_account.items(): + for key, v in total_by_cash_basis_account.items(): + k, tax_id = key line_to_create.append((0, 0, { 'name': '/', 'debit': abs(v) if v < 0 else 0.0, 'credit': v if v > 0 else 0.0, 'account_id': k, + 'tax_line_id': tax_id, + 'tax_exigible': True, })) # Create move @@ -55,7 +80,7 @@ class AccountPartialReconcileCashBasis(models.Model): raise UserError(_('There is no tax cash basis journal defined ' \ 'for this company: "%s" \nConfigure it in Accounting/Configuration/Settings') % \ (self.company_id.name)) - move = self.env['account.move'].create({ + move = self.env['account.move'].with_context(dont_create_taxes=True).create({ 'journal_id': self.company_id.tax_cash_basis_journal_id.id, 'line_ids': line_to_create, 'tax_cash_basis_rec_id': self.id})