Exemplo n.º 1
0
    def test_flow_8(self):
        resupply_sub_on_order_route = self.env['stock.location.route'].search([('name', '=', 'Resupply Subcontractor on Order')])
        (self.comp1 + self.comp2).write({'route_ids': [(4, resupply_sub_on_order_route.id, None)]})

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

        picking_receipt.move_lines.quantity_done = 3
        backorder_wiz = picking_receipt.button_validate()
        backorder_wiz = Form(self.env[backorder_wiz['res_model']].with_context(backorder_wiz['context'])).save()
        backorder_wiz.process()

        backorder = self.env['stock.picking'].search([('backorder_id', '=', picking_receipt.id)])
        self.assertTrue(backorder)
        self.assertEqual(backorder.move_lines.product_uom_qty, 2)
        mo_done = backorder.move_lines.move_orig_ids.production_id.filtered(lambda p: p.state == 'done')
        backorder_mo = backorder.move_lines.move_orig_ids.production_id.filtered(lambda p: p.state != 'done')
        self.assertTrue(mo_done)
        self.assertEqual(mo_done.qty_produced, 3)
        self.assertEqual(mo_done.product_uom_qty, 3)
        self.assertTrue(backorder_mo)
        self.assertEqual(backorder_mo.product_uom_qty, 2)
        self.assertEqual(backorder_mo.qty_produced, 0)
        backorder.move_lines.quantity_done = 2
        backorder._action_done()
        self.assertTrue(picking_receipt.move_lines.move_orig_ids.production_id.state == 'done')
Exemplo n.º 2
0
    def test_unbuild_account_01(self):
        """Test when production location has its valuation accounts. After unbuild,
        the journal entries are the reversal of the journal entries created when
        produce the product.
        """
        # set accounts for production location
        production_location = self.product_A.property_stock_production
        wip_incoming_account = self.env['account.account'].create({
            'name': 'wip incoming',
            'code': '000001',
            'user_type_id': self.env.ref('account.data_account_type_current_assets').id,
        })
        wip_outgoing_account = self.env['account.account'].create({
            'name': 'wip outgoing',
            'code': '000002',
            'user_type_id': self.env.ref('account.data_account_type_current_assets').id,
        })
        production_location.write({
            'valuation_in_account_id': wip_incoming_account.id,
            'valuation_out_account_id': wip_outgoing_account.id,
        })

        # build
        production_form = Form(self.env['mrp.production'])
        production_form.product_id = self.product_A
        production_form.bom_id = self.bom
        production_form.product_qty = 1
        production = production_form.save()
        production.action_confirm()
        mo_form = Form(production)
        mo_form.qty_producing = 1
        production = mo_form.save()
        production._post_inventory()
        production.button_mark_done()

        # finished product move
        productA_debit_line = self.env['account.move.line'].search([('ref', 'ilike', 'MO%Product A'), ('credit', '=', 0)])
        productA_credit_line = self.env['account.move.line'].search([('ref', 'ilike', 'MO%Product A'), ('debit', '=', 0)])
        self.assertEqual(productA_debit_line.account_id, self.stock_valuation_account)
        self.assertEqual(productA_credit_line.account_id, wip_outgoing_account)
        # component move
        productB_debit_line = self.env['account.move.line'].search([('ref', 'ilike', 'MO%Product B'), ('credit', '=', 0)])
        productB_credit_line = self.env['account.move.line'].search([('ref', 'ilike', 'MO%Product B'), ('debit', '=', 0)])
        self.assertEqual(productB_debit_line.account_id, wip_incoming_account)
        self.assertEqual(productB_credit_line.account_id, self.stock_valuation_account)

        # unbuild
        res_dict = production.button_unbuild()
        wizard = Form(self.env[res_dict['res_model']].with_context(res_dict['context'])).save()
        wizard.action_validate()

        productA_debit_line = self.env['account.move.line'].search([('ref', 'ilike', 'UB%Product A'), ('credit', '=', 0)])
        productA_credit_line = self.env['account.move.line'].search([('ref', 'ilike', 'UB%Product A'), ('debit', '=', 0)])
        self.assertEqual(productA_debit_line.account_id, wip_outgoing_account)
        self.assertEqual(productA_credit_line.account_id, self.stock_valuation_account)
        # component move
        productB_debit_line = self.env['account.move.line'].search([('ref', 'ilike', 'UB%Product B'), ('credit', '=', 0)])
        productB_credit_line = self.env['account.move.line'].search([('ref', 'ilike', 'UB%Product B'), ('debit', '=', 0)])
        self.assertEqual(productB_debit_line.account_id, self.stock_valuation_account)
        self.assertEqual(productB_credit_line.account_id, wip_incoming_account)
Exemplo n.º 3
0
    def test_picking_state_with_null_qty(self):
        receipt_form = Form(self.env['stock.picking'].with_context(
            default_immediate_transfer=False))
        picking_type_id = self.warehouse.out_type_id
        receipt_form.picking_type_id = picking_type_id
        with receipt_form.move_ids_without_package.new() as move_line:
            move_line.product_id = self.productA
            move_line.product_uom_qty = 10
        with receipt_form.move_ids_without_package.new() as move_line:
            move_line.product_id = self.productB
            move_line.product_uom_qty = 10
        receipt = receipt_form.save()
        receipt.action_confirm()
        self.assertEqual(receipt.state, 'confirmed')
        receipt.move_ids_without_package[1].product_uom_qty = 0
        self.assertEqual(receipt.state, 'confirmed')

        receipt_form = Form(self.env['stock.picking'].with_context(
            default_immediate_transfer=True))
        picking_type_id = self.warehouse.out_type_id
        receipt_form.picking_type_id = picking_type_id
        with receipt_form.move_ids_without_package.new() as move_line:
            move_line.product_id = self.productA
            move_line.quantity_done = 10
        with receipt_form.move_ids_without_package.new() as move_line:
            move_line.product_id = self.productB
            move_line.quantity_done = 10
        receipt = receipt_form.save()
        receipt.action_confirm()
        self.assertEqual(receipt.state, 'assigned')
        receipt.move_ids_without_package[1].product_uom_qty = 0
        self.assertEqual(receipt.state, 'assigned')
