diff --git a/account_cutoff_accrual_subscription/README.rst b/account_cutoff_accrual_subscription/README.rst new file mode 100644 index 00000000000..28179920ce9 --- /dev/null +++ b/account_cutoff_accrual_subscription/README.rst @@ -0,0 +1,98 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + +============================= +Account Accrual Subscriptions +============================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:937b2a0def873fcf662f8b2c9a3d4366b78fc7236e68c37c74e991a8ee46f30e + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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--closing-lightgray.png?logo=github + :target: https://github.com/OCA/account-closing/tree/19.0/account_cutoff_accrual_subscription + :alt: OCA/account-closing +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/account-closing-19-0/account-closing-19-0-account_cutoff_accrual_subscription + :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-closing&target_branch=19.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allows you to easily compute accrued expenses (and accrued +revenues) by comparing expected expense amounts (configured as +*subscriptions*) with real expense amounts. + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +Go to the menu *Accounting > Configuration > Accounting > Subscriptions* +and create subscriptions: they are used as the expected expenses (or +revenue). For exemple, you may create a subscription for your office +rental, your Internet access, your insurance contracts, etc. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub 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 `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Akretion + +Contributors +------------ + +- Alexis de Lattre + +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. + +.. |maintainer-alexis-via| image:: https://github.com/alexis-via.png?size=40px + :target: https://github.com/alexis-via + :alt: alexis-via + +Current `maintainer `__: + +|maintainer-alexis-via| + +This module is part of the `OCA/account-closing `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/account_cutoff_accrual_subscription/__init__.py b/account_cutoff_accrual_subscription/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/account_cutoff_accrual_subscription/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/account_cutoff_accrual_subscription/__manifest__.py b/account_cutoff_accrual_subscription/__manifest__.py new file mode 100644 index 00000000000..2ac4bb72f50 --- /dev/null +++ b/account_cutoff_accrual_subscription/__manifest__.py @@ -0,0 +1,22 @@ +# Copyright 2019-2021 Akretion France (http://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Account Accrual Subscriptions", + "version": "19.0.1.0.0", + "category": "Accounting", + "license": "AGPL-3", + "summary": "Accrued expenses based on subscriptions", + "author": "Akretion,Odoo Community Association (OCA)", + "maintainers": ["alexis-via"], + "website": "https://github.com/OCA/account-closing", + "depends": ["account_cutoff_start_end_dates"], + "data": [ + "security/ir.model.access.csv", + "security/ir_rule.xml", + "views/account_cutoff_accrual_subscription.xml", + "views/account_cutoff_line.xml", + ], + "installable": True, +} diff --git a/account_cutoff_accrual_subscription/i18n/account_cutoff_accrual_subscription.pot b/account_cutoff_accrual_subscription/i18n/account_cutoff_accrual_subscription.pot new file mode 100644 index 00000000000..acba7d157be --- /dev/null +++ b/account_cutoff_accrual_subscription/i18n/account_cutoff_accrual_subscription.pot @@ -0,0 +1,320 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_cutoff_accrual_subscription +# +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_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +msgid "" +"%(start)s → %(end)s%(prorata)s: %(sub_type)s %(amount)s over min. amount ⇒ " +"no provisionning" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +msgid "" +"%(start)s → %(end)s%(prorata)s: %(sub_type)s %(amount)s under min. amount " +"⇒provisionning %(cutoff_amount)s" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +msgid "" +"

No provision for subscription %(name)s.

" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__account_id +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_search +msgid "Account" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model,name:account_cutoff_accrual_subscription.model_account_cutoff +msgid "Account Cut-off" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model,name:account_cutoff_accrual_subscription.model_account_cutoff_line +msgid "Account Cut-off Line" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__active +msgid "Active" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__analytic_distribution +msgid "Analytic Distribution" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__analytic_precision +msgid "Analytic Precision" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__partner_type__any +msgid "Any Partner" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_form +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_search +msgid "Archived" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +msgid "" +"CONFIG: %(periodicity)s periodicity, start date %(start_date)s, min. expense" +" amount %(min_amount)s, default provision amount %(provision_amount)s" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__company_id +msgid "Company" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__company_currency_id +msgid "Company Currency" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +msgid "Computing cut-offs from %d subscriptions." +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__create_uid +msgid "Created by" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__create_date +msgid "Created on" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__provision_amount +msgid "Default Provision Amount" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__display_name +msgid "Display Name" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__distribution_analytic_account_ids +msgid "Distribution Analytic Account" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__subscription_type__expense +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_search +msgid "Expense" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__id +msgid "ID" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__write_date +msgid "Last Updated on" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__min_amount +msgid "Minimum Amount" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,help:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__min_amount +msgid "Minimum amount without taxes over the period" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff_accrual_subscription.py:0 +msgid "Missing partner on subscription '%s'." +msgstr "" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +msgid "Missing source journals." +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__periodicity__month +msgid "Monthly" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__name +msgid "Name" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__partner_type__none +msgid "No Partner" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +msgid "Odoo cannot compute the fiscal year start date." +msgstr "" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff_accrual_subscription.py:0 +msgid "On subscription %s, the start date is not the first day of a month." +msgstr "" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +msgid "PERIODS:" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +msgid "" +"PRORATED min. amount %(min_amount)s, default provisionning amount " +"%(provision_amount)s" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__partner_id +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_search +msgid "Partner" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__partner_type +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_search +msgid "Partner Type" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__periodicity +msgid "Periodicity" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__periodicity__quarter +msgid "Quarterly" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__subscription_type__revenue +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_search +msgid "Revenue" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__periodicity__semester +msgid "Semesterly" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__partner_type__one +msgid "Specific Partner" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__start_date +msgid "Start Date" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_line__subscription_id +msgid "Subscription" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_form +msgid "Subscription Name" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.actions.act_window,name:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_action +#: model:ir.ui.menu,name:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_menu +msgid "Subscriptions" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model,name:account_cutoff_accrual_subscription.model_account_cutoff_accrual_subscription +msgid "Subscriptions to compute accrual cutoffs" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__tax_ids +msgid "Taxes" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +msgid "" +"The cutoffs with subscription only work when the cutoff date (%s) is the " +"last day of a month." +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.constraint,message:account_cutoff_accrual_subscription.constraint_account_cutoff_accrual_subscription_provision_amount_positive +msgid "The default provision amount must be positive." +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.constraint,message:account_cutoff_accrual_subscription.constraint_account_cutoff_accrual_subscription_min_amount_positive +msgid "The minimum amount must be positive." +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__subscription_type +msgid "Type" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__type_tax_use +msgid "Type Tax Use" +msgstr "" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__periodicity__year +msgid "Yearly" +msgstr "" diff --git a/account_cutoff_accrual_subscription/i18n/es.po b/account_cutoff_accrual_subscription/i18n/es.po new file mode 100644 index 00000000000..8612e18df06 --- /dev/null +++ b/account_cutoff_accrual_subscription/i18n/es.po @@ -0,0 +1,361 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_cutoff_accrual_subscription +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-04-24 11:37+0000\n" +"Last-Translator: Ivorra78 \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_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "" +"%(start)s → %(end)s%(prorata)s: %(sub_type)s %(amount)s over min. amount ⇒ " +"no provisionning" +msgstr "" +"%(start)s → %(end)s%(prorata)s: %(sub_type)s %(amount)s por encima del " +"importe mínimo ⇒ sin provisión" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "" +"%(start)s → %(end)s%(prorata)s: %(sub_type)s %(amount)s under min. amount " +"⇒provisionning %(cutoff_amount)s" +msgstr "" +"%(start)s → %(end)s%(prorata)s: %(sub_type)s %(amount)s bajo importe mín. " +"⇒provisión %(cutoff_amount)s" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "" +"

