예제 #1
0
    def test_pricelist_application(self):
        """ Test different prices are correctly applied based on dates """
        support_product = self.env.ref('product.product_product_2')
        support_product.list_price = 100
        partner = self.res_partner_model.create(dict(name="George"))

        christmas_pricelist = self.env['product.pricelist'].create({
            'name':
            'Christmas pricelist',
            'item_ids': [(0, 0, {
                'date_start': "2017-12-01",
                'date_end': "2017-12-24",
                'compute_price': 'percentage',
                'base': 'list_price',
                'percent_price': 20,
                'applied_on': '3_global',
                'name': 'Pre-Christmas discount'
            }),
                         (0, 0, {
                             'date_start': "2017-12-25",
                             'date_end': "2017-12-31",
                             'compute_price': 'percentage',
                             'base': 'list_price',
                             'percent_price': 50,
                             'applied_on': '3_global',
                             'name': 'Post-Christmas super-discount'
                         })]
        })

        # Create the SO with pricelist based on date
        order_form = Form(
            self.env['sale.order'].with_context(tracking_disable=True))
        order_form.partner_id = partner
        order_form.date_order = '2017-12-20'
        order_form.pricelist_id = christmas_pricelist
        with order_form.order_line.new() as line:
            line.product_id = support_product
        so = order_form.save()
        # Check the unit price and subtotal of SO line
        self.assertEqual(so.order_line[0].price_unit, 80,
                         "First date pricelist rule not applied")
        self.assertEquals(
            so.order_line[0].price_subtotal,
            so.order_line[0].price_unit * so.order_line[0].product_uom_qty,
            'Total of SO line should be a multiplication of unit price and ordered quantity'
        )

        # Change order date of the SO and check the unit price and subtotal of SO line
        with Form(so) as order:
            order.date_order = '2017-12-30'
            with order.order_line.edit(0) as line:
                line.product_id = support_product

        self.assertEqual(so.order_line[0].price_unit, 50,
                         "Second date pricelist rule not applied")
        self.assertEquals(
            so.order_line[0].price_subtotal,
            so.order_line[0].price_unit * so.order_line[0].product_uom_qty,
            'Total of SO line should be a multiplication of unit price and ordered quantity'
        )
예제 #2
0
    def test_00_crossdock(self):

        # Create a supplier
        supplier_crossdock = self.env['res.partner'].create(
            {'name': "Crossdocking supplier"})

        # I first create a warehouse with pick-pack-ship and reception in 2 steps
        wh_f = Form(self.env['stock.warehouse'])
        wh_f.name = 'WareHouse PickPackShip'
        wh_f.code = 'whpps'
        wh_f.reception_steps = 'two_steps'
        wh_f.delivery_steps = 'pick_pack_ship'
        wh_pps = wh_f.save()

        # Check that cross-dock route is active
        self.assertTrue(
            wh_pps.crossdock_route_id.active,
            "Crossdock route should be active when reception_steps is not in 'single_step'"
        )

        p_f = Form(self.env['product.template'])
        p_f.name = 'PCE'
        p_f.type = 'product'
        p_f.categ_id = self.env.ref('product.product_category_1')
        p_f.list_price = 100.0
        p_f.standard_price = 70.0
        with p_f.seller_ids.new() as seller:
            seller.name = supplier_crossdock
        p_f.route_ids.add(wh_pps.crossdock_route_id)
        cross_shop_product = p_f.save()

        # Create a sales order with a line of 100 PCE incoming shipment with route_id crossdock shipping
        so_form = Form(self.env['sale.order'])
        so_form.partner_id = self.env.ref('base.res_partner_4')
        so_form.warehouse_id = wh_pps

        with mute_logger('swerp.tests.common.onchange'):
            # otherwise complains that there's not enough inventory and
            # apparently that's normal according to @jco and @sle
            with so_form.order_line.new() as line:
                line.product_id = cross_shop_product.product_variant_ids
                line.product_uom_qty = 100.0
            sale_order_crossdock = so_form.save()

        # Confirm sales order
        sale_order_crossdock.action_confirm()

        # Run the scheduler
        self.env['procurement.group'].run_scheduler()

        # Check a quotation was created for the created supplier and confirm it
        po = self.env['purchase.order'].search([('partner_id', '=',
                                                 supplier_crossdock.id),
                                                ('state', '=', 'draft')])
        self.assertTrue(po, "an RFQ should have been created by the scheduler")
        po.button_confirm()
예제 #3
0
    def test_reordering_rule(self):
        """
            - Receive products in 2 steps
            - The product has a reordering rule
            - On the po generated, the source document should be the name of the reordering rule
        """
        warehouse_1 = self.env['stock.warehouse'].search([('company_id', '=', self.env.user.id)], limit=1)
        warehouse_1.write({'reception_steps': 'two_steps'})

        # Create a supplier
        partner = self.env['res.partner'].create({
            'name': 'Smith'
        })

        # create product and set the vendor
        product_form = Form(self.env['product.product'])
        product_form.name = 'Product A'
        product_form.type = 'product'
        with product_form.seller_ids.new() as seller:
            seller.name = partner
        product_form.route_ids.add(self.env.ref('purchase_stock.route_warehouse0_buy'))
        product_01 = product_form.save()

        # create reordering rule
        orderpoint_form = Form(self.env['stock.warehouse.orderpoint'])
        orderpoint_form.warehouse_id = warehouse_1
        orderpoint_form.location_id = warehouse_1.lot_stock_id
        orderpoint_form.product_id = product_01
        orderpoint_form.product_min_qty = 0.000
        orderpoint_form.product_max_qty = 0.000
        order_point = orderpoint_form.save()

        # Create Delivery Order of 10 product
        picking_form = Form(self.env['stock.picking'])
        picking_form.partner_id = partner
        picking_form.picking_type_id = self.env.ref('stock.picking_type_out')
        with picking_form.move_ids_without_package.new() as move:
            move.product_id = product_01
            move.product_uom_qty = 10.0
        customer_picking = picking_form.save()

        # picking confirm
        customer_picking.action_confirm()

        # Run scheduler
        self.env['procurement.group'].run_scheduler()

        # Check purchase order created or not
        purchase_order = self.env['purchase.order'].search([('partner_id', '=', partner.id)])
        self.assertTrue(purchase_order, 'No purchase order created.')

        # On the po generated, the source document should be the name of the reordering rule
        self.assertEqual(order_point.name, purchase_order.origin, 'Source document on purchase order should be the name of the reordering rule.')
    def setUp(self):
        super(TestMultistepManufacturing, self).setUp()

        self.MrpProduction = self.env['mrp.production']
        # Create warehouse
        warehouse_form = Form(self.env['stock.warehouse'])
        warehouse_form.name = 'Test'
        warehouse_form.code = 'Test'
        self.warehouse = warehouse_form.save()

        self.uom_unit = self.env.ref('uom.product_uom_unit')

        # Create manufactured product
        product_form = Form(self.env['product.product'])
        product_form.name = 'Stick'
        product_form.uom_id = self.uom_unit
        product_form.uom_po_id = self.uom_unit
        product_form.route_ids.clear()
        product_form.route_ids.add(self.warehouse.manufacture_pull_id.route_id)
        product_form.route_ids.add(self.warehouse.mto_pull_id.route_id)
        self.product_manu = product_form.save()

        # Create raw product for manufactured product
        product_form = Form(self.env['product.product'])
        product_form.name = 'Raw Stick'
        product_form.uom_id = self.uom_unit
        product_form.uom_po_id = self.uom_unit
        self.product_raw = product_form.save()

        # Create bom for manufactured product
        bom_product_form = Form(self.env['mrp.bom'])
        bom_product_form.product_id = self.product_manu
        bom_product_form.product_tmpl_id = self.product_manu.product_tmpl_id
        bom_product_form.product_qty = 1.0
        bom_product_form.type = 'normal'
        with bom_product_form.bom_line_ids.new() as bom_line:
            bom_line.product_id = self.product_raw
            bom_line.product_qty = 2.0
        self.bom_prod_manu = bom_product_form.save()

        # Create sale order
        sale_form = Form(self.env['sale.order'])
        sale_form.partner_id = self.env.ref('base.res_partner_1')
        sale_form.picking_policy = 'direct'
        sale_form.warehouse_id = self.warehouse
        with sale_form.order_line.new() as line:
            line.name = self.product_manu.name
            line.product_id = self.product_manu
            line.product_uom_qty = 1.0
            line.product_uom = self.uom_unit
            line.price_unit = 10.0
        self.sale_order = sale_form.save()
