2
0

Merge PR #1665 into 16.0

Signed-off-by rafaelbn
This commit is contained in:
OCA-git-bot 2023-06-30 16:50:15 +00:00
commit 358925d8ce
6 changed files with 133 additions and 34 deletions

View File

@ -3,7 +3,7 @@
{
"name": "General sequence in account journals",
"summary": "Add configurable sequence to account moves, per journal",
"version": "16.0.1.1.0",
"version": "16.0.2.0.0",
"category": "Accounting/Accounting",
"website": "https://github.com/OCA/account-financial-tools",
"author": "Moduon, Odoo Community Association (OCA)",

View File

@ -0,0 +1,44 @@
# Copyright 2023 Moduon Team S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl-3.0)
from odoo import SUPERUSER_ID, api, fields
def migrate(cr, version):
"""One journal sequence per company."""
env = api.Environment(cr, SUPERUSER_ID, {})
journals = env["account.journal"].search(
[
(
"entry_number_sequence_id.code",
"=",
"account_journal_general_sequence.default",
)
]
)
for journal in journals:
if journal.company_id != journal.entry_number_sequence_id.company_id:
new_sequence = env["ir.sequence"].search(
[
("code", "=", "account_journal_general_sequence.default"),
("company_id", "=", journal.company_id.id),
]
) or journal.entry_number_sequence_id.copy(
{
"company_id": journal.company_id.id,
"name": "{} ({})".format(
journal.entry_number_sequence_id.name, journal.company_id.name
),
"number_next_actual": journal.entry_number_sequence_id.number_next_actual,
"date_range_ids": [
fields.Command.create(
{
"date_from": rng.date_from,
"date_to": rng.date_to,
"number_next_actual": rng.number_next_actual,
}
)
for rng in journal.entry_number_sequence_id.date_range_ids
],
}
)
journal.entry_number_sequence_id = new_sequence

View File

@ -2,7 +2,7 @@
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
import logging
from odoo import _, fields, models
from odoo import _, api, fields, models
_logger = logging.getLogger(__name__)
@ -13,27 +13,40 @@ class AccountJournal(models.Model):
entry_number_sequence_id = fields.Many2one(
comodel_name="ir.sequence",
string="Account entry number sequence",
default=lambda self: self._default_entry_number_sequence(),
compute="_compute_entry_number_sequence",
domain="[('company_id', '=', company_id)]",
check_company=True,
readonly=False,
store=True,
copy=False,
help="Sequence used for account entry numbering.",
)
entry_number_sequence_id_name = fields.Char(related="entry_number_sequence_id.code")
def _default_entry_number_sequence(self):
@api.depends("company_id")
def _compute_entry_number_sequence(self):
"""Get the default sequence for all journals."""
result = self.env["ir.sequence"].search(
[("code", "=", "account_journal_general_sequence.default")]
)
if result:
return result
_logger.info("Creating default sequence for account move numbers")
result = self.env["ir.sequence"].create(
{
"name": _("Account entry default numbering"),
"code": "account_journal_general_sequence.default",
"implementation": "no_gap",
"prefix": "%(range_year)s/",
"padding": 10,
"use_date_range": True,
}
)
return result
for one in self:
sequence = self.env["ir.sequence"].search(
[
("code", "=", "account_journal_general_sequence.default"),
("company_id", "=", one.company_id.id),
]
)
if not sequence:
_logger.info("Creating default sequence for account move numbers")
sequence = self.env["ir.sequence"].create(
{
"name": _(
"Account entry default numbering (%s)",
one.company_id.name,
),
"code": "account_journal_general_sequence.default",
"company_id": one.company_id.id,
"implementation": "no_gap",
"prefix": "%(range_year)s/",
"padding": 8,
"use_date_range": True,
}
)
one.entry_number_sequence_id = sequence

View File

@ -2,6 +2,7 @@
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
from freezegun import freeze_time
from odoo.fields import Command
from odoo.tests.common import Form, new_test_user, tagged, users
from odoo.tools import mute_logger
@ -14,11 +15,18 @@ class RenumberCase(TestAccountReconciliationCommon):
@classmethod
def setUpClass(cls):
super().setUpClass()
companies = cls.company_data["company"] | cls.company_data_2["company"]
cls.invoicer = new_test_user(
cls.env, "test_invoicer", "account.group_account_invoice"
cls.env,
"test_invoicer",
"account.group_account_invoice",
company_ids=[Command.set(companies.ids)],
)
cls.manager = new_test_user(
cls.env, "test_manager", "account.group_account_manager"
cls.env,
"test_manager",
"account.group_account_manager",
company_ids=[Command.set(companies.ids)],
)
@users("test_invoicer")
@ -42,18 +50,22 @@ class RenumberCase(TestAccountReconciliationCommon):
next_year_invoice = self._create_invoice(
date_invoice="2023-12-31", auto_validate=True
)
next_year_invoice.flush(["entry_number"], next_year_invoice)
next_year_invoice.flush_recordset(["entry_number"])
new_invoice = self._create_invoice(
date_invoice="2022-05-10", auto_validate=True
)
new_invoice.flush(["entry_number"], new_invoice)
new_invoice.flush_recordset(["entry_number"])
old_invoice = self._create_invoice(
date_invoice="2022-04-30", auto_validate=True
)
old_invoice.flush(["entry_number"], old_invoice)
old_invoice.flush_recordset(["entry_number"])
self.assertLess(new_invoice.entry_number, old_invoice.entry_number)
# Fix entry number order with wizard; default values are OK
wiz_f = Form(self.env["account.move.renumber.wizard"])
wiz_f = Form(
self.env["account.move.renumber.wizard"].with_company(
self.company_data["company"]
)
)
self.assertEqual(len(wiz_f.available_sequence_ids), 1)
wiz = wiz_f.save()
wiz.action_renumber()
@ -67,10 +79,10 @@ class RenumberCase(TestAccountReconciliationCommon):
wiz_f = Form(self.env["account.move.renumber.wizard"])
wiz = wiz_f.save()
wiz.action_renumber()
self.assertEqual(opening_invoice.entry_number, "2022/0000000001")
self.assertEqual(old_invoice.entry_number, "2022/0000000002")
self.assertEqual(new_invoice.entry_number, "2022/0000000003")
self.assertEqual(next_year_invoice.entry_number, "2023/0000000001")
self.assertEqual(opening_invoice.entry_number, "2022/00000001")
self.assertEqual(old_invoice.entry_number, "2022/00000002")
self.assertEqual(new_invoice.entry_number, "2022/00000003")
self.assertEqual(next_year_invoice.entry_number, "2023/00000001")
@users("test_invoicer")
def test_install_no_entry_number(self):
@ -88,3 +100,21 @@ class RenumberCase(TestAccountReconciliationCommon):
invoice.action_post()
# Ensure there's no entry number
self.assertFalse(invoice.entry_number)
@users("test_invoicer")
def test_new_company_journal(self):
# Create new companies
cmp1 = self.company_data["company"]
cmp2 = self.company_data_2["company"]
# Create a new invoice for each company
self.env = self.env(
context=dict(self.env.context, allowed_company_ids=cmp1.ids)
)
invoice1 = self.create_invoice()
self.env = self.env(
context=dict(self.env.context, allowed_company_ids=cmp2.ids)
)
invoice2 = self.create_invoice()
# Each company has a different sequence, so the entry number should be the same
self.assertEqual(invoice1.entry_number, "2022/00000001")
self.assertEqual(invoice2.entry_number, "2022/00000001")

View File

@ -20,7 +20,11 @@
<field name="inherit_id" ref="account.view_account_journal_form" />
<field name="arch" type="xml">
<field name="refund_sequence" position="before">
<field name="entry_number_sequence_id" />
<field name="entry_number_sequence_id_name" invisible="1" />
<field
name="entry_number_sequence_id"
attrs="{'readonly':[('entry_number_sequence_id_name','=','account_journal_general_sequence.default')]}"
/>
</field>
</field>
</record>

View File

@ -41,13 +41,21 @@ class AccountMoveRenumberWizard(models.TransientModel):
def _default_entry_number_sequence(self):
"""Get default sequence if it exists."""
return self.env["ir.sequence"].search(
[("code", "=", "account_journal_general_sequence.default")]
[
"&",
("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([]).mapped("entry_number_sequence_id")
return (
self.env["account.journal"]
.search([("company_id", "in", self.env.companies.ids)])
.mapped("entry_number_sequence_id")
)
def action_renumber(self):
"""Renumber moves.