No provision for subscription %(name)s:

" +msgstr "" +"

No hay provisión para la suscripción %(name)s:

" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__account_id +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_search +msgid "Account" +msgstr "Cuenta" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model,name:account_cutoff_accrual_subscription.model_account_cutoff +msgid "Account Cut-off" +msgstr "Cierre de cuenta" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model,name:account_cutoff_accrual_subscription.model_account_cutoff_line +msgid "Account Cut-off Line" +msgstr "Línea de cierre de cuenta" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__active +msgid "Active" +msgstr "Activo" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__analytic_distribution +msgid "Analytic Distribution" +msgstr "Distribución Analítica" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__analytic_distribution_search +msgid "Analytic Distribution Search" +msgstr "búsqueda de distribución analítica" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__analytic_precision +msgid "Analytic Precision" +msgstr "Precisión analítica" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__partner_type__any +msgid "Any Partner" +msgstr "Cualquier socio" + +#. module: account_cutoff_accrual_subscription +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_form +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_search +msgid "Archived" +msgstr "Archivado" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "" +"CONFIG: %(periodicity)s periodicity, start date %(start_date)s, min. expense " +"amount %(min_amount)s, default provision amount %(provision_amount)s" +msgstr "" +"CONFIGURACIÓN:%(periodicity)s periodicidad, fecha de inicio%(start_date)s, " +"importe mínimo de gastos%(min_amount)s,importe de la provisión por defecto " +"%(provision_amount)s" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__company_id +msgid "Company" +msgstr "Compañía" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__company_currency_id +msgid "Company Currency" +msgstr "divisa de la compañía" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "Computing cut-offs from %d subscriptions." +msgstr "Cálculo de cierre a partir de %d suscripciones." + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__create_date +msgid "Created on" +msgstr "Creado en" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__provision_amount +msgid "Default Provision Amount" +msgstr "Importe de la provisión por defecto" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__display_name +msgid "Display Name" +msgstr "Nombre para mostrar" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__subscription_type__expense +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_search +#, python-format +msgid "Expense" +msgstr "gasto" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__id +msgid "ID" +msgstr "Identidad" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__write_uid +msgid "Last Updated by" +msgstr "Actualizado por última vez por" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__write_date +msgid "Last Updated on" +msgstr "actualizado por última vez el" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__min_amount +msgid "Minimum Amount" +msgstr "importe mínimo" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,help:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__min_amount +msgid "Minimum amount without taxes over the period" +msgstr "Importe mínimo sin impuestos durante el periodo" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff_accrual_subscription.py:0 +#, python-format +msgid "Missing partner on subscription '%s'." +msgstr "Falta socio en la suscripción '%s'." + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "Missing source journals." +msgstr "diarios de origen perdidos." + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__periodicity__month +msgid "Monthly" +msgstr "mensualmente" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__name +msgid "Name" +msgstr "nombre" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__partner_type__none +msgid "No Partner" +msgstr "no socio" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "Odoo cannot compute the fiscal year start date." +msgstr "Odoo no puede calcular la fecha de inicio del año fiscal." + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff_accrual_subscription.py:0 +#, python-format +msgid "On subscription %s, the start date is not the first day of a month." +msgstr "en la suscripción %s, la fecha de inicio no es el primer dia del mes." + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "PERIODS:" +msgstr "PERIODOS:" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "" +"PRORATED min. amount %(min_amount)s, default provisionning amount " +"%(provision_amount)s" +msgstr "" +"Importe mínimo PRORRATEADO%(min_amount)s, importe de la provisión por defecto" +"%(provision_amount)s" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__partner_id +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_search +msgid "Partner" +msgstr "Socio" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__partner_type +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_search +msgid "Partner Type" +msgstr "Tipo de socio" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__periodicity +msgid "Periodicity" +msgstr "Periodicidad" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__periodicity__quarter +msgid "Quarterly" +msgstr "trimestral" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__subscription_type__revenue +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_search +#, python-format +msgid "Revenue" +msgstr "ingresos" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__periodicity__semester +msgid "Semesterly" +msgstr "semestralmente" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__partner_type__one +msgid "Specific Partner" +msgstr "socio específico" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__start_date +msgid "Start Date" +msgstr "fecha de inicio" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_line__subscription_id +msgid "Subscription" +msgstr "suscripción" + +#. module: account_cutoff_accrual_subscription +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_form +msgid "Subscription Name" +msgstr "Nombre de suscripción" + +#. module: account_cutoff_accrual_subscription +#: model:ir.actions.act_window,name:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_action +#: model:ir.ui.menu,name:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_menu +msgid "Subscriptions" +msgstr "suscripciones" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model,name:account_cutoff_accrual_subscription.model_account_cutoff_accrual_subscription +msgid "Subscriptions to compute accrual cutoffs" +msgstr "Abonos para calcular los límites de devengo" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__tax_ids +msgid "Taxes" +msgstr "Impuestos" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "" +"The cutoffs with subscription only work when the cutoff date (%s) is the " +"last day of a month." +msgstr "" +"Los cierres con suscripción sólo funcionan cuando la fecha de cierre (%s) es " +"el último día de un mes." + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.constraint,message:account_cutoff_accrual_subscription.constraint_account_cutoff_accrual_subscription_provision_amount_positive +msgid "The default provision amount must be positive." +msgstr "El importe de la provisión por defecto debe ser positivo." + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.constraint,message:account_cutoff_accrual_subscription.constraint_account_cutoff_accrual_subscription_min_amount_positive +msgid "The minimum amount must be positive." +msgstr "El importe mínimo debe ser positivo." + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__subscription_type +msgid "Type" +msgstr "tipo" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__type_tax_use +msgid "Type Tax Use" +msgstr "tipo impuesto utilizado" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__periodicity__year +msgid "Yearly" +msgstr "anualmente" + +#~ msgid "Analytic" +#~ msgstr "Analítico" + +#~ msgid "Last Modified on" +#~ msgstr "modificado por última vez el" + +#~ msgid "Minimum Expense Amount" +#~ msgstr "Importe mínimo de gastos" + +#~ msgid "Minimum expense amount without taxes over the period" +#~ msgstr "Importe mínimo de gastos sin impuestos durante el periodo" diff --git a/account_cutoff_accrual_subscription/i18n/fr.po b/account_cutoff_accrual_subscription/i18n/fr.po new file mode 100644 index 00000000000..bf963ba7d78 --- /dev/null +++ b/account_cutoff_accrual_subscription/i18n/fr.po @@ -0,0 +1,366 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_cutoff_accrual_subscription +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2025-10-05 09:42+0000\n" +"Last-Translator: Rémi \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 5.10.4\n" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "" +"%(start)s → %(end)s%(prorata)s: %(sub_type)s %(amount)s over min. amount ⇒ " +"no provisionning" +msgstr "" +"%(start)s → %(end)s%(prorata)s : %(sub_type)s %(amount)s supérieur au " +"montant minimum ⇒ pas de provision" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "" +"%(start)s → %(end)s%(prorata)s: %(sub_type)s %(amount)s under min. amount " +"⇒provisionning %(cutoff_amount)s" +msgstr "" +"%(start)s → %(end)s%(prorata)s : %(sub_type)s %(amount)s inférieur au " +"montant minimum ⇒provision de %(cutoff_amount)s" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "" +"

