Skip to content
Snippets Groups Projects
Commit 9441ec6e0bc1 authored by Etienne Ferriere's avatar Etienne Ferriere
Browse files

Add the possibility to forbid unreconciliation for accounting entries emitted

on specific accounts on closed periods.
parent 5a3faba08229
No related branches found
No related tags found
No related merge requests found
Pipeline #107192 passed
This commit is part of merge request !48. Comments created here will be created in the context of that merge request.
...@@ -2,6 +2,12 @@ ...@@ -2,6 +2,12 @@
Changelog Changelog
========= =========
13.0.1.6.0
----------
Add the possibility to forbid unreconciliation for accounting entries emitted
on specific accounts on closed periods.
13.0.1.5.1 13.0.1.5.1
---------- ----------
......
...@@ -33,5 +33,7 @@ ...@@ -33,5 +33,7 @@
* Add accounting date used to select the right period. * Add accounting date used to select the right period.
* Add transaction date. * Add transaction date.
* Hide default ``date`` field, obsoleted by accounting date above. * Hide default ``date`` field, obsoleted by accounting date above.
* Add the possibility to forbid unreconciliation for accounting entries emitted
on specific accounts on closed periods.
Inspired from what used to be available in previous Odoo versions. Inspired from what used to be available in previous Odoo versions.
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
"name": "Accounting Periods", "name": "Accounting Periods",
"license": "AGPL-3", "license": "AGPL-3",
"summary": "Add period accounting concept", "summary": "Add period accounting concept",
"version": "13.0.1.5.1", "version": "13.0.1.6.0",
"category": "Accounting/Accounting", "category": "Accounting/Accounting",
"author": "XCG Consulting", "author": "XCG Consulting",
"website": "https://odoo.consulting/", "website": "https://odoo.consulting/",
...@@ -26,8 +26,8 @@ ...@@ -26,8 +26,8 @@
"category": "Accounting/Accounting", "category": "Accounting/Accounting",
"author": "XCG Consulting", "author": "XCG Consulting",
"website": "https://odoo.consulting/", "website": "https://odoo.consulting/",
"depends": ["account"], "depends": ["account", "l10n_generic_coa"],
"data": [ "data": [
"security/ir.model.access.csv", "security/ir.model.access.csv",
"security/record_rules.xml", "security/record_rules.xml",
"wizards/account_period_close_view.xml", "wizards/account_period_close_view.xml",
...@@ -30,7 +30,8 @@ ...@@ -30,7 +30,8 @@
"data": [ "data": [
"security/ir.model.access.csv", "security/ir.model.access.csv",
"security/record_rules.xml", "security/record_rules.xml",
"wizards/account_period_close_view.xml", "wizards/account_period_close_view.xml",
"views/account_account.xml",
"views/account_move.xml", "views/account_move.xml",
"views/account_period.xml", "views/account_period.xml",
"views/account_fiscalyear.xml", "views/account_fiscalyear.xml",
......
...@@ -7,8 +7,8 @@ ...@@ -7,8 +7,8 @@
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 10.0\n" "Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-09-09 08:42+0000\n" "POT-Creation-Date: 2024-08-16 16:16+0000\n"
"PO-Revision-Date: 2022-09-09 10:45+0200\n" "PO-Revision-Date: 2024-08-16 18:24+0200\n"
"Last-Translator: Vincent Hatakeyama <vincent.hatakeyama@xcg-consulting.fr>\n" "Last-Translator: Vincent Hatakeyama <vincent.hatakeyama@xcg-consulting.fr>\n"
"Language-Team: XCG Consulting\n" "Language-Team: XCG Consulting\n"
"Language: fr\n" "Language: fr\n"
...@@ -16,7 +16,12 @@ ...@@ -16,7 +16,12 @@
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: Poedit 2.4.2\n" "X-Generator: Poedit 3.0.1\n"
#. module: account_period
#: model:ir.model,name:account_period.model_account_account
msgid "Account"
msgstr "Compte"
#. module: account_period #. module: account_period
#: model:ir.model,name:account_period.model_account_chart_template #: model:ir.model,name:account_period.model_account_chart_template
...@@ -48,6 +53,15 @@ ...@@ -48,6 +53,15 @@
msgstr "Annuler" msgstr "Annuler"
#. module: account_period #. module: account_period
#: model:ir.model.fields,help:account_period.field_account_account__forbid_unreconcile_closed_periods
msgid ""
"Check the box, to forbid unreconciliation for accounting entries emitted on "
"this account on closed periods."
msgstr ""
"Cocher la case pour interdire le délettrage d'écritures comptables émises "
"sur ce compte comptable sur des périodes fermées."
#. module: account_period
#: model:ir.model.fields,field_description:account_period.field_account_period_close__validated #: model:ir.model.fields,field_description:account_period.field_account_period_close__validated
msgid "Check this box" msgid "Check this box"
msgstr "Cocher cette case" msgstr "Cocher cette case"
...@@ -164,6 +178,11 @@ ...@@ -164,6 +178,11 @@
msgstr "Exercices fiscaux" msgstr "Exercices fiscaux"
#. module: account_period #. module: account_period
#: model:ir.model.fields,field_description:account_period.field_account_account__forbid_unreconcile_closed_periods
msgid "Forbid unreconciliation on closed periods"
msgstr "Interdire le délettrage sur périodes fermées"
#. module: account_period
#: code:addons/account_period/models/account_period.py:0 #: code:addons/account_period/models/account_period.py:0
#, python-format #, python-format
msgid "Go to the configuration panel" msgid "Go to the configuration panel"
...@@ -295,6 +314,17 @@ ...@@ -295,6 +314,17 @@
msgstr "Réaffecter les périodes" msgstr "Réaffecter les périodes"
#. module: account_period #. module: account_period
#: code:addons/account_period/models/account_move_line.py:0
#, python-format
msgid ""
"Some accounting entries to unreconcile are emitted on closed periods and "
"accounts, which are set to forbid unreconciliation on closed periods."
msgstr ""
"Des écritures comptables à délettrer sont émises sur des périodes fermées, "
"ce qui interdit le délettrage selon la configuration des comptes comptables "
"sur lesquelles elles sont émises."
#. module: account_period
#: model:ir.model.fields,field_description:account_period.field_account_period__date_start #: model:ir.model.fields,field_description:account_period.field_account_period__date_start
msgid "Start" msgid "Start"
msgstr "Début" msgstr "Début"
......
from . import ( # noqa: F401 from . import ( # noqa: F401
account_account,
account_chart_template, account_chart_template,
account_fiscalyear, account_fiscalyear,
...@@ -2,4 +3,5 @@ ...@@ -2,4 +3,5 @@
account_chart_template, account_chart_template,
account_fiscalyear, account_fiscalyear,
account_full_reconcile,
account_move, account_move,
account_move_line, account_move_line,
...@@ -4,4 +6,5 @@ ...@@ -4,4 +6,5 @@
account_move, account_move,
account_move_line, account_move_line,
account_partial_reconcile,
account_period, account_period,
) )
##############################################################################
#
# Accounting periods, for Odoo
# Copyright (C) 2024 XCG Consulting <http://odoo.consulting>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from odoo import fields, models
class Account(models.Model):
"""Add the possibility to forbid unreconciliation for accounting entries
emitted on specific accounts on closed periods.
"""
_inherit = "account.account"
forbid_unreconcile_closed_periods = fields.Boolean(
string="Forbid unreconciliation on closed periods",
help=(
"Check the box, to forbid unreconciliation for accounting entries "
"emitted on this account on closed periods."
),
index=True,
)
##############################################################################
#
# Accounting periods, for Odoo
# Copyright (C) 2024 XCG Consulting <http://odoo.consulting>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from odoo import models
class AccountFullReconcile(models.Model):
"""Add the possibility to forbid unreconciliation for accounting entries
emitted on specific accounts on closed periods.
"""
_inherit = "account.full.reconcile"
def unlink(self):
"""Override to:
- Forbid unreconciliation for accounting entries emitted on specific
accounts on closed periods.
"""
# Forbid unreconciliation for accounting entries emitted on specific
# accounts on closed periods.
self.reconciled_line_ids.forbid_unreconcile_closed_periods()
return super().unlink()
...@@ -18,9 +18,9 @@ ...@@ -18,9 +18,9 @@
# #
############################################################################## ##############################################################################
from odoo import fields, models from odoo import _, exceptions, fields, models
class AccountMoveLine(models.Model): class AccountMoveLine(models.Model):
"""Add a period & dates onto accounting entries (taken from the related """Add a period & dates onto accounting entries (taken from the related
account.move object). account.move object).
...@@ -22,8 +22,10 @@ ...@@ -22,8 +22,10 @@
class AccountMoveLine(models.Model): class AccountMoveLine(models.Model):
"""Add a period & dates onto accounting entries (taken from the related """Add a period & dates onto accounting entries (taken from the related
account.move object). account.move object).
Add the possibility to forbid unreconciliation for accounting entries
emitted on specific accounts on closed periods.
""" """
_inherit = "account.move.line" _inherit = "account.move.line"
...@@ -50,3 +52,38 @@ ...@@ -50,3 +52,38 @@
readonly=True, readonly=True,
store=True, store=True,
) )
def remove_move_reconcile(self):
"""Override to:
- Forbid unreconciliation for accounting entries emitted on specific
accounts on closed periods.
"""
# Forbid unreconciliation for accounting entries emitted on specific
# accounts on closed periods.
self.forbid_unreconcile_closed_periods()
return super().remove_move_reconcile()
def forbid_unreconcile_closed_periods(self):
"""Forbid unreconciliation for accounting entries emitted on specific
accounts on closed periods.
"""
if any(
self.mapped(
lambda r: (
r.account_id.forbid_unreconcile_closed_periods
and r.period_id.state == "done"
)
)
):
raise exceptions.UserError(
_(
"Some accounting entries to unreconcile are emitted on "
"closed periods and accounts, which are set to forbid "
"unreconciliation on closed periods."
)
)
return True
##############################################################################
#
# Accounting periods, for Odoo
# Copyright (C) 2024 XCG Consulting <http://odoo.consulting>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from odoo import models
class AccountPartialReconcile(models.Model):
"""Add the possibility to forbid unreconciliation for accounting entries
emitted on specific accounts on closed periods.
"""
_inherit = "account.partial.reconcile"
def unlink(self):
"""Override to:
- Forbid unreconciliation for accounting entries emitted on specific
accounts on closed periods.
"""
# Forbid unreconciliation for accounting entries emitted on specific
# accounts on closed periods.
(
self.debit_move_id | self.credit_move_id
).forbid_unreconcile_closed_periods()
return super().unlink()
...@@ -4,4 +4,5 @@ ...@@ -4,4 +4,5 @@
test_account_move2, test_account_move2,
test_account_move3, test_account_move3,
test_account_period, test_account_period,
test_unreconcile,
) )
##############################################################################
#
# Accounting Periods, for Odoo
# Copyright (C) 2024 XCG Consulting <http://odoo.consulting>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from odoo import exceptions, fields
from odoo.tests import tagged
from odoo.addons.account.tests.account_test_savepoint import (
AccountTestInvoicingCommon,
)
@tagged("post_install", "-at_install")
class TestUnreconcile(AccountTestInvoicingCommon):
"""Check it is not possible to unreconcile accounting entries emitted on
closed periods, if one of their account is set in order to forbid this.
"""
@classmethod
def setUpClass(cls, chart_template_ref=None):
super().setUpClass(chart_template_ref=chart_template_ref)
cls.company_data["default_account_revenue"].write(
{"reconcile": True, "forbid_unreconcile_closed_periods": True}
)
cls.move_date = fields.Date.from_string("2019-01-01")
(cls.move_1, cls.move_2, cls.move_3, cls.move_4) = cls.env[
"account.move"
].create(
[
{
"type": "entry",
"date": cls.move_date,
"line_ids": [
(
0,
None,
{
"name": "revenue line 1",
"account_id": cls.company_data[
"default_account_revenue"
].id,
"debit": 500.0,
"credit": 0.0,
},
),
(
0,
None,
{
"name": "revenue line 2",
"account_id": cls.company_data[
"default_account_revenue"
].id,
"debit": 1000.0,
"credit": 0.0,
},
),
(
0,
None,
{
"name": "counterpart line",
"account_id": cls.company_data[
"default_account_expense"
].id,
"debit": 0.0,
"credit": 1500.0,
},
),
],
}
for _i in range(2)
]
+ [
{
"type": "entry",
"date": cls.move_date,
"line_ids": [
(
0,
None,
{
"name": "revenue line 1",
"account_id": cls.company_data[
"default_account_revenue"
].id,
"credit": 500.0,
"debit": 0.0,
},
),
(
0,
None,
{
"name": "revenue line 2",
"account_id": cls.company_data[
"default_account_revenue"
].id,
"credit": 1000.0,
"debit": 0.0,
},
),
(
0,
None,
{
"name": "counterpart line",
"account_id": cls.company_data[
"default_account_expense"
].id,
"credit": 0.0,
"debit": 1500.0,
},
),
],
}
for _i in range(2)
]
)
# Create a fiscal year 2019.
cls.fiscalyear_2019 = cls.env["account.fiscalyear"].create(
{"date_stop": "2019-12-31", "name": "2019", "code": "2019"}
)
cls.fiscalyear_2019.create_period()
cls.moves = cls.move_1 | cls.move_2 | cls.move_3 | cls.move_4
cls.moves.post()
# Full reconcile.
cls.lines_1 = cls.move_1.line_ids.filtered(
lambda r: r.name == "revenue line 1"
)
cls.lines_2 = cls.move_3.line_ids.filtered(
lambda r: r.name == "revenue line 1"
)
(cls.lines_1 | cls.lines_2).reconcile()
cls.full_reconcile_1 = cls.lines_2.full_reconcile_id
cls.lines_1b = cls.move_1.line_ids.filtered(
lambda r: r.name == "revenue line 2"
)
cls.lines_2b = cls.move_3.line_ids.filtered(
lambda r: r.name == "revenue line 2"
)
(cls.lines_1b | cls.lines_2b).reconcile()
cls.full_reconcile_2 = cls.lines_2b.full_reconcile_id
# Partial reconcile.
cls.lines_3 = cls.move_2.line_ids.filtered(
lambda r: r.name == "revenue line 1"
)
cls.lines_4 = cls.move_4.line_ids.filtered(
lambda r: r.name == "revenue line 2"
)
(cls.lines_3 | cls.lines_4).reconcile(
writeoff_acc_id=cls.company_data["default_account_receivable"],
writeoff_journal_id=cls.company_data["default_journal_bank"],
)
cls.partial_reconcile = cls.lines_4.matched_debit_ids
# Close the periods of the fiscal year 2019.
wizard_obj = cls.env["account.period.close"].with_context(
active_ids=cls.fiscalyear_2019.period_ids.ids
)
wizard = wizard_obj.create({"validated": True})
wizard.close()
def test_0101_full_unreconcile_1(self):
"""Check it is not possible to unreconcile accounting entries emitted
on closed periods, if one of their account is set in order to forbid
this.
Check on fully reconciled entries.
"""
for line_1 in self.lines_1:
self.assertEqual(line_1.full_reconcile_id, self.full_reconcile_1)
with self.assertRaises(exceptions.UserError):
self.full_reconcile_1.unlink()
self.company_data["default_account_revenue"].write(
{"forbid_unreconcile_closed_periods": False}
)
self.full_reconcile_1.unlink()
self.assertFalse(self.full_reconcile_1.exists())
self.company_data["default_account_revenue"].write(
{"forbid_unreconcile_closed_periods": True}
)
def test_0102_full_unreconcile_2(self):
"""Check it is not possible to unreconcile accounting entries emitted
on closed periods, if one of their account is set in order to forbid
this.
Check on fully reconciled entries.
"""
for line_1b in self.lines_1b:
self.assertEqual(line_1b.full_reconcile_id, self.full_reconcile_2)
wizard_obj = self.env["account.unreconcile"].with_context(
active_ids=(self.lines_1b | self.lines_2b).ids
)
wizard = wizard_obj.create({})
with self.assertRaises(exceptions.UserError):
wizard.trans_unrec()
self.company_data["default_account_revenue"].write(
{"forbid_unreconcile_closed_periods": False}
)
wizard.trans_unrec()
self.assertFalse(self.full_reconcile_2.exists())
self.company_data["default_account_revenue"].write(
{"forbid_unreconcile_closed_periods": True}
)
def test_0200_partial_unreconcile(self):
"""Check it is not possible to unreconcile accounting entries emitted
on closed periods, if one of their account is set in order to forbid
this.
Check on partially reconciled entries.
"""
for line_3 in self.lines_3:
self.assertIn(line_3.matched_credit_ids, self.partial_reconcile)
with self.assertRaises(exceptions.UserError):
self.partial_reconcile.unlink()
self.company_data["default_account_revenue"].write(
{"forbid_unreconcile_closed_periods": False}
)
self.partial_reconcile.unlink()
self.assertFalse(self.partial_reconcile.exists())
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!-- Add the possibility to forbid unreconciliation for accounting entries
emitted on specific accounts on closed periods. -->
<!-- Inherit from the account form view defined in "account". -->
<record id="account_period_account_form" model="ir.ui.view">
<field name="name">account_period_account_form</field>
<field name="model">account.account</field>
<field name="inherit_id" ref="account.view_account_form" />
<field name="arch" type="xml">
<!-- Add fields. -->
<xpath expr="//div[field[@name='reconcile']]" position="after">
<field name="forbid_unreconcile_closed_periods" />
</xpath>
</field>
</record>
</odoo>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment