コード例 #1
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.'
        )
コード例 #2
0
    def test_toggle_active_warehouse_2(self):
        wh = Form(self.env['stock.warehouse'])
        wh.name = "The attic of Willy"
        wh.code = "WIL"
        wh.reception_steps = "two_steps"
        wh.delivery_steps = "pick_pack_ship"
        warehouse = wh.save()

        warehouse.resupply_wh_ids = [(6, 0, [self.warehouse_1.id])]

        custom_location = Form(self.env['stock.location'])
        custom_location.name = "A Trunk"
        custom_location.location_id = warehouse.lot_stock_id
        custom_location = custom_location.save()

        # Add a warehouse on the route.
        warehouse.reception_route_id.write(
            {'warehouse_ids': [(4, self.warehouse_1.id)]})

        route = Form(self.env['stock.location.route'])
        route.name = "Stair"
        route = route.save()

        route.warehouse_ids = [(6, 0, [warehouse.id, self.warehouse_1.id])]

        # Pre archive a location and a route
        warehouse.delivery_route_id.toggle_active()
        warehouse.wh_pack_stock_loc_id.toggle_active()

        # Archive warehouse
        warehouse.toggle_active()
        # Global rule
        self.assertFalse(warehouse.mto_pull_id.active)

        # Route
        self.assertTrue(warehouse.reception_route_id.active)
        self.assertFalse(warehouse.delivery_route_id.active)
        self.assertTrue(route.active)

        # Location
        self.assertFalse(warehouse.lot_stock_id.active)
        self.assertFalse(warehouse.wh_input_stock_loc_id.active)
        self.assertFalse(warehouse.wh_qc_stock_loc_id.active)
        self.assertFalse(warehouse.wh_output_stock_loc_id.active)
        self.assertFalse(warehouse.wh_pack_stock_loc_id.active)
        self.assertFalse(custom_location.active)

        # Picking Type
        self.assertFalse(warehouse.in_type_id.active)
        self.assertFalse(warehouse.out_type_id.active)
        self.assertFalse(warehouse.int_type_id.active)
        self.assertFalse(warehouse.pick_type_id.active)
        self.assertFalse(warehouse.pack_type_id.active)

        # Active warehouse
        warehouse.toggle_active()
        # Global rule
        self.assertTrue(warehouse.mto_pull_id.active)

        # Route
        self.assertTrue(warehouse.reception_route_id.active)
        self.assertTrue(warehouse.delivery_route_id.active)

        # Location
        self.assertTrue(warehouse.lot_stock_id.active)
        self.assertTrue(warehouse.wh_input_stock_loc_id.active)
        self.assertFalse(warehouse.wh_qc_stock_loc_id.active)
        self.assertTrue(warehouse.wh_output_stock_loc_id.active)
        self.assertTrue(warehouse.wh_pack_stock_loc_id.active)
        self.assertTrue(custom_location.active)

        # Picking Type
        self.assertTrue(warehouse.in_type_id.active)
        self.assertTrue(warehouse.out_type_id.active)
        self.assertTrue(warehouse.int_type_id.active)
        self.assertTrue(warehouse.pick_type_id.active)
        self.assertTrue(warehouse.pack_type_id.active)
コード例 #3
0
    def test_flow_4(self):
        """ Tick "Manufacture" and "MTO" on the components and trigger the
        creation of the subcontracting manufacturing order through a receipt
        picking. Checks that the delivery to the subcontractor is not created
        at the receipt creation. Then run the scheduler and check that
        the delivery and MO exist.
        """
        # Tick "manufacture" and MTO on self.comp2
        mto_route = self.env['stock.location.route'].search([
            ('name', '=', 'Replenish on Order (MTO)')
        ])
        manufacture_route = self.env['stock.location.route'].search([
            ('name', '=', 'Manufacture')
        ])
        self.comp2.write({'route_ids': [(4, manufacture_route.id, None)]})
        self.comp2.write({'route_ids': [(4, mto_route.id, None)]})

        orderpoint_form = Form(self.env['stock.warehouse.orderpoint'])
        orderpoint_form.product_id = self.comp2
        orderpoint_form.product_min_qty = 0.0
        orderpoint_form.product_max_qty = 10.0
        orderpoint_form.location_id = self.env.company.subcontracting_location_id
        orderpoint_form.save()

        # Create a receipt picking from the subcontractor
        picking_form = Form(self.env['stock.picking'])
        picking_form.picking_type_id = self.env.ref('stock.picking_type_in')
        picking_form.partner_id = self.subcontractor_partner1
        with picking_form.move_ids_without_package.new() as move:
            move.product_id = self.finished
            move.product_uom_qty = 1
        picking_receipt = picking_form.save()
        picking_receipt.action_confirm()

        warehouse = picking_receipt.picking_type_id.warehouse_id

        # Pickings should directly be created
        mo = self.env['mrp.production'].search([('bom_id', '=', self.bom.id)])
        self.assertEquals(mo.state, 'confirmed')

        picking_delivery = mo.picking_ids
        self.assertFalse(picking_delivery)

        picking_delivery = self.env['stock.picking'].search([
            ('origin', 'ilike', '%' + picking_receipt.name + '%')
        ])
        self.assertFalse(picking_delivery)

        move = self.env['stock.move'].search([
            ('product_id', '=', self.comp2.id),
            ('location_id', '=', warehouse.lot_stock_id.id),
            ('location_dest_id', '=',
             self.env.company.subcontracting_location_id.id)
        ])
        self.assertFalse(move)

        self.env['procurement.group'].run_scheduler(
            company_id=self.env.company.id)

        move = self.env['stock.move'].search([
            ('product_id', '=', self.comp2.id),
            ('location_id', '=', warehouse.lot_stock_id.id),
            ('location_dest_id', '=',
             self.env.company.subcontracting_location_id.id)
        ])
        self.assertTrue(move)
        picking_delivery = move.picking_id
        self.assertTrue(picking_delivery)
        self.assertEqual(move.product_uom_qty, 11.0)

        # As well as a manufacturing order for `self.comp2`
        comp2mo = self.env['mrp.production'].search([('bom_id', '=',
                                                      self.comp2_bom.id)])
        self.assertEqual(len(comp2mo), 1)
コード例 #4
0
    def test_toggle_active_warehouse_1(self):
        """ Basic test that create a warehouse with classic configuration.
        Archive it and check that locations, picking types, routes, rules are
        correclty active or archive.
        """
        wh = Form(self.env['stock.warehouse'])
        wh.name = "The attic of Willy"
        wh.code = "WIL"
        warehouse = wh.save()

        custom_location = Form(self.env['stock.location'])
        custom_location.name = "A Trunk"
        custom_location.location_id = warehouse.lot_stock_id
        custom_location = custom_location.save()

        # Archive warehouse
        warehouse.toggle_active()
        # Global rule
        self.assertFalse(warehouse.mto_pull_id.active)

        # Route
        self.assertFalse(warehouse.reception_route_id.active)
        self.assertFalse(warehouse.delivery_route_id.active)

        # Location
        self.assertFalse(warehouse.lot_stock_id.active)
        self.assertFalse(warehouse.wh_input_stock_loc_id.active)
        self.assertFalse(warehouse.wh_qc_stock_loc_id.active)
        self.assertFalse(warehouse.wh_output_stock_loc_id.active)
        self.assertFalse(warehouse.wh_pack_stock_loc_id.active)
        self.assertFalse(custom_location.active)

        # Picking Type
        self.assertFalse(warehouse.in_type_id.active)
        self.assertFalse(warehouse.out_type_id.active)
        self.assertFalse(warehouse.int_type_id.active)
        self.assertFalse(warehouse.pick_type_id.active)
        self.assertFalse(warehouse.pack_type_id.active)

        # Active warehouse
        warehouse.toggle_active()
        # Global rule
        self.assertTrue(warehouse.mto_pull_id.active)

        # Route
        self.assertTrue(warehouse.reception_route_id.active)
        self.assertTrue(warehouse.delivery_route_id.active)

        # Location
        self.assertTrue(warehouse.lot_stock_id.active)
        self.assertFalse(warehouse.wh_input_stock_loc_id.active)
        self.assertFalse(warehouse.wh_qc_stock_loc_id.active)
        self.assertFalse(warehouse.wh_output_stock_loc_id.active)
        self.assertFalse(warehouse.wh_pack_stock_loc_id.active)
        self.assertTrue(custom_location.active)

        # Picking Type
        self.assertTrue(warehouse.in_type_id.active)
        self.assertTrue(warehouse.out_type_id.active)
        self.assertTrue(warehouse.int_type_id.active)
        self.assertFalse(warehouse.pick_type_id.active)
        self.assertFalse(warehouse.pack_type_id.active)
コード例 #5
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_form = Form(self.env['mrp.production'])
        mo_form.product_id = finshed_product
        mo_form.bom_id = bom
        mo_form.product_uom_id = finshed_product.uom_id
        mo_form.product_qty = 1.0
        mo = mo_form.save()
        self.assertEqual(len(mo), 1, 'MO should have been created')
        mo.action_confirm()
        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.qty_producing = 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
        x = Form(self.env['mrp.unbuild'])
        x.product_id = finshed_product
        x.bom_id = bom
        x.product_uom_id = self.uom_unit
        x.mo_id = mo
        x.product_qty = 1
        x.location_id = self.stock_location
        x.location_dest_id = unbuild_location
        x.save().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'
        )