No provision for subscription %(name)s:

" +msgstr "" +"

Pas de provision pour l'abonnement %(name)s :

" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__account_id +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_search +msgid "Account" +msgstr "Compte" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model,name:account_cutoff_accrual_subscription.model_account_cutoff +msgid "Account Cut-off" +msgstr "Provision comptable" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model,name:account_cutoff_accrual_subscription.model_account_cutoff_line +msgid "Account Cut-off Line" +msgstr "Ligne de provision" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__active +msgid "Active" +msgstr "Actif" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__analytic_distribution +msgid "Analytic Distribution" +msgstr "Distribution analytique" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__analytic_distribution_search +msgid "Analytic Distribution Search" +msgstr "Recherche de distribution analytique" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__analytic_precision +msgid "Analytic Precision" +msgstr "Précision analytique" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__partner_type__any +msgid "Any Partner" +msgstr "N'importe quel partenaire" + +#. module: account_cutoff_accrual_subscription +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_form +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_search +msgid "Archived" +msgstr "Archivé" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "" +"CONFIG: %(periodicity)s periodicity, start date %(start_date)s, min. expense " +"amount %(min_amount)s, default provision amount %(provision_amount)s" +msgstr "" +"CONFIGURATION : périodicité %(periodicity)s, date de début %(start_date)s, " +"montant minimum de charge %(min_amount)s, montant à provisionner par défaut " +"%(provision_amount)s" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__company_id +msgid "Company" +msgstr "Société" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__company_currency_id +msgid "Company Currency" +msgstr "Devise de la société" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "Computing cut-offs from %d subscriptions." +msgstr "Calcul des provisions à partir de %d abonnements." + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__create_uid +msgid "Created by" +msgstr "Créé par" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__create_date +msgid "Created on" +msgstr "Créé le" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__provision_amount +msgid "Default Provision Amount" +msgstr "Montant à provisionner par défaut" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__display_name +msgid "Display Name" +msgstr "Nom affiché" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__subscription_type__expense +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_search +#, python-format +msgid "Expense" +msgstr "Charges" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__id +msgid "ID" +msgstr "ID" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__write_uid +msgid "Last Updated by" +msgstr "Dernière mise à jour par" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__write_date +msgid "Last Updated on" +msgstr "Dernière mise à jour le" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__min_amount +msgid "Minimum Amount" +msgstr "Montant minimal" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,help:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__min_amount +msgid "Minimum amount without taxes over the period" +msgstr "Montant minimal HT sur la période" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff_accrual_subscription.py:0 +#, python-format +msgid "Missing partner on subscription '%s'." +msgstr "Partenaire manquant sur l'abonnement '%s'." + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "Missing source journals." +msgstr "Journaux sources manquants." + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__periodicity__month +msgid "Monthly" +msgstr "Mensuel" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__name +msgid "Name" +msgstr "Nom" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__partner_type__none +msgid "No Partner" +msgstr "Pas de partenaire" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "Odoo cannot compute the fiscal year start date." +msgstr "Odoo ne peut pas déterminer la date de début de l'exercice comptable." + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff_accrual_subscription.py:0 +#, python-format +msgid "On subscription %s, the start date is not the first day of a month." +msgstr "" +"Sur l'abonnement %s, la date de début n'est pas le premier jour d'un mois." + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "PERIODS:" +msgstr "PÉRIODES :" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "" +"PRORATED min. amount %(min_amount)s, default provisionning amount " +"%(provision_amount)s" +msgstr "" +"Montant minimum proratisé %(min_amount)s, montant à provisionner par défaut " +"%(provision_amount)s" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__partner_id +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_search +msgid "Partner" +msgstr "Partenaire" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__partner_type +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_search +msgid "Partner Type" +msgstr "Type de partenaire" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__periodicity +msgid "Periodicity" +msgstr "Périodicité" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__periodicity__quarter +msgid "Quarterly" +msgstr "Trimestriel" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__subscription_type__revenue +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_search +#, python-format +msgid "Revenue" +msgstr "Produits" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__periodicity__semester +msgid "Semesterly" +msgstr "Semestriel" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__partner_type__one +msgid "Specific Partner" +msgstr "Partenaire spécifique" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__start_date +msgid "Start Date" +msgstr "Date de début" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_line__subscription_id +msgid "Subscription" +msgstr "Abonnement" + +#. module: account_cutoff_accrual_subscription +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_form +msgid "Subscription Name" +msgstr "Nom de l'abonnement" + +#. module: account_cutoff_accrual_subscription +#: model:ir.actions.act_window,name:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_action +#: model:ir.ui.menu,name:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_menu +msgid "Subscriptions" +msgstr "Abonnements" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model,name:account_cutoff_accrual_subscription.model_account_cutoff_accrual_subscription +msgid "Subscriptions to compute accrual cutoffs" +msgstr "Abonnements pour le calcul des charges à payer" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__tax_ids +msgid "Taxes" +msgstr "Taxes" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "" +"The cutoffs with subscription only work when the cutoff date (%s) is the " +"last day of a month." +msgstr "" +"Les provisions à partir des abonnements ne fonctionnent que lorsque la date " +"de provision (%s) est le dernier jour d'un mois." + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.constraint,message:account_cutoff_accrual_subscription.constraint_account_cutoff_accrual_subscription_provision_amount_positive +msgid "The default provision amount must be positive." +msgstr "Le montant à provisionner par défaut doit être positif." + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.constraint,message:account_cutoff_accrual_subscription.constraint_account_cutoff_accrual_subscription_min_amount_positive +msgid "The minimum amount must be positive." +msgstr "Le montant minimum doit être positif." + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__subscription_type +msgid "Type" +msgstr "Type" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__type_tax_use +msgid "Type Tax Use" +msgstr "Type d'utilisation de la taxe" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__periodicity__year +msgid "Yearly" +msgstr "Annuel" + +#~ msgid "Analytic" +#~ msgstr "Analytique" + +#~ msgid "Last Modified on" +#~ msgstr "Dernière modification le" + +#~ msgid "Minimum Expense Amount" +#~ msgstr "Montant minimum de charge" + +#~ msgid "Minimum expense amount without taxes over the period" +#~ msgstr "Montant minimum de charge HT sur la période" + +#, python-format +#~ msgid "Computing provisions from %d subscriptions." +#~ msgstr "Calcul des provisions à partir de %d abonnements." diff --git a/account_cutoff_accrual_subscription/i18n/it.po b/account_cutoff_accrual_subscription/i18n/it.po new file mode 100644 index 00000000000..0809926700a --- /dev/null +++ b/account_cutoff_accrual_subscription/i18n/it.po @@ -0,0 +1,350 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_cutoff_accrual_subscription +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-10-21 13:06+0000\n" +"Last-Translator: mymage \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_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "" +"%(start)s → %(end)s%(prorata)s: %(sub_type)s %(amount)s over min. amount ⇒ " +"no provisionning" +msgstr "" +"%(start)s → %(end)s%(prorata)s: %(sub_type)s %(amount)s oltre valore minimo ⇒" +" nessun approvvigionamento" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "" +"%(start)s → %(end)s%(prorata)s: %(sub_type)s %(amount)s under min. amount " +"⇒provisionning %(cutoff_amount)s" +msgstr "" +"%(start)s → %(end)s%(prorata)s: %(sub_type)s %(amount)s inferiore al valore " +"minimo ⇒ approvvigionamento %(cutoff_amount)s" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "" +"

