[TESTS] mrp and various: updating tests
This commit is contained in:
@@ -2,5 +2,6 @@
|
||||
|
||||
import test_bom
|
||||
import test_order
|
||||
import test_order_process
|
||||
import test_workorder_operation
|
||||
import test_stock
|
||||
import test_workorder_operation
|
||||
import test_procurement
|
||||
+71
-14
@@ -13,7 +13,12 @@ class TestMrpCommon(common2.TestStockCommon):
|
||||
user_group_mrp_user = cls.env.ref('mrp.group_mrp_user')
|
||||
user_group_mrp_manager = cls.env.ref('mrp.group_mrp_manager')
|
||||
|
||||
# User Data: stock user and stock manager
|
||||
# Update demo products
|
||||
(cls.product_2 | cls.product_3 | cls.product_4 | cls.product_5 | cls.product_6 | cls.product_7 | cls.product_8).write({
|
||||
'type': 'product',
|
||||
})
|
||||
|
||||
# User Data: mrp user and mrp manager
|
||||
Users = cls.env['res.users'].with_context({'no_reset_password': True, 'mail_create_nosubscribe': True})
|
||||
cls.user_mrp_user = Users.create({
|
||||
'name': 'Hilda Ferachwal',
|
||||
@@ -28,21 +33,73 @@ class TestMrpCommon(common2.TestStockCommon):
|
||||
'notify_email': 'none',
|
||||
'groups_id': [(6, 0, [user_group_mrp_manager.id])]})
|
||||
|
||||
cls.workcenter_1 = cls.env['mrp.workcenter'].create({
|
||||
'name': 'Nuclear Workcenter',
|
||||
'capacity': 2,
|
||||
'time_start': 10,
|
||||
'time_stop': 5,
|
||||
'time_efficiency': 80,
|
||||
})
|
||||
cls.routing_1 = cls.env['mrp.routing'].create({
|
||||
'name': 'Simple Line',
|
||||
})
|
||||
cls.routing_2 = cls.env['mrp.routing'].create({
|
||||
'name': 'Complicated Line',
|
||||
})
|
||||
cls.operation_1 = cls.env['mrp.routing.workcenter'].create({
|
||||
'name': 'Gift Wrap Maching',
|
||||
'workcenter_id': cls.workcenter_1.id,
|
||||
'routing_id': cls.routing_1.id,
|
||||
'time_cycle': 15,
|
||||
'sequence': 1,
|
||||
})
|
||||
cls.operation_2 = cls.env['mrp.routing.workcenter'].create({
|
||||
'name': 'Cutting Machine',
|
||||
'workcenter_id': cls.workcenter_1.id,
|
||||
'routing_id': cls.routing_2.id,
|
||||
'time_cycle': 12,
|
||||
'sequence': 1,
|
||||
})
|
||||
cls.operation_3 = cls.env['mrp.routing.workcenter'].create({
|
||||
'name': 'Weld Machine',
|
||||
'workcenter_id': cls.workcenter_1.id,
|
||||
'routing_id': cls.routing_2.id,
|
||||
'time_cycle': 18,
|
||||
'sequence': 2,
|
||||
})
|
||||
|
||||
cls.bom_1 = cls.env['mrp.bom'].create({
|
||||
'product_id': cls.product_1.id,
|
||||
'product_tmpl_id': cls.product_1.product_tmpl_id.id,
|
||||
'product_uom_id': cls.product_1.uom_id.id,
|
||||
'product_qty': 1.0,
|
||||
'product_id': cls.product_4.id,
|
||||
'product_tmpl_id': cls.product_4.product_tmpl_id.id,
|
||||
'product_uom_id': cls.uom_unit.id,
|
||||
'product_qty': 4.0,
|
||||
'routing_id': cls.routing_2.id,
|
||||
'type': 'normal',
|
||||
'bom_line_ids': [
|
||||
(0, 0, {'product_id': cls.product_2.id}),
|
||||
(0, 0, {'product_id': cls.product_3.id})
|
||||
(0, 0, {'product_id': cls.product_2.id, 'product_qty': 2}),
|
||||
(0, 0, {'product_id': cls.product_1.id, 'product_qty': 4})
|
||||
]})
|
||||
|
||||
cls.production_1 = cls.env['mrp.production'].create({
|
||||
'name': 'MO-Test',
|
||||
'product_id': cls.product_1.id,
|
||||
cls.bom_2 = cls.env['mrp.bom'].create({
|
||||
'product_id': cls.product_5.id,
|
||||
'product_tmpl_id': cls.product_5.product_tmpl_id.id,
|
||||
'product_uom_id': cls.product_5.uom_id.id,
|
||||
'product_qty': 1.0,
|
||||
'bom_id': cls.bom_1.id,
|
||||
'product_uom_id': cls.product_1.uom_id.id,
|
||||
})
|
||||
'routing_id': cls.routing_1.id,
|
||||
'type': 'phantom',
|
||||
'sequence': 2,
|
||||
'bom_line_ids': [
|
||||
(0, 0, {'product_id': cls.product_4.id, 'product_qty': 2}),
|
||||
(0, 0, {'product_id': cls.product_3.id, 'product_qty': 3})
|
||||
]})
|
||||
cls.bom_3 = cls.env['mrp.bom'].create({
|
||||
'product_id': cls.product_6.id,
|
||||
'product_tmpl_id': cls.product_6.product_tmpl_id.id,
|
||||
'product_uom_id': cls.uom_dozen.id,
|
||||
'product_qty': 2.0,
|
||||
'routing_id': cls.routing_2.id,
|
||||
'type': 'normal',
|
||||
'bom_line_ids': [
|
||||
(0, 0, {'product_id': cls.product_5.id, 'product_qty': 2}),
|
||||
(0, 0, {'product_id': cls.product_4.id, 'product_qty': 8}),
|
||||
(0, 0, {'product_id': cls.product_2.id, 'product_qty': 12})
|
||||
]})
|
||||
|
||||
+125
-22
@@ -1,34 +1,137 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import exceptions
|
||||
from odoo.addons.mrp.tests.common import TestMrpCommon
|
||||
|
||||
|
||||
class TestBoM(TestMrpCommon):
|
||||
|
||||
def test_basic(self):
|
||||
# make the production order
|
||||
production = self.production_1
|
||||
def test_explode(self):
|
||||
boms, lines = self.bom_1.explode(self.product_4, 3)
|
||||
self.assertEqual(set([bom[0].id for bom in boms]), set(self.bom_1.ids))
|
||||
self.assertEqual(set([line[0].id for line in lines]), set(self.bom_1.bom_line_ids.ids))
|
||||
|
||||
# # compute production order data
|
||||
# production.action_compute()
|
||||
boms, lines = self.bom_3.explode(self.product_6, 3)
|
||||
self.assertEqual(set([bom[0].id for bom in boms]), set((self.bom_2 | self.bom_3).ids))
|
||||
self.assertEqual(
|
||||
set([line[0].id for line in lines]),
|
||||
set((self.bom_2 | self.bom_3).mapped('bom_line_ids').filtered(lambda line: not line.child_bom_id or line.child_bom_id.type != 'phantom').ids))
|
||||
|
||||
# # confirm production
|
||||
# production.signal_workflow('button_confirm')
|
||||
self.assertEqual(production.state, 'confirmed')
|
||||
|
||||
# reserve product
|
||||
# production.force_production()
|
||||
|
||||
# produce product
|
||||
produce_wizard = self.env['mrp.product.produce'].with_context({
|
||||
'active_id': production.id,
|
||||
'active_ids': [production.id],
|
||||
}).create({
|
||||
'product_qty': 1.0,
|
||||
def test_variants(self):
|
||||
test_bom = self.env['mrp.bom'].create({
|
||||
'product_id': self.product_7.id,
|
||||
'product_tmpl_id': self.product_7.product_tmpl_id.id,
|
||||
'product_uom_id': self.uom_unit.id,
|
||||
'product_qty': 4.0,
|
||||
'routing_id': self.routing_2.id,
|
||||
'type': 'normal',
|
||||
})
|
||||
# produce_wizard.on_change_qty()
|
||||
produce_wizard.do_produce()
|
||||
test_bom_l1 = self.env['mrp.bom.line'].create({
|
||||
'bom_id': test_bom.id,
|
||||
'product_id': self.product_2.id,
|
||||
'product_qty': 2,
|
||||
})
|
||||
test_bom_l2 = self.env['mrp.bom.line'].create({
|
||||
'bom_id': test_bom.id,
|
||||
'product_id': self.product_3.id,
|
||||
'product_qty': 2,
|
||||
'attribute_value_ids': [(4, self.prod_attr1_v1.id)],
|
||||
})
|
||||
test_bom_l3 = self.env['mrp.bom.line'].create({
|
||||
'bom_id': test_bom.id,
|
||||
'product_id': self.product_4.id,
|
||||
'product_qty': 2,
|
||||
'attribute_value_ids': [(4, self.prod_attr1_v2.id)],
|
||||
})
|
||||
boms, lines = test_bom.explode(self.product_7, 4)
|
||||
self.assertIn(test_bom, [b[0]for b in boms])
|
||||
self.assertIn(test_bom_l1, [l[0] for l in lines])
|
||||
self.assertNotIn(test_bom_l2, [l[0] for l in lines])
|
||||
self.assertNotIn(test_bom_l3, [l[0] for l in lines])
|
||||
|
||||
# check production
|
||||
# self.assertEqual(production.state, 'done')
|
||||
boms, lines = test_bom.explode(self.product_7_1, 4)
|
||||
self.assertIn(test_bom, [b[0]for b in boms])
|
||||
self.assertIn(test_bom_l1, [l[0] for l in lines])
|
||||
self.assertIn(test_bom_l2, [l[0] for l in lines])
|
||||
self.assertNotIn(test_bom_l3, [l[0] for l in lines])
|
||||
|
||||
boms, lines = test_bom.explode(self.product_7_2, 4)
|
||||
self.assertIn(test_bom, [b[0]for b in boms])
|
||||
self.assertIn(test_bom_l1, [l[0] for l in lines])
|
||||
self.assertNotIn(test_bom_l2, [l[0] for l in lines])
|
||||
self.assertIn(test_bom_l3, [l[0] for l in lines])
|
||||
|
||||
def test_multi_level_variants(self):
|
||||
tmp_picking_type = self.env['stock.picking.type'].create({
|
||||
'name': 'Manufacturing',
|
||||
'code': 'mrp_operation',
|
||||
'sequence_id': self.env['ir.sequence'].search([('code', '=', 'mrp.production')], limit=1).id,
|
||||
})
|
||||
test_bom_1 = self.env['mrp.bom'].create({
|
||||
'product_tmpl_id': self.product_5.product_tmpl_id.id,
|
||||
'product_uom_id': self.product_5.uom_id.id,
|
||||
'product_qty': 1.0,
|
||||
'routing_id': self.routing_1.id,
|
||||
'type': 'phantom'
|
||||
})
|
||||
test_bom_1_l1 = self.env['mrp.bom.line'].create({
|
||||
'bom_id': test_bom_1.id,
|
||||
'product_id': self.product_3.id,
|
||||
'product_qty': 3,
|
||||
})
|
||||
|
||||
test_bom_2 = self.env['mrp.bom'].create({
|
||||
'product_id': self.product_7.id,
|
||||
'product_tmpl_id': self.product_7.product_tmpl_id.id,
|
||||
'product_uom_id': self.uom_unit.id,
|
||||
'product_qty': 4.0,
|
||||
'routing_id': self.routing_2.id,
|
||||
'type': 'normal',
|
||||
})
|
||||
test_bom_2_l1 = self.env['mrp.bom.line'].create({
|
||||
'bom_id': test_bom_2.id,
|
||||
'product_id': self.product_2.id,
|
||||
'product_qty': 2,
|
||||
})
|
||||
test_bom_2_l2 = self.env['mrp.bom.line'].create({
|
||||
'bom_id': test_bom_2.id,
|
||||
'product_id': self.product_5.id,
|
||||
'product_qty': 2,
|
||||
'attribute_value_ids': [(4, self.prod_attr1_v1.id)],
|
||||
})
|
||||
test_bom_2_l3 = self.env['mrp.bom.line'].create({
|
||||
'bom_id': test_bom_2.id,
|
||||
'product_id': self.product_5.id,
|
||||
'product_qty': 2,
|
||||
'attribute_value_ids': [(4, self.prod_attr1_v2.id)],
|
||||
})
|
||||
test_bom_2_l4 = self.env['mrp.bom.line'].create({
|
||||
'bom_id': test_bom_2.id,
|
||||
'product_id': self.product_4.id,
|
||||
'product_qty': 2,
|
||||
})
|
||||
|
||||
# check product > product_tmpl
|
||||
boms, lines = test_bom_2.explode(self.product_7_1, 4)
|
||||
self.assertEqual(set((test_bom_2 | self.bom_2).ids), set([b[0].id for b in boms]))
|
||||
self.assertEqual(set((test_bom_2_l1 | test_bom_2_l4 | self.bom_2.bom_line_ids).ids), set([l[0].id for l in lines]))
|
||||
|
||||
# check sequence priority
|
||||
test_bom_1.write({'sequence': 1})
|
||||
boms, lines = test_bom_2.explode(self.product_7_1, 4)
|
||||
self.assertEqual(set((test_bom_2 | test_bom_1).ids), set([b[0].id for b in boms]))
|
||||
self.assertEqual(set((test_bom_2_l1 | test_bom_2_l4 | test_bom_1.bom_line_ids).ids), set([l[0].id for l in lines]))
|
||||
|
||||
# check with another picking_type
|
||||
test_bom_1.write({'picking_type_id': self.warehouse_1.manu_type_id.id})
|
||||
self.bom_2.write({'picking_type_id': tmp_picking_type.id})
|
||||
test_bom_2.write({'picking_type_id': tmp_picking_type.id})
|
||||
boms, lines = test_bom_2.explode(self.product_7_1, 4)
|
||||
self.assertEqual(set((test_bom_2 | self.bom_2).ids), set([b[0].id for b in boms]))
|
||||
self.assertEqual(set((test_bom_2_l1 | test_bom_2_l4 | self.bom_2.bom_line_ids).ids), set([l[0].id for l in lines]))
|
||||
|
||||
# check recursion
|
||||
test_bom_2_l3.write({'attribute_value_ids': [(6, 0, [self.prod_attr1_v1.id])]})
|
||||
with self.assertRaises(exceptions.UserError):
|
||||
test_bom_2.explode(self.product_7_1, 4)
|
||||
|
||||
+321
-15
@@ -1,27 +1,333 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from odoo.fields import Datetime as Dt
|
||||
from odoo.addons.mrp.tests.common import TestMrpCommon
|
||||
|
||||
|
||||
class TestMrpOrder(TestMrpCommon):
|
||||
|
||||
def test_access_rights_manager(self):
|
||||
production = self.production_1.sudo(self.user_mrp_manager)
|
||||
# production.action_compute()
|
||||
# production.signal_workflow('button_confirm')
|
||||
production.action_cancel()
|
||||
self.assertEqual(production.state, 'cancel')
|
||||
production.unlink()
|
||||
man_order = self.env['mrp.production'].sudo(self.user_mrp_manager).create({
|
||||
'name': 'Stick-0',
|
||||
'product_id': self.product_4.id,
|
||||
'product_uom_id': self.product_4.uom_id.id,
|
||||
'product_qty': 5.0,
|
||||
'bom_id': self.bom_1.id,
|
||||
'location_src_id': self.location_1.id,
|
||||
'location_dest_id': self.warehouse_1.wh_output_stock_loc_id.id,
|
||||
})
|
||||
man_order.action_cancel()
|
||||
self.assertEqual(man_order.state, 'cancel', "Production order should be in cancel state.")
|
||||
man_order.unlink()
|
||||
|
||||
def test_access_rights_user(self):
|
||||
production = self.production_1.sudo(self.user_mrp_user)
|
||||
# production.action_compute()
|
||||
# production.signal_workflow('button_confirm')
|
||||
production.action_cancel()
|
||||
self.assertEqual(production.state, 'cancel')
|
||||
production.unlink()
|
||||
man_order = self.env['mrp.production'].sudo(self.user_mrp_user).create({
|
||||
'name': 'Stick-0',
|
||||
'product_id': self.product_4.id,
|
||||
'product_uom_id': self.product_4.uom_id.id,
|
||||
'product_qty': 5.0,
|
||||
'bom_id': self.bom_1.id,
|
||||
'location_src_id': self.location_1.id,
|
||||
'location_dest_id': self.warehouse_1.wh_output_stock_loc_id.id,
|
||||
})
|
||||
man_order.action_cancel()
|
||||
self.assertEqual(man_order.state, 'cancel', "Production order should be in cancel state.")
|
||||
man_order.unlink()
|
||||
|
||||
def test_flow(self):
|
||||
production = self.production_1.sudo(self.user_mrp_user)
|
||||
# production.action_compute()
|
||||
def test_basic(self):
|
||||
""" Basic order test: no routing (thus no workorders), no lot """
|
||||
inventory = self.env['stock.inventory'].create({
|
||||
'name': 'Initial inventory',
|
||||
'filter': 'partial',
|
||||
'line_ids': [(0, 0, {
|
||||
'product_id': self.product_1.id,
|
||||
'product_uom_id': self.product_1.uom_id.id,
|
||||
'product_qty': 500,
|
||||
'location_id': self.warehouse_1.lot_stock_id.id
|
||||
}), (0, 0, {
|
||||
'product_id': self.product_2.id,
|
||||
'product_uom_id': self.product_2.uom_id.id,
|
||||
'product_qty': 500,
|
||||
'location_id': self.warehouse_1.lot_stock_id.id
|
||||
})]
|
||||
})
|
||||
inventory.action_done()
|
||||
|
||||
test_date_planned = datetime.now() - timedelta(days=1)
|
||||
test_quantity = 2.0
|
||||
self.bom_1.routing_id = False
|
||||
man_order = self.env['mrp.production'].sudo(self.user_mrp_user).create({
|
||||
'name': 'Stick-0',
|
||||
'product_id': self.product_4.id,
|
||||
'product_uom_id': self.product_4.uom_id.id,
|
||||
'product_qty': test_quantity,
|
||||
'bom_id': self.bom_1.id,
|
||||
'date_planned_start': test_date_planned,
|
||||
'location_src_id': self.location_1.id,
|
||||
'location_dest_id': self.warehouse_1.wh_output_stock_loc_id.id,
|
||||
})
|
||||
self.assertEqual(man_order.state, 'confirmed', "Production order should be in confirmed state.")
|
||||
|
||||
# check production move
|
||||
production_move = man_order.move_finished_ids
|
||||
self.assertEqual(production_move.date, Dt.to_string(test_date_planned))
|
||||
self.assertEqual(production_move.product_id, self.product_4)
|
||||
self.assertEqual(production_move.product_uom, man_order.product_uom_id)
|
||||
self.assertEqual(production_move.product_qty, man_order.product_qty)
|
||||
self.assertEqual(production_move.location_id, self.product_4.property_stock_production)
|
||||
self.assertEqual(production_move.location_dest_id, man_order.location_dest_id)
|
||||
|
||||
# check consumption moves
|
||||
for move in man_order.move_raw_ids:
|
||||
self.assertEqual(move.date, Dt.to_string(test_date_planned))
|
||||
first_move = man_order.move_raw_ids.filtered(lambda move: move.product_id == self.product_2)
|
||||
self.assertEqual(first_move.product_qty, test_quantity / self.bom_1.product_qty * self.product_4.uom_id.factor_inv * 2)
|
||||
first_move = man_order.move_raw_ids.filtered(lambda move: move.product_id == self.product_1)
|
||||
self.assertEqual(first_move.product_qty, test_quantity / self.bom_1.product_qty * self.product_4.uom_id.factor_inv * 4)
|
||||
|
||||
# waste some material, create a scrap
|
||||
# scrap = self.env['stock.scrap'].with_context(
|
||||
# active_model='mrp.production', active_id=man_order.id
|
||||
# ).create({})
|
||||
# scrap = self.env['stock.scrap'].create({
|
||||
# 'production_id': man_order.id,
|
||||
# 'product_id': first_move.product_id.id,
|
||||
# 'product_uom_id': first_move.product_uom.id,
|
||||
# 'scrap_qty': 5.0,
|
||||
# })
|
||||
# check created scrap
|
||||
|
||||
|
||||
# procurements = self.env['procurement.order'].search([('move_dest_id', 'in', man_order.move_raw_ids.ids)])
|
||||
# print procurements
|
||||
# procurements = self.env['procurement.order'].search([('production_id', '=', man_order.id)])
|
||||
# print procurements
|
||||
# for proc in self.env['procurement.order'].browse(procurements):
|
||||
# date_planned = self.mrp_production_test1.date_planned
|
||||
# if proc.product_id.type not in ('product', 'consu'):
|
||||
# continue
|
||||
# if proc.product_id.id == order_line.product_id.id:
|
||||
# self.assertEqual(proc.date_planned, date_planned, "Planned date does not correspond")
|
||||
# # procurement state should be `confirmed` at this stage, except if procurement_jit is installed, in which
|
||||
# # case it could already be in `running` or `exception` state (not enough stock)
|
||||
# expected_states = ('confirmed', 'running', 'exception')
|
||||
# self.assertEqual(proc.state in expected_states, 'Procurement state is `%s` for %s, expected one of %s' % (proc.state, proc.product_id.name, expected_states))
|
||||
|
||||
# Change production quantity
|
||||
qty_wizard = self.env['change.production.qty'].create({
|
||||
'mo_id': man_order.id,
|
||||
'product_qty': 3.0,
|
||||
})
|
||||
# qty_wizard.change_prod_qty()
|
||||
|
||||
# # I check qty after changed in production order.
|
||||
# #self.assertEqual(self.mrp_production_test1.product_qty, 3, "Qty is not changed in order.")
|
||||
# move = self.mrp_production_test1.move_finished_ids[0]
|
||||
# self.assertEqual(move.product_qty, self.mrp_production_test1.product_qty, "Qty is not changed in move line.")
|
||||
|
||||
# # I run scheduler.
|
||||
# self.env['procurement.order'].run_scheduler()
|
||||
|
||||
# # The production order is Waiting Goods, will force production which should set consume lines as available
|
||||
# self.mrp_production_test1.button_plan()
|
||||
# # I check that production order in ready state after forcing production.
|
||||
|
||||
# #self.assertEqual(self.mrp_production_test1.availability, 'assigned', 'Production order availability should be set as available')
|
||||
|
||||
# produce product
|
||||
produce_wizard = self.env['mrp.product.produce'].sudo(self.user_mrp_user).with_context({
|
||||
'active_id': man_order.id,
|
||||
'active_ids': [man_order.id],
|
||||
}).create({
|
||||
'product_qty': 1.0,
|
||||
})
|
||||
produce_wizard.do_produce()
|
||||
|
||||
# man_order.button_mark_done()
|
||||
man_order.button_mark_done()
|
||||
self.assertEqual(man_order.state, 'done', "Production order should be in done state.")
|
||||
|
||||
def test_explode_from_order(self):
|
||||
#
|
||||
# bom3 produces 2 Dozen of Doors (p6), aka 24
|
||||
# To produce 24 Units of Doors (p6)
|
||||
# - 2 Units of Tools (p5) -> need 4
|
||||
# - 8 Dozen of Sticks (p4) -> need 16
|
||||
# - 12 Units of Wood (p2) -> need 24
|
||||
# bom2 produces 1 Unit of Sticks (p4)
|
||||
# To produce 1 Unit of Sticks (p4)
|
||||
# - 2 Dozen of Sticks (p4) -> need 8
|
||||
# - 3 Dozen of Stones (p3) -> need 12
|
||||
|
||||
# Update capacity, start time, stop time, and time efficiency.
|
||||
# ------------------------------------------------------------
|
||||
self.workcenter_1.write({'capacity': 1, 'time_start': 0, 'time_stop': 0, 'time_efficiency': 100})
|
||||
|
||||
# Set manual time cycle 20 and 10.
|
||||
# --------------------------------
|
||||
self.operation_1.write({'time_cycle_manual': 20})
|
||||
(self.operation_2 | self.operation_3).write({'time_cycle_manual': 10})
|
||||
|
||||
man_order = self.env['mrp.production'].create({
|
||||
'name': 'MO-Test',
|
||||
'product_id': self.product_6.id,
|
||||
'product_uom_id': self.product_6.uom_id.id,
|
||||
'product_qty': 48,
|
||||
'bom_id': self.bom_3.id,
|
||||
})
|
||||
|
||||
# reset quantities
|
||||
self.env['stock.change.product.qty'].create({
|
||||
'product_id': self.product_1.id,
|
||||
'new_quantity': 0.0,
|
||||
'location_id': self.warehouse_1.lot_stock_id.id,
|
||||
}).change_product_qty()
|
||||
|
||||
(self.product_2 | self.product_4).write({
|
||||
'tracking': 'lot',
|
||||
})
|
||||
# assign consume material
|
||||
man_order.action_assign()
|
||||
self.assertEqual(man_order.availability, 'waiting', "Production order should be in waiting state.")
|
||||
|
||||
# check consume materials of manufacturing order
|
||||
self.assertEqual(len(man_order.move_raw_ids), 4, "Consume material lines are not generated proper.")
|
||||
product_2_consume_moves = man_order.move_raw_ids.filtered(lambda x: x.product_id == self.product_2)
|
||||
product_3_consume_moves = man_order.move_raw_ids.filtered(lambda x: x.product_id == self.product_3)
|
||||
product_4_consume_moves = man_order.move_raw_ids.filtered(lambda x: x.product_id == self.product_4)
|
||||
product_5_consume_moves = man_order.move_raw_ids.filtered(lambda x: x.product_id == self.product_5)
|
||||
consume_qty_2 = product_2_consume_moves.product_uom_qty
|
||||
self.assertEqual(consume_qty_2, 24.0, "Consume material quantity of Wood should be 24 instead of %s" % str(consume_qty_2))
|
||||
consume_qty_3 = product_3_consume_moves.product_uom_qty
|
||||
self.assertEqual(consume_qty_3, 12.0, "Consume material quantity of Stone should be 12 instead of %s" % str(consume_qty_3))
|
||||
self.assertEqual(len(product_4_consume_moves), 2, "Consume move are not generated proper.")
|
||||
for consume_moves in product_4_consume_moves:
|
||||
consume_qty_4 = consume_moves.product_uom_qty
|
||||
self.assertIn(consume_qty_4, [8.0, 16.0], "Consume material quantity of Stick should be 8 or 16 instead of %s" % str(consume_qty_4))
|
||||
self.assertFalse(product_5_consume_moves, "Move should not create for phantom bom")
|
||||
|
||||
# create required lots
|
||||
lot_product_2 = self.env['stock.production.lot'].create({'product_id': self.product_2.id})
|
||||
lot_product_4 = self.env['stock.production.lot'].create({'product_id': self.product_4.id})
|
||||
|
||||
# refuel stock
|
||||
inventory = self.env['stock.inventory'].create({
|
||||
'name': 'Inventory For Product C',
|
||||
'filter': 'partial',
|
||||
'line_ids': [(0, 0, {
|
||||
'product_id': self.product_2.id,
|
||||
'product_uom_id': self.product_2.uom_id.id,
|
||||
'product_qty': 30,
|
||||
'prod_lot_id': lot_product_2.id,
|
||||
'location_id': self.ref('stock.stock_location_14')
|
||||
}), (0, 0, {
|
||||
'product_id': self.product_3.id,
|
||||
'product_uom_id': self.product_3.uom_id.id,
|
||||
'product_qty': 60,
|
||||
'location_id': self.ref('stock.stock_location_14')
|
||||
}), (0, 0, {
|
||||
'product_id': self.product_4.id,
|
||||
'product_uom_id': self.product_4.uom_id.id,
|
||||
'product_qty': 60,
|
||||
'prod_lot_id': lot_product_4.id,
|
||||
'location_id': self.ref('stock.stock_location_14')
|
||||
})]
|
||||
})
|
||||
inventory.prepare_inventory()
|
||||
inventory.action_done()
|
||||
|
||||
# re-assign consume material
|
||||
man_order.action_assign()
|
||||
|
||||
# Check production order status after assign.
|
||||
self.assertEqual(man_order.availability, 'assigned', "Production order should be in assigned state.")
|
||||
# Plan production order.
|
||||
man_order.button_plan()
|
||||
|
||||
# check workorders
|
||||
# - main bom: Door: 2 operations
|
||||
# operation 1: Cutting
|
||||
# operation 2: Welding, waiting for the previous one
|
||||
# - kit bom: Stone Tool: 1 operation
|
||||
# operation 1: Gift Wrapping
|
||||
workorders = man_order.workorder_ids
|
||||
kit_wo = man_order.workorder_ids.filtered(lambda wo: wo.operation_id == self.operation_1)
|
||||
door_wo_1 = man_order.workorder_ids.filtered(lambda wo: wo.operation_id == self.operation_2)
|
||||
door_wo_2 = man_order.workorder_ids.filtered(lambda wo: wo.operation_id == self.operation_3)
|
||||
for workorder in workorders:
|
||||
self.assertEqual(workorder.workcenter_id, self.workcenter_1, "Workcenter does not match.")
|
||||
self.assertEqual(kit_wo.state, 'ready', "Workorder should be in ready state.")
|
||||
self.assertEqual(door_wo_1.state, 'ready', "Workorder should be in ready state.")
|
||||
self.assertEqual(door_wo_2.state, 'pending', "Workorder should be in pending state.")
|
||||
self.assertEqual(kit_wo.duration_expected, 80, "Workorder duration should be 80 instead of %s." % str(kit_wo.duration_expected))
|
||||
self.assertEqual(door_wo_1.duration_expected, 20, "Workorder duration should be 20 instead of %s." % str(door_wo_1.duration_expected))
|
||||
self.assertEqual(door_wo_2.duration_expected, 20, "Workorder duration should be 20 instead of %s." % str(door_wo_2.duration_expected))
|
||||
|
||||
# subbom: kit for stone tools
|
||||
kit_wo.button_start()
|
||||
finished_lot = self.env['stock.production.lot'].create({'product_id': man_order.product_id.id})
|
||||
kit_wo.write({
|
||||
'final_lot_id': finished_lot.id,
|
||||
'qty_producing': 48
|
||||
})
|
||||
kit_wo.record_production()
|
||||
|
||||
self.assertEqual(kit_wo.state, 'done', "Workorder should be in done state.")
|
||||
|
||||
# first operation of main bom
|
||||
finished_lot = self.env['stock.production.lot'].create({'product_id': man_order.product_id.id})
|
||||
door_wo_1.write({
|
||||
'final_lot_id': finished_lot.id,
|
||||
'qty_producing': 48
|
||||
})
|
||||
door_wo_1.record_production()
|
||||
self.assertEqual(door_wo_1.state, 'done', "Workorder should be in done state.")
|
||||
|
||||
# second operation of main bom
|
||||
self.assertEqual(door_wo_2.state, 'ready', "Workorder should be in ready state.")
|
||||
door_wo_2.record_production()
|
||||
self.assertEqual(door_wo_2.state, 'done', "Workorder should be in done state.")
|
||||
|
||||
def test_production_avialability(self):
|
||||
"""
|
||||
Test availability of production order.
|
||||
"""
|
||||
self.bom_3.bom_line_ids.filtered(lambda x: x.product_id == self.product_5).unlink()
|
||||
self.bom_3.bom_line_ids.filtered(lambda x: x.product_id == self.product_4).unlink()
|
||||
|
||||
production_2 = self.env['mrp.production'].create({
|
||||
'name': 'MO-Test001',
|
||||
'product_id': self.product_6.id,
|
||||
'product_qty': 5.0,
|
||||
'bom_id': self.bom_3.id,
|
||||
'product_uom_id': self.product_6.uom_id.id,
|
||||
})
|
||||
production_2.action_assign()
|
||||
|
||||
# check sub product availability state is waiting
|
||||
self.assertEqual(production_2.availability, 'waiting', 'Production order should be availability for waiting state')
|
||||
|
||||
# Update Inventory
|
||||
inventory_wizard = self.env['stock.change.product.qty'].create({
|
||||
'product_id': self.product_2.id,
|
||||
'new_quantity': 2.0,
|
||||
})
|
||||
inventory_wizard.change_product_qty()
|
||||
|
||||
production_2.action_assign()
|
||||
# check sub product availability state is partially available
|
||||
self.assertEqual(production_2.availability, 'partially_available', 'Production order should be availability for partially available state')
|
||||
|
||||
# Update Inventory
|
||||
inventory_wizard = self.env['stock.change.product.qty'].create({
|
||||
'product_id': self.product_2.id,
|
||||
'new_quantity': 5.0,
|
||||
})
|
||||
inventory_wizard.change_product_qty()
|
||||
|
||||
production_2.action_assign()
|
||||
# check sub product availability state is assigned
|
||||
self.assertEqual(production_2.availability, 'assigned', 'Production order should be availability for assigned state')
|
||||
|
||||
@@ -1,140 +0,0 @@
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from openerp.tests import common
|
||||
|
||||
|
||||
class TestOrderProcess(common.TransactionCase):
|
||||
|
||||
def test_00_order_process(self):
|
||||
self.res_users_mrp_manager = self.env.ref('mrp.group_mrp_manager')
|
||||
# self.group_account_user = self.env.ref('account.group_account_user')
|
||||
self.main_company = self.env.ref('base.main_company')
|
||||
self.group_mrp_user = self.env.ref('mrp.group_mrp_user')
|
||||
|
||||
self.res_users_mrp_manager = self.env['res.users'].create({
|
||||
'company_id': self.main_company.id,
|
||||
'name': 'MRP Manager',
|
||||
'login': 'mam',
|
||||
'password': 'mam',
|
||||
'email': 'mrp_manager@yourcompany.com',
|
||||
'groups_id': [(6, 0, [self.res_users_mrp_manager.id])] # self.group_account_user.id
|
||||
})
|
||||
|
||||
# Create a user as 'MRP User'
|
||||
# I added groups for MRP User.
|
||||
self.res_users_mrp_user = self.env['res.users'].create({
|
||||
'company_id': self.main_company.id,
|
||||
'name': 'MRP User',
|
||||
'login': 'mau',
|
||||
'password': 'mau',
|
||||
'email': 'mrp_user@yourcompany.com',
|
||||
'groups_id': [(6, 0, [self.group_mrp_user.id])]
|
||||
})
|
||||
|
||||
self.mrp_production_test1 = self.env['mrp.production'].sudo(self.res_users_mrp_user.id).create({
|
||||
'product_id': self.env.ref('product.product_product_3').id,
|
||||
'product_qty': 5.0,
|
||||
'product_uom_id': self.env.ref('product.product_product_3').uom_id.id,
|
||||
'location_src_id': self.env.ref('stock.stock_location_14').id,
|
||||
'location_dest_id': self.env.ref('stock.stock_location_output').id,
|
||||
'bom_id': self.env.ref('mrp.mrp_bom_kit').id,
|
||||
'routing_id': self.env.ref('mrp.mrp_routing_1').id
|
||||
})
|
||||
|
||||
# I compute the production order.
|
||||
# self.mrp_production_test1.action_compute()
|
||||
|
||||
# I check production lines after compute.
|
||||
# self.assertEqual(len(self.mrp_production_test1.product_lines), 7)
|
||||
|
||||
# Now I check workcenter lines.
|
||||
from openerp.tools import float_compare
|
||||
|
||||
def assert_equals(value1, value2, msg, float_compare=float_compare):
|
||||
assert float_compare(value1, value2, precision_digits=2) == 0, msg
|
||||
# self.assertTrue(len(self.mrp_production_test1.workcenter_lines))
|
||||
|
||||
|
||||
# I check details of Produce Move of Production Order to trace Final Product.
|
||||
|
||||
self.assertEqual(self.mrp_production_test1.state, 'confirmed', "Production order should be confirmed.")
|
||||
self.assertTrue(self.mrp_production_test1.move_finished_ids, "Trace Record is not created for Final Product.")
|
||||
move = self.mrp_production_test1.move_finished_ids[0]
|
||||
source_location_id = self.mrp_production_test1.product_id.property_stock_production.id
|
||||
self.assertEqual(move.date, self.mrp_production_test1.date_planned, "Planned date is not correspond.")
|
||||
self.assertEqual(move.product_id.id, self.mrp_production_test1.product_id.id, "Product does not correspond.")
|
||||
self.assertEqual(move.product_uom.id, self.mrp_production_test1.product_uom_id.id, "UOM does not correspond.")
|
||||
self.assertEqual(move.product_qty, self.mrp_production_test1.product_qty, "Qty does not correspond.")
|
||||
self.assertEqual(move.location_id.id, source_location_id, "Source Location does not correspond.")
|
||||
self.assertEqual(move.location_dest_id.id, self.mrp_production_test1.location_dest_id.id, "Destination Location does not correspond.")
|
||||
routing_loc = None
|
||||
if self.mrp_production_test1.bom_id.routing_id and self.mrp_production_test1.bom_id.routing_id.location_id:
|
||||
routing_loc = self.mrp_production_test1.routing_id.location_id.id
|
||||
date_planned = self.mrp_production_test1.date_planned
|
||||
for move_line in self.mrp_production_test1.move_raw_ids:
|
||||
self.assertEqual(move_line.date, date_planned, "Planned date does not correspond in 'To consume line'.")
|
||||
# I consume raw materials and put one material in scrap location due to waste it.
|
||||
for move in self.mrp_production_test1.move_raw_ids:
|
||||
if move.product_id.id == self.env.ref("product.product_product_6").id:
|
||||
self.env['stock.scrap'].with_context(active_model='mrp.production', active_id=self.mrp_production_test1.id).create({'product_id': move.product_id.id, 'scrap_qty': 5.0, 'product_uom_id': move.product_uom.id})
|
||||
|
||||
# I check procurements have been generated for every consume line
|
||||
|
||||
# order = self.env["mrp.production"].browse(self.env.ref("mrp_production_test1"))
|
||||
move_line_ids = [x.id for x in self.mrp_production_test1.move_raw_ids]
|
||||
procurements = self.env['procurement.order'].search([('move_dest_id', 'in', move_line_ids)])
|
||||
for proc in self.env['procurement.order'].browse(procurements):
|
||||
date_planned = self.mrp_production_test1.date_planned
|
||||
if proc.product_id.type not in ('product', 'consu'):
|
||||
continue
|
||||
if proc.product_id.id == order_line.product_id.id:
|
||||
self.assertEqual(proc.date_planned, date_planned, "Planned date does not correspond")
|
||||
# procurement state should be `confirmed` at this stage, except if procurement_jit is installed, in which
|
||||
# case it could already be in `running` or `exception` state (not enough stock)
|
||||
expected_states = ('confirmed', 'running', 'exception')
|
||||
self.assertEqual(proc.state in expected_states, 'Procurement state is `%s` for %s, expected one of %s' % (proc.state, proc.product_id.name, expected_states))
|
||||
|
||||
# I change production qty with 3 PC Assemble SC349.
|
||||
ctx = dict(self.env.context)
|
||||
ctx.update({'active_id': self.mrp_production_test1.id})
|
||||
|
||||
|
||||
#TODO: fix change production qty
|
||||
#self.mrp_production_qty = self.env['change.production.qty'].with_context(ctx).create({
|
||||
# 'product_qty': 3.0
|
||||
#})
|
||||
|
||||
#self.mrp_production_qty.change_prod_qty()
|
||||
|
||||
# I check qty after changed in production order.
|
||||
#self.assertEqual(self.mrp_production_test1.product_qty, 3, "Qty is not changed in order.")
|
||||
move = self.mrp_production_test1.move_finished_ids[0]
|
||||
self.assertEqual(move.product_qty, self.mrp_production_test1.product_qty, "Qty is not changed in move line.")
|
||||
|
||||
# I run scheduler.
|
||||
self.env['procurement.order'].run_scheduler()
|
||||
|
||||
# The production order is Waiting Goods, will force production which should set consume lines as available
|
||||
self.mrp_production_test1.button_plan()
|
||||
# I check that production order in ready state after forcing production.
|
||||
|
||||
#self.assertEqual(self.mrp_production_test1.availability, 'assigned', 'Production order availability should be set as available')
|
||||
|
||||
# I produce product.
|
||||
ctx.update({'active_id': self.mrp_production_test1.id})
|
||||
|
||||
self.mrp_product_produce1 = self.env['mrp.product.produce'].with_context(ctx).create({})
|
||||
|
||||
qty = self.mrp_product_produce1.product_qty
|
||||
self.mrp_product_produce1.do_produce()
|
||||
|
||||
# I check production order after produced.
|
||||
# self.assertEqual(self.mrp_production_test1.state, 'planned', "Production order should be in planned state.")
|
||||
|
||||
def rounding(f, r):
|
||||
import math
|
||||
if not r:
|
||||
return f
|
||||
return math.ceil(f / r) * r
|
||||
@@ -0,0 +1,107 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.mrp.tests.common import TestMrpCommon
|
||||
|
||||
|
||||
class TestProcurement(TestMrpCommon):
|
||||
|
||||
def test_procurement(self):
|
||||
"""This test case when create production order check procurement is create"""
|
||||
# Update BOM
|
||||
self.bom_3.bom_line_ids.filtered(lambda x: x.product_id == self.product_5).unlink()
|
||||
self.bom_1.bom_line_ids.filtered(lambda x: x.product_id == self.product_1).unlink()
|
||||
|
||||
# Update route
|
||||
self.warehouse = self.env.ref('stock.warehouse0')
|
||||
route_manufacture = self.warehouse.manufacture_pull_id.route_id.id
|
||||
route_mto = self.warehouse.mto_pull_id.route_id.id
|
||||
self.product_4.write({'route_ids': [(6, 0, [route_manufacture, route_mto])]})
|
||||
|
||||
# Create production order
|
||||
# -------------------------
|
||||
# Product6 Unit 24
|
||||
# Product4 8 Dozen
|
||||
# Product2 12 Unit
|
||||
# -----------------------
|
||||
|
||||
production_product_6 = self.env['mrp.production'].create({
|
||||
'name': 'MO/Test-00002',
|
||||
'product_id': self.product_6.id,
|
||||
'product_qty': 24,
|
||||
'bom_id': self.bom_3.id,
|
||||
'product_uom_id': self.product_6.uom_id.id,
|
||||
})
|
||||
production_product_6.action_assign()
|
||||
|
||||
# check production state is Confirmed
|
||||
self.assertEqual(production_product_6.state, 'confirmed', 'Production order should be for Confirmed state')
|
||||
|
||||
# Check procurement for product 4 created or not.
|
||||
procurement = self.env['procurement.order'].search([('group_id', '=', production_product_6.procurement_group_id.id), ('product_id', '=', self.product_4.id)])
|
||||
self.assertTrue(procurement, 'No procurement are created !')
|
||||
self.assertEqual(procurement.state, 'running', 'Procurement order should be in state running')
|
||||
|
||||
produce_product_4 = procurement.production_id
|
||||
# produce product
|
||||
self.assertEqual(produce_product_4.availability, 'waiting', "Consume material not available")
|
||||
|
||||
# Create production order
|
||||
# -------------------------
|
||||
# Product 4 96 Unit
|
||||
# Product2 48 Unit
|
||||
# ---------------------
|
||||
# Update Inventory
|
||||
inventory_wizard = self.env['stock.change.product.qty'].create({
|
||||
'product_id': self.product_2.id,
|
||||
'new_quantity': 48,
|
||||
})
|
||||
inventory_wizard.change_product_qty()
|
||||
produce_product_4.action_assign()
|
||||
self.assertEqual(produce_product_4.product_qty, 8, "Wrong quantity of finish product.")
|
||||
self.assertEqual(produce_product_4.product_uom_id, self.uom_dozen, "Wrong quantity of finish product.")
|
||||
self.assertEqual(produce_product_4.availability, 'assigned', "Consume material not available")
|
||||
|
||||
# produce product4
|
||||
# ---------------
|
||||
|
||||
produce_wizard = self.env['mrp.product.produce'].with_context({
|
||||
'active_id': produce_product_4.id,
|
||||
'active_ids': [produce_product_4.id],
|
||||
}).create({
|
||||
'product_qty': produce_product_4.product_qty,
|
||||
})
|
||||
produce_wizard.do_produce()
|
||||
produce_product_4.post_inventory()
|
||||
# Check procurement and Production state for product 4.
|
||||
produce_product_4.button_mark_done()
|
||||
self.assertEqual(produce_product_4.state, 'done', 'Production order should be in state done')
|
||||
self.assertEqual(procurement.state, 'done', 'Procurement order should be in state done')
|
||||
|
||||
# Produce product 6
|
||||
# ------------------
|
||||
|
||||
# Update Inventory
|
||||
inventory_wizard = self.env['stock.change.product.qty'].create({
|
||||
'product_id': self.product_2.id,
|
||||
'new_quantity': 12,
|
||||
})
|
||||
inventory_wizard.change_product_qty()
|
||||
production_product_6.action_assign()
|
||||
|
||||
# ------------------------------------
|
||||
|
||||
self.assertEqual(production_product_6.availability, 'assigned', "Consume material not available")
|
||||
produce_wizard = self.env['mrp.product.produce'].with_context({
|
||||
'active_id': production_product_6.id,
|
||||
'active_ids': [production_product_6.id],
|
||||
}).create({
|
||||
'product_qty': production_product_6.product_qty,
|
||||
})
|
||||
produce_wizard.do_produce()
|
||||
|
||||
production_product_6.post_inventory()
|
||||
# Check procurement and Production state for product 6.
|
||||
production_product_6.button_mark_done()
|
||||
self.assertEqual(production_product_6.state, 'done', 'Production order should be in state done')
|
||||
self.assertEqual(self.product_6.qty_available, 24, 'Wrong quantity available of finished product.')
|
||||
@@ -0,0 +1,101 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import common
|
||||
from odoo.exceptions import except_orm
|
||||
|
||||
|
||||
class TestWarehouse(common.TestMrpCommon):
|
||||
|
||||
def test_manufacturing_route(self):
|
||||
warehouse_1_stock_manager = self.warehouse_1.sudo(self.user_stock_manager)
|
||||
manu_rule = self.env['procurement.rule'].search([
|
||||
('action', '=', 'manufacture'),
|
||||
('warehouse_id', '=', self.warehouse_1.id)])
|
||||
self.assertEqual(self.warehouse_1.manufacture_pull_id, manu_rule)
|
||||
manu_route = manu_rule.route_id
|
||||
self.assertIn(manu_route, warehouse_1_stock_manager._get_all_routes())
|
||||
warehouse_1_stock_manager.write({
|
||||
'manufacture_to_resupply': False
|
||||
})
|
||||
self.assertFalse(self.warehouse_1.manufacture_pull_id)
|
||||
self.assertFalse(self.warehouse_1.manu_type_id.active)
|
||||
self.assertNotIn(manu_route, warehouse_1_stock_manager._get_all_routes())
|
||||
warehouse_1_stock_manager.write({
|
||||
'manufacture_to_resupply': True
|
||||
})
|
||||
manu_rule = self.env['procurement.rule'].search([
|
||||
('action', '=', 'manufacture'),
|
||||
('warehouse_id', '=', self.warehouse_1.id)])
|
||||
self.assertEqual(self.warehouse_1.manufacture_pull_id, manu_rule)
|
||||
self.assertTrue(self.warehouse_1.manu_type_id.active)
|
||||
self.assertIn(manu_route, warehouse_1_stock_manager._get_all_routes())
|
||||
|
||||
def test_manufacturing_scrap(self):
|
||||
"""
|
||||
Testing to do a scrap of consumed material.
|
||||
"""
|
||||
|
||||
# Update demo products
|
||||
(self.product_4 | self.product_2).write({
|
||||
'tracking': 'lot',
|
||||
})
|
||||
|
||||
# Update Bill Of Material to remove product with phantom bom.
|
||||
self.bom_3.bom_line_ids.filtered(lambda x: x.product_id == self.product_5).unlink()
|
||||
|
||||
# Create Inventory Adjustment For Stick and Stone Tools with lot.
|
||||
lot_product_4 = self.env['stock.production.lot'].create({
|
||||
'name': '0000000000001',
|
||||
'product_id': self.product_4.id,
|
||||
})
|
||||
lot_product_2 = self.env['stock.production.lot'].create({
|
||||
'name': '0000000000002',
|
||||
'product_id': self.product_2.id,
|
||||
})
|
||||
|
||||
stock_inv_product_4 = self.env['stock.inventory'].create({
|
||||
'name': 'Stock Inventory for Stick',
|
||||
'filter': 'product',
|
||||
'product_id': self.product_4.id,
|
||||
'line_ids': [
|
||||
(0, 0, {'product_id': self.product_4.id, 'product_uom_id': self.product_4.uom_id.id, 'product_qty': 8, 'prod_lot_id': lot_product_4.id, 'location_id': self.ref('stock.stock_location_14')}),
|
||||
]})
|
||||
|
||||
stock_inv_product_2 = self.env['stock.inventory'].create({
|
||||
'name': 'Stock Inventory for Stone Tools',
|
||||
'filter': 'product',
|
||||
'product_id': self.product_2.id,
|
||||
'line_ids': [
|
||||
(0, 0, {'product_id': self.product_2.id, 'product_uom_id': self.product_2.uom_id.id, 'product_qty': 12, 'prod_lot_id': lot_product_2.id, 'location_id': self.ref('stock.stock_location_14')})
|
||||
]})
|
||||
(stock_inv_product_4 | stock_inv_product_2).prepare_inventory()
|
||||
(stock_inv_product_4 | stock_inv_product_2).action_done()
|
||||
|
||||
#Create Manufacturing order.
|
||||
production_3 = self.env['mrp.production'].create({
|
||||
'name': 'MO-Test003',
|
||||
'product_id': self.product_6.id,
|
||||
'product_qty': 12,
|
||||
'bom_id': self.bom_3.id,
|
||||
'product_uom_id': self.product_6.uom_id.id,
|
||||
})
|
||||
production_3.action_assign()
|
||||
|
||||
# Check Manufacturing order's availability.
|
||||
self.assertEqual(production_3.availability, 'assigned', "Production order's availability should be Available.")
|
||||
|
||||
location_id = production_3.move_raw_ids.filtered(lambda x: x.state not in ('done', 'cancel')) and production_3.location_src_id.id or production_3.location_dest_id.id,
|
||||
|
||||
# Scrap Product Wood without lot to check assert raise ?.
|
||||
with self.assertRaises(except_orm):
|
||||
self.env['stock.scrap'].with_context(active_model='mrp.production', active_id=production_3.id).create({'product_id': self.product_2.id, 'scrap_qty': 1.0, 'product_uom_id': self.product_2.uom_id.id, 'location_id': location_id, 'production_id': production_3.id})
|
||||
|
||||
# Scrap Product Wood with lot.
|
||||
self.env['stock.scrap'].with_context(active_model='mrp.production', active_id=production_3.id).create({'product_id': self.product_2.id, 'scrap_qty': 1.0, 'product_uom_id': self.product_2.uom_id.id, 'location_id': location_id, 'lot_id': lot_product_2.id, 'production_id': production_3.id})
|
||||
|
||||
#Check scrap move is created for this production order.
|
||||
#TODO: should check with scrap objects link in between
|
||||
|
||||
# scrap_move = production_3.move_raw_ids.filtered(lambda x: x.product_id == self.product_2 and x.scrapped)
|
||||
# self.assertTrue(scrap_move, "There are no any scrap move created for production order.")
|
||||
@@ -6,42 +6,9 @@ class TestWorkOrderProcess(common.TransactionCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestWorkOrderProcess, self).setUp()
|
||||
self.MrpProductProduce = self.env['mrp.product.produce']
|
||||
self.Product = self.env['product.product']
|
||||
self.Lot = self.env['stock.production.lot']
|
||||
self.StockMoveLot = self.env['stock.move.lots']
|
||||
self.MrpBom = self.env['mrp.bom']
|
||||
self.MrpBomLine = self.env['mrp.bom.line']
|
||||
self.Inventory = self.env['stock.inventory']
|
||||
self.InventoryLine = self.env['stock.inventory.line']
|
||||
self.source_location_id = self.ref('stock.stock_location_14')
|
||||
self.warehouse = self.env.ref('stock.warehouse0')
|
||||
|
||||
def create_product(self, name, uom_id, route_ids=None):
|
||||
return self.Product.create({
|
||||
'name': name,
|
||||
'type': 'product',
|
||||
'tracking': 'lot',
|
||||
'uom_id': uom_id,
|
||||
'uom_po_id': uom_id,
|
||||
'route_ids': route_ids})
|
||||
|
||||
def create_bom_lines(self, bom_id, product_id, qty, uom_id):
|
||||
self.MrpBomLine.create({
|
||||
'product_id': product_id,
|
||||
'product_qty': qty,
|
||||
'bom_id': bom_id,
|
||||
'product_uom_id': uom_id})
|
||||
|
||||
def create_inventory_line(self, inventory, product, qty, lot_id=False):
|
||||
self.InventoryLine.create({
|
||||
'inventory_id': inventory.id,
|
||||
'product_id': product.id,
|
||||
'product_uom_id': product.uom_id.id,
|
||||
'product_qty': qty,
|
||||
'prod_lot_id': lot_id,
|
||||
'location_id': self.source_location_id})
|
||||
|
||||
def test_00_workorder_process(self):
|
||||
""" Testing consume quants and produced quants with workorder """
|
||||
dining_table = self.env.ref("mrp.product_product_computer_desk")
|
||||
@@ -53,7 +20,8 @@ class TestWorkOrderProcess(common.TransactionCase):
|
||||
'product_id': dining_table.id,
|
||||
'product_qty': 1.0,
|
||||
'product_uom_id': dining_table.uom_id.id,
|
||||
'bom_id': self.ref("mrp.mrp_bom_desk")})
|
||||
'bom_id': self.ref("mrp.mrp_bom_desk")
|
||||
})
|
||||
|
||||
# Set tracking lot on finish and consume products.
|
||||
dining_table.tracking = 'lot'
|
||||
@@ -62,26 +30,41 @@ class TestWorkOrderProcess(common.TransactionCase):
|
||||
product_bolt.tracking = "lot"
|
||||
|
||||
# Initial inventory of product sheet, lags and bolt
|
||||
lot_sheet = self.Lot.create({'product_id': product_table_sheet.id})
|
||||
lot_leg = self.Lot.create({'product_id': product_table_leg.id})
|
||||
lot_bolt = self.Lot.create({'product_id': product_bolt.id})
|
||||
lot_sheet = self.env['stock.production.lot'].create({'product_id': product_table_sheet.id})
|
||||
lot_leg = self.env['stock.production.lot'].create({'product_id': product_table_leg.id})
|
||||
lot_bolt = self.env['stock.production.lot'].create({'product_id': product_bolt.id})
|
||||
|
||||
# Initialize inventory
|
||||
# --------------------
|
||||
inventory = self.Inventory.create({
|
||||
inventory = self.env['stock.inventory'].create({
|
||||
'name': 'Inventory Product Table',
|
||||
'filter': 'partial'})
|
||||
inventory.prepare_inventory()
|
||||
self.assertFalse(inventory.line_ids, "Inventory line should not created.")
|
||||
self.create_inventory_line(inventory, product_table_sheet, 20, lot_sheet.id)
|
||||
self.create_inventory_line(inventory, product_table_leg, 20, lot_leg.id)
|
||||
self.create_inventory_line(inventory, product_bolt, 20, lot_bolt.id)
|
||||
'filter': 'partial',
|
||||
'line_ids': [(0, 0, {
|
||||
'product_id': product_table_sheet.id,
|
||||
'product_uom_id': product_table_sheet.uom_id.id,
|
||||
'product_qty': 20,
|
||||
'prod_lot_id': lot_sheet.id,
|
||||
'location_id': self.source_location_id
|
||||
}), (0, 0, {
|
||||
'product_id': product_table_leg.id,
|
||||
'product_uom_id': product_table_leg.uom_id.id,
|
||||
'product_qty': 20,
|
||||
'prod_lot_id': lot_leg.id,
|
||||
'location_id': self.source_location_id
|
||||
}), (0, 0, {
|
||||
'product_id': product_bolt.id,
|
||||
'product_uom_id': product_bolt.uom_id.id,
|
||||
'product_qty': 20,
|
||||
'prod_lot_id': lot_bolt.id,
|
||||
'location_id': self.source_location_id
|
||||
})]
|
||||
})
|
||||
inventory.action_done()
|
||||
|
||||
# Create work order
|
||||
production_table.button_plan()
|
||||
# Check Work order created or not
|
||||
self.assertEqual(len(production_table.workorder_ids), 3, "Workorder should be created 3 instead of %s"%(len(production_table.workorder_ids)))
|
||||
self.assertEqual(len(production_table.workorder_ids), 3)
|
||||
|
||||
# ---------------------------------------------------------
|
||||
# Process all workorder and check it state.
|
||||
@@ -89,8 +72,8 @@ class TestWorkOrderProcess(common.TransactionCase):
|
||||
|
||||
workorders = production_table.workorder_ids
|
||||
self.assertEqual(workorders[0].state, 'ready', "First workorder state should be ready.")
|
||||
self.assertEqual(workorders[1].state, 'pending', "Workorder state should be pending.")
|
||||
self.assertEqual(workorders[2].state, 'pending', "Workorder state should be pending.")
|
||||
self.assertEqual(workorders[1].state, 'pending')
|
||||
self.assertEqual(workorders[2].state, 'pending')
|
||||
|
||||
# --------------------------------------------------------------
|
||||
# Process cutting operation...
|
||||
@@ -100,11 +83,11 @@ class TestWorkOrderProcess(common.TransactionCase):
|
||||
workorders[0].write({'final_lot_id': finished_lot.id})
|
||||
workorders[0].button_start()
|
||||
workorders[0].active_move_lot_ids[0].write({'lot_id': lot_sheet.id, 'quantity_done': 1})
|
||||
self.assertEqual(workorders[0].state, 'progress', "First workorder state should be Inprogress.")
|
||||
self.assertEqual(workorders[0].state, 'progress')
|
||||
workorders[0].record_production()
|
||||
self.assertEqual(workorders[0].state, 'done', "Cutting process should be done.")
|
||||
self.assertEqual(workorders[0].state, 'done')
|
||||
move_table_sheet = production_table.move_raw_ids.filtered(lambda x : x.product_id == product_table_sheet)
|
||||
self.assertEqual(move_table_sheet.quantity_done, 1, "Wrong consumed quantity of raw materials.")
|
||||
self.assertEqual(move_table_sheet.quantity_done, 1)
|
||||
|
||||
# --------------------------------------------------------------
|
||||
# Process drilling operation ...
|
||||
@@ -114,8 +97,8 @@ class TestWorkOrderProcess(common.TransactionCase):
|
||||
workorders[1].active_move_lot_ids[0].write({'lot_id': lot_leg.id, 'quantity_done': 4})
|
||||
workorders[1].record_production()
|
||||
move_leg = production_table.move_raw_ids.filtered(lambda x : x.product_id == product_table_leg)
|
||||
self.assertEqual(workorders[1].state, 'done', "Drilling process should be done.")
|
||||
self.assertEqual(move_leg.quantity_done, 4, "Wrong consumed quantity of raw materials.")
|
||||
self.assertEqual(workorders[1].state, 'done')
|
||||
self.assertEqual(move_leg.quantity_done, 4)
|
||||
|
||||
# --------------------------------------------------------------
|
||||
# Process fitting operation ...
|
||||
@@ -128,8 +111,8 @@ class TestWorkOrderProcess(common.TransactionCase):
|
||||
move_lot.write({'lot_id': lot_bolt.id, 'quantity_done': 4})
|
||||
move_table_bolt = production_table.move_raw_ids.filtered(lambda x : x.product_id.id == product_bolt.id)
|
||||
workorders[2].record_production()
|
||||
self.assertEqual(workorders[2].state, 'done', "Fitting process should done.")
|
||||
self.assertEqual(move_table_bolt.quantity_done, 4, "Wrong consumed quantity of raw materials.")
|
||||
self.assertEqual(workorders[2].state, 'done')
|
||||
self.assertEqual(move_table_bolt.quantity_done, 4)
|
||||
|
||||
# -----------------------------------------
|
||||
# Post inventory of manufacturing order
|
||||
@@ -141,20 +124,20 @@ class TestWorkOrderProcess(common.TransactionCase):
|
||||
# ----------------------------------------
|
||||
# Check consume quants and produce quants.
|
||||
# ----------------------------------------
|
||||
self.assertEqual(sum(move_table_sheet.quant_ids.mapped('qty')) , 1, "Wrong quantity of consumed product %s"% move_table_sheet.product_id.name)
|
||||
self.assertEqual(sum(move_leg.quant_ids.mapped('qty')), 4, "Wrong quantity of consumed product %s"% move_leg.product_id.name)
|
||||
self.assertEqual(sum(move_table_bolt.quant_ids.mapped('qty')), 4, "Wrong quantity of consumed product %s"% move_table_bolt.product_id.name)
|
||||
self.assertEqual(sum(move_table_sheet.quant_ids.mapped('qty')), 1, "Wrong quantity of consumed product %s" % move_table_sheet.product_id.name)
|
||||
self.assertEqual(sum(move_leg.quant_ids.mapped('qty')), 4, "Wrong quantity of consumed product %s" % move_leg.product_id.name)
|
||||
self.assertEqual(sum(move_table_bolt.quant_ids.mapped('qty')), 4, "Wrong quantity of consumed product %s" % move_table_bolt.product_id.name)
|
||||
|
||||
consume_quants = move_table_sheet.quant_ids + move_leg.quant_ids + move_table_bolt.quant_ids
|
||||
|
||||
# Check for produced quant correctly linked with consumed quants or not.
|
||||
|
||||
finish_move = production_table.move_finished_ids.filtered(lambda x : x.product_id.id == dining_table.id)
|
||||
finish_move = production_table.move_finished_ids.filtered(lambda x: x.product_id.id == dining_table.id)
|
||||
finished_quant = finish_move.quant_ids[0]
|
||||
for quant in consume_quants:
|
||||
self.assertEqual(len(quant.produced_quant_ids), 1, "Wrong produced quants on consumed quant.")
|
||||
self.assertEqual(quant.produced_quant_ids[0].lot_id.id, finished_lot.id, "Wrong produced quant lot on consumed quant.")
|
||||
self.assertEqual(quant.produced_quant_ids[0].id, finished_quant.id, "Wrong produced quants of consume material.")
|
||||
self.assertEqual(len(quant.produced_quant_ids), 1)
|
||||
self.assertEqual(quant.produced_quant_ids[0].lot_id.id, finished_lot.id)
|
||||
self.assertEqual(quant.produced_quant_ids[0].id, finished_quant.id)
|
||||
|
||||
# ------------------------------------------
|
||||
# Check finished quants with consumed quant.
|
||||
@@ -170,17 +153,35 @@ class TestWorkOrderProcess(common.TransactionCase):
|
||||
|
||||
# Create new product charger and keybord
|
||||
# --------------------------------------
|
||||
product_charger = self.create_product('Charger', unit)
|
||||
product_keybord = self.create_product('Usb Keybord', unit)
|
||||
product_charger = self.env['product.product'].create({
|
||||
'name': 'Charger',
|
||||
'type': 'product',
|
||||
'tracking': 'lot',
|
||||
'uom_id': unit,
|
||||
'uom_po_id': unit})
|
||||
product_keybord = self.env['product.product'].create({
|
||||
'name': 'Usb Keybord',
|
||||
'type': 'product',
|
||||
'tracking': 'lot',
|
||||
'uom_id': unit,
|
||||
'uom_po_id': unit})
|
||||
|
||||
# Create bill of material for customized laptop.
|
||||
|
||||
bom_custom_laptop = self.MrpBom.create({
|
||||
'product_tmpl_id': custom_laptop.product_tmpl_id.id,
|
||||
'product_qty': 10,
|
||||
'product_uom_id': unit})
|
||||
self.create_bom_lines(bom_custom_laptop.id, product_charger.id, 20, unit)
|
||||
self.create_bom_lines(bom_custom_laptop.id, product_keybord.id, 20, unit)
|
||||
bom_custom_laptop = self.env['mrp.bom'].create({
|
||||
'product_tmpl_id': custom_laptop.product_tmpl_id.id,
|
||||
'product_qty': 10,
|
||||
'product_uom_id': unit,
|
||||
'bom_line_ids': [(0, 0, {
|
||||
'product_id': product_charger.id,
|
||||
'product_qty': 20,
|
||||
'product_uom_id': unit
|
||||
}), (0, 0, {
|
||||
'product_id': product_keybord.id,
|
||||
'product_qty': 20,
|
||||
'product_uom_id': unit
|
||||
})]
|
||||
})
|
||||
|
||||
# Create production order for customize laptop.
|
||||
|
||||
@@ -195,34 +196,45 @@ class TestWorkOrderProcess(common.TransactionCase):
|
||||
|
||||
# Check production order status of availablity
|
||||
|
||||
self.assertEqual(mo_custom_laptop.availability, 'waiting', "Production order should be in waiting state.")
|
||||
self.assertEqual(mo_custom_laptop.availability, 'waiting')
|
||||
|
||||
# --------------------------------------------------
|
||||
# Set inventory for rawmaterial charger and keybord
|
||||
# --------------------------------------------------
|
||||
|
||||
lot_charger = self.Lot.create({'product_id': product_charger.id})
|
||||
lot_keybord = self.Lot.create({'product_id': product_keybord.id})
|
||||
lot_charger = self.env['stock.production.lot'].create({'product_id': product_charger.id})
|
||||
lot_keybord = self.env['stock.production.lot'].create({'product_id': product_keybord.id})
|
||||
|
||||
# Initialize Inventory
|
||||
# --------------------
|
||||
inventory = self.Inventory.create({
|
||||
inventory = self.env['stock.inventory'].create({
|
||||
'name': 'Inventory Product Table',
|
||||
'filter': 'partial'})
|
||||
inventory.prepare_inventory()
|
||||
self.assertFalse(inventory.line_ids, "Inventory line should not created.")
|
||||
self.create_inventory_line(inventory, product_charger, 20, lot_charger.id)
|
||||
self.create_inventory_line(inventory, product_keybord, 20, lot_keybord.id)
|
||||
'filter': 'partial',
|
||||
'line_ids': [(0, 0, {
|
||||
'product_id': product_charger.id,
|
||||
'product_uom_id': product_charger.uom_id.id,
|
||||
'product_qty': 20,
|
||||
'prod_lot_id': lot_charger.id,
|
||||
'location_id': self.source_location_id
|
||||
}), (0, 0, {
|
||||
'product_id': product_keybord.id,
|
||||
'product_uom_id': product_keybord.uom_id.id,
|
||||
'product_qty': 20,
|
||||
'prod_lot_id': lot_keybord.id,
|
||||
'location_id': self.source_location_id
|
||||
})]
|
||||
})
|
||||
# inventory.prepare_inventory()
|
||||
inventory.action_done()
|
||||
|
||||
# Check consumed move status
|
||||
mo_custom_laptop.action_assign()
|
||||
self.assertEqual( mo_custom_laptop.availability, 'assigned', "Production order should be in assigned state.")
|
||||
self.assertEqual( mo_custom_laptop.availability, 'assigned')
|
||||
|
||||
# Check current status of raw materials.
|
||||
for move in mo_custom_laptop.move_raw_ids:
|
||||
self.assertEqual(move.product_uom_qty, 20, "Wrong consume quantity of raw material %s"% (move.product_id.name))
|
||||
self.assertEqual(move.quantity_done, 0, "Wrong produced quantity on raw material %s"% (move.product_id.name))
|
||||
self.assertEqual(move.product_uom_qty, 20, "Wrong consume quantity of raw material %s: %s instead of %s" % (move.product_id.name, move.product_uom_qty, 20))
|
||||
self.assertEqual(move.quantity_done, 0, "Wrong produced quantity on raw material %s: %s instead of %s" % (move.product_id.name, move.quantity_done, 0))
|
||||
|
||||
# -----------------
|
||||
# Start production
|
||||
@@ -231,41 +243,41 @@ class TestWorkOrderProcess(common.TransactionCase):
|
||||
# Produce 6 Unit of custom laptop will consume ( 12 Unit of keybord and 12 Unit of charger)
|
||||
|
||||
context = {"active_ids": [mo_custom_laptop.id], "active_id": mo_custom_laptop.id}
|
||||
product_consume = self.MrpProductProduce.with_context(context).create({'product_qty': 6.00})
|
||||
laptop_lot_001 = self.Lot.create({'product_id': custom_laptop.id})
|
||||
product_consume = self.env['mrp.product.produce'].with_context(context).create({'product_qty': 6.00})
|
||||
laptop_lot_001 = self.env['stock.production.lot'].create({'product_id': custom_laptop.id})
|
||||
product_consume.lot_id = laptop_lot_001.id
|
||||
product_consume.consume_line_ids.write({'quantity_done': 12})
|
||||
product_consume.do_produce()
|
||||
|
||||
# Check consumed move after produce 6 quantity of customized laptop.
|
||||
for move in mo_custom_laptop.move_raw_ids:
|
||||
self.assertEqual(move.quantity_done, 12, "Wrong produced quantity on raw material %s"% (move.product_id.name))
|
||||
self.assertEqual(len(mo_custom_laptop.move_raw_ids), 2, "Wrong raw material moves of production order.")
|
||||
self.assertEqual(move.quantity_done, 12, "Wrong produced quantity on raw material %s" % (move.product_id.name))
|
||||
self.assertEqual(len(mo_custom_laptop.move_raw_ids), 2)
|
||||
mo_custom_laptop.post_inventory()
|
||||
self.assertEqual(len(mo_custom_laptop.move_raw_ids), 4, "Wrong raw material moves of production order.")
|
||||
self.assertEqual(len(mo_custom_laptop.move_raw_ids), 4)
|
||||
|
||||
# Check done move and confirmed move quantity.
|
||||
|
||||
charger_done_move = mo_custom_laptop.move_raw_ids.filtered(lambda x : x.product_id.id == product_charger.id and x.state == 'done')
|
||||
keybord_done_move = mo_custom_laptop.move_raw_ids.filtered(lambda x : x.product_id.id == product_keybord.id and x.state == 'done')
|
||||
self.assertEquals(charger_done_move.product_uom_qty, 12, "Wrong consumed raw material charger.")
|
||||
self.assertEquals(keybord_done_move.product_uom_qty, 12, "Wrong consumed raw material keybord")
|
||||
charger_done_move = mo_custom_laptop.move_raw_ids.filtered(lambda x: x.product_id.id == product_charger.id and x.state == 'done')
|
||||
keybord_done_move = mo_custom_laptop.move_raw_ids.filtered(lambda x: x.product_id.id == product_keybord.id and x.state == 'done')
|
||||
self.assertEquals(charger_done_move.product_uom_qty, 12)
|
||||
self.assertEquals(keybord_done_move.product_uom_qty, 12)
|
||||
|
||||
# Produce remaining 4 quantity
|
||||
# ----------------------------
|
||||
|
||||
# Produce 4 Unit of custom laptop will consume ( 8 Unit of keybord and 8 Unit of charger).
|
||||
context = {"active_ids": [mo_custom_laptop.id], "active_id": mo_custom_laptop.id}
|
||||
product_consume = self.MrpProductProduce.with_context(context).create({'product_qty': 4.00})
|
||||
laptop_lot_002 = self.Lot.create({'product_id': custom_laptop.id})
|
||||
product_consume = self.env['mrp.product.produce'].with_context(context).create({'product_qty': 4.00})
|
||||
laptop_lot_002 = self.env['stock.production.lot'].create({'product_id': custom_laptop.id})
|
||||
product_consume.lot_id = laptop_lot_002.id
|
||||
self.assertEquals(len(product_consume.consume_line_ids), 2, "Wrong lots linked with move.")
|
||||
self.assertEquals(len(product_consume.consume_line_ids), 2)
|
||||
product_consume.consume_line_ids.write({'quantity_done': 8})
|
||||
product_consume.do_produce()
|
||||
charger_move = mo_custom_laptop.move_raw_ids.filtered(lambda x : x.product_id.id == product_charger.id and x.state != 'done')
|
||||
keybord_move = mo_custom_laptop.move_raw_ids.filtered(lambda x : x.product_id.id == product_keybord.id and x.state !='done')
|
||||
self.assertEquals(charger_move.quantity_done, 8, "Wrong consumed quantity of %s"% charger_move.product_id.name)
|
||||
self.assertEquals(keybord_move.quantity_done, 8, "Wrong consumed quantity of %s"% keybord_move.product_id.name)
|
||||
charger_move = mo_custom_laptop.move_raw_ids.filtered(lambda x: x.product_id.id == product_charger.id and x.state != 'done')
|
||||
keybord_move = mo_custom_laptop.move_raw_ids.filtered(lambda x: x.product_id.id == product_keybord.id and x.state !='done')
|
||||
self.assertEquals(charger_move.quantity_done, 8, "Wrong consumed quantity of %s" % charger_move.product_id.name)
|
||||
self.assertEquals(keybord_move.quantity_done, 8, "Wrong consumed quantity of %s" % keybord_move.product_id.name)
|
||||
|
||||
# Post Inventory of production order.
|
||||
mo_custom_laptop.post_inventory()
|
||||
@@ -277,8 +289,8 @@ class TestWorkOrderProcess(common.TransactionCase):
|
||||
|
||||
# Finished move quants of production order
|
||||
|
||||
finshed_quant_lot_001 = mo_custom_laptop.move_finished_ids.filtered(lambda x : x.product_id.id == custom_laptop.id and x.product_uom_qty==6).mapped('quant_ids')
|
||||
finshed_quant_lot_002 = mo_custom_laptop.move_finished_ids.filtered(lambda x : x.product_id.id == custom_laptop.id and x.product_uom_qty==4).mapped('quant_ids')
|
||||
finshed_quant_lot_001 = mo_custom_laptop.move_finished_ids.filtered(lambda x: x.product_id.id == custom_laptop.id and x.product_uom_qty==6).mapped('quant_ids')
|
||||
finshed_quant_lot_002 = mo_custom_laptop.move_finished_ids.filtered(lambda x: x.product_id.id == custom_laptop.id and x.product_uom_qty==4).mapped('quant_ids')
|
||||
|
||||
# --------------------------------
|
||||
# Check consume and produce quants
|
||||
@@ -286,34 +298,31 @@ class TestWorkOrderProcess(common.TransactionCase):
|
||||
|
||||
# Check consumed quants of lot1
|
||||
for consume_quant in finshed_quant_lot_001[0].consumed_quant_ids:
|
||||
self.assertEqual(consume_quant.qty, 12, "Wrong quantity of quants of consume quants")
|
||||
self.assertEqual(consume_quant.produced_quant_ids[0].lot_id.id , finshed_quant_lot_001[0].lot_id.id , "Wrong produced quant lot on consume quants")
|
||||
self.assertEqual(consume_quant.produced_quant_ids[0].id , finshed_quant_lot_001[0].id , "Wrong produced quant on consume quants")
|
||||
self.assertEqual(consume_quant.qty, 12)
|
||||
self.assertEqual(consume_quant.produced_quant_ids[0].lot_id.id, finshed_quant_lot_001[0].lot_id.id)
|
||||
self.assertEqual(consume_quant.produced_quant_ids[0].id, finshed_quant_lot_001[0].id)
|
||||
|
||||
self.assertEqual(len(finshed_quant_lot_001[0].consumed_quant_ids), 2, "Wrong consumed quant linked with produced quant for lot %s "%laptop_lot_001.name)
|
||||
self.assertEqual(len(finshed_quant_lot_001[0].consumed_quant_ids), 2, "Wrong consumed quant linked with produced quant for lot %s " % laptop_lot_001.name)
|
||||
|
||||
|
||||
# Check total no of quants linked with produced quants.
|
||||
self.assertEqual(len(finshed_quant_lot_002[0].consumed_quant_ids), 2, "Wrong consumed quant linked with produced quant for lot %s "%laptop_lot_002.name)
|
||||
self.assertEqual(len(finshed_quant_lot_002[0].consumed_quant_ids), 2, "Wrong consumed quant linked with produced quant for lot %s " % laptop_lot_002.name)
|
||||
|
||||
# Check consumed quants of lot2
|
||||
for consume_quant in finshed_quant_lot_002[0].consumed_quant_ids:
|
||||
self.assertEqual(consume_quant.qty, 8, "Wrong quantity of quants of consume quants")
|
||||
self.assertEqual(consume_quant.produced_quant_ids[0].lot_id.id , finshed_quant_lot_002[0].lot_id.id , "Wrong produced quant lot on consume quants")
|
||||
self.assertEqual(consume_quant.produced_quant_ids[0].id , finshed_quant_lot_002[0].id , "Wrong produced quant on consume quants")
|
||||
self.assertEqual(consume_quant.qty, 8)
|
||||
self.assertEqual(consume_quant.produced_quant_ids[0].lot_id.id, finshed_quant_lot_002[0].lot_id.id)
|
||||
self.assertEqual(consume_quant.produced_quant_ids[0].id, finshed_quant_lot_002[0].id)
|
||||
|
||||
# Check total quantity consumed of charger, keybord
|
||||
# --------------------------------------------------
|
||||
charger_quants = mo_custom_laptop.move_raw_ids.filtered(lambda x : x.product_id.id == product_charger.id and x.state == 'done').mapped('quant_ids')
|
||||
keybord_moves = mo_custom_laptop.move_raw_ids.filtered(lambda x : x.product_id.id == product_keybord.id and x.state == 'done').mapped('quant_ids')
|
||||
self.assertEqual(sum(charger_quants.mapped('qty')) , 20 , "Wrong consumed quants quantity of charger.")
|
||||
self.assertEqual(sum(keybord_moves.mapped('qty')) , 20 , "Wrong consumed quants quantity of keybord.")
|
||||
charger_quants = mo_custom_laptop.move_raw_ids.filtered(lambda x: x.product_id.id == product_charger.id and x.state == 'done').mapped('quant_ids')
|
||||
keybord_moves = mo_custom_laptop.move_raw_ids.filtered(lambda x: x.product_id.id == product_keybord.id and x.state == 'done').mapped('quant_ids')
|
||||
self.assertEqual(sum(charger_quants.mapped('qty')), 20)
|
||||
self.assertEqual(sum(keybord_moves.mapped('qty')), 20)
|
||||
|
||||
def test_02_different_uom_on_bomlines(self):
|
||||
""" Testing bill of material with diffrent unit of measure."""
|
||||
|
||||
|
||||
|
||||
route_manufacture = self.warehouse.manufacture_pull_id.route_id.id
|
||||
route_mto = self.warehouse.mto_pull_id.route_id.id
|
||||
unit = self.ref("product.product_uom_unit")
|
||||
@@ -321,9 +330,25 @@ class TestWorkOrderProcess(common.TransactionCase):
|
||||
kg = self.ref("product.product_uom_kgm")
|
||||
gm = self.ref("product.product_uom_gram")
|
||||
# Create Product A, B, C
|
||||
product_A = self.create_product('Product A', dozen, [(6, 0, [route_manufacture, route_mto])])
|
||||
product_B = self.create_product('Product B', dozen)
|
||||
product_C = self.create_product('Product C', kg)
|
||||
product_A = self.env['product.product'].create({
|
||||
'name': 'Product A',
|
||||
'type': 'product',
|
||||
'tracking': 'lot',
|
||||
'uom_id': dozen,
|
||||
'uom_po_id': dozen,
|
||||
'route_ids': [(6, 0, [route_manufacture, route_mto])]})
|
||||
product_B = self.env['product.product'].create({
|
||||
'name': 'Product B',
|
||||
'type': 'product',
|
||||
'tracking': 'lot',
|
||||
'uom_id': dozen,
|
||||
'uom_po_id': dozen})
|
||||
product_C = self.env['product.product'].create({
|
||||
'name': 'Product C',
|
||||
'type': 'product',
|
||||
'tracking': 'lot',
|
||||
'uom_id': kg,
|
||||
'uom_po_id': kg})
|
||||
|
||||
# Bill of materials
|
||||
# -----------------
|
||||
@@ -334,13 +359,20 @@ class TestWorkOrderProcess(common.TransactionCase):
|
||||
# Product C 600 gram
|
||||
# -----------------------------------
|
||||
|
||||
bom_a = self.MrpBom.create({
|
||||
'product_tmpl_id': product_A.product_tmpl_id.id,
|
||||
'product_qty': 2,
|
||||
'product_uom_id': unit})
|
||||
self.create_bom_lines(bom_a.id, product_B.id, 4, unit)
|
||||
self.create_bom_lines(bom_a.id, product_C.id, 600, gm)
|
||||
#create_bom_lines(bom_a.id, product_d.id, 4, self.uom_unit.id, 'make_to_order')
|
||||
bom_a = self.env['mrp.bom'].create({
|
||||
'product_tmpl_id': product_A.product_tmpl_id.id,
|
||||
'product_qty': 2,
|
||||
'product_uom_id': unit,
|
||||
'bom_line_ids': [(0, 0, {
|
||||
'product_id': product_B.id,
|
||||
'product_qty': 4,
|
||||
'product_uom_id': unit
|
||||
}), (0, 0, {
|
||||
'product_id': product_C.id,
|
||||
'product_qty': 600,
|
||||
'product_uom_id': gm
|
||||
})]
|
||||
})
|
||||
|
||||
# Create production order with product A 10 Unit.
|
||||
# -----------------------------------------------
|
||||
@@ -351,30 +383,41 @@ class TestWorkOrderProcess(common.TransactionCase):
|
||||
'product_uom_id': unit,
|
||||
'bom_id': bom_a.id})
|
||||
|
||||
move_product_b = mo_custom_product.move_raw_ids.filtered(lambda x : x.product_id == product_B)
|
||||
move_product_c = mo_custom_product.move_raw_ids.filtered(lambda x : x.product_id == product_C)
|
||||
move_product_b = mo_custom_product.move_raw_ids.filtered(lambda x: x.product_id == product_B)
|
||||
move_product_c = mo_custom_product.move_raw_ids.filtered(lambda x: x.product_id == product_C)
|
||||
|
||||
# Check move correctly created or not.
|
||||
self.assertEqual(move_product_b.product_uom_qty, 20 , "Wrong consume quantity of raw materials.")
|
||||
self.assertEqual(move_product_b.product_uom.id, unit, "Wrong unit of measure in rawmaterial.")
|
||||
self.assertEqual(move_product_c.product_uom_qty, 3000, "Wrong consume quantity of raw materials.")
|
||||
self.assertEqual(move_product_c.product_uom.id, gm, "Wrong unit of measure in rawmaterial.")
|
||||
self.assertEqual(move_product_b.product_uom_qty, 20)
|
||||
self.assertEqual(move_product_b.product_uom.id, unit)
|
||||
self.assertEqual(move_product_c.product_uom_qty, 3000)
|
||||
self.assertEqual(move_product_c.product_uom.id, gm)
|
||||
|
||||
# Lot create for product B and product C
|
||||
# ---------------------------------------
|
||||
lot_a = self.Lot.create({'product_id': product_A.id})
|
||||
lot_b = self.Lot.create({'product_id': product_B.id})
|
||||
lot_c = self.Lot.create({'product_id': product_C.id})
|
||||
lot_a = self.env['stock.production.lot'].create({'product_id': product_A.id})
|
||||
lot_b = self.env['stock.production.lot'].create({'product_id': product_B.id})
|
||||
lot_c = self.env['stock.production.lot'].create({'product_id': product_C.id})
|
||||
|
||||
# Inventory Update
|
||||
# ----------------
|
||||
inventory = self.Inventory.create({
|
||||
inventory = self.env['stock.inventory'].create({
|
||||
'name': 'Inventory Product B and C',
|
||||
'filter': 'partial'})
|
||||
inventory.prepare_inventory()
|
||||
self.assertFalse(inventory.line_ids, "Inventory line should not created.")
|
||||
self.create_inventory_line(inventory, product_B, 3, lot_b.id)
|
||||
self.create_inventory_line(inventory, product_C, 3, lot_c.id)
|
||||
'filter': 'partial',
|
||||
'line_ids': [(0, 0, {
|
||||
'product_id': product_B.id,
|
||||
'product_uom_id': product_B.uom_id.id,
|
||||
'product_qty': 3,
|
||||
'prod_lot_id': lot_b.id,
|
||||
'location_id': self.source_location_id
|
||||
}), (0, 0, {
|
||||
'product_id': product_C.id,
|
||||
'product_uom_id': product_C.uom_id.id,
|
||||
'product_qty': 3,
|
||||
'prod_lot_id': lot_c.id,
|
||||
'location_id': self.source_location_id
|
||||
})]
|
||||
})
|
||||
# inventory.prepare_inventory()
|
||||
inventory.action_done()
|
||||
|
||||
# Start Production ...
|
||||
@@ -382,10 +425,10 @@ class TestWorkOrderProcess(common.TransactionCase):
|
||||
|
||||
mo_custom_product.action_assign()
|
||||
context = {"active_ids": [mo_custom_product.id], "active_id": mo_custom_product.id}
|
||||
product_consume = self.MrpProductProduce.with_context(context).create({'product_qty': 10})
|
||||
# laptop_lot_002 = self.Lot.create({'product_id': custom_laptop.id})
|
||||
product_consume = self.env['mrp.product.produce'].with_context(context).create({'product_qty': 10})
|
||||
# laptop_lot_002 = self.env['stock.production.lot'].create({'product_id': custom_laptop.id})
|
||||
product_consume.lot_id = lot_a.id
|
||||
self.assertEquals(len(product_consume.consume_line_ids), 2, "Wrong move lot linked to produce wizard.")
|
||||
self.assertEquals(len(product_consume.consume_line_ids), 2)
|
||||
product_consume.consume_line_ids.filtered(lambda x : x.product_id == product_C).write({'quantity_done': 3000})
|
||||
product_consume.consume_line_ids.filtered(lambda x : x.product_id == product_B).write({'quantity_done': 20})
|
||||
product_consume.do_produce()
|
||||
@@ -393,8 +436,8 @@ class TestWorkOrderProcess(common.TransactionCase):
|
||||
|
||||
# Check correct quant linked with move or not
|
||||
# -------------------------------------------
|
||||
self.assertEqual(len(move_product_b.quant_ids), 1, "Wrong quants on move of product B")
|
||||
self.assertEqual(len(move_product_c.quant_ids), 1, "Wrong quants on move of product C")
|
||||
self.assertEqual(move_product_b.quant_ids.qty, move_product_b.product_qty , "Wrong quantity on quants of product B")
|
||||
self.assertEqual(move_product_c.quant_ids.qty, 3 , "Wrong quantity on quants of product B")
|
||||
self.assertEqual(move_product_c.quant_ids.product_uom_id.id, kg , "Wrong quantity on quants of product B")
|
||||
self.assertEqual(len(move_product_b.quant_ids), 1)
|
||||
self.assertEqual(len(move_product_c.quant_ids), 1)
|
||||
self.assertEqual(move_product_b.quant_ids.qty, move_product_b.product_qty)
|
||||
self.assertEqual(move_product_c.quant_ids.qty, 3)
|
||||
self.assertEqual(move_product_c.quant_ids.product_uom_id.id, kg)
|
||||
|
||||
@@ -8,52 +8,79 @@ class TestMrpByProduct(common.TransactionCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestMrpByProduct, self).setUp()
|
||||
self.product_28 = self.env.ref('product.product_delivery_02')
|
||||
self.product_33 = self.env.ref('product.product_delivery_01')
|
||||
self.product_uom = self.env.ref('product.product_uom_unit')
|
||||
self.location_src = self.env.ref('stock.stock_location_stock')
|
||||
self.mrp_action = self.env.ref('mrp.menu_mrp_production_action')
|
||||
self.MrpBom = self.env['mrp.bom']
|
||||
self.warehouse = self.env.ref('stock.warehouse0')
|
||||
route_manufacture = self.warehouse.manufacture_pull_id.route_id.id
|
||||
route_mto = self.warehouse.mto_pull_id.route_id.id
|
||||
self.uom_unit_id = self.ref('product.product_uom_unit')
|
||||
def create_product(name, route_ids=[]):
|
||||
return self.env['product.product'].create({
|
||||
'name': name,
|
||||
'type': 'product',
|
||||
'route_ids': route_ids})
|
||||
|
||||
# Create product A, B, C.
|
||||
# --------------------------
|
||||
self.product_a = create_product('Product A', route_ids=[(6, 0, [route_manufacture, route_mto])])
|
||||
self.product_b = create_product('Product B', route_ids=[(6, 0, [route_manufacture, route_mto])])
|
||||
self.product_c_id = create_product('Product C', route_ids=[]).id
|
||||
|
||||
def test_00_mrp_byproduct(self):
|
||||
# I add a sub product in Bill of material for product External Hard Disk.
|
||||
bom_hardisk = self.env['mrp.bom'].create({'product_tmpl_id': self.product_28.product_tmpl_id.id,
|
||||
'product_uom_id': self.product_uom.id,
|
||||
'sub_products': [(0, 0, {'product_id': self.product_33.id,
|
||||
'product_uom_id': self.product_uom.id,
|
||||
'product_qty': 2.0})]})
|
||||
# I create a production order for External Hard Disk
|
||||
mnf_hardisk = self.env['mrp.production'].create({'product_id': self.product_28.id,
|
||||
'product_qty': 2.0,
|
||||
'product_uom_id': self.product_uom.id,
|
||||
'bom_id': bom_hardisk.id,
|
||||
'location_src_id': self.location_src.id})
|
||||
""" Test by product with production order."""
|
||||
# Create BOM for product B
|
||||
# ------------------------
|
||||
bom_product_b = 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 BOM for product A and set byproduct product B
|
||||
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_c_id, 'product_uom_id': self.uom_unit_id, 'product_qty': 2})],
|
||||
'sub_products': [(0, 0, {'product_id': self.product_b.id, 'product_uom_id': self.uom_unit_id, 'product_qty': 1})]
|
||||
})
|
||||
|
||||
# Create production order for product A
|
||||
# -------------------------------------
|
||||
|
||||
mnf_product_a = self.env['mrp.production'].create({
|
||||
'product_id': self.product_a.id,
|
||||
'product_qty': 2.0,
|
||||
'product_uom_id': self.uom_unit_id,
|
||||
'bom_id': bom_product_a.id,
|
||||
})
|
||||
|
||||
# I compute the data of production order
|
||||
context = {"active_ids": [mnf_hardisk.id], "active_id": mnf_hardisk.id}
|
||||
# mnf_hardisk.with_context(context).action_compute()
|
||||
context = {"active_model": "mrp.production", "active_ids": [mnf_product_a.id], "active_id": mnf_product_a.id}
|
||||
|
||||
# I confirm the production order.
|
||||
# mnf_hardisk.signal_workflow('button_confirm')
|
||||
|
||||
# I confirm the production order.
|
||||
self.assertEqual(mnf_hardisk.state, 'confirmed', 'Production order should be in state confirmed')
|
||||
self.assertEqual(mnf_product_a.state, 'confirmed', 'Production order should be in state confirmed')
|
||||
|
||||
# Now I check the stock moves for the byproduct I created in the bill of material.
|
||||
# This move is created automatically when I confirmed the production order.
|
||||
moves = self.env['stock.move'].search([('product_id', '=', self.product_33.id)])
|
||||
moves = mnf_product_a.move_raw_ids | mnf_product_a.move_finished_ids
|
||||
self.assertTrue(moves, 'No moves are created !')
|
||||
|
||||
# I consume and produce the production of products.
|
||||
# I create record for selecting mode and quantity of products to produce.
|
||||
product_consume = self.env['mrp.product.produce'].with_context(context).create({'product_qty': 2.00})
|
||||
# I finish the production order.
|
||||
context = {"active_model": "mrp.production", "active_ids": [mnf_hardisk.id], "active_id": mnf_hardisk.id}
|
||||
self.assertEqual(len(mnf_product_a.move_raw_ids), 1, "Wrong consume move on production order.")
|
||||
product_consume.do_produce()
|
||||
mnf_hardisk.post_inventory()
|
||||
consume_move_c = mnf_product_a.move_raw_ids
|
||||
by_product_move = mnf_product_a.move_finished_ids.filtered(lambda x: x.product_id.id == self.product_b.id)
|
||||
# Check sub production produced quantity...
|
||||
self.assertEqual(consume_move_c.product_uom_qty, 4, "Wrong consumed quantity of product c.")
|
||||
self.assertEqual(by_product_move.product_uom_qty, 2, "Wrong produced quantity of sub product.")
|
||||
|
||||
mnf_product_a.post_inventory()
|
||||
|
||||
# I see that stock moves of External Hard Disk including Headset USB are done now.
|
||||
#moves = self.Move.search([('origin', '=', mnf_hardisk.name), ('product_id', 'in', [self.product_28.id, self.product_33.id])])
|
||||
#for move in moves:
|
||||
# self.assertEqual(move.state, 'done', 'Moves are not done!')
|
||||
|
||||
|
||||
self.assertFalse(any(move.state != 'done' for move in moves), 'Moves are not done!')
|
||||
|
||||
@@ -17,51 +17,76 @@ class TestProductCommon(common.SavepointCase):
|
||||
|
||||
# Product environment related data
|
||||
Uom = cls.env['product.uom']
|
||||
categ_unit = cls.env.ref('product.product_uom_categ_unit')
|
||||
weight_unit = cls.env.ref('product.product_uom_categ_kgm')
|
||||
cls.uom_unit = Uom.create({
|
||||
'name': 'TestUnit',
|
||||
'category_id': categ_unit.id,
|
||||
'factor_inv': 1.0,
|
||||
'factor': 1.0,
|
||||
'uom_type': 'reference',
|
||||
'rounding': 0.000001})
|
||||
cls.uom_kunit = Uom.create({
|
||||
'name': 'KTestUnit',
|
||||
'category_id': categ_unit.id,
|
||||
'factor_inv': 1000.0,
|
||||
'factor': 0.001,
|
||||
'uom_type': 'bigger',
|
||||
'rounding': 0.001})
|
||||
cls.uom_munit = Uom.create({
|
||||
'name': 'mTestUnit',
|
||||
'category_id': categ_unit.id,
|
||||
'factor_inv': 0.001,
|
||||
'factor': 1000.0,
|
||||
cls.uom_unit = cls.env.ref('product.product_uom_unit')
|
||||
cls.uom_dozen = cls.env.ref('product.product_uom_dozen')
|
||||
cls.uom_dunit = Uom.create({
|
||||
'name': 'DeciUnit',
|
||||
'category_id': cls.uom_unit.category_id.id,
|
||||
'factor_inv': 0.1,
|
||||
'factor': 10.0,
|
||||
'uom_type': 'smaller',
|
||||
'rounding': 0.001})
|
||||
cls.uom_weight = Uom.create({
|
||||
'name': 'TestWeight',
|
||||
'category_id': weight_unit.id,
|
||||
'factor_inv': 1.0,
|
||||
'factor': 1.0,
|
||||
'uom_type': 'reference',
|
||||
'rounding': 0.000001
|
||||
})
|
||||
cls.uom_weight = cls.env.ref('product.product_uom_kgm')
|
||||
Product = cls.env['product.product']
|
||||
cls.product_1 = Product.create({
|
||||
'name': 'TestProduct 1',
|
||||
cls.product_0 = Product.create({
|
||||
'name': 'Work',
|
||||
'type': 'service',
|
||||
'uom_id': cls.uom_unit.id,
|
||||
'uom_po_id': cls.uom_unit.id})
|
||||
cls.product_1 = Product.create({
|
||||
'name': 'Courage',
|
||||
'type': 'consu',
|
||||
'uom_id': cls.uom_dunit.id,
|
||||
'uom_po_id': cls.uom_dunit.id})
|
||||
|
||||
cls.product_2 = Product.create({
|
||||
'name': 'TestProduct 2',
|
||||
'name': 'Wood',
|
||||
'uom_id': cls.uom_unit.id,
|
||||
'uom_po_id': cls.uom_unit.id})
|
||||
cls.product_3 = Product.create({
|
||||
'name': 'TestProduct 3 (KTestUnit)',
|
||||
'uom_id': cls.uom_kunit.id,
|
||||
'uom_po_id': cls.uom_kunit.id})
|
||||
'name': 'Stone',
|
||||
'uom_id': cls.uom_dozen.id,
|
||||
'uom_po_id': cls.uom_dozen.id})
|
||||
|
||||
cls.product_4 = Product.create({
|
||||
'name': 'TestProduct 4 (mTestUnit)',
|
||||
'uom_id': cls.uom_munit.id,
|
||||
'uom_po_id': cls.uom_munit.id})
|
||||
'name': 'Stick',
|
||||
'uom_id': cls.uom_dozen.id,
|
||||
'uom_po_id': cls.uom_dozen.id})
|
||||
cls.product_5 = Product.create({
|
||||
'name': 'Stone Tools',
|
||||
'uom_id': cls.uom_unit.id,
|
||||
'uom_po_id': cls.uom_unit.id})
|
||||
|
||||
cls.product_6 = Product.create({
|
||||
'name': 'Door',
|
||||
'uom_id': cls.uom_unit.id,
|
||||
'uom_po_id': cls.uom_unit.id})
|
||||
|
||||
cls.prod_att_1 = cls.env['product.attribute'].create({'name': 'Color'})
|
||||
cls.prod_attr1_v1 = cls.env['product.attribute.value'].create({'name': 'red', 'attribute_id': cls.prod_att_1.id})
|
||||
cls.prod_attr1_v2 = cls.env['product.attribute.value'].create({'name': 'blue', 'attribute_id': cls.prod_att_1.id})
|
||||
|
||||
cls.product_7_template = cls.env['product.template'].create({
|
||||
'name': 'Sofa',
|
||||
'uom_id': cls.uom_unit.id,
|
||||
'uom_po_id': cls.uom_unit.id,
|
||||
'attribute_line_ids': [(0, 0, {
|
||||
'attribute_id': cls.prod_att_1.id,
|
||||
})]
|
||||
})
|
||||
cls.product_7 = Product.create({
|
||||
'product_tmpl_id': cls.product_7_template.id,
|
||||
})
|
||||
cls.product_7_1 = Product.create({
|
||||
'product_tmpl_id': cls.product_7_template.id,
|
||||
'attribute_value_ids': [(6, 0, [cls.prod_attr1_v1.id])],
|
||||
})
|
||||
cls.product_7_2 = Product.create({
|
||||
'product_tmpl_id': cls.product_7_template.id,
|
||||
'attribute_value_ids': [(6, 0, [cls.prod_attr1_v2.id])],
|
||||
})
|
||||
|
||||
cls.product_8 = Product.create({
|
||||
'name': 'House',
|
||||
'uom_id': cls.uom_unit.id,
|
||||
'uom_po_id': cls.uom_unit.id})
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import test_move_explode
|
||||
# from . import test_sale_mrp_flow
|
||||
from . import test_sale_mrp_flow
|
||||
|
||||
@@ -56,24 +56,3 @@ class TestMoveExplode(common.TransactionCase):
|
||||
#self.assertEqual(len(move_ids), len(bom_component_length[0]))
|
||||
# We should have same amount of move as the component in the phatom bom
|
||||
#self.assertEqual(len(move_ids), 5)
|
||||
|
||||
# def test_00_bom_find(self):
|
||||
# """Check that _bom_find searches the bom corresponding to the properties passed or takes the bom with the smallest
|
||||
# sequence."""
|
||||
# bom = self.MrpBom._bom_find(product_tmpl_id=self.template.id, product_id=None, properties=[self.mrp_property.id])
|
||||
# self.assertEqual(bom, self.bom_prop)
|
||||
|
||||
# def test_00_bom_find(self):
|
||||
# """Check that _bom_find searches the bom corresponding to the properties passed or takes the bom with the smallest
|
||||
# sequence."""
|
||||
# res = self.MrpBom._bom_find(product_tmpl=self.template)
|
||||
# self.assertEqual(res.id, self.bom_prop.id)
|
||||
|
||||
|
||||
# def test_00_explode(self):
|
||||
# """Check that explode only takes the lines with the right properties."""
|
||||
# bom = self.bom_prop_line
|
||||
# product = self.product_bom_prop
|
||||
# res = bom.explode_data(product, 1, properties=self.mrp_property)
|
||||
# res = set([p['product_id'] for p in res[0]])
|
||||
# self.assertEqual(res, set([self.product_A.id, self.product_B.id]))
|
||||
|
||||
@@ -340,7 +340,8 @@ class TestSaleMrpFlow(common.TransactionCase):
|
||||
""" Test delivered quantity on SO based on delivered quantity in pickings."""
|
||||
# intial so
|
||||
self.partner = self.env.ref('base.res_partner_1')
|
||||
self.product = self.env.ref('product.product_product_5')
|
||||
self.product = self.env.ref('mrp.product_product_build_kit')
|
||||
self.product.invoice_policy = 'delivery'
|
||||
so_vals = {
|
||||
'partner_id': self.partner.id,
|
||||
'partner_invoice_id': self.partner.id,
|
||||
|
||||
@@ -80,7 +80,8 @@ class TestStockCommon(common.TestProductCommon):
|
||||
'name': 'TestLocation1',
|
||||
'posx': 3,
|
||||
'location_id': cls.warehouse_1.lot_stock_id.id,
|
||||
})
|
||||
})
|
||||
|
||||
# Existing data
|
||||
cls.existing_inventories = cls.env['stock.inventory'].search([])
|
||||
cls.existing_quants = cls.env['stock.quant'].search([])
|
||||
|
||||
@@ -19,7 +19,7 @@ class TestInventory(TestStockCommon):
|
||||
self.assertEqual(len(inventory.line_ids), 1)
|
||||
self.assertEqual(inventory.line_ids.theoretical_qty, 50.0)
|
||||
self.assertEqual(inventory.line_ids.product_id, self.product_1)
|
||||
self.assertEqual(inventory.line_ids.product_uom_id, self.uom_unit)
|
||||
self.assertEqual(inventory.line_ids.product_uom_id, self.product_1.uom_id)
|
||||
|
||||
# Update the line, set to 35
|
||||
inventory.line_ids.write({'product_qty': 35.0})
|
||||
@@ -70,7 +70,7 @@ class TestInventory(TestStockCommon):
|
||||
customer_move = self._create_move(product, self.warehouse_1.lot_stock_id, self.env.ref('stock.stock_location_customers'), product_uom_qty=5)
|
||||
|
||||
# test move values
|
||||
self.assertEqual(customer_move.product_uom, self.uom_kunit)
|
||||
self.assertEqual(customer_move.product_uom, product.uom_id)
|
||||
self.assertEqual(customer_move.location_id, self.warehouse_1.lot_stock_id)
|
||||
self.assertEqual(customer_move.location_dest_id, self.env.ref('stock.stock_location_customers'))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user