Пример #1
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()
    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()
Пример #3
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)
    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()
Пример #5
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.')
Пример #6
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)
Пример #7
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)
Пример #8
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')
Пример #9
0
    def test_lifoprice(self):

        self._load('account', 'test', 'account_minimal_test.xml')
        self._load('stock_account', 'test', 'stock_valuation_account.xml')

        # Set product category removal strategy as LIFO
        product_category_001 = self.env['product.category'].create({
            'name':
            'Lifo Category',
            'removal_strategy_id':
            self.env.ref('stock.removal_lifo').id,
            'property_valuation':
            'real_time',
            'property_cost_method':
            'fifo',
        })

        # Set a product as using lifo price
        product_form = Form(self.env['product.product'])
        product_form.default_code = 'LIFO'
        product_form.name = 'LIFO Ice Cream'
        product_form.type = 'product'
        product_form.categ_id = product_category_001
        product_form.lst_price = 100.0
        product_form.standard_price = 70.0
        product_form.uom_id = self.env.ref('uom.product_uom_kgm')
        product_form.uom_po_id = self.env.ref('uom.product_uom_kgm')
        # these are not available (visible) in either product or variant
        # for views, apparently from the UI you can only set the product
        # category (or hand-assign the property_* version which seems...)
        # product_form.valuation = 'real_time'
        # product_form.cost_method = 'fifo'
        product_form.property_stock_account_input = self.env.ref(
            'stock_dropshipping.o_expense')
        product_form.property_stock_account_output = self.env.ref(
            'stock_dropshipping.o_income')
        product_lifo_icecream = product_form.save()

        # I create a draft Purchase Order for first in move for 10 pieces at 60 euro
        order_form = Form(self.env['purchase.order'])
        order_form.partner_id = self.env.ref('base.res_partner_3')
        with order_form.order_line.new() as line:
            line.product_id = product_lifo_icecream
            line.product_qty = 10.0
            line.price_unit = 60.0
        purchase_order_lifo1 = order_form.save()

        # I create a draft Purchase Order for second shipment for 30 pieces at 80 euro
        order2_form = Form(self.env['purchase.order'])
        order2_form.partner_id = self.env.ref('base.res_partner_3')
        with order2_form.order_line.new() as line:
            line.product_id = product_lifo_icecream
            line.product_qty = 30.0
            line.price_unit = 80.0
        purchase_order_lifo2 = order2_form.save()

        # I confirm the first purchase order
        purchase_order_lifo1.button_confirm()

        # I check the "Approved" status of purchase order 1
        self.assertEqual(purchase_order_lifo1.state, 'purchase')

        # Process the receipt of purchase order 1
        purchase_order_lifo1.picking_ids[
            0].move_lines.quantity_done = purchase_order_lifo1.picking_ids[
                0].move_lines.product_qty
        purchase_order_lifo1.picking_ids[0].button_validate()

        # I confirm the second purchase order
        purchase_order_lifo2.button_confirm()

        # Process the receipt of purchase order 2
        purchase_order_lifo2.picking_ids[
            0].move_lines.quantity_done = purchase_order_lifo2.picking_ids[
                0].move_lines.product_qty
        purchase_order_lifo2.picking_ids[0].button_validate()

        # Let us send some goods
        out_form = Form(self.env['stock.picking'])
        out_form.picking_type_id = self.env.ref('stock.picking_type_out')
        out_form.immediate_transfer = True
        with out_form.move_ids_without_package.new() as move:
            move.product_id = product_lifo_icecream
            move.quantity_done = 20.0
            move.date_expected = fields.Datetime.now()
        outgoing_lifo_shipment = out_form.save()

        # I assign this outgoing shipment
        outgoing_lifo_shipment.action_assign()

        # Process the delivery of the outgoing shipment
        outgoing_lifo_shipment.button_validate()

        # Check if the move value correctly reflects the fifo costing method
        self.assertEqual(outgoing_lifo_shipment.move_lines.value, -1400.0,
                         'Stock move value should have been 1400 euro')