예제 #5
0
    def test_rounding(self):
        """ In previous versions we had rounding and efficiency fields.  We check if we can still do the same, but with only the rounding on the UoM"""
        self.product_6.uom_id.rounding = 1.0
        bom_eff = self.env['mrp.bom'].create({'product_id': self.product_6.id,
                                    'product_tmpl_id': self.product_6.product_tmpl_id.id,
                                    'product_qty': 1,
                                    'product_uom_id': self.product_6.uom_id.id,
                                    'type': 'normal',
                                    'bom_line_ids': [
                                        (0, 0, {'product_id': self.product_2.id, 'product_qty': 2.03}),
                                        (0, 0, {'product_id': self.product_8.id, 'product_qty': 4.16})
                                        ]})
        production = self.env['mrp.production'].create({'name': 'MO efficiency test',
                                           'product_id': self.product_6.id,
                                           'product_qty': 20,
                                           'bom_id': bom_eff.id,
                                           'product_uom_id': self.product_6.uom_id.id,})
        #Check the production order has the right quantities
        self.assertEqual(production.move_raw_ids[0].product_qty, 41, 'The quantity should be rounded up')
        self.assertEqual(production.move_raw_ids[1].product_qty, 84, 'The quantity should be rounded up')

        # produce product
        produce_form = Form(self.env['mrp.product.produce'].with_context({
            'active_id': production.id,
            'active_ids': [production.id],
        }))
        produce_form.product_qty = 8
        produce_wizard = produce_form.save()
        produce_wizard.do_produce()
        self.assertEqual(production.move_raw_ids[0].quantity_done, 16, 'Should use half-up rounding when producing')
        self.assertEqual(production.move_raw_ids[1].quantity_done, 34, 'Should use half-up rounding when producing')
예제 #6
0
 def test_split_move_line(self):
     """ Consume more component quantity than the initial demand.
     It should create extra move and share the quantity between the two stock
     moves """
     mo, _, p_final, p1, p2 = self.generate_mo(qty_base_1=10, qty_final=1, qty_base_2=1)
     mo.action_assign()
     produce_form = Form(self.env['mrp.product.produce'].with_context({
         'active_id': mo.id,
         'active_ids': [mo.id],
     }))
     for i in range(len(produce_form.produce_line_ids)):
         with produce_form.produce_line_ids.edit(i) as line:
             line.qty_done += 1
     product_produce = produce_form.save()
     product_produce.do_produce()
     self.assertEqual(len(mo.move_raw_ids), 2)
     self.assertEqual(len(mo.move_raw_ids.mapped('move_line_ids')), 2)
     self.assertEqual(mo.move_raw_ids[0].move_line_ids.mapped('qty_done'), [2])
     self.assertEqual(mo.move_raw_ids[1].move_line_ids.mapped('qty_done'), [11])
     self.assertEqual(mo.move_raw_ids[0].quantity_done, 2)
     self.assertEqual(mo.move_raw_ids[1].quantity_done, 11)
     mo.button_mark_done()
     self.assertEqual(len(mo.move_raw_ids), 4)
     self.assertEqual(len(mo.move_raw_ids.mapped('move_line_ids')), 4)
     self.assertEqual(mo.move_raw_ids.mapped('quantity_done'), [1, 10, 1, 1])
     self.assertEqual(mo.move_raw_ids.mapped('move_line_ids.qty_done'), [1, 10, 1, 1])
 def test_01_warehouse_twostep_manufacturing(self):
     """ Warehouse testing for picking before manufacturing """
     with Form(self.warehouse) as warehouse:
         warehouse.manufacture_steps = 'pbm'
     self._check_location_and_routes()
     self.assertEqual(len(self.warehouse.pbm_route_id.rule_ids), 2)
     self.assertEqual(self.warehouse.manufacture_pull_id.location_id.id,
                      self.warehouse.lot_stock_id.id)
 def test_02_warehouse_twostep_manufacturing(self):
     """ Warehouse testing for picking ans store after manufacturing """
     with Form(self.warehouse) as warehouse:
         warehouse.manufacture_steps = 'pbm_sam'
     self._check_location_and_routes()
     self.assertEqual(len(self.warehouse.pbm_route_id.rule_ids), 3)
     self.assertEqual(self.warehouse.manufacture_pull_id.location_id.id,
                      self.warehouse.sam_loc_id.id)
예제 #9
0
 def test_employee_resource(self):
     _tz = 'Pacific/Apia'
     self.res_users_hr_officer.company_id.resource_calendar_id.tz = _tz
     Employee = self.env['hr.employee'].sudo(self.res_users_hr_officer)
     employee_form = Form(Employee)
     employee_form.name = 'Raoul Grosbedon'
     employee_form.work_email = '*****@*****.**'
     employee = employee_form.save()
     self.assertEqual(employee.tz, _tz)
