From 51d98febcf7310f78a1504908249d35d3094cebd Mon Sep 17 00:00:00 2001 From: Christopher Ormaza Date: Wed, 25 Sep 2024 09:24:27 -0500 Subject: [PATCH] [16.0][IMP] rma, add feature to require origin field in rma approval process --- rma/models/rma_operation.py | 4 +++ rma/models/rma_order_line.py | 12 ++++++++ rma/tests/test_rma.py | 41 +++++++++++++++++++++++++ rma/views/rma_operation_view.xml | 1 + rma_account/models/rma_order_line.py | 5 +++ rma_account/tests/test_rma_account.py | 35 +++++++++++++++++++++ rma_purchase/models/rma_order_line.py | 5 +++ rma_purchase/tests/test_rma_purchase.py | 36 +++++++++++++++++++++- rma_sale/models/rma_order_line.py | 5 +++ rma_sale/tests/test_rma_sale.py | 31 ++++++++++++++++++- 10 files changed, 173 insertions(+), 2 deletions(-) diff --git a/rma/models/rma_operation.py b/rma/models/rma_operation.py index bd3d0f167..8a2419d35 100644 --- a/rma/models/rma_operation.py +++ b/rma/models/rma_operation.py @@ -94,3 +94,7 @@ def _default_routes(self): required=True, default=lambda self: self.env.user.company_id, ) + require_origin_field_filled = fields.Boolean( + default=False, + help="RMA document can't be continue in process if at least one origin field is filled", + ) diff --git a/rma/models/rma_order_line.py b/rma/models/rma_order_line.py index 6ad55456f..95671d517 100644 --- a/rma/models/rma_order_line.py +++ b/rma/models/rma_order_line.py @@ -647,8 +647,20 @@ def _check_lot_assigned(self): % (rec.product_id.display_name) ) + @api.model + def _origin_fields(self): + return ["reference_move_id"] + + def _check_origin_fields_filled(self): + for rec in self.filtered(lambda x: x.operation_id.require_origin_field_filled): + if not any(rec[origin_field] for origin_field in self._origin_fields()): + raise UserError( + _("You should fill at least one origin field to continue") + ) + def action_rma_to_approve(self): self._check_lot_assigned() + self._check_origin_fields_filled() self.write({"state": "to_approve"}) for rec in self: if rec.product_id.rma_approval_policy == "one_step": diff --git a/rma/tests/test_rma.py b/rma/tests/test_rma.py index 5ab4bbd40..a88b37d57 100644 --- a/rma/tests/test_rma.py +++ b/rma/tests/test_rma.py @@ -1093,3 +1093,44 @@ def test_09_rma_state(self): self.assertEqual( rma.rma_line_ids.mapped("state"), ["approved", "approved", "approved"] ) + + def test_10_rma_require_origin_fields(self): + self.rma_cust_replace_op_id.write( + { + "require_origin_field_filled": True, + } + ) + rma_line = Form( + self.rma_line, + view=self.env.ref("rma.view_rma_line_form").id, + ) + rma_line.partner_id = self.partner_id + rma_line.operation_id = self.rma_cust_replace_op_id + rma_line.product_id = self.product_1 + rma_line = rma_line.save() + with self.assertRaises(UserError): + rma_line.action_rma_to_approve() + + self._create_inventory(self.product_1, 5, self.stock_location) + picking_type = self._get_picking_type( + self.wh, self.stock_location, self.customer_location + ) + picking = self._create_picking(self.partner_id, picking_type) + move_values = self._prepare_move( + self.product_1, + 5, + self.stock_location, + self.customer_location, + picking, + ) + move_created = self.env["stock.move"].create(move_values) + self._do_picking(picking) + + rma_line = Form( + rma_line, + view=self.env.ref("rma.view_rma_line_form").id, + ) + rma_line.reference_move_id = move_created + rma_line = rma_line.save() + rma_line.action_rma_to_approve() + self.assertIn(rma_line.state, ("to_approve", "approved")) diff --git a/rma/views/rma_operation_view.xml b/rma/views/rma_operation_view.xml index c2bb1b59e..62a2e6c3d 100644 --- a/rma/views/rma_operation_view.xml +++ b/rma/views/rma_operation_view.xml @@ -41,6 +41,7 @@ + diff --git a/rma_account/models/rma_order_line.py b/rma_account/models/rma_order_line.py index c96667e6e..57b4cdce6 100644 --- a/rma_account/models/rma_order_line.py +++ b/rma_account/models/rma_order_line.py @@ -130,6 +130,11 @@ def _compute_refund_count(self): ondelete="restrict", ) + @api.model + def _origin_fields(self): + res = super()._origin_fields() + return res + ["account_move_line_id"] + @api.depends("partner_id") def _compute_commercial_partner_id(self): for rma_line in self: diff --git a/rma_account/tests/test_rma_account.py b/rma_account/tests/test_rma_account.py index 871e976b9..f3c77b9fb 100644 --- a/rma_account/tests/test_rma_account.py +++ b/rma_account/tests/test_rma_account.py @@ -2,6 +2,7 @@ # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) from odoo import fields +from odoo.exceptions import UserError from odoo.fields import Date from odoo.tests import common from odoo.tests.common import Form @@ -303,3 +304,37 @@ def test_07_add_lines_from_rma(self): self.assertEqual(rma_1.product_id.id, bill_product.id) self.assertEqual(bill.rma_count, 1) self.assertEqual(bill.used_in_rma_count, 0) + + def test_08_rma_require_origin_fields(self): + partner = self.inv_customer.partner_id + operation = self.env.ref("rma.rma_operation_customer_replace") + rma_line = Form( + self.rma_line_obj, + view=self.env.ref("rma_account.view_rma_line_form").id, + ) + rma_line.partner_id = partner + rma_line.operation_id = operation + rma_line.product_id = self.product_1 + rma_line = rma_line.save() + self.assertFalse(bool(rma_line.reference_move_id)) + self.assertFalse(bool(rma_line.account_move_line_id)) + rma_line.operation_id.write( + { + "require_origin_field_filled": True, + } + ) + self.assertTrue(rma_line.operation_id.require_origin_field_filled) + with self.assertRaises(UserError): + rma_line.action_rma_to_approve() + + rma_line = Form( + rma_line, + view=self.env.ref("rma.view_rma_line_form").id, + ) + + move_line = self.inv_customer.invoice_line_ids[0] + + rma_line.account_move_line_id = move_line + rma_line = rma_line.save() + rma_line.action_rma_to_approve() + self.assertIn(rma_line.state, ("to_approve", "approved")) diff --git a/rma_purchase/models/rma_order_line.py b/rma_purchase/models/rma_order_line.py index a2e1aea4f..270d10797 100644 --- a/rma_purchase/models/rma_order_line.py +++ b/rma_purchase/models/rma_order_line.py @@ -88,6 +88,11 @@ def _compute_qty_purchase(self): compute="_compute_qty_purchase", ) + @api.model + def _origin_fields(self): + res = super()._origin_fields() + return res + ["purchase_order_line_id"] + @api.onchange("product_id", "partner_id") def _onchange_product_id(self): """Domain for purchase_order_line_id is computed here to make diff --git a/rma_purchase/tests/test_rma_purchase.py b/rma_purchase/tests/test_rma_purchase.py index 558d23894..591831967 100644 --- a/rma_purchase/tests/test_rma_purchase.py +++ b/rma_purchase/tests/test_rma_purchase.py @@ -1,8 +1,9 @@ # Copyright 2017-2022 ForgeFlow S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) +from odoo.exceptions import UserError from odoo.fields import Datetime -from odoo.tests import common +from odoo.tests import Form, common class TestRmaPurchase(common.TransactionCase): @@ -108,3 +109,36 @@ def test_02_fill_rma_from_po_line(self): rma._onchange_purchase_order_line_id() self.assertEqual(rma.product_id, self.product_1) self.assertEqual(rma.product_qty, 20.0) + + def test_03_rma_require_origin_fields(self): + rma_line = Form( + self.rma_line_obj.with_context(supplier=True), + view=self.env.ref("rma.view_rma_line_supplier_form").id, + ) + rma_line.partner_id = self.po.partner_id + rma_line.product_id = self.product_1 + rma_line.operation_id = self.env.ref("rma.rma_operation_supplier_replace") + rma_line = rma_line.save() + self.assertFalse(bool(rma_line.reference_move_id)) + self.assertFalse(bool(rma_line.account_move_line_id)) + self.assertFalse(bool(rma_line.purchase_order_line_id)) + rma_line.operation_id.write( + { + "require_origin_field_filled": True, + } + ) + self.assertTrue(rma_line.operation_id.require_origin_field_filled) + with self.assertRaises(UserError): + rma_line.action_rma_to_approve() + + rma_line = Form( + rma_line, + view=self.env.ref("rma.view_rma_line_supplier_form").id, + ) + + move_line = self.po.order_line[0] + + rma_line.purchase_order_line_id = move_line + rma_line = rma_line.save() + rma_line.action_rma_to_approve() + self.assertIn(rma_line.state, ("to_approve", "approved")) diff --git a/rma_sale/models/rma_order_line.py b/rma_sale/models/rma_order_line.py index 86c9aff46..c358592e2 100644 --- a/rma_sale/models/rma_order_line.py +++ b/rma_sale/models/rma_order_line.py @@ -82,6 +82,11 @@ def _compute_sales_count(self): ) sales_count = fields.Integer(compute="_compute_sales_count", string="# of Sales") + @api.model + def _origin_fields(self): + res = super()._origin_fields() + return res + ["sale_line_id"] + @api.onchange("product_id", "partner_id") def _onchange_product_id(self): """Domain for sale_line_id is computed here to make it dynamic.""" diff --git a/rma_sale/tests/test_rma_sale.py b/rma_sale/tests/test_rma_sale.py index 903c96092..35a516e4e 100644 --- a/rma_sale/tests/test_rma_sale.py +++ b/rma_sale/tests/test_rma_sale.py @@ -1,7 +1,8 @@ # Copyright 2020 ForgeFlow S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) -from odoo.tests import common +from odoo.exceptions import UserError +from odoo.tests import Form, common class TestRmaSale(common.SingleTransactionCase): @@ -155,3 +156,31 @@ def test_04_fill_rma_from_so_line(self): rma._onchange_sale_line_id() self.assertEqual(rma.product_id, self.product_1) self.assertEqual(rma.product_qty, 20.0) + + def test_05_rma_require_origin_fields(self): + rma_line = self.rma_group.rma_line_ids.filtered( + lambda r: r.product_id == self.product_1 + ).copy() + self.assertFalse(bool(rma_line.reference_move_id)) + self.assertFalse(bool(rma_line.account_move_line_id)) + self.assertFalse(bool(rma_line.sale_line_id)) + rma_line.operation_id.write( + { + "require_origin_field_filled": True, + } + ) + self.assertTrue(rma_line.operation_id.require_origin_field_filled) + with self.assertRaises(UserError): + rma_line.action_rma_to_approve() + + rma_line = Form( + rma_line, + view=self.env.ref("rma.view_rma_line_form").id, + ) + + move_line = self.so.order_line[0] + + rma_line.sale_line_id = move_line + rma_line = rma_line.save() + rma_line.action_rma_to_approve() + self.assertIn(rma_line.state, ("to_approve", "approved"))