[IMP] mrp: raw moves generation in onchange
This commit is contained in:
@@ -157,6 +157,10 @@
|
||||
<field name="bom_id" ref="mrp_bom_manufacture"/>
|
||||
</record>
|
||||
|
||||
<function model="stock.move" name="create">
|
||||
<value model="stock.move" eval="obj().env.ref('mrp.mrp_production_1')._get_moves_raw_values()"/>
|
||||
</function>
|
||||
|
||||
<!-- Table -->
|
||||
|
||||
<record id="product_product_computer_desk" model="product.product">
|
||||
@@ -336,6 +340,10 @@
|
||||
<field name="bom_id" ref="mrp_bom_desk"/>
|
||||
</record>
|
||||
|
||||
<function model="stock.move" name="create">
|
||||
<value model="stock.move" eval="obj().env.ref('mrp.mrp_production_3')._get_moves_raw_values()"/>
|
||||
</function>
|
||||
|
||||
<record id="mrp_bom_table_top" model="mrp.bom">
|
||||
<field name="product_tmpl_id" ref="product_product_computer_desk_head_product_template"/>
|
||||
<field name="product_uom_id" ref="uom.product_uom_unit"/>
|
||||
@@ -612,6 +620,9 @@
|
||||
<field name="bom_id" ref="mrp_bom_laptop_cust"/>
|
||||
</record>
|
||||
|
||||
<function model="stock.move" name="create">
|
||||
<value model="stock.move" eval="obj().env.ref('mrp.mrp_production_laptop_cust')._get_moves_raw_values()"/>
|
||||
</function>
|
||||
|
||||
<!-- Run Scheduler -->
|
||||
<function model="procurement.group" name="run_scheduler"/>
|
||||
|
||||
@@ -52,7 +52,7 @@ class MrpProduction(models.Model):
|
||||
domain=[('type', 'in', ['product', 'consu'])],
|
||||
readonly=True, required=True,
|
||||
states={'draft': [('readonly', False)]})
|
||||
product_tmpl_id = fields.Many2one('product.template', 'Product Template', related='product_id.product_tmpl_id', readonly=True)
|
||||
product_tmpl_id = fields.Many2one('product.template', 'Product Template', related='product_id.product_tmpl_id')
|
||||
product_qty = fields.Float(
|
||||
'Quantity To Produce',
|
||||
default=1.0, digits=dp.get_precision('Product Unit of Measure'),
|
||||
@@ -130,7 +130,7 @@ class MrpProduction(models.Model):
|
||||
|
||||
move_raw_ids = fields.One2many(
|
||||
'stock.move', 'raw_material_production_id', 'Raw Materials', oldname='move_lines',
|
||||
copy=False, states={'done': [('readonly', True)], 'cancel': [('readonly', True)]},
|
||||
copy=True, states={'done': [('readonly', True)], 'cancel': [('readonly', True)]},
|
||||
domain=[('scrapped', '=', False)])
|
||||
move_finished_ids = fields.One2many(
|
||||
'stock.move', 'production_id', 'Finished Products',
|
||||
@@ -371,9 +371,33 @@ class MrpProduction(models.Model):
|
||||
self.product_qty = self.bom_id.product_qty
|
||||
self.product_uom_id = self.bom_id.product_uom_id.id
|
||||
|
||||
@api.onchange('date_planned_start')
|
||||
def _onchange_date_planned_start(self):
|
||||
self.move_raw_ids.update({
|
||||
'date': self.date_planned_start,
|
||||
'date_expected': self.date_planned_start,
|
||||
})
|
||||
|
||||
@api.onchange('bom_id', 'product_id', 'product_qty', 'product_uom_id')
|
||||
def _onchange_move_raw(self):
|
||||
self.move_raw_ids = [(2, move.id) for move in self.move_raw_ids.filtered(lambda m: m.bom_line_id)]
|
||||
if self.bom_id and self.product_qty > 0:
|
||||
moves_raw_values = self._get_moves_raw_values()
|
||||
for move_raw_values in moves_raw_values:
|
||||
self.move_raw_ids += self.env['stock.move'].new(move_raw_values)
|
||||
|
||||
@api.onchange('location_src_id', 'move_raw_ids', 'routing_id')
|
||||
def _onchange_location(self):
|
||||
source_location = self._get_raw_location()
|
||||
self.move_raw_ids.update({
|
||||
'warehouse_id': source_location.get_warehouse().id,
|
||||
'location_id': source_location.id,
|
||||
})
|
||||
|
||||
@api.onchange('picking_type_id')
|
||||
def onchange_picking_type(self):
|
||||
location = self.env.ref('stock.stock_location_stock')
|
||||
self.move_raw_ids.update({'picking_type_id': self.picking_type_id})
|
||||
self.location_src_id = self.picking_type_id.default_location_src_id.id or location.id
|
||||
self.location_dest_id = self.picking_type_id.default_location_dest_id.id or location.id
|
||||
|
||||
@@ -389,11 +413,6 @@ class MrpProduction(models.Model):
|
||||
for production in self:
|
||||
if 'move_raw_ids' in vals and production.state != 'draft':
|
||||
production.move_raw_ids.filtered(lambda m: m.state == 'draft')._action_confirm()
|
||||
# TODO: maybe use update wizard instead
|
||||
if any(field in vals for field in ('bom_id', 'product_qty')) and production.state == 'draft':
|
||||
production.move_raw_ids.filtered(lambda m: m.bom_line_id).unlink()
|
||||
production.move_finished_ids.unlink()
|
||||
production._generate_moves()
|
||||
return res
|
||||
|
||||
@api.model
|
||||
@@ -407,9 +426,7 @@ class MrpProduction(models.Model):
|
||||
values['name'] = self.env['ir.sequence'].next_by_code('mrp.production') or _('New')
|
||||
if not values.get('procurement_group_id'):
|
||||
values['procurement_group_id'] = self.env["procurement.group"].create({'name': values['name']}).id
|
||||
production = super(MrpProduction, self).create(values)
|
||||
production._generate_moves()
|
||||
return production
|
||||
return super(MrpProduction, self).create(values)
|
||||
|
||||
@api.multi
|
||||
def unlink(self):
|
||||
@@ -422,15 +439,6 @@ class MrpProduction(models.Model):
|
||||
self.is_locked = not self.is_locked
|
||||
return True
|
||||
|
||||
@api.multi
|
||||
def _generate_moves(self):
|
||||
for production in self:
|
||||
production._generate_finished_moves()
|
||||
factor = production.product_uom_id._compute_quantity(production.product_qty, production.bom_id.product_uom_id) / production.bom_id.product_qty
|
||||
boms, lines = production.bom_id.explode(production.product_id, factor, picking_type=production.bom_id.picking_type_id)
|
||||
production._generate_raw_moves(lines)
|
||||
return True
|
||||
|
||||
def _generate_finished_moves(self):
|
||||
move = self.env['stock.move'].create({
|
||||
'name': self.name,
|
||||
@@ -452,14 +460,16 @@ class MrpProduction(models.Model):
|
||||
})
|
||||
return move
|
||||
|
||||
def _generate_raw_moves(self, exploded_lines):
|
||||
def _get_moves_raw_values(self):
|
||||
self.ensure_one()
|
||||
moves = self.env['stock.move']
|
||||
for bom_line, line_data in exploded_lines:
|
||||
moves += self._generate_raw_move(bom_line, line_data)
|
||||
moves = []
|
||||
factor = self.product_uom_id._compute_quantity(self.product_qty, self.bom_id.product_uom_id) / self.bom_id.product_qty
|
||||
boms, lines = self.bom_id.explode(self.product_id, factor, picking_type=self.bom_id.picking_type_id)
|
||||
for bom_line, line_data in lines:
|
||||
moves.append(self._get_move_raw_values(bom_line, line_data))
|
||||
return moves
|
||||
|
||||
def _generate_raw_move(self, bom_line, line_data):
|
||||
def _get_move_raw_values(self, bom_line, line_data):
|
||||
quantity = line_data['qty']
|
||||
# alt_op needed for the case when you explode phantom bom and all the lines will be consumed in the operation given by the parent bom line
|
||||
alt_op = line_data['parent_line'] and line_data['parent_line'].operation_id.id or False
|
||||
@@ -486,11 +496,12 @@ class MrpProduction(models.Model):
|
||||
'price_unit': bom_line.product_id.standard_price,
|
||||
'procure_method': 'make_to_stock',
|
||||
'origin': self.name,
|
||||
'state': 'draft',
|
||||
'warehouse_id': source_location.get_warehouse().id,
|
||||
'group_id': self.procurement_group_id.id,
|
||||
'propagate': self.propagate,
|
||||
}
|
||||
return self.env['stock.move'].create(data)
|
||||
return data
|
||||
|
||||
def _get_raw_location(self):
|
||||
if self.routing_id:
|
||||
@@ -537,7 +548,8 @@ class MrpProduction(models.Model):
|
||||
move[0].unlink()
|
||||
return move[0], old_qty, quantity
|
||||
else:
|
||||
move = self._generate_raw_move(bom_line, line_data)
|
||||
move_values = self._get_move_raw_values(bom_line, line_data)
|
||||
move = self.env['stock.move'].create(move_values)
|
||||
return move, 0, quantity
|
||||
|
||||
def _get_ready_to_produce_state(self):
|
||||
@@ -567,9 +579,9 @@ class MrpProduction(models.Model):
|
||||
'group_id': production.procurement_group_id.id,
|
||||
'unit_factor': move_raw.product_uom_qty / production.product_qty
|
||||
})
|
||||
production._generate_finished_moves()
|
||||
production._adjust_procure_method()
|
||||
production.move_raw_ids._action_confirm()
|
||||
production.move_finished_ids._action_confirm()
|
||||
(production.move_raw_ids | production.move_finished_ids)._action_confirm()
|
||||
return True
|
||||
|
||||
@api.multi
|
||||
|
||||
@@ -40,6 +40,7 @@ class StockRule(models.Model):
|
||||
|
||||
# create the MO as SUPERUSER because the current user may not have the rights to do it (mto product launched by a sale for example)
|
||||
production = ProductionSudo.create(self._prepare_mo_vals(product_id, product_qty, product_uom, location_id, name, origin, values, bom))
|
||||
production.move_raw_ids = self.env['stock.move'].create(production._get_moves_raw_values())
|
||||
production.action_confirm()
|
||||
origin_production = values.get('move_dest_ids') and values['move_dest_ids'][0].raw_material_production_id or False
|
||||
orderpoint = values.get('orderpoint_id')
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from odoo.tests import Form
|
||||
from odoo.addons.stock.tests import common2
|
||||
|
||||
|
||||
@@ -37,13 +38,11 @@ class TestMrpCommon(common2.TestStockCommon):
|
||||
(0, 0, {'product_id': product_to_use_2.id, 'product_qty': qty_base_2}),
|
||||
(0, 0, {'product_id': product_to_use_1.id, 'product_qty': qty_base_1})
|
||||
]})
|
||||
mo = self.env['mrp.production'].create({
|
||||
'name': 'MO 1',
|
||||
'product_id': product_to_build.id,
|
||||
'product_uom_id': product_to_build.uom_id.id,
|
||||
'product_qty': qty_final,
|
||||
'bom_id': bom_1.id,
|
||||
})
|
||||
mo_form = Form(self.env['mrp.production'])
|
||||
mo_form.product_id = product_to_build
|
||||
mo_form.bom_id = bom_1
|
||||
mo_form.product_qty = qty_final
|
||||
mo = mo_form.save()
|
||||
mo.action_confirm()
|
||||
return mo, bom_1, product_to_build, product_to_use_1, product_to_use_2
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import exceptions
|
||||
from odoo.tests import Form
|
||||
from odoo.addons.mrp.tests.common import TestMrpCommon
|
||||
from odoo.tests import Form
|
||||
from odoo.tools import float_compare, float_round
|
||||
@@ -202,7 +203,7 @@ class TestBoM(TestMrpCommon):
|
||||
'name': 'Clothes'})
|
||||
|
||||
# Create BOM
|
||||
test_bom = self.env['mrp.bom'].create({
|
||||
self.env['mrp.bom'].create({
|
||||
'product_tmpl_id': product_template.id,
|
||||
'product_qty': 1.0,
|
||||
'type': 'normal',
|
||||
@@ -223,11 +224,10 @@ class TestBoM(TestMrpCommon):
|
||||
for comb in combination.keys():
|
||||
consu_product_ids = combination[comb]
|
||||
product = product_template.product_variant_ids.filtered(lambda x: all(value in comb for value in x.attribute_value_ids))
|
||||
mrp_order = MrpProduction.create({
|
||||
'product_uom_id': product.uom_id.id,
|
||||
'product_id': product.id,
|
||||
'bom_id': test_bom.id,
|
||||
})
|
||||
mrp_order_form = Form(self.env['mrp.production'])
|
||||
mrp_order_form.product_id = product
|
||||
mrp_order = mrp_order_form.save()
|
||||
|
||||
# Check consumed materials in production order.
|
||||
self.assertEqual(mrp_order.move_raw_ids.mapped('product_id').ids, consu_product_ids)
|
||||
|
||||
|
||||
@@ -11,29 +11,25 @@ from odoo.addons.mrp.tests.common import TestMrpCommon
|
||||
class TestMrpOrder(TestMrpCommon):
|
||||
|
||||
def test_access_rights_manager(self):
|
||||
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_form = Form(self.env['mrp.production'].sudo(self.user_mrp_manager))
|
||||
man_order_form.product_id = self.product_4
|
||||
man_order_form.product_qty = 5.0
|
||||
man_order_form.bom_id = self.bom_1
|
||||
man_order_form.location_src_id = self.location_1
|
||||
man_order_form.location_dest_id = self.warehouse_1.wh_output_stock_loc_id
|
||||
man_order = man_order_form.save()
|
||||
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):
|
||||
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_form = Form(self.env['mrp.production'].sudo(self.user_mrp_user))
|
||||
man_order_form.product_id = self.product_4
|
||||
man_order_form.product_qty = 5.0
|
||||
man_order_form.bom_id = self.bom_1
|
||||
man_order_form.location_src_id = self.location_1
|
||||
man_order_form.location_dest_id = self.warehouse_1.wh_output_stock_loc_id
|
||||
man_order = man_order_form.save()
|
||||
man_order.action_cancel()
|
||||
self.assertEqual(man_order.state, 'cancel', "Production order should be in cancel state.")
|
||||
man_order.unlink()
|
||||
@@ -62,16 +58,16 @@ class TestMrpOrder(TestMrpCommon):
|
||||
test_date_planned = Dt.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,
|
||||
})
|
||||
man_order_form = Form(self.env['mrp.production'].sudo(self.user_mrp_user))
|
||||
man_order_form.product_id = self.product_4
|
||||
man_order_form.bom_id = self.bom_1
|
||||
man_order_form.product_uom_id = self.product_4.uom_id
|
||||
man_order_form.product_qty = test_quantity
|
||||
man_order_form.date_planned_start = test_date_planned
|
||||
man_order_form.location_src_id = self.location_1
|
||||
man_order_form.location_dest_id = self.warehouse_1.wh_output_stock_loc_id
|
||||
man_order = man_order_form.save()
|
||||
|
||||
self.assertEqual(man_order.state, 'draft', "Production order should be in draft state.")
|
||||
man_order.action_confirm()
|
||||
self.assertEqual(man_order.state, 'confirmed', "Production order should be in confirmed state.")
|
||||
@@ -176,14 +172,12 @@ class TestMrpOrder(TestMrpCommon):
|
||||
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,
|
||||
})
|
||||
|
||||
man_order_form = Form(self.env['mrp.production'])
|
||||
man_order_form.product_id = self.product_6
|
||||
man_order_form.bom_id = self.bom_3
|
||||
man_order_form.product_qty = 48
|
||||
man_order_form.product_uom_id = self.product_6.uom_id
|
||||
man_order = man_order_form.save()
|
||||
# reset quantities
|
||||
self.product_1.type = "product"
|
||||
self.env['stock.change.product.qty'].create({
|
||||
@@ -307,13 +301,13 @@ class TestMrpOrder(TestMrpCommon):
|
||||
self.bom_3.bom_line_ids.filtered(lambda x: x.product_id == self.product_4).unlink()
|
||||
self.bom_3.ready_to_produce = 'all_available'
|
||||
|
||||
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_form = Form(self.env['mrp.production'])
|
||||
production_form.product_id = self.product_6
|
||||
production_form.bom_id = self.bom_3
|
||||
production_form.product_qty = 5.0
|
||||
production_form.product_uom_id = self.product_6.uom_id
|
||||
production_2 = production_form.save()
|
||||
|
||||
production_2.action_confirm()
|
||||
production_2.action_assign()
|
||||
|
||||
@@ -347,11 +341,11 @@ class TestMrpOrder(TestMrpCommon):
|
||||
routing = self.env['mrp.routing'].create({'name': 'Routing without operations',
|
||||
'location_id': self.warehouse_1.wh_input_stock_loc_id.id,})
|
||||
self.bom_3.routing_id = routing.id
|
||||
production = self.env['mrp.production'].create({'name': 'MO test',
|
||||
'product_id': self.product_6.id,
|
||||
'product_qty': 3,
|
||||
'bom_id': self.bom_3.id,
|
||||
'product_uom_id': self.product_6.uom_id.id,})
|
||||
production_form = Form(self.env['mrp.production'])
|
||||
production_form.product_id = self.product_6
|
||||
production_form.product_qty = 3
|
||||
production_form.product_uom_id = self.product_6.uom_id
|
||||
production = production_form.save()
|
||||
self.assertEqual(production.routing_id.id, False, 'The routing field should be empty on the mo')
|
||||
self.assertEqual(production.move_raw_ids[0].location_id.id, self.warehouse_1.wh_input_stock_loc_id.id, 'Raw moves start location should have altered.')
|
||||
|
||||
@@ -407,12 +401,10 @@ class TestMrpOrder(TestMrpCommon):
|
||||
inventory.action_validate()
|
||||
|
||||
# create a mo for this bom
|
||||
mo_custom_laptop = self.env['mrp.production'].create({
|
||||
'product_id': custom_laptop.id,
|
||||
'product_qty': 2,
|
||||
'product_uom_id': unit,
|
||||
'bom_id': bom_custom_laptop.id
|
||||
})
|
||||
mo_custom_laptop_form = Form(self.env['mrp.production'])
|
||||
mo_custom_laptop_form.product_id = custom_laptop
|
||||
mo_custom_laptop_form.product_qty = 2
|
||||
mo_custom_laptop = mo_custom_laptop_form.save()
|
||||
mo_custom_laptop.action_confirm()
|
||||
mo_custom_laptop.action_assign()
|
||||
self.assertEqual(mo_custom_laptop.reservation_state, 'assigned')
|
||||
@@ -450,11 +442,12 @@ class TestMrpOrder(TestMrpCommon):
|
||||
(0, 0, {'product_id': self.product_2.id, 'product_qty': 2.03}),
|
||||
(0, 0, {'product_id': self.product_8.id, 'product_qty': 4.16})
|
||||
]})
|
||||
production = self.env['mrp.production'].create({'name': 'MO efficiency test',
|
||||
'product_id': self.product_6.id,
|
||||
'product_qty': 20,
|
||||
'bom_id': bom_eff.id,
|
||||
'product_uom_id': self.product_6.uom_id.id,})
|
||||
production_form = Form(self.env['mrp.production'])
|
||||
production_form.product_id = self.product_6
|
||||
production_form.bom_id = bom_eff
|
||||
production_form.product_qty = 20
|
||||
production_form.product_uom_id = self.product_6.uom_id
|
||||
production = production_form.save()
|
||||
production.action_confirm()
|
||||
#Check the production order has the right quantities
|
||||
self.assertEqual(production.move_raw_ids[0].product_qty, 41, 'The quantity should be rounded up')
|
||||
@@ -644,13 +637,12 @@ class TestMrpOrder(TestMrpCommon):
|
||||
|
||||
plastic_laminate.tracking = 'serial'
|
||||
|
||||
mo = self.env['mrp.production'].create({
|
||||
'name': 'Dozen Plastic Laminate',
|
||||
'product_id': plastic_laminate.id,
|
||||
'product_uom_id': dozen.id,
|
||||
'product_qty': 1,
|
||||
'bom_id': bom.id,
|
||||
})
|
||||
mo_form = Form(self.env['mrp.production'])
|
||||
mo_form.product_id = plastic_laminate
|
||||
mo_form.bom_id = bom
|
||||
mo_form.product_uom_id = dozen
|
||||
mo_form.product_qty = 1
|
||||
mo = mo_form.save()
|
||||
|
||||
final_product_lot = self.env['stock.production.lot'].create({
|
||||
'name': 'lot1',
|
||||
|
||||
@@ -26,13 +26,12 @@ class TestProcurement(TestMrpCommon):
|
||||
# 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_form = Form(self.env['mrp.production'])
|
||||
production_form.product_id = self.product_6
|
||||
production_form.bom_id = self.bom_3
|
||||
production_form.product_qty = 24
|
||||
production_form.product_uom_id = self.product_6.uom_id
|
||||
production_product_6 = production_form.save()
|
||||
production_product_6.action_confirm()
|
||||
production_product_6.action_assign()
|
||||
|
||||
@@ -128,11 +127,9 @@ class TestProcurement(TestMrpCommon):
|
||||
|
||||
# create MO, but check it raises error as components are in make to order and not everyone has
|
||||
with self.assertRaises(UserError):
|
||||
production_product_4 = self.env['mrp.production'].create({
|
||||
'name': 'MO/Test-00002',
|
||||
'product_id': self.product_4.id,
|
||||
'product_qty': 1,
|
||||
'bom_id': self.bom_1.id,
|
||||
'product_uom_id': self.product_4.uom_id.id,
|
||||
})
|
||||
production_form = Form(self.env['mrp.production'])
|
||||
production_form.product_id = self.product_4
|
||||
production_form.product_uom_id = self.product_4.uom_id
|
||||
production_form.product_qty = 1
|
||||
production_product_4 = production_form.save()
|
||||
production_product_4.action_confirm()
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
from . import common
|
||||
from odoo.exceptions import except_orm
|
||||
from odoo.tests import Form
|
||||
|
||||
|
||||
class TestWarehouse(common.TestMrpCommon):
|
||||
@@ -74,13 +75,12 @@ class TestWarehouse(common.TestMrpCommon):
|
||||
stock_inv_product_4.action_validate()
|
||||
|
||||
#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_form = Form(self.env['mrp.production'])
|
||||
production_form.product_id = self.product_6
|
||||
production_form.bom_id = self.bom_3
|
||||
production_form.product_qty = 12
|
||||
production_form.product_uom_id = self.product_6.uom_id
|
||||
production_3 = production_form.save()
|
||||
production_3.action_confirm()
|
||||
production_3.action_assign()
|
||||
|
||||
|
||||
@@ -53,14 +53,13 @@ class TestTraceability(TestMrpCommon):
|
||||
(0, 0, {'product_id': consumed_serial.id, 'product_qty': 1}),
|
||||
],
|
||||
})
|
||||
|
||||
mo = self.env['mrp.production'].create({
|
||||
'name': 'MO %s' % finished_product.tracking,
|
||||
'product_id': finished_product.id,
|
||||
'product_uom_id': self.env.ref('uom.product_uom_unit').id,
|
||||
'product_qty': 1,
|
||||
'bom_id': bom.id,
|
||||
})
|
||||
|
||||
mo_form = Form(self.env['mrp.production'])
|
||||
mo_form.product_id = finished_product
|
||||
mo_form.bom_id = bom
|
||||
mo_form.product_uom_id = self.env.ref('uom.product_uom_unit')
|
||||
mo_form.product_qty = 1
|
||||
mo = mo_form.save()
|
||||
mo.action_confirm()
|
||||
mo.action_assign()
|
||||
|
||||
|
||||
@@ -513,13 +513,12 @@ class TestUnbuild(TestMrpCommon):
|
||||
StockQuant._update_available_quantity(component2, self.stock_location, 1)
|
||||
|
||||
# Create mo
|
||||
mo = self.env['mrp.production'].create({
|
||||
'name': 'MO 1',
|
||||
'product_id': finshed_product.id,
|
||||
'product_uom_id': finshed_product.uom_id.id,
|
||||
'product_qty': 1.0,
|
||||
'bom_id': bom.id,
|
||||
})
|
||||
mo_form = Form(self.env['mrp.production'])
|
||||
mo_form.product_id = finshed_product
|
||||
mo_form.bom_id = bom
|
||||
mo_form.product_uom_id = finshed_product.uom_id
|
||||
mo_form.product_qty = 1.0
|
||||
mo = mo_form.save()
|
||||
self.assertEqual(len(mo), 1, 'MO should have been created')
|
||||
mo.action_confirm()
|
||||
mo.action_assign()
|
||||
|
||||
@@ -24,12 +24,12 @@ class TestWorkOrderProcess(common.TransactionCase):
|
||||
self.env['stock.move'].search([('product_id', 'in', [product_bolt.id, product_screw.id])])._do_unreserve()
|
||||
(product_bolt + product_screw).write({'type': 'product'})
|
||||
|
||||
production_table = self.env['mrp.production'].create({
|
||||
'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")
|
||||
})
|
||||
production_table_form = Form(self.env['mrp.production'])
|
||||
production_table_form.product_id = dining_table
|
||||
production_table_form.bom_id = self.env.ref("mrp.mrp_bom_desk")
|
||||
production_table_form.product_qty = 1.0
|
||||
production_table_form.product_uom_id = dining_table.uom_id
|
||||
production_table = production_table_form.save()
|
||||
production_table.action_confirm()
|
||||
|
||||
# Set tracking lot on finish and consume products.
|
||||
@@ -132,14 +132,12 @@ class TestWorkOrderProcess(common.TransactionCase):
|
||||
bom.bom_line_ids.filtered(lambda p: p.product_id == product_table_leg).operation_id = bom.routing_id.operation_ids[1]
|
||||
bom.bom_line_ids.filtered(lambda p: p.product_id == product_bolt).operation_id = bom.routing_id.operation_ids[2]
|
||||
|
||||
production_table = self.env['mrp.production'].create({
|
||||
'product_id': dining_table.id,
|
||||
'product_qty': 2.0,
|
||||
'product_uom_id': dining_table.uom_id.id,
|
||||
'bom_id': bom.id,
|
||||
})
|
||||
production_table.action_confirm()
|
||||
|
||||
production_table_form = Form(self.env['mrp.production'])
|
||||
production_table_form.product_id = dining_table
|
||||
production_table_form.bom_id = bom
|
||||
production_table_form.product_qty = 2.0
|
||||
production_table_form.product_uom_id = dining_table.uom_id
|
||||
production_table = production_table_form.save()
|
||||
# Set tracking lot on finish and consume products.
|
||||
dining_table.tracking = 'lot'
|
||||
product_table_sheet.tracking = 'lot'
|
||||
@@ -279,11 +277,12 @@ class TestWorkOrderProcess(common.TransactionCase):
|
||||
|
||||
# Create production order for customize laptop.
|
||||
|
||||
mo_custom_laptop = self.env['mrp.production'].create({
|
||||
'product_id': custom_laptop.id,
|
||||
'product_qty': 10,
|
||||
'product_uom_id': unit,
|
||||
'bom_id': bom_custom_laptop.id})
|
||||
mo_custom_laptop_form = Form(self.env['mrp.production'])
|
||||
mo_custom_laptop_form.product_id = custom_laptop
|
||||
mo_custom_laptop_form.bom_id = bom_custom_laptop
|
||||
mo_custom_laptop_form.product_qty = 10.0
|
||||
mo_custom_laptop_form.product_uom_id = self.env.ref("uom.product_uom_unit")
|
||||
mo_custom_laptop = mo_custom_laptop_form.save()
|
||||
|
||||
mo_custom_laptop.action_confirm()
|
||||
# Assign component to production order.
|
||||
@@ -453,11 +452,12 @@ class TestWorkOrderProcess(common.TransactionCase):
|
||||
# Create production order with product A 10 Unit.
|
||||
# -----------------------------------------------
|
||||
|
||||
mo_custom_product = self.env['mrp.production'].create({
|
||||
'product_id': product_A.id,
|
||||
'product_qty': 10,
|
||||
'product_uom_id': unit,
|
||||
'bom_id': bom_a.id})
|
||||
mo_custom_product_form = Form(self.env['mrp.production'])
|
||||
mo_custom_product_form.product_id = product_A
|
||||
mo_custom_product_form.bom_id = bom_a
|
||||
mo_custom_product_form.product_qty = 10.0
|
||||
mo_custom_product_form.product_uom_id = self.env.ref("uom.product_uom_unit")
|
||||
mo_custom_product = mo_custom_product_form.save()
|
||||
|
||||
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)
|
||||
@@ -543,12 +543,11 @@ class TestWorkOrderProcess(common.TransactionCase):
|
||||
'routing_id': three_step_routing.id
|
||||
})
|
||||
|
||||
mo_laptop = self.env['mrp.production'].create({
|
||||
'product_id': laptop.id,
|
||||
'product_qty': 3,
|
||||
'product_uom_id': unit.id,
|
||||
'bom_id': bom_laptop.id
|
||||
})
|
||||
mo_laptop_form = Form(self.env['mrp.production'])
|
||||
mo_laptop_form.product_id = laptop
|
||||
mo_laptop_form.bom_id = bom_laptop
|
||||
mo_laptop_form.product_qty = 3
|
||||
mo_laptop = mo_laptop_form.save()
|
||||
|
||||
mo_laptop.action_confirm()
|
||||
mo_laptop.button_plan()
|
||||
|
||||
@@ -119,9 +119,14 @@
|
||||
<field name="name" invisible="1"/>
|
||||
<field name="unit_factor" invisible="1"/>
|
||||
<field name="product_uom" groups="uom.group_uom"/>
|
||||
<field name="date" invisible="1"/>
|
||||
<field name="date_expected" invisible="1"/>
|
||||
<field name="picking_type_id" invisible="1"/>
|
||||
<field name="has_tracking" invisible="1"/>
|
||||
<field name="operation_id" invisible="1"/>
|
||||
<field name="needs_lots" readonly="1" groups="stock.group_production_lot"/>
|
||||
<field name="is_done" invisible="1"/>
|
||||
<field name="bom_line_id" invisible="1"/>
|
||||
<field name="sequence" invisible="1"/>
|
||||
<field name="location_id" invisible="1"/>
|
||||
<field name="warehouse_id" invisible="1"/>
|
||||
|
||||
@@ -35,9 +35,15 @@
|
||||
</div>
|
||||
<field name="is_done" invisible="1"/>
|
||||
<field name="workorder_id" invisible="1"/>
|
||||
<field name="bom_line_id" invisible="1"/>
|
||||
<field name="location_id" invisible="1"/>
|
||||
<field name="location_dest_id" invisible="1"/>
|
||||
<field name="picking_type_id" invisible="1"/>
|
||||
<field name="operation_id" invisible="1"/>
|
||||
<field name="warehouse_id" invisible="1"/>
|
||||
<field name="production_id" invisible="1"/>
|
||||
<field name="date" invisible="1"/>
|
||||
<field name="date_expected" invisible="1"/>
|
||||
<field name="raw_material_production_id" invisible="1"/>
|
||||
<field name="is_locked" invisible="1"/>
|
||||
<field name="name" invisible="1"/>
|
||||
|
||||
@@ -38,11 +38,11 @@ class MrpProduction(models.Model):
|
||||
move._action_confirm()
|
||||
|
||||
@api.multi
|
||||
def _generate_moves(self):
|
||||
def _generate_finished_moves(self):
|
||||
""" Generates moves and work orders
|
||||
@return: Newly generated picking Id.
|
||||
"""
|
||||
res = super(MrpProduction, self)._generate_moves()
|
||||
res = super(MrpProduction, self)._generate_finished_moves()
|
||||
for production in self.filtered(lambda production: production.bom_id):
|
||||
for sub_product in production.bom_id.sub_products:
|
||||
production._create_byproduct_move(sub_product)
|
||||
|
||||
@@ -51,12 +51,11 @@ class TestMrpByProduct(common.TransactionCase):
|
||||
# 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,
|
||||
})
|
||||
mnf_product_a_form = Form(self.env['mrp.production'])
|
||||
mnf_product_a_form.product_id = self.product_a
|
||||
mnf_product_a_form.bom_id = bom_product_a
|
||||
mnf_product_a_form.product_qty = 2.0
|
||||
mnf_product_a = mnf_product_a_form.save()
|
||||
mnf_product_a.action_confirm()
|
||||
|
||||
# I compute the data of production order
|
||||
|
||||
@@ -145,7 +145,7 @@ class StockMove(models.Model):
|
||||
restrict_partner_id = fields.Many2one('res.partner', 'Owner ', help="Technical field used to depict a restriction on the ownership of quants to consider when marking this move as 'done'")
|
||||
route_ids = fields.Many2many('stock.location.route', 'stock_location_route_move', 'move_id', 'route_id', 'Destination route', help="Preferred route")
|
||||
warehouse_id = fields.Many2one('stock.warehouse', 'Warehouse', help="Technical field depicting the warehouse to consider for the route selection on the next procurement (if any).")
|
||||
has_tracking = fields.Selection(related='product_id.tracking', string='Product with Tracking', readonly=False)
|
||||
has_tracking = fields.Selection(related='product_id.tracking', string='Product with Tracking')
|
||||
quantity_done = fields.Float('Quantity Done', compute='_quantity_done_compute', digits=dp.get_precision('Product Unit of Measure'), inverse='_quantity_done_set')
|
||||
show_operations = fields.Boolean(related='picking_id.picking_type_id.show_operations', readonly=False)
|
||||
show_details_visible = fields.Boolean('Details Visible', compute='_compute_show_details_visible')
|
||||
|
||||
Reference in New Issue
Block a user