diff --git a/account_cutoff_picking/README.rst b/account_cutoff_picking/README.rst new file mode 100644 index 00000000000..e1f03b1859b --- /dev/null +++ b/account_cutoff_picking/README.rst @@ -0,0 +1,149 @@ +======================= +Account Cut-off Picking +======================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:e2bd737ffd53ce337b2431a43d4050e332d9d280fe6130578052d8ba14f96fe2 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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/licence-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/18.0/account_cutoff_picking + :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-18-0/account-closing-18-0-account_cutoff_picking + :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=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module generates expense/revenue accruals and prepaid +expense/revenue based on the status of orders, pickings and invoices. +The module is named *account_cutoff_accrual_picking* because it +initially only supported accruals ; support for prepaid expense/revenue +was added later (it should be renamed in later versions). + +To understand the behavior of this module, let's take the example of an +expense accrual. When you click on the button *Re-Generate Lines* of an +*Expense Accrual*: + +1. Odoo will look for all incoming picking in Done state with a + *Transfer Date* <= *Cut-off Date*. For performance reasons, by + default, the incoming picking dated before *Cut-off Date* minus 30 + days will not be taken into account (this limit is configurable via + the field *Picking Analysis*). It will go to the stock moves of those + pickings and see if they are linked to a purchase order line. +2. Once this analysis is completed, Odoo has a list of purchase order + lines to analyse for potential expense accrual. +3. For each of these purchase order lines, Odoo will: + + - scan the related stock moves in *done* state and check their + transfer date, + - scan the related invoices lines and check their invoice date. + +4. If, for a particular purchase order line, the quantity of products + received before the cutoff-date (or on the same day) minus the + quantity of products invoiced before the cut-off date (or on the same + day) is positive, Odoo will generate a cut-off line. + +Now, let's take the example of a prepaid expense. When you click on the +button *Re-Generate Lines* of a *Prepaid Expense*: + +1. Odoo will look for all vendor bills dated before (or equal to) + *Cut-off Date*. For performance reasons, by default, the vendor bills + dated before *Cut-off Date* minus 30 days will not be taken into + account (this limit is configurable via the field *Picking + Analysis*). It will go to the invoice lines of those vendor bills and + see if they are linked to a purchase order line. +2. Once this analysis is completed, Odoo has a list of purchase order + lines to analyse for potential prepaid expense. +3. For each of these purchase order lines, Odoo will: + + - scan the related stock moves in *done* state and check their + transfer date, + - scan the related invoices lines and check their invoice date. + +4. If, for a particular purchase order line, the quantity of products + invoiced before the cutoff-date (or on the same day) minus the + quantity of products received before the cut-off date (or on the same + day) is positive, Odoo will generate a cut-off line. + +This module should work well with multiple units of measure (including +products purchased and invoiced in different units of measure) and in +multi-currency. + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +For configuration instructions, refer to the README of the module +*account_cutoff_base*. + +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 + +Other credits +------------- + +The migration of this module from 16.0 to 17.0 was financially supported +by Camptocamp + +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_picking/__init__.py b/account_cutoff_picking/__init__.py new file mode 100644 index 00000000000..aee8895e7a3 --- /dev/null +++ b/account_cutoff_picking/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import wizards diff --git a/account_cutoff_picking/__manifest__.py b/account_cutoff_picking/__manifest__.py new file mode 100644 index 00000000000..196e21ea24c --- /dev/null +++ b/account_cutoff_picking/__manifest__.py @@ -0,0 +1,23 @@ +# Copyright 2013-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 Cut-off Picking", + "version": "18.0.1.0.0", + "category": "Accounting", + "license": "AGPL-3", + "summary": "Accrued and prepaid expense/revenue from pickings", + "author": "Akretion,Odoo Community Association (OCA)", + "maintainers": ["alexis-via"], + "website": "https://github.com/OCA/account-closing", + "depends": ["account_cutoff_base", "purchase_stock", "sale_stock"], + "data": ["views/res_config_settings.xml", "views/account_cutoff.xml"], + "images": [ + "images/accrued_expense_draft.jpg", + "images/accrued_expense_journal_entry.jpg", + "images/accrued_expense_done.jpg", + ], + "installable": True, + "application": False, +} diff --git a/account_cutoff_picking/i18n/account_cutoff_picking.pot b/account_cutoff_picking/i18n/account_cutoff_picking.pot new file mode 100644 index 00000000000..14a194a74e8 --- /dev/null +++ b/account_cutoff_picking/i18n/account_cutoff_picking.pot @@ -0,0 +1,160 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_cutoff_picking +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.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_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +" • %(qty)s %(uom)s (picking %(picking)s transfered on %(date)s from " +"%(src_location)s to %(dest_location)s)" +msgstr "" + +#. module: account_cutoff_picking +#: model:ir.model,name:account_cutoff_picking.model_account_cutoff +msgid "Account Cut-off" +msgstr "" + +#. module: account_cutoff_picking +#: model:ir.model.fields,field_description:account_cutoff_picking.field_account_cutoff__picking_interval_days +#: model:ir.model.fields,field_description:account_cutoff_picking.field_res_company__default_cutoff_picking_interval_days +#: model:ir.model.fields,field_description:account_cutoff_picking.field_res_config_settings__dft_cutoff_picking_interval_days +msgid "Analysis Interval" +msgstr "" + +#. module: account_cutoff_picking +#: model:ir.model,name:account_cutoff_picking.model_res_company +msgid "Companies" +msgstr "" + +#. module: account_cutoff_picking +#: model:ir.model,name:account_cutoff_picking.model_res_config_settings +msgid "Config Settings" +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +"Missing expense account on product '%(product)s' or on its related product " +"category '%(categ)s'." +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +"Missing income account on product '%(product)s' or on its related product " +"category '%(categ)s'." +msgstr "" + +#. module: account_cutoff_picking +#: model_terms:ir.ui.view,arch_db:account_cutoff_picking.res_config_settings_view_form +msgid "Picking Analysis Interval" +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff delivered quantity details:" +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff delivered quantity minus invoiced quantity:" +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff delivered quantity:" +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff invoiced quantity details:" +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff invoiced quantity minus delivered quantity:" +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff invoiced quantity:" +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +"Purchase order %(order)s confirmed on %(confirm_date)s\n" +"Purchase Order Line: %(order_line)s (ordered qty: %(qty)s %(uom)s)" +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +"Sale order %(order)s confirmed on %(confirm_date)s\n" +"Sale Order Line: %(order_line)s (ordered qty: %(qty)s %(uom)s)" +msgstr "" + +#. module: account_cutoff_picking +#: model:ir.model.constraint,message:account_cutoff_picking.constraint_account_cutoff_picking_interval_days_positive +#: model:ir.model.constraint,message:account_cutoff_picking.constraint_res_company_cutoff_picking_interval_days_positive +msgid "The value of the field 'Analysis Interval' must be strictly positive." +msgstr "" + +#. module: account_cutoff_picking +#: model:ir.model.fields,help:account_cutoff_picking.field_res_company__default_cutoff_picking_interval_days +#: model:ir.model.fields,help:account_cutoff_picking.field_res_config_settings__dft_cutoff_picking_interval_days +msgid "" +"To generate the accrual/prepaid revenue/expenses based on picking dates vs " +"invoice dates, Odoo will analyse all the pickings/invoices from N days " +"before the cutoff date up to the cutoff date. N is the Analysis Interval. If" +" you increase the analysis interval, Odoo will take more time to generate " +"the cutoff lines." +msgstr "" + +#. module: account_cutoff_picking +#: model:ir.model.fields,help:account_cutoff_picking.field_account_cutoff__picking_interval_days +msgid "" +"To generate the cutoffs based on picking dates vs invoice dates, Odoo will " +"analyse all the pickings/invoices from N days before the cutoff date up to " +"the cutoff date. N is the Analysis Interval. If you increase the analysis " +"interval, Odoo will take more time to generate the cutoff lines." +msgstr "" + +#. module: account_cutoff_picking +#: model_terms:ir.ui.view,arch_db:account_cutoff_picking.account_cutoff_form +#: model_terms:ir.ui.view,arch_db:account_cutoff_picking.res_config_settings_view_form +msgid "days" +msgstr "" diff --git a/account_cutoff_picking/i18n/de.po b/account_cutoff_picking/i18n/de.po new file mode 100644 index 00000000000..1215a588674 --- /dev/null +++ b/account_cutoff_picking/i18n/de.po @@ -0,0 +1,187 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * account_cutoff_accrual_picking +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 7.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-02-23 14:37+0000\n" +"PO-Revision-Date: 2015-02-05 23:47+0100\n" +"Last-Translator: Rudolf Schnapka \n" +"Language-Team: \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.5.4\n" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +" • %(qty)s %(uom)s (picking %(picking)s transfered on %(date)s from " +"%(src_location)s to %(dest_location)s)" +msgstr "" + +#. module: account_cutoff_picking +#: model:ir.model,name:account_cutoff_picking.model_account_cutoff +msgid "Account Cut-off" +msgstr "Abgrenzungskonto" + +#. module: account_cutoff_picking +#: model:ir.model.fields,field_description:account_cutoff_picking.field_account_cutoff__picking_interval_days +#: model:ir.model.fields,field_description:account_cutoff_picking.field_res_company__default_cutoff_picking_interval_days +#: model:ir.model.fields,field_description:account_cutoff_picking.field_res_config_settings__dft_cutoff_picking_interval_days +msgid "Analysis Interval" +msgstr "" + +#. module: account_cutoff_picking +#: model:ir.model,name:account_cutoff_picking.model_res_company +msgid "Companies" +msgstr "" + +#. module: account_cutoff_picking +#: model:ir.model,name:account_cutoff_picking.model_res_config_settings +msgid "Config Settings" +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +"Missing expense account on product '%(product)s' or on its related product " +"category '%(categ)s'." +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +"Missing income account on product '%(product)s' or on its related product " +"category '%(categ)s'." +msgstr "" + +#. module: account_cutoff_picking +#: model_terms:ir.ui.view,arch_db:account_cutoff_picking.res_config_settings_view_form +msgid "Picking Analysis Interval" +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff delivered quantity details:" +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff delivered quantity minus invoiced quantity:" +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff delivered quantity:" +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff invoiced quantity details:" +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff invoiced quantity minus delivered quantity:" +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff invoiced quantity:" +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +"Purchase order %(order)s confirmed on %(confirm_date)s\n" +"Purchase Order Line: %(order_line)s (ordered qty: %(qty)s %(uom)s)" +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +"Sale order %(order)s confirmed on %(confirm_date)s\n" +"Sale Order Line: %(order_line)s (ordered qty: %(qty)s %(uom)s)" +msgstr "" + +#. module: account_cutoff_picking +#: model:ir.model.constraint,message:account_cutoff_picking.constraint_account_cutoff_picking_interval_days_positive +#: model:ir.model.constraint,message:account_cutoff_picking.constraint_res_company_cutoff_picking_interval_days_positive +msgid "The value of the field 'Analysis Interval' must be strictly positive." +msgstr "" + +#. module: account_cutoff_picking +#: model:ir.model.fields,help:account_cutoff_picking.field_res_company__default_cutoff_picking_interval_days +#: model:ir.model.fields,help:account_cutoff_picking.field_res_config_settings__dft_cutoff_picking_interval_days +msgid "" +"To generate the accrual/prepaid revenue/expenses based on picking dates vs " +"invoice dates, Odoo will analyse all the pickings/invoices from N days " +"before the cutoff date up to the cutoff date. N is the Analysis Interval. If " +"you increase the analysis interval, Odoo will take more time to generate the " +"cutoff lines." +msgstr "" + +#. module: account_cutoff_picking +#: model:ir.model.fields,help:account_cutoff_picking.field_account_cutoff__picking_interval_days +msgid "" +"To generate the cutoffs based on picking dates vs invoice dates, Odoo will " +"analyse all the pickings/invoices from N days before the cutoff date up to " +"the cutoff date. N is the Analysis Interval. If you increase the analysis " +"interval, Odoo will take more time to generate the cutoff lines." +msgstr "" + +#. module: account_cutoff_picking +#: model_terms:ir.ui.view,arch_db:account_cutoff_picking.account_cutoff_form +#: model_terms:ir.ui.view,arch_db:account_cutoff_picking.res_config_settings_view_form +msgid "days" +msgstr "" + +#~ msgid "Missing '%s' on tax '%s'." +#~ msgstr "Fehlende '%s' bei Steuer '%s'." + +#~ msgid "Account Cut-off Line" +#~ msgstr "Abgrenzungsposten" + +#~ msgid "Product" +#~ msgstr "Produkt" + +#~ msgid "Stock Move" +#~ msgstr "Lagerumbuchung" + +#~ msgid "Re-Generate Lines from Picking" +#~ msgstr "Positionen aus Kommissionierung erneuern" + +#~ msgid "Picking" +#~ msgstr "Entnahme" + +#~ msgid "Date Done of the Picking" +#~ msgstr "Datum erledigter Kommissionierung" + +#~ msgid "Error:" +#~ msgstr "Fehler:" diff --git a/account_cutoff_picking/i18n/es.po b/account_cutoff_picking/i18n/es.po new file mode 100644 index 00000000000..04efd703d7f --- /dev/null +++ b/account_cutoff_picking/i18n/es.po @@ -0,0 +1,184 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_cutoff_picking +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-02-11 13:36+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_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +" • %(qty)s %(uom)s (picking %(picking)s transfered on %(date)s from " +"%(src_location)s to %(dest_location)s)" +msgstr "" +" • %(qty)s %(uom)s (recogiendo %(picking)s transferido el %(date)s desde " +"%(src_location)s hasta %(dest_location)s)" + +#. module: account_cutoff_picking +#: model:ir.model,name:account_cutoff_picking.model_account_cutoff +msgid "Account Cut-off" +msgstr "Cuenta de cierre" + +#. module: account_cutoff_picking +#: model:ir.model.fields,field_description:account_cutoff_picking.field_account_cutoff__picking_interval_days +#: model:ir.model.fields,field_description:account_cutoff_picking.field_res_company__default_cutoff_picking_interval_days +#: model:ir.model.fields,field_description:account_cutoff_picking.field_res_config_settings__dft_cutoff_picking_interval_days +msgid "Analysis Interval" +msgstr "intervalo de análisis" + +#. module: account_cutoff_picking +#: model:ir.model,name:account_cutoff_picking.model_res_company +msgid "Companies" +msgstr "Empresas" + +#. module: account_cutoff_picking +#: model:ir.model,name:account_cutoff_picking.model_res_config_settings +msgid "Config Settings" +msgstr "ajustes de configuración" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +"Missing expense account on product '%(product)s' or on its related product " +"category '%(categ)s'." +msgstr "" +"Falta la cuenta de gastos en el producto' %(product)s' o en su categoría de " +"producto relacionada '%(categ)s'." + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +"Missing income account on product '%(product)s' or on its related product " +"category '%(categ)s'." +msgstr "" +"Falta la cuenta de ingresos en el producto' %(product)s' o en su categoría " +"de producto relacionada '%(categ)s'." + +#. module: account_cutoff_picking +#: model_terms:ir.ui.view,arch_db:account_cutoff_picking.res_config_settings_view_form +msgid "Picking Analysis Interval" +msgstr "Selección del Intervalo de Análisis" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff delivered quantity details:" +msgstr "Detalles de la cantidad entregada antes del cierre:" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff delivered quantity minus invoiced quantity:" +msgstr "Cantidad entregada antes del cierre menos cantidad facturada:" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff delivered quantity:" +msgstr "Cantidad entregada antes del cierre:" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff invoiced quantity details:" +msgstr "Detalles de la cantidad facturada antes del cierre:" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff invoiced quantity minus delivered quantity:" +msgstr "Cantidad facturada antes del cierre menos cantidad entregada:" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff invoiced quantity:" +msgstr "Cantidad facturada antes del cierre:" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +"Purchase order %(order)s confirmed on %(confirm_date)s\n" +"Purchase Order Line: %(order_line)s (ordered qty: %(qty)s %(uom)s)" +msgstr "" +"pedido%(order)s confirmado%(confirm_date)s\n" +"lí%(order_line)snea de pedido (cantidad pedida:%(qty)s%(uom)s" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +"Sale order %(order)s confirmed on %(confirm_date)s\n" +"Sale Order Line: %(order_line)s (ordered qty: %(qty)s %(uom)s)" +msgstr "" +"pedido de venta%(order)s confirmado el%(confirm_date)s\n" +"línea de pedido de venta: %(order_line)s (cantidad pedida%(qty)s%(uom)s)" + +#. module: account_cutoff_picking +#: model:ir.model.constraint,message:account_cutoff_picking.constraint_account_cutoff_picking_interval_days_positive +#: model:ir.model.constraint,message:account_cutoff_picking.constraint_res_company_cutoff_picking_interval_days_positive +msgid "The value of the field 'Analysis Interval' must be strictly positive." +msgstr "" +"El valor del campo 'Intervalo de análisis' debe ser estrictamente positivo." + +#. module: account_cutoff_picking +#: model:ir.model.fields,help:account_cutoff_picking.field_res_company__default_cutoff_picking_interval_days +#: model:ir.model.fields,help:account_cutoff_picking.field_res_config_settings__dft_cutoff_picking_interval_days +msgid "" +"To generate the accrual/prepaid revenue/expenses based on picking dates vs " +"invoice dates, Odoo will analyse all the pickings/invoices from N days " +"before the cutoff date up to the cutoff date. N is the Analysis Interval. If " +"you increase the analysis interval, Odoo will take more time to generate the " +"cutoff lines." +msgstr "" +"Para generar los ingresos/gastos devengados/prepagados basados en fechas de " +"recolección vs fechas de factura, Odoo analizará todas las recolecciones/" +"facturas desde N días antes de la fecha de cierre hasta la fecha de cierre. " +"N es el Intervalo de Análisis. Si incrementa el intervalo de análisis, Odoo " +"tomará mas tiempo para generar las líneas de cierre." + +#. module: account_cutoff_picking +#: model:ir.model.fields,help:account_cutoff_picking.field_account_cutoff__picking_interval_days +msgid "" +"To generate the cutoffs based on picking dates vs invoice dates, Odoo will " +"analyse all the pickings/invoices from N days before the cutoff date up to " +"the cutoff date. N is the Analysis Interval. If you increase the analysis " +"interval, Odoo will take more time to generate the cutoff lines." +msgstr "" +"Para generar los cierres basados en fechas de recolección vs fechas de " +"factura, Odoo analizará todas las recolecciones/facturas desde N días antes " +"de la fecha de cierree hasta la fecha de cierre. N es el Intervalo de " +"Análisis. Si incrementa el intervalo de análisis, Odoo tomará más tiempo " +"para generar las líneas de cierre." + +#. module: account_cutoff_picking +#: model_terms:ir.ui.view,arch_db:account_cutoff_picking.account_cutoff_form +#: model_terms:ir.ui.view,arch_db:account_cutoff_picking.res_config_settings_view_form +msgid "days" +msgstr "días" diff --git a/account_cutoff_picking/i18n/fr.po b/account_cutoff_picking/i18n/fr.po new file mode 100644 index 00000000000..9ce8d301003 --- /dev/null +++ b/account_cutoff_picking/i18n/fr.po @@ -0,0 +1,193 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_cutoff_picking +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-06-20 15:08+0000\n" +"Last-Translator: Alexis de Lattre \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.17\n" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +" • %(qty)s %(uom)s (picking %(picking)s transfered on %(date)s from " +"%(src_location)s to %(dest_location)s)" +msgstr "" +" • %(qty)s %(uom)s (bon de transfert %(picking)s validé le %(date)s de " +"%(src_location)s à %(dest_location)s)" + +#. module: account_cutoff_picking +#: model:ir.model,name:account_cutoff_picking.model_account_cutoff +msgid "Account Cut-off" +msgstr "Provision comptable" + +#. module: account_cutoff_picking +#: model:ir.model.fields,field_description:account_cutoff_picking.field_account_cutoff__picking_interval_days +#: model:ir.model.fields,field_description:account_cutoff_picking.field_res_company__default_cutoff_picking_interval_days +#: model:ir.model.fields,field_description:account_cutoff_picking.field_res_config_settings__dft_cutoff_picking_interval_days +msgid "Analysis Interval" +msgstr "Intervalle d'analyse" + +#. module: account_cutoff_picking +#: model:ir.model,name:account_cutoff_picking.model_res_company +msgid "Companies" +msgstr "Sociétés" + +#. module: account_cutoff_picking +#: model:ir.model,name:account_cutoff_picking.model_res_config_settings +msgid "Config Settings" +msgstr "Configuration" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +"Missing expense account on product '%(product)s' or on its related product " +"category '%(categ)s'." +msgstr "" +"Compte de charge manquant sur l'article '%(product)s' ou sur sa catégorie " +"d'article associée '%(categ)s'." + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +"Missing income account on product '%(product)s' or on its related product " +"category '%(categ)s'." +msgstr "" +"Compte de revenu manquant sur l'article '%(product)s' ou sur sa catégorie " +"d'article associée '%(categ)s'." + +#. module: account_cutoff_picking +#: model_terms:ir.ui.view,arch_db:account_cutoff_picking.res_config_settings_view_form +msgid "Picking Analysis Interval" +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff delivered quantity details:" +msgstr "Détails des quantités livrées jusqu'à la date de provision :" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff delivered quantity minus invoiced quantity:" +msgstr "Quantités livrées moins qtés facturées jusqu'à la date de provision :" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff delivered quantity:" +msgstr "Quantités livrées jusqu'à la date de provision :" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff invoiced quantity details:" +msgstr "Détails des quantités facturées jusqu'à la date de provision :" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff invoiced quantity minus delivered quantity:" +msgstr "Quantité facturée moins quantité livrée jusqu'à la date de provision :" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff invoiced quantity:" +msgstr "Quantité facturée jusqu'à la date de provision :" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +"Purchase order %(order)s confirmed on %(confirm_date)s\n" +"Purchase Order Line: %(order_line)s (ordered qty: %(qty)s %(uom)s)" +msgstr "" +"Commande fournisseur %(order)s confirmée le %(confirm_date)s\n" +"Ligne de commande fournisseur : %(order_line)s (quantité commandée : %(qty)s " +"%(uom)s)" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +"Sale order %(order)s confirmed on %(confirm_date)s\n" +"Sale Order Line: %(order_line)s (ordered qty: %(qty)s %(uom)s)" +msgstr "" +"Commande client %(order)s confirmée le %(confirm_date)s\n" +"Ligne de commande client : %(order_line)s (quantité commandée : %(qty)s " +"%(uom)s)" + +#. module: account_cutoff_picking +#: model:ir.model.constraint,message:account_cutoff_picking.constraint_account_cutoff_picking_interval_days_positive +#: model:ir.model.constraint,message:account_cutoff_picking.constraint_res_company_cutoff_picking_interval_days_positive +msgid "The value of the field 'Analysis Interval' must be strictly positive." +msgstr "" +"La valeur du champ \"Intervalle d'analyse\" doit être strictement positive." + +#. module: account_cutoff_picking +#: model:ir.model.fields,help:account_cutoff_picking.field_res_company__default_cutoff_picking_interval_days +#: model:ir.model.fields,help:account_cutoff_picking.field_res_config_settings__dft_cutoff_picking_interval_days +msgid "" +"To generate the accrual/prepaid revenue/expenses based on picking dates vs " +"invoice dates, Odoo will analyse all the pickings/invoices from N days " +"before the cutoff date up to the cutoff date. N is the Analysis Interval. If " +"you increase the analysis interval, Odoo will take more time to generate the " +"cutoff lines." +msgstr "" +"Pour générer les provisions de produits et charges à partir de la " +"comparaison entre les dates de livraison et les dates de facturation, Odoo " +"analysera tous les livraisons/factures depuis N jours avant la date de " +"provision jusqu'à la date de provision. N est l'intervalle d'analyse. Si " +"vous augmentez l'intervalle d'analyse, Odoo mettra plus de temps pour " +"générer les lignes de provision." + +#. module: account_cutoff_picking +#: model:ir.model.fields,help:account_cutoff_picking.field_account_cutoff__picking_interval_days +msgid "" +"To generate the cutoffs based on picking dates vs invoice dates, Odoo will " +"analyse all the pickings/invoices from N days before the cutoff date up to " +"the cutoff date. N is the Analysis Interval. If you increase the analysis " +"interval, Odoo will take more time to generate the cutoff lines." +msgstr "" +"Pour générer les provisions à partir de la comparaison entre les dates de " +"livraison et les dates de facturation, Odoo analysera toutes les livraisons/" +"factures à partir de N jours avant la date de provision jusqu'à la date de " +"provision. N est l'intervalle d'analyse. Si vous augmentez l'intervalle " +"d'analyse, Odoo prendra plus de temps pour générer les lignes de provision." + +#. module: account_cutoff_picking +#: model_terms:ir.ui.view,arch_db:account_cutoff_picking.account_cutoff_form +#: model_terms:ir.ui.view,arch_db:account_cutoff_picking.res_config_settings_view_form +msgid "days" +msgstr "jours" + +#~ msgid "Display Name" +#~ msgstr "Nom affiché" + +#~ msgid "Last Modified on" +#~ msgstr "Dernière modification le" diff --git a/account_cutoff_picking/i18n/fr_BE.po b/account_cutoff_picking/i18n/fr_BE.po new file mode 100644 index 00000000000..cbae2ccafb4 --- /dev/null +++ b/account_cutoff_picking/i18n/fr_BE.po @@ -0,0 +1,162 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_cutoff_accrual_picking +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-02-23 14:37+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: fr_BE\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" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +" • %(qty)s %(uom)s (picking %(picking)s transfered on %(date)s from " +"%(src_location)s to %(dest_location)s)" +msgstr "" + +#. module: account_cutoff_picking +#: model:ir.model,name:account_cutoff_picking.model_account_cutoff +msgid "Account Cut-off" +msgstr "" + +#. module: account_cutoff_picking +#: model:ir.model.fields,field_description:account_cutoff_picking.field_account_cutoff__picking_interval_days +#: model:ir.model.fields,field_description:account_cutoff_picking.field_res_company__default_cutoff_picking_interval_days +#: model:ir.model.fields,field_description:account_cutoff_picking.field_res_config_settings__dft_cutoff_picking_interval_days +msgid "Analysis Interval" +msgstr "" + +#. module: account_cutoff_picking +#: model:ir.model,name:account_cutoff_picking.model_res_company +msgid "Companies" +msgstr "" + +#. module: account_cutoff_picking +#: model:ir.model,name:account_cutoff_picking.model_res_config_settings +msgid "Config Settings" +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +"Missing expense account on product '%(product)s' or on its related product " +"category '%(categ)s'." +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +"Missing income account on product '%(product)s' or on its related product " +"category '%(categ)s'." +msgstr "" + +#. module: account_cutoff_picking +#: model_terms:ir.ui.view,arch_db:account_cutoff_picking.res_config_settings_view_form +msgid "Picking Analysis Interval" +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff delivered quantity details:" +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff delivered quantity minus invoiced quantity:" +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff delivered quantity:" +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff invoiced quantity details:" +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff invoiced quantity minus delivered quantity:" +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff invoiced quantity:" +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +"Purchase order %(order)s confirmed on %(confirm_date)s\n" +"Purchase Order Line: %(order_line)s (ordered qty: %(qty)s %(uom)s)" +msgstr "" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +"Sale order %(order)s confirmed on %(confirm_date)s\n" +"Sale Order Line: %(order_line)s (ordered qty: %(qty)s %(uom)s)" +msgstr "" + +#. module: account_cutoff_picking +#: model:ir.model.constraint,message:account_cutoff_picking.constraint_account_cutoff_picking_interval_days_positive +#: model:ir.model.constraint,message:account_cutoff_picking.constraint_res_company_cutoff_picking_interval_days_positive +msgid "The value of the field 'Analysis Interval' must be strictly positive." +msgstr "" + +#. module: account_cutoff_picking +#: model:ir.model.fields,help:account_cutoff_picking.field_res_company__default_cutoff_picking_interval_days +#: model:ir.model.fields,help:account_cutoff_picking.field_res_config_settings__dft_cutoff_picking_interval_days +msgid "" +"To generate the accrual/prepaid revenue/expenses based on picking dates vs " +"invoice dates, Odoo will analyse all the pickings/invoices from N days " +"before the cutoff date up to the cutoff date. N is the Analysis Interval. If " +"you increase the analysis interval, Odoo will take more time to generate the " +"cutoff lines." +msgstr "" + +#. module: account_cutoff_picking +#: model:ir.model.fields,help:account_cutoff_picking.field_account_cutoff__picking_interval_days +msgid "" +"To generate the cutoffs based on picking dates vs invoice dates, Odoo will " +"analyse all the pickings/invoices from N days before the cutoff date up to " +"the cutoff date. N is the Analysis Interval. If you increase the analysis " +"interval, Odoo will take more time to generate the cutoff lines." +msgstr "" + +#. module: account_cutoff_picking +#: model_terms:ir.ui.view,arch_db:account_cutoff_picking.account_cutoff_form +#: model_terms:ir.ui.view,arch_db:account_cutoff_picking.res_config_settings_view_form +msgid "days" +msgstr "" diff --git a/account_cutoff_picking/i18n/it.po b/account_cutoff_picking/i18n/it.po new file mode 100644 index 00000000000..4715d5ecf92 --- /dev/null +++ b/account_cutoff_picking/i18n/it.po @@ -0,0 +1,206 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_cutoff_accrual_picking +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-02-23 14:37+0000\n" +"PO-Revision-Date: 2024-03-18 15:34+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 4.17\n" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +" • %(qty)s %(uom)s (picking %(picking)s transfered on %(date)s from " +"%(src_location)s to %(dest_location)s)" +msgstr "" +" • %(qty)s %(uom)s (prelievo %(picking)s trasferito il %(date)s dal " +"%(src_location)s a %(dest_location)s)" + +#. module: account_cutoff_picking +#: model:ir.model,name:account_cutoff_picking.model_account_cutoff +msgid "Account Cut-off" +msgstr "Scritture di fine periodo" + +#. module: account_cutoff_picking +#: model:ir.model.fields,field_description:account_cutoff_picking.field_account_cutoff__picking_interval_days +#: model:ir.model.fields,field_description:account_cutoff_picking.field_res_company__default_cutoff_picking_interval_days +#: model:ir.model.fields,field_description:account_cutoff_picking.field_res_config_settings__dft_cutoff_picking_interval_days +msgid "Analysis Interval" +msgstr "Intervallo analisi" + +#. module: account_cutoff_picking +#: model:ir.model,name:account_cutoff_picking.model_res_company +msgid "Companies" +msgstr "Aziende" + +#. module: account_cutoff_picking +#: model:ir.model,name:account_cutoff_picking.model_res_config_settings +msgid "Config Settings" +msgstr "Impostazioni di configurazione" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +"Missing expense account on product '%(product)s' or on its related product " +"category '%(categ)s'." +msgstr "" +"Conto di costo mancante per il prodotto '%(product)s' o per la categoria " +"prodotto correlata '%(categ)s'." + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +"Missing income account on product '%(product)s' or on its related product " +"category '%(categ)s'." +msgstr "" +"Conto di ricavo mancante per il prodotto '%(product)s' o per la categoria " +"prodotto correlata '%(categ)s'." + +#. module: account_cutoff_picking +#: model_terms:ir.ui.view,arch_db:account_cutoff_picking.res_config_settings_view_form +msgid "Picking Analysis Interval" +msgstr "Intervallo analisi prelievi" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff delivered quantity details:" +msgstr "Dettagli quantità consegnata pre-limite:" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff delivered quantity minus invoiced quantity:" +msgstr "Quantità consegnata pre-limite meno la quantità fatturata:" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff delivered quantity:" +msgstr "Quantità consegnata pre-limite:" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff invoiced quantity details:" +msgstr "Dettagli quantità fatturata pre-limite:" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff invoiced quantity minus delivered quantity:" +msgstr "Dettagli quantità fatturata pre-limite meno quantità consegnata:" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff invoiced quantity:" +msgstr "Quantità fatturata pre-limite:" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +"Purchase order %(order)s confirmed on %(confirm_date)s\n" +"Purchase Order Line: %(order_line)s (ordered qty: %(qty)s %(uom)s)" +msgstr "" +"Ordine acquisto %(order)s confermato il %(confirm_date)s\n" +"Riga ordine consegna: %(order_line)s (q.tà ordinata: %(qty)s %(uom)s)" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +"Sale order %(order)s confirmed on %(confirm_date)s\n" +"Sale Order Line: %(order_line)s (ordered qty: %(qty)s %(uom)s)" +msgstr "" +"Ordine di vendita %(order)s confermato il %(confirm_date)s\n" +"Riga ordine di vendita: %(order_line)s (q.tà ordinata: %(qty)s %(uom)s)" + +#. module: account_cutoff_picking +#: model:ir.model.constraint,message:account_cutoff_picking.constraint_account_cutoff_picking_interval_days_positive +#: model:ir.model.constraint,message:account_cutoff_picking.constraint_res_company_cutoff_picking_interval_days_positive +msgid "The value of the field 'Analysis Interval' must be strictly positive." +msgstr "" +"Il valore del campo \"Intervallo analisi\" deve essere strettamente positivo." + +#. module: account_cutoff_picking +#: model:ir.model.fields,help:account_cutoff_picking.field_res_company__default_cutoff_picking_interval_days +#: model:ir.model.fields,help:account_cutoff_picking.field_res_config_settings__dft_cutoff_picking_interval_days +msgid "" +"To generate the accrual/prepaid revenue/expenses based on picking dates vs " +"invoice dates, Odoo will analyse all the pickings/invoices from N days " +"before the cutoff date up to the cutoff date. N is the Analysis Interval. If " +"you increase the analysis interval, Odoo will take more time to generate the " +"cutoff lines." +msgstr "" +"Per generare i ricavi/spese accumulati/prepagati in base alle date dei " +"prelievi rispetto alle date fattura, Odoo analizzerà tutti prelievi/fatture " +"da N giorni prima la data limite fino alla data limite. N è l'intervallo di " +"analisi. Se si incrementa l'intervallo di analisi, Odoo imiegherà più tempo " +"per generare le righe limite." + +#. module: account_cutoff_picking +#: model:ir.model.fields,help:account_cutoff_picking.field_account_cutoff__picking_interval_days +msgid "" +"To generate the cutoffs based on picking dates vs invoice dates, Odoo will " +"analyse all the pickings/invoices from N days before the cutoff date up to " +"the cutoff date. N is the Analysis Interval. If you increase the analysis " +"interval, Odoo will take more time to generate the cutoff lines." +msgstr "" +"Per generare le soglie in base alle date dei prelievi rispetto alle date " +"fattura, Odoo analizzerà tutti prelievi/fatture da N giorni prima la data " +"limite fino alla data limite. N è l'intervallo di analisi. Se si incrementa " +"l'intervallo di analisi, Odoo imiegherà più tempo per generare le righe " +"limite." + +#. module: account_cutoff_picking +#: model_terms:ir.ui.view,arch_db:account_cutoff_picking.account_cutoff_form +#: model_terms:ir.ui.view,arch_db:account_cutoff_picking.res_config_settings_view_form +msgid "days" +msgstr "giorni" + +#~ msgid "%s: %s" +#~ msgstr "%s: %s" + +#~ msgid "Display Name" +#~ msgstr "Nome visualizzato" + +#~ msgid "ID" +#~ msgstr "ID" + +#~ msgid "Last Modified on" +#~ msgstr "Ultima modifica il" + +#~ msgid "" +#~ "To generate the accruals based on pickings, Odoo will analyse all the " +#~ "pickings between the cutoff date and N days before. N is the Picking " +#~ "Analysis Interval." +#~ msgstr "" +#~ "Per generare le competenze in base ai prelievi, Odoo analizza tutti " +#~ "quelli tra la data di separazione e gli N giorni precedenti. N " +#~ "corrisponde all'intervallo di analisi dei prelievi." diff --git a/account_cutoff_picking/i18n/sv.po b/account_cutoff_picking/i18n/sv.po new file mode 100644 index 00000000000..8dfd93d9ec3 --- /dev/null +++ b/account_cutoff_picking/i18n/sv.po @@ -0,0 +1,182 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_cutoff_picking +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-06-04 16:36+0000\n" +"Last-Translator: jakobkrabbe \n" +"Language-Team: none\n" +"Language: sv\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_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +" • %(qty)s %(uom)s (picking %(picking)s transfered on %(date)s from " +"%(src_location)s to %(dest_location)s)" +msgstr "" +" - %(qty)s %(uom)s (plockning %(picking)s överförd på %(date)s från " +"%(src_location)s till %(dest_location)s)" + +#. module: account_cutoff_picking +#: model:ir.model,name:account_cutoff_picking.model_account_cutoff +msgid "Account Cut-off" +msgstr "Avstängning av konto" + +#. module: account_cutoff_picking +#: model:ir.model.fields,field_description:account_cutoff_picking.field_account_cutoff__picking_interval_days +#: model:ir.model.fields,field_description:account_cutoff_picking.field_res_company__default_cutoff_picking_interval_days +#: model:ir.model.fields,field_description:account_cutoff_picking.field_res_config_settings__dft_cutoff_picking_interval_days +msgid "Analysis Interval" +msgstr "Analysintervall" + +#. module: account_cutoff_picking +#: model:ir.model,name:account_cutoff_picking.model_res_company +msgid "Companies" +msgstr "Företag" + +#. module: account_cutoff_picking +#: model:ir.model,name:account_cutoff_picking.model_res_config_settings +msgid "Config Settings" +msgstr "Konfigureringsinställningar" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +"Missing expense account on product '%(product)s' or on its related product " +"category '%(categ)s'." +msgstr "" +"Saknar kostnadskonto på produkten '%(product)s' eller på dess relaterade " +"produktkategori '%(categ)s'." + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +"Missing income account on product '%(product)s' or on its related product " +"category '%(categ)s'." +msgstr "" +"Saknar inkomstkonto på produkten '%(product)s' eller på dess relaterade " +"produktkategori '%(categ)s'." + +#. module: account_cutoff_picking +#: model_terms:ir.ui.view,arch_db:account_cutoff_picking.res_config_settings_view_form +msgid "Picking Analysis Interval" +msgstr "Välja analysintervall" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff delivered quantity details:" +msgstr "Detaljer om levererad kvantitet före avbrytande:" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff delivered quantity minus invoiced quantity:" +msgstr "Levererad kvantitet före cutoff minus fakturerad kvantitet:" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff delivered quantity:" +msgstr "Levererad kvantitet före cutoff:" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff invoiced quantity details:" +msgstr "Uppgifter om fakturerad kvantitet före avbrott:" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff invoiced quantity minus delivered quantity:" +msgstr "Fakturerad kvantitet före kapning minus levererad kvantitet:" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "Pre-cutoff invoiced quantity:" +msgstr "Fakturerad kvantitet före avbrott:" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +"Purchase order %(order)s confirmed on %(confirm_date)s\n" +"Purchase Order Line: %(order_line)s (ordered qty: %(qty)s %(uom)s)" +msgstr "" +"Inköpsorder %(order)s bekräftad den %(confirm_date)s\n" +"Inköpsorderrad: %(order_line)s (beställt antal: %(qty)s %(uom)s)" + +#. module: account_cutoff_picking +#. odoo-python +#: code:addons/account_cutoff_picking/models/account_cutoff.py:0 +#, python-format +msgid "" +"Sale order %(order)s confirmed on %(confirm_date)s\n" +"Sale Order Line: %(order_line)s (ordered qty: %(qty)s %(uom)s)" +msgstr "" +"Försäljningsorder %(order)s bekräftad den %(confirm_date)s\n" +"Försäljningsorderrad: %(order_line)s (beställt antal: %(qty)s %(uom)s)" + +#. module: account_cutoff_picking +#: model:ir.model.constraint,message:account_cutoff_picking.constraint_account_cutoff_picking_interval_days_positive +#: model:ir.model.constraint,message:account_cutoff_picking.constraint_res_company_cutoff_picking_interval_days_positive +msgid "The value of the field 'Analysis Interval' must be strictly positive." +msgstr "Värdet i fältet \"Analysintervall\" måste vara positivt." + +#. module: account_cutoff_picking +#: model:ir.model.fields,help:account_cutoff_picking.field_res_company__default_cutoff_picking_interval_days +#: model:ir.model.fields,help:account_cutoff_picking.field_res_config_settings__dft_cutoff_picking_interval_days +msgid "" +"To generate the accrual/prepaid revenue/expenses based on picking dates vs " +"invoice dates, Odoo will analyse all the pickings/invoices from N days " +"before the cutoff date up to the cutoff date. N is the Analysis Interval. If" +" you increase the analysis interval, Odoo will take more time to generate " +"the cutoff lines." +msgstr "" +"För att generera upplupna/förutbetalda intäkter/kostnader baserat på " +"plockdatum vs fakturadatum, kommer Odoo att analysera alla plockningar/" +"fakturor från N dagar före brytdatumet fram till brytdatumet. N är " +"analysintervallet. Om du ökar analysintervallet kommer Odoo att ta mer tid " +"på sig att generera gränslinjerna." + +#. module: account_cutoff_picking +#: model:ir.model.fields,help:account_cutoff_picking.field_account_cutoff__picking_interval_days +msgid "" +"To generate the cutoffs based on picking dates vs invoice dates, Odoo will " +"analyse all the pickings/invoices from N days before the cutoff date up to " +"the cutoff date. N is the Analysis Interval. If you increase the analysis " +"interval, Odoo will take more time to generate the cutoff lines." +msgstr "" +"För att generera gränsvärdena baserat på plockdatum vs fakturadatum kommer " +"Odoo att analysera alla plockningar/fakturor från N dagar före gränsdatumet " +"fram till gränsdatumet. N är analysintervallet. Om du ökar analysintervallet " +"kommer Odoo att ta mer tid på sig att generera gränslinjerna." + +#. module: account_cutoff_picking +#: model_terms:ir.ui.view,arch_db:account_cutoff_picking.account_cutoff_form +#: model_terms:ir.ui.view,arch_db:account_cutoff_picking.res_config_settings_view_form +msgid "days" +msgstr "dagar" diff --git a/account_cutoff_picking/images/accrued_expense_done.jpg b/account_cutoff_picking/images/accrued_expense_done.jpg new file mode 100644 index 00000000000..f34985d5c84 Binary files /dev/null and b/account_cutoff_picking/images/accrued_expense_done.jpg differ diff --git a/account_cutoff_picking/images/accrued_expense_draft.jpg b/account_cutoff_picking/images/accrued_expense_draft.jpg new file mode 100644 index 00000000000..7a0033677cc Binary files /dev/null and b/account_cutoff_picking/images/accrued_expense_draft.jpg differ diff --git a/account_cutoff_picking/images/accrued_expense_journal_entry.jpg b/account_cutoff_picking/images/accrued_expense_journal_entry.jpg new file mode 100644 index 00000000000..baddc64314c Binary files /dev/null and b/account_cutoff_picking/images/accrued_expense_journal_entry.jpg differ diff --git a/account_cutoff_picking/models/__init__.py b/account_cutoff_picking/models/__init__.py new file mode 100644 index 00000000000..260a2b786ec --- /dev/null +++ b/account_cutoff_picking/models/__init__.py @@ -0,0 +1,2 @@ +from . import res_company +from . import account_cutoff diff --git a/account_cutoff_picking/models/account_cutoff.py b/account_cutoff_picking/models/account_cutoff.py new file mode 100644 index 00000000000..496881f8943 --- /dev/null +++ b/account_cutoff_picking/models/account_cutoff.py @@ -0,0 +1,491 @@ +# Copyright 2013-2021 Akretion France (http://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from datetime import datetime + +import pytz +from dateutil.relativedelta import relativedelta + +from odoo import api, fields, models +from odoo.exceptions import UserError +from odoo.tools import float_compare, float_is_zero +from odoo.tools.misc import format_date, format_datetime, formatLang + + +class AccountCutoff(models.Model): + _inherit = "account.cutoff" + + picking_interval_days = fields.Integer( + string="Analysis Interval", + default=lambda self: self._default_picking_interval_days(), + tracking=True, + help="To generate the cutoffs based on picking " + "dates vs invoice dates, Odoo will analyse all the pickings/invoices from " + "N days before the cutoff date up to the cutoff date. " + "N is the Analysis Interval. If you increase the analysis interval, " + "Odoo will take more time to generate the cutoff lines.", + ) + + _sql_constraints = [ + ( + "picking_interval_days_positive", + "CHECK(picking_interval_days > 0)", + "The value of the field 'Analysis Interval' must be strictly positive.", + ) + ] + + @api.model + def _default_picking_interval_days(self): + return self.env.company.default_cutoff_picking_interval_days + + def picking_prepare_cutoff_line(self, vdict, account_mapping): + dpo = self.env["decimal.precision"] + qty_prec = dpo.precision_get("Product Unit of Measure") + if self.cutoff_type in ("accrued_expense", "accrued_revenue"): + qty = vdict["precut_delivered_qty"] - vdict["precut_invoiced_qty"] + qty_label = self.env._( + "Pre-cutoff delivered quantity minus invoiced quantity:" + ) + elif self.cutoff_type in ("prepaid_expense", "prepaid_revenue"): + qty = vdict["precut_invoiced_qty"] - vdict["precut_delivered_qty"] + qty_label = self.env._( + "Pre-cutoff invoiced quantity minus delivered quantity:" + ) + + if float_compare(qty, 0, precision_digits=qty_prec) <= 0: + return False + + company_currency = self.company_currency_id + currency = vdict["currency"] + sign = self.cutoff_type in ("accrued_expense", "prepaid_revenue") and -1 or 1 + amount = qty * vdict["price_unit"] * sign + amount_company_currency = vdict["currency"]._convert( + amount, company_currency, self.company_id, self.cutoff_date + ) + + # Use account mapping + account_id = vdict["account_id"] + if account_id in account_mapping: + cutoff_account_id = account_mapping[account_id] + else: + cutoff_account_id = account_id + uom_name = vdict["product"].uom_id.name + notes = vdict["notes"] + precut_delivered_qty_fl = formatLang( + self.env, vdict.get("precut_delivered_qty", 0), dp="Product Unit of Measure" + ) + notes += ( + "\n" + + self.env._("Pre-cutoff delivered quantity:") + + f" {precut_delivered_qty_fl} {uom_name}" + ) + if vdict.get("precut_delivered_logs"): + param = "\n".join(vdict["precut_delivered_logs"]) + notes += ( + "\n" + + self.env._("Pre-cutoff delivered quantity details:") + + f"\n{param}" + ) + precut_invoiced_qty_fl = formatLang( + self.env, vdict.get("precut_invoiced_qty", 0), dp="Product Unit of Measure" + ) + notes += ( + "\n" + + self.env._("Pre-cutoff invoiced quantity:") + + f" {precut_invoiced_qty_fl} {uom_name}" + ) + if vdict.get("precut_invoiced_logs"): + param = "\n".join(vdict["precut_invoiced_logs"]) + notes += ( + "\n" + + self.env._("Pre-cutoff invoiced quantity details:") + + f"\n{param}" + ) + qty_fl = formatLang(self.env, qty, dp="Product Unit of Measure") + notes += f"\n{qty_label} {qty_fl} {uom_name}" + + vals = { + "parent_id": self.id, + "partner_id": vdict["partner"].id, + "name": vdict["name"], + "account_id": account_id, + "cutoff_account_id": cutoff_account_id, + "analytic_distribution": vdict["analytic_distribution"], + "currency_id": vdict["currency"].id, + "quantity": qty, + "price_unit": vdict["price_unit"], + "amount": amount, + "cutoff_amount": amount_company_currency, + "price_origin": vdict.get("price_origin"), + "notes": notes, + } + + if ( + self.cutoff_type in ("accrued_expense", "accrued_revenue") + and vdict["taxes"] + and self.company_id.accrual_taxes + ): + # vdict["price_unit"] is a price without tax, + # so I set handle_price_include=False + tax_compute_all_res = vdict["taxes"].compute_all( + vdict["price_unit"], + currency=currency, + quantity=qty * sign, + product=vdict["product"], + partner=vdict["partner"], + handle_price_include=False, + ) + vals["tax_line_ids"] = self._prepare_tax_lines( + tax_compute_all_res, self.company_currency_id + ) + return vals + + def order_line_update_oline_dict( + self, order_line, order_type, oline_dict, cutoff_datetime + ): + assert order_line not in oline_dict + order = order_line.order_id # same on PO and SO + oline_dict[order_line] = { + "precut_delivered_qty": 0.0, # in product_uom + "precut_delivered_logs": [], + "precut_invoiced_qty": 0.0, # in product_uom + "precut_invoiced_logs": [], + "name": ": ".join([order.name, order_line.name]), + "product": order_line.product_id, + "partner": order.partner_id.commercial_partner_id, + "notes": "", + "price_unit": 0.0, + "price_origin": False, + "currency": False, + "analytic_distribution": False, + "account_id": False, + "taxes": False, + } + self.order_line_update_oline_dict_from_stock_moves( + order_line, order_type, oline_dict, cutoff_datetime + ) + self.order_line_update_oline_dict_from_invoice_lines( + order_line, order_type, oline_dict, cutoff_datetime + ) + if not oline_dict[order_line]["price_origin"]: + self.order_line_update_oline_dict_price_fallback( + order_line, order_type, oline_dict + ) + + def order_line_update_oline_dict_from_stock_moves( + self, order_line, order_type, oline_dict, cutoff_datetime + ): + wdict = oline_dict[order_line] + # These fields/methods have the same name on PO and SO + order = order_line.order_id + product = order_line.product_id + product_uom = product.uom_id + outgoing_moves, incoming_moves = order_line._get_outgoing_incoming_moves() + if order_type == "purchase": + ordered_qty = order_line.product_uom._compute_quantity( + order_line.product_qty, product_uom + ) + wdict["notes"] = self.env._( + "Purchase order %(order)s confirmed on %(confirm_date)s\n" + "Purchase Order Line: %(order_line)s (ordered qty: %(qty)s %(uom)s)" + ) % { + "order": order.name, + "confirm_date": format_datetime(self.env, order.date_approve), + "order_line": order_line.name, + "qty": formatLang(self.env, ordered_qty, dp="Product Unit of Measure"), + "uom": product_uom.name, + } + elif order_type == "sale": + ordered_qty = order_line.product_uom._compute_quantity( + order_line.product_uom_qty, product_uom + ) + wdict["notes"] = self.env._( + "Sale order %(order)s confirmed on %(confirm_date)s\n" + "Sale Order Line: %(order_line)s (ordered qty: %(qty)s %(uom)s)" + ) % { + "order": order.name, + "confirm_date": format_datetime(self.env, order.date_order), + "order_line": order_line.name, + "qty": formatLang(self.env, ordered_qty, dp="Product Unit of Measure"), + "uom": product_uom.name, + } + move_logs = [] + for out_move in outgoing_moves.filtered( + lambda m: m.state == "done" and m.date <= cutoff_datetime + ): + sign = order_type == "purchase" and -1 or 1 + move_qty = out_move.product_uom._compute_quantity( + out_move.quantity * sign, product_uom + ) + move_logs.append((out_move, move_qty)) + for in_move in incoming_moves.filtered( + lambda m: m.state == "done" and m.date <= cutoff_datetime + ): + sign = order_type == "sale" and -1 or 1 + move_qty = in_move.product_uom._compute_quantity( + in_move.quantity * sign, product_uom + ) + move_logs.append((in_move, move_qty)) + move_logs_sorted = sorted(move_logs, key=lambda to_sort: to_sort[0].date) + for move, move_qty_signed in move_logs_sorted: + wdict["precut_delivered_qty"] += move_qty_signed + move_qty_signed_formatted = formatLang( + self.env, move_qty_signed, dp="Product Unit of Measure" + ) + wdict["precut_delivered_logs"].append( + self.env._( + " • %(qty)s %(uom)s (picking %(picking)s transfered on %(date)s " + "from %(src_location)s to %(dest_location)s)" + ) + % { + "qty": move_qty_signed_formatted, + "uom": move.product_id.uom_id.name, + "picking": move.picking_id.name or "none", + "date": format_datetime(self.env, move.date), + "src_location": move.location_id.display_name, + "dest_location": move.location_dest_id.display_name, + } + ) + + def order_line_update_oline_dict_from_invoice_lines( + self, order_line, order_type, oline_dict, cutoff_datetime + ): + wdict = oline_dict[order_line] + dpo = self.env["decimal.precision"] + qty_prec = dpo.precision_get("Product Unit of Measure") + move_type2label = dict( + self.env["account.move"].fields_get("move_type", "selection")["move_type"][ + "selection" + ] + ) + # These fields have the same name on PO and SO + product = order_line.product_id + product_uom = product.uom_id + if self.source_move_state == "posted": + ilines = order_line.invoice_lines.filtered( + lambda x: x.parent_state == "posted" + ) + else: + ilines = order_line.invoice_lines.filtered( + lambda x: x.parent_state in ("draft", "posted") + ) + for iline in ilines: + invoice = iline.move_id + if not float_is_zero(iline.quantity, precision_digits=qty_prec): + sign = invoice.move_type in ("out_refund", "in_refund") and -1 or 1 + iline_qty_puom = iline.product_uom_id._compute_quantity( + iline.quantity * sign, product_uom + ) + if invoice.date <= self.cutoff_date: + wdict["precut_invoiced_qty"] += iline_qty_puom + iline_qty_puom_formatted = formatLang( + self.env, iline_qty_puom, dp="Product Unit of Measure" + ) + qty = iline_qty_puom_formatted + uom = iline.product_id.uom_id.name + move_type = move_type2label[invoice.move_type] + move_name = invoice.name + date = format_date(self.env, invoice.date) + wdict["precut_invoiced_logs"].append( + f" • {qty} {uom} ({move_type} {move_name} dated {date})" + ) + # Most recent invoice line used for price_unit, account,... + wdict["price_unit"] = iline.price_subtotal / iline_qty_puom + wdict["price_origin"] = invoice.name + wdict["currency"] = invoice.currency_id + wdict["account_id"] = iline.account_id.id + wdict["analytic_distribution"] = iline.analytic_distribution + wdict["taxes"] = iline.tax_ids + + def order_line_update_oline_dict_price_fallback( + self, order_line, order_type, oline_dict + ): + wdict = oline_dict[order_line] + order = order_line.order_id + product = order_line.product_id + if order_type == "purchase": + oline_qty_puom = order_line.product_uom._compute_quantity( + order_line.product_qty, product.uom_id + ) + wdict["price_unit"] = order_line.price_subtotal / oline_qty_puom + wdict["price_origin"] = order.name + wdict["currency"] = order.currency_id + wdict["analytic_distribution"] = order_line.analytic_distribution + wdict["taxes"] = order_line.taxes_id + account = product._get_product_accounts()["expense"] + if not account: + raise UserError( + self.env._( + "Missing expense account on product '%(product)s' or on its " + "related product category '%(categ)s'." + ) + % { + "product": product.display_name, + "categ": product.categ_id.display_name, + } + ) + wdict["account_id"] = order.fiscal_position_id.map_account(account).id + elif order_type == "sale": + oline_qty_puom = order_line.product_uom._compute_quantity( + order_line.product_uom_qty, product.uom_id + ) + wdict["price_unit"] = order_line.price_subtotal / oline_qty_puom + wdict["price_origin"] = order.name + wdict["currency"] = order.currency_id + wdict["analytic_distribution"] = order_line.analytic_distribution + wdict["taxes"] = order_line.tax_id + account = product._get_product_accounts()["income"] + if not account: + raise UserError( + self.env._( + "Missing income account on product '%(product)s' or on its " + "related product category '%(categ)s'." + ) + % { + "product": product.display_name, + "categ": product.categ_id.display_name, + } + ) + wdict["account_id"] = order.fiscal_position_id.map_account(account).id + + def stock_move_update_oline_dict(self, move_line, oline_dict, cutoff_datetime): + dpo = self.env["decimal.precision"] + qty_prec = dpo.precision_get("Product Unit of Measure") + if self.cutoff_type == "accrued_expense": + if ( + move_line.purchase_line_id + and move_line.purchase_line_id not in oline_dict + and not float_is_zero( + move_line.purchase_line_id.product_qty, precision_digits=qty_prec + ) + ): + self.order_line_update_oline_dict( + move_line.purchase_line_id, "purchase", oline_dict, cutoff_datetime + ) + elif self.cutoff_type == "accrued_revenue": + if ( + move_line.sale_line_id + and move_line.sale_line_id not in oline_dict + and not float_is_zero( + move_line.sale_line_id.product_uom_qty, precision_digits=qty_prec + ) + ): + self.order_line_update_oline_dict( + move_line.sale_line_id, "sale", oline_dict, cutoff_datetime + ) + + def invoice_line_update_oline_dict(self, inv_line, oline_dict, cutoff_datetime): + dpo = self.env["decimal.precision"] + qty_prec = dpo.precision_get("Product Unit of Measure") + if self.cutoff_type == "prepaid_expense": + if ( + inv_line.purchase_line_id + and inv_line.purchase_line_id not in oline_dict + and not float_is_zero( + inv_line.purchase_line_id.product_qty, precision_digits=qty_prec + ) + ): + self.order_line_update_oline_dict( + inv_line.purchase_line_id, "purchase", oline_dict, cutoff_datetime + ) + elif self.cutoff_type == "prepaid_revenue": + for so_line in inv_line.sale_line_ids: + if so_line not in oline_dict and not float_is_zero( + so_line.product_uom_qty, precision_digits=qty_prec + ): + self.order_line_update_oline_dict( + so_line, "sale", oline_dict, cutoff_datetime + ) + + def get_lines(self): + res = super().get_lines() + aclo = self.env["account.cutoff.line"] + + account_mapping = self._get_mapping_dict() + cutoff_type = self.cutoff_type + cutoff_datetime = self._get_cutoff_datetime() + + oline_dict = {} # order line dict + # key = PO line or SO line recordset + # value = { + # 'precut_delivered_qty': 1.0, + # 'precut_invoiced_qty': 0.0, + # 'price_unit': 12.42, + # } + + # ACCRUAL : + # starting point : picking + # then, go to order line. From order line, go to stock moves and invoices lines + # => gen cutoff line if precut_delivered_qty - precut_invoiced_qty > 0 + # PREPAID : + # starting point : invoice + # then, go to order line. From order line, go to stock moves and invoices lines + # => gen cutoff line if precut_invoiced_qty - precut_delivered_qty > 0 + + # ACCURAL + if cutoff_type in ("accrued_revenue", "accrued_expense"): + pick_type_map = { + "accrued_revenue": "outgoing", + "accrued_expense": "incoming", + } + + min_date_dt = cutoff_datetime - relativedelta( + days=self.picking_interval_days + ) + + pickings = self.env["stock.picking"].search( + [ + ("picking_type_code", "=", pick_type_map[cutoff_type]), + ("state", "=", "done"), + ("date_done", "<=", cutoff_datetime), + ("date_done", ">=", min_date_dt), + ("company_id", "=", self.company_id.id), + ] + ) + + for p in pickings: + for move in p.move_ids.filtered(lambda m: m.state == "done"): + self.stock_move_update_oline_dict(move, oline_dict, cutoff_datetime) + elif cutoff_type in ("prepaid_revenue", "prepaid_expense"): + move_type_map = { + "prepaid_revenue": ("out_invoice", "out_refund"), + "prepaid_expense": ("in_invoice", "in_refund"), + } + min_date = self.cutoff_date - relativedelta(days=self.picking_interval_days) + inv_domain = [ + ("move_type", "in", move_type_map[cutoff_type]), + ("date", "<=", self.cutoff_date), + ("date", ">=", min_date), + ("company_id", "=", self.company_id.id), + ] + if self.source_move_state == "posted": + inv_domain.append(("state", "=", "posted")) + else: + inv_domain.append(("state", "in", ("draft", "posted"))) + invoices = self.env["account.move"].search(inv_domain) + for invoice in invoices: + for iline in invoice.invoice_line_ids.filtered( + lambda x: x.display_type == "product" + and x.product_id.type in ("product", "consu") + ): + self.invoice_line_update_oline_dict( + iline, oline_dict, cutoff_datetime + ) + + # from pprint import pprint + # pprint(oline_dict) + for vdict in oline_dict.values(): + vals = self.picking_prepare_cutoff_line(vdict, account_mapping) + if vals: + aclo.create(vals) + return res + + def _get_cutoff_datetime(self): + self.ensure_one() + cutoff_date = datetime.combine(self.cutoff_date, datetime.max.time()) + tz = self.env.user.tz and pytz.timezone(self.env.user.tz) or pytz.utc + cutoff_datetime_aware = tz.localize(cutoff_date) + cutoff_datetime_utc = cutoff_datetime_aware.astimezone(pytz.utc) + cutoff_datetime_utc_naive = cutoff_datetime_utc.replace(tzinfo=None) + return cutoff_datetime_utc_naive diff --git a/account_cutoff_picking/models/res_company.py b/account_cutoff_picking/models/res_company.py new file mode 100644 index 00000000000..9ce17a0a5ba --- /dev/null +++ b/account_cutoff_picking/models/res_company.py @@ -0,0 +1,27 @@ +# Copyright 2020-2021 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 ResCompany(models.Model): + _inherit = "res.company" + + default_cutoff_picking_interval_days = fields.Integer( + string="Analysis Interval", + help="To generate the accrual/prepaid revenue/expenses based on picking " + "dates vs invoice dates, Odoo will analyse all the pickings/invoices from " + "N days before the cutoff date up to the cutoff date. " + "N is the Analysis Interval. If you increase the analysis interval, " + "Odoo will take more time to generate the cutoff lines.", + default=30, + ) + + _sql_constraints = [ + ( + "cutoff_picking_interval_days_positive", + "CHECK(default_cutoff_picking_interval_days > 0)", + "The value of the field 'Analysis Interval' must be strictly positive.", + ) + ] diff --git a/account_cutoff_picking/pyproject.toml b/account_cutoff_picking/pyproject.toml new file mode 100644 index 00000000000..4231d0cccb3 --- /dev/null +++ b/account_cutoff_picking/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/account_cutoff_picking/readme/CONFIGURE.md b/account_cutoff_picking/readme/CONFIGURE.md new file mode 100644 index 00000000000..17bd0dc7925 --- /dev/null +++ b/account_cutoff_picking/readme/CONFIGURE.md @@ -0,0 +1,2 @@ +For configuration instructions, refer to the README of the module +*account_cutoff_base*. diff --git a/account_cutoff_picking/readme/CONTRIBUTORS.md b/account_cutoff_picking/readme/CONTRIBUTORS.md new file mode 100644 index 00000000000..b61afe5d01b --- /dev/null +++ b/account_cutoff_picking/readme/CONTRIBUTORS.md @@ -0,0 +1 @@ +- Alexis de Lattre \<\> diff --git a/account_cutoff_picking/readme/CREDITS.md b/account_cutoff_picking/readme/CREDITS.md new file mode 100644 index 00000000000..9ad870e3edb --- /dev/null +++ b/account_cutoff_picking/readme/CREDITS.md @@ -0,0 +1,2 @@ +The migration of this module from 16.0 to 17.0 was financially supported +by Camptocamp \ No newline at end of file diff --git a/account_cutoff_picking/readme/DESCRIPTION.md b/account_cutoff_picking/readme/DESCRIPTION.md new file mode 100644 index 00000000000..eeb3d3f4c45 --- /dev/null +++ b/account_cutoff_picking/readme/DESCRIPTION.md @@ -0,0 +1,50 @@ +This module generates expense/revenue accruals and prepaid +expense/revenue based on the status of orders, pickings and invoices. +The module is named *account_cutoff_accrual_picking* because it +initially only supported accruals ; support for prepaid expense/revenue +was added later (it should be renamed in later versions). + +To understand the behavior of this module, let's take the example of an +expense accrual. When you click on the button *Re-Generate Lines* of an +*Expense Accrual*: + +1. Odoo will look for all incoming picking in Done state with a + *Transfer Date* \<= *Cut-off Date*. For performance reasons, by + default, the incoming picking dated before *Cut-off Date* minus 30 + days will not be taken into account (this limit is configurable via + the field *Picking Analysis*). It will go to the stock moves of + those pickings and see if they are linked to a purchase order line. +2. Once this analysis is completed, Odoo has a list of purchase order + lines to analyse for potential expense accrual. +3. For each of these purchase order lines, Odoo will: + - scan the related stock moves in *done* state and check their + transfer date, + - scan the related invoices lines and check their invoice date. +4. If, for a particular purchase order line, the quantity of products + received before the cutoff-date (or on the same day) minus the + quantity of products invoiced before the cut-off date (or on the + same day) is positive, Odoo will generate a cut-off line. + +Now, let's take the example of a prepaid expense. When you click on the +button *Re-Generate Lines* of a *Prepaid Expense*: + +1. Odoo will look for all vendor bills dated before (or equal to) + *Cut-off Date*. For performance reasons, by default, the vendor + bills dated before *Cut-off Date* minus 30 days will not be taken + into account (this limit is configurable via the field *Picking + Analysis*). It will go to the invoice lines of those vendor bills + and see if they are linked to a purchase order line. +2. Once this analysis is completed, Odoo has a list of purchase order + lines to analyse for potential prepaid expense. +3. For each of these purchase order lines, Odoo will: + - scan the related stock moves in *done* state and check their + transfer date, + - scan the related invoices lines and check their invoice date. +4. If, for a particular purchase order line, the quantity of products + invoiced before the cutoff-date (or on the same day) minus the + quantity of products received before the cut-off date (or on the + same day) is positive, Odoo will generate a cut-off line. + +This module should work well with multiple units of measure (including +products purchased and invoiced in different units of measure) and in +multi-currency. diff --git a/account_cutoff_picking/static/description/icon.png b/account_cutoff_picking/static/description/icon.png new file mode 100644 index 00000000000..3a0328b516c Binary files /dev/null and b/account_cutoff_picking/static/description/icon.png differ diff --git a/account_cutoff_picking/static/description/index.html b/account_cutoff_picking/static/description/index.html new file mode 100644 index 00000000000..7fe8122e644 --- /dev/null +++ b/account_cutoff_picking/static/description/index.html @@ -0,0 +1,489 @@ + + + + + +Account Cut-off Picking + + + +
+