No provision for subscription %(name)s:

" +msgstr "" +"

Nessuna fornitura per l'iscrizione %(name)s:

" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__account_id +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_search +msgid "Account" +msgstr "Conto" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model,name:account_cutoff_accrual_subscription.model_account_cutoff +msgid "Account Cut-off" +msgstr "Ripartizioni di fine esercizio" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model,name:account_cutoff_accrual_subscription.model_account_cutoff_line +msgid "Account Cut-off Line" +msgstr "Riga scritture fine periodo" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__active +msgid "Active" +msgstr "Attiva" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__analytic_distribution +msgid "Analytic Distribution" +msgstr "Distribuzione analitica" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__analytic_distribution_search +msgid "Analytic Distribution Search" +msgstr "Ricerca distribuzione analitica" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__analytic_precision +msgid "Analytic Precision" +msgstr "Precisione analitica" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__partner_type__any +msgid "Any Partner" +msgstr "Qualsiasi partner" + +#. module: account_cutoff_accrual_subscription +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_form +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_search +msgid "Archived" +msgstr "In archivio" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "" +"CONFIG: %(periodicity)s periodicity, start date %(start_date)s, min. expense" +" amount %(min_amount)s, default provision amount %(provision_amount)s" +msgstr "" +"CONFIGURAZIONE: periodicità %(periodicity)s, data inizio %(start_date)s, " +"valore minimo spesa %(min_amount)s, valore predefinito fornitura " +"%(provision_amount)s" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__company_id +msgid "Company" +msgstr "Azienda" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__company_currency_id +msgid "Company Currency" +msgstr "Valuta azienda" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "Computing cut-offs from %d subscriptions." +msgstr "Calcolo cut-offs da %d iscrizioni." + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__create_uid +msgid "Created by" +msgstr "Creato da" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__create_date +msgid "Created on" +msgstr "Creato il" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__provision_amount +msgid "Default Provision Amount" +msgstr "Valore fornitura predefinito" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__display_name +msgid "Display Name" +msgstr "Nome visualizzato" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__subscription_type__expense +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_search +#, python-format +msgid "Expense" +msgstr "Spesa" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__id +msgid "ID" +msgstr "ID" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__write_uid +msgid "Last Updated by" +msgstr "Ultimo aggiornamento di" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__write_date +msgid "Last Updated on" +msgstr "Ultimo aggiornamento il" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__min_amount +msgid "Minimum Amount" +msgstr "Valore minimo" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,help:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__min_amount +msgid "Minimum amount without taxes over the period" +msgstr "Valore minimo senza imposte nel periodo" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff_accrual_subscription.py:0 +#, python-format +msgid "Missing partner on subscription '%s'." +msgstr "Partner assente nell'iscrizione '%s'." + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "Missing source journals." +msgstr "Registri origine mancanti." + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__periodicity__month +msgid "Monthly" +msgstr "Mensile" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__name +msgid "Name" +msgstr "Nome" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__partner_type__none +msgid "No Partner" +msgstr "Nessun partner" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "Odoo cannot compute the fiscal year start date." +msgstr "Odoo non può calcolare la data iniziale dell'anno fiscale." + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff_accrual_subscription.py:0 +#, python-format +msgid "On subscription %s, the start date is not the first day of a month." +msgstr "Nell'iscrizione %s, la data inizio non è il primo giorno del mese." + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "PERIODS:" +msgstr "PERIODI:" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "" +"PRORATED min. amount %(min_amount)s, default provisionning amount " +"%(provision_amount)s" +msgstr "" +"Valore minimo ripartizione %(min_amount)s, valore predefinito fornitura " +"%(provision_amount)s" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__partner_id +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_search +msgid "Partner" +msgstr "Partner" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__partner_type +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_search +msgid "Partner Type" +msgstr "Tipo partner" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__periodicity +msgid "Periodicity" +msgstr "Periodicità" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__periodicity__quarter +msgid "Quarterly" +msgstr "Trimestrale" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__subscription_type__revenue +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_search +#, python-format +msgid "Revenue" +msgstr "Ricavi" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__periodicity__semester +msgid "Semesterly" +msgstr "Semestrale" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__partner_type__one +msgid "Specific Partner" +msgstr "Partner specifico" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__start_date +msgid "Start Date" +msgstr "Data inizio" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_line__subscription_id +msgid "Subscription" +msgstr "Iscrizione" + +#. module: account_cutoff_accrual_subscription +#: model_terms:ir.ui.view,arch_db:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_form +msgid "Subscription Name" +msgstr "Nome iscrizione" + +#. module: account_cutoff_accrual_subscription +#: model:ir.actions.act_window,name:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_action +#: model:ir.ui.menu,name:account_cutoff_accrual_subscription.account_cutoff_accrual_subscription_menu +msgid "Subscriptions" +msgstr "Iscrizioni" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model,name:account_cutoff_accrual_subscription.model_account_cutoff_accrual_subscription +msgid "Subscriptions to compute accrual cutoffs" +msgstr "Numero iscrizioni per il calcolo dell'accumulo cut-off" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__tax_ids +msgid "Taxes" +msgstr "Imposte" + +#. module: account_cutoff_accrual_subscription +#. odoo-python +#: code:addons/account_cutoff_accrual_subscription/models/account_cutoff.py:0 +#, python-format +msgid "" +"The cutoffs with subscription only work when the cutoff date (%s) is the " +"last day of a month." +msgstr "" +"Il cut-off con iscrizione lavora solo quando la data cut-off (%s) è l'ultima " +"di un mese." + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.constraint,message:account_cutoff_accrual_subscription.constraint_account_cutoff_accrual_subscription_provision_amount_positive +msgid "The default provision amount must be positive." +msgstr "Il valore fornitura predefinito deve essere positivo." + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.constraint,message:account_cutoff_accrual_subscription.constraint_account_cutoff_accrual_subscription_min_amount_positive +msgid "The minimum amount must be positive." +msgstr "Il valore minimo deve essere positivo." + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__subscription_type +msgid "Type" +msgstr "Tipo" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields,field_description:account_cutoff_accrual_subscription.field_account_cutoff_accrual_subscription__type_tax_use +msgid "Type Tax Use" +msgstr "Tipo utilizzo imposta" + +#. module: account_cutoff_accrual_subscription +#: model:ir.model.fields.selection,name:account_cutoff_accrual_subscription.selection__account_cutoff_accrual_subscription__periodicity__year +msgid "Yearly" +msgstr "Annuale" diff --git a/account_cutoff_accrual_subscription/models/__init__.py b/account_cutoff_accrual_subscription/models/__init__.py new file mode 100644 index 00000000000..75a4f9606c3 --- /dev/null +++ b/account_cutoff_accrual_subscription/models/__init__.py @@ -0,0 +1,3 @@ +from . import account_cutoff_accrual_subscription +from . import account_cutoff +from . import account_cutoff_line diff --git a/account_cutoff_accrual_subscription/models/account_cutoff.py b/account_cutoff_accrual_subscription/models/account_cutoff.py new file mode 100644 index 00000000000..3b0bf96a760 --- /dev/null +++ b/account_cutoff_accrual_subscription/models/account_cutoff.py @@ -0,0 +1,196 @@ +# Copyright 2019-2022 Akretion France (http://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from dateutil.relativedelta import relativedelta +from markupsafe import Markup + +from odoo import models +from odoo.exceptions import UserError +from odoo.fields import Domain +from odoo.tools import date_utils +from odoo.tools.misc import format_amount, format_date + + +class AccountCutoff(models.Model): + _inherit = "account.cutoff" + + def get_lines(self): + res = super().get_lines() + type2subtype = { + "accrued_expense": "expense", + "accrued_revenue": "revenue", + } + if self.cutoff_type not in type2subtype: + return res + + line_obj = self.env["account.cutoff.line"] + sub_obj = self.env["account.cutoff.accrual.subscription"] + + fy_start_date, fy_end_date = date_utils.get_fiscal_year( + self.cutoff_date, + day=self.company_id.fiscalyear_last_day, + month=int(self.company_id.fiscalyear_last_month), + ) + if not fy_start_date: + raise UserError( + self.env._("Odoo cannot compute the fiscal year start date.") + ) + + sub_type = type2subtype[self.cutoff_type] + sign = sub_type == "revenue" and -1 or 1 + subs = sub_obj.search( + Domain( + [ + ("company_id", "=", self.company_id.id), + ("subscription_type", "=", sub_type), + ("start_date", "<=", self.cutoff_date), + ] + ) + ) + if subs: + # check that the cutoff is the last day of a month + # otherwise, we have pb with when we compute intervals + # with cutoff date is a day which is not present for all months + last_day_same_month = self.cutoff_date + relativedelta(day=31) + if last_day_same_month.day != self.cutoff_date.day: + raise UserError( + self.env._( + "The cutoffs with subscription only work when the cutoff " + "date (%s) is the last day of a month.", + format_date(self.env, self.cutoff_date), + ) + ) + if not self.source_journal_ids: + raise UserError(self.env._("Missing source journals.")) + self.message_post( + body=self.env._("Computing cut-offs from %d subscriptions.", len(subs)) + ) + common_domain = Domain("journal_id", "in", self.source_journal_ids.ids) + if self.source_move_state == "posted": + common_domain &= Domain("parent_state", "=", "posted") + else: + common_domain &= Domain("parent_state", "in", ("draft", "posted")) + work = {} + # Generate time intervals and compute existing expenses/revenue + for sub in subs: + sub._process_subscription( + work, fy_start_date, self.cutoff_date, common_domain, sign + ) + # Create mapping dict + mapping = self._get_mapping_dict() + sub_type_label = ( + sub_type == "expense" and self.env._("Expense") or self.env._("Revenue") + ) + lsign = sub_type == "expense" and -1 or 1 + for sub in work.keys(): + vals = self._prepare_subscription_cutoff_line( + work[sub], mapping, sub_type_label, lsign + ) + if vals: + line_obj.create(vals) + return res + + def _prepare_subscription_cutoff_line(self, data, mapping, sub_type_label, lsign): + # Compute provision for a subscription + # -> analyse each time interval + # Write the details of the computation in the notes + # (or in the chatter if the amount to provision is 0) + sub = data["sub"] + ccur = self.company_currency_id + note_config = self.env._( + "CONFIG: %(periodicity)s periodicity, start date %(start_date)s, " + "min. expense amount %(min_amount)s, default provision amount " + "%(provision_amount)s", + periodicity=dict( + sub._fields["periodicity"]._description_selection(self.env) + ).get(sub.periodicity), + start_date=format_date(self.env, sub.start_date), + min_amount=format_amount(self.env, sub.min_amount, ccur), + provision_amount=format_amount(self.env, sub.provision_amount, ccur), + ) + note_period = self.env._("PERIODS:") + notes = f"

