diff --git a/l10n_es_sigaus_account/README.rst b/l10n_es_sigaus_account/README.rst new file mode 100644 index 00000000000..b8f5eb4f28e --- /dev/null +++ b/l10n_es_sigaus_account/README.rst @@ -0,0 +1,166 @@ +==================== +SIGAUS - Facturación +==================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:f908f4dbd0a1bbbfb163b42dcae80a66019b600a45a7bbe337034d4892f99a97 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fl10n--spain-lightgray.png?logo=github + :target: https://github.com/OCA/l10n-spain/tree/17.0/l10n_es_sigaus_account + :alt: OCA/l10n-spain +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/l10n-spain-17-0/l10n-spain-17-0-l10n_es_sigaus_account + :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/l10n-spain&target_branch=17.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +El origen de SIGAUS responde a la iniciativa de los fabricantes de +lubricantes que, a través de su participación en este Sistema, cumplen +con las obligaciones establecidas en la normativa sobre aceites usados +(Real Decreto 679/2006, de 2 de junio, por el que se regula la gestión +de los aceites industriales usados). + +Este módulo permite el cálculo de la aportación SIGAUS en las facturas a +partir del peso de aquellos productos en los que se aplica. + +- Más información en https://www.sigaus.es + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +Se tienen que configurar los siguientes aspectos: + +- En la ficha del producto "Aportación SIGAUS (R.D. 679/2006)" + establecer el impuesto correspondiente. +- La configuración del precio de la aportación SIGAUS que se aplica + durante un periodo de tiempo se realiza desde Facturación > + Configuración > Aportación SIGAUS. En caso de no rellenar el campo + "Fecha hasta", el precio seleccionado se aplicará a partir de la fecha + indicada en "Fecha desde". El precio establecido dentro del periodo + marcado se utilizará siempre que se calcule la aportación SIGAUS en + las facturas. +- Es necesario indicar aquellas compañías en las que se aplicará la + aportación SIGAUS. Para ello, hay que acceder a la pestaña SIGAUS de + la configuración de la compañía y marcar la casilla "Habilitar + SIGAUS". Asimismo, es obligatorio indicar la fecha a partir de la que + la aportación SIGAUS se podrá aplicar en el campo "SIGAUS fecha + desde". No será posible calcular la aportación SIGAUS con fecha + anterior a la seleccionada en este campo. Cuando la opción "Habilitar + SIGAUS" está activada, se muestra el campo "Mostrar cantidades de + SIGAUS en líneas de informes" que, si está marcada, permite mostrar la + aportación SIGAUS de cada una de las líneas de facturas en los + informes. +- Las posiciones fiscales con las que se aplicará la aportación SIGAUS + tienen que indicarse. Para ello hay que acceder a Facturación > + Configuración > Posiciones Fiscales y marcar la casilla "Sujeto a + SIGAUS" en aquellas en las que se aplicará. +- Se puede establecer que los productos de ciertas categorías estén + sujetas a SIGAUS accediendo a la configuración de la categoría y + marcando la casilla "Sujeto a SIGAUS". +- Desde la ficha de los productos, pueden establecerse varias opciones + de sujeción a la aportación SIGAUS desde el campo "Sujeto a SIGAUS". + Existen tres opciones: + + - "Categoría": La aplicación o no de la aportación SIGAUS para ese + producto depende de si la casilla "Sujeto a SIGAUS" está o no + marcada en la categoría establecida. + - "Sí": Se aplica siempre la aportación SIGAUS, independientemente de + lo seleccionado en la categoría de producto. + - "No": No se aplica nunca la aportación SIGAUS, independientemente de + lo seleccionado en la categoría de producto. + +Cuando se calcule la aportación SIGAUS en facturas, se tendrá en cuenta +el peso de todos aquellos productos a los que se les aplica la +aportación SIGAUS para determinar el importe. + +- Todos los productos a los que se les aplica la aportación SIGAUS deben + tener un peso establecido. + +Usage +===== + +- El importe de la aportación SIGAUS se calculará a partir de los pesos + de aquellos productos sujetos a dicha aportación y el precio + establecido en "Aportación SIGAUS" según la fecha de factura o, en su + defecto, la fecha de creación. +- Los productos sujetos a aportación SIGAUS son los siguientes: + + - Aquellos que tienen establecida la opción "Sí" en el campo "Sujeto a + SIGAUS". + - Aquellos que tienen establecida la opción "Categoría" en el campo + "Sujeto a SIGAUS" y cuya categoría tenga marcada la opción "Sujeto a + SIGAUS". + +- Se mostrará un mensaje en el chatter si al calcular la aportación + SIGAUS, alguno de los productos sujetos no tiene un peso establecido. +- Si se desmarca la opción "Sujeto a SIGAUS", no se aplicará la + aportación SIGAUS. + +Known issues / Roadmap +====================== + +- El módulo no está preparado para añadir automáticamente las líneas de + aportación SIGAUS a los pedidos procedentes del comercio online. + +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 +------- + +* Sygel + +Contributors +------------ + +- `Sygel `__: + + - Manuel Regidor + - Harald Panten + - Valentín Vinagre + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/l10n-spain `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/l10n_es_sigaus_account/__init__.py b/l10n_es_sigaus_account/__init__.py new file mode 100644 index 00000000000..5e717cd67c5 --- /dev/null +++ b/l10n_es_sigaus_account/__init__.py @@ -0,0 +1,6 @@ +# Copyright 2023 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import models +from . import wizard +from .hooks import pre_init_hook diff --git a/l10n_es_sigaus_account/__manifest__.py b/l10n_es_sigaus_account/__manifest__.py new file mode 100644 index 00000000000..5b5a66fdf8f --- /dev/null +++ b/l10n_es_sigaus_account/__manifest__.py @@ -0,0 +1,28 @@ +# Copyright 2023 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + "name": "SIGAUS - Facturación", + "summary": """Sistema de gestión de aceites + industriales usados en España - Facturación""", + "version": "17.0.1.0.0", + "license": "AGPL-3", + "author": "Sygel, Odoo Community Association (OCA)", + "category": "Accounting", + "website": "https://github.com/OCA/l10n-spain", + "depends": ["account"], + "data": [ + "data/data.xml", + "data/exception_templates.xml", + "security/ir.model.access.csv", + "views/l10n_es_sigaus_amount_views.xml", + "views/product_category_views.xml", + "views/product_views.xml", + "views/account_move_views.xml", + "views/report_invoice.xml", + "views/res_company_views.xml", + "views/account_fiscal_position_views.xml", + ], + "pre_init_hook": "pre_init_hook", + "installable": True, +} diff --git a/l10n_es_sigaus_account/data/data.xml b/l10n_es_sigaus_account/data/data.xml new file mode 100644 index 00000000000..e5eab69a5b4 --- /dev/null +++ b/l10n_es_sigaus_account/data/data.xml @@ -0,0 +1,30 @@ + + + + + Aportación SIGAUS (R.D. 679/2006) + + service + 0.0 + no + + + + + + + + + Aportación SIGAUS 2023 + 2023-1-1 + 2023-12-31 + 0.06 + + + Aportación SIGAUS 2024 + 2024-1-1 + 0.05 + + + diff --git a/l10n_es_sigaus_account/data/exception_templates.xml b/l10n_es_sigaus_account/data/exception_templates.xml new file mode 100644 index 00000000000..0b739c8c4fc --- /dev/null +++ b/l10n_es_sigaus_account/data/exception_templates.xml @@ -0,0 +1,23 @@ + + + + diff --git a/l10n_es_sigaus_account/hooks.py b/l10n_es_sigaus_account/hooks.py new file mode 100644 index 00000000000..39d2544f238 --- /dev/null +++ b/l10n_es_sigaus_account/hooks.py @@ -0,0 +1,46 @@ +# Copyright 2023 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + + +import logging + +from odoo import tools +from odoo.tools.sql import column_exists + +_logger = logging.getLogger(__name__) + + +def create_columns(cr): + if not column_exists(cr, "account_move", "is_sigaus"): + _logger.info("Initializing column is_sigaus on table account_move") + tools.create_column( + cr=cr, + tablename="account_move", + columnname="is_sigaus", + columntype="boolean", + comment="Indicates if it is a SIGAUS invoice", + ) + + if not column_exists(cr, "account_move", "sigaus_is_date"): + _logger.info("Initializing column sigaus_is_date on table account_move") + tools.create_column( + cr=cr, + tablename="account_move", + columnname="sigaus_is_date", + columntype="boolean", + comment="Date indicator for SIGAUS", + ) + + if not column_exists(cr, "product_product", "sigaus_has_amount"): + _logger.info("Initializing column sigaus_has_amount on table product_product") + tools.create_column( + cr=cr, + tablename="product_product", + columnname="sigaus_has_amount", + columntype="boolean", + comment="Indicates if the product has SIGAUS amount", + ) + + +def pre_init_hook(env): + create_columns(env.cr) diff --git a/l10n_es_sigaus_account/i18n/es.po b/l10n_es_sigaus_account/i18n/es.po new file mode 100644 index 00000000000..80a1fc1325e --- /dev/null +++ b/l10n_es_sigaus_account/i18n/es.po @@ -0,0 +1,324 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * l10n_es_sigaus_account +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-10-16 08:53+0000\n" +"PO-Revision-Date: 2024-10-16 08:53+0000\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: l10n_es_sigaus_account +#. odoo-python +#: code:addons/l10n_es_sigaus_account/models/res_company.py:0 +#, python-format +msgid "'Sigaus Date From' is mandatory for companies with SIGAUS enabled." +msgstr "" + +#. module: l10n_es_sigaus_account +#: model_terms:ir.ui.view,arch_db:l10n_es_sigaus_account.exception_sigaus +msgid "" +".\n" +" The following products are subject to SIGAUS but have no weight." +msgstr "" +".\n" +" Los siguientes productos están sujetos a SIGAUS pero no tienen peso." + +#. module: l10n_es_sigaus_account +#: model_terms:ir.ui.view,arch_db:l10n_es_sigaus_account.l10n_es_sigaus_account_amount_form_view +msgid "" +"" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model,name:l10n_es_sigaus_account.model_account_move_reversal +msgid "Account Move Reversal" +msgstr "Revocación de movimiento en cuenta" + +#. module: l10n_es_sigaus_account +#: model_terms:ir.ui.view,arch_db:l10n_es_sigaus_account.report_invoice_document +msgid "Aporatación SIGAUS (RD 679/2006):" +msgstr "Aportación SIGAUS (RD 679/2006):" + +#. module: l10n_es_sigaus_account +#: model:product.template,name:l10n_es_sigaus_account.aportacion_sigaus_product_template_product_template +msgid "Aportación SIGAUS (R.D. 679/2006)" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields.selection,name:l10n_es_sigaus_account.selection__product_template__sigaus_subject__category +msgid "Category" +msgstr "Categoría" + +#. module: l10n_es_sigaus_account +#: model:ir.model,name:l10n_es_sigaus_account.model_res_company +msgid "Companies" +msgstr "Compañías" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_l10n_es_sigaus_amount__create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_l10n_es_sigaus_amount__create_date +msgid "Created on" +msgstr "Creado el" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_l10n_es_sigaus_amount__date_from +msgid "Date From" +msgstr "Fecha desde" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_l10n_es_sigaus_amount__date_to +msgid "Date To" +msgstr "Fecha hasta" + +#. module: l10n_es_sigaus_account +#: model_terms:ir.ui.view,arch_db:l10n_es_sigaus_account.l10n_es_sigaus_account_amount_form_view +msgid "Dates" +msgstr "Fechas" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_l10n_es_sigaus_amount__display_name +msgid "Display Name" +msgstr "Nombre a mostrar" + +#. module: l10n_es_sigaus_account +#: model_terms:ir.ui.view,arch_db:l10n_es_sigaus_account.exception_sigaus +msgid "Exception(s) occurred:" +msgstr "Excepcion(es):" + +#. module: l10n_es_sigaus_account +#: model:ir.model,name:l10n_es_sigaus_account.model_account_fiscal_position +msgid "Fiscal Position" +msgstr "Posición fiscal" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_l10n_es_sigaus_amount__id +msgid "ID" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,help:l10n_es_sigaus_account.field_res_company__sigaus_show_in_reports +msgid "If active, SIGAUS amount is shown in reports." +msgstr "Si está activo, la aportación SIGAUS se muestra en los informes." + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_move_line__is_sigaus +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_sigaus_line_mixin__is_sigaus +msgid "Is Sigaus" +msgstr "Es SIGAUS" + +#. module: l10n_es_sigaus_account +#: model:ir.model,name:l10n_es_sigaus_account.model_account_move +msgid "Journal Entry" +msgstr "Asiento contable" + +#. module: l10n_es_sigaus_account +#: model:ir.model,name:l10n_es_sigaus_account.model_account_move_line +msgid "Journal Item" +msgstr "Apunte contable" + +#. module: l10n_es_sigaus_account +#: model:ir.actions.act_window,name:l10n_es_sigaus_account.l10n_es_sigaus_account_amount_action +#: model:ir.ui.menu,name:l10n_es_sigaus_account.menu_l10n_es_sigaus_account_amount +msgid "L10n Es Sigaus Amount" +msgstr "Aportación SIGAUS" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_l10n_es_sigaus_amount__write_uid +msgid "Last Updated by" +msgstr "Actualizado por última vez por" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_l10n_es_sigaus_amount__write_date +msgid "Last Updated on" +msgstr "Actualizado por última vez el" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_l10n_es_sigaus_amount__name +msgid "Name" +msgstr "Nombre" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields.selection,name:l10n_es_sigaus_account.selection__product_template__sigaus_subject__no +msgid "No" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_l10n_es_sigaus_amount__price +msgid "Price" +msgstr "Precio" + +#. module: l10n_es_sigaus_account +#: model:ir.model,name:l10n_es_sigaus_account.model_product_template +msgid "Product" +msgstr "Producto" + +#. module: l10n_es_sigaus_account +#: model:ir.model,name:l10n_es_sigaus_account.model_product_category +msgid "Product Category" +msgstr "Categoría de producto" + +#. module: l10n_es_sigaus_account +#: model:ir.model,name:l10n_es_sigaus_account.model_product_product +msgid "Product Variant" +msgstr "Variante de producto" + +#. module: l10n_es_sigaus_account +#: model_terms:ir.ui.view,arch_db:l10n_es_sigaus_account.exception_sigaus +msgid "Product(s):" +msgstr "Producto(s):" + +#. module: l10n_es_sigaus_account +#: model:ir.ui.menu,name:l10n_es_sigaus_account.menu_l10n_es_sigaus +msgid "SIGAUS" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,help:l10n_es_sigaus_account.field_res_company__sigaus_date_from +msgid "SIGAUS can only be applied from this date." +msgstr "La aportación SIGAUS solamente se aplica a partir de esta fecha." + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_res_company__sigaus_show_in_reports +msgid "Show detailed SIGAUS amount in report lines" +msgstr "Mostrar cantidades de SIGAUS en líneas de informes" + +#. module: l10n_es_sigaus_account +#: model_terms:ir.ui.view,arch_db:l10n_es_sigaus_account.l10n_es_sigaus_account_view_company_form +msgid "Sigaus" +msgstr "SIGAUS" + +#. module: l10n_es_sigaus_account +#: model:ir.model,name:l10n_es_sigaus_account.model_l10n_es_sigaus_amount +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_move_line__sigaus_amount +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_sigaus_line_mixin__sigaus_amount +msgid "Sigaus Amount" +msgstr "Aportación SIGAUS" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_bank_statement_line__sigaus_automated_exception_id +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_move__sigaus_automated_exception_id +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_payment__sigaus_automated_exception_id +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_sigaus_mixin__sigaus_automated_exception_id +msgid "Sigaus Automated Exception" +msgstr "Excepción de automatización de SIGAUS" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_bank_statement_line__sigaus_company +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_move__sigaus_company +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_payment__sigaus_company +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_sigaus_mixin__sigaus_company +msgid "Sigaus Company" +msgstr "Compañía SIGAUS" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_res_company__sigaus_date_from +msgid "Sigaus Date From" +msgstr "SIGAUS fecha desde" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_res_company__sigaus_enable +msgid "Sigaus Enable" +msgstr "SIGAUS activado" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_product_product__sigaus_has_amount +msgid "Sigaus Has Amount" +msgstr "Hay aportación SIGAUS" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_bank_statement_line__sigaus_has_line +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_move__sigaus_has_line +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_payment__sigaus_has_line +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_sigaus_mixin__sigaus_has_line +msgid "Sigaus Has Line" +msgstr "Hay línea SIGAUS" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_bank_statement_line__sigaus_is_date +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_move__sigaus_is_date +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_payment__sigaus_is_date +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_sigaus_mixin__sigaus_is_date +msgid "Sigaus Is Date" +msgstr "Es fecha SIGAUS" + +#. module: l10n_es_sigaus_account +#: model:ir.model,name:l10n_es_sigaus_account.model_sigaus_line_mixin +msgid "Sigaus Line Mixin" +msgstr "Mezcla de Líneas Sigaus" + +#. module: l10n_es_sigaus_account +#: model:ir.model,name:l10n_es_sigaus_account.model_sigaus_mixin +msgid "Sigaus Mixin" +msgstr "Mezclador Sigaus" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_fiscal_position__sigaus_subject +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_product_product__sigaus_subject +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_product_template__sigaus_subject +msgid "Subject To SIGAUS" +msgstr "Sujeto a SIGAUS" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_bank_statement_line__is_sigaus +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_move__is_sigaus +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_payment__is_sigaus +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_product_category__sigaus_subject +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_sigaus_mixin__is_sigaus +msgid "Subject to SIGAUS" +msgstr "Es SIGAUS" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,help:l10n_es_sigaus_account.field_account_bank_statement_line__sigaus_is_date +#: model:ir.model.fields,help:l10n_es_sigaus_account.field_account_move__sigaus_is_date +#: model:ir.model.fields,help:l10n_es_sigaus_account.field_account_payment__sigaus_is_date +#: model:ir.model.fields,help:l10n_es_sigaus_account.field_sigaus_mixin__sigaus_is_date +msgid "" +"Technical field to determine whether the date of a document subject to " +"SIGAUS is equal or after the date selected in the company from which SIGAUS " +"has to be applied." +msgstr "" +"Campo técnico para determinar si la fecha de un documento sujeto a SIGAUS es" +" igual o posterior a la fecha seleccionada en la compañía a partir de la que" +" el SIGAUS puede aplicarse." + +#. module: l10n_es_sigaus_account +#. odoo-python +#: code:addons/l10n_es_sigaus_account/models/l10n_es_sigaus_amount.py:0 +#, python-format +msgid "The ending date must not be prior to the starting date." +msgstr "" + +#. module: l10n_es_sigaus_account +#. odoo-python +#: code:addons/l10n_es_sigaus_account/models/l10n_es_sigaus_amount.py:0 +#, python-format +msgid "" +"There is not a SIGAUS price set for the date: {}. Please, go to Invoicing > " +"Configuration > L10n Es Sigaus Amount and make sure that the date is include" +" in one of the configured date ranges." +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields.selection,name:l10n_es_sigaus_account.selection__product_template__sigaus_subject__yes +msgid "Yes" +msgstr "Sí" + +#. module: l10n_es_sigaus_account +#. odoo-python +#: code:addons/l10n_es_sigaus_account/models/l10n_es_sigaus_amount.py:0 +#, python-format +msgid "You can not have overlapping date ranges." +msgstr "" diff --git a/l10n_es_sigaus_account/i18n/l10n_es_sigaus_account.pot b/l10n_es_sigaus_account/i18n/l10n_es_sigaus_account.pot new file mode 100644 index 00000000000..61d9f9149ff --- /dev/null +++ b/l10n_es_sigaus_account/i18n/l10n_es_sigaus_account.pot @@ -0,0 +1,319 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * l10n_es_sigaus_account +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-10-16 08:53+0000\n" +"PO-Revision-Date: 2024-10-16 08:53+0000\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: l10n_es_sigaus_account +#. odoo-python +#: code:addons/l10n_es_sigaus_account/models/res_company.py:0 +#, python-format +msgid "'Sigaus Date From' is mandatory for companies with SIGAUS enabled." +msgstr "" + +#. module: l10n_es_sigaus_account +#: model_terms:ir.ui.view,arch_db:l10n_es_sigaus_account.exception_sigaus +msgid "" +".\n" +" The following products are subject to SIGAUS but have no weight." +msgstr "" + +#. module: l10n_es_sigaus_account +#: model_terms:ir.ui.view,arch_db:l10n_es_sigaus_account.l10n_es_sigaus_account_amount_form_view +msgid "" +"" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model,name:l10n_es_sigaus_account.model_account_move_reversal +msgid "Account Move Reversal" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model_terms:ir.ui.view,arch_db:l10n_es_sigaus_account.report_invoice_document +msgid "Aporatación SIGAUS (RD 679/2006):" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:product.template,name:l10n_es_sigaus_account.aportacion_sigaus_product_template_product_template +msgid "Aportación SIGAUS (R.D. 679/2006)" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields.selection,name:l10n_es_sigaus_account.selection__product_template__sigaus_subject__category +msgid "Category" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model,name:l10n_es_sigaus_account.model_res_company +msgid "Companies" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_l10n_es_sigaus_amount__create_uid +msgid "Created by" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_l10n_es_sigaus_amount__create_date +msgid "Created on" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_l10n_es_sigaus_amount__date_from +msgid "Date From" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_l10n_es_sigaus_amount__date_to +msgid "Date To" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model_terms:ir.ui.view,arch_db:l10n_es_sigaus_account.l10n_es_sigaus_account_amount_form_view +msgid "Dates" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_l10n_es_sigaus_amount__display_name +msgid "Display Name" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model_terms:ir.ui.view,arch_db:l10n_es_sigaus_account.exception_sigaus +msgid "Exception(s) occurred:" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model,name:l10n_es_sigaus_account.model_account_fiscal_position +msgid "Fiscal Position" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_l10n_es_sigaus_amount__id +msgid "ID" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,help:l10n_es_sigaus_account.field_res_company__sigaus_show_in_reports +msgid "If active, SIGAUS amount is shown in reports." +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_move_line__is_sigaus +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_sigaus_line_mixin__is_sigaus +msgid "Is Sigaus" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model,name:l10n_es_sigaus_account.model_account_move +msgid "Journal Entry" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model,name:l10n_es_sigaus_account.model_account_move_line +msgid "Journal Item" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.actions.act_window,name:l10n_es_sigaus_account.l10n_es_sigaus_account_amount_action +#: model:ir.ui.menu,name:l10n_es_sigaus_account.menu_l10n_es_sigaus_account_amount +msgid "L10n Es Sigaus Amount" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_l10n_es_sigaus_amount__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_l10n_es_sigaus_amount__write_date +msgid "Last Updated on" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_l10n_es_sigaus_amount__name +msgid "Name" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields.selection,name:l10n_es_sigaus_account.selection__product_template__sigaus_subject__no +msgid "No" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_l10n_es_sigaus_amount__price +msgid "Price" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model,name:l10n_es_sigaus_account.model_product_template +msgid "Product" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model,name:l10n_es_sigaus_account.model_product_category +msgid "Product Category" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model,name:l10n_es_sigaus_account.model_product_product +msgid "Product Variant" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model_terms:ir.ui.view,arch_db:l10n_es_sigaus_account.exception_sigaus +msgid "Product(s):" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.ui.menu,name:l10n_es_sigaus_account.menu_l10n_es_sigaus +msgid "SIGAUS" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,help:l10n_es_sigaus_account.field_res_company__sigaus_date_from +msgid "SIGAUS can only be applied from this date." +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_res_company__sigaus_show_in_reports +msgid "Show detailed SIGAUS amount in report lines" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model_terms:ir.ui.view,arch_db:l10n_es_sigaus_account.l10n_es_sigaus_account_view_company_form +msgid "Sigaus" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model,name:l10n_es_sigaus_account.model_l10n_es_sigaus_amount +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_move_line__sigaus_amount +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_sigaus_line_mixin__sigaus_amount +msgid "Sigaus Amount" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_bank_statement_line__sigaus_automated_exception_id +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_move__sigaus_automated_exception_id +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_payment__sigaus_automated_exception_id +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_sigaus_mixin__sigaus_automated_exception_id +msgid "Sigaus Automated Exception" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_bank_statement_line__sigaus_company +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_move__sigaus_company +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_payment__sigaus_company +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_sigaus_mixin__sigaus_company +msgid "Sigaus Company" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_res_company__sigaus_date_from +msgid "Sigaus Date From" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_res_company__sigaus_enable +msgid "Sigaus Enable" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_product_product__sigaus_has_amount +msgid "Sigaus Has Amount" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_bank_statement_line__sigaus_has_line +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_move__sigaus_has_line +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_payment__sigaus_has_line +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_sigaus_mixin__sigaus_has_line +msgid "Sigaus Has Line" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_bank_statement_line__sigaus_is_date +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_move__sigaus_is_date +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_payment__sigaus_is_date +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_sigaus_mixin__sigaus_is_date +msgid "Sigaus Is Date" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model,name:l10n_es_sigaus_account.model_sigaus_line_mixin +msgid "Sigaus Line Mixin" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model,name:l10n_es_sigaus_account.model_sigaus_mixin +msgid "Sigaus Mixin" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_fiscal_position__sigaus_subject +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_product_product__sigaus_subject +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_product_template__sigaus_subject +msgid "Subject To SIGAUS" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_bank_statement_line__is_sigaus +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_move__is_sigaus +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_account_payment__is_sigaus +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_product_category__sigaus_subject +#: model:ir.model.fields,field_description:l10n_es_sigaus_account.field_sigaus_mixin__is_sigaus +msgid "Subject to SIGAUS" +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields,help:l10n_es_sigaus_account.field_account_bank_statement_line__sigaus_is_date +#: model:ir.model.fields,help:l10n_es_sigaus_account.field_account_move__sigaus_is_date +#: model:ir.model.fields,help:l10n_es_sigaus_account.field_account_payment__sigaus_is_date +#: model:ir.model.fields,help:l10n_es_sigaus_account.field_sigaus_mixin__sigaus_is_date +msgid "" +"Technical field to determine whether the date of a document subject to " +"SIGAUS is equal or after the date selected in the company from which SIGAUS " +"has to be applied." +msgstr "" + +#. module: l10n_es_sigaus_account +#. odoo-python +#: code:addons/l10n_es_sigaus_account/models/l10n_es_sigaus_amount.py:0 +#, python-format +msgid "The ending date must not be prior to the starting date." +msgstr "" + +#. module: l10n_es_sigaus_account +#. odoo-python +#: code:addons/l10n_es_sigaus_account/models/l10n_es_sigaus_amount.py:0 +#, python-format +msgid "" +"There is not a SIGAUS price set for the date: {}. Please, go to Invoicing > " +"Configuration > L10n Es Sigaus Amount and make sure that the date is include" +" in one of the configured date ranges." +msgstr "" + +#. module: l10n_es_sigaus_account +#: model:ir.model.fields.selection,name:l10n_es_sigaus_account.selection__product_template__sigaus_subject__yes +msgid "Yes" +msgstr "" + +#. module: l10n_es_sigaus_account +#. odoo-python +#: code:addons/l10n_es_sigaus_account/models/l10n_es_sigaus_amount.py:0 +#, python-format +msgid "You can not have overlapping date ranges." +msgstr "" diff --git a/l10n_es_sigaus_account/models/__init__.py b/l10n_es_sigaus_account/models/__init__.py new file mode 100644 index 00000000000..aae101d6497 --- /dev/null +++ b/l10n_es_sigaus_account/models/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2023 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import sigaus_mixin +from . import sigaus_line_mixin +from . import l10n_es_sigaus_amount +from . import product_category +from . import product_template +from . import product_product +from . import account_move +from . import account_move_line +from . import res_company +from . import account_fiscal_position diff --git a/l10n_es_sigaus_account/models/account_fiscal_position.py b/l10n_es_sigaus_account/models/account_fiscal_position.py new file mode 100644 index 00000000000..094fc81528f --- /dev/null +++ b/l10n_es_sigaus_account/models/account_fiscal_position.py @@ -0,0 +1,10 @@ +# Copyright 2023 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class AccountFiscalPosition(models.Model): + _inherit = "account.fiscal.position" + + sigaus_subject = fields.Boolean(string="Subject To SIGAUS") diff --git a/l10n_es_sigaus_account/models/account_move.py b/l10n_es_sigaus_account/models/account_move.py new file mode 100644 index 00000000000..8457f0b0342 --- /dev/null +++ b/l10n_es_sigaus_account/models/account_move.py @@ -0,0 +1,129 @@ +# Copyright 2023 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import api, models +from odoo.osv import expression + + +class AccountMove(models.Model): + _name = "account.move" + _inherit = ["account.move", "sigaus.mixin"] + + _sigaus_secondary_unit_fields = { + "line_ids": "invoice_line_ids", + "date_field": "invoice_date", + "editable_states": [ + "draft", + ], + } + + @api.depends( + "company_id", + "fiscal_position_id", + "move_type", + ) + def _compute_is_sigaus(self): + for rec in self: + if rec.is_invoice(): + return super()._compute_is_sigaus() + else: + rec.is_sigaus = False + + @api.depends("is_sigaus", "invoice_date", "company_id") + def _compute_sigaus_is_date(self): + ret = super()._compute_sigaus_is_date() + for rec in self.filtered( + lambda a: a.is_sigaus + and not a.invoice_date + and a.company_id.sigaus_date_from + ): + rec.sigaus_is_date = ( + rec.create_date.date() >= rec.company_id.sigaus_date_from + ) + return ret + + @api.depends("invoice_line_ids") + def _compute_sigaus_has_line(self): + return super()._compute_sigaus_has_line() + + @api.depends("company_id") + def _compute_sigaus_company(self): + return super()._compute_sigaus_company() + + def sigaus_default_date(self, lines): + self.ensure_one() + return self.invoice_date or self.create_date.date() + + @api.model + def get_independent_invoice_lines_domain(self): + """ + Override this method to get the invoice lines not related to other + models (i.e. sale orders) + """ + return [] + + def manage_sigaus_invoice_lines(self): + self.ensure_one() + independent_lines_domain = self.get_independent_invoice_lines_domain() + independent_sigaus_lines_domain = expression.AND( + [ + [ + ("move_id", "=", self.id), + ("is_sigaus", "=", True), + ], + independent_lines_domain, + ] + ) + self.env["account.move.line"].search(independent_sigaus_lines_domain).unlink() + # Invoice lines not related to other documents (i.e. sales) + independent_lines_domain = expression.AND( + [ + [ + ("move_id", "=", self.id), + ("product_id", "!=", False), + ("product_id.sigaus_has_amount", "=", True), + ], + independent_lines_domain, + ] + ) + independent_lines = self.env["account.move.line"].search( + independent_lines_domain + ) + if independent_lines: + self.create_sigaus_line(independent_lines) + + def create_sigaus_line(self, lines, **kwargs): + values = self._get_sigaus_line_vals(lines, **kwargs) + self.env["account.move.line"].create(values) + + def apply_sigaus(self): + for invoice in self.filtered( + lambda a: a.state == "draft" and a.is_sigaus and a.sigaus_is_date and a.id + ): + invoice.automatic_sigaus_exception() + invoice.with_context(avoid_recursion=True).manage_sigaus_invoice_lines() + + def write(self, vals): + res = super().write(vals) + if any( + value in list(vals.keys()) + for value in [ + "is_sigaus", + "company_id", + "fiscal_position_id", + "invoice_line_ids", + "move_type", + "invoice_date", + ] + ): + self.with_context(avoid_recursion=True)._delete_sigaus() + self.apply_sigaus() + return res + + @api.model_create_multi + def create(self, vals_list): + moves = super().create(vals_list) + for move in moves.filtered(lambda a: a.is_sigaus and a.sigaus_is_date): + move.automatic_sigaus_exception() + move.apply_sigaus() + return moves diff --git a/l10n_es_sigaus_account/models/account_move_line.py b/l10n_es_sigaus_account/models/account_move_line.py new file mode 100644 index 00000000000..a1990e1e2b0 --- /dev/null +++ b/l10n_es_sigaus_account/models/account_move_line.py @@ -0,0 +1,26 @@ +# Copyright 2023 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import models + + +class AccountMoveLine(models.Model): + _name = "account.move.line" + _inherit = ["account.move.line", "sigaus.line.mixin"] + + _sigaus_secondary_unit_fields = { + "parent_id": "move_id", + "date_field": "date", + "qty_field": "quantity", + "uom_field": "product_uom_id", + } + + def unlink(self): + sigaus_invoices = self.mapped("move_id").filtered( + lambda a: a.state == "draft" and a.is_sigaus and a.sigaus_is_date + ) + res = super().unlink() + if sigaus_invoices and not self.env.context.get("avoid_recursion"): + sigaus_invoices.with_context(avoid_recursion=True)._delete_sigaus() + sigaus_invoices.apply_sigaus() + return res diff --git a/l10n_es_sigaus_account/models/l10n_es_sigaus_amount.py b/l10n_es_sigaus_account/models/l10n_es_sigaus_amount.py new file mode 100644 index 00000000000..79a83d4b698 --- /dev/null +++ b/l10n_es_sigaus_account/models/l10n_es_sigaus_amount.py @@ -0,0 +1,73 @@ +# Copyright 2023 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError + + +class L10nEsSigausAmount(models.Model): + _name = "l10n.es.sigaus.amount" + _description = "Sigaus Amount" + + name = fields.Char(required=True) + date_from = fields.Date(required=True) + date_to = fields.Date() + price = fields.Float(digits="Product Price", required=True) + + @api.constrains("date_from", "date_to") + def _check_dates(self): + for rec in self: + date_from = rec.date_from + date_to = rec.date_to + if date_to and date_to < date_from: + raise ValidationError( + _("The ending date must not be prior to the starting date.") + ) + domain = [ + ("id", "!=", rec.id), + "|", + "|", + "|", + "|", + "&", + ("date_from", "<=", date_from), + "|", + ("date_to", ">=", date_from), + ("date_to", "=", False), + "&", + ("date_from", "<=", date_to), + ("date_to", ">=", date_to), + "&", + ("date_from", "<=", date_from), + ("date_to", ">=", date_to), + "&", + ("date_from", ">=", date_from), + ("date_to", "<=", date_to), + "&", + ("date_from", ">=", date_from), + ("date_from", "<=", date_to), + ] + + if self.search_count(domain) > 0: + raise ValidationError(_("You can not have overlapping date ranges.")) + + @api.model + def get_sigaus_amount(self, date): + l10n_es_sigaus_amount = self.search( + [ + ("date_from", "<=", date), + "|", + ("date_to", ">=", date), + ("date_to", "=", False), + ], + limit=1, + ) + if not l10n_es_sigaus_amount: + raise ValidationError( + _( + "There is not a SIGAUS price set for the date: {}. Please, go to " + "Invoicing > Configuration > L10n Es Sigaus Amount and make sure " + "that the date is include in one of the configured date ranges." + ).format(date) + ) + return l10n_es_sigaus_amount.price diff --git a/l10n_es_sigaus_account/models/product_category.py b/l10n_es_sigaus_account/models/product_category.py new file mode 100644 index 00000000000..ce7012e0f9e --- /dev/null +++ b/l10n_es_sigaus_account/models/product_category.py @@ -0,0 +1,10 @@ +# Copyright 2023 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class ProductCategory(models.Model): + _inherit = "product.category" + + sigaus_subject = fields.Boolean(string="Subject to SIGAUS") diff --git a/l10n_es_sigaus_account/models/product_product.py b/l10n_es_sigaus_account/models/product_product.py new file mode 100644 index 00000000000..76e147e3d09 --- /dev/null +++ b/l10n_es_sigaus_account/models/product_product.py @@ -0,0 +1,17 @@ +# Copyright 2023 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + + +class ProductProduct(models.Model): + _inherit = "product.product" + + sigaus_has_amount = fields.Boolean(compute="_compute_sigaus_has_amount", store=True) + + @api.depends("sigaus_subject", "categ_id", "categ_id.sigaus_subject") + def _compute_sigaus_has_amount(self): + for rec in self: + rec.sigaus_has_amount = rec.sigaus_subject == "yes" or ( + rec.sigaus_subject == "category" and rec.categ_id.sigaus_subject + ) diff --git a/l10n_es_sigaus_account/models/product_template.py b/l10n_es_sigaus_account/models/product_template.py new file mode 100644 index 00000000000..dfe160b8d58 --- /dev/null +++ b/l10n_es_sigaus_account/models/product_template.py @@ -0,0 +1,15 @@ +# Copyright 2023 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class ProductTemplate(models.Model): + _inherit = "product.template" + + sigaus_subject = fields.Selection( + [("category", "Category"), ("yes", "Yes"), ("no", "No")], + default="category", + string="Subject To SIGAUS", + required=True, + ) diff --git a/l10n_es_sigaus_account/models/res_company.py b/l10n_es_sigaus_account/models/res_company.py new file mode 100644 index 00000000000..08ff21c517e --- /dev/null +++ b/l10n_es_sigaus_account/models/res_company.py @@ -0,0 +1,23 @@ +# Copyright 2023 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError + + +class ResCompany(models.Model): + _inherit = "res.company" + + sigaus_enable = fields.Boolean() + sigaus_date_from = fields.Date(help="SIGAUS can only be applied from this date.") + sigaus_show_in_reports = fields.Boolean( + string="Show detailed SIGAUS amount in report lines", + help="If active, SIGAUS amount is shown in reports.", + ) + + @api.constrains("sigaus_enable", "sigaus_date_from") + def _check_sigaus_date(self): + if self.filtered(lambda a: a.sigaus_enable and not a.sigaus_date_from): + raise ValidationError( + _("'Sigaus Date From' is mandatory for companies with SIGAUS enabled.") + ) diff --git a/l10n_es_sigaus_account/models/sigaus_line_mixin.py b/l10n_es_sigaus_account/models/sigaus_line_mixin.py new file mode 100644 index 00000000000..b2a36fbd03e --- /dev/null +++ b/l10n_es_sigaus_account/models/sigaus_line_mixin.py @@ -0,0 +1,35 @@ +# Copyright 2023 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class SigausLineMixin(models.AbstractModel): + _name = "sigaus.line.mixin" + _description = "Sigaus Line Mixin" + + is_sigaus = fields.Boolean(copy=True, default=False) + sigaus_amount = fields.Float( + compute="_compute_sigaus_amount", digits="Product Price" + ) + + _sigaus_secondary_unit_fields = {} + + def _compute_sigaus_amount(self): + for rec in self: + sigaus_amount = 0.0 + if rec.product_id and rec.product_id.sigaus_has_amount: + price = self.env["l10n.es.sigaus.amount"].get_sigaus_amount( + rec[rec._sigaus_secondary_unit_fields["parent_id"]][ + rec._sigaus_secondary_unit_fields["date_field"] + ] + ) + quantity = rec[ + rec._sigaus_secondary_unit_fields["uom_field"] + ]._compute_quantity( + rec[rec._sigaus_secondary_unit_fields["qty_field"]], + rec.product_id.uom_id, + ) + weight = quantity * rec.product_id.weight + sigaus_amount = weight * price + rec.sigaus_amount = sigaus_amount diff --git a/l10n_es_sigaus_account/models/sigaus_mixin.py b/l10n_es_sigaus_account/models/sigaus_mixin.py new file mode 100644 index 00000000000..0fb2f2f8ead --- /dev/null +++ b/l10n_es_sigaus_account/models/sigaus_mixin.py @@ -0,0 +1,187 @@ +# Copyright 2023 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from datetime import date + +from odoo import SUPERUSER_ID, fields, models + + +class SigausMixin(models.AbstractModel): + _name = "sigaus.mixin" + _description = "Sigaus Mixin" + + is_sigaus = fields.Boolean( + compute="_compute_is_sigaus", + string="Subject to SIGAUS", + store=True, + readonly=False, + ) + sigaus_is_date = fields.Boolean( + compute="_compute_sigaus_is_date", + store=True, + help="Technical field to determine whether the date of a document subject to " + "SIGAUS is equal or after the date selected in the company from which SIGAUS " + "has to be applied.", + ) + sigaus_has_line = fields.Boolean(compute="_compute_sigaus_has_line") + # It cannot be a related field as sigaus.mixin does not have a company_id field + sigaus_company = fields.Boolean(compute="_compute_sigaus_company") + sigaus_automated_exception_id = fields.Many2one( + comodel_name="mail.activity", readonly=True + ) + + _sigaus_secondary_unit_fields = {} + + def _compute_is_sigaus(self): + for rec in self: + rec.is_sigaus = rec.company_id.sigaus_enable and ( + not rec.fiscal_position_id or rec.fiscal_position_id.sigaus_subject + ) + + def _compute_sigaus_is_date(self): + for rec in self: + try: + date = rec[rec._sigaus_secondary_unit_fields["date_field"]].date() + except AttributeError: + date = rec[rec._sigaus_secondary_unit_fields["date_field"]] + rec.sigaus_is_date = ( + rec.is_sigaus and date and date >= rec.company_id.sigaus_date_from + ) + + def _compute_sigaus_has_line(self): + for rec in self: + rec.sigaus_has_line = any( + line.is_sigaus + for line in rec[rec._sigaus_secondary_unit_fields["line_ids"]] + ) + + def _compute_sigaus_company(self): + for rec in self: + rec.sigaus_company = rec.company_id.sigaus_enable + + def _delete_sigaus(self): + self.filtered( + lambda a: a.state in self._sigaus_secondary_unit_fields["editable_states"] + ).mapped(self._sigaus_secondary_unit_fields["line_ids"]).filtered( + lambda b: b.is_sigaus + ).unlink() + + def _get_sigaus_line_vals(self, lines=False, **kwargs): + self.ensure_one() + sigaus_vals = dict() + sigaus_product_id = self.env.ref( + "l10n_es_sigaus_account.aportacion_sigaus_product_template" + ) + sigaus_vals["product_id"] = sigaus_product_id.id + kg_uom_id = self.env.ref("uom.product_uom_kgm") + sigaus_vals[ + self[ + self._sigaus_secondary_unit_fields["line_ids"] + ]._sigaus_secondary_unit_fields["uom_field"] + ] = kg_uom_id.id + date = False + sigaus_lines = ( + lines + if lines + else self[self._sigaus_secondary_unit_fields["line_ids"]].filtered( + lambda a: a.product_id and a.product_id.sigaus_has_amount + ) + ) + if self._name == "account.move": + # Get a default date to calculate the SIGAUS amount when the + # SIGAUS line is newly generated + date = self.sigaus_default_date(sigaus_lines) + else: + date = self[self._sigaus_secondary_unit_fields["date_field"]] + price = self.env["l10n.es.sigaus.amount"].get_sigaus_amount(date) + # if model isn't account.move we delete the sigaus line + invoice_lines = [] + if self._name != "account.move": + sigaus_line_delete = self[ + self._sigaus_secondary_unit_fields["line_ids"] + ].filtered(lambda a: a.product_id == sigaus_product_id) + if ( + sigaus_line_delete + and sigaus_line_delete[ + sigaus_line_delete._sigaus_secondary_unit_fields[ + "invoice_lines_field" + ] + ] + ): + invoice_lines = sigaus_line_delete[ + sigaus_line_delete._sigaus_secondary_unit_fields[ + "invoice_lines_field" + ] + ].ids + sigaus_line_delete.unlink() + weight = sum( + line[ + self[ + self._sigaus_secondary_unit_fields["line_ids"] + ]._sigaus_secondary_unit_fields["uom_field"] + ]._compute_quantity( + line[line._sigaus_secondary_unit_fields["qty_field"]], + line.product_id.uom_id, + ) + * line.product_id.weight + for line in sigaus_lines + ) + sigaus_vals.update( + { + self[ + self._sigaus_secondary_unit_fields["line_ids"] + ]._sigaus_secondary_unit_fields["qty_field"]: weight, + "price_unit": price, + "is_sigaus": True, + } + ) + if invoice_lines: + sigaus_vals.update( + { + self[ + self._sigaus_secondary_unit_fields["line_ids"] + ]._sigaus_secondary_unit_fields[ + "invoice_lines_field" + ]: invoice_lines + } + ) + if self._name == "account.move": + sigaus_vals["move_id"] = self.id + return sigaus_vals + + def automatic_sigaus_exception(self): + self.ensure_one() + products_without_weight = ( + self[self._sigaus_secondary_unit_fields["line_ids"]] + .mapped("product_id") + .filtered(lambda a: a.sigaus_has_amount and a.weight <= 0.0) + ) + if products_without_weight: + values = { + "model": self._name, + "origin": self.id, + "products": products_without_weight, + } + note = self.env["ir.qweb"]._render( + "l10n_es_sigaus_account.exception_sigaus", values + ) + if not self.sigaus_automated_exception_id: + odoobot_id = self.env.ref("base.partner_root").id + activity = self.activity_schedule( + "mail.mail_activity_data_warning", + date.today(), + note=note, + user_id=self.user_id.id or SUPERUSER_ID, + ) + activity.write( + { + "create_uid": odoobot_id, + } + ) + self.write( + { + "sigaus_automated_exception_id": activity.id, + } + ) + else: + self.sigaus_automated_exception_id.write({"note": note}) diff --git a/l10n_es_sigaus_account/pyproject.toml b/l10n_es_sigaus_account/pyproject.toml new file mode 100644 index 00000000000..4231d0cccb3 --- /dev/null +++ b/l10n_es_sigaus_account/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/l10n_es_sigaus_account/readme/CONFIGURE.md b/l10n_es_sigaus_account/readme/CONFIGURE.md new file mode 100644 index 00000000000..11624894d53 --- /dev/null +++ b/l10n_es_sigaus_account/readme/CONFIGURE.md @@ -0,0 +1,46 @@ +Se tienen que configurar los siguientes aspectos: + +- En la ficha del producto "Aportación SIGAUS (R.D. 679/2006)" + establecer el impuesto correspondiente. +- La configuración del precio de la aportación SIGAUS que se aplica + durante un periodo de tiempo se realiza desde Facturación \> + Configuración \> Aportación SIGAUS. En caso de no rellenar el campo + "Fecha hasta", el precio seleccionado se aplicará a partir de la fecha + indicada en "Fecha desde". El precio establecido dentro del periodo + marcado se utilizará siempre que se calcule la aportación SIGAUS en + las facturas. +- Es necesario indicar aquellas compañías en las que se aplicará la + aportación SIGAUS. Para ello, hay que acceder a la pestaña SIGAUS de + la configuración de la compañía y marcar la casilla "Habilitar + SIGAUS". Asimismo, es obligatorio indicar la fecha a partir de la que + la aportación SIGAUS se podrá aplicar en el campo "SIGAUS fecha + desde". No será posible calcular la aportación SIGAUS con fecha + anterior a la seleccionada en este campo. Cuando la opción "Habilitar + SIGAUS" está activada, se muestra el campo "Mostrar cantidades de + SIGAUS en líneas de informes" que, si está marcada, permite mostrar la + aportación SIGAUS de cada una de las líneas de facturas en los + informes. +- Las posiciones fiscales con las que se aplicará la aportación SIGAUS + tienen que indicarse. Para ello hay que acceder a Facturación \> + Configuración \> Posiciones Fiscales y marcar la casilla "Sujeto a + SIGAUS" en aquellas en las que se aplicará. +- Se puede establecer que los productos de ciertas categorías estén + sujetas a SIGAUS accediendo a la configuración de la categoría y + marcando la casilla "Sujeto a SIGAUS". +- Desde la ficha de los productos, pueden establecerse varias opciones + de sujeción a la aportación SIGAUS desde el campo "Sujeto a SIGAUS". + Existen tres opciones: + - "Categoría": La aplicación o no de la aportación SIGAUS para ese + producto depende de si la casilla "Sujeto a SIGAUS" está o no + marcada en la categoría establecida. + - "Sí": Se aplica siempre la aportación SIGAUS, independientemente de + lo seleccionado en la categoría de producto. + - "No": No se aplica nunca la aportación SIGAUS, independientemente de + lo seleccionado en la categoría de producto. + +Cuando se calcule la aportación SIGAUS en facturas, se tendrá en cuenta +el peso de todos aquellos productos a los que se les aplica la +aportación SIGAUS para determinar el importe. + +- Todos los productos a los que se les aplica la aportación SIGAUS deben + tener un peso establecido. diff --git a/l10n_es_sigaus_account/readme/CONTRIBUTORS.md b/l10n_es_sigaus_account/readme/CONTRIBUTORS.md new file mode 100644 index 00000000000..b523930631f --- /dev/null +++ b/l10n_es_sigaus_account/readme/CONTRIBUTORS.md @@ -0,0 +1,4 @@ +- [Sygel](https://sygel.es): + - Manuel Regidor \<\> + - Harald Panten \<\> + - Valentín Vinagre \<\> diff --git a/l10n_es_sigaus_account/readme/DESCRIPTION.md b/l10n_es_sigaus_account/readme/DESCRIPTION.md new file mode 100644 index 00000000000..9435e956752 --- /dev/null +++ b/l10n_es_sigaus_account/readme/DESCRIPTION.md @@ -0,0 +1,10 @@ +El origen de SIGAUS responde a la iniciativa de los fabricantes de +lubricantes que, a través de su participación en este Sistema, cumplen +con las obligaciones establecidas en la normativa sobre aceites usados +(Real Decreto 679/2006, de 2 de junio, por el que se regula la gestión +de los aceites industriales usados). + +Este módulo permite el cálculo de la aportación SIGAUS en las facturas a +partir del peso de aquellos productos en los que se aplica. + +- Más información en diff --git a/l10n_es_sigaus_account/readme/ROADMAP.md b/l10n_es_sigaus_account/readme/ROADMAP.md new file mode 100644 index 00000000000..92ba2fa9e90 --- /dev/null +++ b/l10n_es_sigaus_account/readme/ROADMAP.md @@ -0,0 +1,2 @@ +- El módulo no está preparado para añadir automáticamente las líneas de + aportación SIGAUS a los pedidos procedentes del comercio online. diff --git a/l10n_es_sigaus_account/readme/USAGE.md b/l10n_es_sigaus_account/readme/USAGE.md new file mode 100644 index 00000000000..6082569485e --- /dev/null +++ b/l10n_es_sigaus_account/readme/USAGE.md @@ -0,0 +1,14 @@ +- El importe de la aportación SIGAUS se calculará a partir de los pesos + de aquellos productos sujetos a dicha aportación y el precio + establecido en "Aportación SIGAUS" según la fecha de factura o, en su + defecto, la fecha de creación. +- Los productos sujetos a aportación SIGAUS son los siguientes: + - Aquellos que tienen establecida la opción "Sí" en el campo "Sujeto a + SIGAUS". + - Aquellos que tienen establecida la opción "Categoría" en el campo + "Sujeto a SIGAUS" y cuya categoría tenga marcada la opción "Sujeto a + SIGAUS". +- Se mostrará un mensaje en el chatter si al calcular la aportación + SIGAUS, alguno de los productos sujetos no tiene un peso establecido. +- Si se desmarca la opción "Sujeto a SIGAUS", no se aplicará la + aportación SIGAUS. diff --git a/l10n_es_sigaus_account/security/ir.model.access.csv b/l10n_es_sigaus_account/security/ir.model.access.csv new file mode 100644 index 00000000000..fab1916fc89 --- /dev/null +++ b/l10n_es_sigaus_account/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +l10n_es_sigaus_amount_manager,l10n.es.sigaus.amount.manager,model_l10n_es_sigaus_amount,account.group_account_manager,1,1,1,1 +l10n_es_sigaus_amount_user_invoicing,l10n.es.sigaus.amount.user.invoicing,model_l10n_es_sigaus_amount,sales_team.group_sale_salesman,1,0,0,0 diff --git a/l10n_es_sigaus_account/static/description/icon.png b/l10n_es_sigaus_account/static/description/icon.png new file mode 100644 index 00000000000..af0c57f04d6 Binary files /dev/null and b/l10n_es_sigaus_account/static/description/icon.png differ diff --git a/l10n_es_sigaus_account/static/description/icon.svg b/l10n_es_sigaus_account/static/description/icon.svg new file mode 100644 index 00000000000..43822ac2c88 --- /dev/null +++ b/l10n_es_sigaus_account/static/description/icon.svg @@ -0,0 +1,350 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/l10n_es_sigaus_account/static/description/index.html b/l10n_es_sigaus_account/static/description/index.html new file mode 100644 index 00000000000..70b2f683e09 --- /dev/null +++ b/l10n_es_sigaus_account/static/description/index.html @@ -0,0 +1,520 @@ + + + + + +SIGAUS - Facturación + + + +
+

