[MIG] account_move_name_sequence: Migration to 17.0

This commit is contained in:
Marcos Oitaben
2023-11-13 16:26:23 +01:00
committed by Marcos Oitaben
parent e8b3d2ed97
commit d95f747d39
8 changed files with 44 additions and 76 deletions

View File

@@ -7,7 +7,7 @@
{
"name": "Account Move Number Sequence",
"version": "16.0.1.1.6",
"version": "17.0.1.0.0",
"category": "Accounting",
"license": "AGPL-3",
"summary": "Generate journal entry number from sequence",

View File

@@ -5,11 +5,8 @@
# @author: Francisco Luna <fluna@vauxoo.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import SUPERUSER_ID, api
def post_init_hook(cr, registry):
env = api.Environment(cr, SUPERUSER_ID, {})
def post_init_hook(env):
create_journal_sequences(env)

View File

@@ -86,10 +86,11 @@ class AccountJournal(models.Model):
@api.model
def _prepare_sequence(self, vals, refund=False):
code = vals.get("code") and vals["code"].upper() or ""
prefix = "%s%s/%%(range_year)s/" % (refund and "R" or "", code)
prefix = "{}{}/%(range_year)s/".format(refund and "R" or "", code)
seq_vals = {
"name": "%s%s"
% (vals.get("name", _("Sequence")), refund and " " + _("Refund") or ""),
"name": "{}{}".format(
vals.get("name", _("Sequence")), refund and " " + _("Refund") or ""
),
"company_id": vals.get("company_id") or self.env.company.id,
"implementation": "no_gap",
"prefix": prefix,
@@ -124,8 +125,8 @@ class AccountJournal(models.Model):
move_domain, limit=1, order="id DESC"
)
msg_err = (
"Journal %s could not get sequence %s values based on current moves. "
"Using default values." % (self.id, refund and "refund" or "")
"Journal {} could not get sequence {} values based on current moves. "
"Using default values.".format(self.id, refund and "refund" or "")
)
if not last_move:
_logger.warning("%s %s", msg_err, "No moves found")
@@ -168,7 +169,7 @@ class AccountJournal(models.Model):
if month:
prefix += "%(range_month)s"
prefix3 = seq_format_values.get("prefix3") or ""
where_name_value = "%s%s%s%s%s%%" % (
where_name_value = "{}{}{}{}{}%".format(
prefix1,
"_" * seq_format_values["year_length"],
prefix2,
@@ -177,31 +178,27 @@ class AccountJournal(models.Model):
)
prefixes = prefix1 + prefix2
select_year = (
"split_part(name, '%s', %d)" % (prefix2, prefixes.count(prefix2))
f"split_part(name, '{prefix2}', {prefixes.count(prefix2)})"
if prefix2
else "''"
)
prefixes += prefix3
select_month = (
"split_part(name, '%s', %d)" % (prefix3, prefixes.count(prefix3))
f"split_part(name, '{prefix3}', {prefixes.count(prefix3)})"
if prefix3
else "''"
)
select_max_number = (
"MAX(split_part(name, '%s', %d)::INTEGER) AS max_number"
% (
"MAX(split_part(name, '{}', {})::INTEGER) AS max_number".format(
prefixes[-1],
prefixes.count(prefixes[-1]) + 1,
)
)
query = (
"SELECT %s, %s, %s FROM account_move "
"WHERE name LIKE %%s AND journal_id=%%s GROUP BY 1,2"
) % (
select_year,
select_month,
select_max_number,
)
"SELECT {}, {}, {} FROM account_move "
"WHERE name LIKE %s AND journal_id=%s GROUP BY 1,2"
).format(select_year, select_month, select_max_number)
# It is not using user input
# pylint: disable=sql-injection
self.env.cr.execute(query, (where_name_value, self.id))
@@ -231,11 +228,11 @@ class AccountJournal(models.Model):
else:
year = "20" + year
if month:
date_from = fields.Date.to_date("%s-%s-1" % (year, month))
date_from = fields.Date.to_date(f"{year}-{month}-1")
date_to = fields.Date.end_of(date_from, "month")
else:
date_from = fields.Date.to_date("%s-1-1" % year)
date_to = fields.Date.to_date("%s-12-31" % year)
date_from = fields.Date.to_date(f"{year}-1-1")
date_to = fields.Date.to_date(f"{year}-12-31")
seq_vals["date_range_ids"].append(
(
0,

View File

@@ -75,5 +75,5 @@ class AccountMove(models.Model):
self.flush_model(["name", "journal_id", "move_type", "state"])
return super()._fetch_duplicate_supplier_reference(only_posted=only_posted)
def _get_last_sequence(self, relaxed=False, with_prefix=None, lock=True):
return super()._get_last_sequence(relaxed, None, lock)
def _get_last_sequence(self, relaxed=False, with_prefix=None):
return super()._get_last_sequence(relaxed, None)

View File

@@ -11,7 +11,7 @@ class IrSequence(models.Model):
# https://github.com/odoo/odoo/pull/91019
date_obj = fields.Date.from_string(date)
sequence_range = self.env["ir.sequence.date_range"]
prefix_suffix = "%s %s" % (self.prefix, self.suffix)
prefix_suffix = f"{self.prefix} {self.suffix}"
if "%(range_day)s" in prefix_suffix:
date_from = date_obj
date_to = date_obj

View File

@@ -72,7 +72,7 @@ class TestAccountMoveNameSequence(TransactionCase):
self.assertEqual(move.name, "/")
move.action_post()
seq = self.misc_journal.sequence_id
move_name = "%s%s" % (seq.prefix, "1".zfill(seq.padding))
move_name = "{}{}".format(seq.prefix, "1".zfill(seq.padding))
move_name = move_name.replace("%(range_year)s", str(self.date.year))
self.assertEqual(move.name, move_name)
self.assertTrue(seq.date_range_ids)
@@ -170,22 +170,6 @@ class TestAccountMoveNameSequence(TransactionCase):
self.assertEqual(in_invoice.name, "/")
in_invoice.action_post()
move_reversal = (
self.env["account.move.reversal"]
.with_context(active_model="account.move", active_ids=in_invoice.ids)
.create(
{
"journal_id": in_invoice.journal_id.id,
"reason": "no reason",
"refund_method": "cancel",
}
)
)
reversal = move_reversal.reverse_moves()
reversed_move = self.env["account.move"].browse(reversal["res_id"])
self.assertTrue(reversed_move)
self.assertEqual(reversed_move.state, "posted")
in_invoice = in_invoice.copy(
{
"invoice_date": self.date,
@@ -193,18 +177,14 @@ class TestAccountMoveNameSequence(TransactionCase):
)
in_invoice.action_post()
move_reversal = (
self.env["account.move.reversal"]
.with_context(active_model="account.move", active_ids=in_invoice.ids)
.create(
{
"journal_id": in_invoice.journal_id.id,
"reason": "no reason",
"refund_method": "modify",
}
)
move_reversal = self.env["account.move.reversal"].create(
{
"move_ids": in_invoice.ids,
"journal_id": in_invoice.journal_id.id,
"reason": "no reason",
}
)
reversal = move_reversal.reverse_moves()
reversal = move_reversal.modify_moves()
draft_invoice = self.env["account.move"].browse(reversal["res_id"])
self.assertTrue(draft_invoice)
self.assertEqual(draft_invoice.state, "draft")
@@ -217,18 +197,14 @@ class TestAccountMoveNameSequence(TransactionCase):
)
in_invoice.action_post()
move_reversal = (
self.env["account.move.reversal"]
.with_context(active_model="account.move", active_ids=in_invoice.ids)
.create(
{
"journal_id": in_invoice.journal_id.id,
"reason": "no reason",
"refund_method": "refund",
}
)
move_reversal = self.env["account.move.reversal"].create(
{
"move_ids": in_invoice.ids,
"journal_id": in_invoice.journal_id.id,
"reason": "no reason",
}
)
reversal = move_reversal.reverse_moves()
reversal = move_reversal.refund_moves()
draft_reversed_move = self.env["account.move"].browse(reversal["res_id"])
self.assertTrue(draft_reversed_move)
self.assertEqual(draft_reversed_move.state, "draft")
@@ -257,7 +233,7 @@ class TestAccountMoveNameSequence(TransactionCase):
self.assertEqual(in_refund_invoice.name, "/")
in_refund_invoice.action_post()
seq = self.purchase_journal.refund_sequence_id
move_name = "%s%s" % (seq.prefix, "1".zfill(seq.padding))
move_name = "{}{}".format(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()
@@ -277,7 +253,7 @@ class TestAccountMoveNameSequence(TransactionCase):
)
self.assertEqual(invoice.name, "/")
invoice.action_post()
error_msg = "You cannot delete an item linked to a posted entry."
error_msg = "You can't delete a posted journal item. Dont play games with your accounting records; reset the journal entry to draft before deleting it."
with self.assertRaisesRegex(UserError, error_msg):
invoice.unlink()
invoice.button_draft()
@@ -309,7 +285,7 @@ class TestAccountMoveNameSequence(TransactionCase):
)
self.assertEqual(in_refund_invoice.name, "/")
in_refund_invoice.action_post()
error_msg = "You cannot delete an item linked to a posted entry."
error_msg = "You can't delete a posted journal item. Dont play games with your accounting records; reset the journal entry to draft before deleting it."
with self.assertRaisesRegex(UserError, error_msg):
in_refund_invoice.unlink()
in_refund_invoice.button_draft()

View File

@@ -22,8 +22,8 @@
<field name="refund_sequence" position="after">
<field
name="refund_sequence_id"
attrs="{'invisible': ['|', ('type', 'not in', ('sale', 'purchase')), ('refund_sequence', '=', False)],
'required': [('type', 'in', ('sale', 'purchase')), ('refund_sequence', '=', True)]}"
invisible="type not in ('sale', 'purchase') or not refund_sequence"
required="type in ('sale', 'purchase') and refund_sequence"
context="{'default_name': name, 'default_company_id': company_id, 'default_implementation': 'no_gap', 'default_padding': 4, 'default_use_date_range': True, 'default_prefix': 'R' + (code or 'UNKNOWN') + '/%%(range_year)s/'}"
/>
</field>

View File

@@ -17,13 +17,11 @@
expr="//div[hasclass('oe_title')]//field[@name='name']"
position="attributes"
>
<attribute name="attrs">{'invisible': [('name', '=', '/')]}</attribute>
<attribute name="invisible">name == '/'</attribute>
<attribute name="readonly">1</attribute>
</xpath>
<xpath expr="//div[hasclass('oe_title')]//h1//span" position="attributes">
<attribute
name="attrs"
>{'invisible': ['|', ('state', '!=', 'draft'), ('name', '!=', '/')]}</attribute>
<attribute name="invisible">state != 'draft' or name != '/'</attribute>
</xpath>
</field>
</record>