Account Cut-off Picking

+ + +

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

+

This module generates expense/revenue accruals and prepaid +expense/revenue based on the status of orders, pickings and invoices. +The module is named account_cutoff_accrual_picking because it +initially only supported accruals ; support for prepaid expense/revenue +was added later (it should be renamed in later versions).

+

To understand the behavior of this module, let’s take the example of an +expense accrual. When you click on the button Re-Generate Lines of an +Expense Accrual:

+
    +
  1. Odoo will look for all incoming picking in Done state with a +Transfer Date <= Cut-off Date. For performance reasons, by +default, the incoming picking dated before Cut-off Date minus 30 +days will not be taken into account (this limit is configurable via +the field Picking Analysis). It will go to the stock moves of those +pickings and see if they are linked to a purchase order line.
  2. +
  3. Once this analysis is completed, Odoo has a list of purchase order +lines to analyse for potential expense accrual.
  4. +
  5. For each of these purchase order lines, Odoo will:
      +
    • scan the related stock moves in done state and check their +transfer date,
    • +
    • scan the related invoices lines and check their invoice date.
    • +
    +
  6. +
  7. If, for a particular purchase order line, the quantity of products +received before the cutoff-date (or on the same day) minus the +quantity of products invoiced before the cut-off date (or on the same +day) is positive, Odoo will generate a cut-off line.
  8. +
