From e076c3762cea307cd682cf30d38678bd776e11cd Mon Sep 17 00:00:00 2001 From: Oihane Crucelaegui Date: Tue, 10 Sep 2024 15:25:54 +0200 Subject: [PATCH] [FIX] mrp_repair_cancel_reason: wizard does not launch + permissions + dependencies --- mrp_repair_cancel_reason/README.rst | 7 +- mrp_repair_cancel_reason/__manifest__.py | 12 +- mrp_repair_cancel_reason/i18n/es.po | 139 +++++++ .../i18n/mrp_repair_cancel_reason.pot | 138 +++++++ .../models/repair_order.py | 41 +- .../security/ir.model.access.csv | 5 +- .../tests/test_repair_order_cancel_reason.py | 353 ++++++++++++++++-- .../views/repair_order_cancel_reason_view.xml | 9 +- .../views/repair_order_view.xml | 17 - .../wizard/wiz_repair_order_cancel_reason.py | 26 +- .../wiz_repair_order_cancel_reason_view.xml | 4 +- 11 files changed, 668 insertions(+), 83 deletions(-) create mode 100644 mrp_repair_cancel_reason/i18n/es.po create mode 100644 mrp_repair_cancel_reason/i18n/mrp_repair_cancel_reason.pot diff --git a/mrp_repair_cancel_reason/README.rst b/mrp_repair_cancel_reason/README.rst index bded134..84373f6 100644 --- a/mrp_repair_cancel_reason/README.rst +++ b/mrp_repair_cancel_reason/README.rst @@ -2,9 +2,10 @@ :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 -======================== -MRP repair cancel reason -======================== +==================== +Repair cancel reason +==================== + This module creates the new object "Repair Cancel Reason". When canceling a repair, we will display a wizard in which you have to select the "reason for cancellation". By confirming the wizard, the "reason for diff --git a/mrp_repair_cancel_reason/__manifest__.py b/mrp_repair_cancel_reason/__manifest__.py index 1153801..2e403b6 100644 --- a/mrp_repair_cancel_reason/__manifest__.py +++ b/mrp_repair_cancel_reason/__manifest__.py @@ -1,21 +1,15 @@ # (c) 2015 Alfredo de la Fuente - AvanzOSC # License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html { - "name": "MRP Repair Cancel Reason", + "name": "Repair Cancel Reason", "version": "16.0.1.0.0", "license": "AGPL-3", "author": "AvanzOSC", "website": "https://github.com/avanzosc/mrp-repair-addons", - "contributors": [ - "Ana Juaristi ", - "Alfredo de la Fuente ", - ], - "category": "Manufacturing", + "category": "Inventory/Inventory", "depends": [ - "product", - "stock", - "mrp", "repair", + "stock", ], "data": [ "security/ir.model.access.csv", diff --git a/mrp_repair_cancel_reason/i18n/es.po b/mrp_repair_cancel_reason/i18n/es.po new file mode 100644 index 0000000..4adba9c --- /dev/null +++ b/mrp_repair_cancel_reason/i18n/es.po @@ -0,0 +1,139 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mrp_repair_cancel_reason +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-09-18 11:58+0000\n" +"PO-Revision-Date: 2024-09-18 11:58+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: mrp_repair_cancel_reason +#: model:ir.model,name:mrp_repair_cancel_reason.model_wiz_repair_order_cancel_reason +msgid "Ask a reason from the repair cancellation" +msgstr "Preguntar la razón para cancelar la reparación" + +#. module: mrp_repair_cancel_reason +#: model_terms:ir.ui.view,arch_db:mrp_repair_cancel_reason.wiz_repair_order_cancel_reason_form_view +msgid "Cancel" +msgstr "Cancelar" + +#. module: mrp_repair_cancel_reason +#: model:repair.order.cancel.reason,name:mrp_repair_cancel_reason.mrp_cancel_reason_customer +msgid "Canceled at customer request" +msgstr "Cancelado por petición del cliente" + +#. module: mrp_repair_cancel_reason +#: model_terms:ir.ui.view,arch_db:mrp_repair_cancel_reason.wiz_repair_order_cancel_reason_form_view +msgid "Choose the reason for the cancellation of the repair." +msgstr "Seleccione la razón de la cancelación de la reparación." + +#. module: mrp_repair_cancel_reason +#: model_terms:ir.ui.view,arch_db:mrp_repair_cancel_reason.wiz_repair_order_cancel_reason_form_view +msgid "Confirm" +msgstr "Confirmar" + +#. module: mrp_repair_cancel_reason +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_repair_order_cancel_reason__create_uid +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_wiz_repair_order_cancel_reason__create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: mrp_repair_cancel_reason +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_repair_order_cancel_reason__create_date +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_wiz_repair_order_cancel_reason__create_date +msgid "Created on" +msgstr "Creado el" + +#. module: mrp_repair_cancel_reason +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_repair_order_cancel_reason__display_name +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_wiz_repair_order_cancel_reason__display_name +msgid "Display Name" +msgstr "Nombre mostrado" + +#. module: mrp_repair_cancel_reason +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_repair_order_cancel_reason__id +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_wiz_repair_order_cancel_reason__id +msgid "ID" +msgstr "" + +#. module: mrp_repair_cancel_reason +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_repair_order_cancel_reason____last_update +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_wiz_repair_order_cancel_reason____last_update +msgid "Last Modified on" +msgstr "Última modificación el" + +#. module: mrp_repair_cancel_reason +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_repair_order_cancel_reason__write_uid +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_wiz_repair_order_cancel_reason__write_uid +msgid "Last Updated by" +msgstr "Última actualización por" + +#. module: mrp_repair_cancel_reason +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_repair_order_cancel_reason__write_date +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_wiz_repair_order_cancel_reason__write_date +msgid "Last Updated on" +msgstr "Última actualización el" + +#. module: mrp_repair_cancel_reason +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_repair_order_cancel_reason__name +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_wiz_repair_order_cancel_reason__reason_id +msgid "Reason" +msgstr "Razón" + +#. module: mrp_repair_cancel_reason +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_repair_order__cancel_reason_id +msgid "Reason for cancellation" +msgstr "Razón para la cancelación" + +#. module: mrp_repair_cancel_reason +#: model:ir.actions.act_window,name:mrp_repair_cancel_reason.action_repair_order_cancel_with_reason +#: model_terms:ir.ui.view,arch_db:mrp_repair_cancel_reason.wiz_repair_order_cancel_reason_form_view +msgid "Reason for the cancellation" +msgstr "Razón para la cancelación" + +#. module: mrp_repair_cancel_reason +#: model:ir.actions.act_window,name:mrp_repair_cancel_reason.action_repair_order_cancel_reason +#: model:ir.model,name:mrp_repair_cancel_reason.model_repair_order_cancel_reason +#: model:ir.ui.menu,name:mrp_repair_cancel_reason.menu_repair_order_cancel_reason +msgid "Repair Cancel Reason" +msgstr "Razón de cancelación de reparación" + +#. module: mrp_repair_cancel_reason +#: model:ir.model,name:mrp_repair_cancel_reason.model_repair_order +msgid "Repair Order" +msgstr "Orden de reparación" + +#. module: mrp_repair_cancel_reason +#. odoo-python +#: code:addons/mrp_repair_cancel_reason/models/repair_order.py:0 +#, python-format +msgid "Repair must be canceled in order to reset it to draft." +msgstr "" +"La reparación debe de estar cancelada para poder ser puesta en borrador." + +#. module: mrp_repair_cancel_reason +#. odoo-python +#: code:addons/mrp_repair_cancel_reason/models/repair_order.py:0 +#, python-format +msgid "You cannot cancel a completed repair order." +msgstr "No puede cancelar una orden de reparación completada." + +#. module: mrp_repair_cancel_reason +#. odoo-python +#: code:addons/mrp_repair_cancel_reason/models/repair_order.py:0 +#, python-format +msgid "You cannot cancel a repair order with done stock moves." +msgstr "No puede cancelar una orden con movimientos de stock realizados." + +#. module: mrp_repair_cancel_reason +#: model_terms:ir.ui.view,arch_db:mrp_repair_cancel_reason.wiz_repair_order_cancel_reason_form_view +msgid "or" +msgstr "o" diff --git a/mrp_repair_cancel_reason/i18n/mrp_repair_cancel_reason.pot b/mrp_repair_cancel_reason/i18n/mrp_repair_cancel_reason.pot new file mode 100644 index 0000000..cf93161 --- /dev/null +++ b/mrp_repair_cancel_reason/i18n/mrp_repair_cancel_reason.pot @@ -0,0 +1,138 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mrp_repair_cancel_reason +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-09-18 11:58+0000\n" +"PO-Revision-Date: 2024-09-18 11:58+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: mrp_repair_cancel_reason +#: model:ir.model,name:mrp_repair_cancel_reason.model_wiz_repair_order_cancel_reason +msgid "Ask a reason from the repair cancellation" +msgstr "" + +#. module: mrp_repair_cancel_reason +#: model_terms:ir.ui.view,arch_db:mrp_repair_cancel_reason.wiz_repair_order_cancel_reason_form_view +msgid "Cancel" +msgstr "" + +#. module: mrp_repair_cancel_reason +#: model:repair.order.cancel.reason,name:mrp_repair_cancel_reason.mrp_cancel_reason_customer +msgid "Canceled at customer request" +msgstr "" + +#. module: mrp_repair_cancel_reason +#: model_terms:ir.ui.view,arch_db:mrp_repair_cancel_reason.wiz_repair_order_cancel_reason_form_view +msgid "Choose the reason for the cancellation of the repair." +msgstr "" + +#. module: mrp_repair_cancel_reason +#: model_terms:ir.ui.view,arch_db:mrp_repair_cancel_reason.wiz_repair_order_cancel_reason_form_view +msgid "Confirm" +msgstr "" + +#. module: mrp_repair_cancel_reason +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_repair_order_cancel_reason__create_uid +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_wiz_repair_order_cancel_reason__create_uid +msgid "Created by" +msgstr "" + +#. module: mrp_repair_cancel_reason +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_repair_order_cancel_reason__create_date +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_wiz_repair_order_cancel_reason__create_date +msgid "Created on" +msgstr "" + +#. module: mrp_repair_cancel_reason +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_repair_order_cancel_reason__display_name +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_wiz_repair_order_cancel_reason__display_name +msgid "Display Name" +msgstr "" + +#. module: mrp_repair_cancel_reason +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_repair_order_cancel_reason__id +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_wiz_repair_order_cancel_reason__id +msgid "ID" +msgstr "" + +#. module: mrp_repair_cancel_reason +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_repair_order_cancel_reason____last_update +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_wiz_repair_order_cancel_reason____last_update +msgid "Last Modified on" +msgstr "" + +#. module: mrp_repair_cancel_reason +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_repair_order_cancel_reason__write_uid +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_wiz_repair_order_cancel_reason__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: mrp_repair_cancel_reason +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_repair_order_cancel_reason__write_date +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_wiz_repair_order_cancel_reason__write_date +msgid "Last Updated on" +msgstr "" + +#. module: mrp_repair_cancel_reason +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_repair_order_cancel_reason__name +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_wiz_repair_order_cancel_reason__reason_id +msgid "Reason" +msgstr "" + +#. module: mrp_repair_cancel_reason +#: model:ir.model.fields,field_description:mrp_repair_cancel_reason.field_repair_order__cancel_reason_id +msgid "Reason for cancellation" +msgstr "" + +#. module: mrp_repair_cancel_reason +#: model:ir.actions.act_window,name:mrp_repair_cancel_reason.action_repair_order_cancel_with_reason +#: model_terms:ir.ui.view,arch_db:mrp_repair_cancel_reason.wiz_repair_order_cancel_reason_form_view +msgid "Reason for the cancellation" +msgstr "" + +#. module: mrp_repair_cancel_reason +#: model:ir.actions.act_window,name:mrp_repair_cancel_reason.action_repair_order_cancel_reason +#: model:ir.model,name:mrp_repair_cancel_reason.model_repair_order_cancel_reason +#: model:ir.ui.menu,name:mrp_repair_cancel_reason.menu_repair_order_cancel_reason +msgid "Repair Cancel Reason" +msgstr "" + +#. module: mrp_repair_cancel_reason +#: model:ir.model,name:mrp_repair_cancel_reason.model_repair_order +msgid "Repair Order" +msgstr "" + +#. module: mrp_repair_cancel_reason +#. odoo-python +#: code:addons/mrp_repair_cancel_reason/models/repair_order.py:0 +#, python-format +msgid "Repair must be canceled in order to reset it to draft." +msgstr "" + +#. module: mrp_repair_cancel_reason +#. odoo-python +#: code:addons/mrp_repair_cancel_reason/models/repair_order.py:0 +#, python-format +msgid "You cannot cancel a completed repair order." +msgstr "" + +#. module: mrp_repair_cancel_reason +#. odoo-python +#: code:addons/mrp_repair_cancel_reason/models/repair_order.py:0 +#, python-format +msgid "You cannot cancel a repair order with done stock moves." +msgstr "" + +#. module: mrp_repair_cancel_reason +#: model_terms:ir.ui.view,arch_db:mrp_repair_cancel_reason.wiz_repair_order_cancel_reason_form_view +msgid "or" +msgstr "" diff --git a/mrp_repair_cancel_reason/models/repair_order.py b/mrp_repair_cancel_reason/models/repair_order.py index 0f259dd..5a88580 100644 --- a/mrp_repair_cancel_reason/models/repair_order.py +++ b/mrp_repair_cancel_reason/models/repair_order.py @@ -1,21 +1,56 @@ # (c) 2015 Alfredo de la Fuente - AvanzOSC # License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html -from odoo import fields, models +from odoo import _, fields, models +from odoo.exceptions import UserError class MrpRepair(models.Model): _inherit = "repair.order" cancel_reason_id = fields.Many2one( - "repair.order.cancel.reason", + comodel_name="repair.order.cancel.reason", string="Reason for cancellation", readonly=True, + copy=False, ondelete="restrict", ) + def action_repair_cancel(self): + if any(move.state == "done" for move in self.mapped("move_id")): + raise UserError( + _("You cannot cancel a repair order if it is already finished.") + ) + if any(move.state == "done" for move in self.mapped("operations.move_id")): + raise UserError( + _("You cannot cancel a repair order with done stock moves.") + ) + if any(repair.state == "done" for repair in self): + raise UserError(_("You cannot cancel a completed repair order.")) + if not all(repair.cancel_reason_id for repair in self): + action = self.env["ir.actions.actions"]._for_xml_id( + "mrp_repair_cancel_reason.action_repair_order_cancel_with_reason" + ) + action["context"] = dict(self._context, create=False) + return action + return super().action_repair_cancel() + + def action_repair_cancel_draft(self): + if self.filtered(lambda repair: repair.state != "cancel"): + raise UserError(_("Repair must be canceled in order to reset it to draft.")) + self.write( + { + "cancel_reason_id": False, + } + ) + return super().action_repair_cancel_draft() + class MrpRepairCancelReason(models.Model): _name = "repair.order.cancel.reason" _description = "Repair Cancel Reason" - name = fields.Char("Reason", required=True, translate=True) + name = fields.Char( + string="Reason", + required=True, + translate=True, + ) diff --git a/mrp_repair_cancel_reason/security/ir.model.access.csv b/mrp_repair_cancel_reason/security/ir.model.access.csv index e89ef10..b523ee9 100644 --- a/mrp_repair_cancel_reason/security/ir.model.access.csv +++ b/mrp_repair_cancel_reason/security/ir.model.access.csv @@ -1,3 +1,4 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_repair_order_cancel_reason_user,access_repair_order_cancel_reason user,model_repair_order_cancel_reason,mrp.group_mrp_user,1,0,0,0 -access_repair_order_cancel_reason_manager,access_repair_order_cancel_reason manager,model_repair_order_cancel_reason,mrp.group_mrp_manager,1,1,1,1 +access_repair_order_cancel_reason_user,access_repair_order_cancel_reason user,model_repair_order_cancel_reason,stock.group_stock_user,1,0,0,0 +access_repair_order_cancel_reason_manager,access_repair_order_cancel_reason manager,model_repair_order_cancel_reason,stock.group_stock_manager,1,1,1,1 +access_wiz_repair_order_cancel_reason,access_wiz_repair_order_cancel_reason,mrp_repair_cancel_reason.model_wiz_repair_order_cancel_reason,stock.group_stock_user,1,1,1,1 diff --git a/mrp_repair_cancel_reason/tests/test_repair_order_cancel_reason.py b/mrp_repair_cancel_reason/tests/test_repair_order_cancel_reason.py index 4ffdcab..b974343 100644 --- a/mrp_repair_cancel_reason/tests/test_repair_order_cancel_reason.py +++ b/mrp_repair_cancel_reason/tests/test_repair_order_cancel_reason.py @@ -1,53 +1,342 @@ -# (c) 2015 Alfredo de la Fuente - AvanzOSC +# Copyright 2015 Alfredo de la Fuente - AvanzOSC # License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html -import openerp.tests.common as common +from odoo.exceptions import UserError +from odoo.tests import common, tagged + +@tagged("post_install", "-at_install") class TestMrpRepairCancelReason(common.TransactionCase): - def setUp(self): - super().setUp() - self.data_model = self.env["ir.model.data"] - self.repair_order_model = self.env["repair.order"] - self.wiz_model = self.env["wiz.repair.order.cancel.reason"] - self.product = self.env.ref("product.product_product_6") - self.warehouse = self.data_model.get_object("stock", "warehouse0") - vals = { - "product_id": self.product.id, - "location_id": self.warehouse.lot_stock_id.id, - "location_dest_id": self.warehouse.lot_stock_id.id, - "product_uom": self.product.uom_id.id, - } - self.repair_order = self.repair_order_model.create(vals) - self.reason = self.env.ref( - "repair_order_cancel_reason.mrp_cancel_reason_customer" - ) - - def test_wizard_cancel_draft_repair_with_reason(self): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.wiz_model = cls.env["wiz.repair.order.cancel.reason"] + cls.reason = cls.env.ref("mrp_repair_cancel_reason.mrp_cancel_reason_customer") + + # Partners + cls.res_partner_1 = cls.env["res.partner"].create({"name": "Wood Corner"}) + cls.res_partner_address_1 = cls.env["res.partner"].create( + {"name": "Willie Burke", "parent_id": cls.res_partner_1.id} + ) + cls.res_partner_12 = cls.env["res.partner"].create({"name": "Partner 12"}) + + # Products + cls.product_product_3 = cls.env["product.product"].create( + {"name": "Desk Combination"} + ) + cls.product_product_11 = cls.env["product.product"].create( + {"name": "Conference Chair"} + ) + cls.product_product_5 = cls.env["product.product"].create({"name": "Product 5"}) + cls.product_product_6 = cls.env["product.product"].create( + {"name": "Large Cabinet"} + ) + cls.product_product_12 = cls.env["product.product"].create( + {"name": "Office Chair Black"} + ) + cls.product_product_13 = cls.env["product.product"].create( + {"name": "Corner Desk Left Sit"} + ) + cls.product_product_2 = cls.env["product.product"].create( + {"name": "Virtual Home Staging"} + ) + cls.product_service_order_repair = cls.env["product.product"].create( + { + "name": "Repair Services", + "type": "service", + } + ) + + # Location + cls.stock_warehouse = cls.env["stock.warehouse"].search( + [("company_id", "=", cls.env.company.id)], limit=1 + ) + cls.stock_location_14 = cls.env["stock.location"].create( + { + "name": "Shelf 2", + "location_id": cls.stock_warehouse.lot_stock_id.id, + } + ) + + # Repair Orders + cls.repair1 = cls.env["repair.order"].create( + { + "address_id": cls.res_partner_address_1.id, + "guarantee_limit": "2019-01-01", + "invoice_method": "none", + "user_id": False, + "product_id": cls.product_product_3.id, + "product_uom": cls.env.ref("uom.product_uom_unit").id, + "partner_invoice_id": cls.res_partner_address_1.id, + "location_id": cls.stock_warehouse.lot_stock_id.id, + "operations": [ + ( + 0, + 0, + { + "location_dest_id": ( + cls.product_product_11.property_stock_production.id + ), + "location_id": cls.stock_warehouse.lot_stock_id.id, + "name": cls.product_product_11.name, + "product_id": cls.product_product_11.id, + "product_uom": cls.env.ref("uom.product_uom_unit").id, + "product_uom_qty": 1.0, + "price_unit": 50.0, + "state": "draft", + "type": "add", + "company_id": cls.env.company.id, + }, + ) + ], + "fees_lines": [ + ( + 0, + 0, + { + "name": cls.product_service_order_repair.name, + "product_id": cls.product_service_order_repair.id, + "product_uom_qty": 1.0, + "product_uom": cls.env.ref("uom.product_uom_unit").id, + "price_unit": 50.0, + "company_id": cls.env.company.id, + }, + ) + ], + "partner_id": cls.res_partner_12.id, + } + ) + + cls.repair0 = cls.env["repair.order"].create( + { + "product_id": cls.product_product_5.id, + "product_uom": cls.env.ref("uom.product_uom_unit").id, + "address_id": cls.res_partner_address_1.id, + "invoice_method": "after_repair", + "partner_invoice_id": cls.res_partner_address_1.id, + "location_id": cls.stock_warehouse.lot_stock_id.id, + "operations": [ + ( + 0, + 0, + { + "location_dest_id": ( + cls.product_product_12.property_stock_production.id + ), + "location_id": cls.stock_warehouse.lot_stock_id.id, + "name": cls.product_product_12.name, + "price_unit": 50.0, + "product_id": cls.product_product_12.id, + "product_uom": cls.env.ref("uom.product_uom_unit").id, + "product_uom_qty": 1.0, + "state": "draft", + "type": "add", + "company_id": cls.env.company.id, + }, + ) + ], + "fees_lines": [ + ( + 0, + 0, + { + "name": cls.product_service_order_repair.name, + "product_id": cls.product_service_order_repair.id, + "product_uom_qty": 1.0, + "product_uom": cls.env.ref("uom.product_uom_unit").id, + "price_unit": 50.0, + "company_id": cls.env.company.id, + }, + ) + ], + "partner_id": cls.res_partner_12.id, + } + ) + + cls.repair2 = cls.env["repair.order"].create( + { + "product_id": cls.product_product_6.id, + "product_uom": cls.env.ref("uom.product_uom_unit").id, + "address_id": cls.res_partner_address_1.id, + "invoice_method": "b4repair", + "partner_invoice_id": cls.res_partner_address_1.id, + "location_id": cls.stock_location_14.id, + "operations": [ + ( + 0, + 0, + { + "location_dest_id": ( + cls.product_product_13.property_stock_production.id + ), + "location_id": cls.stock_warehouse.lot_stock_id.id, + "name": cls.product_product_13.name, + "price_unit": 50.0, + "product_id": cls.product_product_13.id, + "product_uom": cls.env.ref("uom.product_uom_unit").id, + "product_uom_qty": 1.0, + "state": "draft", + "type": "add", + "company_id": cls.env.company.id, + }, + ) + ], + "fees_lines": [ + ( + 0, + 0, + { + "name": cls.product_service_order_repair.name, + "product_id": cls.product_service_order_repair.id, + "product_uom_qty": 1.0, + "product_uom": cls.env.ref("uom.product_uom_unit").id, + "price_unit": 50.0, + "company_id": cls.env.company.id, + }, + ) + ], + "partner_id": cls.res_partner_12.id, + } + ) + + cls.env.user.groups_id |= cls.env.ref("stock.group_stock_user") + + def test_no_invoice_cancel_under_repair(self): + self.assertEqual( + self.repair1.invoice_method, + "none", + "Repair order invoice method should be 'none'", + ) + self.repair1.action_repair_confirm() + self.repair1.action_repair_start() + self.assertEqual( + self.repair1.state, + "under_repair", + "Repair order should be in 'under_repair' state", + ) vals = {"reason_id": self.reason.id} wiz = self.wiz_model.create(vals) - wiz.with_context(active_ids=[self.repair_order.id]).confirm_cancel() + wiz.with_context(active_ids=[self.repair1.id]).confirm_cancel() self.assertEqual( - self.repair_order.state, "cancel", "Repair order not in CANCEL state" + self.repair1.state, "cancel", "Repair order should be in 'cancel' state" ) self.assertEqual( - self.repair_order.cancel_reason_id.id, + self.repair1.cancel_reason_id.id, self.reason.id, - "Repair order canceled without cancel reason", + "Repair order should have a cancel reason", + ) + self.repair1.action_repair_cancel_draft() + self.assertFalse( + self.repair1.cancel_reason_id.id, + "Repair order should have erased cancel reason", ) - def test_wizard_cancel_confirmed_repair_with_reason(self): - self.repair_order.signal_workflow("repair_confirm") + def test_no_invoice_cancel_done(self): + self.assertEqual( + self.repair1.invoice_method, + "none", + "Repair order invoice method should be 'none'", + ) + self.repair1.action_repair_confirm() + self.repair1.action_repair_start() + self.repair1.action_repair_end() + self.assertEqual( + self.repair1.state, "done", "Repair order should be in 'done' state" + ) vals = {"reason_id": self.reason.id} wiz = self.wiz_model.create(vals) - wiz.with_context(active_ids=[self.repair_order.id]).confirm_cancel() + with self.assertRaises(UserError): + wiz.with_context(active_ids=[self.repair1.id]).confirm_cancel() + + def test_cancel_b4repair_under_repair(self): self.assertEqual( - self.repair_order.state, + self.repair2.invoice_method, + "b4repair", + "Repair order invoice method should be 'b4repair'", + ) + self.repair2.action_repair_confirm() + self.repair2.action_repair_invoice_create() + self.repair2.action_repair_start() + self.assertEqual( + self.repair2.state, + "under_repair", + "Repair order should be in 'under_repair' state", + ) + vals = {"reason_id": self.reason.id} + wiz = self.wiz_model.create(vals) + wiz.with_context(active_ids=[self.repair2.id]).confirm_cancel() + self.assertEqual( + self.repair2.state, + "cancel", + "Repair order should be in 'cancel' state", + ) + self.assertEqual( + self.repair2.cancel_reason_id.id, + self.reason.id, + "Repair order should have a cancel reason", + ) + + def test_cancel_b4repair_done(self): + self.assertEqual( + self.repair2.invoice_method, + "b4repair", + "Repair order invoice method should be 'b4repair'", + ) + self.repair2.action_repair_confirm() + self.repair2.action_repair_invoice_create() + self.repair2.action_repair_start() + self.repair2.action_repair_end() + self.assertEqual( + self.repair2.state, "done", "Repair order should be in 'done' state" + ) + vals = {"reason_id": self.reason.id} + wiz = self.wiz_model.create(vals) + with self.assertRaises(UserError): + wiz.with_context(active_ids=[self.repair2.id]).confirm_cancel() + + def test_cancel_after_repair_under_repair(self): + self.assertEqual( + self.repair0.invoice_method, + "after_repair", + "Repair order invoice method should be 'after_repair'", + ) + self.repair0.action_repair_confirm() + self.repair0.action_repair_start() + self.assertEqual( + self.repair0.state, + "under_repair", + "Repair order should be in 'under_repair' state", + ) + vals = {"reason_id": self.reason.id} + wiz = self.wiz_model.create(vals) + wiz.with_context(active_ids=[self.repair0.id]).confirm_cancel() + self.assertEqual( + self.repair0.state, "cancel", - "Confirmed Repair order not in CANCEL state", + "Repair order should be in 'cancel' state", ) self.assertEqual( - self.repair_order.cancel_reason_id.id, + self.repair0.cancel_reason_id.id, self.reason.id, - "Confirmed Repair order canceled without cancel reason", + "Repair order should have a cancel reason", + ) + + def test_cancel_after_repair_done(self): + self.assertEqual( + self.repair0.invoice_method, + "after_repair", + "Repair order invoice method should be 'after_repair'", ) + self.repair0.action_repair_confirm() + self.repair0.action_repair_start() + self.repair0.action_repair_end() + self.assertEqual( + self.repair0.state, + "2binvoiced", + "Repair order should be in '2binvoiced' state", + ) + vals = {"reason_id": self.reason.id} + wiz = self.wiz_model.create(vals) + with self.assertRaises(UserError): + wiz.with_context(active_ids=[self.repair0.id]).confirm_cancel() diff --git a/mrp_repair_cancel_reason/views/repair_order_cancel_reason_view.xml b/mrp_repair_cancel_reason/views/repair_order_cancel_reason_view.xml index 4d30147..fbb8f16 100644 --- a/mrp_repair_cancel_reason/views/repair_order_cancel_reason_view.xml +++ b/mrp_repair_cancel_reason/views/repair_order_cancel_reason_view.xml @@ -8,6 +8,7 @@ + repair.order.cancel.reason @@ -16,17 +17,17 @@ + Repair Cancel Reason repair.order.cancel.reason tree,form + + diff --git a/mrp_repair_cancel_reason/views/repair_order_view.xml b/mrp_repair_cancel_reason/views/repair_order_view.xml index 2ca40da..6b76f3a 100644 --- a/mrp_repair_cancel_reason/views/repair_order_view.xml +++ b/mrp_repair_cancel_reason/views/repair_order_view.xml @@ -7,23 +7,6 @@ - - True - - -