From 0751d887e6d4f810d779183d3bf17806cccaf97e Mon Sep 17 00:00:00 2001 From: ABE-Mark45 Date: Tue, 6 Feb 2024 17:18:51 +0300 Subject: [PATCH] [IMP] mrp_subcontracting_purchase: test BoM report quantities and availabilities Testing quantities and availablility states in subcontracted BoM report 1. Create a BoM of a finished product with a single component 2. Update the on hand quantity of BoM to 100 3. Move 20 components to subcontracting location 4. Check that the free/on-hand quantity of component is 100 (sum of warehouse stock and subcontracting location stock) 5. Check that producible quantity of 'Product' is equal to only subcontractor location stock 6. Check availability states when: 6a. Search quantity <= subcontractor quantity: component is available 6b. Subcontractor quantity <= search quantity <= total quantity: component is available 6c. Total quantity < search quantity: component is unavailable task-3632211 closes odoo/odoo#145889 Signed-off-by: Steve Van Essche --- .../tests/test_mrp_subcontracting_purchase.py | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/addons/mrp_subcontracting_purchase/tests/test_mrp_subcontracting_purchase.py b/addons/mrp_subcontracting_purchase/tests/test_mrp_subcontracting_purchase.py index 74693f5e376..b0480a2bc6c 100644 --- a/addons/mrp_subcontracting_purchase/tests/test_mrp_subcontracting_purchase.py +++ b/addons/mrp_subcontracting_purchase/tests/test_mrp_subcontracting_purchase.py @@ -656,3 +656,81 @@ class MrpSubcontractingPurchaseTest(TestMrpSubcontractingCommon): self.assertEqual(picking.backorder_ids.state, 'cancel') po.order_line.product_qty = 2.0 self.assertEqual(po.order_line.product_qty, 2.0) + + def test_mrp_report_bom_structure_subcontracting_quantities(self): + """Testing quantities and availablility states in subcontracted BoM report + 1. Create a BoM of a finished product with a single component + 2. Update the on hand quantity of BoM to 100 + 3. Move 20 components to subcontracting location + 4. Check that the free/on-hand quantity of component is 100 (sum of warehouse stock and subcontracting location stock) + 5. Check that producible quantity of 'Product' is equal to only subcontractor location stock + 6. Check availability states when: + 6a. Search quantity <= subcontractor quantity: component is available + 6b. Subcontractor quantity <= search quantity <= total quantity: component is available + 6c. Total quantity < search quantity: component is unavailable + """ + search_qty_less_than_or_equal_moved = 10 + moved_quantity_to_subcontractor = 20 + search_qty_less_than_or_equal_total = 90 + total_component_quantity = 100 + search_qty_more_than_total = 110 + + resupply_route = self.env['stock.route'].search([('name', '=', 'Resupply Subcontractor on Order')]) + finished, component = self.env['product.product'].create([{ + 'name': 'Finished Product', + 'type': 'product', + 'seller_ids': [(0, 0, {'partner_id': self.subcontractor_partner1.id})] + }, { + 'name': 'Component', + 'type': 'product', + 'route_ids': [(4, resupply_route.id)], + }]) + + bom = self.env['mrp.bom'].create({ + 'product_tmpl_id': finished.product_tmpl_id.id, + 'product_qty': 1.0, + 'type': 'subcontract', + 'subcontractor_ids': [(4, self.subcontractor_partner1.id)], + 'bom_line_ids': [(0, 0, {'product_id': component.id, 'product_qty': 1.0})], + }) + + inventory_wizard = self.env['stock.change.product.qty'].create({ + 'product_id': component.id, + 'product_tmpl_id': component.product_tmpl_id.id, + 'new_quantity': total_component_quantity, + }) + inventory_wizard.change_product_qty() + # Check quantity was updated + self.assertEqual(component.virtual_available, total_component_quantity) + self.assertEqual(component.qty_available, total_component_quantity) + + quantity_before_move = self.env['stock.quant']._get_available_quantity(component, self.subcontractor_partner1.property_stock_subcontractor, allow_negative=True) + picking_form = Form(self.env['stock.picking']) + picking_form.picking_type_id = self.warehouse.subcontracting_resupply_type_id + picking_form.partner_id = self.subcontractor_partner1 + with picking_form.move_ids_without_package.new() as move: + move.product_id = component + move.product_uom_qty = moved_quantity_to_subcontractor + picking = picking_form.save() + picking.action_confirm() + picking.move_ids.quantity = moved_quantity_to_subcontractor + picking.move_ids.picked = True + picking.button_validate() + quantity_after_move = self.env['stock.quant']._get_available_quantity(component, self.subcontractor_partner1.property_stock_subcontractor, allow_negative=True) + self.assertEqual(quantity_after_move, quantity_before_move + moved_quantity_to_subcontractor) + + report_values = self.env['report.mrp.report_bom_structure']._get_report_data(bom.id, searchQty=search_qty_less_than_or_equal_moved, searchVariant=False) + self.assertEqual(report_values['lines']['components'][0]['quantity_available'], total_component_quantity) + self.assertEqual(report_values['lines']['components'][0]['quantity_on_hand'], total_component_quantity) + self.assertEqual(report_values['lines']['quantity_available'], 0) + self.assertEqual(report_values['lines']['quantity_on_hand'], 0) + self.assertEqual(report_values['lines']['producible_qty'], moved_quantity_to_subcontractor) + self.assertEqual(report_values['lines']['stock_avail_state'], 'unavailable') + + self.assertEqual(report_values['lines']['components'][0]['stock_avail_state'], 'available') + + report_values = self.env['report.mrp.report_bom_structure']._get_report_data(bom.id, searchQty=search_qty_less_than_or_equal_total, searchVariant=False) + self.assertEqual(report_values['lines']['components'][0]['stock_avail_state'], 'available') + + report_values = self.env['report.mrp.report_bom_structure']._get_report_data(bom.id, searchQty=search_qty_more_than_total, searchVariant=False) + self.assertEqual(report_values['lines']['components'][0]['stock_avail_state'], 'unavailable')