Exemplo n.º 4
0
    def test_read_purchase_order(self):
        """ Check that a purchase user can read all purchase order and 'in' invoices"""
        purchase_user_2 = self.purchase_user.copy({
            'name': 'Purchase user 2',
            'login': '******',
            'email': '*****@*****.**',
        })

        purchase_order_form = Form(
            self.env['purchase.order'].with_user(purchase_user_2))
        purchase_order_form.partner_id = self.vendor
        with purchase_order_form.order_line.new() as line:
            line.name = self.product.name
            line.product_id = self.product
            line.product_qty = 4
            line.price_unit = 5

        purchase_order_user2 = purchase_order_form.save()
        purchase_order_user2.button_confirm()

        purchase_order_user2.order_line.qty_received = 4
        purchase_order_user2.action_create_invoice()
        vendor_bill_user2 = purchase_order_user2.invoice_ids

        # open purchase_order_user2 and vendor_bill_user2 with `self.purchase_user`
        purchase_order_user1 = Form(
            purchase_order_user2.with_user(self.purchase_user))
        purchase_order_user1 = purchase_order_user1.save()
        vendor_bill_user1 = Form(
            vendor_bill_user2.with_user(self.purchase_user))
        vendor_bill_user1 = vendor_bill_user1.save()
Exemplo n.º 5
0
    def test_manufacturing_3_steps_flexible(self):
        """ Test MO/picking before manufacturing/picking after manufacturing
        components and move_orig/move_dest. Ensure that additional moves are put
        in picking before manufacturing too.
        """
        with Form(self.warehouse) as warehouse:
            warehouse.manufacture_steps = 'pbm_sam'
        bom = self.env['mrp.bom'].search([('product_id', '=',
                                           self.finished_product.id)])
        new_product = self.env['product.product'].create({
            'name': 'New product',
            'type': 'product',
        })
        bom.consumption = 'flexible'
        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()

        production.action_confirm()

        production_form = Form(production)
        with production_form.move_raw_ids.new() as move:
            move.product_id = new_product
            move.product_uom_qty = 2
        production = production_form.save()
        move_raw_ids = production.move_raw_ids
        self.assertEqual(len(move_raw_ids), 2)
        pbm_move = move_raw_ids.move_orig_ids
        self.assertEqual(len(pbm_move), 2)
        self.assertTrue(new_product in pbm_move.product_id)
Exemplo n.º 6
0
 def test_remove_package(self):
     """
     In the overshipping scenario, if I remove the package after adding it, we should not remove the associated 
     stock move.
     """
     self.warehouse.delivery_steps = 'ship_only'
     package = self.env["stock.quant.package"].create({"name": "Src Pack"})
     self.env['stock.quant']._update_available_quantity(self.productA,
                                                        self.stock_location,
                                                        100,
                                                        package_id=package)
     self.warehouse.out_type_id.show_entire_packs = True
     picking = self.env['stock.picking'].create({
         'location_id':
         self.stock_location.id,
         'location_dest_id':
         self.customer_location.id,
         'picking_type_id':
         self.warehouse.out_type_id.id,
     })
     with Form(picking) as picking_form:
         with picking_form.move_ids_without_package.new() as move:
             move.product_id = self.productA
             move.product_uom_qty = 75
     picking.action_assign()
     with Form(picking) as picking_form:
         with picking_form.package_level_ids_details.new() as package_level:
             package_level.package_id = package
     with Form(picking) as picking_form:
         picking_form.package_level_ids.remove(0)
     self.assertEqual(len(picking.move_lines), 1,
                      'Should have only 1 stock move')
Exemplo n.º 7
0
    def test_07_differed_schedule_date(self):
        warehouse = self.env['stock.warehouse'].search([], limit=1)

        with Form(warehouse) as w:
            w.reception_steps = 'three_steps'
        po_form = Form(self.env['purchase.order'])
        po_form.partner_id = self.partner_id
        with po_form.order_line.new() as line:
            line.product_id = self.product_id_1
            line.date_planned = datetime.today()
            line.product_qty = 1.0
        with po_form.order_line.new() as line:
            line.product_id = self.product_id_1
            line.date_planned = datetime.today() + timedelta(days=7)
            line.product_qty = 1.0
        po = po_form.save()

        po.button_approve()

        po.picking_ids.move_line_ids.write({'qty_done': 1.0})
        po.picking_ids.button_validate()

        pickings = self.env['stock.picking'].search([('group_id', '=',
                                                      po.group_id.id)])
        for picking in pickings:
            self.assertEqual(picking.scheduled_date.date(), date.today())
Exemplo n.º 8
0
    def test_tracking_backorder_immediate_production_serial_1(self):
        """ Create a MO to build 2 of a SN tracked product.
        Build both the starting MO and its backorder as immediate productions
        (i.e. Mark As Done without setting SN/filling any quantities)
        """
        mo, _, p_final, p1, p2 = self.generate_mo(qty_final=2, tracking_final='serial', qty_base_1=2, qty_base_2=2)
        self.env['stock.quant']._update_available_quantity(p1, self.stock_location_components, 2.0)
        self.env['stock.quant']._update_available_quantity(p2, self.stock_location_components, 2.0)
        mo.action_assign()
        res_dict = mo.button_mark_done()
        self.assertEqual(res_dict.get('res_model'), 'mrp.immediate.production')
        immediate_wizard = Form(self.env[res_dict['res_model']].with_context(res_dict['context'])).save()
        res_dict = immediate_wizard.process()
        self.assertEqual(res_dict.get('res_model'), 'mrp.production.backorder')
        backorder_wizard = Form(self.env[res_dict['res_model']].with_context(res_dict['context']))

        # backorder should automatically open
        action = backorder_wizard.save().action_backorder()
        self.assertEqual(action.get('res_model'), 'mrp.production')
        backorder_mo_form = Form(self.env[action['res_model']].with_context(action['context']).browse(action['res_id']))
        backorder_mo = backorder_mo_form.save()
        res_dict = backorder_mo.button_mark_done()
        self.assertEqual(res_dict.get('res_model'), 'mrp.immediate.production')
        immediate_wizard = Form(self.env[res_dict['res_model']].with_context(res_dict['context'])).save()
        immediate_wizard.process()

        self.assertEqual(self.env['stock.quant']._get_available_quantity(p_final, self.stock_location), 2, "Incorrect number of final product produced.")
        self.assertEqual(len(self.env['stock.production.lot'].search([('product_id', '=', p_final.id)])), 2, "Serial Numbers were not correctly produced.")