{note_config}

{note_period}

    " + cutoff_amount = 0 + for interval in data["intervals"]: + prorata_label = ( + interval["prorata"] + and " " + + self.env._( + "PRORATED min. amount %(min_amount)s, " + "default provisionning amount %(provision_amount)s", + min_amount=format_amount(self.env, interval["min_amount"], ccur), + provision_amount=format_amount( + self.env, interval["provision_amount"], ccur + ), + ) + or "" + ) + if ccur.compare_amounts(interval["amount"], interval["min_amount"]) < 0: + period_cutoff_amount = ccur.round( + interval["provision_amount"] - interval["amount"] + ) + line_note = self.env._( + "%(start)s → %(end)s%(prorata)s: %(sub_type)s " + "%(amount)s under min. amount ⇒provisionning %(cutoff_amount)s", + start=format_date(self.env, interval["start"]), + end=format_date(self.env, interval["end"]), + prorata=prorata_label, + sub_type=sub_type_label, + amount=format_amount(self.env, interval["amount"], ccur), + cutoff_amount=format_amount(self.env, period_cutoff_amount, ccur), + ) + cutoff_amount += period_cutoff_amount * lsign + else: + line_note = self.env._( + "%(start)s → %(end)s%(prorata)s: %(sub_type)s %(amount)s " + "over min. amount ⇒ no provisionning", + start=format_date(self.env, interval["start"]), + end=format_date(self.env, interval["end"]), + prorata=prorata_label, + sub_type=sub_type_label, + amount=format_amount(self.env, interval["amount"], ccur), + ) + notes += f"
  • {line_note}
  • " + notes += "