예제 #10
0
    def test_00_product_company_level_delays(self):
        """ In order to check schedule date, set product's Manufacturing Lead Time
            and Customer Lead Time and also set company's Manufacturing Lead Time
            and Sales Safety Days."""

        company = self.env.ref('base.main_company')

        # Update company with Manufacturing Lead Time and Sales Safety Days
        company.write({'manufacturing_lead': 3.0, 'security_lead': 3.0})

        # Create sale order of product_1
        order_form = Form(self.env['sale.order'])
        order_form.partner_id = self.partner_1
        with order_form.order_line.new() as line:
            line.product_id = self.product_1
            line.product_uom_qty = 10
        order = order_form.save()
        # Confirm sale order
        order.action_confirm()

        # Check manufacturing order created or not
        manufacturing_order = self.env['mrp.production'].search([
            ('product_id', '=', self.product_1.id),
            ('move_dest_ids', 'in', order.picking_ids[0].move_lines.ids)
        ])
        self.assertTrue(manufacturing_order,
                        'Manufacturing order should be created.')

        # Check schedule date of picking
        out_date = fields.Datetime.from_string(order.date_order) + timedelta(
            days=self.product_1.sale_delay) - timedelta(
                days=company.security_lead)
        min_date = fields.Datetime.from_string(
            order.picking_ids[0].scheduled_date)
        self.assertAlmostEqual(
            min_date,
            out_date,
            delta=timedelta(seconds=1),
            msg=
            'Schedule date of picking should be equal to: Order date + Customer Lead Time - Sales Safety Days.'
        )

        # Check schedule date of manufacturing order
        mo_date = out_date - timedelta(
            days=self.product_1.produce_delay) - timedelta(
                days=company.manufacturing_lead)
        date_planned_start = fields.Datetime.from_string(
            manufacturing_order.date_planned_start)
        self.assertAlmostEqual(
            date_planned_start,
            mo_date,
            delta=timedelta(seconds=1),
            msg=
            "Schedule date of manufacturing order should be equal to: Schedule date of picking - product's Manufacturing Lead Time - company's Manufacturing Lead Time."
        )
    def setUp(self):
        super(TestMultistepManufacturingWarehouse, self).setUp()
        # Create warehouse
        self.customer_location = self.env['ir.model.data'].xmlid_to_res_id(
            'stock.stock_location_customers')
        warehouse_form = Form(self.env['stock.warehouse'])
        warehouse_form.name = 'Test Warehouse'
        warehouse_form.code = 'TWH'
        self.warehouse = warehouse_form.save()

        self.uom_unit = self.env.ref('uom.product_uom_unit')

        # Create manufactured product
        product_form = Form(self.env['product.product'])
        product_form.name = 'Stick'
        product_form.uom_id = self.uom_unit
        product_form.uom_po_id = self.uom_unit
        product_form.type = 'product'
        product_form.route_ids.clear()
        product_form.route_ids.add(self.warehouse.manufacture_pull_id.route_id)
        product_form.route_ids.add(self.warehouse.mto_pull_id.route_id)
        self.finished_product = product_form.save()

        # Create raw product for manufactured product
        product_form = Form(self.env['product.product'])
        product_form.name = 'Raw Stick'
        product_form.type = 'product'
        product_form.uom_id = self.uom_unit
        product_form.uom_po_id = self.uom_unit
        self.raw_product = product_form.save()

        # Create bom for manufactured product
        bom_product_form = Form(self.env['mrp.bom'])
        bom_product_form.product_id = self.finished_product
        bom_product_form.product_tmpl_id = self.finished_product.product_tmpl_id
        bom_product_form.product_qty = 1.0
        bom_product_form.type = 'normal'
        with bom_product_form.bom_line_ids.new() as bom_line:
            bom_line.product_id = self.raw_product
            bom_line.product_qty = 2.0

        self.bom = bom_product_form.save()
예제 #12
0
    def test_product_produce_2(self):
        """ Check that line are created when the consumed products are
        tracked by serial and the lot proposed are correct. """
        self.stock_location = self.env.ref('stock.stock_location_stock')
        mo, bom, p_final, p1, p2 = self.generate_mo(tracking_base_1='serial', qty_base_1=1, qty_final=2)
        self.assertEqual(len(mo), 1, 'MO should have been created')

        lot_p1_1 = self.env['stock.production.lot'].create({
            'name': 'lot1',
            'product_id': p1.id,
        })
        lot_p1_2 = self.env['stock.production.lot'].create({
            'name': 'lot2',
            'product_id': p1.id,
        })

        self.env['stock.quant']._update_available_quantity(p1, self.stock_location, 1, lot_id=lot_p1_1)
        self.env['stock.quant']._update_available_quantity(p1, self.stock_location, 1, lot_id=lot_p1_2)
        self.env['stock.quant']._update_available_quantity(p2, self.stock_location, 5)

        mo.action_assign()
        produce_form = Form(self.env['mrp.product.produce'].with_context({
            'active_id': mo.id,
            'active_ids': [mo.id],
        }))
        product_produce = produce_form.save()

        self.assertEqual(len(product_produce.produce_line_ids), 3, 'You should have 3 produce lines. One for each serial to consume')
        product_produce.product_qty = 1
        produce_line_1 = product_produce.produce_line_ids[0]
        produce_line_1.qty_done = 1
        remaining_lot = (lot_p1_1 | lot_p1_2) - produce_line_1.lot_id
        product_produce.do_produce()

        produce_form = Form(self.env['mrp.product.produce'].with_context({
            'active_id': mo.id,
            'active_ids': [mo.id],
        }))
        product_produce = produce_form.save()
        self.assertEqual(len(product_produce.produce_line_ids), 2, 'You should have 2 produce lines since one has already be consumed.')
        for line in product_produce.produce_line_ids.filtered(lambda x: x.lot_id):
            self.assertEqual(line.lot_id, remaining_lot, 'Wrong lot proposed.')
 def test_00_create_warehouse(self):
     """ Warehouse testing for direct manufacturing """
     with Form(self.warehouse) as warehouse:
         warehouse.manufacture_steps = 'mrp_one_step'
     self._check_location_and_routes()
     # Check locations of existing pull rule
     self.assertFalse(
         self.warehouse.pbm_route_id.rule_ids,
         'only the update of global manufacture route should happen.')
     self.assertEqual(self.warehouse.manufacture_pull_id.location_id.id,
                      self.warehouse.lot_stock_id.id)
예제 #14
0
    def test_00_procurement_exception(self):

        # I create a product with no supplier define for it.
        product_form = Form(self.env['product.product'])
        product_form.name = 'product with no seller'
        product_form.lst_price = 20.00
        product_form.standard_price = 15.00
        product_form.categ_id = self.env.ref('product.product_category_1')
        product_with_no_seller = product_form.save()

        # I create a sales order with this product with route dropship.
        so_form = Form(self.env['sale.order'])
        so_form.partner_id = self.env.ref('base.res_partner_2')
        so_form.partner_invoice_id = self.env.ref('base.res_partner_address_3')
        so_form.partner_shipping_id = self.env.ref('base.res_partner_address_3')
        so_form.payment_term_id = self.env.ref('account.account_payment_term')
        with so_form.order_line.new() as line:
            line.product_id = product_with_no_seller
            line.product_uom_qty = 1
            line.route_id = self.env.ref('stock_dropshipping.route_drop_shipping')
        sale_order_route_dropship01 = so_form.save()

        # I confirm the sales order, but it will raise an error
        with self.assertRaises(Exception):
            sale_order_route_dropship01.action_confirm()

        # I set the at least one supplier on the product.
        with Form(product_with_no_seller) as f:
            with f.seller_ids.new() as seller:
                seller.delay = 1
                seller.name = self.env.ref('base.res_partner_2')
                seller.min_qty = 2.0

        # I confirm the sales order, no error this time
        sale_order_route_dropship01.action_confirm()

        # I check a purchase quotation was created.
        purchase = self.env['purchase.order.line'].search([
            ('sale_line_id', '=', sale_order_route_dropship01.order_line.ids[0])]).order_id

        self.assertTrue(purchase, 'No Purchase Quotation is created')