SIGAUS - Facturación

+ + +

Beta License: AGPL-3 OCA/l10n-spain Translate me on Weblate Try me on Runboat

+

El origen de SIGAUS responde a la iniciativa de los fabricantes de +lubricantes que, a través de su participación en este Sistema, cumplen +con las obligaciones establecidas en la normativa sobre aceites usados +(Real Decreto 679/2006, de 2 de junio, por el que se regula la gestión +de los aceites industriales usados).

+

Este módulo permite el cálculo de la aportación SIGAUS en las facturas a +partir del peso de aquellos productos en los que se aplica.

+ +

Table of contents

+ +
+

Configuration

+

Se tienen que configurar los siguientes aspectos:

+
    +
  • En la ficha del producto “Aportación SIGAUS (R.D. 679/2006)” +establecer el impuesto correspondiente.
  • +
  • La configuración del precio de la aportación SIGAUS que se aplica +durante un periodo de tiempo se realiza desde Facturación > +Configuración > Aportación SIGAUS. En caso de no rellenar el campo +“Fecha hasta”, el precio seleccionado se aplicará a partir de la fecha +indicada en “Fecha desde”. El precio establecido dentro del periodo +marcado se utilizará siempre que se calcule la aportación SIGAUS en +las facturas.
  • +
  • Es necesario indicar aquellas compañías en las que se aplicará la +aportación SIGAUS. Para ello, hay que acceder a la pestaña SIGAUS de +la configuración de la compañía y marcar la casilla “Habilitar +SIGAUS”. Asimismo, es obligatorio indicar la fecha a partir de la que +la aportación SIGAUS se podrá aplicar en el campo “SIGAUS fecha +desde”. No será posible calcular la aportación SIGAUS con fecha +anterior a la seleccionada en este campo. Cuando la opción “Habilitar +SIGAUS” está activada, se muestra el campo “Mostrar cantidades de +SIGAUS en líneas de informes” que, si está marcada, permite mostrar la +aportación SIGAUS de cada una de las líneas de facturas en los +informes.
  • +
  • Las posiciones fiscales con las que se aplicará la aportación SIGAUS +tienen que indicarse. Para ello hay que acceder a Facturación > +Configuración > Posiciones Fiscales y marcar la casilla “Sujeto a +SIGAUS” en aquellas en las que se aplicará.
  • +
  • Se puede establecer que los productos de ciertas categorías estén +sujetas a SIGAUS accediendo a la configuración de la categoría y +marcando la casilla “Sujeto a SIGAUS”.
  • +
  • Desde la ficha de los productos, pueden establecerse varias opciones +de sujeción a la aportación SIGAUS desde el campo “Sujeto a SIGAUS”. +Existen tres opciones:
      +
    • “Categoría”: La aplicación o no de la aportación SIGAUS para ese +producto depende de si la casilla “Sujeto a SIGAUS” está o no +marcada en la categoría establecida.
    • +
    • “Sí”: Se aplica siempre la aportación SIGAUS, independientemente de +lo seleccionado en la categoría de producto.
    • +
    • “No”: No se aplica nunca la aportación SIGAUS, independientemente de +lo seleccionado en la categoría de producto.
    • +
    +
  • +