" + if ccur.is_zero(cutoff_amount): + msg = self.env._( + "

No provision for subscription %(name)s.

", + id=sub.id, + name=sub.name, + ) + msg += notes + self.message_post(body=Markup(msg)) + return False + else: + if sub.partner_type == "one": + partner_id = sub.partner_id.id + else: + partner_id = False + if sub.account_id.id in mapping: + cutoff_account_id = mapping[sub.account_id.id] + else: + cutoff_account_id = sub.account_id.id + vals = { + "subscription_id": sub.id, + "parent_id": self.id, + "partner_id": partner_id, + "account_id": sub.account_id.id, + "analytic_distribution": sub.analytic_distribution, + "name": sub.name, + "currency_id": sub.company_currency_id.id, + "amount": 0, + "cutoff_amount": cutoff_amount, + "cutoff_account_id": cutoff_account_id, + "notes": notes, + } + if sub.tax_ids and self.company_id.accrual_taxes: + tax_compute_all_res = sub.tax_ids.compute_all( + cutoff_amount, partner=sub.partner_id, handle_price_include=False + ) + vals["tax_line_ids"] = self._prepare_tax_lines( + tax_compute_all_res, ccur + ) + return vals diff --git a/account_cutoff_accrual_subscription/models/account_cutoff_accrual_subscription.py b/account_cutoff_accrual_subscription/models/account_cutoff_accrual_subscription.py new file mode 100644 index 00000000000..ce2fa24528d --- /dev/null +++ b/account_cutoff_accrual_subscription/models/account_cutoff_accrual_subscription.py @@ -0,0 +1,326 @@ +# Copyright 2019-2022 Akretion France (http://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import logging + +from dateutil.relativedelta import relativedelta + +from odoo import api, fields, models +from odoo.exceptions import UserError, ValidationError +from odoo.fields import Domain + +logger = logging.getLogger(__name__) + + +class AccountCutoffAccrualSubscription(models.Model): + _name = "account.cutoff.accrual.subscription" + _inherit = "analytic.mixin" + _description = "Subscriptions to compute accrual cutoffs" + _order = "subscription_type, name" + _check_company_auto = True + + company_id = fields.Many2one( + "res.company", + string="Company", + ondelete="cascade", + required=True, + default=lambda self: self.env.company, + ) + company_currency_id = fields.Many2one( + string="Company Currency", related="company_id.currency_id", store=True + ) + name = fields.Char(required=True) + subscription_type = fields.Selection( + [ + ("revenue", "Revenue"), + ("expense", "Expense"), + ], + default="expense", + required=True, + string="Type", + ) + partner_type = fields.Selection( + [ + ("any", "Any Partner"), + ("one", "Specific Partner"), + ("none", "No Partner"), + ], + default="one", + required=True, + ) + partner_id = fields.Many2one( + "res.partner", + compute="_compute_partner_id", + readonly=False, + store=True, + precompute=True, + string="Partner", + domain=[("parent_id", "=", False)], + ondelete="restrict", + ) + active = fields.Boolean(default=True) + periodicity = fields.Selection( + [ + ("month", "Monthly"), + ("quarter", "Quarterly"), + ("semester", "Semesterly"), + ("year", "Yearly"), + ], + required=True, + ) + start_date = fields.Date(required=True) + min_amount = fields.Monetary( + string="Minimum Amount", + required=True, + currency_field="company_currency_id", + help="Minimum amount without taxes over the period", + ) + provision_amount = fields.Monetary( + compute="_compute_provision_amount", + readonly=False, + store=True, + precompute=True, + string="Default Provision Amount", + currency_field="company_currency_id", + ) + account_id = fields.Many2one( + "account.account", + string="Account", + required=True, + domain="[('company_ids', 'in', company_id)]", + check_company=True, + ) + type_tax_use = fields.Char(compute="_compute_type_tax_use") + tax_ids = fields.Many2many( + "account.tax", + compute="_compute_tax_ids", + readonly=False, + store=True, + precompute=True, + string="Taxes", + domain="[('price_include', '=', False), ('company_id', '=', company_id), " + "('type_tax_use', '=', type_tax_use)]", + check_company=True, + ) + + @api.depends("subscription_type") + def _compute_type_tax_use(self): + mapping = { + "revenue": "sale", + "expense": "purchase", + } + for sub in self: + sub.type_tax_use = mapping.get(sub.subscription_type) + + @api.constrains("start_date") + def check_start_date(self): + for sub in self: + if sub.start_date.day != 1: + raise ValidationError( + self.env._( + "On subscription %s, the start date is not the first " + "day of a month.", + sub.display_name, + ) + ) + + _min_amount_positive = models.Constraint( + "CHECK(min_amount >= 0)", "The minimum amount must be positive." + ) + _provision_amount_positive = models.Constraint( + "CHECK(provision_amount >= 0)", "The default provision amount must be positive." + ) + + @api.depends("min_amount") + def _compute_provision_amount(self): + for sub in self: + if sub.company_currency_id.compare_amounts( + sub.min_amount, 0 + ) > 0 and sub.company_currency_id.is_zero(sub.provision_amount): + sub.provision_amount = sub.min_amount + + @api.depends("account_id") + def _compute_tax_ids(self): + for sub in self: + if sub.account_id: + sub.tax_ids = sub.account_id.tax_ids + + @api.depends("partner_type") + def _compute_partner_id(self): + for sub in self: + if sub.partner_type != "one": + sub.partner_id = False + + def _process_subscription( + self, work, fy_start_date, cutoff_date, common_domain, sign + ): + self.ensure_one() + logger.debug("Processing subscription %s", self.display_name) + aml_obj = self.env["account.move.line"] + periodicity2months = { + "month": 1, + "quarter": 3, + "semester": 6, + "year": 12, + } + company = self.company_id + ccur = company.currency_id + months = periodicity2months[self.periodicity] + work[self] = {"intervals": [], "sub": self} + domain_base = common_domain & Domain( + [ + ("company_id", "=", company.id), + ("account_id", "=", self.account_id.id), + ] + ) + if self.partner_type == "one": + if self.partner_id: + domain_base &= Domain("partner_id", "=", self.partner_id.id) + else: + raise UserError( + self.env._( + "Missing partner on subscription '%s'.", self.display_name + ) + ) + elif self.partner_type == "none": + domain_base &= Domain("partner_id", "=", False) + domain_base_w_start_end = domain_base & Domain( + [ + ("start_date", "!=", False), + ("end_date", "!=", False), + ] + ) + + start_date = fy_start_date # initialize start_date + while start_date < cutoff_date: + end_date = start_date + relativedelta(day=31, months=(months - 1)) + logger.debug("Compute interval from %s to %s", start_date, end_date) + if self.start_date > end_date: + logger.debug( + "Skip interval because subscription start_date %s > end_date", + self.start_date, + ) + start_date = end_date + relativedelta(days=1) + continue + # the next start_date is set at the very end of this method + min_amount = self.min_amount + provision_amount = self.provision_amount + prorata = False + if end_date > cutoff_date or self.start_date > start_date: + prorata = True + initial_interval_days = (end_date - start_date).days + 1 + if end_date > cutoff_date: + end_date = cutoff_date + if self.start_date > start_date: + start_date = self.start_date + final_interval_days = (end_date - start_date).days + 1 + ratio = final_interval_days / initial_interval_days + min_amount = ccur.round(min_amount * ratio) + provision_amount = ccur.round(provision_amount * ratio) + logger.debug( + "Interval has been prorated: %s to %s " + "initial_interval_days=%d final_interval_days=%s", + start_date, + end_date, + initial_interval_days, + final_interval_days, + ) + logger.debug( + "min_amount prorated from %s to %s", self.min_amount, min_amount + ) + logger.debug( + "provision_amount prorated from %s to %s", + self.provision_amount, + provision_amount, + ) + # compute amount + amount = 0 + # 1. No start/end dates + no_start_end_res = aml_obj._read_group( + domain_base + & Domain( + [ + ("date", "<=", end_date), + ("date", ">=", start_date), + ("start_date", "=", False), + ("end_date", "=", False), + ] + ), + aggregates=["balance:sum"], + ) + amount_no_start_end = no_start_end_res and no_start_end_res[0][0] or 0 + amount += amount_no_start_end * sign + # 2. Start/end dates, INSIDE interval + inside_res = aml_obj._read_group( + domain_base_w_start_end + & Domain( + [ + ("start_date", ">=", start_date), + ("end_date", "<=", end_date), + ] + ), + aggregates=["balance:sum"], + ) + amount_inside = inside_res and inside_res[0][0] or 0 + amount += amount_inside * sign + # 3. Start/end dates, OVER interval + mlines = aml_obj.search( + domain_base_w_start_end + & Domain( + [ + ("start_date", "<", start_date), + ("end_date", ">", end_date), + ] + ) + ) + for mline in mlines: + total_days = (mline.end_date - mline.start_date).days + 1 + days_in_interval = (end_date - start_date).days + 1 + amount_in_interval = mline.balance * days_in_interval / total_days + amount += amount_in_interval * sign + # 4. Start/end dates, start_date before, end_date inside + mlines = aml_obj.search( + domain_base_w_start_end + & Domain( + [ + ("start_date", "<", start_date), + ("end_date", ">=", start_date), + ("end_date", "<=", end_date), + ] + ) + ) + for mline in mlines: + total_days = (mline.end_date - mline.start_date).days + 1 + days_in_interval = (mline.end_date - start_date).days + 1 + amount_in_interval = mline.balance * days_in_interval / total_days + amount += amount_in_interval * sign + # 5. Start/end dates, start_date inside, end_date after + mlines = aml_obj.search( + domain_base_w_start_end + & Domain( + [ + ("start_date", ">=", start_date), + ("start_date", "<=", end_date), + ("end_date", ">", end_date), + ] + ) + ) + for mline in mlines: + total_days = (mline.end_date - mline.start_date).days + 1 + days_in_interval = (end_date - mline.start_date).days + 1 + amount_in_interval = mline.balance * days_in_interval / total_days + amount += amount_in_interval * sign + + work[self]["intervals"].append( + { + "start": start_date, + "end": end_date, + "amount": ccur.round(amount), + "prorata": prorata, + "min_amount": min_amount, + "provision_amount": provision_amount, + } + ) + # prepare next interval + start_date = end_date + relativedelta(days=1) diff --git a/account_cutoff_accrual_subscription/models/account_cutoff_line.py b/account_cutoff_accrual_subscription/models/account_cutoff_line.py new file mode 100644 index 00000000000..9ae3f17e92f --- /dev/null +++ b/account_cutoff_accrual_subscription/models/account_cutoff_line.py @@ -0,0 +1,13 @@ +# Copyright 2019-2022 Akretion France (http://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class AccountCutoffLine(models.Model): + _inherit = "account.cutoff.line" + + subscription_id = fields.Many2one( + "account.cutoff.accrual.subscription", ondelete="restrict", check_company=True + ) diff --git a/account_cutoff_accrual_subscription/pyproject.toml b/account_cutoff_accrual_subscription/pyproject.toml new file mode 100644 index 00000000000..4231d0cccb3 --- /dev/null +++ b/account_cutoff_accrual_subscription/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/account_cutoff_accrual_subscription/readme/CONFIGURE.md b/account_cutoff_accrual_subscription/readme/CONFIGURE.md new file mode 100644 index 00000000000..eb598e2c779 --- /dev/null +++ b/account_cutoff_accrual_subscription/readme/CONFIGURE.md @@ -0,0 +1,4 @@ +Go to the menu *Accounting \> Configuration \> Accounting \> +Subscriptions* and create subscriptions: they are used as the expected +expenses (or revenue). For exemple, you may create a subscription for +your office rental, your Internet access, your insurance contracts, etc. diff --git a/account_cutoff_accrual_subscription/readme/CONTRIBUTORS.md b/account_cutoff_accrual_subscription/readme/CONTRIBUTORS.md new file mode 100644 index 00000000000..b61afe5d01b --- /dev/null +++ b/account_cutoff_accrual_subscription/readme/CONTRIBUTORS.md @@ -0,0 +1 @@ +- Alexis de Lattre \<\> diff --git a/account_cutoff_accrual_subscription/readme/DESCRIPTION.md b/account_cutoff_accrual_subscription/readme/DESCRIPTION.md new file mode 100644 index 00000000000..ccd1c76fa12 --- /dev/null +++ b/account_cutoff_accrual_subscription/readme/DESCRIPTION.md @@ -0,0 +1,3 @@ +This module allows you to easily compute accrued expenses (and accrued +revenues) by comparing expected expense amounts (configured as +*subscriptions*) with real expense amounts. diff --git a/account_cutoff_accrual_subscription/security/ir.model.access.csv b/account_cutoff_accrual_subscription/security/ir.model.access.csv new file mode 100644 index 00000000000..de445afaf90 --- /dev/null +++ b/account_cutoff_accrual_subscription/security/ir.model.access.csv @@ -0,0 +1,4 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_account_cutoff_accrual_subscription_read,Read access on account.cutoff.accrual.subscription,model_account_cutoff_accrual_subscription,account.group_account_user,1,0,0,0 +access_account_cutoff_accrual_subscription_group_readonly,Read access on account.cutoff.accrual.subscription to Auditor,model_account_cutoff_accrual_subscription,account.group_account_readonly,1,0,0,0 +access_account_cutoff_accrual_subscription_full,Full access on account.cutoff.accrual.subscription,model_account_cutoff_accrual_subscription,account.group_account_manager,1,1,1,1 diff --git a/account_cutoff_accrual_subscription/security/ir_rule.xml b/account_cutoff_accrual_subscription/security/ir_rule.xml new file mode 100644 index 00000000000..58ea1fa5cff --- /dev/null +++ b/account_cutoff_accrual_subscription/security/ir_rule.xml @@ -0,0 +1,8 @@ + + + + Account Cutoff Accrual Subscription Multi-Company + + [('company_id', 'in', company_ids)] + + diff --git a/account_cutoff_accrual_subscription/static/description/icon.png b/account_cutoff_accrual_subscription/static/description/icon.png new file mode 100644 index 00000000000..3a0328b516c Binary files /dev/null and b/account_cutoff_accrual_subscription/static/description/icon.png differ diff --git a/account_cutoff_accrual_subscription/static/description/index.html b/account_cutoff_accrual_subscription/static/description/index.html new file mode 100644 index 00000000000..dc3c6c8a699 --- /dev/null +++ b/account_cutoff_accrual_subscription/static/description/index.html @@ -0,0 +1,441 @@ + + + + + +README.rst + + + +
+ + + +Odoo Community Association + +
+

