ddb5d15f53
Instead of defining the new sequence as a field default, it is now a compute. This is because the sequence depends on the company, but we don't have the `company_id` field until the record is created. Reduced the default number of padded zeroes to 8. This is a product decision. The original implementation didn't make much sense because it allowed the user to set a different sequence per journal, but Odoo already has that kind of sequence. The only purpose of this module is to have a sequence *per company*. To avoid breaking too much, for now, when the journal sequence is the default one, we set it as readonly. Limit the available sequences in the renumbering wizard. Display only those that you have access by your selected context companies. For some reason, Odoo doesn't filter sequences by company automatically. @moduon MT-3076 Co-authored-by: Andrea Cattalani <22261939+anddago78@users.noreply.github.com>
93 lines
3.3 KiB
Python
93 lines
3.3 KiB
Python
# Copyright 2022 Moduon
|
|
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
|
|
|
|
from datetime import date
|
|
|
|
from odoo import _, api, exceptions, fields, models
|
|
|
|
|
|
class AccountMoveRenumberWizard(models.TransientModel):
|
|
_name = "account.move.renumber.wizard"
|
|
_description = "Account move entry renumbering wizard"
|
|
|
|
starting_date = fields.Date(
|
|
required=True,
|
|
default=lambda self: self._default_starting_date(),
|
|
help="Renumber account moves starting this day.",
|
|
)
|
|
starting_number = fields.Integer(
|
|
default=1, help="Reset sequence to this number before starting."
|
|
)
|
|
available_sequence_ids = fields.Many2many(
|
|
comodel_name="ir.sequence",
|
|
string="Available sequences",
|
|
default=lambda self: self._default_available_sequence_ids(),
|
|
)
|
|
sequence_id = fields.Many2one(
|
|
comodel_name="ir.sequence",
|
|
string="Sequence",
|
|
required=True,
|
|
default=lambda self: self._default_entry_number_sequence(),
|
|
domain="[('id', 'in', available_sequence_ids)]",
|
|
help="Sequence to use for renumbering. Affects all journals that use this sequence.",
|
|
)
|
|
|
|
@api.model
|
|
def _default_starting_date(self):
|
|
"""Start by default on day 1 of current year."""
|
|
return date(date.today().year, 1, 1)
|
|
|
|
@api.model
|
|
def _default_entry_number_sequence(self):
|
|
"""Get default sequence if it exists."""
|
|
return self.env["ir.sequence"].search(
|
|
[
|
|
"&",
|
|
("code", "=", "account_journal_general_sequence.default"),
|
|
("company_id", "in", self.env.companies.ids),
|
|
]
|
|
)
|
|
|
|
@api.model
|
|
def _default_available_sequence_ids(self):
|
|
"""Let view display only journal-related sequences."""
|
|
return (
|
|
self.env["account.journal"]
|
|
.search([("company_id", "in", self.env.companies.ids)])
|
|
.mapped("entry_number_sequence_id")
|
|
)
|
|
|
|
def action_renumber(self):
|
|
"""Renumber moves.
|
|
|
|
Makes sure moves exist. Sorts them. Resets sequences. Renumbers them.
|
|
"""
|
|
# Find posted moves that match wizard criteria
|
|
moves = self.env["account.move"].search(
|
|
[
|
|
("state", "=", "posted"),
|
|
("date", ">=", self.starting_date),
|
|
("journal_id.entry_number_sequence_id", "=", self.sequence_id.id),
|
|
],
|
|
order="date, id",
|
|
)
|
|
if not moves:
|
|
raise exceptions.UserError(_("No account moves found."))
|
|
# Reset sequence
|
|
future_ranges = self.env["ir.sequence.date_range"].search(
|
|
[
|
|
("date_from", ">", self.starting_date),
|
|
("sequence_id", "=", self.sequence_id.id),
|
|
]
|
|
)
|
|
# Safe `sudo` calls; wizard only available for accounting managers
|
|
future_ranges.sudo().unlink()
|
|
current_range = self.sequence_id._get_current_sequence(self.starting_date)
|
|
current_range.sudo().number_next = self.starting_number
|
|
self.sequence_id.sudo().number_next = self.starting_number
|
|
# Renumber the moves
|
|
moves = moves.with_context(skip_invoice_sync=True)
|
|
moves.entry_number = False
|
|
moves.flush_recordset(["entry_number"])
|
|
moves._compute_entry_number()
|