Пример #10
0
    def test_bom_report(self):
        """ Simulate a crumble receipt with mrp and open the bom structure
        report and check that data insde are correct.
        """
        uom_kg = self.env.ref('uom.product_uom_kgm')
        uom_litre = self.env.ref('uom.product_uom_litre')
        crumble = self.env['product.product'].create({
            'name': 'Crumble',
            'type': 'product',
            'uom_id': uom_kg.id,
            'uom_po_id': uom_kg.id,
        })
        butter = self.env['product.product'].create({
            'name': 'Butter',
            'type': 'product',
            'uom_id': uom_kg.id,
            'uom_po_id': uom_kg.id,
            'standard_price': 7.01
        })
        biscuit = self.env['product.product'].create({
            'name': 'Biscuit',
            'type': 'product',
            'uom_id': uom_kg.id,
            'uom_po_id': uom_kg.id,
            'standard_price': 1.5
        })
        bom_form_crumble = Form(self.env['mrp.bom'])
        bom_form_crumble.product_tmpl_id = crumble.product_tmpl_id
        bom_form_crumble.product_qty = 11
        bom_form_crumble.product_uom_id = uom_kg
        bom_crumble = bom_form_crumble.save()

        with Form(bom_crumble) as bom:
            with bom.bom_line_ids.new() as line:
                line.product_id = butter
                line.product_uom_id = uom_kg
                line.product_qty = 5
            with bom.bom_line_ids.new() as line:
                line.product_id = biscuit
                line.product_uom_id = uom_kg
                line.product_qty = 6

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

        routing_form = Form(self.env['mrp.routing'])
        routing_form.name = "Crumble process"
        routing_crumble = routing_form.save()

        with Form(routing_crumble) as routing:
            with routing.operation_ids.new() as operation:
                operation.workcenter_id = workcenter
                operation.name = 'Prepare biscuits'
                operation.time_cycle_manual = 5
            with routing.operation_ids.new() as operation:
                operation.workcenter_id = workcenter
                operation.name = 'Prepare butter'
                operation.time_cycle_manual = 3
            with routing.operation_ids.new() as operation:
                operation.workcenter_id = workcenter
                operation.name = 'Mix manually'
                operation.time_cycle_manual = 5

        bom_crumble.routing_id = routing_crumble.id

        # TEST BOM STRUCTURE VALUE WITH BOM QUANTITY
        report_values = self.env[
            'report.mrp.report_bom_structure']._get_report_data(
                bom_id=bom_crumble.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'], 13.0,
            'Operation time should be the same for 1 unit or for the batch')
        # Operation cost is the sum of operation line.
        operation_cost = float_round(5 / 60 * 10,
                                     precision_digits=2) * 2 + float_round(
                                         3 / 60 * 10, precision_digits=2)
        self.assertEqual(
            float_compare(report_values['lines']['operations_cost'],
                          operation_cost,
                          precision_digits=2), 0,
            '13 minute for 10$/hours -> 2.16')

        for component_line in report_values['lines']['components']:
            # standard price * bom line quantity * current quantity / bom finished product quantity
            if component_line['prod_id'] == butter.id:
                # 5 kg of butter at 7.01$ for 11kg of crumble -> 35.05$
                self.assertEqual(
                    float_compare(component_line['total'], (7.01 * 5),
                                  precision_digits=2), 0)
            if component_line['prod_id'] == biscuit.id:
                # 6 kg of biscuits at 1.50$ for 11kg of crumble -> 9$
                self.assertEqual(
                    float_compare(component_line['total'], (1.5 * 6),
                                  precision_digits=2), 0)
        # total price = 35.05 + 9 + operation_cost(0.83 + 0.83 + 0.5 = 2.16) = 46,21
        self.assertEqual(
            float_compare(report_values['lines']['total'],
                          46.21,
                          precision_digits=2), 0,
            'Product Bom Price is not correct')
        self.assertEqual(
            float_compare(report_values['lines']['total'] / 11.0,
                          4.20,
                          precision_digits=2), 0,
            'Product Unit Bom Price is not correct')

        # TEST BOM STRUCTURE VALUE BY UNIT
        report_values = self.env[
            'report.mrp.report_bom_structure']._get_report_data(
                bom_id=bom_crumble.id, searchQty=1, searchVariant=False)
        # 5 min 'Prepare biscuits' + 3 min 'Prepare butter' + 5 min 'Mix manually' = 13 minutes
        self.assertEqual(
            report_values['lines']['operations_time'], 13.0,
            'Operation time should be the same for 1 unit or for the batch')
        # Operation cost is the sum of operation line.
        operation_cost = float_round(5 / 60 * 10,
                                     precision_digits=2) * 2 + float_round(
                                         3 / 60 * 10, precision_digits=2)
        self.assertEqual(
            float_compare(report_values['lines']['operations_cost'],
                          operation_cost,
                          precision_digits=2), 0,
            '13 minute for 10$/hours -> 2.16')

        for component_line in report_values['lines']['components']:
            # standard price * bom line quantity * current quantity / bom finished product quantity
            if component_line['prod_id'] == butter.id:
                # 5 kg of butter at 7.01$ for 11kg of crumble -> / 11 for price per unit (3.19)
                self.assertEqual(
                    float_compare(component_line['total'],
                                  (7.01 * 5) * (1 / 11),
                                  precision_digits=2), 0)
            if component_line['prod_id'] == biscuit.id:
                # 6 kg of biscuits at 1.50$ for 11kg of crumble -> / 11 for price per unit (0.82)
                self.assertEqual(
                    float_compare(component_line['total'],
                                  (1.5 * 6) * (1 / 11),
                                  precision_digits=2), 0)
        # total price = 3.19 + 0.82 + operation_cost(0.83 + 0.83 + 0.5 = 2.16) = 6,17
        self.assertEqual(
            float_compare(report_values['lines']['total'],
                          6.17,
                          precision_digits=2), 0,
            'Product Unit Bom Price is not correct')

        # TEST OPERATION COST WHEN PRODUCED QTY > BOM QUANTITY
        report_values_12 = self.env[
            'report.mrp.report_bom_structure']._get_report_data(
                bom_id=bom_crumble.id, searchQty=12, searchVariant=False)
        report_values_22 = self.env[
            'report.mrp.report_bom_structure']._get_report_data(
                bom_id=bom_crumble.id, searchQty=22, searchVariant=False)
        operation_cost = float_round(10 / 60 * 10,
                                     precision_digits=2) * 2 + float_round(
                                         6 / 60 * 10, precision_digits=2)
        # Both needs 2 operation cycle
        self.assertEqual(report_values_12['lines']['operations_cost'],
                         report_values_22['lines']['operations_cost'])
        self.assertEqual(report_values_22['lines']['operations_cost'],
                         operation_cost)
        report_values_23 = self.env[
            'report.mrp.report_bom_structure']._get_report_data(
                bom_id=bom_crumble.id, searchQty=23, searchVariant=False)
        operation_cost = float_round(15 / 60 * 10,
                                     precision_digits=2) * 2 + float_round(
                                         9 / 60 * 10, precision_digits=2)
        self.assertEqual(report_values_23['lines']['operations_cost'],
                         operation_cost)

        # Create a more complex BoM with a sub product
        cheese_cake = self.env['product.product'].create({
            'name': 'Cheese Cake 300g',
            'type': 'product',
        })
        cream = self.env['product.product'].create({
            'name': 'cream',
            'type': 'product',
            'uom_id': uom_litre.id,
            'uom_po_id': uom_litre.id,
            'standard_price': 5.17,
        })
        bom_form_cheese_cake = Form(self.env['mrp.bom'])
        bom_form_cheese_cake.product_tmpl_id = cheese_cake.product_tmpl_id
        bom_form_cheese_cake.product_qty = 60
        bom_form_cheese_cake.product_uom_id = self.uom_unit
        bom_cheese_cake = bom_form_cheese_cake.save()

        with Form(bom_cheese_cake) as bom:
            with bom.bom_line_ids.new() as line:
                line.product_id = cream
                line.product_uom_id = uom_litre
                line.product_qty = 3
            with bom.bom_line_ids.new() as line:
                line.product_id = crumble
                line.product_uom_id = uom_kg
                line.product_qty = 5.4

        workcenter_2 = self.env['mrp.workcenter'].create({
            'name': 'cake mounting',
            'costs_hour': 20,
            'time_start': 10,
            'time_stop': 15
        })

        routing_form = Form(self.env['mrp.routing'])
        routing_form.name = "Cheese cake process"
        routing_cheese = routing_form.save()

        with Form(routing_cheese) as routing:
            with routing.operation_ids.new() as operation:
                operation.workcenter_id = workcenter
                operation.name = 'Mix cheese and crumble'
                operation.time_cycle_manual = 10
            with routing.operation_ids.new() as operation:
                operation.workcenter_id = workcenter_2
                operation.name = 'Cake mounting'
                operation.time_cycle_manual = 5

        bom_cheese_cake.routing_id = routing_cheese.id

        # TEST CHEESE BOM STRUCTURE VALUE WITH BOM QUANTITY
        report_values = self.env[
            'report.mrp.report_bom_structure']._get_report_data(
                bom_id=bom_cheese_cake.id, searchQty=60, searchVariant=False)
        self.assertEqual(
            report_values['lines']['operations_time'], 40.0,
            'Operation time should be the same for 1 unit or for the batch')
        # Operation cost is the sum of operation line.
        operation_cost = float_round(
            10 / 60 * 10, precision_digits=2) + float_round(30 / 60 * 20,
                                                            precision_digits=2)
        self.assertEqual(
            float_compare(report_values['lines']['operations_cost'],
                          operation_cost,
                          precision_digits=2), 0)

        for component_line in report_values['lines']['components']:
            # standard price * bom line quantity * current quantity / bom finished product quantity
            if component_line['prod_id'] == cream.id:
                # 3 liter of cream at 5.17$ for 60 unit of cheese cake -> 15.51$
                self.assertEqual(
                    float_compare(component_line['total'], (3 * 5.17),
                                  precision_digits=2), 0)
            if component_line['prod_id'] == crumble.id:
                # 5.4 kg of crumble at the cost of a batch.
                crumble_cost = self.env[
                    'report.mrp.report_bom_structure']._get_report_data(
                        bom_id=bom_crumble.id,
                        searchQty=5.4,
                        searchVariant=False)['lines']['total']
                self.assertEqual(
                    float_compare(component_line['total'],
                                  crumble_cost,
                                  precision_digits=2), 0)
        # total price = 15.51 + crumble_cost + operation_cost(10 + 1.67 = 11.67) = 27.18 + crumble_cost
        self.assertEqual(
            float_compare(report_values['lines']['total'],
                          27.18 + crumble_cost,
                          precision_digits=2), 0,
            'Product Bom Price is not correct')
