From b2a868cb1dda9ff8608cac8afd0725bd104c5fe6 Mon Sep 17 00:00:00 2001 From: Jordi Ballester Date: Tue, 6 Jul 2021 17:34:48 +0200 Subject: [PATCH] [account_asset_management][imp] Allow to reverse the posting of a depreciation line instead of deleting the journal entry. This will be done when the company has activated the inalterability hash on the original journal entry. --- account_asset_management/__manifest__.py | 1 + .../models/account_asset_line.py | 42 ++++++++--- .../models/account_asset_profile.py | 6 ++ .../models/account_move.py | 11 ++- .../readme/CONTRIBUTORS.rst | 4 ++ account_asset_management/readme/HISTORY.rst | 6 ++ .../tests/test_account_asset_management.py | 72 +++++++++++++++++++ .../views/account_asset.xml | 2 +- .../views/account_asset_profile.xml | 1 + account_asset_management/wizard/__init__.py | 1 + .../wizard/wiz_asset_move_reverse.py | 57 +++++++++++++++ .../wizard/wiz_asset_move_reverse.xml | 27 +++++++ 12 files changed, 217 insertions(+), 13 deletions(-) create mode 100644 account_asset_management/wizard/wiz_asset_move_reverse.py create mode 100644 account_asset_management/wizard/wiz_asset_move_reverse.xml diff --git a/account_asset_management/__manifest__.py b/account_asset_management/__manifest__.py index fef7a10bc..ec2aa3a01 100644 --- a/account_asset_management/__manifest__.py +++ b/account_asset_management/__manifest__.py @@ -26,5 +26,6 @@ "views/menuitem.xml", "data/cron.xml", "wizard/wiz_account_asset_report.xml", + "wizard/wiz_asset_move_reverse.xml", ], } diff --git a/account_asset_management/models/account_asset_line.py b/account_asset_management/models/account_asset_line.py index cd5763917..b9fa953fb 100644 --- a/account_asset_management/models/account_asset_line.py +++ b/account_asset_management/models/account_asset_line.py @@ -292,16 +292,38 @@ class AccountAssetLine(models.Model): "domain": [("id", "=", self.move_id.id)], } + def update_asset_line_after_unlink_move(self): + self.write({"move_id": False}) + if self.parent_state == "close": + self.asset_id.write({"state": "open"}) + elif self.parent_state == "removed" and self.type == "remove": + self.asset_id.write({"state": "close", "date_remove": False}) + self.unlink() + def unlink_move(self): for line in self: - move = line.move_id - move.button_draft() - move.with_context(force_delete=True, unlink_from_asset=True).unlink() - # trigger store function - line.with_context(unlink_from_asset=True).write({"move_id": False}) - if line.parent_state == "close": - line.asset_id.write({"state": "open"}) - elif line.parent_state == "removed" and line.type == "remove": - line.asset_id.write({"state": "close", "date_remove": False}) - line.unlink() + if line.asset_id.profile_id.allow_reversal: + context = dict(self._context or {}) + context.update( + { + "active_model": self._name, + "active_ids": line.ids, + "active_id": line.id, + } + ) + return { + "name": _("Reverse Move"), + "view_mode": "form", + "res_model": "wiz.asset.move.reverse", + "target": "new", + "type": "ir.actions.act_window", + "context": context, + } + else: + move = line.move_id + move.button_draft() + move.with_context(force_delete=True, unlink_from_asset=True).unlink() + line.with_context( + unlink_from_asset=True + ).update_asset_line_after_unlink_move() return True diff --git a/account_asset_management/models/account_asset_profile.py b/account_asset_management/models/account_asset_profile.py index ee4ba67f2..5b049fe73 100644 --- a/account_asset_management/models/account_asset_profile.py +++ b/account_asset_management/models/account_asset_profile.py @@ -163,6 +163,12 @@ class AccountAssetProfile(models.Model): "product item. So, there will be an asset by product item.", ) active = fields.Boolean(default=True) + allow_reversal = fields.Boolean( + "Allow Reversal of journal entries", + help="If set, when pressing the Delete/Reverse Move button in a " + "posted depreciation line will prompt the option to reverse the " + "journal entry, instead of deleting them.", + ) @api.model def _default_company_id(self): diff --git a/account_asset_management/models/account_move.py b/account_asset_management/models/account_move.py index 9df9ae442..f18d2a80e 100644 --- a/account_asset_management/models/account_move.py +++ b/account_asset_management/models/account_move.py @@ -125,8 +125,15 @@ class AccountMove(models.Model): for line_command in move_vals.get("line_ids", []): line_vals = line_command[2] # (0, 0, {...}) asset = self.env["account.asset"].browse(line_vals["asset_id"]) - asset.unlink() - line_vals.update(asset_profile_id=False, asset_id=False) + # We remove the asset if we recognize that we are reversing + # the asset creation + if asset: + asset_line = self.env["account.asset.line"].search( + [("asset_id", "=", asset.id), ("type", "=", "create")], limit=1 + ) + if asset_line and asset_line.move_id == self: + asset.unlink() + line_vals.update(asset_profile_id=False, asset_id=False) return move_vals def action_view_assets(self): diff --git a/account_asset_management/readme/CONTRIBUTORS.rst b/account_asset_management/readme/CONTRIBUTORS.rst index 0a67bec62..01cf3b0d0 100644 --- a/account_asset_management/readme/CONTRIBUTORS.rst +++ b/account_asset_management/readme/CONTRIBUTORS.rst @@ -15,3 +15,7 @@ * Pedro M. Baeza * Víctor Martínez * João Marques + +* `ForgeFlow `_: + + * Jordi Ballester diff --git a/account_asset_management/readme/HISTORY.rst b/account_asset_management/readme/HISTORY.rst index e35ac96cb..bac2415b5 100644 --- a/account_asset_management/readme/HISTORY.rst +++ b/account_asset_management/readme/HISTORY.rst @@ -1,3 +1,9 @@ +13.0.3.0.0 (2021-07-06) +~~~~~~~~~~~~~~~~~~~~~~~ + +* Allow to reverse the posting of a depreciation line instead of deleting the + journal entry. + 13.0.2.0.0 (2021-02-19) ~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/account_asset_management/tests/test_account_asset_management.py b/account_asset_management/tests/test_account_asset_management.py index 778a72b4b..5ea9d3d90 100644 --- a/account_asset_management/tests/test_account_asset_management.py +++ b/account_asset_management/tests/test_account_asset_management.py @@ -794,3 +794,75 @@ class TestAssetManagement(SavepointCase): self.assertAlmostEqual(d_lines[_i].amount, 416.67, places=2) # In the last month the small deviations are compensated self.assertAlmostEqual(d_lines[12].amount, 416.63, places=2) + + def test_18_reverse_entries(self): + """Test that cancelling a posted entry creates a reversal.""" + # + # first load demo assets and do some sanity checks + # + ict0 = self.browse_ref("account_asset_management.account_asset_asset_ict0") + ict0.profile_id.allow_reversal = True + # + # I compute the depreciation boards + # + ict0.compute_depreciation_board() + ict0.refresh() + # + # I post the first depreciation line + # + ict0.validate() + ict0.depreciation_line_ids[1].create_move() + original_move = ict0.depreciation_line_ids[1].move_id + ict0.refresh() + self.assertEqual(ict0.state, "open") + self.assertEqual(ict0.value_depreciated, 500) + self.assertEqual(ict0.value_residual, 1000) + depreciation_line = ict0.depreciation_line_ids[1] + wiz_res = depreciation_line.unlink_move() + self.assertTrue( + "res_model" in wiz_res and wiz_res["res_model"] == "wiz.asset.move.reverse" + ) + wiz = Form( + self.env["wiz.asset.move.reverse"].with_context( + { + "active_model": depreciation_line._name, + "active_id": depreciation_line.id, + "active_ids": [depreciation_line.id], + } + ) + ) + reverse_wizard = wiz.save() + reverse_wizard.reverse_move() + ict0.refresh() + self.assertEqual(ict0.value_depreciated, 0) + self.assertEqual(ict0.value_residual, 1500) + self.assertEqual(len(original_move.reversal_move_id), 1) + + def test_19_unlink_entries(self): + """Test that cancelling a posted entry creates a reversal, if the + journal entry has the inalterability hash.""" + # + # first load demo assets and do some sanity checks + # + ict0 = self.browse_ref("account_asset_management." "account_asset_asset_ict0") + # + # I compute the depreciation boards + # + ict0.compute_depreciation_board() + ict0.refresh() + # + # I post the first depreciation line + # + ict0.validate() + ict0.depreciation_line_ids[1].create_move() + original_move_id = ict0.depreciation_line_ids[1].move_id.id + ict0.refresh() + self.assertEqual(ict0.state, "open") + self.assertEqual(ict0.value_depreciated, 500) + self.assertEqual(ict0.value_residual, 1000) + ict0.depreciation_line_ids[1].unlink_move() + ict0.refresh() + self.assertEqual(ict0.value_depreciated, 0) + self.assertEqual(ict0.value_residual, 1500) + move = self.env["account.move"].search([("id", "=", original_move_id)]) + self.assertFalse(move) diff --git a/account_asset_management/views/account_asset.xml b/account_asset_management/views/account_asset.xml index e61fa99f1..879b806f9 100644 --- a/account_asset_management/views/account_asset.xml +++ b/account_asset_management/views/account_asset.xml @@ -206,7 +206,7 @@