Exemplo n.º 9
0
    def test_unbuild_decimal_qty(self):
        """
        Use case:
        - decimal accuracy of Product UoM > decimal accuracy of Units
        - unbuild a product with a decimal quantity of component
        """
        self.env['decimal.precision'].search([
            ('name', '=', 'Product Unit of Measure')
        ]).digits = 4
        self.uom_unit.rounding = 0.001

        self.bom_1.product_qty = 3
        self.bom_1.bom_line_ids.product_qty = 5
        self.env['stock.quant']._update_available_quantity(
            self.product_2, self.stock_location, 3)

        mo_form = Form(self.env['mrp.production'])
        mo_form.product_id = self.bom_1.product_id
        mo_form.bom_id = self.bom_1
        mo = mo_form.save()
        mo.action_confirm()
        mo.action_assign()

        mo_form = Form(mo)
        mo_form.qty_producing = 3
        mo_form.save()
        mo.button_mark_done()

        uo_form = Form(self.env['mrp.unbuild'])
        uo_form.mo_id = mo
        # Unbuilding one product means a decimal quantity equal to 1 / 3 * 5 for each component
        uo_form.product_qty = 1
        uo = uo_form.save()
        uo.action_unbuild()
        self.assertEqual(uo.state, 'done')
Exemplo n.º 10
0
    def test_flow_5(self):
        """ Check that the correct BoM is chosen accordingly to the partner
        """
        # We create a second partner of type subcontractor
        main_partner_2 = self.env['res.partner'].create({'name': 'main_partner'})
        subcontractor_partner2 = self.env['res.partner'].create({
            'name': 'subcontractor_partner',
            'parent_id': main_partner_2.id,
            'company_id': self.env.ref('base.main_company').id
        })

        # We create a different BoM for the same product
        comp3 = self.env['product.product'].create({
            'name': 'Component1',
            'type': 'product',
            'categ_id': self.env.ref('product.product_category_all').id,
        })

        bom_form = Form(self.env['mrp.bom'])
        bom_form.type = 'subcontract'
        bom_form.product_tmpl_id = self.finished.product_tmpl_id
        with bom_form.bom_line_ids.new() as bom_line:
            bom_line.product_id = self.comp1
            bom_line.product_qty = 1
        with bom_form.bom_line_ids.new() as bom_line:
            bom_line.product_id = comp3
            bom_line.product_qty = 1
        bom2 = bom_form.save()

        # We assign the second BoM to the new partner
        self.bom.write({'subcontractor_ids': [(4, self.subcontractor_partner1.id, None)]})
        bom2.write({'subcontractor_ids': [(4, subcontractor_partner2.id, None)]})

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

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

        mo_pick1 = picking_receipt1.move_lines.mapped('move_orig_ids.production_id')
        mo_pick2 = picking_receipt2.move_lines.mapped('move_orig_ids.production_id')
        self.assertEqual(len(mo_pick1), 1)
        self.assertEqual(len(mo_pick2), 1)
        self.assertEqual(mo_pick1.bom_id, self.bom)
        self.assertEqual(mo_pick2.bom_id, bom2)
Exemplo n.º 11
0
 def produce_one(mo):
     mo_form = Form(mo)
     mo_form.qty_producing = 1
     mo = mo_form.save()
     action = mo.button_mark_done()
     backorder = Form(self.env['mrp.production.backorder'].with_context(**action['context']))
     backorder.save().action_backorder()
     return mo.procurement_group_id.mrp_production_ids[-1]
    def test_stock_valuation_layer_revaluation_fifo(self):
        self.product1.categ_id.property_cost_method = 'fifo'
        context = {
            'default_product_id': self.product1.id,
            'default_company_id': self.env.company.id,
            'default_added_value': 0.0
        }
        # Quantity of product1 is zero, raise
        with self.assertRaises(UserError):
            Form(self.env['stock.valuation.layer.revaluation'].with_context(
                context)).save()

        self._make_in_move(self.product1, 10, unit_cost=2)
        self._make_in_move(self.product1, 10, unit_cost=4)

        self.assertEqual(self.product1.standard_price, 2)
        self.assertEqual(self.product1.quantity_svl, 20)

        old_layers = self.env['stock.valuation.layer'].search(
            [('product_id', '=', self.product1.id)],
            order="create_date desc, id desc")

        self.assertEqual(len(old_layers), 2)
        self.assertEqual(old_layers[0].remaining_value, 40)

        revaluation_wizard = Form(
            self.env['stock.valuation.layer.revaluation'].with_context(
                context))
        revaluation_wizard.added_value = 20
        revaluation_wizard.account_id = self.stock_valuation_account
        revaluation_wizard.save().action_validate_revaluation()

        self.assertEqual(self.product1.standard_price, 2)

        # Check the creation of stock.valuation.layer
        new_layer = self.env['stock.valuation.layer'].search(
            [('product_id', '=', self.product1.id)],
            order="create_date desc, id desc",
            limit=1)
        self.assertEqual(new_layer.value, 20)

        # Check the remaing value of current layers
        self.assertEqual(old_layers[0].remaining_value, 50)
        self.assertEqual(sum(slv.remaining_value for slv in old_layers), 80)

        # Check account move
        self.assertTrue(bool(new_layer.account_move_id))
        self.assertTrue(len(new_layer.account_move_id.line_ids), 2)

        self.assertEqual(
            sum(new_layer.account_move_id.line_ids.mapped("debit")), 20)
        self.assertEqual(
            sum(new_layer.account_move_id.line_ids.mapped("credit")), 20)

        credit_lines = [
            l for l in new_layer.account_move_id.line_ids if l.credit > 0
        ]
        self.assertEqual(len(credit_lines), 1)