+

Now, let’s take the example of a prepaid expense. When you click on the +button Re-Generate Lines of a Prepaid Expense:

+
    +
  1. Odoo will look for all vendor bills dated before (or equal to) +Cut-off Date. For performance reasons, by default, the vendor bills +dated before Cut-off Date minus 30 days will not be taken into +account (this limit is configurable via the field Picking +Analysis). It will go to the invoice lines of those vendor bills and +see if they are linked to a purchase order line.
  2. +
  3. Once this analysis is completed, Odoo has a list of purchase order +lines to analyse for potential prepaid expense.
  4. +
  5. For each of these purchase order lines, Odoo will:
      +
    • scan the related stock moves in done state and check their +transfer date,
    • +
    • scan the related invoices lines and check their invoice date.
    • +
    +
  6. +
  7. If, for a particular purchase order line, the quantity of products +invoiced before the cutoff-date (or on the same day) minus the +quantity of products received before the cut-off date (or on the same +day) is positive, Odoo will generate a cut-off line.
  8. +
+

This module should work well with multiple units of measure (including +products purchased and invoiced in different units of measure) and in +multi-currency.

+

Table of contents

+ +
+

Configuration

+

For configuration instructions, refer to the README of the module +account_cutoff_base.

+
+
+

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

+ +
+
+