예제 #15
0
 def test_employee_from_user_tz_no_reset(self):
     _tz = 'Pacific/Apia'
     self.res_users_hr_officer.tz = False
     Employee = self.env['hr.employee'].sudo(self.res_users_hr_officer)
     employee_form = Form(Employee)
     employee_form.name = 'Raoul Grosbedon'
     employee_form.work_email = '*****@*****.**'
     employee_form.tz = _tz
     employee_form.user_id = self.res_users_hr_officer
     employee = employee_form.save()
     self.assertEqual(employee.name, self.res_users_hr_officer.name)
     self.assertEqual(employee.work_email, self.res_users_hr_officer.email)
     self.assertEqual(employee.tz, _tz)
예제 #16
0
    def setUp(self):
        super(TestSaleMrpLeadTime, self).setUp()

        # Update the product_1 with type, route, Manufacturing Lead Time and Customer Lead Time
        with Form(self.product_1) as p1:
            p1.type = 'product'
            p1.produce_delay = 5.0
            p1.sale_delay = 5.0
            p1.route_ids.clear()
            p1.route_ids.add(self.warehouse_1.manufacture_pull_id.route_id)
            p1.route_ids.add(self.warehouse_1.mto_pull_id.route_id)

        # Update the product_2 with type
        with Form(self.product_2) as p2:
            p2.type = 'consu'

        # Create Bill of materials for product_1
        with Form(self.env['mrp.bom']) as bom:
            bom.product_tmpl_id = self.product_1.product_tmpl_id
            bom.product_qty = 2
            with bom.bom_line_ids.new() as line:
                line.product_id = self.product_2
                line.product_qty = 4
예제 #17
0
 def test_employee_from_user(self):
     _tz = 'Pacific/Apia'
     _tz2 = 'America/Tijuana'
     self.res_users_hr_officer.company_id.resource_calendar_id.tz = _tz
     self.res_users_hr_officer.tz = _tz2
     Employee = self.env['hr.employee'].sudo(self.res_users_hr_officer)
     employee_form = Form(Employee)
     employee_form.name = 'Raoul Grosbedon'
     employee_form.work_email = '*****@*****.**'
     employee_form.user_id = self.res_users_hr_officer
     employee = employee_form.save()
     self.assertEqual(employee.name, self.res_users_hr_officer.name)
     self.assertEqual(employee.work_email, self.res_users_hr_officer.email)
     self.assertEqual(employee.tz, self.res_users_hr_officer.tz)
    def test_manufacturing_3_steps(self):
        """ Test MO/picking before manufacturing/picking after manufacturing
        components and move_orig/move_dest. Ensure that everything is created
        correctly.
        """
        with Form(self.warehouse) as warehouse:
            warehouse.manufacture_steps = 'pbm_sam'

        production_form = Form(self.env['mrp.production'])
        production_form.product_id = self.finished_product
        production_form.picking_type_id = self.warehouse.manu_type_id
        production = production_form.save()

        move_raw_ids = production.move_raw_ids
        self.assertEqual(len(move_raw_ids), 1)
        self.assertEqual(move_raw_ids.product_id, self.raw_product)
        self.assertEqual(move_raw_ids.picking_type_id,
                         self.warehouse.manu_type_id)
        pbm_move = move_raw_ids.move_orig_ids
        self.assertEqual(len(pbm_move), 1)
        self.assertEqual(pbm_move.location_id, self.warehouse.lot_stock_id)
        self.assertEqual(pbm_move.location_dest_id, self.warehouse.pbm_loc_id)
        self.assertEqual(pbm_move.picking_type_id, self.warehouse.pbm_type_id)
        self.assertFalse(pbm_move.move_orig_ids)

        move_finished_ids = production.move_finished_ids
        self.assertEqual(len(move_finished_ids), 1)
        self.assertEqual(move_finished_ids.product_id, self.finished_product)
        self.assertEqual(move_finished_ids.picking_type_id,
                         self.warehouse.manu_type_id)
        sam_move = move_finished_ids.move_dest_ids
        self.assertEqual(len(sam_move), 1)
        self.assertEqual(sam_move.location_id, self.warehouse.sam_loc_id)
        self.assertEqual(sam_move.location_dest_id,
                         self.warehouse.lot_stock_id)
        self.assertEqual(sam_move.picking_type_id, self.warehouse.sam_type_id)
        self.assertFalse(sam_move.move_dest_ids)
예제 #19
0
    def test_product_produce_7(self):
        """ Plan 100 products to produce. Produce 50. Do a 'Post Inventory'.
        Update the quantity to produce to 200. Produce 50 again. Check that
        the components has been consumed correctly.
        """
        self.stock_location = self.env.ref('stock.stock_location_stock')
        mo, bom, p_final, p1, p2 = self.generate_mo(qty_base_1=2, qty_base_2=2, qty_final=100)
        self.assertEqual(len(mo), 1, 'MO should have been created')

        self.env['stock.quant']._update_available_quantity(p1, self.stock_location, 200)
        self.env['stock.quant']._update_available_quantity(p2, self.stock_location, 200)

        produce_form = Form(self.env['mrp.product.produce'].with_context({
            'active_id': mo.id,
            'active_ids': [mo.id],
        }))
        produce_form.product_qty = 50.0
        produce_wizard = produce_form.save()
        produce_wizard.do_produce()

        mo.post_inventory()
        update_quantity_wizard = self.env['change.production.qty'].create({
            'mo_id': mo.id,
            'product_qty': 200,
        })
        update_quantity_wizard.change_prod_qty()
        produce_form = Form(self.env['mrp.product.produce'].with_context({
            'active_id': mo.id,
            'active_ids': [mo.id],
        }))
        produce_form.product_qty = 50.0
        produce_wizard = produce_form.save()
        produce_wizard.do_produce()

        self.assertEqual(sum(mo.move_raw_ids.filtered(lambda m: m.product_id == p1).mapped('quantity_done')), 200)
        self.assertEqual(sum(mo.move_raw_ids.filtered(lambda m: m.product_id == p2).mapped('quantity_done')), 200)
        self.assertEqual(sum(mo.move_finished_ids.mapped('quantity_done')), 100)
