Skip to content

Commit

Permalink
[IMP] account_cutoff_base: auto reverse
Browse files Browse the repository at this point in the history
Allow to automatically reverse generated moves
  • Loading branch information
jbaudoux committed Oct 26, 2023
1 parent e5e0bca commit 0f30e6b
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 3 deletions.
38 changes: 35 additions & 3 deletions account_cutoff_base/models/account_cutoff.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Copyright 2013-2021 Akretion (http://www.akretion.com/)
# @author: Alexis de Lattre <[email protected]>
# Copyright 2013 Alexis de Lattre (Akretion) <alexis.delattre@akretion.com>
# Copyright 2018 Jacques-Etienne Baudoux (BCIM) <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

import json
Expand Down Expand Up @@ -109,6 +109,17 @@ def _default_cutoff_account_id(self):
copy=False,
check_company=True,
)
auto_reverse = fields.Boolean(
help="Automatically reverse created move on following day. Use this "
"if you accrue a value end of period that you want to reverse "
"begin of next period",
)
move_reversal_id = fields.Many2one(
"account.move",
string="Cut-off Journal Entry Reversal",
readonly=True,
copy=False,
)
move_ref = fields.Char(
string="Reference of the Cut-off Journal Entry",
states={"done": [("readonly", True)]},
Expand Down Expand Up @@ -191,6 +202,10 @@ def name_get(self):

def back2draft(self):
self.ensure_one()
if self.move_reversal_id:
self.move_reversal_id.line_ids.remove_move_reconcile()
self.move_reversal_id.unlink()
self.move_id.line_ids.remove_move_reconcile()
if self.move_id:
self.move_id.unlink()
self.write({"state": "draft"})
Expand Down Expand Up @@ -325,7 +340,24 @@ def create_move(self):
move = move_obj.create(vals)
if self.company_id.post_cutoff_move:
move._post(soft=False)
self.write({"move_id": move.id, "state": "done"})

data = {"move_id": move.id, "state": "done"}

if self.auto_reverse:
next_day = fields.Date.from_string(self.cutoff_date) + relativedelta(days=1)
rev_move = move._reverse_moves(
[
{
"date": next_day,
"ref": _("reversal of: ") + move.ref,
}
]
)
data["move_reversal_id"] = rev_move.id
if self.company_id.post_cutoff_move:
rev_move._post(soft=False)

self.write(data)
self.message_post(body=_("Journal entry generated"))

action = self.env.ref("account.action_move_journal_line").sudo().read()[0]
Expand Down
1 change: 1 addition & 0 deletions account_cutoff_base/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
* Jim Hoefnagels <[email protected]>
* `Trobz <https://trobz.com>`_:
* Dzung Tran <[email protected]>
* Jacques-Etienne Baudoux (BCIM) <[email protected]>
108 changes: 108 additions & 0 deletions account_cutoff_base/tests/test_account_cutoff.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,33 @@
# Copyright 2018 Jacques-Etienne Baudoux (BCIM) <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import Command, fields
from odoo.tests.common import TransactionCase


class TestAccountCutoff(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
cls.company = cls.env.ref("base.main_company")
cls.cutoff_journal = cls.env["account.journal"].create(
{
"code": "cop0",
"company_id": cls.company.id,
"name": "Cutoff Journal Base",
"type": "general",
}
)
cls.cutoff_account = cls.env["account.account"].create(
{
"name": "Cutoff Base Account",
"code": "ACB480000",
"company_id": cls.company.id,
"account_type": "liability_current",
}
)

def test_default_cutoff_account_id(self):
account_id = self.env["account.cutoff"]._default_cutoff_account_id()
self.assertEqual(account_id, False)
Expand Down Expand Up @@ -36,3 +60,87 @@ def test_default_cutoff_account_id(self):
random_account.id,
"The account must be equals to %s" % random_account.id,
)

def test_create_move(self):
type_cutoff = "accrued_revenue"
cutoff = (
self.env["account.cutoff"]
.with_context(default_cutoff_type=type_cutoff)
.create(
{
"cutoff_type": type_cutoff,
"company_id": 1,
"cutoff_date": fields.Date.today(),
"cutoff_account_id": self.cutoff_account.id,
"cutoff_journal_id": self.cutoff_journal.id,
}
)
)
account = self.env["account.account"].create(
{
"name": "Base account",
"code": "ACB220000",
"company_id": self.company.id,
"account_type": "liability_current",
}
)
cutoff.line_ids = [
Command.create(
{
"parent_id": cutoff.id,
"account_id": account.id,
"cutoff_account_id": self.cutoff_account.id,
"cutoff_amount": 50,
},
)
]
self.company.post_cutoff_move = False
cutoff.auto_reverse = False
cutoff.create_move()
self.assertEqual(
cutoff.move_id.state,
"draft",
"A draft move is expected",
)
self.assertFalse(
cutoff.move_reversal_id,
"No reversal move is expected",
)
cutoff.back2draft()
self.assertFalse(
cutoff.move_id,
"No move is expected",
)
cutoff.auto_reverse = True
cutoff.create_move()
self.assertEqual(
cutoff.move_id.state,
"draft",
"A draft move is expected",
)
self.assertEqual(
cutoff.move_reversal_id.state,
"draft",
"A draft reversal move is expected",
)
cutoff.back2draft()
self.assertFalse(
cutoff.move_id,
"No move is expected",
)
self.assertFalse(
cutoff.move_reversal_id,
"No reversal move is expected",
)
self.company.post_cutoff_move = True
cutoff.create_move()
self.assertEqual(
cutoff.move_id.state,
"posted",
"A posted move is expected",
)
self.assertEqual(
cutoff.move_id.state,
"posted",
"A posted reversal move is expected",
)
1 change: 1 addition & 0 deletions account_cutoff_base/views/account_cutoff.xml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
options="{'datepicker': {'warn_future': true}}"
/>
<field name="total_cutoff_amount" />
<field name="auto_reverse" />
<field name="source_move_state" widget="radio" />
<field name="company_id" options="{'no_create': True}" />
<field name="company_currency_id" invisible="1" />
Expand Down

0 comments on commit 0f30e6b

Please sign in to comment.