[FIX] repair: make mltpl ROs when serial tracking

**Current behavior:**
Confirming a sale order containing an order line associated
with >1 products which are tracked via serial number creates a
single repair order.

**Expected behavior:**
A repair order for each individual product in the line is
created.

**Steps to reproduce:**
0. Create a storable product which is tracked via serial number
     and has create_repair set to True. Update on hand stock so
     there are at least two available and assign them each a
     serial number.

1. Make a new sale order with one order line for that product
     with the product_uom_quantity equal to the quantity
     created in step 0

2. Confirm the order and open the newly created repair order

3. Select a serial number for the repair order, start the
     repair, then end the repair to raise the exception

**Cause of the issue:**
Multiple products will be associated with one serial number. In
stock_quant.py, the check_quantity() method checks the quantity
of product_ids associated with a particular lot_id and
location_id. In this instance, quantity will now be >1 which
results in the ValidationError exception.

**Fix:**
Make a discrete repair order for each product in the order
line when the product has serial tracking. This is more logical
than asking a user to select one serial number for many
products.

opw-3688072

closes odoo/odoo#151041

Signed-off-by: Quentin Wolfs (quwo) <quwo@odoo.com>
This commit is contained in:
Ethan Vincent
2024-02-07 12:48:51 +00:00
parent cc6ecce5f0
commit c5728f58b5
2 changed files with 45 additions and 4 deletions
+16 -4
View File
@@ -93,20 +93,32 @@ class SaleOrderLine(models.Model):
continue
if not line.product_template_id.sudo().create_repair or line.move_ids.sudo().repair_id or float_compare(line.product_uom_qty, 0, precision_rounding=line.product_uom.rounding) <= 0:
continue
order = line.order_id
new_repair_vals.append({
default_repair_vals = {
'state': 'confirmed',
'partner_id': order.partner_id.id,
'sale_order_id': order.id,
'sale_order_line_id': line.id,
'picking_type_id': order.warehouse_id.repair_type_id.id,
})
if line.product_template_id.type in ('consu', 'product'):
new_repair_vals[-1].update({
}
if line.product_id.tracking == 'serial':
vals = {
**default_repair_vals,
'product_id': line.product_id.id,
'product_qty': 1,
'product_uom': line.product_uom.id,
}
new_repair_vals.extend([vals] * int(line.product_uom_qty))
elif line.product_id.type in ('consu', 'product'):
new_repair_vals.append({
**default_repair_vals,
'product_id': line.product_id.id,
'product_qty': line.product_uom_qty,
'product_uom': line.product_uom.id,
})
else:
new_repair_vals.append(default_repair_vals.copy())
if new_repair_vals:
self.env['repair.order'].sudo().create(new_repair_vals)
+29
View File
@@ -3,6 +3,7 @@
from odoo.exceptions import UserError
from odoo.tests import tagged, common, Form
from odoo.tools import float_compare, float_is_zero
from odoo import Command
@tagged('post_install', '-at_install')
@@ -623,3 +624,31 @@ class TestRepair(common.TransactionCase):
repair_order.move_ids.quantity = 1
repair_order.action_repair_end()
self.assertEqual(repair_order.state, 'done')
def test_repair_multi_unit_order_with_serial_tracking(self):
"""
Test that a sale order with a single order line with quantity > 1 for a product that creates a repair order and
is tracked via serial number creates multiple repair orders rather than grouping the line into a single RO
"""
product_a = self.env['product.product'].create({
'name': 'productA',
'detailed_type': 'product',
'tracking': 'serial',
'create_repair': True,
})
sale_order = self.env['sale.order'].create({
'partner_id': self.res_partner_1.id,
'order_line': [Command.create({
'product_id': product_a.id,
'product_uom_qty': 3.0,
})]
})
sale_order.action_confirm()
repair_orders = sale_order.repair_order_ids
self.assertRecordValues(repair_orders, [
{'product_id': product_a.id, 'product_qty': 1.0},
{'product_id': product_a.id, 'product_qty': 1.0},
{'product_id': product_a.id, 'product_qty': 1.0},
])