예제 #20
0
    def test_update_quantity_3(self):
        """ Build 1 final products then update the Manufacturing
        order quantity. Check the remaining quantity to produce
        take care of the first quantity produced."""
        self.stock_location = self.env.ref('stock.stock_location_stock')
        mo, bom, p_final, p1, p2 = self.generate_mo(qty_final=2)
        self.assertEqual(len(mo), 1, 'MO should have been created')

        self.env['stock.quant']._update_available_quantity(p1, self.stock_location, 20)
        self.env['stock.quant']._update_available_quantity(p2, self.stock_location, 5)
        mo.action_assign()

        produce_form = Form(self.env['mrp.product.produce'].with_context({
            'active_id': mo.id,
            'active_ids': [mo.id],
        }))
        produce_form.product_qty = 1
        produce_wizard = produce_form.save()
        produce_wizard.do_produce()

        update_quantity_wizard = self.env['change.production.qty'].create({
            'mo_id': mo.id,
            'product_qty': 3,
        })
        update_quantity_wizard.change_prod_qty()

        produce_form = Form(self.env['mrp.product.produce'].with_context({
            'active_id': mo.id,
            'active_ids': [mo.id],
        }))
        produce_wizard = produce_form.save()
        produce_wizard.do_produce()
        mo.button_mark_done()

        self.assertEqual(sum(mo.move_raw_ids.filtered(lambda m: m.product_id == p1).mapped('quantity_done')), 12)
        self.assertEqual(sum(mo.move_finished_ids.mapped('quantity_done')), 3)
예제 #21
0
    def test_01_manufacturing_step_two(self):
        """ Testing for Step-2 """
        with Form(self.warehouse) as warehouse:
            warehouse.manufacture_steps = 'pbm'
        self.sale_order.action_confirm()
        # Get manufactured procurement
        mo_procurement = self.MrpProduction.search([('origin', '=',
                                                     self.sale_order.name)])
        self.assertEqual(mo_procurement.location_src_id.id,
                         self.warehouse.pbm_loc_id.id,
                         "Source loction does not match.")
        self.assertEqual(mo_procurement.location_dest_id.id,
                         self.warehouse.lot_stock_id.id,
                         "Destination location does not match.")

        self.assertEqual(len(mo_procurement), 1, "No Procurement !")
예제 #22
0
    def test_onchange_product_id(self):

        uom_id = self.product_uom_model.search([('name', '=', 'Unit(s)')])[0]
        pricelist = self.pricelist_model.search([('name', '=',
                                                  'Public Pricelist')])[0]

        partner_id = self.res_partner_model.create(dict(name="George"))
        tax_include_id = self.tax_model.create(
            dict(name="Include tax",
                 amount='21.00',
                 price_include=True,
                 type_tax_use='sale'))
        tax_exclude_id = self.tax_model.create(
            dict(name="Exclude tax", amount='0.00', type_tax_use='sale'))

        product_tmpl_id = self.product_tmpl_model.create(
            dict(name="Voiture",
                 list_price=121,
                 taxes_id=[(6, 0, [tax_include_id.id])]))

        product_id = self.product_model.create(
            dict(product_tmpl_id=product_tmpl_id.id))

        fp_id = self.fiscal_position_model.create(
            dict(name="fiscal position", sequence=1))

        fp_tax_id = self.fiscal_position_tax_model.create(
            dict(position_id=fp_id.id,
                 tax_src_id=tax_include_id.id,
                 tax_dest_id=tax_exclude_id.id))

        # Create the SO with one SO line and apply a pricelist and fiscal position on it
        order_form = Form(
            self.env['sale.order'].with_context(tracking_disable=True))
        order_form.partner_id = partner_id
        order_form.pricelist_id = pricelist
        order_form.fiscal_position_id = fp_id
        with order_form.order_line.new() as line:
            line.name = product_id.name
            line.product_id = product_id
            line.product_uom_qty = 1.0
            line.product_uom = uom_id
        sale_order = order_form.save()

        # Check the unit price of SO line
        self.assertEquals(100, sale_order.order_line[0].price_unit,
                          "The included tax must be subtracted to the price")
예제 #23
0
 def test_00_manufacturing_step_one(self):
     """ Testing for Step-1 """
     # Change steps of manufacturing.
     with Form(self.warehouse) as warehouse:
         warehouse.manufacture_steps = 'mrp_one_step'
     # Confirm sale order.
     self.sale_order.action_confirm()
     # Check all procurements for created sale order
     mo_procurement = self.MrpProduction.search([('origin', '=',
                                                  self.sale_order.name)])
     # Get manufactured procurement
     self.assertEqual(mo_procurement.location_src_id.id,
                      self.warehouse.lot_stock_id.id,
                      "Source loction does not match.")
     self.assertEqual(mo_procurement.location_dest_id.id,
                      self.warehouse.lot_stock_id.id,
                      "Destination location does not match.")
     self.assertEqual(len(mo_procurement), 1, "No Procurement !")
예제 #24
0
    def test_product_produce_1(self):
        """ Check that no produce line are created when the consumed products are not tracked """
        self.stock_location = self.env.ref('stock.stock_location_stock')
        mo, bom, p_final, p1, p2 = self.generate_mo()
        self.assertEqual(len(mo), 1, 'MO should have been created')

        self.env['stock.quant']._update_available_quantity(p1, self.stock_location, 100)
        self.env['stock.quant']._update_available_quantity(p2, self.stock_location, 5)

        mo.action_assign()

        produce_form = Form(self.env['mrp.product.produce'].with_context({
            'active_id': mo.id,
            'active_ids': [mo.id],
        }))
        product_produce = produce_form.save()
        product_produce.do_produce()

        self.assertEqual(len(product_produce.produce_line_ids), 2, 'You should have produce lines even the consumed products are not tracked.')
예제 #25
0
    def test_product_produce_uom(self):
        plastic_laminate = self.env.ref('mrp.product_product_plastic_laminate')
        bom = self.env.ref('mrp.mrp_bom_plastic_laminate')
        dozen = self.env.ref('uom.product_uom_dozen')
        unit = self.env.ref('uom.product_uom_unit')

        plastic_laminate.tracking = 'serial'

        mo = self.env['mrp.production'].create({
            'name': 'Dozen Plastic Laminate',
            'product_id': plastic_laminate.id,
            'product_uom_id': dozen.id,
            'product_qty': 1,
            'bom_id': bom.id,
        })

        final_product_lot = self.env['stock.production.lot'].create({
            'name': 'lot1',
            'product_id': plastic_laminate.id,
        })

        mo.action_assign()
        self.assertEqual(mo.move_raw_ids.product_qty, 12, '12 units should be reserved.')

        # produce product
        produce_form = Form(self.env['mrp.product.produce'].with_context({
            'active_id': mo.id,
            'active_ids': [mo.id],
        }))
        produce_form.lot_id = final_product_lot
        product_produce = produce_form.save()
        self.assertEqual(product_produce.product_qty, 1)
        self.assertEqual(product_produce.product_uom_id, unit, 'Should be 1 unit since the tracking is serial.')
        product_produce.lot_id = final_product_lot.id

        product_produce.do_produce()
        move_line_raw = mo.move_raw_ids.mapped('move_line_ids').filtered(lambda m: m.qty_done)
        self.assertEqual(move_line_raw.qty_done, 1)
        self.assertEqual(move_line_raw.product_uom_id, unit, 'Should be 1 unit since the tracking is serial.')

        move_line_finished = mo.move_finished_ids.mapped('move_line_ids').filtered(lambda m: m.qty_done)
        self.assertEqual(move_line_finished.qty_done, 1)
        self.assertEqual(move_line_finished.product_uom_id, unit, 'Should be 1 unit since the tracking is serial.')
