From 7a049df904241a08def8da6617cfeb116e275993 Mon Sep 17 00:00:00 2001 From: Stanislas Gueniffey Date: Fri, 26 Aug 2022 17:44:18 +0000 Subject: [PATCH] [IMP] account: dedicated payments sequence Add setting on bank/cash journals to have dedicated payments sequences Enabled by default closes odoo/odoo#99058 See: odoo/enterprise#31059 Task: 2894299 Signed-off-by: Laurent Smet --- addons/account/models/account_journal.py | 6 ++++++ addons/account/models/account_move.py | 11 +++++++++++ addons/account/models/account_payment.py | 8 ++++---- addons/account/views/account_journal_views.xml | 1 + addons/account/wizard/account_resequence.py | 3 +++ 5 files changed, 25 insertions(+), 4 deletions(-) diff --git a/addons/account/models/account_journal.py b/addons/account/models/account_journal.py index b23d12fda65..ed53255b2c1 100644 --- a/addons/account/models/account_journal.py +++ b/addons/account/models/account_journal.py @@ -108,6 +108,7 @@ class AccountJournal(models.Model): country_code = fields.Char(related='company_id.account_fiscal_country_id.code', readonly=True) refund_sequence = fields.Boolean(string='Dedicated Credit Note Sequence', help="Check this box if you don't want to share the same sequence for invoices and credit notes made from this journal", default=False) + payment_sequence = fields.Boolean(string='Dedicated Payment Sequence', help="Check this box if you don't want to share the same sequence on payments and bank transactions posted on this journal", default='_compute_payment_sequence') sequence_override_regex = fields.Text(help="Technical field used to enforce complex sequence composition that the system would normally misunderstand.\n"\ "This is a regex that can include all the following capture groups: prefix1, year, prefix2, month, prefix3, seq, suffix.\n"\ "The prefix* groups are the separators between the year, month and the actual increasing sequence number (seq).\n"\ @@ -483,6 +484,11 @@ class AccountJournal(models.Model): def _onchange_type(self): self.refund_sequence = self.type in ('sale', 'purchase') + @api.depends('type') + def _compute_payment_sequence(self): + for journal in self: + journal.payment_sequence = journal.type in ('bank', 'cash') + def unlink(self): bank_accounts = self.env['res.partner.bank'].browse() for bank_account in self.mapped('bank_account_id'): diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index 6c35a2119fc..ccecfd0af0e 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -2248,12 +2248,15 @@ class AccountMove(models.Model): return "WHERE FALSE", {} where_string = "WHERE journal_id = %(journal_id)s AND name != '/'" param = {'journal_id': self.journal_id.id} + is_payment = self.payment_id or self._context.get('is_payment') if not relaxed: domain = [('journal_id', '=', self.journal_id.id), ('id', '!=', self.id or self._origin.id), ('name', 'not in', ('/', '', False))] if self.journal_id.refund_sequence: refund_types = ('out_refund', 'in_refund') domain += [('move_type', 'in' if self.move_type in refund_types else 'not in', refund_types)] + if self.journal_id.payment_sequence: + domain += [('payment_id', '!=' if is_payment else '=', False)] reference_move_name = self.search(domain + [('date', '<=', self.date)], order='date desc', limit=1).name if not reference_move_name: reference_move_name = self.search(domain, order='date asc', limit=1).name @@ -2276,18 +2279,26 @@ class AccountMove(models.Model): where_string += " AND move_type IN ('out_refund', 'in_refund') " else: where_string += " AND move_type NOT IN ('out_refund', 'in_refund') " + elif self.journal_id.payment_sequence: + if is_payment: + where_string += " AND payment_id IS NOT NULL " + else: + where_string += " AND payment_id IS NULL " return where_string, param def _get_starting_sequence(self): # EXTENDS account sequence.mixin self.ensure_one() + is_payment = self.payment_id or self._context.get('is_payment') if self.journal_id.type == 'sale': starting_sequence = "%s/%04d/00000" % (self.journal_id.code, self.date.year) else: starting_sequence = "%s/%04d/%02d/0000" % (self.journal_id.code, self.date.year, self.date.month) if self.journal_id.refund_sequence and self.move_type in ('out_refund', 'in_refund'): starting_sequence = "R" + starting_sequence + if self.journal_id.payment_sequence and is_payment: + starting_sequence = "P" + starting_sequence return starting_sequence # ------------------------------------------------------------------------- diff --git a/addons/account/models/account_payment.py b/addons/account/models/account_payment.py index 62a0eed6f73..12c376990e3 100644 --- a/addons/account/models/account_payment.py +++ b/addons/account/models/account_payment.py @@ -692,8 +692,7 @@ class AccountPayment(models.Model): # ------------------------------------------------------------------------- def new(self, values=None, origin=None, ref=None): - self = self.with_context(is_payment=True) - payment = super().new(values, origin, ref) + payment = super(AccountPayment, self.with_context(is_payment=True)).new(values, origin, ref) if not payment.journal_id: # might not be computed because declared by inheritance payment.move_id._compute_journal_id() return payment @@ -701,7 +700,6 @@ class AccountPayment(models.Model): @api.model_create_multi def create(self, vals_list): # OVERRIDE - self = self.with_context(is_payment=True) write_off_line_vals_list = [] for vals in vals_list: @@ -712,7 +710,9 @@ class AccountPayment(models.Model): # Force the move_type to avoid inconsistency with residual 'default_move_type' inside the context. vals['move_type'] = 'entry' - payments = super().create(vals_list) + payments = super(AccountPayment, self.with_context(is_payment=True))\ + .create(vals_list)\ + .with_context(is_payment=False) for i, pay in enumerate(payments): write_off_line_vals = write_off_line_vals_list[i] diff --git a/addons/account/views/account_journal_views.xml b/addons/account/views/account_journal_views.xml index fbe4888d8e3..4ca6063cd32 100644 --- a/addons/account/views/account_journal_views.xml +++ b/addons/account/views/account_journal_views.xml @@ -84,6 +84,7 @@ options="{'no_quick_create': True}" groups="account.group_account_readonly"/> + diff --git a/addons/account/wizard/account_resequence.py b/addons/account/wizard/account_resequence.py index 21303e33656..992592b9d53 100644 --- a/addons/account/wizard/account_resequence.py +++ b/addons/account/wizard/account_resequence.py @@ -39,6 +39,9 @@ class ReSequenceWizard(models.TransientModel): and len(move_types) > 1 ): raise UserError(_('The sequences of this journal are different for Invoices and Refunds but you selected some of both types.')) + is_payment = set(active_move_ids.mapped(lambda x: bool(x.payment_id))) + if len(is_payment) > 1: + raise UserError(_('The sequences of this journal are different for Payments and non-Payments but you selected some of both types.')) values['move_ids'] = [(6, 0, active_move_ids.ids)] return values