diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ba8c93b68..8dd0d77af 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,7 +22,7 @@ exclude: | (LICENSE.*|COPYING.*) default_language_version: python: python3 - node: "16.17.0" + node: system repos: - repo: local hooks: diff --git a/agreement_legal/README.rst b/agreement_legal/README.rst index 5db3a54ac..fe89588e3 100644 --- a/agreement_legal/README.rst +++ b/agreement_legal/README.rst @@ -1,7 +1,3 @@ -.. image:: https://odoo-community.org/readme-banner-image - :target: https://odoo-community.org/get-involved?utm_source=readme - :alt: Odoo Community Association - ================ Agreements Legal ================ @@ -17,7 +13,7 @@ Agreements Legal .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png +.. |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%2Fagreement-lightgray.png?logo=github @@ -111,6 +107,7 @@ Contributors - `APSL-Nagarro `__: - Antoni Marroig + - Miquel Alzanillas Other credits ------------- diff --git a/agreement_legal/__manifest__.py b/agreement_legal/__manifest__.py index 856bc3d2c..47336db0f 100644 --- a/agreement_legal/__manifest__.py +++ b/agreement_legal/__manifest__.py @@ -16,6 +16,7 @@ "data": [ "data/cron.xml", "data/ir_sequence.xml", + "data/ir_actions.xml", "data/agreement_stage.xml", "data/agreement_type.xml", "security/res_groups.xml", diff --git a/agreement_legal/data/ir_actions.xml b/agreement_legal/data/ir_actions.xml new file mode 100644 index 000000000..21fe7cff6 --- /dev/null +++ b/agreement_legal/data/ir_actions.xml @@ -0,0 +1,18 @@ + + + + + Recompute From Template + + code + +model.recompute_from_template() + + + list,form + + diff --git a/agreement_legal/i18n/es.po b/agreement_legal/i18n/es.po index b455d4a61..d709d6321 100644 --- a/agreement_legal/i18n/es.po +++ b/agreement_legal/i18n/es.po @@ -4,17 +4,16 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 12.0\n" +"Project-Id-Version: Odoo Server 17.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2023-07-20 23:10+0000\n" -"Last-Translator: Ivorra78 \n" -"Language-Team: none\n" -"Language: es\n" +"POT-Creation-Date: 2026-02-03 12:39+0000\n" +"PO-Revision-Date: 2026-02-03 12:39+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: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.17\n" +"Plural-Forms: \n" #. module: agreement_legal #: model_terms:ir.ui.view,arch_db:agreement_legal.view_project_agreement_kanban @@ -147,6 +146,13 @@ msgstr "Tipos de Acuerdo" msgid "Agreement needs a review" msgstr "El acuerdo necesita una revisión" +#. module: agreement_legal +#. odoo-python +#: code:addons/agreement_legal/models/agreement.py:0 +#, python-format +msgid "Agreement recomputed from template %s" +msgstr "Acuerdo recomputado desde la plantilla %s" + #. module: agreement_legal #: model:ir.actions.server,name:agreement_legal.ir_cron_test_acc_move_except_ir_actions_server msgid "Agreement: Check to Review Days" @@ -198,8 +204,8 @@ msgstr "Acuerdos por revisar" #. module: agreement_legal #: model:ir.model.fields,help:agreement_legal.field_agreement__special_terms msgid "" -"Any terms that you have agreed to and want to track on the agreement/" -"contract." +"Any terms that you have agreed to and want to track on the " +"agreement/contract." msgstr "" "Cualquier término que haya acordado y que desee seguir en el acuerdo / " "contrato." @@ -301,7 +307,7 @@ msgstr "Cláusulas" #. module: agreement_legal #: model:ir.model.fields,field_description:agreement_legal.field_agreement__color msgid "Color" -msgstr "Color" +msgstr "" #. module: agreement_legal #: model_terms:ir.ui.view,arch_db:agreement_legal.partner_agreement_form_view @@ -342,7 +348,7 @@ msgstr "Computar términos especiales dinámicos" #. module: agreement_legal #: model:ir.model,name:agreement_legal.model_res_config_settings msgid "Config Settings" -msgstr "Detalles Configuración" +msgstr "Ajustes de configuración" #. module: agreement_legal #: model:ir.ui.menu,name:agreement_legal.agreement_configuration @@ -560,7 +566,7 @@ msgstr "Editar" #. module: agreement_legal #: model:ir.model.fields,field_description:agreement_legal.field_agreement__company_contact_email msgid "Email" -msgstr "Email" +msgstr "" #. module: agreement_legal #: model:ir.model.fields,field_description:agreement_legal.field_agreement__end_date @@ -621,7 +627,7 @@ msgstr "" #. module: agreement_legal #: model_terms:ir.ui.view,arch_db:agreement_legal.partner_agreement_form_view msgid "General" -msgstr "General" +msgstr "" #. module: agreement_legal #: model_terms:ir.ui.view,arch_db:agreement_legal.res_config_settings_view_form @@ -638,7 +644,7 @@ msgstr "Mesa de Ayuda" #: model:ir.model.fields,field_description:agreement_legal.field_agreement_subtype__id #: model:ir.model.fields,field_description:agreement_legal.field_create_agreement_wizard__id msgid "ID" -msgstr "ID" +msgstr "" #. module: agreement_legal #: model:ir.model.fields,help:agreement_legal.field_agreement__code @@ -657,7 +663,8 @@ msgstr "Si no está marcada, le permitirá ocultar el acuerdo sin eliminarlo." #: model:ir.model.fields,help:agreement_legal.field_agreement_appendix__active msgid "" "If unchecked, it will allow you to hide this appendix without removing it." -msgstr "Si no está marcada, le permitirá ocultar este apéndice sin eliminarlo." +msgstr "" +"Si no está marcada, le permitirá ocultar este apéndice sin eliminarlo." #. module: agreement_legal #: model:ir.model.fields,help:agreement_legal.field_agreement_recital__active @@ -713,8 +720,8 @@ msgstr "" #: model:ir.model.fields,help:agreement_legal.field_agreement__parent_agreement_id msgid "" "Link this agreement to a parent agreement. For example if this agreement is " -"an amendment to another agreement. This list will only show other agreements " -"related to the same account." +"an amendment to another agreement. This list will only show other agreements" +" related to the same account." msgstr "" "Enlace este acuerdo a un acuerdo principal. Por ejemplo, si este acuerdo es " "una enmienda a otro acuerdo. Esta lista solo mostrará otros acuerdos " @@ -851,6 +858,10 @@ msgstr "" #. module: agreement_legal #. odoo-python #: code:addons/agreement_legal/models/agreement.py:0 +#: code:addons/agreement_legal/models/agreement.py:0 +#: code:addons/agreement_legal/models/agreement.py:0 +#: code:addons/agreement_legal/models/agreement.py:0 +#: code:addons/agreement_legal/models/agreement.py:0 #: model:agreement.stage,name:agreement_legal.agreement_stage_new #, python-format msgid "New" @@ -933,7 +944,7 @@ msgstr "Acuerdo de las Partes" #: model_terms:ir.ui.view,arch_db:agreement_legal.partner_agreement_form_view #: model_terms:ir.ui.view,arch_db:agreement_legal.report_agreement_document msgid "Partner" -msgstr "Contacto" +msgstr "Cliente" #. module: agreement_legal #: model:ir.model.fields,field_description:agreement_legal.field_agreement__partner_contact_id @@ -1061,6 +1072,11 @@ msgstr "Narración" msgid "Recitals" msgstr "La narración" +#. module: agreement_legal +#: model:ir.actions.server,name:agreement_legal.action_agreement_legal_recompute_from_template +msgid "Recompute From Template" +msgstr "Actualizar desde plantilla" + #. module: agreement_legal #: model_terms:ir.ui.view,arch_db:agreement_legal.view_project_agreement_kanban msgid "Record's Colour" @@ -1167,12 +1183,10 @@ msgstr "Secciones" #: model:ir.model.fields,help:agreement_legal.field_agreement_section__field_id msgid "" "Select target field from the related document model. If it is a\n" -" relationship field you will be able to select a target field at " -"the\n" +" relationship field you will be able to select a target field at the\n" " destination of the relationship." msgstr "" -"Seleccione el campo de destino en el modelo de documento relacionado. Si se " -"trata de un\n" +"Seleccione el campo de destino en el modelo de documento relacionado. Si se trata de un\n" " campo de relación podrá seleccionar un campo de destino en el\n" " destino de la relación." @@ -1398,8 +1412,8 @@ msgstr "Fecha de Finalización Solicitada" #. module: agreement_legal #: model:ir.model.fields,help:agreement_legal.field_agreement__notification_address_id msgid "" -"The address to send notifications to, if different from customer address." -"(Address Type = Other)" +"The address to send notifications to, if different from customer " +"address.(Address Type = Other)" msgstr "" "Dirección a la que se enviarán las notificaciones, si es distinta de la " "dirección del cliente.(Tipo de dirección = Otra)" @@ -1470,8 +1484,8 @@ msgid "" "This section (on the left) allows you to add dynamic fields inside the " "content." msgstr "" -"Esta sección (a la izquierda) le permite agregar campos dinámicos dentro del " -"contenido." +"Esta sección (a la izquierda) le permite agregar campos dinámicos dentro del" +" contenido." #. module: agreement_legal #: model_terms:ir.ui.view,arch_db:agreement_legal.partner_agreement_form_view @@ -1595,13 +1609,11 @@ msgstr "" #: model:ir.model.fields,help:agreement_legal.field_agreement_section__sub_model_object_field_id msgid "" "When a relationship field is selected as first field, this\n" -" field lets you select the target field within the destination " -"document\n" +" field lets you select the target field within the destination document\n" " model (sub-model)." msgstr "" "Cuando se selecciona un campo de relación como primer campo, este\n" -" campo le permite seleccionar el campo de destino dentro del modelo " -"de documento de destino\n" +" campo le permite seleccionar el campo de destino dentro del modelo de documento de destino\n" " (submodelo)." #. module: agreement_legal @@ -1631,8 +1643,7 @@ msgstr "Cuando comienza el acuerdo." #: model:ir.model.fields,help:agreement_legal.field_agreement__field_id msgid "" "You can select a target field from the related document model.\n" -" If it is a relationship field you will be able to select a target " -"field\n" +" If it is a relationship field you will be able to select a target field\n" " at the destination of the relationship." msgstr "" @@ -1659,7 +1670,7 @@ msgstr "nota" #. module: agreement_legal #: model_terms:ir.ui.view,arch_db:agreement_legal.view_project_agreement_kanban msgid "oe_kanban_text_red" -msgstr "oe_kanban_text_red" +msgstr "" #. module: agreement_legal #: model_terms:ir.ui.view,arch_db:agreement_legal.partner_agreement_form_view @@ -1680,201 +1691,3 @@ msgstr "| Creado por:" #: model_terms:ir.ui.view,arch_db:agreement_legal.partner_agreement_form_view msgid "| Created On:" msgstr "| Creado el:" - -#~ msgid "Last Modified on" -#~ msgstr "Última modificación el" - -#~ msgid "" -#~ "The address to send notificaitons to, if different from customer address." -#~ "(Address Type = Other)" -#~ msgstr "" -#~ "La dirección a la que enviar notificaciones, si es diferente de la " -#~ "dirección del cliente. (Tipo de dirección = Otro)" - -#~ msgid "Use parties content" -#~ msgstr "Usar contenido de partes" - -#~ msgid "# Code editor" -#~ msgstr "# Editor de código" - -#~ msgid "Add branch" -#~ msgstr "Agregar rama" - -#~ msgid "Add filter" -#~ msgstr "Agregar filtro" - -#~ msgid "Add new value" -#~ msgstr "Agregar nuevo valor" - -#~ msgid "Add node" -#~ msgstr "Agregar nodo" - -#~ msgid "Add tag" -#~ msgstr "Agregar etiqueta" - -#~ msgid "Agreement Clause Search" -#~ msgstr "Búsqueda de Cláusula de Acuerdo" - -#~ msgid "Agreement Increase Type" -#~ msgstr "Tipo de Aumento de Acuerdo" - -#~ msgid "Agreement Renewal Type" -#~ msgstr "Tipo de Renovación del Acuerdo" - -#~ msgid "Agreement Section Search" -#~ msgstr "Búsqueda de Sección de Acuerdo" - -#~ msgid "Agreements Type Form" -#~ msgstr "Formulario de Tipo de Acuerdos" - -#~ msgid "Close" -#~ msgstr "Cerrado" - -#~ msgid "Contract Document" -#~ msgstr "Documento de Contrato" - -#~ msgid "Contract Document Preview" -#~ msgstr "Vista previa del Documento del Contrato" - -#~ msgid "Currency" -#~ msgstr "Moneda" - -#~ msgid "Delete node" -#~ msgstr "Eliminar nodo" - -#~ msgid "Describes what happens after the contract expires." -#~ msgstr "Describe lo que sucede después de que expira el contrato." - -#~ msgid "Description of the renewal type." -#~ msgstr "Descripción del tipo de renovación." - -#~ msgid "Domain" -#~ msgstr "Dominio" - -#~ msgid "Edit Domain" -#~ msgstr "Editar Dominio" - -#~ msgid "Field Expression" -#~ msgstr "Expresión de Campo" - -#~ msgid "Increase Percentage" -#~ msgstr "Porcentaje de Aumento" - -#~ msgid "Increase Type" -#~ msgstr "Aumentar tipo" - -#~ msgid "Increase Types" -#~ msgstr "Aumentar tipos" - -#~ msgid "" -#~ "Increase types describe any increases that may happen during the contract." -#~ msgstr "" -#~ "Los tipos de aumento describen cualquier aumento que pueda ocurrir " -#~ "durante el contrato." - -#~ msgid "Invalid domain" -#~ msgstr "Dominio inválido" - -#~ msgid "Invalid field chain" -#~ msgstr "Cadena de campo inválida" - -#~ msgid "Manage Agreements" -#~ msgstr "Gestionar Acuerdos" - -#~ msgid "Match" -#~ msgstr "Relacionar" - -#~ msgid "Match records with" -#~ msgstr "Relacionar registros con" - -#~ msgid "Match records with the following rule:" -#~ msgstr "Haga coincidir los registros con la siguiente regla:" - -#~ msgid "" -#~ "Number of months this agreement/contract is in effect with the partner." -#~ msgstr "" -#~ "Número de meses que este acuerdo / contrato está vigente con el socio." - -#~ msgid "Percentage that the amount will increase." -#~ msgstr "Porcentaje que aumentará la cantidad." - -#~ msgid "Please navigate below and select field:" -#~ msgstr "Navegue a continuación y seleccione el campo:" - -#~ msgid "Previous" -#~ msgstr "Previo" - -#~ msgid "Product Template" -#~ msgstr "Plantilla de Producto" - -#~ msgid "Products & Services" -#~ msgstr "Productos y Servicios" - -#~ msgid "Remove tag" -#~ msgstr "Remover etiqueta" - -#~ msgid "Renewal Type" -#~ msgstr "Tipo de Renovación" - -#~ msgid "Renewal Types" -#~ msgstr "Tipos de Renovación" - -#~ msgid "" -#~ "Renewal types describe what happens after the agreement/contract expires." -#~ msgstr "" -#~ "Los tipos de renovación describen lo que sucede después de que expira el " -#~ "acuerdo / contrato." - -#~ msgid "SMatch" -#~ msgstr "SRelacionar" - -#~ msgid "SSMatch records with" -#~ msgstr "SSRelacionar registros con" - -#~ msgid "Select a model to add a filter." -#~ msgstr "Seleccione un modelo para agregar un filtro." - -#~ msgid "Select the agreement field using the popup" -#~ msgstr "Seleccione el campo del acuerdo usando la ventana emergente" - -#~ msgid "Select the field using the popup" -#~ msgstr "Seleccione el campo usando la ventana emergente" - -#~ msgid "Service Profile" -#~ msgstr "Perfil de Servicio" - -#~ msgid "Subtypes" -#~ msgstr "Subtipos" - -#~ msgid "Term (Months)" -#~ msgstr "Plazo (meses)" - -#~ msgid "The amount that certain rates may increase." -#~ msgstr "La cantidad que ciertas tarifas pueden aumentar." - -#~ msgid "The title is displayed on the PDF.The name is not." -#~ msgstr "El título se muestra en el PDF. El nombre no." - -#~ msgid "Warning" -#~ msgstr "Advertencia" - -#~ msgid "all records" -#~ msgstr "todos los registros" - -#~ msgid "is" -#~ msgstr "es" - -#~ msgid "not" -#~ msgstr "no" - -#~ msgid "of the following rules:" -#~ msgstr "de las siguientes reglas:" - -#~ msgid "or" -#~ msgstr "o" - -#~ msgid "record(s)" -#~ msgstr "registro(s)" - -#~ msgid "set" -#~ msgstr "establecer" diff --git a/agreement_legal/models/agreement.py b/agreement_legal/models/agreement.py index 9e8fc4624..6383845ce 100644 --- a/agreement_legal/models/agreement.py +++ b/agreement_legal/models/agreement.py @@ -294,6 +294,58 @@ def _alert_to_review_date(self): note=_("Your activity is going to end soon"), ) + @api.model + def recompute_from_template(self): + agreements = self.browse(self.env.context.get("active_ids", [])).filtered( + lambda a: a.template_id + ) + for agreement in agreements: + template = agreement.template_id + agreement.recital_ids.unlink() + agreement.sections_ids.unlink() + agreement.clauses_ids.unlink() + agreement.appendix_ids.unlink() + agreement.line_ids.unlink() + agreement.child_agreements_ids.unlink() + for recital in template.recital_ids: + recital.copy({"agreement_id": agreement.id}) + + section_map = {} + for section in template.sections_ids: + new_section = section.copy( + { + "agreement_id": agreement.id, + # Copy clauses explicitly below to avoid duplicated clauses. + "clauses_ids": False, + } + ) + section_map[section.id] = new_section.id + + for clause in template.clauses_ids: + values = {"agreement_id": agreement.id} + if clause.section_id: + values["section_id"] = section_map.get(clause.section_id.id) + clause.copy(values) + + for appendix in template.appendix_ids: + appendix.copy({"agreement_id": agreement.id}) + + for line in template.line_ids: + line.copy({"agreement_id": agreement.id}) + + for child in template.child_agreements_ids: + child.copy({"parent_agreement_id": agreement.id}) + + agreement.write( + { + "reviewed_user_id": self.env.uid, + "reviewed_date": fields.Date.today(), + } + ) + agreement.message_post( + body=_("Agreement recomputed from template %s") % template.display_name + ) + # compute the dynamic content for jinja expression def _compute_dynamic_description(self): MailTemplates = self.env["mail.template"] diff --git a/agreement_legal/readme/CONTRIBUTORS.md b/agreement_legal/readme/CONTRIBUTORS.md index b5cc36d63..516627543 100644 --- a/agreement_legal/readme/CONTRIBUTORS.md +++ b/agreement_legal/readme/CONTRIBUTORS.md @@ -7,4 +7,5 @@ - Tharathip Chaweewongphan \<\> - Italo LOPES \<\> - [APSL-Nagarro](https://www.apsl.tech): - - Antoni Marroig \<\> \ No newline at end of file + - Antoni Marroig \<\> + - Miquel Alzanillas \<\> diff --git a/agreement_legal/static/description/index.html b/agreement_legal/static/description/index.html index 538cfd589..5a332da1e 100644 --- a/agreement_legal/static/description/index.html +++ b/agreement_legal/static/description/index.html @@ -3,7 +3,7 @@ -README.rst +Agreements Legal -
+ -
diff --git a/agreement_legal/tests/test_agreement.py b/agreement_legal/tests/test_agreement.py index 6fcfa5c44..0aa7c3a44 100644 --- a/agreement_legal/tests/test_agreement.py +++ b/agreement_legal/tests/test_agreement.py @@ -161,3 +161,86 @@ def test_partner_action(self): self.test_agreement, self.env[action["res_model"]].search(action["domain"]) ) self.assertEqual(1, self.test_agreement.partner_id.agreements_count) + + def test_recompute_logic(self): + self.template = self.env["agreement"].create( + { + "name": "Template Agreement", + "is_template": True, + } + ) + + self.section = self.env["agreement.section"].create( + { + "name": "Section Test", + "agreement_id": self.template.id, + } + ) + + self.clause = self.env["agreement.clause"].create( + { + "name": "Clause Test", + "agreement_id": self.template.id, + "section_id": self.section.id, + } + ) + + self.appendix = self.env["agreement.appendix"].create( + { + "name": "Appendix A", + "agreement_id": self.template.id, + "title": "Anex A", + } + ) + + self.test_agreement.template_id = self.template.id + + self.old_appendix = self.env["agreement.appendix"].create( + { + "name": "Appendix Old", + "agreement_id": self.test_agreement.id, + "title": "Anex Old", + } + ) + self.test_agreement.with_context( + active_ids=self.test_agreement.ids, + ).recompute_from_template() + + self.assertEqual(len(self.test_agreement.sections_ids), 1) + new_section = self.test_agreement.sections_ids[0] + self.assertEqual(len(new_section.clauses_ids), 1) + self.assertEqual(len(self.test_agreement.clauses_ids), 1) + self.assertEqual(self.test_agreement.clauses_ids.section_id, new_section) + child_template = self.env["agreement"].create( + { + "name": "Child Agreement of Template", + "parent_agreement_id": self.template.id, + "is_template": True, + } + ) + self.template.child_agreements_ids = [(4, child_template.id)] + + self.test_agreement.with_context( + active_ids=self.test_agreement.ids + ).recompute_from_template() + + self.assertEqual( + len(self.test_agreement.child_agreements_ids), + 1, + ) + + new_child = self.test_agreement.child_agreements_ids[0] + + self.assertEqual( + new_child.name, + "Child Agreement of Template", + "El nombre del acuerdo hijo no coincide", + ) + self.assertEqual( + new_child.parent_agreement_id.id, + self.test_agreement.id, + ) + self.assertNotEqual( + new_child.id, + child_template.id, + )