[IMP] rma_sale: operation required

The rma operation is required in the portal, and it makes sense
for it to be required in the sales wizard as well
This commit is contained in:
sbejaoui
2024-07-22 09:53:34 +02:00
parent 3436ec67af
commit 142a3c3c56
11 changed files with 84 additions and 13 deletions

View File

@@ -169,6 +169,8 @@ Contributors
* Chafique Delli <chafique.delli@akretion.com>
* Giovanni Serra - Ooops <giovanni@ooops404.com>
* Michael Tietz (MT Software) <mtietz@mt-software.de>
* Jacques-Etienne Baudoux - BCIM <je@bcim.be>
* Souheil Bejaoui - ACSONE SA/NV <souheil.bejaoui@acsone.eu>
Maintainers
~~~~~~~~~~~

View File

@@ -920,6 +920,7 @@ class Rma(models.Model):
"partner_invoice_id",
"product_id",
"location_id",
"operation_id",
]
for record in self:
desc = ""

View File

@@ -8,3 +8,5 @@
* Chafique Delli <chafique.delli@akretion.com>
* Giovanni Serra - Ooops <giovanni@ooops404.com>
* Michael Tietz (MT Software) <mtietz@mt-software.de>
* Jacques-Etienne Baudoux - BCIM <je@bcim.be>
* Souheil Bejaoui - ACSONE SA/NV <souheil.bejaoui@acsone.eu>

View File

@@ -522,6 +522,8 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
<li>Chafique Delli &lt;<a class="reference external" href="mailto:chafique.delli&#64;akretion.com">chafique.delli&#64;akretion.com</a>&gt;</li>
<li>Giovanni Serra - Ooops &lt;<a class="reference external" href="mailto:giovanni&#64;ooops404.com">giovanni&#64;ooops404.com</a>&gt;</li>
<li>Michael Tietz (MT Software) &lt;<a class="reference external" href="mailto:mtietz&#64;mt-software.de">mtietz&#64;mt-software.de</a>&gt;</li>
<li>Jacques-Etienne Baudoux - BCIM &lt;<a class="reference external" href="mailto:je&#64;bcim.be">je&#64;bcim.be</a>&gt;</li>
<li>Souheil Bejaoui - ACSONE SA/NV &lt;<a class="reference external" href="mailto:souheil.bejaoui&#64;acsone.eu">souheil.bejaoui&#64;acsone.eu</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">

View File

@@ -79,8 +79,11 @@ class TestRma(TransactionCase):
cls.warehouse = cls.env.ref("stock.warehouse0")
# Ensure grouping
cls.env.company.rma_return_grouping = True
cls.operation = cls.env.ref("rma.rma_operation_replace")
def _create_rma(self, partner=None, product=None, qty=None, location=None):
def _create_rma(
self, partner=None, product=None, qty=None, location=None, operation=None
):
vals = {}
if partner:
vals["partner_id"] = partner.id
@@ -90,12 +93,16 @@ class TestRma(TransactionCase):
vals["product_uom_qty"] = qty
if location:
vals["location_id"] = location.id
if operation:
vals["operation_id"] = operation.id
elif operation is None:
vals["operation_id"] = self.operation.id
return self.env["rma"].create(vals)
def _create_confirm_receive(
self, partner=None, product=None, qty=None, location=None
self, partner=None, product=None, qty=None, location=None, operation=None
):
rma = self._create_rma(partner, product, qty, location)
rma = self._create_rma(partner, product, qty, location, operation)
rma.action_confirm()
rma.reception_move_id.quantity_done = rma.product_uom_qty
rma.reception_move_id.picking_id._action_done()
@@ -227,19 +234,26 @@ class TestRmaCase(TestRma):
self.assertEqual(rma.product_uom, self.product.uom_id)
def test_ensure_required_fields_on_confirm(self):
rma = self._create_rma()
rma = self._create_rma(operation=False)
with self.assertRaises(ValidationError) as e:
rma.action_confirm()
self.assertEqual(
e.exception.args[0],
"Required field(s):\nCustomer\nShipping Address\nInvoice Address\nProduct",
"Required field(s):\nCustomer\nShipping Address\nInvoice Address\nProduct"
"\nRequested operation",
)
rma.partner_id = self.partner.id
with self.assertRaises(ValidationError) as e:
rma.action_confirm()
self.assertEqual(e.exception.args[0], "Required field(s):\nProduct")
self.assertEqual(
e.exception.args[0], "Required field(s):\nProduct\nRequested operation"
)
rma.product_id = self.product.id
rma.location_id = self.rma_loc.id
with self.assertRaises(ValidationError) as e:
rma.action_confirm()
self.assertEqual(e.exception.args[0], "Required field(s):\nRequested operation")
rma.operation_id = self.operation
rma.action_confirm()
self.assertEqual(rma.state, "confirmed")
@@ -687,6 +701,7 @@ class TestRmaCase(TestRma):
)
)
stock_return_picking_form.create_rma = True
stock_return_picking_form.rma_operation_id = self.operation
return_wizard = stock_return_picking_form.save()
picking_action = return_wizard.create_returns()
# Each origin move is linked to a different RMA
@@ -715,6 +730,7 @@ class TestRmaCase(TestRma):
rma_form.move_id = origin_delivery.move_ids.filtered(
lambda r: r.product_id == self.product
)
rma_form.operation_id = self.operation
rma = rma_form.save()
rma.action_confirm()
rma.reception_move_id.quantity_done = 10

View File