Account Accrual Subscriptions

+ +

Beta License: AGPL-3 OCA/account-closing Translate me on Weblate Try me on Runboat

+

This module allows you to easily compute accrued expenses (and accrued +revenues) by comparing expected expense amounts (configured as +subscriptions) with real expense amounts.

+

Table of contents

+ +
+

Configuration

+

Go to the menu Accounting > Configuration > Accounting > Subscriptions +and create subscriptions: they are used as the expected expenses (or +revenue). For exemple, you may create a subscription for your office +rental, your Internet access, your insurance contracts, etc.

+
+
+

Bug Tracker

+

Bugs are tracked on GitHub 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.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Akretion
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

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.

+

Current maintainer:

+

alexis-via

+

This module is part of the OCA/account-closing project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+
+ + diff --git a/account_cutoff_accrual_subscription/views/account_cutoff_accrual_subscription.xml b/account_cutoff_accrual_subscription/views/account_cutoff_accrual_subscription.xml new file mode 100644 index 00000000000..7f3f6563e09 --- /dev/null +++ b/account_cutoff_accrual_subscription/views/account_cutoff_accrual_subscription.xml @@ -0,0 +1,160 @@ + + + + + account.cutoff.accrual.subscription.form + account.cutoff.accrual.subscription + +
+ + +
+
+ + + + + + + + + + + + + + + + + +
+
+
+
+ + + account.cutoff.accrual.subscription.list + account.cutoff.accrual.subscription + + + + + + + + + + + + + + + + + + + + + account.cutoff.accrual.subscription.search + account.cutoff.accrual.subscription + + + + + + + + + + + + + + + + + + + + + Subscriptions + account.cutoff.accrual.subscription + list,form + + + +
diff --git a/account_cutoff_accrual_subscription/views/account_cutoff_line.xml b/account_cutoff_accrual_subscription/views/account_cutoff_line.xml new file mode 100644 index 00000000000..e5faecd3287 --- /dev/null +++ b/account_cutoff_accrual_subscription/views/account_cutoff_line.xml @@ -0,0 +1,26 @@ + + + + + account.cutoff.line + + + + + + + + + account.cutoff.line + + + + + + + +