Exemplo n.º 13
0
    def test_entire_pack_overship(self):
        """
        Test the scenario of overshipping: we send the customer an entire package, even though it might be more than
        what they initially ordered, and update the quantity on the sales order to reflect what was actually sent.
        """
        self.warehouse.delivery_steps = 'ship_only'
        package = self.env["stock.quant.package"].create({"name": "Src Pack"})
        self.env['stock.quant']._update_available_quantity(self.productA,
                                                           self.stock_location,
                                                           100,
                                                           package_id=package)
        self.warehouse.out_type_id.show_entire_packs = True
        picking = self.env['stock.picking'].create({
            'location_id':
            self.stock_location.id,
            'location_dest_id':
            self.customer_location.id,
            'picking_type_id':
            self.warehouse.out_type_id.id,
        })
        with Form(picking) as picking_form:
            with picking_form.move_ids_without_package.new() as move:
                move.product_id = self.productA
                move.product_uom_qty = 75
        picking.action_confirm()
        picking.action_assign()
        with Form(picking) as picking_form:
            with picking_form.package_level_ids_details.new() as package_level:
                package_level.package_id = package
        self.assertEqual(len(picking.move_lines), 1,
                         'Should have only 1 stock move')
        self.assertEqual(len(picking.move_lines), 1,
                         'Should have only 1 stock move')
        with Form(picking) as picking_form:
            with picking_form.package_level_ids_details.edit(
                    0) as package_level:
                package_level.is_done = True
        action = picking.button_validate()

        self.assertEqual(action, True, 'Should not open wizard')

        for ml in picking.move_line_ids:
            self.assertEqual(ml.package_id, package, 'move_line.package')
            self.assertEqual(ml.result_package_id, package,
                             'move_line.result_package')
            self.assertEqual(ml.state, 'done', 'move_line.state')
        quant = package.quant_ids.filtered(
            lambda q: q.location_id == self.customer_location)
        self.assertEqual(len(quant), 1,
                         'Should have quant at customer location')
        self.assertEqual(quant.reserved_quantity, 0,
                         'quant.reserved_quantity should = 0')
        self.assertEqual(quant.quantity, 100.0, 'quant.quantity should = 100')
        self.assertEqual(sum(ml.qty_done for ml in picking.move_line_ids),
                         100.0, 'total move_line.qty_done should = 100')
        backorders = self.env['stock.picking'].search([('backorder_id', '=',
                                                        picking.id)])
        self.assertEqual(len(backorders), 0, 'Should not create a backorder')
Exemplo n.º 14
0
    def test_batch_with_immediate_transfer_and_backorder_wizard_with_manual_operations(
            self):
        """ Test a simple batch picking with only one quantity fully available.
        The user set the quantity done only for the partially available picking.
        The test should run the immediate transfer for the first picking and then
        the backorder wizard for the second picking.
        """
        self.env['stock.quant']._update_available_quantity(
            self.productA, self.stock_location, 5.0)
        self.env['stock.quant']._update_available_quantity(
            self.productB, self.stock_location, 10.0)

        # Confirm batch, pickings should not be automatically assigned.
        self.batch.action_confirm()
        self.assertEqual(self.picking_client_1.state, 'confirmed',
                         'Picking 1 should be confirmed')
        self.assertEqual(self.picking_client_2.state, 'confirmed',
                         'Picking 2 should be confirmed')
        # Ask to assign, so pickings should be assigned now.
        self.batch.action_assign()
        self.assertEqual(self.picking_client_1.state, 'assigned',
                         'Picking 1 should be ready')
        self.assertEqual(self.picking_client_2.state, 'assigned',
                         'Picking 2 should be ready')

        self.picking_client_1.move_lines.quantity_done = 5
        # There should be a wizard asking to process picking without quantity done
        immediate_transfer_wizard_dict = self.batch.action_done()
        self.assertTrue(immediate_transfer_wizard_dict)
        immediate_transfer_wizard = Form(self.env[(
            immediate_transfer_wizard_dict.get('res_model'))].with_context(
                immediate_transfer_wizard_dict['context'])).save()
        self.assertEqual(len(immediate_transfer_wizard.pick_ids), 1)
        back_order_wizard_dict = immediate_transfer_wizard.process()
        self.assertTrue(back_order_wizard_dict)
        back_order_wizard = Form(
            self.env[(back_order_wizard_dict.get('res_model'))].with_context(
                back_order_wizard_dict['context'])).save()
        self.assertEqual(len(back_order_wizard.pick_ids), 1)
        back_order_wizard.process()

        self.assertEqual(self.picking_client_1.state, 'done',
                         'Picking 1 should be done')
        self.assertEqual(self.picking_client_1.move_lines.product_uom_qty, 5,
                         'initial demand should be 5 after picking split')
        self.assertTrue(
            self.env['stock.picking'].search([
                ('backorder_id', '=', self.picking_client_1.id)
            ]), 'no back order created')

        quant_A = self.env['stock.quant']._gather(self.productA,
                                                  self.stock_location)
        quant_B = self.env['stock.quant']._gather(self.productB,
                                                  self.stock_location)

        # ensure that quantity for picking has been moved
        self.assertFalse(sum(quant_A.mapped('quantity')))
        self.assertFalse(sum(quant_B.mapped('quantity')))
Exemplo n.º 15
0
    def test_stock_landed_costs_rounding_02(self):
        """ The landed costs should be correctly computed, even when the decimal accuracy
        of the deciaml price is increased. """
        self.env.ref("product.decimal_price").digits = 4

        fifo_pc = self.env['product.category'].create({
            'name':
            'Fifo Category',
            'parent_id':
            self.env.ref("product.product_category_all").id,
            'property_valuation':
            'real_time',
            'property_cost_method':
            'fifo',
        })

        products = self.Product.create([{
            'name': 'Super Product %s' % price,
            'categ_id': fifo_pc.id,
            'type': 'product',
            'standard_price': price,
        } for price in [0.91, 0.93, 75.17, 20.54]])

        landed_product = self.Product.create({
            'name': 'Landed Costs',
            'type': 'service',
            'landed_cost_ok': True,
            'split_method_landed_cost': 'by_quantity',
            'standard_price': 1000.0,
        })

        po = self.env['purchase.order'].create({
            'partner_id':
            self.partner_a.id,
            'order_line': [(0, 0, {
                'product_id': product.id,
                'product_qty': qty,
                'price_unit': product.standard_price,
            }) for product, qty in zip(products, [6, 6, 3, 6])]
        })
        po.button_confirm()

        res_dict = po.picking_ids.button_validate()
        validate_wizard = Form(
            self.env[(res_dict.get('res_model'))].with_context(
                res_dict.get('context'))).save()
        validate_wizard.process()

        lc_form = Form(self.LandedCost)
        lc_form.picking_ids.add(po.picking_ids)
        with lc_form.cost_lines.new() as line:
            line.product_id = landed_product
        lc = lc_form.save()
        lc.compute_landed_cost()

        self.assertEqual(
            sum(lc.valuation_adjustment_lines.mapped(
                'additional_landed_cost')), 1000.0)
