Initial commit: Odoo 18.0-20251222 extra-addons
Some checks failed
pre-commit / pre-commit (push) Has been cancelled
tests / Detect unreleased dependencies (push) Has been cancelled
tests / test with OCB (push) Has been cancelled
tests / test with Odoo (push) Has been cancelled

This commit is contained in:
tocmo0nlord
2026-03-13 20:43:25 +00:00
parent 36e847a7df
commit adbe430761
9472 changed files with 1265727 additions and 0 deletions

101
account_lock_to_date/README.rst Executable file
View File

@@ -0,0 +1,101 @@
.. image:: https://odoo-community.org/readme-banner-image
:target: https://odoo-community.org/get-involved?utm_source=readme
:alt: Odoo Community Association
====================
Account Lock To Date
====================
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:76e4e73f76858c9c58ca4873e595b81fdfd386e0606f51bf4a57bf3284522770
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Faccount--financial--tools-lightgray.png?logo=github
:target: https://github.com/OCA/account-financial-tools/tree/18.0/account_lock_to_date
:alt: OCA/account-financial-tools
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/account-financial-tools-18-0/account-financial-tools-18-0-account_lock_to_date
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/account-financial-tools&target_branch=18.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
This module allows to set a Period and Fiscal year Locking end dates.
This will prevent users from posting journal entries on a date after the
defined period or fiscal year end date.
**Table of contents**
.. contents::
:local:
Usage
=====
To set a new lock to dates, go to *Invoicing / Accounting / Actions /
Update accounting lock to dates*.
A user without an Adviser group will not be able to post or update
posted journal entries on the date "Lock To Date for Non-Advisers" or
after.
A user that has an Adviser group will not be able to post or update
posted journal entries on the date "Lock To Date" or after.
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/account-financial-tools/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/account-financial-tools/issues/new?body=module:%20account_lock_to_date%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
-------
* ForgeFlow
Contributors
------------
- | ForgeFlow
<`https://www.ForgeFlow.com\\> <https://www.ForgeFlow.com\>>`__
| \*\* Jordi Ballester Alomar <jordi.ballester@ForgeFlow.com>
- `Aion Tech <https://aiontech.company/>`__:
- Simone Rubino <simone.rubino@aion-tech.it>
Maintainers
-----------
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
This module is part of the `OCA/account-financial-tools <https://github.com/OCA/account-financial-tools/tree/18.0/account_lock_to_date>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

@@ -0,0 +1,2 @@
from . import models
from . import wizards

View File

@@ -0,0 +1,19 @@
# Copyright 2019 ForgeFlow S.L.
# Copyright 2023 Simone Rubino - Aion Tech
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "Account Lock To Date",
"summary": """
Allows to set an account lock date in the future.""",
"version": "18.0.1.0.0",
"license": "AGPL-3",
"author": "ForgeFlow, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/account-financial-tools",
"installable": True,
"depends": ["account"],
"data": [
"security/ir.model.access.csv",
"wizards/account_update_lock_to_date.xml",
],
}

View File

@@ -0,0 +1,240 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_lock_to_date
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 18.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: account_lock_to_date
#. odoo-python
#: code:addons/account_lock_to_date/models/res_company.py:0
msgid "A new Hard Lock To Date must be prior (or equal) to the previous one."
msgstr ""
#. module: account_lock_to_date
#: model:ir.model,name:account_lock_to_date.model_account_lock_exception
msgid "Account Lock Exception"
msgstr ""
#. module: account_lock_to_date
#: model:ir.model,name:account_lock_to_date.model_account_update_lock_to_date
msgid "Account Update Lock_to_date"
msgstr ""
#. module: account_lock_to_date
#: model_terms:ir.ui.view,arch_db:account_lock_to_date.account_update_lock_to_date_form_view
msgid "Cancel"
msgstr ""
#. module: account_lock_to_date
#: model:ir.model,name:account_lock_to_date.model_res_company
msgid "Companies"
msgstr ""
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__company_id
msgid "Company"
msgstr ""
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__create_uid
msgid "Created by"
msgstr ""
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__create_date
msgid "Created on"
msgstr ""
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__display_name
msgid "Display Name"
msgstr ""
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_lock_exception__fiscalyear_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__fiscalyear_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_res_company__fiscalyear_lock_to_date
#: model:ir.model.fields.selection,name:account_lock_to_date.selection__account_lock_exception__lock_date_field__fiscalyear_lock_to_date
msgid "Global Lock To Date"
msgstr ""
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_res_company__hard_lock_to_date
msgid "Hard Lock To Date"
msgstr ""
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__id
msgid "ID"
msgstr ""
#. module: account_lock_to_date
#: model:ir.model,name:account_lock_to_date.model_account_move
msgid "Journal Entry"
msgstr ""
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__write_uid
msgid "Last Updated by"
msgstr ""
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__write_date
msgid "Last Updated on"
msgstr ""
#. module: account_lock_to_date
#: model:ir.model.fields,help:account_lock_to_date.field_account_update_lock_to_date__hard_lock_to_date
#: model:ir.model.fields,help:account_lock_to_date.field_res_company__hard_lock_to_date
msgid "Like the \"Global Lock Date\", but no exceptions are possible."
msgstr ""
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_lock_exception__lock_date_field
msgid "Lock Date Field"
msgstr ""
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__hard_lock_to_date
msgid "Lock To Date"
msgstr ""
#. module: account_lock_to_date
#: model:ir.model.fields,help:account_lock_to_date.field_account_update_lock_to_date__fiscalyear_lock_to_date
#: model:ir.model.fields,help:account_lock_to_date.field_res_company__fiscalyear_lock_to_date
msgid ""
"No users can edit accounts posterior to this date. Use it for fiscal year "
"locking for example."
msgstr ""
#. module: account_lock_to_date
#. odoo-python
#: code:addons/account_lock_to_date/models/account_lock_exception.py:0
msgid "Operation not supported"
msgstr ""
#. module: account_lock_to_date
#: model:ir.model.fields,help:account_lock_to_date.field_account_update_lock_to_date__purchase_lock_to_date
#: model:ir.model.fields,help:account_lock_to_date.field_res_company__purchase_lock_to_date
msgid ""
"Prevents creation and modification of entries in purchase journals posterior"
" to the defined date inclusive."
msgstr ""
#. module: account_lock_to_date
#: model:ir.model.fields,help:account_lock_to_date.field_account_update_lock_to_date__sale_lock_to_date
#: model:ir.model.fields,help:account_lock_to_date.field_res_company__sale_lock_to_date
msgid ""
"Prevents creation and modification of entries in sales journals posterior to"
" the defined date inclusive."
msgstr ""
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_lock_exception__purchase_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__purchase_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_res_company__purchase_lock_to_date
#: model:ir.model.fields.selection,name:account_lock_to_date.selection__account_lock_exception__lock_date_field__purchase_lock_to_date
msgid "Purchase Lock To Date"
msgstr ""
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_lock_exception__sale_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__sale_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_res_company__sale_lock_to_date
#: model:ir.model.fields.selection,name:account_lock_to_date.selection__account_lock_exception__lock_date_field__sale_lock_to_date
msgid "Sales Lock To Date"
msgstr ""
#. module: account_lock_to_date
#: model:ir.model.fields,help:account_lock_to_date.field_account_lock_exception__lock_date_field
msgid "Technical field identifying the changed lock date"
msgstr ""
#. module: account_lock_to_date
#. odoo-python
#: code:addons/account_lock_to_date/models/res_company.py:0
msgid "The Hard Lock Date cannot be removed."
msgstr ""
#. module: account_lock_to_date
#: model:ir.model.fields,help:account_lock_to_date.field_account_lock_exception__fiscalyear_lock_to_date
msgid ""
"The date the Global Lock To Date is set to by this exception. If the lock to"
" date is not changed it is set to False."
msgstr ""
#. module: account_lock_to_date
#: model:ir.model.fields,help:account_lock_to_date.field_account_lock_exception__purchase_lock_to_date
msgid ""
"The date the Purchase Lock To Date is set to by this exception. If the lock "
"to date is not changed it is set to False."
msgstr ""
#. module: account_lock_to_date
#: model:ir.model.fields,help:account_lock_to_date.field_account_lock_exception__sale_lock_to_date
msgid ""
"The date the Sale Lock To Date is set to by this exception. If the lock to "
"date is not changed it is set to False."
msgstr ""
#. module: account_lock_to_date
#. odoo-python
#: code:addons/account_lock_to_date/models/res_company.py:0
msgid ""
"There are still unposted entries in the period to date you want to hard "
"lock. You should either post or delete them."
msgstr ""
#. module: account_lock_to_date
#: model_terms:ir.ui.view,arch_db:account_lock_to_date.account_update_lock_to_date_form_view
msgid "Update"
msgstr ""
#. module: account_lock_to_date
#: model:ir.actions.act_window,name:account_lock_to_date.account_update_lock_to_date_act_window
#: model:ir.ui.menu,name:account_lock_to_date.account_update_lock_to_date_menu
msgid "Update accounting lock to dates"
msgstr ""
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_res_company__user_fiscalyear_lock_to_date
msgid "User Fiscalyear Lock To Date"
msgstr ""
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_res_company__user_hard_lock_to_date
msgid "User Hard Lock To Date"
msgstr ""
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_res_company__user_purchase_lock_to_date
msgid "User Purchase Lock To Date"
msgstr ""
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_res_company__user_sale_lock_to_date
msgid "User Sale Lock To Date"
msgstr ""
#. module: account_lock_to_date
#. odoo-python
#: code:addons/account_lock_to_date/wizards/account_update_lock_to_date.py:0
msgid "You are not allowed to execute this action."
msgstr ""
#. module: account_lock_to_date
#. odoo-python
#: code:addons/account_lock_to_date/models/account_move.py:0
msgid ""
"You cannot add/modify entries posterior to and inclusive of: "
"%(lock_date_info)s."
msgstr ""

214
account_lock_to_date/i18n/es.po Executable file
View File

@@ -0,0 +1,214 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_lock_to_date
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 15.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2023-08-09 15:10+0000\n"
"Last-Translator: Ivorra78 <informatica@totmaterial.es>\n"
"Language-Team: none\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.17\n"
#. module: account_lock_to_date
#: model:ir.model,name:account_lock_to_date.model_account_update_lock_to_date
msgid "Account Update Lock_to_date"
msgstr "Actualización de cuenta Lock_to_date"
#. module: account_lock_to_date
#: model_terms:ir.ui.view,arch_db:account_lock_to_date.account_update_lock_to_date_form_view
msgid "Cancel"
msgstr "Cancelar"
#. module: account_lock_to_date
#: model:ir.model,name:account_lock_to_date.model_res_company
msgid "Companies"
msgstr "Compañías"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__company_id
msgid "Company"
msgstr "Companía"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__create_uid
msgid "Created by"
msgstr "Creado por"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__create_date
msgid "Created on"
msgstr "Creado el"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__display_name
msgid "Display Name"
msgstr "Mostrar Nombre"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__id
msgid "ID"
msgstr "ID (identificación)"
#. module: account_lock_to_date
#: model:ir.model,name:account_lock_to_date.model_account_move
msgid "Journal Entry"
msgstr "Entrada Diaria"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date____last_update
msgid "Last Modified on"
msgstr "Última Modificación el"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__write_uid
msgid "Last Updated by"
msgstr "Actualizado por Última vez por"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__write_date
msgid "Last Updated on"
msgstr "Última Actualización el"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__fiscalyear_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_res_company__fiscalyear_lock_to_date
msgid "Lock To Date"
msgstr "Bloquear hasta la fecha"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__period_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_res_company__period_lock_to_date
msgid "Lock To Date for Non-Advisers"
msgstr "Bloqueo hasta la fecha para no asesores"
#. module: account_lock_to_date
#: model:ir.model.fields,help:account_lock_to_date.field_account_update_lock_to_date__fiscalyear_lock_to_date
msgid ""
"No users, including Advisers, can edit accounts after and inclusive of this "
"date. Use it for fiscal year locking for example."
msgstr ""
"Ningún usuario, incluidos los Asesores, puede editar cuentas después de esta "
"fecha e inclusive. Utilícelo, por ejemplo, para el cierre del ejercicio."
#. module: account_lock_to_date
#: model:ir.model.fields,help:account_lock_to_date.field_res_company__fiscalyear_lock_to_date
msgid ""
"No users, including Advisers, can edit accounts after this date. Use it for "
"fiscal year locking for example."
msgstr ""
"Ningún usuario, incluidos los Asesores, puede editar cuentas después de esta "
"fecha. Utilícelo, por ejemplo, para el cierre del ejercicio."
#. module: account_lock_to_date
#: model:ir.model.fields,help:account_lock_to_date.field_account_update_lock_to_date__period_lock_to_date
msgid ""
"Only users with the 'Adviser' role can edit accounts after and inclusive of "
"this date. Use it for period locking inside an open fiscal year, for "
"example."
msgstr ""
"Sólo los usuarios con el rol de 'Asesor' pueden editar cuentas después e "
"inclusive de esta fecha. Utilícelo para bloquear periodos dentro de un "
"ejercicio fiscal abierto, por ejemplo."
#. module: account_lock_to_date
#: model:ir.model.fields,help:account_lock_to_date.field_res_company__period_lock_to_date
msgid ""
"Only users with the 'Adviser' role can edit accounts after this date. Use it"
" for period locking inside an open fiscal year, for example."
msgstr ""
"Sólo los usuarios con el rol de 'Asesor' pueden editar cuentas después de "
"esta fecha. Utilícelo para bloquear periodos dentro de un ejercicio fiscal "
"abierto, por ejemplo."
#. module: account_lock_to_date
#: code:addons/account_lock_to_date/models/res_company.py:0
#, python-format
msgid "The lock date for advisors is irreversible and can't be removed."
msgstr ""
"La fecha de bloqueo de los asesores es irreversible y no puede eliminarse."
#. module: account_lock_to_date
#: code:addons/account_lock_to_date/models/res_company.py:0
#, python-format
msgid ""
"The new lock to date for advisors must be set after the previous lock to "
"date."
msgstr ""
"La nueva fecha de bloqueo para los asesores debe fijarse después de la fecha "
"de bloqueo anterior."
#. module: account_lock_to_date
#: code:addons/account_lock_to_date/models/res_company.py:0
#, python-format
msgid ""
"There are still unposted entries in the period to date you want to lock. You"
" should either post or delete them."
msgstr ""
"Todavía hay entradas sin contabilizar en el periodo hasta la fecha que desea "
"bloquear. Debe contabilizarlas o eliminarlas."
#. module: account_lock_to_date
#: model_terms:ir.ui.view,arch_db:account_lock_to_date.account_update_lock_to_date_form_view
msgid "Update"
msgstr "Actualización"
#. module: account_lock_to_date
#: model:ir.actions.act_window,name:account_lock_to_date.account_update_lock_to_date_act_window
#: model:ir.ui.menu,name:account_lock_to_date.account_update_lock_to_date_menu
msgid "Update accounting lock to dates"
msgstr "Actualizar el bloqueo contable a fechas"
#. module: account_lock_to_date
#: code:addons/account_lock_to_date/wizards/account_update_lock_to_date.py:0
#, python-format
msgid "You are not allowed to execute this action."
msgstr "No puede ejecutar esta acción."
#. module: account_lock_to_date
#: code:addons/account_lock_to_date/models/account_move.py:0
#, python-format
msgid ""
"You cannot add/modify entries after and inclusive of the lock to date %s"
msgstr ""
"No puede añadir/modificar entradas después e inclusive del bloqueo hasta la "
"fecha %s"
#. module: account_lock_to_date
#: code:addons/account_lock_to_date/models/account_move.py:0
#, python-format
msgid ""
"You cannot add/modify entries after and inclusive of the lock to date %s. "
"Check the company settings or ask someone with the 'Adviser' role"
msgstr ""
"No se pueden añadir/modificar entradas después e incluyendo el bloqueo hasta "
"la fecha %s. Compruebe la configuración de la empresa o pregunte a alguien "
"con el rol de 'Asesor'"
#. module: account_lock_to_date
#: code:addons/account_lock_to_date/models/res_company.py:0
#, python-format
msgid ""
"You cannot define stricter conditions on advisors than on users. Please make"
" sure that the lock date on advisor is set after the lock date for users."
msgstr ""
"No se pueden definir condiciones más estrictas para los asesores que para "
"los usuarios. Asegúrese de que la fecha de bloqueo de los asesores es "
"posterior a la fecha de bloqueo de los usuarios."
#. module: account_lock_to_date
#: code:addons/account_lock_to_date/models/res_company.py:0
#, python-format
msgid ""
"You cannot lock a period that is not finished yet. Please make sure that the"
" lock date for advisors is set at or after the last day of the next month."
msgstr ""
"No se puede bloquear un periodo que aún no ha terminado. Asegúrese de que la "
"fecha de bloqueo de los asesores sea igual o posterior al último día del mes "
"siguiente."

204
account_lock_to_date/i18n/fr.po Executable file
View File

@@ -0,0 +1,204 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_lock_to_date
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2022-11-09 20:44+0000\n"
"Last-Translator: Valaeys Stéphane <svalaeys@fiefmanage.ch>\n"
"Language-Team: none\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 4.14.1\n"
#. module: account_lock_to_date
#: model:ir.model,name:account_lock_to_date.model_account_update_lock_to_date
msgid "Account Update Lock_to_date"
msgstr "Verrouillage des dates comptables futures"
#. module: account_lock_to_date
#: model_terms:ir.ui.view,arch_db:account_lock_to_date.account_update_lock_to_date_form_view
msgid "Cancel"
msgstr "Annuler"
#. module: account_lock_to_date
#: model:ir.model,name:account_lock_to_date.model_res_company
msgid "Companies"
msgstr "Sociétés"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__company_id
msgid "Company"
msgstr "Société"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__create_uid
msgid "Created by"
msgstr "Créé par"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__create_date
msgid "Created on"
msgstr "Créé le"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__display_name
msgid "Display Name"
msgstr "Nom affiché"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__id
msgid "ID"
msgstr "ID"
#. module: account_lock_to_date
#: model:ir.model,name:account_lock_to_date.model_account_move
msgid "Journal Entry"
msgstr "Pièce comptable"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date____last_update
msgid "Last Modified on"
msgstr "Dernière modification le"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__write_uid
msgid "Last Updated by"
msgstr "Dernière mise à jour par"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__write_date
msgid "Last Updated on"
msgstr "Dernière mise à jour le"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__fiscalyear_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_res_company__fiscalyear_lock_to_date
msgid "Lock To Date"
msgstr "Date de verrouillage future"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__period_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_res_company__period_lock_to_date
msgid "Lock To Date for Non-Advisers"
msgstr "Date de verrouillage future pour les non-conseillers"
#. module: account_lock_to_date
#: model:ir.model.fields,help:account_lock_to_date.field_account_update_lock_to_date__fiscalyear_lock_to_date
msgid ""
"No users, including Advisers, can edit accounts after and inclusive of this "
"date. Use it for fiscal year locking for example."
msgstr ""
"Aucun utilisateur, y compris les conseillers, ne peuvent modifier des "
"éléments comptables à partir de et y compris cette date. À utiliser pour "
"limiter un exercice fiscal, par exemple."
#. module: account_lock_to_date
#: model:ir.model.fields,help:account_lock_to_date.field_res_company__fiscalyear_lock_to_date
msgid ""
"No users, including Advisers, can edit accounts after this date. Use it for "
"fiscal year locking for example."
msgstr ""
"Aucun utilisateur, y compris les conseillers, ne peuvent modifier des "
"éléments comptables après cette date."
#. module: account_lock_to_date
#: model:ir.model.fields,help:account_lock_to_date.field_account_update_lock_to_date__period_lock_to_date
msgid ""
"Only users with the 'Adviser' role can edit accounts after and inclusive of "
"this date. Use it for period locking inside an open fiscal year, for example."
msgstr ""
#. module: account_lock_to_date
#: model:ir.model.fields,help:account_lock_to_date.field_res_company__period_lock_to_date
msgid ""
"Only users with the 'Adviser' role can edit accounts after this date. Use it "
"for period locking inside an open fiscal year, for example."
msgstr ""
#. module: account_lock_to_date
#: code:addons/account_lock_to_date/models/res_company.py:0
#, python-format
msgid "The lock date for advisors is irreversible and can't be removed."
msgstr ""
#. module: account_lock_to_date
#: code:addons/account_lock_to_date/models/res_company.py:0
#, python-format
msgid ""
"The new lock to date for advisors must be set after the previous lock to "
"date."
msgstr ""
#. module: account_lock_to_date
#: code:addons/account_lock_to_date/models/res_company.py:0
#, python-format
msgid ""
"There are still unposted entries in the period to date you want to lock. You "
"should either post or delete them."
msgstr ""
#. module: account_lock_to_date
#: model_terms:ir.ui.view,arch_db:account_lock_to_date.account_update_lock_to_date_form_view
msgid "Update"
msgstr "Mettre à jour"
#. module: account_lock_to_date
#: model:ir.actions.act_window,name:account_lock_to_date.account_update_lock_to_date_act_window
#: model:ir.ui.menu,name:account_lock_to_date.account_update_lock_to_date_menu
msgid "Update accounting lock to dates"
msgstr "Mettre à jour les dates de verrouillage futures"
#. module: account_lock_to_date
#: code:addons/account_lock_to_date/wizards/account_update_lock_to_date.py:0
#, python-format
msgid "You are not allowed to execute this action."
msgstr "Vous n'êtes pas autorisé à exécuter cette action."
#. module: account_lock_to_date
#: code:addons/account_lock_to_date/models/account_move.py:0
#, python-format
msgid ""
"You cannot add/modify entries after and inclusive of the lock to date %s"
msgstr ""
"Il n'est pas permis d'ajouter / modifier des éléments comptables après et y "
"compris la date de %s"
#. module: account_lock_to_date
#: code:addons/account_lock_to_date/models/account_move.py:0
#, python-format
msgid ""
"You cannot add/modify entries after and inclusive of the lock to date %s. "
"Check the company settings or ask someone with the 'Adviser' role"
msgstr ""
"Vous n'avez pas le droit d'ajouter / modifier des éléments comptables après "
"et y compris la date de %s. Veuillez vérifier la configuration de la société "
"ou vous rapprocher d'une personne avec le rôle de conseiller."
#. module: account_lock_to_date
#: code:addons/account_lock_to_date/models/res_company.py:0
#, python-format
msgid ""
"You cannot define stricter conditions on advisors than on users. Please make "
"sure that the lock date on advisor is set after the lock date for users."
msgstr ""
"Il n'est pas permis de définir des conditions plus strictes pour les "
"conseillers que les autres utilisateurs. Veuillez vous assurer que la date "
"de verrouillage future pour les conseillers et ultérieure à celle pour les "
"autres utilisateurs."
#. module: account_lock_to_date
#: code:addons/account_lock_to_date/models/res_company.py:0
#, python-format
msgid ""
"You cannot lock a period that is not finished yet. Please make sure that the "
"lock date for advisors is set at or after the last day of the next month."
msgstr ""
"Vous ne pouvez pas verrouiller une période qui n'est pas encore finie. "
"Veuille vous assurer que la date pour les conseillers est après le dernier "
"jour du mois prochain."

222
account_lock_to_date/i18n/it.po Executable file
View File

@@ -0,0 +1,222 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_lock_to_date
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2024-11-18 22:06+0000\n"
"Last-Translator: mymage <stefano.consolaro@mymage.it>\n"
"Language-Team: none\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.6.2\n"
#. module: account_lock_to_date
#: model:ir.model,name:account_lock_to_date.model_account_update_lock_to_date
msgid "Account Update Lock_to_date"
msgstr "Aggiorna Data di blocco contabilità nel futuro"
#. module: account_lock_to_date
#: model_terms:ir.ui.view,arch_db:account_lock_to_date.account_update_lock_to_date_form_view
msgid "Cancel"
msgstr "Annulla"
#. module: account_lock_to_date
#: model:ir.model,name:account_lock_to_date.model_res_company
msgid "Companies"
msgstr "Aziende"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__company_id
msgid "Company"
msgstr "Azienda"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__create_uid
msgid "Created by"
msgstr "Creato da"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__create_date
msgid "Created on"
msgstr "Creato il"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__display_name
msgid "Display Name"
msgstr "Nome visualizzato"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__id
msgid "ID"
msgstr "ID"
#. module: account_lock_to_date
#: model:ir.model,name:account_lock_to_date.model_account_move
msgid "Journal Entry"
msgstr "Registrazione contabile"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date____last_update
msgid "Last Modified on"
msgstr "Ultima modifica il"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__write_uid
msgid "Last Updated by"
msgstr "Ultimo aggiornamento di"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__write_date
msgid "Last Updated on"
msgstr "Ultimo aggiornamento il"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__fiscalyear_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_res_company__fiscalyear_lock_to_date
msgid "Lock To Date"
msgstr "Blocca alla data"
#. module: account_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_account_update_lock_to_date__period_lock_to_date
#: model:ir.model.fields,field_description:account_lock_to_date.field_res_company__period_lock_to_date
msgid "Lock To Date for Non-Advisers"
msgstr "Blocco alla data per non consulenti"
#. module: account_lock_to_date
#: model:ir.model.fields,help:account_lock_to_date.field_account_update_lock_to_date__fiscalyear_lock_to_date
msgid ""
"No users, including Advisers, can edit accounts after and inclusive of this "
"date. Use it for fiscal year locking for example."
msgstr ""
"Nessun utente, inclusi i consulenti, può modificare i movimenti contabili "
"dopo, e inclusa, questa data. Usarla per bloccare gli anni fiscali, per "
"esempio."
#. module: account_lock_to_date
#: model:ir.model.fields,help:account_lock_to_date.field_res_company__fiscalyear_lock_to_date
msgid ""
"No users, including Advisers, can edit accounts after this date. Use it for "
"fiscal year locking for example."
msgstr ""
"Nessun utente, inclusi i consulenti, può modificare i movimenti contabili "
"dopo questa data. Usarla per bloccare gli anni fiscali, per esempio."
#. module: account_lock_to_date
#: model:ir.model.fields,help:account_lock_to_date.field_account_update_lock_to_date__period_lock_to_date
msgid ""
"Only users with the 'Adviser' role can edit accounts after and inclusive of "
"this date. Use it for period locking inside an open fiscal year, for "
"example."
msgstr ""
"Solo gli utenti con il ruolo 'Consulente' possono editare i movimenti "
"contabili dopo, e inclusa, questa data. Usarla per bloccare i periodi in un "
"anno fiscale aperto, per esempio."
#. module: account_lock_to_date
#: model:ir.model.fields,help:account_lock_to_date.field_res_company__period_lock_to_date
msgid ""
"Only users with the 'Adviser' role can edit accounts after this date. Use it"
" for period locking inside an open fiscal year, for example."
msgstr ""
"Solo gli utenti con il ruolo 'Consulente' possono editare i movimenti "
"contabili dopo questa data. Usarla per bloccare i periodi all'interno di un "
"anno fiscale aperto, per esempio."
#. module: account_lock_to_date
#. odoo-python
#: code:addons/account_lock_to_date/models/res_company.py:0
#, python-format
msgid "The lock date for advisors is irreversible and can't be removed."
msgstr ""
"La data di blocco per i consulenti è immodificabile e non può essere rimossa."
#. module: account_lock_to_date
#. odoo-python
#: code:addons/account_lock_to_date/models/res_company.py:0
#, python-format
msgid ""
"The new lock to date for advisors must be set after the previous lock to "
"date."
msgstr ""
"La nuova data di blocco per consulenti deve essere impostata dopo la "
"precedente data di blocco."
#. module: account_lock_to_date
#. odoo-python
#: code:addons/account_lock_to_date/models/res_company.py:0
#, python-format
msgid ""
"There are still unposted entries in the period to date you want to lock. You"
" should either post or delete them."
msgstr ""
"Ci sono ancora movimenti non confermati nel periodo in cui si vuole bloccare "
"la data. Si dovrebbe confermarli oppure eliminarli."
#. module: account_lock_to_date
#: model_terms:ir.ui.view,arch_db:account_lock_to_date.account_update_lock_to_date_form_view
msgid "Update"
msgstr "Aggiorna"
#. module: account_lock_to_date
#: model:ir.actions.act_window,name:account_lock_to_date.account_update_lock_to_date_act_window
#: model:ir.ui.menu,name:account_lock_to_date.account_update_lock_to_date_menu
msgid "Update accounting lock to dates"
msgstr "Aggiornare date di blocco per contabilità"
#. module: account_lock_to_date
#. odoo-python
#: code:addons/account_lock_to_date/wizards/account_update_lock_to_date.py:0
#, python-format
msgid "You are not allowed to execute this action."
msgstr "Non si ha l'autorizzazione di eseguire questa azione."
#. module: account_lock_to_date
#. odoo-python
#: code:addons/account_lock_to_date/models/account_move.py:0
#, python-format
msgid ""
"You cannot add/modify entries after and inclusive of the lock to date %s"
msgstr ""
"Non si possono aggiungere/modificare le registrazioni dalla data di blocco %s"
#. module: account_lock_to_date
#. odoo-python
#: code:addons/account_lock_to_date/models/account_move.py:0
#, python-format
msgid ""
"You cannot add/modify entries after and inclusive of the lock to date %s. "
"Check the company settings or ask someone with the 'Adviser' role"
msgstr ""
"Non si possono aggiungere/modificare le registrazioni dalla data di blocco "
"%s. Controllare le impostazioni azienda o chiedere a qualcuno con il ruolo "
"di 'Revisore'"
#. module: account_lock_to_date
#. odoo-python
#: code:addons/account_lock_to_date/models/res_company.py:0
#, python-format
msgid ""
"You cannot define stricter conditions on advisors than on users. Please make"
" sure that the lock date on advisor is set after the lock date for users."
msgstr ""
"Non si possono definire condizioni sui revisori più stringenti che sui "
"revisori. Assicurarsi che la data di blocco sul revisore sia impostata "
"successiva alla data di blocco per gli utenti."
#. module: account_lock_to_date
#. odoo-python
#: code:addons/account_lock_to_date/models/res_company.py:0
#, python-format
msgid ""
"You cannot lock a period that is not finished yet. Please make sure that the"
" lock date for advisors is set at or after the last day of the next month."
msgstr ""
"Non si può bloccare un periodo che non sia ancora terminato. Assicurarsi che "
"la data di blocco per i revisori sia pari o successiva all' ultimo giorno "
"del mese successivo."

View File

@@ -0,0 +1,26 @@
# Copyright 2025 ForgeFlow S.L. (https://www.forgeflow.com)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from openupgradelib import openupgrade
def handle_new_lock_to_dates(env):
openupgrade.logged_query(
env.cr,
"""
UPDATE res_company
SET sale_lock_to_date = period_lock_to_date,
purchase_lock_to_date = period_lock_to_date
WHERE period_lock_to_date IS NOT NULL""",
)
openupgrade.logged_query(
env.cr,
"""
UPDATE res_company
SET hard_lock_to_date = fiscalyear_lock_to_date
WHERE fiscalyear_lock_to_date IS NOT NULL""",
)
@openupgrade.migrate()
def migrate(env, version):
handle_new_lock_to_dates(env)

View File

@@ -0,0 +1,3 @@
from . import res_company
from . import account_move
from . import account_lock_exception

View File

@@ -0,0 +1,90 @@
# Copyright 2025 ForgeFlow S.L.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import _, api, fields, models
from odoo.exceptions import UserError
from odoo.osv import expression
from .res_company import SOFT_LOCK_TO_DATE_FIELDS
class AccountLockException(models.Model):
_inherit = "account.lock_exception"
# The changed lock date
lock_date_field = fields.Selection(
selection_add=[
("fiscalyear_lock_to_date", "Global Lock To Date"),
("sale_lock_to_date", "Sales Lock To Date"),
("purchase_lock_to_date", "Purchase Lock To Date"),
],
ondelete={
"fiscalyear_lock_to_date": "cascade",
"sale_lock_to_date": "cascade",
"purchase_lock_to_date": "cascade",
},
)
# (Non-stored) computed lock to date fields; c.f. res.company
fiscalyear_lock_to_date = fields.Date(
string="Global Lock To Date",
compute="_compute_lock_dates",
search="_search_fiscalyear_lock_to_date",
help="The date the Global Lock To Date is set to by this exception. "
"If the lock to date is not changed it is set to False.",
)
sale_lock_to_date = fields.Date(
string="Sales Lock To Date",
compute="_compute_lock_dates",
search="_search_sale_lock_to_date",
help="The date the Sale Lock To Date is set to by this exception. "
"If the lock to date is not changed it is set to False.",
)
purchase_lock_to_date = fields.Date(
compute="_compute_lock_dates",
search="_search_purchase_lock_to_date",
help="The date the Purchase Lock To Date is set to by this exception. "
"If the lock to date is not changed it is set to False.",
)
@api.depends("lock_date_field", "lock_date")
def _compute_lock_dates(self):
res = super()._compute_lock_dates()
for exception in self:
for field in SOFT_LOCK_TO_DATE_FIELDS:
if field == exception.lock_date_field:
exception[field] = exception.lock_date
else:
exception[field] = False
return res
def _search_lock_to_date(self, field, operator, value):
if operator not in [">", ">="] or not value:
raise UserError(_("Operation not supported"))
return [
"&",
("lock_date_field", "=", field),
"|",
("lock_date", "=", False),
("lock_date", operator, value),
]
def _search_fiscalyear_lock_to_date(self, operator, value):
return self._search_lock_to_date("fiscalyear_lock_to_date", operator, value)
def _search_sale_lock_to_date(self, operator, value):
return self._search_lock_to_date("sale_lock_to_date", operator, value)
def _search_purchase_lock_to_date(self, operator, value):
return self._search_lock_to_date("purchase_lock_to_date", operator, value)
@api.model
def _get_active_exceptions_to_domain(self, company, soft_lock_to_date_fields):
return [
*expression.OR(
[(field, ">", company[field])]
for field in soft_lock_to_date_fields
if company[field]
),
("company_id", "=", company.id),
("state", "=", "active"), # checks the datetime
]

View File

@@ -0,0 +1,46 @@
# Copyright 2019 ForgeFlow S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import _, models
from odoo.exceptions import ValidationError
from odoo.addons.account.models.account_move import BYPASS_LOCK_CHECK
class AccountMove(models.Model):
_inherit = "account.move"
def _check_lock_to_dates(self):
if self.env.context.get("bypass_lock_check") is BYPASS_LOCK_CHECK:
return
for move in self:
journal = move.journal_id
violated_lock_to_dates = move.company_id._get_lock_to_date_violations(
move.date,
fiscalyear=True,
sale=journal and journal.type == "sale",
purchase=journal and journal.type == "purchase",
hard=True,
)
if violated_lock_to_dates:
message = _(
"You cannot add/modify entries posterior to "
"and inclusive of: %(lock_date_info)s.",
lock_date_info=self.env["res.company"]._format_lock_dates(
violated_lock_to_dates
),
)
raise ValidationError(message)
return True
def action_post(self):
self._check_lock_to_dates()
return super().action_post()
def button_cancel(self):
self._check_lock_to_dates()
return super().button_cancel()
def button_draft(self):
self._check_lock_to_dates()
return super().button_draft()

View File

@@ -0,0 +1,264 @@
# Copyright 2019 ForgeFlow S.L.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
SOFT_LOCK_TO_DATE_FIELDS = [
"fiscalyear_lock_to_date",
"sale_lock_to_date",
"purchase_lock_to_date",
]
LOCK_TO_DATE_FIELDS = [
*SOFT_LOCK_TO_DATE_FIELDS,
"hard_lock_to_date",
]
class ResCompany(models.Model):
_inherit = "res.company"
sale_lock_to_date = fields.Date(
string="Sales Lock To Date",
tracking=True,
help="Prevents creation and modification of entries in sales journals"
" posterior to the defined date inclusive.",
)
purchase_lock_to_date = fields.Date(
tracking=True,
help="Prevents creation and modification of entries in purchase journals"
" posterior to the defined date inclusive.",
)
fiscalyear_lock_to_date = fields.Date(
string="Global Lock To Date",
tracking=True,
help="No users can edit accounts posterior to this date."
" Use it for fiscal year locking for example.",
)
hard_lock_to_date = fields.Date(
tracking=True,
help='Like the "Global Lock Date", but no exceptions are possible.',
)
user_fiscalyear_lock_to_date = fields.Date(
compute="_compute_user_fiscalyear_lock_to_date"
)
user_sale_lock_to_date = fields.Date(compute="_compute_user_sale_lock_to_date")
user_purchase_lock_to_date = fields.Date(
compute="_compute_user_purchase_lock_to_date"
)
user_hard_lock_to_date = fields.Date(compute="_compute_user_hard_lock_to_date")
@api.depends("fiscalyear_lock_to_date")
@api.depends_context("uid", "ignore_exceptions")
def _compute_user_fiscalyear_lock_to_date(self):
ignore_exceptions = bool(self.env.context.get("ignore_exceptions", False))
for company in self:
company.user_fiscalyear_lock_to_date = company._get_user_lock_to_date(
"fiscalyear_lock_to_date", ignore_exceptions
)
@api.depends("sale_lock_to_date")
@api.depends_context("uid", "ignore_exceptions")
def _compute_user_sale_lock_to_date(self):
ignore_exceptions = bool(self.env.context.get("ignore_exceptions", False))
for company in self:
company.user_sale_lock_to_date = company._get_user_lock_to_date(
"sale_lock_to_date", ignore_exceptions
)
@api.depends("purchase_lock_to_date")
@api.depends_context("uid", "ignore_exceptions")
def _compute_user_purchase_lock_to_date(self):
ignore_exceptions = bool(self.env.context.get("ignore_exceptions", False))
for company in self:
company.user_purchase_lock_to_date = company._get_user_lock_to_date(
"purchase_lock_to_date", ignore_exceptions
)
@api.depends("hard_lock_to_date")
def _compute_user_hard_lock_to_date(self):
for company in self:
company.user_hard_lock_to_date = (
min(
c.hard_lock_to_date
for c in company.with_context(active_test=False).sudo().parent_ids
if c.hard_lock_to_date
)
if any(
c.hard_lock_to_date
for c in company.with_context(active_test=False).sudo().parent_ids
)
else False
)
def _validate_locks(self, values):
res = super()._validate_locks(values)
if "hard_lock_to_date" in values:
hard_lock_to_date = fields.Date.to_date(values["hard_lock_to_date"])
for company in self:
if not company.hard_lock_to_date:
continue
if not hard_lock_to_date:
raise ValidationError(_("The Hard Lock Date cannot be removed."))
if hard_lock_to_date > company.hard_lock_to_date:
raise ValidationError(
_(
"A new Hard Lock To Date must be prior "
"(or equal) to the previous one."
)
)
nb_draft_entries = self.env["account.move"].search(
[
("company_id", "child_of", self.ids),
("state", "=", "draft"),
("date", ">=", hard_lock_to_date),
],
limit=1,
)
if nb_draft_entries:
raise ValidationError(
_(
"There are still unposted entries in the period to date"
" you want to hard lock. "
"You should either post or delete them."
)
)
self.env["res.company"].invalidate_model(
fnames=[f"user_{field}" for field in LOCK_TO_DATE_FIELDS if field in values]
)
return res
def _get_user_lock_to_date(self, soft_lock_to_date_field, ignore_exceptions=False):
self.ensure_one()
soft_lock_to_date = False
# We need to use sudo, since we might not have access to a parent company.
for company in self.sudo().parent_ids:
if company[soft_lock_to_date_field]:
if ignore_exceptions:
exception = None
else:
exception = self.env["account.lock_exception"].search(
[
("state", "=", "active"), # checks the datetime
"|",
("user_id", "=", None),
("user_id", "=", self.env.user.id),
(
soft_lock_to_date_field,
">",
company[soft_lock_to_date_field],
),
("company_id", "=", company.id),
],
order="lock_date asc NULLS FIRST",
limit=1,
)
if exception:
# The search domain of the exception ensures
# `exception[
# soft_lock_to_date_field] > company[
# soft_lock_to_date_field]`
# or `exception[soft_lock_to_date_field] is False`
soft_lock_to_date = (
min(soft_lock_to_date, exception[soft_lock_to_date_field])
if soft_lock_to_date and exception[soft_lock_to_date_field]
else soft_lock_to_date
or exception[soft_lock_to_date_field]
or False
)
else:
soft_lock_to_date = (
min(soft_lock_to_date, company[soft_lock_to_date_field])
if soft_lock_to_date and company[soft_lock_to_date_field]
else soft_lock_to_date
or company[soft_lock_to_date_field]
or False
)
return soft_lock_to_date
def _get_user_fiscal_lock_to_date(self, journal, ignore_exceptions=False):
self.ensure_one()
company = self.with_context(ignore_exceptions=ignore_exceptions)
lock = (
min(company.user_fiscalyear_lock_to_date, company.user_hard_lock_to_date)
if company.user_fiscalyear_lock_to_date and company.user_hard_lock_to_date
else company.user_fiscalyear_lock_to_date
or company.user_hard_lock_to_date
or False
)
if journal.type == "sale":
lock = (
min(company.user_sale_lock_to_date, lock)
if company.user_sale_lock_to_date and lock
else company.user_sale_lock_to_date or lock or False
)
elif journal.type == "purchase":
lock = (
min(company.user_purchase_lock_to_date, lock)
if company.user_purchase_lock_to_date and lock
else company.user_purchase_lock_to_date or lock or False
)
return lock
def _get_violated_soft_lock_to_date(self, soft_lock_to_date_field, date):
violated_date = None
if not self:
return violated_date
self.ensure_one()
user_lock_to_date_field = f"user_{soft_lock_to_date_field}"
regular_lock_to_date = self.with_context(ignore_exceptions=True)[
user_lock_to_date_field
]
if regular_lock_to_date and date >= regular_lock_to_date:
user_lock_to_date = self.with_context(ignore_exceptions=False)[
user_lock_to_date_field
]
violated_date = (
None
if regular_lock_to_date and date < user_lock_to_date
else user_lock_to_date
)
return violated_date
def _get_lock_to_date_violations(
self, accounting_date, fiscalyear=True, sale=True, purchase=True, hard=True
):
self.ensure_one()
locks = []
if not accounting_date:
return locks
soft_lock_to_date_fields_to_check = [
# (field, "to check")
("fiscalyear_lock_to_date", fiscalyear),
("sale_lock_to_date", sale),
("purchase_lock_to_date", purchase),
]
for field, to_check in soft_lock_to_date_fields_to_check:
if not to_check:
continue
violated_date = self._get_violated_soft_lock_to_date(field, accounting_date)
if violated_date:
locks.append((violated_date, field))
if hard:
hard_lock_date = self.user_hard_lock_to_date
if hard_lock_date and accounting_date >= hard_lock_date:
locks.append((hard_lock_date, "hard_lock_date"))
return locks
def write(self, values):
companies = super().write(values)
# We revoke all active exceptions affecting the changed lock to dates
# and recreate them (with the updated lock to dates)
changed_soft_lock_fields = [
field for field in SOFT_LOCK_TO_DATE_FIELDS if field in values
]
for company in self:
active_exceptions = self.env["account.lock_exception"].search(
self.env["account.lock_exception"]._get_active_exceptions_to_domain(
company, changed_soft_lock_fields
),
)
active_exceptions._recreate()
return companies

View File

@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"

View File

@@ -0,0 +1,5 @@
- ForgeFlow \<https://www.ForgeFlow.com\>
\*\* Jordi Ballester Alomar \<jordi.ballester@ForgeFlow.com\>
- [Aion Tech](https://aiontech.company/):
- Simone Rubino \<simone.rubino@aion-tech.it\>

View File

@@ -0,0 +1,3 @@
This module allows to set a Period and Fiscal year Locking end dates.
This will prevent users from posting journal entries on a date after the
defined period or fiscal year end date.

View File

@@ -0,0 +1,9 @@
To set a new lock to dates, go to *Invoicing / Accounting / Actions /
Update accounting lock to dates*.
A user without an Adviser group will not be able to post or update
posted journal entries on the date "Lock To Date for Non-Advisers" or
after.
A user that has an Adviser group will not be able to post or update
posted journal entries on the date "Lock To Date" or after.

View File

@@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_account_update_lock_to_date,Full access on account.update.lock_to_date,model_account_update_lock_to_date,account.group_account_invoice,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_account_update_lock_to_date Full access on account.update.lock_to_date model_account_update_lock_to_date account.group_account_invoice 1 1 1 1

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -0,0 +1,452 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>README.rst</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic, pre.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document">
<a class="reference external image-reference" href="https://odoo-community.org/get-involved?utm_source=readme">
<img alt="Odoo Community Association" src="https://odoo-community.org/readme-banner-image" />
</a>
<div class="section" id="account-lock-to-date">
<h1>Account Lock To Date</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:76e4e73f76858c9c58ca4873e595b81fdfd386e0606f51bf4a57bf3284522770
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/account-financial-tools/tree/18.0/account_lock_to_date"><img alt="OCA/account-financial-tools" src="https://img.shields.io/badge/github-OCA%2Faccount--financial--tools-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/account-financial-tools-18-0/account-financial-tools-18-0-account_lock_to_date"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/account-financial-tools&amp;target_branch=18.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This module allows to set a Period and Fiscal year Locking end dates.
This will prevent users from posting journal entries on a date after the
defined period or fiscal year end date.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#usage" id="toc-entry-1">Usage</a></li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-2">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-3">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-4">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-5">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-6">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="usage">
<h2><a class="toc-backref" href="#toc-entry-1">Usage</a></h2>
<p>To set a new lock to dates, go to <em>Invoicing / Accounting / Actions /
Update accounting lock to dates</em>.</p>
<p>A user without an Adviser group will not be able to post or update
posted journal entries on the date “Lock To Date for Non-Advisers” or
after.</p>
<p>A user that has an Adviser group will not be able to post or update
posted journal entries on the date “Lock To Date” or after.</p>
</div>
<div class="section" id="bug-tracker">
<h2><a class="toc-backref" href="#toc-entry-2">Bug Tracker</a></h2>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/account-financial-tools/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/account-financial-tools/issues/new?body=module:%20account_lock_to_date%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h2><a class="toc-backref" href="#toc-entry-3">Credits</a></h2>
<div class="section" id="authors">
<h3><a class="toc-backref" href="#toc-entry-4">Authors</a></h3>
<ul class="simple">
<li>ForgeFlow</li>
</ul>
</div>
<div class="section" id="contributors">
<h3><a class="toc-backref" href="#toc-entry-5">Contributors</a></h3>
<ul>
<li><div class="first line-block">
<div class="line">ForgeFlow
&lt;<a class="reference external" href="https://www.ForgeFlow.com&gt;">https://www.ForgeFlow.com\&gt;</a></div>
<div class="line">** Jordi Ballester Alomar &lt;<a class="reference external" href="mailto:jordi.ballester&#64;ForgeFlow.com">jordi.ballester&#64;ForgeFlow.com</a>&gt;</div>
</div>
</li>
<li><p class="first"><a class="reference external" href="https://aiontech.company/">Aion Tech</a>:</p>
<ul class="simple">
<li>Simone Rubino &lt;<a class="reference external" href="mailto:simone.rubino&#64;aion-tech.it">simone.rubino&#64;aion-tech.it</a>&gt;</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="maintainers">
<h3><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h3>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
</a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/account-financial-tools/tree/18.0/account_lock_to_date">OCA/account-financial-tools</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1 @@
from . import test_account_lock_to_date_update

View File

@@ -0,0 +1,181 @@
# Copyright 2019 ForgeFlow S.L.
# Copyright 2023 Simone Rubino - Aion Tech
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from datetime import datetime
from odoo.exceptions import ValidationError
from odoo.tests.common import TransactionCase
from odoo.tools.misc import DEFAULT_SERVER_DATE_FORMAT
class TestAccountLockToDateUpdate(TransactionCase):
def setUp(self):
super().setUp()
self.company = self.env.ref("base.main_company")
self.demo_user = self.env.ref("base.user_demo")
self.invoicing_group = self.env.ref("account.group_account_user")
self.adviser_group = self.env.ref("account.group_account_manager")
self.UpdateLockToDateUpdateObj = self.env[
"account.update.lock_to_date"
].with_user(self.demo_user)
self.AccountObj = self.env["account.account"]
self.AccountJournalObj = self.env["account.journal"]
self.AccountMoveObj = self.env["account.move"]
self.demo_user.write({"groups_id": [(4, self.invoicing_group.id)]})
self.bank_journal = self.AccountJournalObj.create(
{
"name": "Bank Journal - BJ",
"code": "BJ",
"type": "bank",
"company_id": self.company.id,
}
)
self.sale_journal = self.AccountJournalObj.create(
{
"name": "Sale Journal - SJ",
"code": "SJ",
"type": "sale",
"company_id": self.company.id,
}
)
self.purchase_journal = self.AccountJournalObj.create(
{
"name": "Purchase Journal - PJ",
"code": "PJ",
"type": "purchase",
"company_id": self.company.id,
}
)
self.account_type_recv = "asset_receivable"
self.account_type_rev = "income"
self.account_recv = self.AccountObj.create(
{
"code": "RECVDR",
"name": "Receivable (test)",
"reconcile": True,
"account_type": self.account_type_recv,
}
)
self.account_sale = self.AccountObj.create(
{
"code": "SALEDR",
"name": "Receivable (sale)",
"reconcile": True,
"account_type": self.account_type_rev,
}
)
def create_account_move(self, date_str, journal):
return self.AccountMoveObj.create(
{
"journal_id": journal.id,
"date": date_str,
"line_ids": [
(
0,
0,
{
"name": "Debit",
"debit": 1000,
"account_id": self.account_recv.id,
},
),
(
0,
0,
{
"name": "Credit",
"credit": 1000,
"account_id": self.account_sale.id,
},
),
],
}
)
def create_account_lock_date_update(self):
return self.UpdateLockToDateUpdateObj.create({"company_id": self.company.id})
def test_01_update_without_access(self):
wizard = self.create_account_lock_date_update()
wizard.write(
{
"sale_lock_to_date": "2900-01-01",
"purchase_lock_to_date": "2900-01-01",
"fiscalyear_lock_to_date": "2900-01-01",
"hard_lock_to_date": "2900-01-01",
}
)
self.demo_user.write({"groups_id": [(3, self.adviser_group.id)]})
with self.assertRaises(ValidationError):
wizard.with_user(self.demo_user.id).execute()
def test_02_update_with_access(self):
wizard = self.create_account_lock_date_update()
wizard.write(
{
"sale_lock_to_date": "2900-01-01",
"purchase_lock_to_date": "2900-01-01",
"fiscalyear_lock_to_date": "2900-02-01",
"hard_lock_to_date": "2900-02-01",
}
)
self.demo_user.write({"groups_id": [(4, self.adviser_group.id)]})
wizard.with_user(self.demo_user.id).execute()
self.assertEqual(
self.company.sale_lock_to_date,
datetime.strptime("2900-01-01", DEFAULT_SERVER_DATE_FORMAT).date(),
)
self.assertEqual(
self.company.purchase_lock_to_date,
datetime.strptime("2900-01-01", DEFAULT_SERVER_DATE_FORMAT).date(),
)
self.assertEqual(
self.company.fiscalyear_lock_to_date,
datetime.strptime("2900-02-01", DEFAULT_SERVER_DATE_FORMAT).date(),
)
self.assertEqual(
self.company.hard_lock_to_date,
datetime.strptime("2900-02-01", DEFAULT_SERVER_DATE_FORMAT).date(),
)
def test_03_create_purchase_move_outside_period(self):
"""We test that we cannot create journal entries after the
locked date"""
self.company.purchase_lock_to_date = "2900-01-01"
self.company.fiscalyear_lock_to_date = "2900-02-01"
move = self.create_account_move("2900-01-01", self.purchase_journal)
with self.assertRaises(ValidationError):
move.with_user(self.demo_user.id).action_post()
def test_04_create_sale_move_outside_period(self):
"""We test that we cannot create journal entries after the
locked date"""
self.company.sale_lock_to_date = "2900-01-01"
self.company.fiscalyear_lock_to_date = "2900-02-01"
move = self.create_account_move("2900-01-01", self.sale_journal)
with self.assertRaises(ValidationError):
move.with_user(self.demo_user.id).action_post()
def test_05_create_move_inside_period(self):
"""We test that we can successfully create a journal entry
within period that is not locked"""
self.company.sale_lock_to_date = "2900-01-01"
self.company.purchase_lock_to_date = "2900-01-01"
self.company.fiscalyear_lock_to_date = "2900-02-01"
self.company.hard_lock_to_date = "2900-02-01"
move = self.create_account_move("2800-01-01", self.bank_journal)
move.with_user(self.demo_user.id).action_post()
self.assertEqual(move.state, "posted")
def test_06_lock_period_with_draft_moves(self):
"""We test that we cannot change the hard lock to date
if there are draft journal entries after that date."""
self.create_account_move("2900-02-01", self.bank_journal)
with self.assertRaises(ValidationError):
self.company.sale_lock_to_date = "2900-01-01"
self.company.purchase_lock_to_date = "2900-01-01"
self.company.fiscalyear_lock_to_date = "2900-02-01"
self.company.hard_lock_to_date = "2900-02-01"

View File

@@ -0,0 +1 @@
from . import account_update_lock_to_date

View File

@@ -0,0 +1,68 @@
# Copyright 2019 ForgeFlow S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import SUPERUSER_ID, _, api, fields, models
from odoo.exceptions import ValidationError
class AccountUpdateLockToDate(models.TransientModel):
_name = "account.update.lock_to_date"
_description = "Account Update Lock_to_date"
company_id = fields.Many2one(
comodel_name="res.company",
string="Company",
required=True,
default=lambda self: self.env.user.company_id,
)
sale_lock_to_date = fields.Date(
string="Sales Lock To Date",
help="Prevents creation and modification of entries in sales journals"
" posterior to the defined date inclusive.",
)
purchase_lock_to_date = fields.Date(
help="Prevents creation and modification of entries in purchase journals"
" posterior to the defined date inclusive.",
)
fiscalyear_lock_to_date = fields.Date(
string="Global Lock To Date",
help="No users can edit accounts posterior to this date."
" Use it for fiscal year locking for example.",
)
hard_lock_to_date = fields.Date(
string="Lock To Date",
help='Like the "Global Lock Date", but no exceptions are possible.',
)
@api.model
def default_get(self, field_list):
res = super().default_get(field_list)
company = self.env.user.company_id
res.update(
{
"company_id": company.id,
"sale_lock_to_date": company.sale_lock_to_date,
"purchase_lock_to_date": company.purchase_lock_to_date,
"fiscalyear_lock_to_date": company.fiscalyear_lock_to_date,
"hard_lock_to_date": company.hard_lock_to_date,
}
)
return res
def _check_execute_allowed(self):
self.ensure_one()
has_adviser_group = self.env.user.has_group("account.group_account_manager")
if not (has_adviser_group or self.env.uid == SUPERUSER_ID):
raise ValidationError(_("You are not allowed to execute this action."))
def execute(self):
self.ensure_one()
self._check_execute_allowed()
self.company_id.sudo().write(
{
"sale_lock_to_date": self.sale_lock_to_date,
"purchase_lock_to_date": self.purchase_lock_to_date,
"fiscalyear_lock_to_date": self.fiscalyear_lock_to_date,
"hard_lock_to_date": self.hard_lock_to_date,
}
)

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- # Copyright 2019 ForgeFlow S.L.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).-->
<odoo>
<record model="ir.ui.view" id="account_update_lock_to_date_form_view">
<field name="name">account.update.lock_to_date.form</field>
<field name="model">account.update.lock_to_date</field>
<field name="arch" type="xml">
<form>
<header />
<sheet>
<group>
<field
name="company_id"
options="{'no_create': True}"
groups="base.group_multi_company"
/>
<field name="sale_lock_to_date" />
<field name="purchase_lock_to_date" />
<field name="fiscalyear_lock_to_date" />
<field name="hard_lock_to_date" />
</group>
</sheet>
<footer>
<button
string="Update"
name="execute"
type="object"
class="btn-primary"
/>
<button string="Cancel" class="btn-default" special="cancel" />
</footer>
</form>
</field>
</record>
<record model="ir.actions.act_window" id="account_update_lock_to_date_act_window">
<field name="name">Update accounting lock to dates</field>
<field name="res_model">account.update.lock_to_date</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<record model="ir.ui.menu" id="account_update_lock_to_date_menu">
<field name="name">Update accounting lock to dates</field>
<field name="parent_id" ref="account.menu_finance_entries" />
<field name="action" ref="account_update_lock_to_date_act_window" />
<field
name="groups_id"
eval="[(6, 0, [ref('account.group_account_manager')])]"
/>
<field name="sequence" eval="70" />
</record>
</odoo>