Пример #11
0
    def test_01_compute_price_operation_cost(self):
        """Test calcuation of bom cost with operations."""
        workcenter_from1 = Form(self.env['mrp.workcenter'])
        workcenter_from1.name = 'Workcenter'
        workcenter_from1.time_efficiency = 100
        workcenter_from1.capacity = 2
        workcenter_from1.oee_target = 100
        workcenter_from1.time_start = 0
        workcenter_from1.time_stop = 0
        workcenter_from1.costs_hour = 100
        workcenter_1 = workcenter_from1.save()

        routing_form1 = Form(self.Routing)
        routing_form1.name = 'Assembly Furniture'
        routing_1 = routing_form1.save()

        operation_1 = self.operation.create({
            'name': 'Cutting',
            'workcenter_id': workcenter_1.id,
            'routing_id': routing_1.id,
            'time_mode': 'manual',
            'time_cycle_manual': 20,
            'batch': 'no',
            'sequence': 1,
        })
        operation_2 = self.operation.create({
            'name': 'Drilling',
            'workcenter_id': workcenter_1.id,
            'routing_id': routing_1.id,
            'time_mode': 'manual',
            'time_cycle_manual': 25,
            'batch': 'no',
            'sequence': 2,
        })
        operation_3 = self.operation.create({
            'name': 'Fitting',
            'workcenter_id': workcenter_1.id,
            'routing_id': routing_1.id,
            'time_mode': 'manual',
            'time_cycle_manual': 30,
            'batch': 'no',
            'sequence': 3,
        })

        # -----------------------------------------------------------------
        # Dinning Table Operation Cost(1 Unit)
        # -----------------------------------------------------------------
        # Operation cost calculate for 1 units
        # Cutting        (20 / 60) * 100 =  33.33
        # Drilling       (25 / 60) * 100 =  41.67
        # Fitting        (30 / 60) * 100 =  50.00
        # ----------------------------------------
        # Operation Cost  1 unit = 125
        # -----------------------------------------------------------------

        self.bom_1.routing_id = routing_1.id

        # --------------------------------------------------------------------------
        # Table Head Operation Cost (1 Dozen)
        # --------------------------------------------------------------------------
        # Operation cost calculate for 1 dozens
        # Cutting        (20 * 1 / 60) * 100 =  33,33
        # Drilling       (25 * 1 / 60) * 100 =  41,67
        # Fitting        (30 * 1 / 60) * 100 =  50
        # ----------------------------------------
        # Operation Cost 1 dozen (125 per dozen) and 10.42 for 1 Unit
        # --------------------------------------------------------------------------

        self.bom_2.routing_id = routing_1.id

        self.assertEqual(self.dining_table.standard_price, 1000,
                         "Initial price of the Product should be 1000")
        self.dining_table.button_bom_cost()
        # Total cost of Dining Table = (550) + Total cost of operations (125) = 675.0
        self.assertEquals(
            float_round(self.dining_table.standard_price, precision_digits=2),
            675.0, "After computing price from BoM price should be 612.5")
        self.Product.browse([self.dining_table.id,
                             self.table_head.id]).action_bom_cost()
        # Total cost of Dining Table = (718.75) + Total cost of all operations (125 + 10.42) = 854.17
        self.assertEquals(
            float_compare(self.dining_table.standard_price,
                          854.17,
                          precision_digits=2), 0,
            "After computing price from BoM price should be 786.46")
