def test_product_produce_1(self): """Check that using a finished lot of company b in the produce wizard of a production of company a is not allowed """ product = self.env['product.product'].create({ 'name': 'p1', 'tracking': 'lot', }) component = self.env['product.product'].create({ 'name': 'p2', }) lot_b = self.env['stock.production.lot'].create({ 'product_id': product.id, 'company_id': self.company_b.id, }) self.env['mrp.bom'].create({ 'product_id': product.id, 'product_tmpl_id': product.product_tmpl_id.id, 'company_id': self.company_a.id, 'bom_line_ids': [(0, 0, { 'product_id': component.id })] }) mo_form = Form(self.env['mrp.production'].with_user(self.user_a)) mo_form.product_id = product mo = mo_form.save() mo.with_user(self.user_b).action_confirm() produce_form = Form(self.env['mrp.product.produce'].with_user( self.user_b).with_context({ 'active_id': mo.id, 'active_ids': [mo.id], })) produce_form.finished_lot_id = lot_b with self.assertRaises(UserError): produce_form.save()
def test_tracking_types_on_mo(self): finished_no_track = self._create_product('none') finished_lot = self._create_product('lot') finished_serial = self._create_product('serial') consumed_no_track = self._create_product('none') consumed_lot = self._create_product('lot') consumed_serial = self._create_product('serial') stock_id = self.env.ref('stock.stock_location_stock').id inventory_adjustment = self.env['stock.inventory'].create({ 'name': 'Initial Inventory', 'location_ids': [(4, stock_id)], }) inventory_adjustment.action_start() inventory_adjustment.write({ 'line_ids': [ (0, 0, { 'product_id': consumed_no_track.id, 'product_qty': 3, 'location_id': stock_id }), (0, 0, { 'product_id': consumed_lot.id, 'product_qty': 3, 'prod_lot_id': self.env['stock.production.lot'].create({ 'name': 'L1', 'product_id': consumed_lot.id, 'company_id': self.env.company.id }).id, 'location_id': stock_id }), (0, 0, { 'product_id': consumed_serial.id, 'product_qty': 1, 'prod_lot_id': self.env['stock.production.lot'].create({ 'name': 'S1', 'product_id': consumed_serial.id, 'company_id': self.env.company.id }).id, 'location_id': stock_id }), (0, 0, { 'product_id': consumed_serial.id, 'product_qty': 1, 'prod_lot_id': self.env['stock.production.lot'].create({ 'name': 'S2', 'product_id': consumed_serial.id, 'company_id': self.env.company.id }).id, 'location_id': stock_id }), (0, 0, { 'product_id': consumed_serial.id, 'product_qty': 1, 'prod_lot_id': self.env['stock.production.lot'].create({ 'name': 'S3', 'product_id': consumed_serial.id, 'company_id': self.env.company.id }).id, 'location_id': stock_id }), ] }) inventory_adjustment.action_validate() for finished_product in [ finished_no_track, finished_lot, finished_serial ]: bom = self.env['mrp.bom'].create({ 'product_id': finished_product.id, 'product_tmpl_id': finished_product.product_tmpl_id.id, 'product_uom_id': self.env.ref('uom.product_uom_unit').id, 'product_qty': 1.0, 'type': 'normal', 'bom_line_ids': [ (0, 0, { 'product_id': consumed_no_track.id, 'product_qty': 1 }), (0, 0, { 'product_id': consumed_lot.id, 'product_qty': 1 }), (0, 0, { 'product_id': consumed_serial.id, 'product_qty': 1 }), ], }) mo_form = Form(self.env['mrp.production']) mo_form.product_id = finished_product mo_form.bom_id = bom mo_form.product_uom_id = self.env.ref('uom.product_uom_unit') mo_form.product_qty = 1 mo = mo_form.save() mo.action_confirm() mo.action_assign() # Start MO production produce_form = Form(self.env['mrp.product.produce'].with_context({ 'active_id': mo.id, 'active_ids': [mo.id], })) if finished_product.tracking != 'serial': produce_form.qty_producing = 1 if finished_product.tracking != 'none': produce_form.finished_lot_id = self.env[ 'stock.production.lot'].create({ 'name': 'Serial or Lot finished', 'product_id': finished_product.id, 'company_id': self.env.company.id }) produce_wizard = produce_form.save() produce_wizard.do_produce() mo.button_mark_done() self.assertEqual(mo.state, 'done', "Production order should be in done state.") # Check results of traceability context = ({ 'active_id': mo.id, 'model': 'mrp.production', }) lines = self.env['stock.traceability.report'].with_context( context).get_lines() self.assertEqual( len(lines), 1, "Should always return 1 line : the final product") final_product = lines[0] self.assertEqual(final_product['unfoldable'], True, "Final product should always be unfoldable") # Find parts of the final products lines = self.env['stock.traceability.report'].get_lines( final_product['id'], **{ 'level': final_product['level'], 'model_id': final_product['model_id'], 'model_name': final_product['model'], }) self.assertEqual( len(lines), 3, "There should be 3 lines. 1 for untracked, 1 for lot, and 1 for serial" ) for line in lines: tracking = line['columns'][1].split(' ')[1] self.assertEqual( line['columns'][-1], "1.000 Units", 'Part with tracking type "%s", should have quantity = 1' % (tracking)) unfoldable = False if tracking == 'none' else True self.assertEqual( line['unfoldable'], unfoldable, 'Parts with tracking type "%s", should have be unfoldable : %s' % (tracking, unfoldable))
def test_tracking_on_byproducts(self): product_final = self.env['product.product'].create({ 'name': 'Finished Product', 'type': 'product', 'tracking': 'serial', }) product_1 = self.env['product.product'].create({ 'name': 'Raw 1', 'type': 'product', 'tracking': 'serial', }) product_2 = self.env['product.product'].create({ 'name': 'Raw 2', 'type': 'product', 'tracking': 'serial', }) byproduct_1 = self.env['product.product'].create({ 'name': 'Byproduct 1', 'type': 'product', 'tracking': 'serial', }) byproduct_2 = self.env['product.product'].create({ 'name': 'Byproduct 2', 'type': 'product', 'tracking': 'serial', }) bom_1 = self.env['mrp.bom'].create({ 'product_id': product_final.id, 'product_tmpl_id': product_final.product_tmpl_id.id, 'product_uom_id': self.uom_unit.id, 'product_qty': 1.0, 'type': 'normal', 'bom_line_ids': [(0, 0, { 'product_id': product_1.id, 'product_qty': 1 }), (0, 0, { 'product_id': product_2.id, 'product_qty': 1 })], 'byproduct_ids': [(0, 0, { 'product_id': byproduct_1.id, 'product_qty': 1, 'product_uom_id': byproduct_1.uom_id.id }), (0, 0, { 'product_id': byproduct_2.id, 'product_qty': 1, 'product_uom_id': byproduct_2.uom_id.id })] }) mo_form = Form(self.env['mrp.production']) mo_form.product_id = product_final mo_form.bom_id = bom_1 mo_form.product_qty = 2 mo = mo_form.save() mo.action_confirm() produce_form = Form(self.env['mrp.product.produce'].with_context({ 'active_id': mo.id, 'active_ids': [mo.id], })) produce_form.finished_lot_id = self.env['stock.production.lot'].create( { 'product_id': product_final.id, 'name': 'Final_lot_1', 'company_id': self.env.company.id, }) with produce_form.raw_workorder_line_ids.edit(0) as line: line.lot_id = self.env['stock.production.lot'].create({ 'product_id': product_1.id, 'name': 'Raw_1_lot_1', 'company_id': self.env.company.id, }) with produce_form.raw_workorder_line_ids.edit(1) as line: line.lot_id = self.env['stock.production.lot'].create({ 'product_id': product_2.id, 'name': 'Raw_2_lot_1', 'company_id': self.env.company.id, }) with produce_form.finished_workorder_line_ids.edit(0) as line: line.lot_id = self.env['stock.production.lot'].create({ 'product_id': byproduct_1.id, 'name': 'Byproduct_1_lot_1', 'company_id': self.env.company.id, }) with produce_form.finished_workorder_line_ids.edit(1) as line: line.lot_id = self.env['stock.production.lot'].create({ 'product_id': byproduct_2.id, 'name': 'Byproduct_2_lot_1', 'company_id': self.env.company.id, }) produce_wizard = produce_form.save() produce_wizard.continue_production() produce_form = Form(self.env['mrp.product.produce'].with_context({ 'active_id': mo.id, 'active_ids': [mo.id], })) produce_form.finished_lot_id = self.env['stock.production.lot'].create( { 'product_id': product_final.id, 'name': 'Final_lot_2', 'company_id': self.env.company.id, }) with produce_form.raw_workorder_line_ids.edit(0) as line: line.lot_id = self.env['stock.production.lot'].create({ 'product_id': product_1.id, 'name': 'Raw_1_lot_2', 'company_id': self.env.company.id, }) with produce_form.raw_workorder_line_ids.edit(1) as line: line.lot_id = self.env['stock.production.lot'].create({ 'product_id': product_2.id, 'name': 'Raw_2_lot_2', 'company_id': self.env.company.id, }) with produce_form.finished_workorder_line_ids.edit(0) as line: line.lot_id = self.env['stock.production.lot'].create({ 'product_id': byproduct_1.id, 'name': 'Byproduct_1_lot_2', 'company_id': self.env.company.id, }) with produce_form.finished_workorder_line_ids.edit(1) as line: line.lot_id = self.env['stock.production.lot'].create({ 'product_id': byproduct_2.id, 'name': 'Byproduct_2_lot_2', 'company_id': self.env.company.id, }) produce_wizard = produce_form.save() produce_wizard.do_produce() mo.button_mark_done() self.assertEqual(len(mo.move_raw_ids.mapped('move_line_ids')), 4) self.assertEqual(len(mo.move_finished_ids.mapped('move_line_ids')), 6) raw_move_lines = mo.move_raw_ids.mapped('move_line_ids') raw_line_raw_1_lot_1 = raw_move_lines.filtered( lambda ml: ml.lot_id.name == 'Raw_1_lot_1') self.assertEqual( set(raw_line_raw_1_lot_1.lot_produced_ids.mapped('name')), set(['Final_lot_1', 'Byproduct_1_lot_1', 'Byproduct_2_lot_1'])) raw_line_raw_1_lot_2 = raw_move_lines.filtered( lambda ml: ml.lot_id.name == 'Raw_1_lot_2') self.assertEqual( set(raw_line_raw_1_lot_2.lot_produced_ids.mapped('name')), set(['Final_lot_2', 'Byproduct_1_lot_2', 'Byproduct_2_lot_2'])) raw_line_raw_2_lot_1 = raw_move_lines.filtered( lambda ml: ml.lot_id.name == 'Raw_2_lot_1') self.assertEqual( set(raw_line_raw_2_lot_1.lot_produced_ids.mapped('name')), set(['Final_lot_1', 'Byproduct_1_lot_1', 'Byproduct_2_lot_1'])) raw_line_raw_2_lot_2 = raw_move_lines.filtered( lambda ml: ml.lot_id.name == 'Raw_2_lot_2') self.assertEqual( set(raw_line_raw_2_lot_2.lot_produced_ids.mapped('name')), set(['Final_lot_2', 'Byproduct_1_lot_2', 'Byproduct_2_lot_2'])) finished_move_lines = mo.move_finished_ids.mapped('move_line_ids') finished_move_line_lot_1 = finished_move_lines.filtered( lambda ml: ml.lot_id.name == 'Final_lot_1') self.assertEqual(finished_move_line_lot_1.consume_line_ids, raw_line_raw_1_lot_1 | raw_line_raw_2_lot_1) finished_move_line_lot_2 = finished_move_lines.filtered( lambda ml: ml.lot_id.name == 'Final_lot_2') self.assertEqual(finished_move_line_lot_2.consume_line_ids, raw_line_raw_1_lot_2 | raw_line_raw_2_lot_2) byproduct_move_line_1_lot_1 = finished_move_lines.filtered( lambda ml: ml.lot_id.name == 'Byproduct_1_lot_1') self.assertEqual(byproduct_move_line_1_lot_1.consume_line_ids, raw_line_raw_1_lot_1 | raw_line_raw_2_lot_1) byproduct_move_line_1_lot_2 = finished_move_lines.filtered( lambda ml: ml.lot_id.name == 'Byproduct_1_lot_2') self.assertEqual(byproduct_move_line_1_lot_2.consume_line_ids, raw_line_raw_1_lot_2 | raw_line_raw_2_lot_2) byproduct_move_line_2_lot_1 = finished_move_lines.filtered( lambda ml: ml.lot_id.name == 'Byproduct_2_lot_1') self.assertEqual(byproduct_move_line_2_lot_1.consume_line_ids, raw_line_raw_1_lot_1 | raw_line_raw_2_lot_1) byproduct_move_line_2_lot_2 = finished_move_lines.filtered( lambda ml: ml.lot_id.name == 'Byproduct_2_lot_2') self.assertEqual(byproduct_move_line_2_lot_2.consume_line_ids, raw_line_raw_1_lot_2 | raw_line_raw_2_lot_2)
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) # 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, 'company_id': self.env.company.id, }) serial_id = self.env['stock.production.lot'].create({ 'name': 'lot1', 'product_id': self.comp1_sn.id, 'company_id': self.env.company.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) picking_receipt.move_lines.quantity_done = 1 picking_receipt.move_lines.move_line_ids.lot_id = lot_id.id 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_subcontractor, allow_negative=True) avail_qty_comp2 = self.env['stock.quant']._get_available_quantity( self.comp2, self.subcontractor_partner1.property_stock_subcontractor, 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)
def test_flow_7(self): """ Process a subcontracting receipt with tracked component and finished product. Simulate the regiter components button. Once the components are registered, try to do a correction on exisiting move lines and check that the subcontracting document is updated. """ # Create a receipt picking from the subcontractor (self.comp1 | self.comp2 | self.finished).write({'tracking': 'lot'}) 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 = 5 picking_receipt = picking_form.save() picking_receipt.action_confirm() mo = picking_receipt.move_lines.move_orig_ids.production_id move_comp1 = mo.move_raw_ids.filtered( lambda m: m.product_id == self.comp1) move_comp2 = mo.move_raw_ids.filtered( lambda m: m.product_id == self.comp2) # move_finished is linked to receipt and not MO finished move. move_finished = picking_receipt.move_lines self.assertEqual(move_comp1.quantity_done, 0) self.assertEqual(move_comp2.quantity_done, 0) lot_c1 = self.env['stock.production.lot'].create({ 'name': 'LOT C1', 'product_id': self.comp1.id, 'company_id': self.env.company.id, }) lot_c2 = self.env['stock.production.lot'].create({ 'name': 'LOT C2', 'product_id': self.comp2.id, 'company_id': self.env.company.id, }) lot_f1 = self.env['stock.production.lot'].create({ 'name': 'LOT F1', 'product_id': self.finished.id, 'company_id': self.env.company.id, }) register_form = Form(self.env['mrp.product.produce'].with_context( active_id=picking_receipt._get_subcontracted_productions().id, default_subcontract_move_id=picking_receipt.move_lines.id)) register_form.qty_producing = 3.0 self.assertEqual( len(register_form._values['raw_workorder_line_ids']), 2, 'Register Components Form should contains one line per component.') self.assertTrue( all(p[2]['product_id'] in (self.comp1 | self.comp2).ids for p in register_form._values['raw_workorder_line_ids']), 'Register Components Form should contains component.') with register_form.raw_workorder_line_ids.edit(0) as pl: pl.lot_id = lot_c1 with register_form.raw_workorder_line_ids.edit(1) as pl: pl.lot_id = lot_c2 register_form.finished_lot_id = lot_f1 register_wizard = register_form.save() action = register_wizard.continue_production() register_form = Form( self.env['mrp.product.produce'].with_context(**action['context'])) with register_form.raw_workorder_line_ids.edit(0) as pl: pl.lot_id = lot_c1 with register_form.raw_workorder_line_ids.edit(1) as pl: pl.lot_id = lot_c2 register_form.finished_lot_id = lot_f1 register_wizard = register_form.save() register_wizard.do_produce() self.assertEqual(move_comp1.quantity_done, 5.0) self.assertEqual( move_comp1.move_line_ids.filtered( lambda ml: not ml.product_uom_qty).lot_id.name, 'LOT C1') self.assertEqual(move_comp2.quantity_done, 5.0) self.assertEqual( move_comp2.move_line_ids.filtered( lambda ml: not ml.product_uom_qty).lot_id.name, 'LOT C2') self.assertEqual(move_finished.quantity_done, 5.0) self.assertEqual( move_finished.move_line_ids.filtered( lambda ml: ml.product_uom_qty).lot_id.name, 'LOT F1') corrected_final_lot = self.env['stock.production.lot'].create({ 'name': 'LOT F2', 'product_id': self.finished.id, 'company_id': self.env.company.id, }) details_operation_form = Form( picking_receipt.move_lines, view=self.env.ref('stock.view_stock_move_operations')) for i in range(len(details_operation_form._values['move_line_ids'])): with details_operation_form.move_line_ids.edit(i) as ml: if ml._values['qty_done']: ml.lot_id = corrected_final_lot details_operation_form.save() move_raw_comp_1 = picking_receipt.move_lines.move_orig_ids.production_id.move_raw_ids.filtered( lambda m: m.product_id == self.comp1) move_raw_comp_2 = picking_receipt.move_lines.move_orig_ids.production_id.move_raw_ids.filtered( lambda m: m.product_id == self.comp2) details_subcontract_moves_form = Form( move_raw_comp_1, view=self.env.ref( 'mrp_subcontracting.mrp_subcontracting_move_form_view')) for i in range( len(details_subcontract_moves_form._values['move_line_ids'])): with details_subcontract_moves_form.move_line_ids.edit(i) as sc: if sc._values['qty_done']: sc.lot_produced_ids.remove(index=0) sc.lot_produced_ids.add(corrected_final_lot) details_subcontract_moves_form.save() details_subcontract_moves_form = Form( move_raw_comp_2, view=self.env.ref( 'mrp_subcontracting.mrp_subcontracting_move_form_view')) for i in range( len(details_subcontract_moves_form._values['move_line_ids'])): with details_subcontract_moves_form.move_line_ids.edit(i) as sc: if sc._values['qty_done']: sc.lot_produced_ids.remove(index=0) sc.lot_produced_ids.add(corrected_final_lot) details_subcontract_moves_form.save() self.assertEqual( move_comp1.move_line_ids.filtered( lambda ml: not ml.product_uom_qty).lot_produced_ids.name, 'LOT F2') self.assertEqual( move_comp2.move_line_ids.filtered( lambda ml: not ml.product_uom_qty).lot_produced_ids.name, 'LOT F2')
def test_production_links_with_non_tracked_lots(self): """ This test produces an MO in two times and checks that the move lines are linked in a correct way """ mo, bom, p_final, p1, p2 = self.generate_mo(tracking_final='lot', tracking_base_1='none', tracking_base_2='lot') lot_1 = self.env['stock.production.lot'].create({ 'name': 'lot_1', 'product_id': p2.id, 'company_id': self.env.company.id, }) self.env['stock.quant']._update_available_quantity(p2, self.stock_location, 3, lot_id=lot_1) lot_finished_1 = self.env['stock.production.lot'].create({ 'name': 'lot_finished_1', 'product_id': p_final.id, 'company_id': self.env.company.id, }) produce_form = Form(self.env['mrp.product.produce'].with_context({ 'active_id': mo.id, 'active_ids': [mo.id], })) produce_form.qty_producing = 3.0 produce_form.finished_lot_id = lot_finished_1 produce_wizard = produce_form.save() produce_wizard._workorder_line_ids()[0].lot_id = lot_1 produce_wizard.do_produce() lot_2 = self.env['stock.production.lot'].create({ 'name': 'lot_2', 'product_id': p2.id, 'company_id': self.env.company.id, }) self.env['stock.quant']._update_available_quantity(p2, self.stock_location, 4, lot_id=lot_2) lot_finished_2 = self.env['stock.production.lot'].create({ 'name': 'lot_finished_2', 'product_id': p_final.id, 'company_id': self.env.company.id, }) produce_form = Form(self.env['mrp.product.produce'].with_context({ 'active_id': mo.id, 'active_ids': [mo.id], })) produce_form.qty_producing = 2.0 produce_form.finished_lot_id = lot_finished_2 produce_wizard = produce_form.save() produce_wizard._workorder_line_ids()[0].lot_id = lot_2 produce_wizard.do_produce() mo.button_mark_done() ml = mo.finished_move_line_ids[0].consume_line_ids.filtered( lambda m: m.product_id == p1 and lot_finished_1 in m. lot_produced_ids) self.assertEqual(ml[0].qty_done, 12.0, 'Should have consumed 12 for the first lot') ml = mo.finished_move_line_ids[1].consume_line_ids.filtered( lambda m: m.product_id == p1 and lot_finished_2 in m. lot_produced_ids) self.assertEqual(ml[0].qty_done, 8.0, 'Should have consumed 8 for the second lot')
def test_unbuild_with_everything_tracked(self): """ This test creates a MO and then creates 3 unbuild orders for the final product. All the products for this test are tracked. It checks the stock state after each order and ensure it is correct. """ mo, bom, p_final, p1, p2 = self.generate_mo(tracking_final='lot', tracking_base_2='lot', tracking_base_1='lot') self.assertEqual(len(mo), 1, 'MO should have been created') lot_final = self.env['stock.production.lot'].create({ 'name': 'lot_final', 'product_id': p_final.id, 'company_id': self.env.company.id, }) lot_1 = self.env['stock.production.lot'].create({ 'name': 'lot_consumed_1', 'product_id': p1.id, 'company_id': self.env.company.id, }) lot_2 = self.env['stock.production.lot'].create({ 'name': 'lot_consumed_2', 'product_id': p2.id, 'company_id': self.env.company.id, }) self.env['stock.quant']._update_available_quantity(p1, self.stock_location, 100, lot_id=lot_1) self.env['stock.quant']._update_available_quantity(p2, self.stock_location, 5, lot_id=lot_2) mo.action_assign() produce_form = Form(self.env['mrp.product.produce'].with_context({ 'active_id': mo.id, 'active_ids': [mo.id], })) produce_form.qty_producing = 5.0 produce_form.finished_lot_id = lot_final produce_wizard = produce_form.save() produce_wizard.do_produce() mo.button_mark_done() self.assertEqual(mo.state, 'done', "Production order should be in done state.") # Check quantity in stock before unbuild. self.assertEqual( self.env['stock.quant']._get_available_quantity( p_final, self.stock_location, lot_id=lot_final), 5, 'You should have the 5 final product in stock') self.assertEqual( self.env['stock.quant']._get_available_quantity( p1, self.stock_location, lot_id=lot_1), 80, 'You should have 80 products in stock') self.assertEqual( self.env['stock.quant']._get_available_quantity( p2, self.stock_location, lot_id=lot_2), 0, 'You should have consumed all the 5 product in stock') # --------------------------------------------------- # unbuild # --------------------------------------------------- x = Form(self.env['mrp.unbuild']) with self.assertRaises(AssertionError): x.product_id = p_final x.bom_id = bom x.product_uom_id = self.uom_unit x.product_qty = 3 x.save() with self.assertRaises(AssertionError): x.product_id = p_final x.bom_id = bom x.product_uom_id = self.uom_unit x.product_qty = 3 x.save() self.assertEqual( self.env['stock.quant']._get_available_quantity( p_final, self.stock_location, lot_id=lot_final), 5, 'You should have consumed 3 final product in stock') with self.assertRaises(AssertionError): x.product_id = p_final x.bom_id = bom x.product_uom_id = self.uom_unit x.mo_id = mo x.product_qty = 3 x.save() self.assertEqual( self.env['stock.quant']._get_available_quantity( p_final, self.stock_location, lot_id=lot_final), 5, 'You should have consumed 3 final product in stock') x = Form(self.env['mrp.unbuild']) x.product_id = p_final x.bom_id = bom x.product_uom_id = self.uom_unit x.mo_id = mo x.product_qty = 3 x.lot_id = lot_final x.save().action_unbuild() self.assertEqual( self.env['stock.quant']._get_available_quantity( p_final, self.stock_location, lot_id=lot_final), 2, 'You should have consumed 3 final product in stock') self.assertEqual( self.env['stock.quant']._get_available_quantity( p1, self.stock_location, lot_id=lot_1), 92, 'You should have 80 products in stock') self.assertEqual( self.env['stock.quant']._get_available_quantity( p2, self.stock_location, lot_id=lot_2), 3, 'You should have consumed all the 5 product in stock') x = Form(self.env['mrp.unbuild']) x.product_id = p_final x.bom_id = bom x.product_uom_id = self.uom_unit x.mo_id = mo x.product_qty = 2 x.lot_id = lot_final x.save().action_unbuild() self.assertEqual( self.env['stock.quant']._get_available_quantity( p_final, self.stock_location, lot_id=lot_final), 0, 'You should have 0 finalproduct in stock') self.assertEqual( self.env['stock.quant']._get_available_quantity( p1, self.stock_location, lot_id=lot_1), 100, 'You should have 80 products in stock') self.assertEqual( self.env['stock.quant']._get_available_quantity( p2, self.stock_location, lot_id=lot_2), 5, 'You should have consumed all the 5 product in stock') x = Form(self.env['mrp.unbuild']) x.product_id = p_final x.bom_id = bom x.product_uom_id = self.uom_unit x.mo_id = mo x.product_qty = 5 x.lot_id = lot_final x.save().action_unbuild() self.assertEqual( self.env['stock.quant']._get_available_quantity( p_final, self.stock_location, lot_id=lot_final, allow_negative=True), -5, 'You should have negative quantity for final product in stock') self.assertEqual( self.env['stock.quant']._get_available_quantity( p1, self.stock_location, lot_id=lot_1), 120, 'You should have 80 products in stock') self.assertEqual( self.env['stock.quant']._get_available_quantity( p2, self.stock_location, lot_id=lot_2), 10, 'You should have consumed all the 5 product in stock')