Exemplo n.º 16
0
    def test_flow_6(self):
        """ Extra quantity on the move.
        """
        # We create a second partner of type subcontractor
        main_partner_2 = self.env['res.partner'].create({'name': 'main_partner'})
        subcontractor_partner2 = self.env['res.partner'].create({
            'name': 'subcontractor_partner',
            'parent_id': main_partner_2.id,
            'company_id': self.env.ref('base.main_company').id,
        })
        self.env.cache.invalidate()

        # We create a different BoM for the same product
        comp3 = self.env['product.product'].create({
            'name': 'Component3',
            'type': 'product',
            'categ_id': self.env.ref('product.product_category_all').id,
        })

        bom_form = Form(self.env['mrp.bom'])
        bom_form.type = 'subcontract'
        bom_form.product_tmpl_id = self.finished.product_tmpl_id
        with bom_form.bom_line_ids.new() as bom_line:
            bom_line.product_id = self.comp1
            bom_line.product_qty = 1
        with bom_form.bom_line_ids.new() as bom_line:
            bom_line.product_id = comp3
            bom_line.product_qty = 2
        bom2 = bom_form.save()

        # We assign the second BoM to the new partner
        self.bom.write({'subcontractor_ids': [(4, self.subcontractor_partner1.id, None)]})
        bom2.write({'subcontractor_ids': [(4, subcontractor_partner2.id, None)]})

        # Create a receipt picking from the subcontractor1
        picking_form = Form(self.env['stock.picking'])
        picking_form.picking_type_id = self.env.ref('stock.picking_type_in')
        picking_form.partner_id = subcontractor_partner2
        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()

        picking_receipt.move_lines.quantity_done = 3.0
        picking_receipt._action_done()
        mo = picking_receipt._get_subcontracted_productions()
        move_comp1 = mo.move_raw_ids.filtered(lambda m: m.product_id == self.comp1)
        move_comp3 = mo.move_raw_ids.filtered(lambda m: m.product_id == comp3)
        self.assertEqual(sum(move_comp1.mapped('product_uom_qty')), 3.0)
        self.assertEqual(sum(move_comp3.mapped('product_uom_qty')), 6.0)
        self.assertEqual(sum(move_comp1.mapped('quantity_done')), 3.0)
        self.assertEqual(sum(move_comp3.mapped('quantity_done')), 6.0)
        move_finished = mo.move_finished_ids
        self.assertEqual(sum(move_finished.mapped('product_uom_qty')), 3.0)
        self.assertEqual(sum(move_finished.mapped('quantity_done')), 3.0)
Exemplo n.º 17
0
    def test_tracking_backorder_series_serial_1(self):
        """ Create a MO of 4 tracked products (serial) with pbm_sam.
        all component is tracked by serial
        Produce one by one with one bakorder for each until end.
        """
        nb_product_todo = 4
        production, _, p_final, p1, p2 = self.generate_mo(qty_final=nb_product_todo, tracking_final='serial', tracking_base_1='serial', tracking_base_2='serial', qty_base_1=1)
        serials_final, serials_p1, serials_p2 = [], [], []
        for i in range(nb_product_todo):
            serials_final.append(self.env['stock.production.lot'].create({
                'name': f'lot_final_{i}',
                'product_id': p_final.id,
                'company_id': self.env.company.id,
            }))
            serials_p1.append(self.env['stock.production.lot'].create({
                'name': f'lot_consumed_1_{i}',
                'product_id': p1.id,
                'company_id': self.env.company.id,
            }))
            serials_p2.append(self.env['stock.production.lot'].create({
                'name': f'lot_consumed_2_{i}',
                'product_id': p2.id,
                'company_id': self.env.company.id,
            }))
            self.env['stock.quant']._update_available_quantity(p1, self.stock_location, 1, lot_id=serials_p1[-1])
            self.env['stock.quant']._update_available_quantity(p2, self.stock_location, 1, lot_id=serials_p2[-1])

        production.action_assign()
        active_production = production
        for i in range(nb_product_todo):

            details_operation_form = Form(active_production.move_raw_ids.filtered(lambda m: m.product_id == p1), view=self.env.ref('stock.view_stock_move_operations'))
            with details_operation_form.move_line_ids.edit(0) as ml:
                ml.qty_done = 1
                ml.lot_id = serials_p1[i]
            details_operation_form.save()
            details_operation_form = Form(active_production.move_raw_ids.filtered(lambda m: m.product_id == p2), view=self.env.ref('stock.view_stock_move_operations'))
            with details_operation_form.move_line_ids.edit(0) as ml:
                ml.qty_done = 1
                ml.lot_id = serials_p2[i]
            details_operation_form.save()

            production_form = Form(active_production)
            production_form.qty_producing = 1
            production_form.lot_producing_id = serials_final[i]
            active_production = production_form.save()

            active_production.button_mark_done()
            if i + 1 != nb_product_todo:  # If last MO, don't make a backorder
                action = active_production.button_mark_done()
                backorder = Form(self.env['mrp.production.backorder'].with_context(**action['context']))
                backorder.save().action_backorder()
            active_production = active_production.procurement_group_id.mrp_production_ids[-1]

        self.assertEqual(self.env['stock.quant']._get_available_quantity(p_final, self.stock_location), nb_product_todo, f'You should have the {nb_product_todo} final product in stock')
        self.assertEqual(len(production.procurement_group_id.mrp_production_ids), nb_product_todo)