예제 #26
0
    def create_account_invoice(self,
                               invoice_type,
                               partner,
                               product,
                               quantity=0.0,
                               price_unit=0.0):
        """ Create an invoice as in a view by triggering its onchange methods"""

        invoice_form = Form(
            self.env['account.invoice'].with_context(type=invoice_type))
        invoice_form.partner_id = partner
        with invoice_form.invoice_line_ids.new() as line:
            line.product_id = product
            line.quantity = quantity
            line.price_unit = price_unit

        invoice = invoice_form.save()
        invoice.action_invoice_open()
        return invoice
예제 #27
0
    def test_02_different_uom_on_bomlines(self):
        """ Testing bill of material with different unit of measure."""
        route_manufacture = self.warehouse.manufacture_pull_id.route_id.id
        route_mto = self.warehouse.mto_pull_id.route_id.id
        unit = self.ref("uom.product_uom_unit")
        dozen = self.ref("uom.product_uom_dozen")
        kg = self.ref("uom.product_uom_kgm")
        gm = self.ref("uom.product_uom_gram")
        # Create Product A, B, C
        product_A = self.env['product.product'].create({
            'name':
            'Product A',
            'type':
            'product',
            'tracking':
            'lot',
            'uom_id':
            dozen,
            'uom_po_id':
            dozen,
            'route_ids': [(6, 0, [route_manufacture, route_mto])]
        })
        product_B = self.env['product.product'].create({
            'name': 'Product B',
            'type': 'product',
            'tracking': 'lot',
            'uom_id': dozen,
            'uom_po_id': dozen
        })
        product_C = self.env['product.product'].create({
            'name': 'Product C',
            'type': 'product',
            'tracking': 'lot',
            'uom_id': kg,
            'uom_po_id': kg
        })

        # Bill of materials
        # -----------------

        #===================================
        # Product A 1 Unit
        #     Product B 4 Unit
        #     Product C 600 gram
        # -----------------------------------

        bom_a = self.env['mrp.bom'].create({
            'product_tmpl_id':
            product_A.product_tmpl_id.id,
            'product_qty':
            2,
            'product_uom_id':
            unit,
            'bom_line_ids': [(0, 0, {
                'product_id': product_B.id,
                'product_qty': 4,
                'product_uom_id': unit
            }),
                             (0, 0, {
                                 'product_id': product_C.id,
                                 'product_qty': 600,
                                 'product_uom_id': gm
                             })]
        })

        # Create production order with product A 10 Unit.
        # -----------------------------------------------

        mo_custom_product = self.env['mrp.production'].create({
            'product_id':
            product_A.id,
            'product_qty':
            10,
            'product_uom_id':
            unit,
            'bom_id':
            bom_a.id
        })

        move_product_b = mo_custom_product.move_raw_ids.filtered(
            lambda x: x.product_id == product_B)
        move_product_c = mo_custom_product.move_raw_ids.filtered(
            lambda x: x.product_id == product_C)

        # Check move correctly created or not.
        self.assertEqual(move_product_b.product_uom_qty, 20)
        self.assertEqual(move_product_b.product_uom.id, unit)
        self.assertEqual(move_product_c.product_uom_qty, 3000)
        self.assertEqual(move_product_c.product_uom.id, gm)

        # Lot create for product B and product C
        # ---------------------------------------
        lot_a = self.env['stock.production.lot'].create(
            {'product_id': product_A.id})
        lot_b = self.env['stock.production.lot'].create(
            {'product_id': product_B.id})
        lot_c = self.env['stock.production.lot'].create(
            {'product_id': product_C.id})

        # Inventory Update
        # ----------------
        inventory = self.env['stock.inventory'].create({
            'name':
            'Inventory Product B and C',
            'filter':
            'partial',
            'line_ids': [(0, 0, {
                'product_id': product_B.id,
                'product_uom_id': product_B.uom_id.id,
                'product_qty': 3,
                'prod_lot_id': lot_b.id,
                'location_id': self.source_location_id
            }),
                         (0, 0, {
                             'product_id': product_C.id,
                             'product_uom_id': product_C.uom_id.id,
                             'product_qty': 3,
                             'prod_lot_id': lot_c.id,
                             'location_id': self.source_location_id
                         })]
        })
        # inventory.action_start()
        inventory.action_validate()

        # Start Production ...
        # --------------------

        mo_custom_product.action_assign()
        context = {
            "active_ids": [mo_custom_product.id],
            "active_id": mo_custom_product.id
        }
        produce_form = Form(
            self.env['mrp.product.produce'].with_context(context))
        produce_form.product_qty = 10.00
        produce_form.lot_id = lot_a
        product_consume = produce_form.save()
        # laptop_lot_002 = self.env['stock.production.lot'].create({'product_id': custom_laptop.id})
        self.assertEquals(len(product_consume.produce_line_ids), 2)
        product_consume.produce_line_ids.filtered(
            lambda x: x.product_id == product_C).write({'qty_done': 3000})
        product_consume.produce_line_ids.filtered(
            lambda x: x.product_id == product_B).write({'qty_done': 20})
        product_consume.do_produce()
        mo_custom_product.post_inventory()