Пример #12
0
    def test_pack_in_receipt_two_step_multi_putaway(self):
        """ Checks all works right in the following specific corner case:

          * For a two-step receipt, receives two products using two putaways
          targeting different locations.
          * Puts these products in a package then valid the receipt.
          * Cancels the automatically generated internal transfer then create a new one.
          * In this internal transfer, adds the package then valid it.
        """
        grp_multi_loc = self.env.ref('stock.group_stock_multi_locations')
        grp_multi_step_rule = self.env.ref('stock.group_adv_location')
        grp_pack = self.env.ref('stock.group_tracking_lot')
        self.env.user.write({'groups_id': [(3, grp_multi_loc.id)]})
        self.env.user.write({'groups_id': [(3, grp_multi_step_rule.id)]})
        self.env.user.write({'groups_id': [(3, grp_pack.id)]})
        self.warehouse.reception_steps = 'two_steps'
        # Settings of receipt.
        self.warehouse.in_type_id.show_operations = True
        self.warehouse.in_type_id.show_entire_packs = True
        # Settings of internal transfer.
        self.warehouse.int_type_id.show_operations = True
        self.warehouse.int_type_id.show_entire_packs = True

        # Creates two new locations for putaway.
        location_form = Form(self.env['stock.location'])
        location_form.name = 'Shelf A'
        location_form.location_id = self.stock_location
        loc_shelf_A = location_form.save()
        location_form = Form(self.env['stock.location'])
        location_form.name = 'Shelf B'
        location_form.location_id = self.stock_location
        loc_shelf_B = location_form.save()

        # Creates a new putaway rule for productA and productB.
        putaway = self.env['product.putaway'].create({
            'name':
            'Stock Putaway',
            'product_location_ids': [(0, 0, {
                'product_id': self.productA.id,
                'fixed_location_id': loc_shelf_A.id,
            }),
                                     (0, 0, {
                                         'product_id': self.productB.id,
                                         'fixed_location_id': loc_shelf_B.id,
                                     })]
        })
        location_form = Form(self.stock_location)
        location_form.putaway_strategy_id = putaway
        self.stock_location = location_form.save()

        # Create a new receipt with the two products.
        receipt_form = Form(self.env['stock.picking'])
        receipt_form.picking_type_id = self.warehouse.in_type_id
        # Add 2 lines
        with receipt_form.move_ids_without_package.new() as move_line:
            move_line.product_id = self.productA
            move_line.product_uom_qty = 1
        with receipt_form.move_ids_without_package.new() as move_line:
            move_line.product_id = self.productB
            move_line.product_uom_qty = 1
        receipt = receipt_form.save()
        receipt.action_confirm()

        # Adds quantities then packs them and valids the receipt.
        receipt_form = Form(receipt)
        with receipt_form.move_line_ids_without_package.edit(0) as move_line:
            move_line.qty_done = 1
        with receipt_form.move_line_ids_without_package.edit(1) as move_line:
            move_line.qty_done = 1
        receipt = receipt_form.save()
        receipt.put_in_pack()
        receipt.button_validate()

        receipt_package = receipt.package_level_ids_details[0]
        self.assertEqual(receipt_package.location_dest_id.id,
                         receipt.location_dest_id.id)
        self.assertEqual(receipt_package.move_line_ids[0].location_dest_id.id,
                         receipt.location_dest_id.id)
        self.assertEqual(receipt_package.move_line_ids[1].location_dest_id.id,
                         receipt.location_dest_id.id)

        # Checks an internal transfer was created following the validation of the receipt.
        internal_transfer = self.env['stock.picking'].search(
            [('picking_type_id', '=', self.warehouse.int_type_id.id)],
            order='id desc',
            limit=1)
        self.assertEqual(internal_transfer.origin, receipt.name)
        self.assertEqual(len(internal_transfer.package_level_ids_details), 1)
        internal_package = internal_transfer.package_level_ids_details[0]
        self.assertEqual(internal_package.location_dest_id.id,
                         internal_transfer.location_dest_id.id)
        self.assertNotEqual(
            internal_package.location_dest_id.id,
            putaway.product_location_ids[0].fixed_location_id.id,
            "The package destination location must be the one from the picking."
        )
        self.assertNotEqual(
            internal_package.move_line_ids[0].location_dest_id.id,
            putaway.product_location_ids[0].fixed_location_id.id,
            "The move line destination location must be the one from the picking."
        )
        self.assertNotEqual(
            internal_package.move_line_ids[1].location_dest_id.id,
            putaway.product_location_ids[0].fixed_location_id.id,
            "The move line destination location must be the one from the picking."
        )

        # Cancels the internal transfer and creates a new one.
        internal_transfer.action_cancel()
        internal_form = Form(self.env['stock.picking'])
        internal_form.picking_type_id = self.warehouse.int_type_id
        internal_form.location_id = self.warehouse.wh_input_stock_loc_id
        with internal_form.package_level_ids_details.new() as pack_line:
            pack_line.package_id = receipt_package.package_id
        internal_transfer = internal_form.save()

        # Checks the package fields have been correctly set.
        internal_package = internal_transfer.package_level_ids_details[0]
        self.assertEqual(internal_package.location_dest_id.id,
                         internal_transfer.location_dest_id.id)
        internal_transfer.action_assign()
        self.assertEqual(internal_package.location_dest_id.id,
                         internal_transfer.location_dest_id.id)
        self.assertNotEqual(
            internal_package.location_dest_id.id,
            putaway.product_location_ids[0].fixed_location_id.id,
            "The package destination location must be the one from the picking."
        )
        self.assertNotEqual(
            internal_package.move_line_ids[0].location_dest_id.id,
            putaway.product_location_ids[0].fixed_location_id.id,
            "The move line destination location must be the one from the picking."
        )
        self.assertNotEqual(
            internal_package.move_line_ids[1].location_dest_id.id,
            putaway.product_location_ids[0].fixed_location_id.id,
            "The move line destination location must be the one from the picking."
        )
        internal_transfer.button_validate()