@@ -11,6 +11,20 @@ from odoo.tools import float_compare
class ReturnPickingLine(models.TransientModel):
_inherit = "stock.return.picking.line"
rma_operation_id = fields.Many2one(
comodel_name="rma.operation",
string="Operation",
compute="_compute_rma_operation_id",
store=True,
readonly=False,
)
@api.depends("wizard_id.rma_operation_id")
def _compute_rma_operation_id(self):
for rec in self:
if rec.wizard_id.rma_operation_id:
rec.rma_operation_id = rec.wizard_id.rma_operation_id
def _prepare_rma_vals(self):
self.ensure_one()
return {
@@ -19,6 +33,7 @@ class ReturnPickingLine(models.TransientModel):
"product_uom_qty": self.quantity,
"product_uom": self.product_id.uom_id.id,
"location_id": self.wizard_id.location_id.id or self.move_id.location_id.id,
"operation_id": self.rma_operation_id.id,
}
@@ -30,6 +45,10 @@ class ReturnPicking(models.TransientModel):
rma_location_ids = fields.Many2many(
comodel_name="stock.location", compute="_compute_rma_location_id"
)
rma_operation_id = fields.Many2one(
comodel_name="rma.operation",
string="Requested operation",
)
# Expand domain for RMAs
location_id = fields.Many2one(
domain="create_rma and [('id', 'child_of', rma_location_ids)]"

View File

@@ -8,12 +8,22 @@
<field name="model">stock.return.picking</field>
<field name="inherit_id" ref="stock.view_stock_return_picking_form" />
<field name="arch" type="xml">
<field name="product_return_moves" position="after">
<xpath expr="//field[@name='product_return_moves']//tree" position="inside">
<field
name="rma_operation_id"
attrs="{'column_invisible': [('parent.create_rma', '=', False)], 'required': [('parent.create_rma', '=', True), ('quantity', '>', 0)]}"
/>
</xpath>
<field name="product_return_moves" position="before">
<group name="group_rma">
<field
name="create_rma"
attrs="{'invisible': [('picking_type_code', '!=', 'outgoing')]}"
/>
<field
name="rma_operation_id"
attrs="{'invisible': [('create_rma', '=', False)]}"
/>
<field name="rma_location_ids" invisible="1" />
<field name="picking_id" invisible="1" />
<field name="picking_type_code" invisible="1" />

View File

@@ -26,6 +26,7 @@ class TestRmaSaleBase(TransactionCase):
)
cls.report_model = cls.env["ir.actions.report"]
cls.rma_operation_model = cls.env["rma.operation"]
cls.operation = cls.env.ref("rma.rma_operation_replace")
cls._partner_portal_wizard(cls, cls.partner)
def _create_sale_order(self, products):
@@ -47,7 +48,9 @@ class TestRmaSaleBase(TransactionCase):
def _rma_sale_wizard(self, order):
wizard_id = order.action_create_rma()["res_id"]
return self.env["sale.order.rma.wizard"].browse(wizard_id)
wizard = self.env["sale.order.rma.wizard"].browse(wizard_id)
wizard.operation_id = self.operation
return wizard
class TestRmaSale(TestRmaSaleBase):
@@ -95,6 +98,7 @@ class TestRmaSale(TestRmaSaleBase):
"product_id": self.product_1.id,
"product_uom_qty": 5,
"location_id": self.sale_order.warehouse_id.rma_loc_id.id,
"operation_id": self.operation.id,
}
rma = self.env["rma"].create(rma_vals)
rma.action_confirm()

View File

@@ -18,6 +18,10 @@ class SaleOrderRmaWizard(models.TransientModel):
)
return [("id", "child_of", rma_loc.ids)]
operation_id = fields.Many2one(
comodel_name="rma.operation",
string="Requested operation",
)
order_id = fields.Many2one(
comodel_name="sale.order",
default=lambda self: self.env.context.get("active_id", False),
@@ -145,12 +149,21 @@ class SaleOrderLineRmaWizard(models.TransientModel):
operation_id = fields.Many2one(
comodel_name="rma.operation",
string="Requested operation",
compute="_compute_operation_id",
store=True,
readonly=False,
)
sale_line_id = fields.Many2one(
comodel_name="sale.order.line",
)
description = fields.Text()
@api.depends("wizard_id.operation_id")
def _compute_operation_id(self):
for rec in self:
if rec.wizard_id.operation_id:
rec.operation_id = rec.wizard_id.operation_id
@api.onchange("product_id")
def onchange_product_id(self):
self.picking_id = False

View File

@@ -12,6 +12,7 @@
<field name="arch" type="xml">
<form>
<group>
<field name="operation_id" />
<field name="line_ids" nolabel="1" colspan="2">
<tree editable="bottom">
<field name="order_id" invisible="1" />
@@ -30,7 +31,10 @@
options="{'no_create': True}"
required="1"
/>
<field name="operation_id" />
<field
name="operation_id"
attrs="{'required': [('quantity', '>', 0)]}"
/>
</tree>
</field>
</group>

View File

@@ -128,14 +128,12 @@ class TestRmaSaleMrp(TestRmaSaleBase):
self.assertEqual(rma.refund_id.invoice_line_ids.product_id, self.product_kit)
rma.refund_id.action_post()
# We can still return another kit
wizard_id = order.action_create_rma()["res_id"]
wizard = self.env["sale.order.rma.wizard"].browse(wizard_id)
wizard = self._rma_sale_wizard(order)
self.assertEqual(wizard.line_ids.quantity, 1)
wizard.create_and_open_rma()
# Now we open the wizard again and try to force the RMA qty wich should
# be 0 at this time
wizard_id = order.action_create_rma()["res_id"]
wizard = self.env["sale.order.rma.wizard"].browse(wizard_id)
wizard = self._rma_sale_wizard(order)
self.assertEqual(wizard.line_ids.quantity, 0)
wizard.line_ids.quantity = 1
with self.assertRaises(ValidationError):