From 4aeaa9ca51ba15e824edcbf307c0384ae0e46ca4 Mon Sep 17 00:00:00 2001 From: Alexis de Lattre Date: Wed, 8 Sep 2021 14:21:43 +0200 Subject: [PATCH] sequence is now required on journals Add post-install script to create a sequence for all existing journals Update README accordingly --- account_move_name_sequence/__init__.py | 1 + account_move_name_sequence/__manifest__.py | 2 + .../models/account_journal.py | 1 + .../models/account_move.py | 55 ++++++++++++------- account_move_name_sequence/post_install.py | 25 +++++++++ .../readme/CONFIGURE.rst | 2 + .../tests/test_account_move_name_seq.py | 6 ++ .../views/account_journal.xml | 32 +++++------ .../views/account_move.xml | 33 +++++++++++ 9 files changed, 118 insertions(+), 39 deletions(-) create mode 100644 account_move_name_sequence/post_install.py create mode 100644 account_move_name_sequence/views/account_move.xml diff --git a/account_move_name_sequence/__init__.py b/account_move_name_sequence/__init__.py index 0650744f..f8149cf4 100644 --- a/account_move_name_sequence/__init__.py +++ b/account_move_name_sequence/__init__.py @@ -1 +1,2 @@ +from .post_install import create_journal_sequences from . import models diff --git a/account_move_name_sequence/__manifest__.py b/account_move_name_sequence/__manifest__.py index b0b62405..2d131aab 100644 --- a/account_move_name_sequence/__manifest__.py +++ b/account_move_name_sequence/__manifest__.py @@ -14,7 +14,9 @@ "depends": ["account"], "data": [ "views/account_journal.xml", + "views/account_move.xml", "security/ir.model.access.csv", ], + "post_init_hook": "create_journal_sequences", "installable": True, } diff --git a/account_move_name_sequence/models/account_journal.py b/account_move_name_sequence/models/account_journal.py index 2d616d00..a1e20146 100644 --- a/account_move_name_sequence/models/account_journal.py +++ b/account_move_name_sequence/models/account_journal.py @@ -13,6 +13,7 @@ class AccountJournal(models.Model): "ir.sequence", string="Entry Sequence", copy=False, + required=True, check_company=True, domain="[('company_id', '=', company_id)]", help="This sequence will be used to generate the journal entry number.", diff --git a/account_move_name_sequence/models/account_move.py b/account_move_name_sequence/models/account_move.py index 986d64dd..b090eb52 100644 --- a/account_move_name_sequence/models/account_move.py +++ b/account_move_name_sequence/models/account_move.py @@ -2,31 +2,44 @@ # @author: Alexis de Lattre # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models +from odoo import api, fields, models class AccountMove(models.Model): _inherit = "account.move" - def _compute_name(self): - for move in self.filtered( - lambda m: (m.name == "/" or not m.name) - and m.state == "posted" - and m.journal_id - and m.journal_id.sequence_id - ): + name = fields.Char(compute="_compute_name_by_sequence") + # highest_name, sequence_prefix and sequence_number are not needed any more + # -> compute=False to improve perf + highest_name = fields.Char(compute=False) + sequence_prefix = fields.Char(compute=False) + sequence_number = fields.Integer(compute=False) + + @api.depends("state", "journal_id", "date") + def _compute_name_by_sequence(self): + for move in self: + name = move.name or "/" + # I can't use posted_before in this IF because + # posted_before is set to True in _post() at the same + # time as state is set to "posted" if ( - move.move_type in ("out_refund", "in_refund") - and move.journal_id.type in ("sale", "purchase") - and move.journal_id.refund_sequence - and move.journal_id.refund_sequence_id + move.state == "posted" + and (not move.name or move.name == "/") + and move.journal_id + and move.journal_id.sequence_id ): - seq = move.journal_id.refund_sequence_id - else: - seq = move.journal_id.sequence_id - move.name = seq.next_by_id(sequence_date=move.date) - super()._compute_name() - for move in self.filtered( - lambda m: m.name and m.name != "/" and m.state != "posted" - ): - move.name = "/" + if ( + move.move_type in ("out_refund", "in_refund") + and move.journal_id.type in ("sale", "purchase") + and move.journal_id.refund_sequence + and move.journal_id.refund_sequence_id + ): + seq = move.journal_id.refund_sequence_id + else: + seq = move.journal_id.sequence_id + name = seq.next_by_id(sequence_date=move.date) + move.name = name + + # We must by-pass this constraint of sequence.mixin + def _constrains_date_sequence(self): + return True diff --git a/account_move_name_sequence/post_install.py b/account_move_name_sequence/post_install.py new file mode 100644 index 00000000..5384a8cb --- /dev/null +++ b/account_move_name_sequence/post_install.py @@ -0,0 +1,25 @@ +# Copyright 2021 Akretion France (http://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import SUPERUSER_ID, api + + +def create_journal_sequences(cr, registry): + with api.Environment.manage(): + env = api.Environment(cr, SUPERUSER_ID, {}) + journals = env["account.journal"].with_context(active_test=False).search([]) + for journal in journals: + vals = {} + journal_vals = { + "code": journal.code, + "name": journal.name, + "company_id": journal.company_id.id, + } + seq_vals = journal._prepare_sequence(journal_vals) + vals["sequence_id"] = env["ir.sequence"].create(seq_vals).id + if journal.type in ("sale", "purchase") and journal.refund_sequence: + rseq_vals = journal._prepare_sequence(journal_vals, refund=True) + vals["refund_sequence_id"] = env["ir.sequence"].create(rseq_vals).id + journal.write(vals) + return diff --git a/account_move_name_sequence/readme/CONFIGURE.rst b/account_move_name_sequence/readme/CONFIGURE.rst index 1b4bf54b..b2998870 100644 --- a/account_move_name_sequence/readme/CONFIGURE.rst +++ b/account_move_name_sequence/readme/CONFIGURE.rst @@ -1,3 +1,5 @@ On the form view of an account journal, in the first tab, there is a many2one link to the sequence. When you create a new journal, you can keep this field empty and a new sequence will be automatically created when you save the journal. On sale and purchase journals, you have an additionnal option to have another sequence dedicated to refunds. + +Upon module installation, all existing journals will be updated with a journal entry sequence (and also a credit note sequence for sale and purchase journals). You should update the configuration of the sequences to fit your needs. You can uncheck the option *Dedicated Credit Note Sequence* on existing sale and purchase journals if you don't want it. For the journals which already have journal entries, you should update the sequence configuration to avoid a discontinuity in the numbering for the next journal entry. diff --git a/account_move_name_sequence/tests/test_account_move_name_seq.py b/account_move_name_sequence/tests/test_account_move_name_seq.py index 1ba0f2ac..c6acf33c 100644 --- a/account_move_name_sequence/tests/test_account_move_name_seq.py +++ b/account_move_name_sequence/tests/test_account_move_name_seq.py @@ -78,6 +78,9 @@ class TestAccountMoveNameSequence(TransactionCase): ] ) self.assertEqual(drange_count, 1) + move.button_draft() + move.action_post() + self.assertEqual(move.name, move_name) def test_in_refund(self): in_refund_invoice = self.env["account.move"].create( @@ -105,3 +108,6 @@ class TestAccountMoveNameSequence(TransactionCase): move_name = "%s%s" % (seq.prefix, "1".zfill(seq.padding)) move_name = move_name.replace("%(range_year)s", str(self.date.year)) self.assertEqual(in_refund_invoice.name, move_name) + in_refund_invoice.button_draft() + in_refund_invoice.action_post() + self.assertEqual(in_refund_invoice.name, move_name) diff --git a/account_move_name_sequence/views/account_journal.xml b/account_move_name_sequence/views/account_journal.xml index 8c557014..073d40be 100644 --- a/account_move_name_sequence/views/account_journal.xml +++ b/account_move_name_sequence/views/account_journal.xml @@ -6,29 +6,25 @@ --> - - account.journal - - - - + account.journal + + + + - - + + - - - + + + - + diff --git a/account_move_name_sequence/views/account_move.xml b/account_move_name_sequence/views/account_move.xml new file mode 100644 index 00000000..cb945731 --- /dev/null +++ b/account_move_name_sequence/views/account_move.xml @@ -0,0 +1,33 @@ + + + + + + account.move + + + + {'invisible': [('name', '=', '/')]} + + + {'readonly': 1} + + + {'invisible': 1} + + + + +