+

Cuando se calcule la aportación SIGAUS en facturas, se tendrá en cuenta +el peso de todos aquellos productos a los que se les aplica la +aportación SIGAUS para determinar el importe.

+
    +
  • Todos los productos a los que se les aplica la aportación SIGAUS deben +tener un peso establecido.
  • +
+
+
+

Usage

+
    +
  • El importe de la aportación SIGAUS se calculará a partir de los pesos +de aquellos productos sujetos a dicha aportación y el precio +establecido en “Aportación SIGAUS” según la fecha de factura o, en su +defecto, la fecha de creación.
  • +
  • Los productos sujetos a aportación SIGAUS son los siguientes:
      +
    • Aquellos que tienen establecida la opción “Sí” en el campo “Sujeto a +SIGAUS”.
    • +
    • Aquellos que tienen establecida la opción “Categoría” en el campo +“Sujeto a SIGAUS” y cuya categoría tenga marcada la opción “Sujeto a +SIGAUS”.
    • +
    +
  • +
  • Se mostrará un mensaje en el chatter si al calcular la aportación +SIGAUS, alguno de los productos sujetos no tiene un peso establecido.
  • +
  • Si se desmarca la opción “Sujeto a SIGAUS”, no se aplicará la +aportación SIGAUS.
  • +
