[FIX] purchase_requsition: ensure product_uom_id exists in bo lines

Previous commit 0501bbd62e made it so
the `product_uom_id` for the `line_ids` of a purchase.requsition (i.e. a
blanket order) were no longer being saved when the UoM setting is not
active. This would cause an error to occur when the "New Quotation"
button is pushed because the missing uom is expected by purchase
_onchange_requisition_id.

Steps to reproduce:
- Have UoM setting NOT active
- Create a blanket order for any product/vendor
- Confirm the blanket order
- Click on "New Quotation"

Expected Behavior:
New RFQ created

Actual Behavior:
Stacktrace

We also properly restrict the product_uom_id in the form view of the
line_ids to when the uom setting is active.

closes odoo/odoo#104900

X-original-commit: e90200a7b927ecccb8d4d6f31e3ddecba24d0b6d
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
This commit is contained in:
Tiffany Chang (tic)
2022-11-17 11:58:50 +01:00
parent 5b9c93ef04
commit 4e32d1fe37
3 changed files with 34 additions and 2 deletions
@@ -168,7 +168,10 @@ class PurchaseRequisitionLine(models.Model):
_rec_name = 'product_id'
product_id = fields.Many2one('product.product', string='Product', domain=[('purchase_ok', '=', True)], required=True)
product_uom_id = fields.Many2one('uom.uom', string='Product Unit of Measure', domain="[('category_id', '=', product_uom_category_id)]")
product_uom_id = fields.Many2one(
'uom.uom', 'Product Unit of Measure',
compute='_compute_product_uom_id', store=True, readonly=False, precompute=True,
domain="[('category_id', '=', product_uom_category_id)]")
product_uom_category_id = fields.Many2one(related='product_id.uom_id.category_id')
product_qty = fields.Float(string='Quantity', digits='Product Unit of Measure')
product_description_variants = fields.Char('Custom Description')
@@ -240,6 +243,11 @@ class PurchaseRequisitionLine(models.Model):
else:
line.qty_ordered = 0
@api.depends('product_id')
def _compute_product_uom_id(self):
for line in self:
line.product_uom_id = line.product_id.uom_id
@api.onchange('product_id')
def _onchange_product_id(self):
if self.product_id:
@@ -71,6 +71,30 @@ class TestPurchaseRequisition(TestPurchaseRequisitionCommon):
self.assertFalse(self.env['product.supplierinfo'].search([('id', '=', supplierinfo09.id)]), 'The supplier info should be removed')
self.assertFalse(self.env['product.supplierinfo'].search([('id', '=', supplierinfo13.id)]), 'The supplier info should be removed')
def test_03_blanket_order_rfq(self):
""" Create a blanket order + an RFQ for it """
requisition_type = self.env['purchase.requisition.type'].create({
'name': 'Blanket test',
'quantity_copy': 'none'
})
bo_form = Form(self.env['purchase.requisition'])
bo_form.vendor_id = self.res_partner_1
bo_form.type_id = requisition_type
with bo_form.line_ids.new() as line:
line.product_id = self.product_09
line.product_qty = 5.0
line.price_unit = 21
bo = bo_form.save()
bo.action_in_progress()
# lazy reproduction of clicking on "New Quotation" act_window button
po_form = Form(self.env['purchase.order'].with_context({"default_requisition_id": bo.id, "default_user_id": False}))
po = po_form.save()
po.button_confirm()
self.assertEqual(po.order_line.price_unit, bo.line_ids.price_unit, 'The blanket order unit price should have been copied to purchase order')
self.assertEqual(po.partner_id, bo.vendor_id, 'The blanket order vendor should have been copied to purchase order')
def test_06_purchase_requisition(self):
""" Create a blanket order for a product and a vendor already linked via
a supplier info"""
@@ -174,7 +174,7 @@
<field name="product_qty"/>
<field name="qty_ordered"/>
<field name="product_uom_category_id" invisible="1"/>
<field name="product_uom_id" />
<field name="product_uom_id" groups="uom.group_uom"/>
<field name="schedule_date"/>
<field name="analytic_distribution" widget="analytic_distribution"
groups="analytic.group_analytic_accounting"