Commit 5ef46664a2 share code between produce
wizard and workorder. Field final_lot_id is now commonly used but not very
well named. This commit rename it into finished_lot_id as it represent the
lot number of the finished product.
Task : 1998064
closes odoo/odoo#32761
Signed-off-by: Simon Lejeune (sle) <sle@openerp.com>
527 lines
25 KiB
Python
527 lines
25 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
from odoo.tests import Form
|
|
from odoo.tests.common import SavepointCase, TransactionCase
|
|
|
|
from odoo.tests import tagged
|
|
|
|
@tagged('post_install', '-at_install')
|
|
class TestSubcontractingBasic(TransactionCase):
|
|
def test_partner_1(self):
|
|
""" Checks the `display_name` of subcontracted partners. """
|
|
main_partner = self.env['res.partner'].create({'name': 'main_partner'})
|
|
|
|
# When a name is set to the subcontracted partner.
|
|
subcontractor_partner1 = self.env['res.partner'].create({
|
|
'name': 'subcontractor_partner',
|
|
'type': 'subcontractor',
|
|
'parent_id': main_partner.id,
|
|
})
|
|
self.assertEqual(subcontractor_partner1.display_name, "main_partner, subcontractor_partner, Subcontractor")
|
|
|
|
# When a name is not set to the subcontracted partner.
|
|
subcontractor_partner1 = self.env['res.partner'].create({
|
|
'name': '',
|
|
'type': 'subcontractor',
|
|
'parent_id': main_partner.id,
|
|
})
|
|
self.assertEqual(subcontractor_partner1.display_name, "main_partner, Subcontractor")
|
|
|
|
def test_partner_2(self):
|
|
""" Open an existing partner and add a contact of type subcontractor (simple form view).
|
|
Checks the customer and supplier locations are set to the subcontracting one onces saved.
|
|
"""
|
|
that_company = self.env['res.partner'].create({
|
|
'is_company': True,
|
|
'name': "That Company",
|
|
})
|
|
partner_form = Form(that_company)
|
|
with partner_form.child_ids.new() as partner:
|
|
partner.name = 'That Guy'
|
|
partner.type = 'subcontractor'
|
|
partner_form.save()
|
|
subcontractor = that_company.child_ids
|
|
self.assertEquals(subcontractor.property_stock_supplier, self.env.user.company_id.subcontracting_location_id)
|
|
self.assertEquals(subcontractor.property_stock_customer, self.env.user.company_id.subcontracting_location_id)
|
|
|
|
def test_partner_3(self):
|
|
""" Create a new partner, select a parent company, and choose type subcontractor (debug
|
|
active). Checks the onchange correctly set the customer and supplier locations to the
|
|
subcontracting ones. Change them to another one, save, checks they are rightly applied.
|
|
"""
|
|
# FIXME sle: this field should not be writeable without the debug mode but it is. ask xmo
|
|
group_no_one = self.env.ref('base.group_no_one')
|
|
self.env.user.write({'groups_id': [(3, group_no_one.id)]})
|
|
partner_form = Form(self.env['res.partner'])
|
|
partner_form.name = 'subcontractor partner'
|
|
self.assertNotEqual(partner_form.property_stock_supplier, self.env.user.company_id.subcontracting_location_id)
|
|
self.assertNotEqual(partner_form.property_stock_customer, self.env.user.company_id.subcontracting_location_id)
|
|
partner_form.type = 'subcontractor'
|
|
self.assertEqual(partner_form.property_stock_supplier, self.env.user.company_id.subcontracting_location_id)
|
|
self.assertEqual(partner_form.property_stock_customer, self.env.user.company_id.subcontracting_location_id)
|
|
subcontracting_location2 = self.env.user.company_id.subcontracting_location_id.copy()
|
|
partner_form.property_stock_supplier = subcontracting_location2
|
|
partner_form.property_stock_customer = subcontracting_location2
|
|
partner = partner_form.save()
|
|
self.assertEqual(partner.property_stock_supplier, subcontracting_location2)
|
|
self.assertEqual(partner.property_stock_customer, subcontracting_location2)
|
|
|
|
def test_partner_4(self):
|
|
""" Create a new partner, select a parent company, and choose type subcontractor (debug
|
|
not active). Checks the customer and supplier locations are set to the subcontracting one
|
|
onces saved.
|
|
"""
|
|
that_company = self.env['res.partner'].create({
|
|
'is_company': True,
|
|
'name': "That Company",
|
|
})
|
|
partner_form = Form(self.env['res.partner'])
|
|
partner_form.name = 'That Guy'
|
|
partner_form.parent_id = that_company
|
|
partner_form.type = 'subcontractor'
|
|
subcontractor = partner_form.save()
|
|
self.assertEquals(subcontractor.property_stock_supplier, self.env.user.company_id.subcontracting_location_id)
|
|
self.assertEquals(subcontractor.property_stock_customer, self.env.user.company_id.subcontracting_location_id)
|
|
|
|
def test_partner_5(self):
|
|
""" Create a new partner with a child partner of type contact,
|
|
then write the type 'subcontractor' on it
|
|
"""
|
|
that_company = self.env['res.partner'].create({
|
|
'is_company': True,
|
|
'name': "That Company",
|
|
})
|
|
partner_form = Form(that_company)
|
|
with partner_form.child_ids.new() as partner:
|
|
partner.name = 'That Guy'
|
|
partner.type = 'contact'
|
|
partner_form.save()
|
|
|
|
# We write a new type on the created child partner
|
|
subcontractor = that_company.child_ids
|
|
self.assertEquals(len(that_company.child_ids), 1)
|
|
subcontractor.type = 'subcontractor'
|
|
|
|
self.assertEquals(subcontractor.property_stock_supplier, self.env.user.company_id.subcontracting_location_id)
|
|
self.assertEquals(subcontractor.property_stock_customer, self.env.user.company_id.subcontracting_location_id)
|
|
|
|
def test_subcontracting_location_1(self):
|
|
""" Checks the creation and presence of the subcontracting location. """
|
|
self.assertTrue(self.env.user.company_id.subcontracting_location_id)
|
|
self.assertTrue(self.env.user.company_id.subcontracting_location_id.active)
|
|
company2 = self.env['res.company'].create({'name': 'Test Company'})
|
|
self.assertTrue(company2.subcontracting_location_id)
|
|
|
|
|
|
class TestSubcontractingFlows(SavepointCase):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super(TestSubcontractingFlows, cls).setUpClass()
|
|
# 1: Create a subcontracting partner
|
|
main_partner = cls.env['res.partner'].create({'name': 'main_partner'})
|
|
cls.subcontractor_partner1 = cls.env['res.partner'].create({
|
|
'name': 'subcontractor_partner',
|
|
'type': 'subcontractor',
|
|
'parent_id': main_partner.id,
|
|
})
|
|
|
|
# 2. Create a BOM of subcontracting type
|
|
cls.comp1 = cls.env['product.product'].create({
|
|
'name': 'Component1',
|
|
'type': 'product',
|
|
'categ_id': cls.env.ref('product.product_category_all').id,
|
|
})
|
|
cls.comp2 = cls.env['product.product'].create({
|
|
'name': 'Component2',
|
|
'type': 'product',
|
|
'categ_id': cls.env.ref('product.product_category_all').id,
|
|
})
|
|
cls.finished = cls.env['product.product'].create({
|
|
'name': 'finished',
|
|
'type': 'product',
|
|
'categ_id': cls.env.ref('product.product_category_all').id,
|
|
})
|
|
bom_form = Form(cls.env['mrp.bom'])
|
|
bom_form.type = 'subcontract'
|
|
bom_form.product_tmpl_id = cls.finished.product_tmpl_id
|
|
with bom_form.bom_line_ids.new() as bom_line:
|
|
bom_line.product_id = cls.comp1
|
|
bom_line.product_qty = 1
|
|
with bom_form.bom_line_ids.new() as bom_line:
|
|
bom_line.product_id = cls.comp2
|
|
bom_line.product_qty = 1
|
|
cls.bom = bom_form.save()
|
|
|
|
# Create a BoM for cls.comp2
|
|
cls.comp2comp = cls.env['product.product'].create({
|
|
'name': 'component for Component2',
|
|
'type': 'product',
|
|
'categ_id': cls.env.ref('product.product_category_all').id,
|
|
})
|
|
bom_form = Form(cls.env['mrp.bom'])
|
|
bom_form.product_tmpl_id = cls.comp2.product_tmpl_id
|
|
with bom_form.bom_line_ids.new() as bom_line:
|
|
bom_line.product_id = cls.comp2comp
|
|
bom_line.product_qty = 1
|
|
cls.comp2_bom = bom_form.save()
|
|
|
|
def test_flow_1(self):
|
|
""" Don't tick any route on the components and trigger the creation of the subcontracting
|
|
manufacturing order through a receipt picking. Create a reordering rule in the
|
|
subcontracting locations for a component and run the scheduler to resupply. Checks if the
|
|
resupplying actually works
|
|
"""
|
|
# Create a receipt picking from the subcontractor
|
|
picking_form = Form(self.env['stock.picking'])
|
|
picking_form.picking_type_id = self.env.ref('stock.picking_type_in')
|
|
picking_form.partner_id = self.subcontractor_partner1
|
|
with picking_form.move_ids_without_package.new() as move:
|
|
move.product_id = self.finished
|
|
move.product_uom_qty = 1
|
|
picking_receipt = picking_form.save()
|
|
picking_receipt.action_confirm()
|
|
|
|
# Nothing should be tracked
|
|
self.assertFalse(picking_receipt.display_action_record_components)
|
|
self.assertFalse(picking_receipt.display_view_subcontracted_move_lines)
|
|
|
|
# Check the created manufacturing order
|
|
mo = self.env['mrp.production'].search([('bom_id', '=', self.bom.id)])
|
|
self.assertEqual(len(mo), 1)
|
|
self.assertEqual(len(mo.picking_ids), 0)
|
|
wh = picking_receipt.picking_type_id.warehouse_id
|
|
self.assertEquals(mo.picking_type_id, wh.subcontracting_type_id)
|
|
self.assertFalse(mo.picking_type_id.active)
|
|
|
|
# Create a RR
|
|
pg1 = self.env['procurement.group'].create({})
|
|
self.env['stock.warehouse.orderpoint'].create({
|
|
'name': 'xxx',
|
|
'product_id': self.comp1.id,
|
|
'product_min_qty': 0,
|
|
'product_max_qty': 0,
|
|
'location_id': self.env.user.company_id.subcontracting_location_id.id,
|
|
'group_id': pg1.id,
|
|
})
|
|
|
|
# Run the scheduler and check the created picking
|
|
self.env['procurement.group'].run_scheduler()
|
|
picking = self.env['stock.picking'].search([('group_id', '=', pg1.id)])
|
|
self.assertEqual(len(picking), 1)
|
|
self.assertEquals(picking.picking_type_id, wh.out_type_id)
|
|
picking_receipt.move_lines.quantity_done = 1
|
|
picking_receipt.button_validate()
|
|
self.assertEquals(mo.state, 'done')
|
|
|
|
# Now that the picking is done, the details stat button should be visible
|
|
self.assertTrue(picking_receipt.display_view_subcontracted_move_lines)
|
|
|
|
# Available quantities should be negative at the subcontracting location for each components
|
|
avail_qty_comp1 = self.env['stock.quant']._get_available_quantity(self.comp1, self.subcontractor_partner1.property_stock_supplier, allow_negative=True)
|
|
avail_qty_comp2 = self.env['stock.quant']._get_available_quantity(self.comp2, self.subcontractor_partner1.property_stock_supplier, allow_negative=True)
|
|
avail_qty_finished = self.env['stock.quant']._get_available_quantity(self.finished, wh.lot_stock_id)
|
|
self.assertEquals(avail_qty_comp1, -1)
|
|
self.assertEquals(avail_qty_comp2, -1)
|
|
self.assertEquals(avail_qty_finished, 1)
|
|
|
|
def test_flow_2(self):
|
|
""" Tick "Resupply Subcontractor on Order" on the components and trigger the creation of
|
|
the subcontracting manufacturing order through a receipt picking. Checks if the resupplying
|
|
actually works.
|
|
"""
|
|
# Tick "resupply subconractor on order"
|
|
resupply_sub_on_order_route = self.env['stock.location.route'].search([('name', '=', 'Resupply Subcontractor on Order')])
|
|
(self.comp1 + self.comp2).write({'route_ids': [(4, resupply_sub_on_order_route.id, None)]})
|
|
|
|
# Create a receipt picking from the subcontractor
|
|
picking_form = Form(self.env['stock.picking'])
|
|
picking_form.picking_type_id = self.env.ref('stock.picking_type_in')
|
|
picking_form.partner_id = self.subcontractor_partner1
|
|
with picking_form.move_ids_without_package.new() as move:
|
|
move.product_id = self.finished
|
|
move.product_uom_qty = 1
|
|
picking_receipt = picking_form.save()
|
|
picking_receipt.action_confirm()
|
|
|
|
# Nothing should be tracked
|
|
self.assertFalse(picking_receipt.display_action_record_components)
|
|
self.assertFalse(picking_receipt.display_view_subcontracted_move_lines)
|
|
|
|
# Pickings should directly be created
|
|
mo = self.env['mrp.production'].search([('bom_id', '=', self.bom.id)])
|
|
self.assertEqual(len(mo.picking_ids), 1)
|
|
self.assertEquals(mo.state, 'to_close')
|
|
self.assertEqual(len(mo.picking_ids.move_lines), 2)
|
|
|
|
picking = mo.picking_ids
|
|
wh = picking.picking_type_id.warehouse_id
|
|
|
|
# The picking should be a delivery order
|
|
self.assertEquals(picking.picking_type_id, wh.out_type_id)
|
|
|
|
self.assertEquals(mo.picking_type_id, wh.subcontracting_type_id)
|
|
self.assertFalse(mo.picking_type_id.active)
|
|
|
|
# No manufacturing order for `self.comp2`
|
|
comp2mo = self.env['mrp.production'].search([('bom_id', '=', self.comp2_bom.id)])
|
|
self.assertEqual(len(comp2mo), 0)
|
|
|
|
picking_receipt.move_lines.quantity_done = 1
|
|
picking_receipt.button_validate()
|
|
self.assertEquals(mo.state, 'done')
|
|
|
|
# Now that the picking is done, the details stat button should be visible
|
|
self.assertTrue(picking_receipt.display_view_subcontracted_move_lines)
|
|
|
|
# Available quantities should be negative at the subcontracting location for each components
|
|
avail_qty_comp1 = self.env['stock.quant']._get_available_quantity(self.comp1, self.subcontractor_partner1.property_stock_supplier, allow_negative=True)
|
|
avail_qty_comp2 = self.env['stock.quant']._get_available_quantity(self.comp2, self.subcontractor_partner1.property_stock_supplier, allow_negative=True)
|
|
avail_qty_finished = self.env['stock.quant']._get_available_quantity(self.finished, wh.lot_stock_id)
|
|
self.assertEquals(avail_qty_comp1, -1)
|
|
self.assertEquals(avail_qty_comp2, -1)
|
|
self.assertEquals(avail_qty_finished, 1)
|
|
|
|
def test_flow_3(self):
|
|
""" Tick "Resupply Subcontractor on Order" and "MTO" on the components and trigger the
|
|
creation of the subcontracting manufacturing order through a receipt picking. Checks if the
|
|
resupplying actually works. One of the component has also "manufacture" set and a BOM
|
|
linked. Checks that an MO is created for this one.
|
|
"""
|
|
# Tick "resupply subconractor on order"
|
|
resupply_sub_on_order_route = self.env['stock.location.route'].search([('name', '=', 'Resupply Subcontractor on Order')])
|
|
(self.comp1 + self.comp2).write({'route_ids': [(4, resupply_sub_on_order_route.id, None)]})
|
|
|
|
# Tick "manufacture" and MTO on self.comp2
|
|
mto_route = self.env['stock.location.route'].search([('name', '=', 'Replenish on Order (MTO)')])
|
|
manufacture_route = self.env['stock.location.route'].search([('name', '=', 'Manufacture')])
|
|
self.comp2.write({'route_ids': [(4, manufacture_route.id, None)]})
|
|
self.comp2.write({'route_ids': [(4, mto_route.id, None)]})
|
|
|
|
# Create a receipt picking from the subcontractor
|
|
picking_form = Form(self.env['stock.picking'])
|
|
picking_form.picking_type_id = self.env.ref('stock.picking_type_in')
|
|
picking_form.partner_id = self.subcontractor_partner1
|
|
with picking_form.move_ids_without_package.new() as move:
|
|
move.product_id = self.finished
|
|
move.product_uom_qty = 1
|
|
picking_receipt = picking_form.save()
|
|
picking_receipt.action_confirm()
|
|
|
|
# Nothing should be tracked
|
|
self.assertFalse(picking_receipt.display_action_record_components)
|
|
self.assertFalse(picking_receipt.display_view_subcontracted_move_lines)
|
|
|
|
# Pickings should directly be created
|
|
mo = self.env['mrp.production'].search([('bom_id', '=', self.bom.id)])
|
|
self.assertEqual(len(mo.picking_ids), 1)
|
|
self.assertEquals(mo.state, 'to_close')
|
|
self.assertEqual(len(mo.picking_ids.move_lines), 2)
|
|
|
|
# The picking should be a delivery order
|
|
wh = picking_receipt.picking_type_id.warehouse_id
|
|
self.assertEquals(mo.picking_ids.picking_type_id, wh.out_type_id)
|
|
|
|
self.assertEquals(mo.picking_type_id, wh.subcontracting_type_id)
|
|
self.assertFalse(mo.picking_type_id.active)
|
|
|
|
# As well as a manufacturing order for `self.comp2`
|
|
comp2mo = self.env['mrp.production'].search([('bom_id', '=', self.comp2_bom.id)])
|
|
self.assertEqual(len(comp2mo), 1)
|
|
picking_receipt.move_lines.quantity_done = 1
|
|
picking_receipt.button_validate()
|
|
self.assertEquals(mo.state, 'done')
|
|
|
|
# Now that the picking is done, the details stat button should be visible
|
|
self.assertTrue(picking_receipt.display_view_subcontracted_move_lines)
|
|
|
|
# Available quantities should be negative at the subcontracting location for each components
|
|
avail_qty_comp1 = self.env['stock.quant']._get_available_quantity(self.comp1, self.subcontractor_partner1.property_stock_supplier, allow_negative=True)
|
|
avail_qty_comp2 = self.env['stock.quant']._get_available_quantity(self.comp2, self.subcontractor_partner1.property_stock_supplier, allow_negative=True)
|
|
avail_qty_finished = self.env['stock.quant']._get_available_quantity(self.finished, wh.lot_stock_id)
|
|
self.assertEquals(avail_qty_comp1, -1)
|
|
self.assertEquals(avail_qty_comp2, -1)
|
|
self.assertEquals(avail_qty_finished, 1)
|
|
|
|
def test_flow_4(self):
|
|
""" Check that the correct BoM is chosen accordingly to the partner
|
|
"""
|
|
# We create a second partner of type subcontractor
|
|
main_partner_2 = self.env['res.partner'].create({'name': 'main_partner'})
|
|
subcontractor_partner2 = self.env['res.partner'].create({
|
|
'name': 'subcontractor_partner',
|
|
'type': 'subcontractor',
|
|
'parent_id': main_partner_2.id,
|
|
})
|
|
|
|
# We create a different BoM for the same product
|
|
comp3 = self.env['product.product'].create({
|
|
'name': 'Component1',
|
|
'type': 'product',
|
|
'categ_id': self.env.ref('product.product_category_all').id,
|
|
})
|
|
|
|
bom_form = Form(self.env['mrp.bom'])
|
|
bom_form.type = 'subcontract'
|
|
bom_form.product_tmpl_id = self.finished.product_tmpl_id
|
|
with bom_form.bom_line_ids.new() as bom_line:
|
|
bom_line.product_id = self.comp1
|
|
bom_line.product_qty = 1
|
|
with bom_form.bom_line_ids.new() as bom_line:
|
|
bom_line.product_id = comp3
|
|
bom_line.product_qty = 1
|
|
bom2 = bom_form.save()
|
|
|
|
# We assign the second BoM to the new partner
|
|
self.bom.write({'subcontractor_ids': [(4, self.subcontractor_partner1.id, None)]})
|
|
bom2.write({'subcontractor_ids': [(4, subcontractor_partner2.id, None)]})
|
|
|
|
# Create a receipt picking from the subcontractor1
|
|
picking_form = Form(self.env['stock.picking'])
|
|
picking_form.picking_type_id = self.env.ref('stock.picking_type_in')
|
|
picking_form.partner_id = self.subcontractor_partner1
|
|
with picking_form.move_ids_without_package.new() as move:
|
|
move.product_id = self.finished
|
|
move.product_uom_qty = 1
|
|
picking_receipt1 = picking_form.save()
|
|
picking_receipt1.action_confirm()
|
|
|
|
# Create a receipt picking from the subcontractor2
|
|
picking_form = Form(self.env['stock.picking'])
|
|
picking_form.picking_type_id = self.env.ref('stock.picking_type_in')
|
|
picking_form.partner_id = subcontractor_partner2
|
|
with picking_form.move_ids_without_package.new() as move:
|
|
move.product_id = self.finished
|
|
move.product_uom_qty = 1
|
|
picking_receipt2 = picking_form.save()
|
|
picking_receipt2.action_confirm()
|
|
|
|
mo_pick1 = picking_receipt1.move_lines.mapped('move_orig_ids.production_id')
|
|
mo_pick2 = picking_receipt2.move_lines.mapped('move_orig_ids.production_id')
|
|
self.assertEquals(len(mo_pick1), 1)
|
|
self.assertEquals(len(mo_pick2), 1)
|
|
self.assertEquals(mo_pick1.bom_id, self.bom)
|
|
self.assertEquals(mo_pick2.bom_id, bom2)
|
|
|
|
|
|
class TestSubcontractingTracking(TransactionCase):
|
|
def setUp(self):
|
|
super(TestSubcontractingTracking, self).setUp()
|
|
# 1: Create a subcontracting partner
|
|
main_company_1 = self.env['res.partner'].create({'name': 'main_partner'})
|
|
self.subcontractor_partner1 = self.env['res.partner'].create({
|
|
'name': 'Subcontractor 1',
|
|
'type': 'subcontractor',
|
|
'parent_id': main_company_1.id,
|
|
})
|
|
|
|
# 2. Create a BOM of subcontracting type
|
|
# 2.1. Comp1 has tracking by lot
|
|
self.comp1_sn = self.env['product.product'].create({
|
|
'name': 'Component1',
|
|
'type': 'product',
|
|
'categ_id': self.env.ref('product.product_category_all').id,
|
|
'tracking': 'serial'
|
|
})
|
|
self.comp2 = self.env['product.product'].create({
|
|
'name': 'Component2',
|
|
'type': 'product',
|
|
'categ_id': self.env.ref('product.product_category_all').id,
|
|
})
|
|
|
|
# 2.2. Finished prodcut has tracking by serial number
|
|
self.finished_lot = self.env['product.product'].create({
|
|
'name': 'finished',
|
|
'type': 'product',
|
|
'categ_id': self.env.ref('product.product_category_all').id,
|
|
'tracking': 'lot'
|
|
})
|
|
bom_form = Form(self.env['mrp.bom'])
|
|
bom_form.type = 'subcontract'
|
|
bom_form.product_tmpl_id = self.finished_lot.product_tmpl_id
|
|
with bom_form.bom_line_ids.new() as bom_line:
|
|
bom_line.product_id = self.comp1_sn
|
|
bom_line.product_qty = 1
|
|
with bom_form.bom_line_ids.new() as bom_line:
|
|
bom_line.product_id = self.comp2
|
|
bom_line.product_qty = 1
|
|
self.bom_tracked = bom_form.save()
|
|
|
|
def test_flow_tracked_1(self):
|
|
""" This test mimics test_flow_1 but with a BoM that has tracking included in it.
|
|
"""
|
|
# Create a receipt picking from the subcontractor
|
|
picking_form = Form(self.env['stock.picking'])
|
|
picking_form.picking_type_id = self.env.ref('stock.picking_type_in')
|
|
picking_form.partner_id = self.subcontractor_partner1
|
|
with picking_form.move_ids_without_package.new() as move:
|
|
move.product_id = self.finished_lot
|
|
move.product_uom_qty = 1
|
|
picking_receipt = picking_form.save()
|
|
picking_receipt.action_confirm()
|
|
|
|
# We should be able to call the 'record_components' button
|
|
self.assertTrue(picking_receipt.display_action_record_components)
|
|
self.assertFalse(picking_receipt.display_view_subcontracted_move_lines)
|
|
|
|
# Check the created manufacturing order
|
|
mo = self.env['mrp.production'].search([('bom_id', '=', self.bom_tracked.id)])
|
|
self.assertEqual(len(mo), 1)
|
|
self.assertEquals(mo.state, 'confirmed')
|
|
self.assertEqual(len(mo.picking_ids), 0)
|
|
wh = picking_receipt.picking_type_id.warehouse_id
|
|
self.assertEquals(mo.picking_type_id, wh.subcontracting_type_id)
|
|
self.assertFalse(mo.picking_type_id.active)
|
|
|
|
# Create a RR
|
|
pg1 = self.env['procurement.group'].create({})
|
|
self.env['stock.warehouse.orderpoint'].create({
|
|
'name': 'xxx',
|
|
'product_id': self.comp1_sn.id,
|
|
'product_min_qty': 0,
|
|
'product_max_qty': 0,
|
|
'location_id': self.env.user.company_id.subcontracting_location_id.id,
|
|
'group_id': pg1.id,
|
|
})
|
|
|
|
# Run the scheduler and check the created picking
|
|
self.env['procurement.group'].run_scheduler()
|
|
picking = self.env['stock.picking'].search([('group_id', '=', pg1.id)])
|
|
self.assertEqual(len(picking), 1)
|
|
self.assertEquals(picking.picking_type_id, wh.out_type_id)
|
|
|
|
lot_id = self.env['stock.production.lot'].create({
|
|
'name': 'lot1',
|
|
'product_id': self.finished_lot.id
|
|
})
|
|
serial_id = self.env['stock.production.lot'].create({
|
|
'name': 'lot1',
|
|
'product_id': self.comp1_sn.id
|
|
})
|
|
produce_form = Form(self.env['mrp.product.produce'].with_context({
|
|
'active_id': mo.id,
|
|
'active_ids': [mo.id],
|
|
}))
|
|
produce_form.finished_lot_id = lot_id
|
|
produce_form.raw_workorder_line_ids._records[0]['lot_id'] = serial_id.id
|
|
wiz_produce = produce_form.save()
|
|
wiz_produce.do_produce()
|
|
|
|
# We should not be able to call the 'record_components' button
|
|
self.assertFalse(picking_receipt.display_action_record_components)
|
|
# We should see the move lines stat button
|
|
self.assertTrue(picking_receipt.display_view_subcontracted_move_lines)
|
|
|
|
picking_receipt.move_lines.quantity_done = 1
|
|
picking_receipt.move_lines.move_line_ids.lot_name = 'lot00001test'
|
|
picking_receipt.button_validate()
|
|
self.assertEquals(mo.state, 'done')
|
|
|
|
# Available quantities should be negative at the subcontracting location for each components
|
|
avail_qty_comp1 = self.env['stock.quant']._get_available_quantity(self.comp1_sn, self.subcontractor_partner1.property_stock_supplier, allow_negative=True)
|
|
avail_qty_comp2 = self.env['stock.quant']._get_available_quantity(self.comp2, self.subcontractor_partner1.property_stock_supplier, allow_negative=True)
|
|
avail_qty_finished = self.env['stock.quant']._get_available_quantity(self.finished_lot, wh.lot_stock_id)
|
|
self.assertEquals(avail_qty_comp1, -1)
|
|
self.assertEquals(avail_qty_comp2, -1)
|
|
self.assertEquals(avail_qty_finished, 1)
|