Exemplo n.º 18
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 and MO for its components are
        automatically created.
        """
        # Tick "manufacture" and MTO on self.comp2
        mto_route = self.env.ref('stock.route_warehouse0_mto')
        mto_route.active = True
        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 = 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.assertEqual(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.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)
Exemplo n.º 19
0
    def test_message_qty_already_received(self):
        _product = self.env['product.product'].create({
            'name':
            'TempProduct',
            'type':
            'consu',
            'company_id':
            self.env.user.company_id.id,
        })

        _purchase_order = self.env['purchase.order'].create({
            'company_id':
            self.env.user.company_id.id,
            'partner_id':
            self.partner_a.id,
            'order_line': [(0, 0, {
                'name': _product.name,
                'product_id': _product.id,
                'product_qty': 25.0,
                'price_unit': 250.0,
            })],
        })

        _purchase_order.button_confirm()

        first_picking = _purchase_order.picking_ids[0]
        first_picking.move_lines.quantity_done = 5
        backorder_wizard_dict = first_picking.button_validate()
        backorder_wizard = Form(
            self.env[backorder_wizard_dict['res_model']].with_context(
                backorder_wizard_dict['context'])).save()
        backorder_wizard.process()

        second_picking = _purchase_order.picking_ids[1]
        second_picking.move_lines.quantity_done = 5
        backorder_wizard_dict = second_picking.button_validate()
        backorder_wizard = Form(
            self.env[backorder_wizard_dict['res_model']].with_context(
                backorder_wizard_dict['context'])).save()
        backorder_wizard.process()

        third_picking = _purchase_order.picking_ids[2]
        third_picking.move_lines.quantity_done = 5
        backorder_wizard_dict = third_picking.button_validate()
        backorder_wizard = Form(
            self.env[backorder_wizard_dict['res_model']].with_context(
                backorder_wizard_dict['context'])).save()
        backorder_wizard.process()

        _message_content = _purchase_order.message_ids.mapped("body")[0]
        self.assertIsNotNone(
            re.search(r"Received Quantity: 5.0 -> 10.0", _message_content),
            "Already received quantity isn't correctly taken into consideration"
        )
Exemplo n.º 20
0
    def test_backorder_and_orderpoint(self):
        """ Same as test_no_tracking_2, except one of components also has an orderpoint (i.e. reordering rule)
        and not enough components are in stock (i.e. so orderpoint is triggered)."""
        production, _, product_to_build, product_to_use_1, product_to_use_2 = self.generate_mo(qty_final=4, qty_base_1=1)

        # Make some stock and reserve
        for product in production.move_raw_ids.product_id:
            self.env['stock.quant'].with_context(inventory_mode=True).create({
                'product_id': product.id,
                'inventory_quantity': 1,
                'location_id': production.location_src_id.id,
            })
        production.action_assign()

        self.env['stock.warehouse.orderpoint'].create({
            'name': 'product_to_use_1 RR',
            'location_id': production.location_src_id.id,
            'product_id': product_to_use_1.id,
            'product_min_qty': 1,
            'product_max_qty': 5,
        })

        self.env['mrp.bom'].create({
            'product_id': product_to_use_1.id,
            'product_tmpl_id': product_to_use_1.product_tmpl_id.id,
            'product_uom_id': product_to_use_1.uom_id.id,
            'product_qty': 1.0,
            'type': 'normal',
            'consumption': 'flexible',
            'bom_line_ids': [
                (0, 0, {'product_id': product_to_use_2.id, 'product_qty': 1.0})
            ]})
        product_to_use_1.write({'route_ids': [(4, self.ref('mrp.route_warehouse0_manufacture'))]})

        mo_form = Form(production)
        mo_form.qty_producing = 1
        production = mo_form.save()

        action = production.button_mark_done()
        backorder = Form(self.env['mrp.production.backorder'].with_context(**action['context']))
        backorder.save().action_backorder()

        # Two related MO, orig + backorder, in same the procurement group
        mos = self.env['mrp.production'].search([
            ('product_id', '=', product_to_build.id),
        ])
        self.assertEqual(len(mos), 2, "Backorder was not created.")
        self.assertEqual(len(production.procurement_group_id.mrp_production_ids), 2, "MO backorder not linked to original MO")

        # Orderpoint MO is NOT part of procurement group
        mo_orderpoint = self.env['mrp.production'].search([
            ('product_id', '=', product_to_use_1.id),
        ])
        self.assertEqual(len(mo_orderpoint.procurement_group_id.mrp_production_ids), 1, "Reordering rule MO incorrectly linked to other MOs")
Exemplo n.º 21
0
    def setUp(self):
        super(TestMultistepManufacturing, self).setUp()

        self.env.ref('stock.route_warehouse0_mto').active = True
        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['res.partner'].create(
            {'name': 'My Test Partner'})
        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()
Exemplo n.º 22
0
    def test_vendor_bill_flow_anglo_saxon_2(self):
        """In anglo saxon accounting, receive 10@10 and invoice with the addition of 1@50 as a
        landed costs and create a linked landed costs record.
        """
        self.env.company.anglo_saxon_accounting = True

        # Create an RFQ for self.product1, 10@10
        rfq = Form(self.env['purchase.order'])
        rfq.partner_id = self.vendor1

        with rfq.order_line.new() as po_line:
            po_line.product_id = self.product1
            po_line.product_qty = 10
            po_line.price_unit = 10
            po_line.taxes_id.clear()

        rfq = rfq.save()
        rfq.button_confirm()

        # Process the receipt
        receipt = rfq.picking_ids
        wiz = receipt.button_validate()
        wiz = Form(self.env['stock.immediate.transfer'].with_context(wiz['context'])).save()
        wiz.process()
        self.assertEqual(rfq.order_line.qty_received, 10)

        input_aml = self._get_stock_input_move_lines()[-1]
        self.assertEqual(input_aml.debit, 0)
        self.assertEqual(input_aml.credit, 100)
        valuation_aml = self._get_stock_valuation_move_lines()[-1]
        self.assertEqual(valuation_aml.debit, 100)
        self.assertEqual(valuation_aml.credit, 0)

        # Create a vendor bill for the RFQ and add to it the landed cost
        vb = Form(self.env['account.move'].with_context(default_move_type='in_invoice'))
        vb.partner_id = self.vendor1
        vb.invoice_date = vb.date
        with vb.invoice_line_ids.new() as inv_line:
            inv_line.product_id = self.productlc1
            inv_line.price_unit = 50
            inv_line.is_landed_costs_line = True
        vb = vb.save()
        vb.action_post()

        action = vb.button_create_landed_costs()
        lc = Form(self.env[action['res_model']].browse(action['res_id']))
        lc.picking_ids.add(receipt)
        lc = lc.save()
        lc.button_validate()

        # Check reconciliation of input aml of lc
        lc_input_aml = lc.account_move_id.line_ids.filtered(lambda aml: aml.account_id == self.company_data['default_account_stock_in'])
        self.assertTrue(len(lc_input_aml.full_reconcile_id), 1)
Exemplo n.º 23
0
    def test_00_production_order_with_accounting(self):
        self.product_table_sheet.standard_price = 20.0
        self.product_table_leg.standard_price = 15.0
        self.product_bolt.standard_price = 10.0
        self.product_screw.standard_price = 0.1
        self.product_table_leg.tracking = 'none'
        self.product_table_sheet.tracking = 'none'
        inventory = self.env['stock.inventory'].create({
            'name': 'Inventory Product Table',
            'line_ids': [(0, 0, {
                'product_id': self.product_table_sheet.id,  # tracking serial
                'product_uom_id': self.product_table_sheet.uom_id.id,
                'product_qty': 20,
                'location_id': self.source_location_id
            }), (0, 0, {
                'product_id': self.product_table_leg.id,  # tracking lot
                'product_uom_id': self.product_table_leg.uom_id.id,
                'product_qty': 20,
                'location_id': self.source_location_id
            }), (0, 0, {
                'product_id': self.product_bolt.id,
                'product_uom_id': self.product_bolt.uom_id.id,
                'product_qty': 20,
                'location_id': self.source_location_id
            }), (0, 0, {
                'product_id': self.product_screw.id,
                'product_uom_id': self.product_screw.uom_id.id,
                'product_qty': 200000,
                'location_id': self.source_location_id
            }),
            ]
        })
        inventory.action_validate
        bom = self.mrp_bom_desk.copy()
        bom.operation_ids = False
        production_table_form = Form(self.env['mrp.production'])
        production_table_form.product_id = self.dining_table
        production_table_form.bom_id = bom
        production_table_form.product_qty = 1
        production_table = production_table_form.save()

        production_table.extra_cost = 20
        production_table.action_confirm()

        mo_form = Form(production_table)
        mo_form.qty_producing = 1
        production_table = mo_form.save()
        production_table._post_inventory()
        move_value = production_table.move_finished_ids.filtered(lambda x: x.state == "done").stock_valuation_layer_ids.value

        # 1 table head at 20 + 4 table leg at 15 + 4 bolt at 10 + 10 screw at 10 + 1*20 (extra cost)
        self.assertEqual(move_value, 141, 'Thing should have the correct price')
Exemplo n.º 24
0
    def test_edit_warehouse_1(self):
        wh = Form(self.env['stock.warehouse'])
        wh.name = "Chicago"
        wh.code = "chic"
        warehouse = wh.save()
        self.assertEqual(warehouse.int_type_id.barcode, 'CHIC-INTERNAL')
        self.assertEqual(warehouse.int_type_id.sequence_id.prefix, 'chic/INT/')

        wh = Form(warehouse)
        wh.code = 'CH'
        wh.save()
        self.assertEqual(warehouse.int_type_id.barcode, 'CH-INTERNAL')
        self.assertEqual(warehouse.int_type_id.sequence_id.prefix, 'CH/INT/')
Exemplo n.º 25
0
    def test_cancel_multilevel_manufacturing(self):
        """ Testing for multilevel Manufacturing orders.
            When user creates multi-level manufacturing orders,
            and then cancelles child manufacturing order,
            an activity should be generated on parent MO, to notify user that
            demands from child MO has been cancelled.
        """

        product_form = Form(self.env['product.product'])
        product_form.name = 'Screw'
        self.product_screw = product_form.save()

        # Add routes for manufacturing and make to order to the raw material product
        with Form(self.product_raw) as p1:
            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)

        # New BoM for raw material product, it will generate another Production order i.e. child Production order
        bom_product_form = Form(self.env['mrp.bom'])
        bom_product_form.product_id = self.product_raw
        bom_product_form.product_tmpl_id = self.product_raw.product_tmpl_id
        bom_product_form.product_qty = 1.0
        with bom_product_form.bom_line_ids.new() as bom_line:
            bom_line.product_id = self.product_screw
            bom_line.product_qty = 5.0
        self.bom_prod_manu = bom_product_form.save()

        # create MO from sale order.
        self.sale_order.action_confirm()
        # Find child MO.
        child_manufaturing = self.env['mrp.production'].search([
            ('product_id', '=', self.product_raw.id)
        ])
        self.assertTrue(
            (len(child_manufaturing.ids) == 1),
            'Manufacturing order of raw material must be generated.')
        # Cancel child MO.
        child_manufaturing.action_cancel()
        manufaturing_from_so = self.env['mrp.production'].search([
            ('product_id', '=', self.product_manu.id)
        ])
        # Check if activity is generated or not on parent MO.
        exception = self.env['mail.activity'].search([
            ('res_model', '=', 'mrp.production'),
            ('res_id', '=', manufaturing_from_so.id)
        ])
        self.assertEqual(
            len(exception.ids), 1,
            'When user cancelled child manufacturing, exception must be generated on parent manufacturing.'
        )
Exemplo n.º 26
0
    def test_change_product(self):
        """ Create a production order for a specific product with a BoM. Then change the BoM and the finished product for
        other ones and check the finished product of the first mo did not became a byproduct of the second one."""
        # Create BOM for product A with product B as component
        bom_product_a = self.MrpBom.create({
            'product_tmpl_id':
            self.product_a.product_tmpl_id.id,
            'product_qty':
            1.0,
            'type':
            'normal',
            'product_uom_id':
            self.uom_unit_id,
            'bom_line_ids': [(0, 0, {
                'product_id': self.product_b.id,
                'product_uom_id': self.uom_unit_id,
                'product_qty': 2
            })],
        })

        bom_product_a_2 = self.MrpBom.create({
            'product_tmpl_id':
            self.product_b.product_tmpl_id.id,
            'product_qty':
            1.0,
            'type':
            'normal',
            'product_uom_id':
            self.uom_unit_id,
            'bom_line_ids': [(0, 0, {
                'product_id': self.product_c_id,
                'product_uom_id': self.uom_unit_id,
                'product_qty': 2
            })],
        })
        # Create production order for product A
        # -------------------------------------

        mnf_product_a_form = Form(self.env['mrp.production'])
        mnf_product_a_form.product_id = self.product_a
        mnf_product_a_form.bom_id = bom_product_a
        mnf_product_a_form.product_qty = 1.0
        mnf_product_a = mnf_product_a_form.save()
        mnf_product_a_form = Form(mnf_product_a)
        mnf_product_a_form.bom_id = bom_product_a_2
        mnf_product_a = mnf_product_a_form.save()
        self.assertEqual(mnf_product_a.move_raw_ids.product_id.id,
                         self.product_c_id)
        self.assertFalse(mnf_product_a.move_byproduct_ids)
Exemplo n.º 27
0
    def test_00_procurement_exception(self):

        res_partner_2 = self.env['res.partner'].create({'name': 'My Test Partner'})
        res_partner_address = self.env['res.partner'].create({
            'name': 'My Test Partner Address',
            'parent_id': res_partner_2.id,
        })

        # 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.categ_id = self.env.ref('product.product_category_1')
        product_with_no_seller = product_form.save()

        product_with_no_seller.standard_price = 70.0

        # I create a sales order with this product with route dropship.
        so_form = Form(self.env['sale.order'])
        so_form.partner_id = res_partner_2
        so_form.partner_invoice_id = res_partner_address
        so_form.partner_shipping_id = res_partner_address
        so_form.payment_term_id = self.env.ref('account.account_payment_term_end_following_month')
        with so_form.order_line.new() as line:
            line.product_id = product_with_no_seller
            line.product_uom_qty = 3
            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 = 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')
Exemplo n.º 28
0
    def test_bom_report_dozens(self):
        """ Simulate a drawer bom with dozens as bom units
        """
        uom_dozen = self.env.ref('uom.product_uom_dozen')
        uom_unit = self.env.ref('uom.product_uom_unit')
        drawer = self.env['product.product'].create({
            'name': 'drawer',
            'type': 'product',
            'uom_id': uom_unit.id,
            'uom_po_id': uom_unit.id,
        })
        screw = self.env['product.product'].create({
            'name': 'screw',
            'type': 'product',
            'uom_id': uom_unit.id,
            'uom_po_id': uom_unit.id,
            'standard_price': 7.01
        })

        bom_form_drawer = Form(self.env['mrp.bom'])
        bom_form_drawer.product_tmpl_id = drawer.product_tmpl_id
        bom_form_drawer.product_qty = 11
        bom_form_drawer.product_uom_id = uom_dozen
        bom_drawer = bom_form_drawer.save()

        workcenter = self.env['mrp.workcenter'].create({
            'costs_hour': 10,
            'name': 'Deserts Table'
        })

        with Form(bom_drawer) as bom:
            with bom.bom_line_ids.new() as line:
                line.product_id = screw
                line.product_uom_id = uom_unit
                line.product_qty = 5
            with bom.operation_ids.new() as operation:
                operation.workcenter_id = workcenter
                operation.name = 'Screw drawer'
                operation.time_cycle_manual = 5

        # TEST BOM STRUCTURE VALUE WITH BOM QUANTITY
        report_values = self.env[
            'report.mrp.report_bom_structure']._get_report_data(
                bom_id=bom_drawer.id, searchQty=11, searchVariant=False)
        # 5 min 'Prepare biscuits' + 3 min 'Prepare butter' + 5 min 'Mix manually' = 13 minutes
        self.assertEqual(
            report_values['lines']['operations_time'], 660.0,
            'Operation time should be the same for 1 unit or for the batch')
Exemplo n.º 29
0
    def test_flow_9(self):
        """Ensure that cancel the subcontract moves will also delete the
        components need for the subcontractor.
        """
        resupply_sub_on_order_route = self.env['stock.location.route'].search([
            ('name', '=', 'Resupply Subcontractor on Order')
        ])
        (self.comp1 + self.comp2).write({
            'route_ids': [(4, resupply_sub_on_order_route.id)]
        })

        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()

        picking_delivery = self.env['stock.move'].search([
            ('product_id', 'in', (self.comp1 | self.comp2).ids)
        ]).picking_id
        self.assertTrue(picking_delivery)
        self.assertEqual(picking_delivery.state, 'confirmed')
        self.assertEqual(self.comp1.virtual_available, -5)
        self.assertEqual(self.comp2.virtual_available, -5)
        # action_cancel is not call on the picking in order
        # to test behavior from other source than picking (e.g. puchase).
        picking_receipt.move_lines._action_cancel()
        self.assertEqual(picking_delivery.state, 'cancel')
        self.assertEqual(self.comp1.virtual_available, 0.0)
        self.assertEqual(self.comp1.virtual_available, 0.0)
Exemplo n.º 30
0
    def test_procurement_2(self):
        """Check that a manufacturing order create the right procurements when the route are set on
        a parent category of a product"""
        # find a child category id
        all_categ_id = self.env['product.category'].search(
            [('parent_id', '=', None)], limit=1)
        child_categ_id = self.env['product.category'].search(
            [('parent_id', '=', all_categ_id.id)], limit=1)

        # set the product of `self.bom_1` to this child category
        for bom_line_id in self.bom_1.bom_line_ids:
            # check that no routes are defined on the product
            self.assertEqual(len(bom_line_id.product_id.route_ids), 0)
            # set the category of the product to a child category
            bom_line_id.product_id.categ_id = child_categ_id

        # set the MTO route to the parent category (all)
        self.warehouse = self.env.ref('stock.warehouse0')
        mto_route = self.warehouse.mto_pull_id.route_id
        mto_route.active = True
        mto_route.product_categ_selectable = True
        all_categ_id.write({'route_ids': [(6, 0, [mto_route.id])]})

        # create MO, but check it raises error as components are in make to order and not everyone has
        with self.assertRaises(UserError):
            production_form = Form(self.env['mrp.production'])
            production_form.product_id = self.product_4
            production_form.product_uom_id = self.product_4.uom_id
            production_form.product_qty = 1
            production_product_4 = production_form.save()
            production_product_4.action_confirm()