Other credits

+

The migration of this module from 16.0 to 17.0 was financially supported +by Camptocamp

+
+
+

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_picking/static/src/img/icon.png b/account_cutoff_picking/static/src/img/icon.png new file mode 100644 index 00000000000..fb9eeb14752 Binary files /dev/null and b/account_cutoff_picking/static/src/img/icon.png differ diff --git a/account_cutoff_picking/views/account_cutoff.xml b/account_cutoff_picking/views/account_cutoff.xml new file mode 100644 index 00000000000..a1fc51165d4 --- /dev/null +++ b/account_cutoff_picking/views/account_cutoff.xml @@ -0,0 +1,25 @@ + + + + + accrual.picking.account_cutoff_form + account.cutoff + + + + + + + diff --git a/account_cutoff_picking/views/res_config_settings.xml b/account_cutoff_picking/views/res_config_settings.xml new file mode 100644 index 00000000000..f497b518ceb --- /dev/null +++ b/account_cutoff_picking/views/res_config_settings.xml @@ -0,0 +1,31 @@ + + + + + accrual.picking.account.config.form + res.config.settings + + + + +
+ days +
+
+
+
+
+
diff --git a/account_cutoff_picking/wizards/__init__.py b/account_cutoff_picking/wizards/__init__.py new file mode 100644 index 00000000000..0deb68c4680 --- /dev/null +++ b/account_cutoff_picking/wizards/__init__.py @@ -0,0 +1 @@ +from . import res_config_settings diff --git a/account_cutoff_picking/wizards/res_config_settings.py b/account_cutoff_picking/wizards/res_config_settings.py new file mode 100644 index 00000000000..edd95567e52 --- /dev/null +++ b/account_cutoff_picking/wizards/res_config_settings.py @@ -0,0 +1,16 @@ +# Copyright 2020-2021 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 ResConfigSettings(models.TransientModel): + _inherit = "res.config.settings" + + # I can't name it default_cutoff_accrual_picking_interval_days + # because 'default_' is a special prefix + dft_cutoff_picking_interval_days = fields.Integer( + related="company_id.default_cutoff_picking_interval_days", + readonly=False, + ) diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 00000000000..452dbdb1bb3 --- /dev/null +++ b/test-requirements.txt @@ -0,0 +1 @@ +odoo-addon-account_cutoff_base @ git+https://github.com/OCA/account-closing.git@refs/pull/311/head#subdirectory=account_cutoff_base