+
+
+

Known issues / Roadmap

+
    +
  • El módulo no está preparado para añadir automáticamente las líneas de +aportación SIGAUS a los pedidos procedentes del comercio online.
  • +
+
+
+

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

+
    +
  • Sygel
  • +
+
+
+

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.

+

This module is part of the OCA/l10n-spain project on GitHub.

+

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

+
+
+
+ + diff --git a/l10n_es_sigaus_account/tests/__init__.py b/l10n_es_sigaus_account/tests/__init__.py new file mode 100644 index 00000000000..dfe0d75591f --- /dev/null +++ b/l10n_es_sigaus_account/tests/__init__.py @@ -0,0 +1,5 @@ +# Copyright 2023 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import test_l10n_es_sigaus_general_values +from . import test_l10n_es_sigaus_account diff --git a/l10n_es_sigaus_account/tests/common.py b/l10n_es_sigaus_account/tests/common.py new file mode 100644 index 00000000000..65c0498a6a0 --- /dev/null +++ b/l10n_es_sigaus_account/tests/common.py @@ -0,0 +1,60 @@ +# Copyright 2023 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo.tests import common + + +class TestL10nEsSigausCommon(common.TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) + cls.company = cls.env.ref("base.main_company") + cls.company.write({"sigaus_enable": True, "sigaus_date_from": "2022-01-01"}) + cls.partner = cls.env["res.partner"].create({"name": "Test"}) + cls.fiscal_position_sigaus = cls.env["account.fiscal.position"].create( + {"name": "Test Fiscal Sigaus", "active": True, "sigaus_subject": True} + ) + cls.fiscal_position_no_sigaus = cls.env["account.fiscal.position"].create( + {"name": "Test Fiscal Sigaus", "active": True, "sigaus_subject": False} + ) + cls.category_sigaus = cls.env["product.category"].create( + {"name": "Sigaus Category", "sigaus_subject": True} + ) + cls.product_sigaus_no = cls.env["product.product"].create( + { + "name": "Product-1", + "sigaus_subject": "no", + "weight": 1, + } + ) + cls.product_sigaus_in_product = cls.env["product.product"].create( + { + "name": "Product (SIGAUS in product)", + "sigaus_subject": "yes", + "weight": 1, + } + ) + cls.product_sigaus_in_category = cls.env["product.product"].create( + { + "name": "Product (SIGAUS in category)", + "sigaus_subject": "category", + "weight": 2, + "categ_id": cls.category_sigaus.id, + } + ) + cls.product_sigaus_in_category_excluded = cls.env["product.product"].create( + { + "name": "Product (SIGAUS in category excluded)", + "sigaus_subject": "no", + "weight": 3, + "categ_id": cls.category_sigaus.id, + } + ) + cls.product_sigaus_no_weight = cls.env["product.product"].create( + { + "name": "Product (SIGAUS no weight)", + "sigaus_subject": "yes", + "weight": 0, + } + ) diff --git a/l10n_es_sigaus_account/tests/test_l10n_es_sigaus_account.py b/l10n_es_sigaus_account/tests/test_l10n_es_sigaus_account.py new file mode 100644 index 00000000000..77f05968c4e --- /dev/null +++ b/l10n_es_sigaus_account/tests/test_l10n_es_sigaus_account.py @@ -0,0 +1,281 @@ +# Copyright 2023 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo.exceptions import ValidationError + +from .common import TestL10nEsSigausCommon + + +class TestL10nEsSigausInvoice(TestL10nEsSigausCommon): + def create_invoice(self, date, lines, sigaus_no=False): + invoice_lines = [] + for line in lines: + invoice_lines.append( + ( + 0, + False, + { + "product_id": line["product"].id, + "quantity": line["quantity"], + "price_unit": line["price_unit"], + }, + ) + ) + invoice = self.env["account.move"].create( + { + "company_id": self.company.id, + "partner_id": self.partner.id, + "invoice_date": date, + "invoice_line_ids": invoice_lines, + "move_type": "out_invoice", + "is_sigaus": not sigaus_no, + } + ) + return invoice + + def create_reversal(self): + lines = [ + { + "product": self.product_sigaus_in_product, + "quantity": 1.0, + "price_unit": 2, + }, + { + "product": self.product_sigaus_in_category, + "quantity": 2.0, + "price_unit": 3, + }, + { + "product": self.product_sigaus_in_category_excluded, + "quantity": 3.0, + "price_unit": 4, + }, + ] + invoice = self.create_invoice("2023-01-01", lines) + invoice.action_post() + move_reversal = ( + self.env["account.move.reversal"] + .with_context(active_model="account.move", active_ids=[invoice.id]) + .create( + { + "date": "2023-01-01", + "journal_id": invoice.journal_id.id, + } + ) + ) + return invoice, move_reversal.reverse_moves() + + def test_invoice_without_sigaus_products(self): + lines = [{"product": self.product_sigaus_no, "quantity": 2.0, "price_unit": 1}] + invoice = self.create_invoice("2023-01-01", lines) + self.assertEqual(invoice.sigaus_has_line, False) + self.assertEqual(invoice.amount_untaxed, 2) + + def test_invoice_with_sigaus_products_no_weight(self): + lines = [ + {"product": self.product_sigaus_no_weight, "quantity": 2.0, "price_unit": 1} + ] + invoice = self.create_invoice("2023-01-01", lines) + self.assertEqual(invoice.sigaus_company, True) + self.assertTrue(invoice.sigaus_automated_exception_id) + + def test_invoice_with_sigaus(self): + lines = [ + { + "product": self.product_sigaus_in_product, + "quantity": 1.0, + "price_unit": 2, + }, + { + "product": self.product_sigaus_in_category, + "quantity": 2.0, + "price_unit": 3, + }, + { + "product": self.product_sigaus_in_category_excluded, + "quantity": 3.0, + "price_unit": 4, + }, + ] + invoice = self.create_invoice("2023-01-01", lines, True) + self.assertEqual(invoice.sigaus_has_line, False) + self.assertEqual(invoice.amount_untaxed, 20.00) + product_sigaus_in_product_line = invoice.invoice_line_ids.filtered( + lambda a: a.product_id == self.product_sigaus_in_product + ) + self.assertEqual(product_sigaus_in_product_line.sigaus_amount, 0.06) + product_sigaus_in_category_line = invoice.invoice_line_ids.filtered( + lambda a: a.product_id == self.product_sigaus_in_category + ) + self.assertEqual(product_sigaus_in_category_line.sigaus_amount, 0.24) + product_sigaus_in_product_line = invoice.invoice_line_ids.filtered( + lambda a: a.product_id == self.product_sigaus_in_product + ) + self.assertEqual(product_sigaus_in_product_line.sigaus_amount, 0.06) + product_sigaus_in_category_excluded_line = invoice.invoice_line_ids.filtered( + lambda a: a.product_id == self.product_sigaus_in_category_excluded + ) + self.assertEqual(product_sigaus_in_category_excluded_line.sigaus_amount, 0.00) + + invoice.write({"is_sigaus": True}) + self.assertEqual(invoice.sigaus_has_line, True) + self.assertEqual(invoice.amount_untaxed, 20.3) + invoice.write( + { + "invoice_line_ids": [ + ( + 0, + False, + { + "product_id": self.product_sigaus_in_product.id, + "quantity": 1.0, + "price_unit": 2, + }, + ) + ] + } + ) + self.assertEqual(invoice.amount_untaxed, 22.36) + invoice.write({"fiscal_position_id": self.fiscal_position_no_sigaus.id}) + self.assertEqual(invoice.amount_untaxed, 22.00) + invoice.write({"fiscal_position_id": False}) + self.assertEqual(invoice.amount_untaxed, 22.36) + invoice.write({"is_sigaus": False}) + self.assertEqual(invoice.amount_untaxed, 22.00) + + def test_invoice_with_sigaus_general_reverse(self): + lines = [ + { + "product": self.product_sigaus_in_product, + "quantity": 1.0, + "price_unit": 2, + }, + { + "product": self.product_sigaus_in_category, + "quantity": 2.0, + "price_unit": 3, + }, + { + "product": self.product_sigaus_in_category_excluded, + "quantity": 3.0, + "price_unit": 4, + }, + ] + invoice = self.create_invoice("2023-01-01", lines) + invoice_sigaus_line = invoice.invoice_line_ids.filtered("is_sigaus") + invoice.action_post() + credit_note = invoice._reverse_moves() + credit_note.write({"invoice_date": invoice.invoice_date}) + self.assertEqual(credit_note.move_type, "out_refund") + self.assertEqual(invoice.amount_untaxed, credit_note.amount_untaxed) + self.assertTrue(credit_note.is_sigaus) + credit_note_sigaus_line = credit_note.invoice_line_ids.filtered("is_sigaus") + self.assertEqual(len(credit_note_sigaus_line), 1) + self.assertEqual( + invoice_sigaus_line.price_subtotal, credit_note_sigaus_line.price_subtotal + ) + + def test_invoice_with_sigaus_different_dates(self): + self.company.write({"sigaus_date_from": "3000-01-01"}) + lines = [ + { + "product": self.product_sigaus_in_product, + "quantity": 1.0, + "price_unit": 2, + }, + { + "product": self.product_sigaus_in_category, + "quantity": 2.0, + "price_unit": 3, + }, + { + "product": self.product_sigaus_in_category_excluded, + "quantity": 3.0, + "price_unit": 4, + }, + ] + invoice = self.create_invoice(False, lines) + self.assertFalse(invoice.sigaus_is_date) + self.assertFalse(invoice.sigaus_has_line) + invoice.write({"invoice_date": "3000-01-01"}) + self.assertTrue(invoice.sigaus_is_date) + self.assertTrue(invoice.sigaus_has_line) + self.company.write({"sigaus_date_from": "2023-01-01"}) + lines = [ + { + "product": self.product_sigaus_in_product, + "quantity": 1.0, + "price_unit": 2, + }, + { + "product": self.product_sigaus_in_category, + "quantity": 2.0, + "price_unit": 3, + }, + { + "product": self.product_sigaus_in_category_excluded, + "quantity": 3.0, + "price_unit": 4, + }, + ] + invoice = self.create_invoice(False, lines) + self.assertTrue(invoice.sigaus_is_date) + self.assertTrue(invoice.sigaus_has_line) + + def test_copy_sigaus_invoice(self): + lines = [ + { + "product": self.product_sigaus_in_product, + "quantity": 1.0, + "price_unit": 2, + }, + { + "product": self.product_sigaus_in_category, + "quantity": 2.0, + "price_unit": 3, + }, + { + "product": self.product_sigaus_in_category_excluded, + "quantity": 3.0, + "price_unit": 4, + }, + ] + invoice = self.create_invoice("2023-01-01", lines) + invoice_copy = invoice.copy({"invoice_date": "2023-01-01"}) + self.assertEqual(invoice.amount_untaxed, invoice_copy.amount_untaxed) + self.assertTrue(invoice_copy.is_sigaus) + self.assertTrue(invoice_copy.sigaus_has_line) + self.assertEqual(len(invoice_copy.invoice_line_ids.filtered("is_sigaus")), 1) + self.assertEqual( + invoice_copy.invoice_line_ids.filtered("is_sigaus").price_subtotal, 0.3 + ) + invoice.write( + { + "invoice_line_ids": [ + ( + 0, + False, + { + "product_id": self.product_sigaus_in_category.id, + "quantity": 2.0, + "price_unit": 3, + }, + ), + ] + } + ) + self.assertEqual(len(invoice_copy.invoice_line_ids.filtered("is_sigaus")), 1) + self.assertEqual( + invoice_copy.invoice_line_ids.filtered("is_sigaus").price_subtotal, 0.3 + ) + + def test_invoice_error_date(self): + lines = [ + { + "product": self.product_sigaus_in_product, + "quantity": 1.0, + "price_unit": 2, + } + ] + with self.assertRaises(ValidationError): + self.create_invoice("2022-01-01", lines) diff --git a/l10n_es_sigaus_account/tests/test_l10n_es_sigaus_general_values.py b/l10n_es_sigaus_account/tests/test_l10n_es_sigaus_general_values.py new file mode 100644 index 00000000000..9c41bc7c158 --- /dev/null +++ b/l10n_es_sigaus_account/tests/test_l10n_es_sigaus_general_values.py @@ -0,0 +1,42 @@ +# Copyright 2023 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo.exceptions import ValidationError + +from .common import TestL10nEsSigausCommon + + +class TestL10nEsSigausPriceRange(TestL10nEsSigausCommon): + def test_wrong_date(self): + with self.assertRaises(ValidationError): + self.env["l10n.es.sigaus.amount"].create( + { + "name": "Test", + "price": 0.1, + "date_from": "2021-01-01", + "date_to": "2020-01-01", + } + ) + + def test_overlapping_dates(self): + self.env["l10n.es.sigaus.amount"].create( + { + "name": "Test-1", + "price": 0.1, + "date_from": "2020-01-01", + "date_to": "2021-01-01", + } + ) + with self.assertRaises(ValidationError): + self.env["l10n.es.sigaus.amount"].create( + { + "name": "Test-2", + "price": 0.1, + "date_from": "2020-01-07", + "date_to": "2021-01-07", + } + ) + + def test_sigaus_date_from_required(self): + with self.assertRaises(ValidationError): + self.company.write({"sigaus_date_from": False}) diff --git a/l10n_es_sigaus_account/views/account_fiscal_position_views.xml b/l10n_es_sigaus_account/views/account_fiscal_position_views.xml new file mode 100644 index 00000000000..d1a9a46ae3a --- /dev/null +++ b/l10n_es_sigaus_account/views/account_fiscal_position_views.xml @@ -0,0 +1,24 @@ + + + + l10n.es.sigaus.account.view.account.position.form + account.fiscal.position + + + + + + + + + l10n.es.sigaus.account.view.account.position.tree + account.fiscal.position + + + + + + + + diff --git a/l10n_es_sigaus_account/views/account_move_views.xml b/l10n_es_sigaus_account/views/account_move_views.xml new file mode 100644 index 00000000000..a5f25b08be0 --- /dev/null +++ b/l10n_es_sigaus_account/views/account_move_views.xml @@ -0,0 +1,30 @@ + + + + l10n.es.sigaus.account.view.move.form + account.move + + + + + + + + + + + + + + + diff --git a/l10n_es_sigaus_account/views/l10n_es_sigaus_amount_views.xml b/l10n_es_sigaus_account/views/l10n_es_sigaus_amount_views.xml new file mode 100644 index 00000000000..9c53d7bdc6d --- /dev/null +++ b/l10n_es_sigaus_account/views/l10n_es_sigaus_amount_views.xml @@ -0,0 +1,68 @@ + + + + l10n.es.sigaus.account.amount.form.view + l10n.es.sigaus.amount + +
+ + + + + + + + + + + +
+
+ + l10n.es.sigaus.account.amount.tree.view + l10n.es.sigaus.amount + + + + + + + + + + + L10n Es Sigaus Amount + l10n.es.sigaus.amount + tree,form + + + + +
diff --git a/l10n_es_sigaus_account/views/product_category_views.xml b/l10n_es_sigaus_account/views/product_category_views.xml new file mode 100644 index 00000000000..d83e25eea6c --- /dev/null +++ b/l10n_es_sigaus_account/views/product_category_views.xml @@ -0,0 +1,14 @@ + + + + l10n.es.sigaus.account.product.category.form.view + product.category + + + + + + + + diff --git a/l10n_es_sigaus_account/views/product_views.xml b/l10n_es_sigaus_account/views/product_views.xml new file mode 100644 index 00000000000..61ecdd46f69 --- /dev/null +++ b/l10n_es_sigaus_account/views/product_views.xml @@ -0,0 +1,14 @@ + + + + l10n.es.sigaus.account.product.template.form.view + product.template + + + + + + + + diff --git a/l10n_es_sigaus_account/views/report_invoice.xml b/l10n_es_sigaus_account/views/report_invoice.xml new file mode 100644 index 00000000000..96f3b1fee0d --- /dev/null +++ b/l10n_es_sigaus_account/views/report_invoice.xml @@ -0,0 +1,18 @@ + + + + diff --git a/l10n_es_sigaus_account/views/res_company_views.xml b/l10n_es_sigaus_account/views/res_company_views.xml new file mode 100644 index 00000000000..f9d6076a805 --- /dev/null +++ b/l10n_es_sigaus_account/views/res_company_views.xml @@ -0,0 +1,26 @@ + + + + l10n.es.sigaus.account.view.company.form + res.company + + + + + + + + + + + + + + diff --git a/l10n_es_sigaus_account/wizard/__init__.py b/l10n_es_sigaus_account/wizard/__init__.py new file mode 100644 index 00000000000..f4419ff8f1c --- /dev/null +++ b/l10n_es_sigaus_account/wizard/__init__.py @@ -0,0 +1,4 @@ +# Copyright 2023 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import account_move_reversal diff --git a/l10n_es_sigaus_account/wizard/account_move_reversal.py b/l10n_es_sigaus_account/wizard/account_move_reversal.py new file mode 100644 index 00000000000..f8d81f1db9d --- /dev/null +++ b/l10n_es_sigaus_account/wizard/account_move_reversal.py @@ -0,0 +1,13 @@ +# Copyright 2023 Manuel Regidor +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import models + + +class AccountMoveReversal(models.TransientModel): + _inherit = "account.move.reversal" + + def reverse_moves(self): + if any(move.is_sigaus for move in self.move_ids): + self = self.with_context(reverse_has_sigaus=True) + return super().reverse_moves()