예제 #28
0
    def test_00_account_voucher_flow(self):
        """ Create Account Voucher for Customer and Vendor """
        self._load('account', 'test', 'account_minimal_test.xml')

        # User-groups and References
        partner_id = self.env.ref('base.res_partner_12')
        cash_journal_id = self.env.ref('account_voucher.cash_journal')
        sales_journal_id = self.env.ref('account_voucher.sales_journal')
        account_receivable_id = self.env.ref('account_voucher.a_recv')

        # Create a Account Voucher User
        voucher_user = self.env['res.users'].create({
            'name': 'Voucher Accountant',
            'login': '******',
            'email': '*****@*****.**',
            'company_id': self.env.ref('base.main_company').id,
            'groups_id': [(6, 0, [
                self.ref('base.group_partner_manager'),
                self.ref('account.group_account_user'),
                self.ref('account.group_account_invoice'),
            ])]
        })
        Voucher = self.env['account.voucher'].sudo(voucher_user)

        # Create Customer Voucher
        c = Form(Voucher.with_context(default_voucher_type="sale", voucher_type="sale"),
                 view='account_voucher.view_sale_receipt_form')
        c.partner_id = partner_id
        c.journal_id = sales_journal_id
        with c.line_ids.new() as line:
            line.name = "Voucher for Axelor"
            line.account_id = account_receivable_id
            line.price_unit = 1000.0
        account_voucher_customer = c.save()

        # Check Customer Voucher status.
        self.assertEquals(account_voucher_customer.state, 'draft', 'Initially customer voucher should be in the "Draft" state')

        # Validate Customer voucher
        account_voucher_customer.proforma_voucher()
        # Check for Journal Entry of customer voucher
        self.assertTrue(account_voucher_customer.move_id, 'No journal entry created !.')
        # Find related account move line for Customer Voucher.
        customer_voucher_move = account_voucher_customer.move_id

        # Check state of Account move line.
        self.assertEquals(customer_voucher_move.state, 'posted', 'Account move state is incorrect.')
        # Check partner of Account move line.
        self.assertEquals(customer_voucher_move.partner_id, partner_id, 'Partner is incorrect on account move.')
        # Check journal in Account move line.
        self.assertEquals(customer_voucher_move.journal_id, sales_journal_id, 'Journal is incorrect on account move.')
        # Check amount in Account move line.
        self.assertEquals(customer_voucher_move.amount, 1000.0, 'Amount is incorrect in account move.')

        # Create Vendor Voucher
        v = Form(Voucher.with_context(default_voucher_type="purchase", voucher_type="purchase"))
        v.partner_id = partner_id
        v.journal_id = cash_journal_id
        with v.line_ids.new() as line:
            line.name = "Voucher Axelor"
            line.account_id = account_receivable_id
            line.price_unit = 1000.0
        account_voucher_vendor = v.save()

        # Check Vendor Voucher status.
        self.assertEquals(account_voucher_vendor.state, 'draft', 'Initially vendor voucher should be in the "Draft" state')

        # Validate Vendor voucher
        account_voucher_vendor.proforma_voucher()
        # Check for Journal Entry of vendor voucher
        self.assertTrue(account_voucher_vendor.move_id, 'No journal entry created !.')
        # Find related account move line for Vendor Voucher.
        vendor_voucher_move = account_voucher_vendor.move_id

        # Check state of Account move line.
        self.assertEquals(vendor_voucher_move.state, 'posted', 'Account move state is incorrect.')
        # Check partner of Account move line.
        self.assertEquals(vendor_voucher_move.partner_id, partner_id, 'Partner is incorrect on account move.')
        # Check journal in Account move line.
        self.assertEquals(vendor_voucher_move.journal_id, cash_journal_id, 'Journal is incorrect on account move.')
        # Check amount in Account move line.
        self.assertEquals(vendor_voucher_move.amount, 1000.0, 'Amount is incorrect in acccount move.')
예제 #29
0
    def test_01_without_workorder(self):
        """ Testing consume quants and produced quants without workorder """
        unit = self.ref("uom.product_uom_unit")
        custom_laptop = self.env.ref("product.product_product_27")
        custom_laptop.tracking = 'lot'

        # Create new product charger and keybord
        # --------------------------------------
        product_charger = self.env['product.product'].create({
            'name': 'Charger',
            'type': 'product',
            'tracking': 'lot',
            'uom_id': unit,
            'uom_po_id': unit
        })
        product_keybord = self.env['product.product'].create({
            'name': 'Usb Keybord',
            'type': 'product',
            'tracking': 'lot',
            'uom_id': unit,
            'uom_po_id': unit
        })

        # Create bill of material for customized laptop.

        bom_custom_laptop = self.env['mrp.bom'].create({
            'product_tmpl_id':
            custom_laptop.product_tmpl_id.id,
            'product_qty':
            10,
            'product_uom_id':
            unit,
            'bom_line_ids': [(0, 0, {
                'product_id': product_charger.id,
                'product_qty': 20,
                'product_uom_id': unit
            }),
                             (0, 0, {
                                 'product_id': product_keybord.id,
                                 'product_qty': 20,
                                 'product_uom_id': unit
                             })]
        })

        # Create production order for customize laptop.

        mo_custom_laptop = self.env['mrp.production'].create({
            'product_id':
            custom_laptop.id,
            'product_qty':
            10,
            'product_uom_id':
            unit,
            'bom_id':
            bom_custom_laptop.id
        })

        # Assign component to production order.
        mo_custom_laptop.action_assign()

        # Check production order status of availablity

        self.assertEqual(mo_custom_laptop.availability, 'waiting')

        # --------------------------------------------------
        # Set inventory for rawmaterial charger and keybord
        # --------------------------------------------------

        lot_charger = self.env['stock.production.lot'].create(
            {'product_id': product_charger.id})
        lot_keybord = self.env['stock.production.lot'].create(
            {'product_id': product_keybord.id})

        # Initialize Inventory
        # --------------------
        inventory = self.env['stock.inventory'].create({
            'name':
            'Inventory Product Table',
            'filter':
            'partial',
            'line_ids': [(0, 0, {
                'product_id': product_charger.id,
                'product_uom_id': product_charger.uom_id.id,
                'product_qty': 20,
                'prod_lot_id': lot_charger.id,
                'location_id': self.source_location_id
            }),
                         (0, 0, {
                             'product_id': product_keybord.id,
                             'product_uom_id': product_keybord.uom_id.id,
                             'product_qty': 20,
                             'prod_lot_id': lot_keybord.id,
                             'location_id': self.source_location_id
                         })]
        })
        # inventory.action_start()
        inventory.action_validate()

        # Check consumed move status
        mo_custom_laptop.action_assign()
        self.assertEqual(mo_custom_laptop.availability, 'assigned')

        # Check current status of raw materials.
        for move in mo_custom_laptop.move_raw_ids:
            self.assertEqual(
                move.product_uom_qty, 20,
                "Wrong consume quantity of raw material %s: %s instead of %s" %
                (move.product_id.name, move.product_uom_qty, 20))
            self.assertEqual(
                move.quantity_done, 0,
                "Wrong produced quantity on raw material %s: %s instead of %s"
                % (move.product_id.name, move.quantity_done, 0))

        # -----------------
        # Start production
        # -----------------

        # Produce 6 Unit of custom laptop will consume ( 12 Unit of keybord and 12 Unit of charger)
        context = {
            "active_ids": [mo_custom_laptop.id],
            "active_id": mo_custom_laptop.id
        }
        product_form = Form(
            self.env['mrp.product.produce'].with_context(context))
        product_form.product_qty = 6.00
        laptop_lot_001 = self.env['stock.production.lot'].create(
            {'product_id': custom_laptop.id})
        product_form.lot_id = laptop_lot_001
        product_consume = product_form.save()
        product_consume.produce_line_ids[0].qty_done = 12
        product_consume.do_produce()

        # Check consumed move after produce 6 quantity of customized laptop.
        for move in mo_custom_laptop.move_raw_ids:
            self.assertEqual(
                move.quantity_done, 12,
                "Wrong produced quantity on raw material %s" %
                (move.product_id.name))
        self.assertEqual(len(mo_custom_laptop.move_raw_ids), 2)
        mo_custom_laptop.post_inventory()
        self.assertEqual(len(mo_custom_laptop.move_raw_ids), 4)

        # Check done move and confirmed move quantity.

        charger_done_move = mo_custom_laptop.move_raw_ids.filtered(
            lambda x: x.product_id.id == product_charger.id and x.state ==
            'done')
        keybord_done_move = mo_custom_laptop.move_raw_ids.filtered(
            lambda x: x.product_id.id == product_keybord.id and x.state ==
            'done')
        self.assertEquals(charger_done_move.product_uom_qty, 12)
        self.assertEquals(keybord_done_move.product_uom_qty, 12)

        # Produce remaining 4 quantity
        # ----------------------------

        # Produce 4 Unit of custom laptop will consume ( 8 Unit of keybord and 8 Unit of charger).
        context = {
            "active_ids": [mo_custom_laptop.id],
            "active_id": mo_custom_laptop.id
        }
        produce_form = Form(
            self.env['mrp.product.produce'].with_context(context))
        produce_form.product_qty = 4.00
        laptop_lot_002 = self.env['stock.production.lot'].create(
            {'product_id': custom_laptop.id})
        produce_form.lot_id = laptop_lot_002
        product_consume = produce_form.save()
        self.assertEquals(len(product_consume.produce_line_ids), 2)
        product_consume.produce_line_ids[0].qty_done = 8
        product_consume.do_produce()
        charger_move = mo_custom_laptop.move_raw_ids.filtered(
            lambda x: x.product_id.id == product_charger.id and x.state !=
            'done')
        keybord_move = mo_custom_laptop.move_raw_ids.filtered(
            lambda x: x.product_id.id == product_keybord.id and x.state !=
            'done')
        self.assertEquals(
            charger_move.quantity_done, 8,
            "Wrong consumed quantity of %s" % charger_move.product_id.name)
        self.assertEquals(
            keybord_move.quantity_done, 8,
            "Wrong consumed quantity of %s" % keybord_move.product_id.name)

        # Post Inventory of production order.
        mo_custom_laptop.post_inventory()
예제 #30
0
    def test_unbuild_with_routes(self):
        """ This test creates a MO of a stockable product (Table). A new route for rule QC/Unbuild -> Stock 
        is created with Warehouse -> True.
        The unbuild order should revert the consumed components into QC/Unbuild location for quality check 
        and then a picking should be generated for transferring components from QC/Unbuild location to stock.
        """
        StockQuant = self.env['stock.quant']
        ProductObj = self.env['product.product']
        # Create new QC/Unbuild location
        warehouse = self.env.ref('stock.warehouse0')
        unbuild_location = self.env['stock.location'].create({
            'name':
            'QC/Unbuild',
            'usage':
            'internal',
            'location_id':
            warehouse.view_location_id.id
        })

        # Create a product route containing a stock rule that will move product from QC/Unbuild location to stock
        product_route = self.env['stock.location.route'].create({
            'name':
            'QC/Unbuild -> Stock',
            'warehouse_selectable':
            True,
            'warehouse_ids': [(4, warehouse.id)],
            'rule_ids': [(0, 0, {
                'name':
                'Send Matrial QC/Unbuild -> Stock',
                'action':
                'push',
                'picking_type_id':
                self.ref('stock.picking_type_internal'),
                'location_src_id':
                unbuild_location.id,
                'location_id':
                self.stock_location.id,
            })],
        })

        # Create a stockable product and its components
        finshed_product = ProductObj.create({
            'name': 'Table',
            'type': 'product',
        })
        component1 = ProductObj.create({
            'name': 'Table head',
            'type': 'product',
        })
        component2 = ProductObj.create({
            'name': 'Table stand',
            'type': 'product',
        })

        # Create bom and add components
        bom = self.env['mrp.bom'].create({
            'product_id':
            finshed_product.id,
            'product_tmpl_id':
            finshed_product.product_tmpl_id.id,
            'product_uom_id':
            self.uom_unit.id,
            'product_qty':
            1.0,
            'type':
            'normal',
            'bom_line_ids': [(0, 0, {
                'product_id': component1.id,
                'product_qty': 1
            }), (0, 0, {
                'product_id': component2.id,
                'product_qty': 1
            })]
        })

        # Set on hand quantity
        StockQuant._update_available_quantity(component1, self.stock_location,
                                              1)
        StockQuant._update_available_quantity(component2, self.stock_location,
                                              1)

        # Create mo
        mo = self.env['mrp.production'].create({
            'name':
            'MO 1',
            'product_id':
            finshed_product.id,
            'product_uom_id':
            finshed_product.uom_id.id,
            'product_qty':
            1.0,
            'bom_id':
            bom.id,
        })
        self.assertEqual(len(mo), 1, 'MO should have been created')
        mo.action_assign()

        # Produce the final product
        produce_form = Form(self.env['mrp.product.produce'].with_context({
            'active_id':
            mo.id,
            'active_ids': [mo.id],
        }))
        produce_form.product_qty = 1.0
        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(
            StockQuant._get_available_quantity(finshed_product,
                                               self.stock_location), 1,
            'Table should be available in stock')
        self.assertEqual(
            StockQuant._get_available_quantity(component1,
                                               self.stock_location), 0,
            'Table head should not be available in stock')
        self.assertEqual(
            StockQuant._get_available_quantity(component2,
                                               self.stock_location), 0,
            'Table stand should not be available in stock')

        # ---------------------------------------------------
        #       Unbuild
        # ---------------------------------------------------

        # Create an unbuild order of the finished product and set the destination loacation = QC/Unbuild
        self.env['mrp.unbuild'].create({
            'product_id': finshed_product.id,
            'bom_id': bom.id,
            'product_qty': 1.0,
            'product_uom_id': self.uom_unit.id,
            'mo_id': mo.id,
            'location_id': self.stock_location.id,
            'location_dest_id': unbuild_location.id
        }).action_unbuild()

        # Check the available quantity of components and final product in stock
        self.assertEqual(
            StockQuant._get_available_quantity(finshed_product,
                                               self.stock_location), 0,
            'Table should not be available in stock as it is unbuild')
        self.assertEqual(
            StockQuant._get_available_quantity(component1,
                                               self.stock_location), 0,
            'Table head should not be available in stock as it is in QC/Unbuild location'
        )
        self.assertEqual(
            StockQuant._get_available_quantity(component2,
                                               self.stock_location), 0,
            'Table stand should not be available in stock as it is in QC/Unbuild location'
        )

        # Find new generated picking
        picking = self.env['stock.picking'].search([
            ('product_id', 'in', [component1.id, component2.id])
        ])
        self.assertEqual(picking.location_id.id, unbuild_location.id,
                         'Wrong source location in picking')
        self.assertEqual(picking.location_dest_id.id, self.stock_location.id,
                         'Wrong destination location in picking')

        # Transfer it
        for ml in picking.move_ids_without_package:
            ml.quantity_done = 1
        picking.action_done()

        # Check the available quantity of components and final product in stock
        self.assertEqual(
            StockQuant._get_available_quantity(finshed_product,
                                               self.stock_location), 0,
            'Table should not be available in stock')
        self.assertEqual(
            StockQuant._get_available_quantity(component1,
                                               self.stock_location), 1,
            'Table head should be available in stock as the picking is transferred'
        )
        self.assertEqual(
            StockQuant._get_available_quantity(component2,
                                               self.stock_location), 1,
            'Table stand should be available in stock as the picking is transferred'
        )