[MERGE] mrp, mrp_operations: clean yml tests

bzr revid: rco@openerp.com-20111216142324-eep7vg58yccqknwi
This commit is contained in:
Raphael Collet
2011-12-16 15:23:24 +01:00
23 changed files with 1227 additions and 1383 deletions
+3 -7
View File
@@ -92,13 +92,9 @@ Dashboard provided by this module:
'mrp_demo.xml',
],
'test': [
'test/mrp_procurement.yml',
'test/mrp_packs.yml',
'test/mrp_phantom_bom.yml',
'test/mrp_production_order.yml',
'test/mrp_production_cancel.yml',
'test/mrp_report.yml',
'test/order_demo.yml',
'test/order_process.yml',
'test/cancel_order.yml',
],
'installable': True,
'application': True,
+166 -131
View File
@@ -62,8 +62,6 @@ class mrp_workcenter(osv.osv):
}
def on_change_product_cost(self, cr, uid, ids, product_id, context=None):
if context is None:
context = {}
value = {}
if product_id:
@@ -253,8 +251,7 @@ class mrp_bom(osv.osv):
all_prod.append(bom.product_id.id)
lines = bom.bom_lines
if lines:
newboms = [a for a in lines if a not in boms]
res = res and check_bom(newboms)
res = res and check_bom([bom_id for bom_id in lines if bom_id not in boms])
return res
return check_bom(boms)
@@ -269,14 +266,9 @@ class mrp_bom(osv.osv):
@param product_id: Changed product_id
@return: Dictionary of changed values
"""
if context is None:
context = {}
context['lang'] = self.pool.get('res.users').browse(cr,uid,uid).context_lang
if product_id:
prod = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
v = {'name': prod.name, 'product_uom': prod.uom_id.id}
return {'value': v}
return {'value': {'name': prod.name, 'product_uom': prod.uom_id.id}}
return {}
def _bom_find(self, cr, uid, product_id, product_uom, properties=[]):
@@ -320,6 +312,7 @@ class mrp_bom(osv.osv):
phantom = False
if bom.type == 'phantom' and not bom.bom_lines:
newbom = self._bom_find(cr, uid, bom.product_id.id, bom.product_uom.id, properties)
if newbom:
res = self._bom_explode(cr, uid, self.browse(cr, uid, [newbom])[0], factor*bom.product_qty, properties, addthis=True, level=level+10)
result = result + res[0]
@@ -361,8 +354,6 @@ class mrp_bom(osv.osv):
def copy_data(self, cr, uid, id, default=None, context=None):
if default is None:
default = {}
if context is None:
context = {}
bom_data = self.read(cr, uid, id, [], context=context)
default.update({'name': bom_data['name'] + ' ' + _('Copy'), 'bom_id':False})
return super(mrp_bom, self).copy_data(cr, uid, id, default, context=context)
@@ -497,8 +488,7 @@ class mrp_production(osv.osv):
_order = 'priority desc, date_planned asc';
def _check_qty(self, cr, uid, ids, context=None):
orders = self.browse(cr, uid, ids, context=context)
for order in orders:
for order in self.browse(cr, uid, ids, context=context):
if order.product_qty <= 0:
return False
return True
@@ -508,14 +498,10 @@ class mrp_production(osv.osv):
]
def unlink(self, cr, uid, ids, context=None):
productions = self.read(cr, uid, ids, ['state'])
unlink_ids = []
for s in productions:
if s['state'] in ['draft','cancel']:
unlink_ids.append(s['id'])
else:
raise osv.except_osv(_('Invalid action !'), _('Cannot delete a manufacturing order in the state \'%s\'!') % s['state'])
return osv.osv.unlink(self, cr, uid, unlink_ids, context=context)
for production in self.browse(cr, uid, ids, context=context):
if production.state not in ('draft', 'cancel'):
raise osv.except_osv(_('Invalid action !'), _('Cannot delete a manufacturing order in state \'%s\'') % production.state)
return super(mrp_production, self).unlink(cr, uid, ids, context=context)
def copy(self, cr, uid, id, default=None, context=None):
if default is None:
@@ -577,8 +563,7 @@ class mrp_production(osv.osv):
return {'value': {
'routing_id': False
}}
bom_pool = self.pool.get('mrp.bom')
bom_point = bom_pool.browse(cr, uid, bom_id, context=context)
bom_point = self.pool.get('mrp.bom').browse(cr, uid, bom_id, context=context)
routing_id = bom_point.routing_id.id or False
result = {
'routing_id': routing_id
@@ -592,7 +577,7 @@ class mrp_production(osv.osv):
self.write(cr, uid, ids, {'state': 'picking_except'})
return True
def action_compute(self, cr, uid, ids, properties=[]):
def action_compute(self, cr, uid, ids, properties=[], context=None):
""" Computes bills of material of a product.
@param properties: List containing dictionaries of properties.
@return: No. of products.
@@ -747,7 +732,7 @@ class mrp_production(osv.osv):
# if qtys we have to consume is more than qtys available to consume
prod_name = scheduled.product_id.name_get()[0][1]
raise osv.except_osv(_('Warning!'), _('You are going to consume total %s quantities of "%s".\nBut you can consume upto total %s quantities.' % (qty, prod_name, qty_avail)))
if qty < 0.0:
if qty <= 0.0:
# we already have more qtys consumed than we need
continue
@@ -855,119 +840,169 @@ class mrp_production(osv.osv):
def _get_auto_picking(self, cr, uid, production):
return True
def action_confirm(self, cr, uid, ids):
""" Confirms production order.
@return: Newly generated picking Id.
"""
picking_id = False
proc_ids = []
seq_obj = self.pool.get('ir.sequence')
pick_obj = self.pool.get('stock.picking')
move_obj = self.pool.get('stock.move')
proc_obj = self.pool.get('procurement.order')
def _make_production_line_procurement(self, cr, uid, production_line, shipment_move_id, context=None):
wf_service = netsvc.LocalService("workflow")
for production in self.browse(cr, uid, ids):
if not production.product_lines:
self.action_compute(cr, uid, [production.id])
production = self.browse(cr, uid, [production.id])[0]
routing_loc = None
pick_type = 'internal'
address_id = False
if production.bom_id.routing_id and production.bom_id.routing_id.location_id:
routing_loc = production.bom_id.routing_id.location_id
if routing_loc.usage <> 'internal':
pick_type = 'out'
address_id = routing_loc.address_id and routing_loc.address_id.id or False
routing_loc = routing_loc.id
pick_name = seq_obj.get(cr, uid, 'stock.picking.' + pick_type)
picking_id = pick_obj.create(cr, uid, {
'name': pick_name,
'origin': (production.origin or '').split(':')[0] + ':' + production.name,
'type': pick_type,
'move_type': 'one',
'state': 'auto',
'address_id': address_id,
'auto_picking': self._get_auto_picking(cr, uid, production),
'company_id': production.company_id.id,
})
source = production.product_id.product_tmpl_id.property_stock_production.id
data = {
'name':'PROD:' + production.name,
'date': production.date_planned,
'product_id': production.product_id.id,
'product_qty': production.product_qty,
'product_uom': production.product_uom.id,
'product_uos_qty': production.product_uos and production.product_uos_qty or False,
'product_uos': production.product_uos and production.product_uos.id or False,
'location_id': source,
'location_dest_id': production.location_dest_id.id,
'move_dest_id': production.move_prod_id.id,
'state': 'waiting',
'company_id': production.company_id.id,
}
res_final_id = move_obj.create(cr, uid, data)
self.write(cr, uid, [production.id], {'move_created_ids': [(6, 0, [res_final_id])]})
moves = []
for line in production.product_lines:
move_id = False
newdate = production.date_planned
if line.product_id.type in ('product', 'consu'):
res_dest_id = move_obj.create(cr, uid, {
'name':'PROD:' + production.name,
'date': production.date_planned,
'product_id': line.product_id.id,
'product_qty': line.product_qty,
'product_uom': line.product_uom.id,
'product_uos_qty': line.product_uos and line.product_uos_qty or False,
'product_uos': line.product_uos and line.product_uos.id or False,
'location_id': routing_loc or production.location_src_id.id,
'location_dest_id': source,
'move_dest_id': res_final_id,
'state': 'waiting',
'company_id': production.company_id.id,
})
moves.append(res_dest_id)
move_id = move_obj.create(cr, uid, {
'name':'PROD:' + production.name,
'picking_id':picking_id,
'product_id': line.product_id.id,
'product_qty': line.product_qty,
'product_uom': line.product_uom.id,
'product_uos_qty': line.product_uos and line.product_uos_qty or False,
'product_uos': line.product_uos and line.product_uos.id or False,
'date': newdate,
'move_dest_id': res_dest_id,
'location_id': production.location_src_id.id,
'location_dest_id': routing_loc or production.location_src_id.id,
'state': 'waiting',
'company_id': production.company_id.id,
})
proc_id = proc_obj.create(cr, uid, {
'name': (production.origin or '').split(':')[0] + ':' + production.name,
'origin': (production.origin or '').split(':')[0] + ':' + production.name,
'date_planned': newdate,
'product_id': line.product_id.id,
'product_qty': line.product_qty,
'product_uom': line.product_uom.id,
'product_uos_qty': line.product_uos and line.product_qty or False,
'product_uos': line.product_uos and line.product_uos.id or False,
'location_id': production.location_src_id.id,
'procure_method': line.product_id.procure_method,
'move_id': move_id,
procurement_order = self.pool.get('procurement.order')
production = production_line.production_id
location_id = production.location_src_id.id
date_planned = production.date_planned
procurement_name = (production.origin or '').split(':')[0] + ':' + production.name
procurement_id = procurement_order.create(cr, uid, {
'name': procurement_name,
'origin': procurement_name,
'date_planned': date_planned,
'product_id': production_line.product_id.id,
'product_qty': production_line.product_qty,
'product_uom': production_line.product_uom.id,
'product_uos_qty': production_line.product_uos and production_line.product_qty or False,
'product_uos': production_line.product_uos and production_line.product_uos.id or False,
'location_id': location_id,
'procure_method': production_line.product_id.procure_method,
'move_id': shipment_move_id,
'company_id': production.company_id.id,
})
wf_service.trg_validate(uid, 'procurement.order', proc_id, 'button_confirm', cr)
proc_ids.append(proc_id)
wf_service.trg_validate(uid, 'stock.picking', picking_id, 'button_confirm', cr)
self.write(cr, uid, [production.id], {'picking_id': picking_id, 'move_lines': [(6,0,moves)], 'state':'confirmed'})
wf_service.trg_validate(uid, procurement_order._name, procurement_id, 'button_confirm', cr)
return procurement_id
def _make_production_internal_shipment_line(self, cr, uid, production_line, shipment_id, parent_move_id, destination_location_id=False, context=None):
stock_move = self.pool.get('stock.move')
production = production_line.production_id
date_planned = production.date_planned
# Internal shipment is created for Stockable and Consumer Products
if production_line.product_id.type not in ('product', 'consu'):
return False
move_name = _('PROD: %s') % production.name
source_location_id = production.location_src_id.id
if not destination_location_id:
destination_location_id = source_location_id
return stock_move.create(cr, uid, {
'name': move_name,
'picking_id': shipment_id,
'product_id': production_line.product_id.id,
'product_qty': production_line.product_qty,
'product_uom': production_line.product_uom.id,
'product_uos_qty': production_line.product_uos and production_line.product_uos_qty or False,
'product_uos': production_line.product_uos and production_line.product_uos.id or False,
'date': date_planned,
'move_dest_id': parent_move_id,
'location_id': source_location_id,
'location_dest_id': destination_location_id,
'state': 'waiting',
'company_id': production.company_id.id,
})
def _make_production_internal_shipment(self, cr, uid, production, context=None):
ir_sequence = self.pool.get('ir.sequence')
stock_picking = self.pool.get('stock.picking')
routing_loc = None
pick_type = 'internal'
address_id = False
# Take routing address as a Shipment Address.
# If usage of routing location is a internal, make outgoing shipment otherwise internal shipment
if production.bom_id.routing_id and production.bom_id.routing_id.location_id:
routing_loc = production.bom_id.routing_id.location_id
if routing_loc.usage <> 'internal':
pick_type = 'out'
address_id = routing_loc.address_id and routing_loc.address_id.id or False
# Take next Sequence number of shipment base on type
pick_name = ir_sequence.get(cr, uid, 'stock.picking.' + pick_type)
picking_id = stock_picking.create(cr, uid, {
'name': pick_name,
'origin': (production.origin or '').split(':')[0] + ':' + production.name,
'type': pick_type,
'move_type': 'one',
'state': 'auto',
'address_id': address_id,
'auto_picking': self._get_auto_picking(cr, uid, production),
'company_id': production.company_id.id,
})
production.write({'picking_id': picking_id}, context=context)
return picking_id
def _make_production_produce_line(self, cr, uid, production, context=None):
stock_move = self.pool.get('stock.move')
source_location_id = production.product_id.product_tmpl_id.property_stock_production.id
destination_location_id = production.location_dest_id.id
move_name = _('PROD: %s') + production.name
data = {
'name': move_name,
'date': production.date_planned,
'product_id': production.product_id.id,
'product_qty': production.product_qty,
'product_uom': production.product_uom.id,
'product_uos_qty': production.product_uos and production.product_uos_qty or False,
'product_uos': production.product_uos and production.product_uos.id or False,
'location_id': source_location_id,
'location_dest_id': destination_location_id,
'move_dest_id': production.move_prod_id.id,
'state': 'waiting',
'company_id': production.company_id.id,
}
move_id = stock_move.create(cr, uid, data, context=context)
production.write({'move_created_ids': [(6, 0, [move_id])]}, context=context)
return move_id
def _make_production_consume_line(self, cr, uid, production_line, parent_move_id, source_location_id=False, context=None):
stock_move = self.pool.get('stock.move')
production = production_line.production_id
# Internal shipment is created for Stockable and Consumer Products
if production_line.product_id.type not in ('product', 'consu'):
return False
move_name = _('PROD: %s') % production.name
destination_location_id = production.product_id.product_tmpl_id.property_stock_production.id
if not source_location_id:
source_location_id = production.location_src_id.id
move_id = stock_move.create(cr, uid, {
'name': move_name,
'date': production.date_planned,
'product_id': production_line.product_id.id,
'product_qty': production_line.product_qty,
'product_uom': production_line.product_uom.id,
'product_uos_qty': production_line.product_uos and production_line.product_uos_qty or False,
'product_uos': production_line.product_uos and production_line.product_uos.id or False,
'location_id': source_location_id,
'location_dest_id': destination_location_id,
'move_dest_id': parent_move_id,
'state': 'waiting',
'company_id': production.company_id.id,
})
production.write({'move_lines': [(4, move_id)]}, context=context)
return move_id
def action_confirm(self, cr, uid, ids, context=None):
""" Confirms production order.
@return: Newly generated Shipment Id.
"""
shipment_id = False
wf_service = netsvc.LocalService("workflow")
uncompute_ids = filter(lambda x:x, [not x.product_lines and x.id or False for x in self.browse(cr, uid, ids, context=context)])
self.action_compute(cr, uid, uncompute_ids, context=context)
for production in self.browse(cr, uid, ids, context=context):
shipment_id = self._make_production_internal_shipment(cr, uid, production, context=context)
produce_move_id = self._make_production_produce_line(cr, uid, production, context=context)
# Take routing location as a Source Location.
source_location_id = production.location_src_id.id
if production.bom_id.routing_id and production.bom_id.routing_id.location_id:
source_location_id = production.bom_id.routing_id.location_id.id
for line in production.product_lines:
consume_move_id = self._make_production_consume_line(cr, uid, line, produce_move_id, source_location_id=source_location_id, context=context)
shipment_move_id = self._make_production_internal_shipment_line(cr, uid, line, shipment_id, consume_move_id,\
destination_location_id=source_location_id, context=context)
self._make_production_line_procurement(cr, uid, line, shipment_move_id, context=context)
wf_service.trg_validate(uid, 'stock.picking', shipment_id, 'button_confirm', cr)
production.write({'state':'confirmed'}, context=context)
message = _("Manufacturing order '%s' is scheduled for the %s.") % (
production.name,
datetime.strptime(production.date_planned,'%Y-%m-%d %H:%M:%S').strftime('%m/%d/%Y'),
)
self.log(cr, uid, production.id, message)
return picking_id
return shipment_id
def force_production(self, cr, uid, ids, *args):
""" Assigns products.
+513 -122
View File
@@ -5,6 +5,32 @@
<record id="base.user_demo" model="res.users">
<field eval="[(4, ref('group_mrp_user'))]" name="groups_id"/>
</record>
<record id="account_assembly_hours" model="account.analytic.account">
<field name="type">normal</field>
<field name="code">ASML - HOUR</field>
<field name="name">Costing Account For Hours of Assembly.</field>
</record>
<record id="account_assembly_cycle" model="account.analytic.account">
<field name="type">normal</field>
<field name="code">ASML - Cycle</field>
<field name="name">Costing Account For Cycle of Assembly.</field>
</record>
<record id="product.product_category_assembly" model="product.category">
<field name="parent_id" ref="product.product_category_services"/>
<field name="name">Assembly Service</field>
</record>
<record id="product.product_assembly" model="product.product">
<field name="standard_price">0.1</field>
<field name="uom_id" ref="product.uom_hour"/>
<field name="uom_po_id" ref="product.uom_hour"/>
<field name="type">service</field>
<field name="name">Assembly Service Cost</field>
<field name="categ_id" ref="product.product_category_assembly"/>
</record>
<!--
@@ -14,10 +40,25 @@
<record id="mrp_workcenter_0" model="mrp.workcenter">
<field name="name">Assembly workshop</field>
<field name="calendar_id" ref="resource.timesheet_group1"/>
<field name="capacity_per_cycle">5</field>
<field name="time_cycle">1</field>
<field name="time_start">0.1</field>
<field name="time_stop">0.1</field>
<field name="time_efficiency">0.87</field>
<field name="product_id" ref="product.product_assembly"/>
<field name="costs_hour">0.1</field>
<field name="costs_hour_account_id" ref="account_assembly_hours"/>
<field name="costs_cycle">0.05</field>
<field name="costs_cycle_account_id" ref="account_assembly_cycle"/>
<field name="costs_journal_id" ref="account.expenses_journal"/>
<field name="costs_general_account_id" ref="account.a_expense"/>
<field name="costs_general_account_id" ref="account.a_expense"/>
<field name="calendar_id" ref="resource.timesheet_group1"/>
</record>
<record id="mrp_workcenter_1" model="mrp.workcenter">
<field name="name">Repairs workshop</field>
<field name="calendar_id" ref="resource.timesheet_group1"/>
<field name="time_cycle">1</field>
</record>
<!--
Resource: res.company
@@ -133,15 +174,12 @@
-->
<record id="mrp_routing_0" model="mrp.routing">
<field name="workcenter_lines">[1]</field>
<field name="name">Assembly Line 1</field>
</record>
<record id="mrp_routing_1" model="mrp.routing">
<field name="workcenter_lines">[2]</field>
<field name="name">Custom Assembly Line</field>
</record>
<record id="mrp_routing_2" model="mrp.routing">
<field name="workcenter_lines">[3]</field>
<field name="name">Component Manufacturing</field>
</record>
@@ -154,18 +192,38 @@
<field name="workcenter_id" ref="mrp_workcenter_0"/>
<field name="name">Short time assembly</field>
<field name="hour_nbr">2</field>
<field name="sequence">5</field>
</record>
<record id="mrp_routing_workcenter_1" model="mrp.routing.workcenter">
<field name="routing_id" ref="mrp_routing_1"/>
<field name="workcenter_id" ref="mrp_workcenter_0"/>
<field name="name">long time assembly</field>
<field name="hour_nbr">5</field>
<field name="cycle_nbr">2</field>
<field name="sequence">15</field>
</record>
<record id="mrp_routing_workcenter_3" model="mrp.routing.workcenter">
<field name="routing_id" ref="mrp_routing_1"/>
<field name="workcenter_id" ref="mrp_workcenter_0"/>
<field name="name">Testing</field>
<field name="hour_nbr">1</field>
<field name="sequence">10</field>
</record>
<record id="mrp_routing_workcenter_4" model="mrp.routing.workcenter">
<field name="routing_id" ref="mrp_routing_1"/>
<field name="workcenter_id" ref="mrp_workcenter_1"/>
<field name="name">Packing</field>
<field name="hour_nbr">0.5</field>
<field name="sequence">5</field>
</record>
<record id="mrp_routing_workcenter_2" model="mrp.routing.workcenter">
<field name="routing_id" ref="mrp_routing_2"/>
<field name="workcenter_id" ref="mrp_workcenter_0"/>
<field name="cycle_nbr">0.5</field>
<field name="hour_nbr">3</field>
<field name="sequence">5</field>
<field name="name">assembly main + processor + fan</field>
</record>
@@ -214,7 +272,7 @@
<field model="product.product" name="product_id" ref="product.product_product_20"/>
</record>
<record id="mrp_bom_5" model="mrp.bom">
<field name="name">RAM on demand</field>
<field name="name">RAM512 on demand</field>
<field name="sequence">18</field>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
@@ -254,12 +312,12 @@
<field model="product.product" name="product_id" ref="product.product_product_23"/>
</record>
<record id="mrp_bom_11" model="mrp.bom">
<field name="name">RAM on demand</field>
<field name="name">RAM256 on demand</field>
<field name="sequence">36</field>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="type">phantom</field>
<field model="product.product" name="product_id" ref="product.product_product_23"/>
<field model="product.product" name="product_id" ref="product.product_product_21"/>
</record>
<record id="mrp_bom_13" model="mrp.bom">
@@ -267,42 +325,28 @@
<field name="sequence">38</field>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="routing_id" ref="mrp_routing_1"/>
<field model="product.product" name="product_id" ref="product.product_product_cpu3"/>
</record>
<record id="mrp_bom_kit" model="mrp.bom">
<record id="mrp_bom_kit3" model="mrp.bom">
<field name="code">KIT</field>
<field name="name">Kit Mouse</field>
<field name="name">Kit Keyboard + Mouse</field>
<field name="sequence">40</field>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="type">normal</field>
<field name="type">phantom</field>
<field name="bom_id" ref="mrp_bom_10"/>
<field model="product.product" name="product_id" ref="product.product_product_25"/>
</record>
<record id="mrp_bom_clavier" model="mrp.bom">
<field name="name">Keyboard</field>
<field name="sequence">42</field>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="bom_id" ref="mrp_bom_kit"/>
<field model="product.product" name="product_id" ref="product.product_product_24"/>
</record>
<record id="mrp_bom_mouse" model="mrp.bom">
<field name="name">Mouse</field>
<field name="sequence">44</field>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="bom_id" ref="mrp_bom_kit"/>
<field model="product.product" name="product_id" ref="product.product_product_25"/>
<field model="product.product" name="product_id" ref="product.product_product_26"/>
</record>
<record id="mrp_bom_16" model="mrp.bom">
<field name="name">Moon PC</field>
<field name="sequence">45</field>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="bom_id" ref="mrp_bom_10"/>
<field model="product.product" name="product_id" ref="product.product_product_pc1"/>
<field model="product.product" name="product_id" ref="product.product_product_pc2"/>
</record>
<record id="mrp_bom_18" model="mrp.bom">
<field name="name">Mainboard ASUStek A7N8X</field>
@@ -502,6 +546,35 @@
<field name="bom_id" ref="mrp_bom_0"/>
<field model="product.product" name="product_id" ref="product.product_product_ram"/>
</record>
<record id="mrp_bom_kit1" model="mrp.bom">
<field name="code">KIT</field>
<field name="sequence">15</field>
<field name="name">Kit Keyboard + Mouse</field>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="type">normal</field>
<field model="product.product" name="product_id" ref="product.product_product_26"/>
</record>
<record id="mrp_bom_mouse2" model="mrp.bom">
<field name="name">Mouse</field>
<field name="sequence">121</field>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="bom_id" ref="mrp_bom_kit1"/>
<field model="product.product" name="product_id" ref="product.product_product_25"/>
</record>
<record id="mrp_bom_clavier2" model="mrp.bom">
<field name="name">Keyboard</field>
<field name="sequence">123</field>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="bom_id" ref="mrp_bom_kit1"/>
<field model="product.product" name="product_id" ref="product.product_product_24"/>
</record>
<record id="mrp_bom_41" model="mrp.bom">
<field name="name">Regular processor config</field>
<field name="sequence">111</field>
@@ -536,176 +609,496 @@
<field name="name">Kit Keyboard + Mouse</field>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="type">normal</field>
<field name="type">phantom</field>
<field name="bom_id" ref="mrp_bom_9"/>
<field model="product.product" name="product_id" ref="product.product_product_26"/>
</record>
<record id="mrp_bom_mouse2" model="mrp.bom">
<field name="name">Mouse</field>
<field name="sequence">121</field>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="bom_id" ref="mrp_bom_kit2"/>
<field model="product.product" name="product_id" ref="product.product_product_25"/>
</record>
<record id="mrp_bom_clavier2" model="mrp.bom">
<field name="name">Keyboard</field>
<field name="sequence">123</field>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="bom_id" ref="mrp_bom_kit2"/>
<field model="product.product" name="product_id" ref="product.product_product_24"/>
</record>
<!--
Resource: mrp.bom new EVV
-->
<record id="mrp_bom_defaultbomforshelfofcm0" model="mrp.bom">
<field name="name">Default BOM for Shelf of 100cm</field>
<field name="code">SHE100</field>
<field name="sequence">129</field>
<field name="sequence">10</field>
<field name="product_id" ref="product.product_product_shelfofcm0"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="product_qty">1.0</field>
<field name="routing_id" ref="mrp.mrp_routing_1"/>
</record>
<!-- BoMs for 1 Shelf 100cm
Product Ref. Qty UoM Type of BoM
SIDEPAN 2 PCE normal
PROFIL 4 PCE phantom
RPAN100 1 PCE phantom
RCK100 3 PCE phantom
-->
<record id="mrp_bom_sidepanel0" model="mrp.bom">
<field name="name">Side Panel</field>
<field name="sequence">101</field>
<field name="product_id" ref="product.product_product_sidepanel0"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">2.0</field>
<field name="bom_id" ref="mrp_bom_defaultbomforshelfofcm0"/>
</record>
<record id="mrp_bom_assemblysection0" model="mrp.bom">
<field name="name">Assembly Section</field>
<field name="sequence">123</field>
<field name="sequence">102</field>
<field name="product_id" ref="product.product_product_assemblysection0"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">4.0</field>
<field model="mrp.bom" name="bom_id" search="[('name', '=', u'Default BOM for Shelf of 100cm')]"/>
</record>
<record id="mrp_bom_sidepanel0" model="mrp.bom">
<field name="name">Side Panel</field>
<field name="sequence">125</field>
<field name="product_id" ref="product.product_product_sidepanel0"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">2.0</field>
<field model="mrp.bom" name="bom_id" search="[('name', '=', u'Default BOM for Shelf of 100cm')]"/>
</record>
<record id="mrp_bom_metalcleats0" model="mrp.bom">
<field name="name">Metal Cleats</field>
<field name="sequence">127</field>
<field name="product_id" ref="product.product_product_metalcleats0"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">12.0</field>
<field model="mrp.bom" name="bom_id" search="[('name', '=', u'Default BOM for Shelf of 100cm')]"/>
<field name="product_qty">4.0</field>
<field name="bom_id" ref="mrp_bom_defaultbomforshelfofcm0"/>
<field name="type">phantom</field>
</record>
<record id="mrp_bom_rearpanelarm0" model="mrp.bom">
<field name="sequence">131</field>
<field name="sequence">103</field>
<field name="product_id" ref="product.product_product_rearpanelarm0"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="bom_id" ref="mrp_bom_defaultbomforshelfofcm0"/>
<field name="product_qty">1.0</field>
<field name="product_qty">1.0</field>
<field name="name">Rear panel SHE100</field>
<field name="type">phantom</field>
</record>
<record id="mrp_bom_shelf0" model="mrp.bom">
<field name="sequence">133</field>
<field name="sequence">104</field>
<field name="product_id" ref="product.product_product_shelf0"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="bom_id" ref="mrp_bom_defaultbomforshelfofcm0"/>
<field name="product_qty">3.0</field>
<field name="name">Shelf 100</field>
<field name="product_qty">3.0</field>
<field name="name">RCK100</field>
<field name="type">phantom</field>
</record>
<!--
BOMs for 1 RCK100 PCE
Product Ref Qty UoM Type of BoM
SPAN100 1 PCE phantom
METC000 4 PCE normal
-->
<record id="mrp_bom_shelf1" model="mrp.bom">
<field name="sequence">133</field>
<field name="product_id" ref="product.product_product_shelf0"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="name">RCK100</field>
</record>
<record id="mrp_bom_shelf0_span100" model="mrp.bom">
<field name="sequence">1331</field>
<field name="product_id" ref="product.product_product_span100"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="bom_id" ref="mrp_bom_shelf1"/>
<field name="product_qty">1.0</field>
<field name="type">phantom</field> <!-- It should be phantom -->
<field name="name">SPAN100</field>
</record>
<record id="mrp_bom_shelf0_metalcleats0" model="mrp.bom">
<field name="sequence">1332</field>
<field name="product_id" ref="product.product_product_metalcleats0"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="bom_id" ref="mrp_bom_shelf1"/>
<field name="product_qty">4.0</field>
<field name="name">METC000</field>
</record>
<!--
Bill of Materials for 1 SPAN100 PCE
Product Code Quantity Unit of Measure
WOOD010 0.083 m
-->
<record id="mrp_bom_span100" model="mrp.bom">
<field name="sequence">135</field>
<field name="product_id" ref="product.product_product_span100"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="name">SPAN100</field>
</record>
<record id="mrp_bom_span100_wood010" model="mrp.bom">
<field name="sequence">1351</field>
<field name="product_id" ref="product.product_product_woodmm10"/>
<field name="product_uom" ref="product.product_uom_meter"/>
<field name="bom_id" ref="mrp_bom_span100"/>
<field name="product_qty">0.083</field>
<field name="name">WOOD010</field>
</record>
<!-- BoMs for 1 Assembly Section PCE
Product Ref. Qty UoM
LIN40 0.25 Meter
-->
<record id="mrp_bom_assemblysection1" model="mrp.bom">
<field name="name">Assembly Section</field>
<field name="sequence">123</field>
<field name="product_id" ref="product.product_product_assemblysection0"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="routing_id" ref="mrp.mrp_routing_0"/>
</record>
<record id="mrp_bom_woodlintelm0" model="mrp.bom">
<field name="sequence">135</field>
<field name="sequence">1231</field>
<field name="product_id" ref="product.product_product_woodlintelm0"/>
<field name="product_uom" ref="product.product_uom_meter"/>
<field name="bom_id" ref="mrp_bom_defaultbomforshelfofcm0"/>
<field name="product_qty">1.0</field>
<field model="mrp.bom" name="bom_id" search="[('name', '=', u'Assembly Section')]"/>
<field name="name">Wood Lintel 4m</field>
<field name="product_qty">0.25</field>
<field name="bom_id" ref="mrp_bom_assemblysection1"/>
<field name="name">Wood Lintel 0.25m</field>
</record>
<!--
Bill of Materials for 1 RPAN100 PCE
Product Code Quantity Unit of Measure
WOOD002 0.25 m
-->
<record id="mrp_bom_rearpanelarm1" model="mrp.bom">
<field name="sequence">131</field>
<field name="product_id" ref="product.product_product_rearpanelarm0"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="name">Rear panel SHE100</field>
<field name="routing_id" ref="mrp.mrp_routing_0"/>
</record>
<record id="mrp_bom_rearpanelarm1_wood002" model="mrp.bom">
<field name="sequence">1311</field>
<field name="product_id" ref="product.product_product_woodmm0"/>
<field name="product_uom" ref="product.product_uom_meter"/>
<field name="bom_id" ref="mrp_bom_rearpanelarm1"/>
<field name="product_qty">0.25</field>
<field name="name">WOOD002 0.25m</field>
</record>
<record id="mrp_bom_defaultbomforshelfofcm1" model="mrp.bom">
<field name="name">Default BOM for Shelf of 200cm</field>
<field name="code">SHE200</field>
<field name="sequence">137</field>
<field name="product_id" ref="product.product_product_shelfofcm0"/>
<field name="sequence">137</field>
<field name="product_id" ref="product.product_product_shelfofcm1"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
</record>
<record id="mrp_bom_defaultbomforkitshelfofcm0" model="mrp.bom">
<field name="name">Default BOM for KIT Shelf of 100cm</field>
<field name="code">SHE100KIT</field>
<field name="sequence">139</field>
<field name="product_id" ref="product.product_product_kitshelfofcm0"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="type">phantom</field>
</record>
<record id="mrp_bom_assemblysection2" model="mrp.bom">
<field name="name">Assembly Section</field>
<field name="sequence">143</field>
<field name="product_id" ref="product.product_product_assemblysection0"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">4.0</field>
<field name="bom_id" ref="mrp_bom_defaultbomforkitshelfofcm0"/>
</record>
<record id="mrp_bom_sidepanel2" model="mrp.bom">
<field name="name">Side Panel</field>
<field name="sequence">145</field>
<field name="product_id" ref="product.product_product_sidepanel0"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">2.0</field>
<field name="bom_id" ref="mrp_bom_defaultbomforkitshelfofcm0"/>
<field name="product_qty">1.0</field>
</record>
<!--Defining BoMs of Shelf 200cm
Product Ref. Qty UoM Type of BoM
RPAN200 1 PCE normal
PROFIL 4 PCE normal
SIDEPAN 2 PCE normal
METC000 12 PCE normal
RCK200 3 PCE normal
-->
<record id="mrp_bom_rearpanelarm2" model="mrp.bom">
<field name="sequence">147</field>
<field name="product_id" ref="product.product_product_rearpanelarm0"/>
<field name="sequence">147</field>
<field name="product_id" ref="product.product_product_rearpanelarm1"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="bom_id" ref="mrp_bom_defaultbomforshelfofcm1"/>
<field name="product_qty">1.0</field>
<field name="product_qty">1.0</field>
<field name="name">Rear panel SHE200</field>
</record>
<record id="mrp_bom_assemblysection3" model="mrp.bom">
<field name="name">Assembly Section</field>
<field name="sequence">149</field>
<field name="sequence">149</field>
<field name="product_id" ref="product.product_product_assemblysection0"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">4.0</field>
<field name="product_qty">4.0</field>
<field name="bom_id" ref="mrp_bom_defaultbomforshelfofcm1"/>
</record>
<record id="mrp_bom_sidepanel3" model="mrp.bom">
<field name="name">Side Panel</field>
<field name="sequence">151</field>
<field name="sequence">151</field>
<field name="product_id" ref="product.product_product_sidepanel0"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">2.0</field>
<field name="product_qty">2.0</field>
<field name="bom_id" ref="mrp_bom_defaultbomforshelfofcm1"/>
</record>
<record id="mrp_bom_shelf2" model="mrp.bom">
<field name="sequence">153</field>
<field name="sequence">153</field>
<field name="product_id" ref="product.product_product_shelf1"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="bom_id" ref="mrp_bom_defaultbomforshelfofcm1"/>
<field name="product_qty">3.0</field>
<field name="product_qty">3.0</field>
<field name="name">Shelf 200</field>
</record>
<record id="mrp_bom_metalcleats3" model="mrp.bom">
<field name="name">Metal Cleats</field>
<field name="sequence">155</field>
<field name="sequence">155</field>
<field name="product_id" ref="product.product_product_metalcleats0"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">12.0</field>
<field name="product_qty">12.0</field>
<field name="bom_id" ref="mrp_bom_defaultbomforshelfofcm1"/>
</record>
<record id="mrp_bom_defaultbomforkitshelfofcm0" model="mrp.bom">
<field name="name">Default BOM for KIT Shelf of 100cm</field>
<field name="code">SHE100KIT</field>
<field name="sequence">139</field>
<field name="product_id" ref="product.product_product_kitshelfofcm0"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="type">phantom</field>
</record>
<!--Defining BoMs of KIT Shelf 100cm
Product Ref. Qty UoM Type of BoM
PROFIL 4 PCE normal
SIDEPAN 2 PCE normal
-->
<record id="mrp_bom_assemblysection2" model="mrp.bom">
<field name="name">Assembly Section</field>
<field name="sequence">143</field>
<field name="product_id" ref="product.product_product_assemblysection0"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">4.0</field>
<field name="bom_id" ref="mrp_bom_defaultbomforkitshelfofcm0"/>
</record>
<record id="mrp_bom_sidepanel2" model="mrp.bom">
<field name="name">Side Panel</field>
<field name="sequence">145</field>
<field name="product_id" ref="product.product_product_sidepanel0"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">2.0</field>
<field name="bom_id" ref="mrp_bom_defaultbomforkitshelfofcm0"/>
</record>
<record id="product.product_uom_dozen" model="product.uom">
<field name="category_id" ref="product.product_uom_categ_unit"/>
<field name="name">Dozen</field>
<field name="factor" eval="0.083"/>
<field name="uom_type">bigger</field>
</record>
<record id="mrp_production_shelf100cm" model="mrp.production">
<field name="product_id" ref="product.product_product_shelfofcm0"/>
<field name="product_uom" ref="product.product_uom_dozen"/>
<field name="product_qty">3</field>
<field name="location_src_id" ref="stock.stock_location_stock"/>
<field name="location_dest_id" ref="stock.stock_location_output"/>
<field name="bom_id" ref="mrp_bom_defaultbomforshelfofcm0"/>
</record>
<record id="product_uom_categ_fluid" model="product.uom.categ">
<field name="name">Fluid</field>
</record>
<record id="product_uom_litre" model="product.uom">
<field name="name">Litre</field>
<field name="category_id" ref="product_uom_categ_fluid"/>
<field name="factor">1.0</field>
</record>
<record id="product_orangejuice" model="product.product">
<field name="categ_id" ref="product.cat1"/>
<field name="name">Orange Juice</field>
<field name="procure_method">make_to_order</field>
<field name="supply_method">produce</field>
<field name="type">product</field>
<field name="uom_id" ref="product_uom_litre"/>
<field name="uom_po_id" ref="product_uom_litre"/>
</record>
<record id="product_orange" model="product.product">
<field name="categ_id" ref="product.cat1"/>
<field name="name">Orange</field>
<field name="procure_method">make_to_stock</field>
<field name="supply_method">buy</field>
<field name="type">product</field>
<field name="uom_id" ref="product.product_uom_kgm"/>
<field name="uom_po_id" ref="product.product_uom_kgm"/>
</record>
<record id="orange_supplier_asus" model="product.supplierinfo">
<field name="product_id" ref="product_orange"/>
<field name="name" ref="base.res_partner_asus"/>
<field name="min_qty">1.0</field>
<field name="product_uom" ref="product.product_uom_kgm"/>
</record>
<record id="product_sugar" model="product.product">
<field name="categ_id" ref="product.cat1"/>
<field name="name">Sugar</field>
<field name="procure_method">make_to_stock</field>
<field name="supply_method">buy</field>
<field name="type">product</field>
<field name="uom_id" ref="product.product_uom_kgm"/>
<field name="uom_po_id" ref="product.product_uom_kgm"/>
</record>
<record id="sugar_supplier_desertic" model="product.supplierinfo">
<field name="product_id" ref="product_sugar"/>
<field name="name" ref="base.res_partner_desertic_hispafuentes"/>
<field name="product_uom" ref="product.product_uom_kgm"/>
<field name="min_qty">2.0</field>
</record>
<record id="product_water" model="product.product">
<field name="categ_id" ref="product.cat1"/>
<field name="name">Water</field>
<field name="procure_method">make_to_order</field>
<field name="supply_method">buy</field>
<field name="type">consu</field>
<field name="uom_id" ref="product_uom_litre"/>
<field name="uom_po_id" ref="product_uom_litre"/>
</record>
<record id="water_supplier_agrolait" model="product.supplierinfo">
<field name="product_id" ref="product_water"/>
<field name="name" ref="base.res_partner_agrolait"/>
<field name="product_uom" ref="product_uom_litre"/>
<field name="min_qty">2.0</field>
</record>
<record id="mrp_bom_orangejuice" model="mrp.bom">
<field name="sequence">200</field>
<field name="product_id" ref="product_orangejuice"/>
<field name="product_uom" ref="product_uom_litre"/>
<field name="product_qty">1.0</field>
<field name="name">Orange Juice</field>
<field name="type">phantom</field>
</record>
<record id="raw_orangejuice_orange" model="mrp.bom">
<field name="sequence">201</field>
<field name="product_id" ref="product_orange"/>
<field name="product_uom" ref="product.product_uom_kgm"/>
<field name="product_qty">0.5</field>
<field name="name">Orange</field>
<field name="type">normal</field>
<field name="bom_id" ref="mrp_bom_orangejuice"/>
</record>
<record id="raw_orangejuice_sugar" model="mrp.bom">
<field name="sequence">202</field>
<field name="product_id" ref="product_sugar"/>
<field name="product_uom" ref="product.product_uom_kgm"/>
<field name="product_qty">0.02</field>
<field name="name">Sugar</field>
<field name="type">normal</field>
<field name="bom_id" ref="mrp_bom_orangejuice"/>
</record>
<record id="raw_orangejuice_water" model="mrp.bom">
<field name="sequence">203</field>
<field name="product_id" ref="product_water"/>
<field name="product_uom" ref="product_uom_litre"/>
<field name="product_qty">0.80</field>
<field name="name">Water</field>
<field name="type">normal</field>
<field name="bom_id" ref="mrp_bom_orangejuice"/>
</record>
<record id="stock_rule_orange" model="stock.warehouse.orderpoint">
<field name="product_id" ref="product_orange"/>
<field name="product_uom" ref="product.product_uom_kgm"/>
<field name="product_max_qty">10.0</field>
<field name="product_min_qty">5.0</field>
<field name="qty_multiple">1</field>
<field name="warehouse_id" ref="stock.warehouse0"/>
<field name="location_id" ref="stock.stock_location_stock"/>
</record>
<record id="stock_rule_sugar" model="stock.warehouse.orderpoint">
<field name="product_id" ref="product_sugar"/>
<field name="product_uom" ref="product.product_uom_kgm"/>
<field name="product_max_qty">4.0</field>
<field name="product_min_qty">2.0</field>
<field name="qty_multiple">1</field>
<field name="logic">max</field>
<field name="warehouse_id" ref="stock.warehouse0"/>
<field name="location_id" ref="stock.stock_location_stock"/>
</record>
<record id="mrp_production_orangejuice" model="mrp.production">
<field name="product_id" ref="product_orangejuice"/>
<field name="product_uom" ref="product_uom_litre"/>
<field name="location_src_id" ref="stock.stock_location_stock"/>
<field name="location_dest_id" ref="stock.stock_location_output"/>
<field name="bom_id" ref="mrp_bom_orangejuice"/>
<field name="product_qty">100.00</field>
</record>
<record id="product_shirt" model="product.product">
<field name="categ_id" ref="product.cat1"/>
<field name="name">Shirt</field>
<field name="procure_method">make_to_stock</field>
<field name="supply_method">produce</field>
<field name="type">product</field>
<field name="uom_id" ref="product.product_uom_unit"/>
<field name="uom_po_id" ref="product.product_uom_unit"/>
</record>
<record id="product_cloth" model="product.product">
<field name="categ_id" ref="product.cat1"/>
<field name="name">Cloth</field>
<field name="procure_method">make_to_order</field>
<field name="supply_method">buy</field>
<field name="type">product</field>
<field name="uom_id" ref="product.product_uom_unit"/>
<field name="uom_po_id" ref="product.product_uom_unit"/>
</record>
<record id="cloth_supplier_maxtor" model="product.supplierinfo">
<field name="product_id" ref="product_cloth"/>
<field name="name" ref="base.res_partner_maxtor"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="min_qty">300.0</field>
</record>
<record id="product_buttons" model="product.product">
<field name="categ_id" ref="product.cat1"/>
<field name="name">Shirt Buttons</field>
<field name="procure_method">make_to_stock</field>
<field name="supply_method">buy</field>
<field name="type">product</field>
<field name="uom_id" ref="product.product_uom_unit"/>
<field name="uom_po_id" ref="product.product_uom_unit"/>
</record>
<record id="buttons_supplier_asus" model="product.supplierinfo">
<field name="product_id" ref="product_buttons"/>
<field name="name" ref="base.res_partner_asus"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="min_qty">100.0</field>
</record>
<record id="mrp_bom_shirt" model="mrp.bom">
<field name="sequence">300</field>
<field name="product_id" ref="product_shirt"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="name">Shirt</field>
</record>
<record id="raw_shirt_cloth" model="mrp.bom">
<field name="sequence">301</field>
<field name="product_id" ref="product_cloth"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="name">Cloth</field>
<field name="type">normal</field>
<field name="bom_id" ref="mrp_bom_shirt"/>
</record>
<record id="raw_shirt_buttons" model="mrp.bom">
<field name="sequence">302</field>
<field name="product_id" ref="product_buttons"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">8.0</field>
<field name="name">Shirt Buttons</field>
<field name="type">normal</field>
<field name="bom_id" ref="mrp_bom_shirt"/>
</record>
<record id="stock_shirt_buttons" model="stock.warehouse.orderpoint">
<field name="product_id" ref="product_buttons"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_max_qty">50.0</field>
<field name="product_min_qty">10.0</field>
<field name="qty_multiple">1</field>
<field name="logic">max</field>
<field name="warehouse_id" ref="stock.warehouse0"/>
<field name="location_id" ref="stock.stock_location_stock"/>
</record>
<record id="mrp_production_shirt" model="mrp.production">
<field name="product_id" ref="product_shirt"/>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="location_src_id" ref="stock.stock_location_stock"/>
<field name="location_dest_id" ref="stock.stock_location_output"/>
<field name="bom_id" ref="mrp_bom_shirt"/>
</record>
<record id="mrp_production_order1" model="mrp.production">
<field name="product_id" ref="product.product_product_pc1"/>
<field name="product_uom" ref="product.product_uom_unit"/>
@@ -714,11 +1107,9 @@
<field name="bom_id" ref="mrp.mrp_bom_9"/>
<field name="routing_id" ref="mrp.mrp_routing_0"/>
</record>
<workflow action="button_confirm" model="mrp.production" ref="mrp_production_order1"/>
<!-- Run Scheduler -->
<function model="procurement.order" name="run_scheduler"/>
</data>
</openerp>
+1 -1
View File
@@ -317,7 +317,7 @@
<field name="arch" type="xml">
<form string="Bill of Material">
<group colspan="4" col="6">
<field name="product_id" on_change="onchange_product_id(product_id, name)" select="1"/>
<field name="product_id" on_change="onchange_product_id(product_id, name, context)" select="1"/>
<field name="name" select="1"/>
<field name="code" select="1" string="Reference" groups="base.group_extended"/>
<newline/>
-28
View File
@@ -25,37 +25,9 @@ from tools.translate import _
class product_product(osv.osv):
_inherit = "product.product"
def get_product_accounts(self, cr, uid, product_id, context=None):
""" To get the stock input account, stock output account and stock journal related to product.
@param product_id: product id
@return: dictionary which contains information regarding stock input account, stock output account and stock journal
"""
product_obj = self.pool.get('product.product').browse(cr, uid, product_id, False)
res = super(product_product,self).get_product_accounts(cr, uid, product_id, context=context)
stock_input_acc = product_obj.property_stock_account_input and product_obj.property_stock_account_input.id or False
if not stock_input_acc:
stock_input_acc = product_obj.categ_id.property_stock_account_input_categ and product_obj.categ_id.property_stock_account_input_categ.id or False
stock_output_acc = product_obj.property_stock_account_output and product_obj.property_stock_account_output.id or False
if not stock_output_acc:
stock_output_acc = product_obj.categ_id.property_stock_account_output_categ and product_obj.categ_id.property_stock_account_output_categ.id or False
journal_id = product_obj.categ_id.property_stock_journal and product_obj.categ_id.property_stock_journal.id or False
res.update({'stock_account_input': stock_input_acc})
res.update({'stock_account_output': stock_output_acc})
res.update({'stock_journal': journal_id})
return res
_columns = {
"bom_ids": fields.one2many('mrp.bom', 'product_id','Bill of Materials'),
}
# Removed do_change_standard_price for the fix of lp:747056
def copy(self, cr, uid, id, default=None, context=None):
if not default:
default = {}
+25
View File
@@ -0,0 +1,25 @@
-
I first confirm order for shirt.
-
!workflow {model: mrp.production, action: button_confirm, ref: mrp_production_shirt}
-
In order to cancel the production order, I first cancel its picking.
-
!function {model: stock.picking, name: action_cancel}:
- model: mrp.production
eval: "[obj(ref('mrp_production_shirt')).picking_id.id]"
-
Now I cancel the production order.
-
!workflow {model: mrp.production, action: button_cancel, ref: mrp_production_shirt}
-
Now I check that the production order is cancelled.
-
!assert {model: mrp.production, id: mrp_production_shirt}:
- state == 'cancel'
-
I remove cancelled production order.
-
!python {model: mrp.production}: |
order = self.browse(cr, uid, ref("mrp_production_shirt"), context=context)
self.unlink(cr, uid, [order.id])
-103
View File
@@ -1,103 +0,0 @@
-
In order to test the Packs in OpenERP, we will try to sell a "Pack of 24
beers" which is composed of 24 "Beers" and a "Beers Pack".
-
I start by creating the Beers product.
-
!record {model: product.product, id: product_product_beers0}:
categ_id: product.cat1
name: Beers
procure_method: make_to_stock
seller_ids:
- delay: 1
name: base.res_partner_agrolait
min_qty: 2.0
supply_method: buy
type: product
uom_id: product.product_uom_unit
uom_po_id: product.product_uom_unit
-
I create the "Beers Pack" product.
-
!record {model: product.product, id: product_product_beerspack0}:
categ_id: product.cat1
name: Beers Pack
procure_method: make_to_stock
seller_ids:
- delay: 1
name: base.res_partner_asus
min_qty: 2.0
supply_method: buy
type: product
uom_id: product.product_uom_unit
uom_po_id: product.product_uom_unit
-
I create the "Pack of 24 beers" product
-
!record {model: product.product, id: product_product_packofbeers0}:
categ_id: product.cat1
name: Pack of 24 Beers
procure_method: make_to_order
supply_method: produce
type: product
uom_id: product.product_uom_unit
uom_po_id: product.product_uom_unit
-
I define the Phantom Bill of Material for the "Pack of 24 beers"
-
!record {model: mrp.bom, id: mrp_bom_packofbeers0}:
bom_lines:
- company_id: base.main_company
name: Beers
product_id: product_product_beers0
product_qty: 24.0
product_uom: product.product_uom_unit
type: normal
- company_id: base.main_company
name: Beers Pack
product_id: product_product_beerspack0
product_qty: 1.0
product_uom: product.product_uom_unit
type: normal
name: Pack of 24 Beers
product_id: product_product_packofbeers0
product_qty: 1.0
product_uom: product.product_uom_unit
type: phantom
-
As all my data are created, I will create an outgoing order picking for a
"Pack of 24 Beers"
-
!record {model: stock.picking, id: picking_out}:
address_id: base.res_partner_address_tang
company_id: base.main_company
invoice_state: none
move_lines:
- company_id: base.main_company
location_dest_id: stock.stock_location_customers
location_id: stock.stock_location_stock
name: Pack of 24 Beers
product_id: product_product_packofbeers0
product_qty: 2.0
product_uom: product.product_uom_unit
move_type: direct
type: out
-
I validate the newly created picking.
-
!python {model: stock.picking}: |
self.draft_validate(cr, uid, [ref("picking_out")], {
"active_ids": [ref("stock.menu_action_picking_tree")],
"active_id": ref("stock.menu_action_picking_tree"), }
)
-
I check that my Picking of a "Pack of 24 beers" has been automatically
converted to a picking of 24 beers and a pack of beer, so that my
stock of beers remains exact.
-
!assert {model: stock.picking, id: picking_out, string: pack_of_beer_splitted}:
- len(move_lines) >= 2
- move_lines[0].product_id.id <> move_lines[1].product_id.id
- move_lines[0].product_id.id in (ref('product_product_beers0'), ref('product_product_beerspack0'))
- move_lines[1].product_id.id in (ref('product_product_beers0'), ref('product_product_beerspack0'))
-273
View File
@@ -1,273 +0,0 @@
-
In order to test the mrp phantom bom type in OpenERP, I will create products
and then I will create Phantom bom structure for those products.
-
I create BOM category fluid for Orange Juice
-
!record {model: product.uom.categ, id: product_uom_categ_fluid}:
name: Fluid
-
I create the products required to produce some orange juices with Oranges, Sugar and Water.
-
!record {model: product.uom, id: product_uom_litre0}:
category_id: product_uom_categ_fluid
factor: 1.0
name: Litre
rounding: 0.01
-
I create record for product Orange Juice.
-
!record {model: product.product, id: product_product_orangejuice0}:
categ_id: product.cat1
name: Orange Juice
procure_method: make_to_order
supply_method: produce
type: product
uom_id: product_uom_litre0
uom_po_id: product_uom_litre0
property_stock_inventory: stock.location_inventory
property_stock_procurement: stock.location_procurement
property_stock_production: stock.location_production
-
I create record for product Orange.
-
!record {model: product.product, id: product_product_orange0}:
categ_id: product.cat1
name: Orange
procure_method: make_to_stock
seller_ids:
- delay: 1
name: base.res_partner_asus
min_qty: 1.0
product_uom: product.product_uom_kgm
supply_method: buy
type: product
uom_id: product.product_uom_kgm
uom_po_id: product.product_uom_kgm
property_stock_inventory: stock.location_inventory
property_stock_procurement: stock.location_procurement
property_stock_production: stock.location_production
-
I create record for product Sugar.
-
!record {model: product.product, id: product_product_sugar0}:
categ_id: product.cat1
name: Sugar
procure_method: make_to_stock
seller_ids:
- delay: 1
name: base.res_partner_desertic_hispafuentes
min_qty: 2.0
product_uom: product.product_uom_kgm
supply_method: buy
type: product
uom_id: product.product_uom_kgm
uom_po_id: product.product_uom_kgm
property_stock_inventory: stock.location_inventory
property_stock_procurement: stock.location_procurement
property_stock_production: stock.location_production
-
I create record for product Water.
-
!record {model: product.product, id: product_product_water0}:
categ_id: product.cat1
name: Water
procure_method: make_to_order
seller_ids:
- delay: 1
name: base.res_partner_agrolait
product_uom: product_uom_litre0
min_qty: 2.0
supply_method: buy
type: consu
uom_id: product_uom_litre0
uom_po_id: product_uom_litre0
property_stock_inventory: stock.location_inventory
property_stock_procurement: stock.location_procurement
property_stock_production: stock.location_production
-
I define the BoM to produce an orange juice.
-
!record {model: mrp.bom, id: mrp_bom_orangejuice0}:
company_id: base.main_company
name: Orange Juice
product_efficiency: 1.0
product_id: product_product_orangejuice0
product_qty: 1.0
product_uom: product_uom_litre0
type: phantom
-
changes UOM and name if product change.
-
!python {model: mrp.bom}: |
production_id = self.browse(cr, uid, [ref('mrp_bom_orangejuice0')], context=context)[0]
self.onchange_product_id(cr, uid, [ref('mrp_bom_orangejuice0')], production_id.product_id.id, False)
-
I create bom lines for BoM for Orange Juice.
-
!record {model: mrp.bom, id: mrp_bom_orangejuice0}:
bom_lines:
- bom_id: mrp_bom_orangejuice0
company_id: base.main_company
name: Orange
product_efficiency: 1.0
product_id: product_product_orange0
product_qty: 0.5
product_uom: product.product_uom_kgm
type: normal
- bom_id: mrp_bom_orangejuice0
company_id: base.main_company
name: Sugar
product_efficiency: 1.0
product_id: product_product_sugar0
product_qty: 0.02
product_uom: product.product_uom_kgm
type: normal
- bom_id: mrp_bom_orangejuice0
company_id: base.main_company
name: Water
product_efficiency: 1.0
product_id: product_product_water0
product_qty: 0.80000000000000004
product_uom: product_uom_litre0
type: normal
-
I define Minimum stock rules for my stockable product "Orange".
-
!record {model: stock.warehouse.orderpoint, id: stock_warehouse_orderpoint_op0}:
company_id: base.main_company
location_id: stock.stock_location_stock
logic: max
name: OP/00002
product_id: product_product_orange0
product_max_qty: 10.0
product_min_qty: 5.0
product_uom: product.product_uom_kgm
qty_multiple: 1
warehouse_id: stock.warehouse0
-
I define Minimum stock rules for my stockable product "Sugar".
-
!record {model: stock.warehouse.orderpoint, id: stock_warehouse_orderpoint_op1}:
company_id: base.main_company
location_id: stock.stock_location_stock
logic: max
name: OP/00003
product_id: product_product_sugar0
product_max_qty: 4.0
product_min_qty: 2.0
product_uom: product.product_uom_kgm
qty_multiple: 1
warehouse_id: stock.warehouse0
-
I want to produce 100 litres of Orange juice. I am creating a manufacturing order for this.
I want to see how much quantities of sub products I need, to produce the Orange juice.
-
I compute the data. I get the bill of material of Orange juice and list of
scheduled products according to my bom.
-
!record {model: mrp.production, id: mrp_production_mo0}:
company_id: base.main_company
date_planned: !eval datetime.today().strftime("%Y-%m-%d %H:%M:%S")
location_dest_id: stock.stock_location_output
location_src_id: stock.stock_location_stock
product_id: product_product_orangejuice0
product_qty: 100.0
product_uom: product_uom_litre0
-
Creating an mrp.production record. Computing Bills of materials.
-
!record {model: mrp.production, id: mrp_production_mo0}:
bom_id: mrp.mrp_bom_orangejuice0
date_planned: !eval datetime.today().strftime("%Y-%m-%d %H:%M:%S")
location_dest_id: stock.stock_location_output
location_src_id: stock.stock_location_stock
product_id: mrp.product_product_orangejuice0
product_lines:
- name: Orange
product_id: mrp.product_product_orange0
product_qty: 50.0
product_uom: product.product_uom_kgm
production_id: mrp_production_mo0
- name: Sugar
product_id: mrp.product_product_sugar0
product_qty: 2.0
product_uom: product.product_uom_kgm
production_id: mrp_production_mo0
- name: Water
product_id: mrp.product_product_water0
product_qty: 80.0
product_uom: mrp.product_uom_litre0
production_id: mrp_production_mo0
product_qty: 100.0
product_uom: mrp.product_uom_litre0
-
I confirm the order.
-
!workflow {model: mrp.production, action: button_confirm, ref: mrp_production_mo0}
-
I am checking Procurement orders. There are 3 orders generated for Oranges, Sugar and Water.
-
!python {model: procurement.order}: |
proc_ids = self.search(cr, uid, [('product_id','in',[ref('product_product_orange0'),ref('product_product_sugar0'),ref('product_product_water0')])])
assert proc_ids, 'No Procurements!'
-
The scheduler runs.
-
!function {model: procurement.order, name: run_scheduler}:
- model: procurement.order
search: "[]"
-
I am checking Internal picking. I see one picking for Orange juice and its
stock moves for Oranges, Sugar and Water made correctly.
-
!python {model: stock.picking}: |
pick_ids = self.search(cr, uid, [('type','=','internal')])
assert pick_ids, 'No Internal Pickings!'
-
According to minimum stock rules. I have 2 purchase orders for
Sugar with 6 Kg from Axelor and Orange 60 Kg from ASUStek.
-
I confirm the purchase order of Sugar and Orange.
-
!python {model: purchase.order}: |
import netsvc
purch_ids = self.search(cr, uid, [('state','=','draft')])
assert purch_ids, 'No Purchase Orders were made!'
wf_service = netsvc.LocalService("workflow")
for p_id in purch_ids:
wf_service.trg_validate(uid, 'purchase.order', p_id, 'purchase_confirm', cr)
-
I see two incoming pickings for Orange and Sugar, and receive them.
-
!python {model: stock.picking}: |
pick_ids = self.search(cr, uid, [('type','=','in')])
assert pick_ids, 'No Incoming Shipments found!'
stock_partial_picking = self.pool.get('stock.partial.picking')
for pick_id in pick_ids:
partial_id = stock_partial_picking.create(cr, uid, {},
context={'active_model': 'stock.picking',
'active_ids': [pick_id]})
stock_partial_picking.do_partial(cr, uid, [partial_id])
-
Again the scheduler runs.
-
!function {model: procurement.order, name: run_scheduler}:
- model: procurement.order
search: "[]"
-
I check my internal picking of "Orange Juice" is done.
-
!python {model: stock.picking}: |
pick_ids = self.search(cr, uid, [('type','=','internal'),('state','=','done')])
assert pick_ids, 'Internal Picking is not done yet!'
-
I check my manufacturing order for "Orange Juice" is ready or not.
-
!python {model: mrp.production}: |
prod_ids = self.search(cr, uid, [('state','=','ready'),('id','=',ref('mrp_production_mo0'))])
assert prod_ids, 'Manufacturing order is not ready!'
-
I start the production order.
-
!workflow {model: mrp.production, action: button_produce, ref: mrp_production_mo0}
-278
View File
@@ -1,278 +0,0 @@
-
In order to test the flow of procurement orders. I will put some orders with
different procurement methods. I have installed sale, mrp and purchase modules.
-
I am creating products.
-
I create record for product Shirt.
-
!record {model: product.product, id: product_product_shirt0}:
categ_id: product.cat1
cost_method: standard
list_price: 350.0
mes_type: fixed
name: Shirt
procure_method: make_to_stock
property_stock_inventory: stock.location_inventory
property_stock_procurement: stock.location_procurement
property_stock_production: stock.location_production
seller_delay: '1'
standard_price: 300.0
supply_method: produce
type: product
uom_id: product.product_uom_unit
uom_po_id: product.product_uom_unit
volume: 0.0
warranty: 0.0
weight: 0.0
weight_net: 0.0
-
I create record for product Cloth.
-
!record {model: product.product, id: product_product_cloth0}:
categ_id: product.cat1
cost_method: standard
mes_type: fixed
name: Cloth
procure_method: make_to_order
property_stock_inventory: stock.location_inventory
property_stock_procurement: stock.location_procurement
property_stock_production: stock.location_production
seller_delay: '1'
seller_ids:
- delay: 1
name: base.res_partner_maxtor
product_uom: product.product_uom_unit
min_qty: 300.0
standard_price: 1.0
supply_method: buy
type: product
uom_id: product.product_uom_unit
uom_po_id: product.product_uom_unit
volume: 0.0
warranty: 0.0
weight: 0.0
weight_net: 0.0
-
I create record for product Buttons.
-
!record {model: product.product, id: product_product_buttons0}:
categ_id: product.cat1
cost_method: standard
mes_type: fixed
name: Buttons
procure_method: make_to_stock
property_stock_inventory: stock.location_inventory
property_stock_procurement: stock.location_procurement
property_stock_production: stock.location_production
seller_delay: '1'
seller_ids:
- delay: 1
name: base.res_partner_asus
product_uom: product.product_uom_kgm
min_qty: 100.0
standard_price: 1.0
supply_method: buy
type: product
uom_id: product.product_uom_kgm
uom_po_id: product.product_uom_kgm
volume: 0.0
warranty: 0.0
weight: 0.0
weight_net: 0.0
-
I am creating bills of material for 'Shirt'.
-
I create bills of material for Shirt.
-
!record {model: mrp.bom, id: mrp_bom_shirt0}:
bom_lines:
- company_id: base.main_company
name: Cloth
product_efficiency: 1.0
product_id: product_product_cloth0
product_qty: 1.0
product_uom: product.product_uom_unit
product_uos_qty: 0.0
sequence: 0.0
type: normal
- company_id: base.main_company
name: Buttons
product_efficiency: 1.0
product_id: product_product_buttons0
product_qty: 8.0
product_uom: product.product_uom_kgm
product_uos_qty: 0.0
sequence: 0.0
type: normal
company_id: base.main_company
name: Shirt
product_efficiency: 1.0
product_id: product_product_shirt0
product_qty: 1.0
product_uom: product.product_uom_unit
product_uos_qty: 0.0
sequence: 0.0
type: normal
-
I create minimum stock rule for product Buttons
-
!record {model: stock.warehouse.orderpoint, id: stock_warehouse_orderpoint_op0}:
company_id: base.main_company
location_id: stock.stock_location_stock
logic: max
name: OP/00007
product_id: mrp.product_product_buttons0
product_max_qty: 50.0
product_min_qty: 10.0
product_uom: product.product_uom_kgm
qty_multiple: 1
warehouse_id: stock.warehouse0
-
I create a procurement order for product Shirt.
-
!record {model: procurement.order, id: procurement_order_shirt0}:
name: 'PROC: Shirt'
product_id: product_product_shirt0
product_qty: 5.00
location_id: stock.stock_location_stock
product_uom: product.product_uom_unit
-
I confirm the procurement order.
-
!workflow {model: procurement.order, action: button_confirm, ref: procurement_order_shirt0}
-
I run the procurement.
-
!workflow {model: procurement.order, action: button_check, ref: procurement_order_shirt0}
-
I see that there is a manufacturing order for Shirt.
-
!python {model: mrp.production}: |
from tools.translate import _
order_ids = self.search(cr, uid, [('product_id','=',ref('product_product_shirt0'))])
assert order_ids, 'No Manufacturing Order.'
-
I also check that there are two more procurement orders for sub products Cloth and Buttons.
-
!python {model: procurement.order}: |
from tools.translate import _
proc_ids = self.search(cr, uid, [('product_id','in',[ref('product_product_cloth0'),ref('product_product_buttons0')])])
assert proc_ids, 'No Procurements.'
-
The scheduler runs.
-
!function {model: procurement.order, name: run_scheduler}:
- model: procurement.order
search: "[]"
-
I check that there is one purchase order for Cloth.
-
!python {model: purchase.order}: |
purch_ids = self.search(cr, uid, [('partner_id.name','=','Maxtor')])
assert purch_ids, 'No Purchase Orders.'
-
I confirm purchase order for Cloth.
-
!python {model: purchase.order}: |
import netsvc
purch_ids = self.search(cr, uid, [('partner_id.name','=','Maxtor')])
wf_service = netsvc.LocalService("workflow")
for p_id in purch_ids:
wf_service.trg_validate(uid, 'purchase.order', p_id, 'purchase_confirm', cr)
-
I confirm purchase order for Buttons.
-
!python {model: purchase.order}: |
import netsvc
purch_ids = self.search(cr, uid, [('partner_id.name','=','ASUStek')])
wf_service = netsvc.LocalService("workflow")
for p_id in purch_ids:
wf_service.trg_validate(uid, 'purchase.order', p_id, 'purchase_confirm', cr)
-
I Check incoming shipments for cloth. And receive products.
-
!python {model: stock.picking}: |
pick_ids = self.search(cr, uid, [('address_id.name','=','Wong'),('state','=','assigned')])
assert pick_ids, 'No Incoming Shipments found!'
stock_partial_picking = self.pool.get('stock.partial.picking')
for pick_id in pick_ids:
partial_id = stock_partial_picking.create(cr, uid, {},
context={'active_model': 'stock.picking',
'active_ids': [pick_id]})
stock_partial_picking.do_partial(cr, uid, [partial_id])
-
I Check incoming shipments for buttons and receive products.
-
!python {model: stock.picking}: |
pick_ids = self.search(cr, uid, [('address_id.name','=','Tang'),('state','=','assigned')])
assert pick_ids, 'No Incoming Shipments found!'
stock_partial_picking = self.pool.get('stock.partial.picking')
for pick_id in pick_ids:
partial_id = stock_partial_picking.create(cr, uid, {},
context={'active_model': 'stock.picking',
'active_ids': [pick_id]})
stock_partial_picking.do_partial(cr, uid, [partial_id])
-
Run scheduler again.
-
!function {model: procurement.order, name: run_scheduler}:
- model: procurement.order
search: "[]"
-
Check state of manufacturing order for Shirt.
-
!python {model: mrp.production}: |
from tools.translate import _
order_ids = self.search(cr, uid, [('product_id','=',ref('product_product_shirt0')),('state','=','ready')])
assert order_ids, 'No Manufacturing Order in Ready state.'
-
I start production order for Shirt.
-
!python {model: mrp.production}: |
from tools.translate import _
import netsvc
prod_ids = self.search(cr, uid, [('state','=','ready')])
assert prod_ids, _('No Ready Manufacturing Orders found!')
wf_service = netsvc.LocalService("workflow")
for p_id in prod_ids:
wf_service.trg_validate(uid, 'mrp.production', p_id, 'button_produce', cr)
-
I create record for producing products with quantity 5.00.
-
!record {model: mrp.product.produce, id: mrp_product_produce0}:
product_qty: 2.00
mode: 'consume_produce'
-
I produce 2 products with 5.00 quantities each.
-
!python {model: mrp.product.produce}: |
prod_obj = self.pool.get('mrp.production')
prod_ids = prod_obj.search(cr, uid, [('product_id.name','=','Shirt')])
self.do_produce(cr, uid, [ref('mrp_product_produce0')], context={'active_ids': prod_ids})
-
I create record for remaining products with quantity 35.00.
-
!record {model: stock.move.consume, id: stock_move_consume0}:
product_id: product_product_buttons0
product_qty: 35.00
product_uom: product.product_uom_unit
location_id: stock.stock_location_stock
-
I produce remaining product Buttons with 35.00 quantity.
-
!python {model: stock.move.consume}: |
from tools.translate import _
stock_obj = self.pool.get('stock.move')
stock_ids = stock_obj.search(cr, uid, [('product_id.name','=','Buttons')])
self.do_move_consume(cr, uid, [ref('stock_move_consume0')], context={'active_ids': stock_ids})
-
And finally production order is done.
-
!python {model: mrp.product.produce}: |
prod_obj = self.pool.get('mrp.production')
prod_ids = prod_obj.search(cr, uid, [('product_id.name','=','Shirt')])
self.do_produce(cr, uid, [ref('mrp_product_produce0')], context={'active_ids': prod_ids})
-29
View File
@@ -1,29 +0,0 @@
-
In order to test the manufacturing order in Openerp,
I am creating one manufacturing order
-
!record {model: mrp.production, id: mrp_production_mo1}:
company_id: base.main_company
date_planned: !eval datetime.today().strftime("%Y-%m-%d %H:%M:%S")
location_dest_id: stock.stock_location_stock
location_src_id: stock.stock_location_stock
product_id: product.product_product_pc1
name: MO/01234
product_qty: 5.0
product_uom: product.product_uom_unit
product_uos_qty: 0.0
-
I confirm the order.
-
!workflow {model: mrp.production, action: button_confirm, ref: mrp_production_mo1}
-
In order to cancel the MO, I first cancel its picking.
-
!python {model: stock.picking}: |
mrp_obj = self.pool.get('mrp.production')
mo = mrp_obj.browse(cr, uid, ref("mrp_production_mo1"))
self.action_cancel(cr, uid, [mo.picking_id.id], context=None)
-
Then I Cancel the production order and related stock moves.
-
!workflow {model: mrp.production, action: button_cancel, ref: mrp_production_mo1}
-119
View File
@@ -1,119 +0,0 @@
-
In order to test the manufacturing order working with procurements I will use
some products with different supply method and procurement method, also check
the bills of material for the products.
-
I am creating one manufacturing order.
-
!record {model: mrp.production, id: mrp_production_mo1}:
company_id: base.main_company
date_planned: !eval datetime.today().strftime("%Y-%m-%d %H:%M:%S")
location_dest_id: stock.stock_location_stock
location_src_id: stock.stock_location_stock
product_id: product.product_product_pc1
name: MO/0123
product_qty: 5.0
product_uom: product.product_uom_unit
product_uos_qty: 0.0
-
I compute the data.
-
!python {model: mrp.production}: |
self.action_compute(cr, uid, [ref("mrp_production_mo1")])
-
I confirm the order.
-
!workflow {model: mrp.production, action: button_confirm, ref: mrp_production_mo1}
-
I create record for changing production quantity to 6.00
-
!record {model: change.production.qty, id: mrp_production_qty}:
product_qty: 6.0
-
Changes the Quantity of Product.
-
!python {model: change.production.qty}: |
context = {"lang": 'en_US', "active_model":"mrp.production", "active_ids": [ref("mrp_production_mo1")], "tz": False, "active_id":ref('mrp_production_mo1')}
self.default_get(cr, uid, ["product_qty"], context)
self.change_prod_qty(cr, uid, [ref("mrp_production_qty")], context=context)
-
I check now quantity of the production order is 6 or not.
-
!assert {model: mrp.production, id: mrp_production_mo1}:
- product_qty == 6
-
I am checking Procurement orders for components of PC1.
-
!python {model: procurement.order}: |
from tools.translate import _
production_obj = self.pool.get('mrp.production')
production = production_obj.browse(cr, uid, ref('mrp_production_mo1'))
product_ids = map(lambda x:x.product_id.id, production.move_lines)
proc_ids = self.search(cr, uid, [('product_id','in',product_ids)])
assert proc_ids, _('No Procurements!')
-
The scheduler runs.
-
!function {model: procurement.order, name: run_scheduler}:
- model: procurement.order
search: "[]"
-
I am checking Internal picking.
-
!python {model: stock.picking}: |
from tools.translate import _
pick_ids = self.search(cr, uid, [('type','=','internal')])
assert pick_ids, _('No Internal Pickings!')
-
I see that there is a manufacturing order for the sub product CPU_GEN with ready state and I start production of it.
-
!python {model: mrp.production}: |
from tools.translate import _
order_ids = self.search(cr, uid, [('state','=','ready'), ('product_id', '=', ref('product.product_product_cpu_gen'))])
assert order_ids, _('No manufacturing order in Ready state!')
import netsvc
wf_service = netsvc.LocalService("workflow")
for order in order_ids:
wf_service.trg_validate(uid, 'mrp.production', order, 'button_produce', cr)
-
I create record for producing products with quantity 1.00.
-
!record {model: mrp.product.produce, id: mrp_product_produce0}:
product_qty: 1.00
mode: 'consume_produce'
-
I produce the product.
-
!python {model: mrp.product.produce}: |
prod_obj = self.pool.get('mrp.production')
prod_ids = prod_obj.search(cr, uid, [('state','=','in_production'), ('product_id', '=', ref('product.product_product_cpu_gen'))])
self.do_produce(cr, uid, [ref('mrp_product_produce0')], context={'active_ids': prod_ids})
-
Now the manufacturing order for subproduct CPU_GEN is done and manufacturing
order for PC1 is in ready state.
-
!python {model: mrp.production}: |
from tools.translate import _
prod_ids = self.search(cr, uid, [('state','=','done'), ('product_id', '=', ref('product.product_product_cpu_gen'))])
assert prod_ids, _('Manufacturing order for CPU_GEN is yet not done!')
-
I start producing the product PC1.
-
!workflow {model: mrp.production, action: button_produce, ref: mrp_production_mo1}
-
I create record for producing products with quantity 6.00.
-
!record {model: mrp.product.produce, id: mrp_product_produce1}:
product_qty: 6.00
mode: 'consume_produce'
-
Finally my production order is done.
-
!python {model: mrp.product.produce}: |
context = {"lang": 'en_US', "active_model":"mrp.production", "active_ids": [ref("mrp_production_mo1")], "tz": False, "active_id":ref('mrp_production_mo1')}
self.do_produce(cr, uid, [ref('mrp_product_produce1')], context=context)
-
I check now the production order for PC1 is done.
-
!assert {model: mrp.production, id: mrp_production_mo1}:
- state == 'done'
-38
View File
@@ -1,38 +0,0 @@
-
In order to test the PDF reports defined on a MRP, we will print a BOM Structure Report
-
!python {model: mrp.bom}: |
import netsvc, tools, os
(data, format) = netsvc.LocalService('report.bom.structure').create(cr, uid, [ref('mrp.mrp_bom_0'),ref('mrp.mrp_bom_1'),ref('mrp.mrp_bom_2'),ref('mrp.mrp_bom_23'),ref('mrp.mrp_bom_1901'),ref('mrp.mrp_bom_assemblysection0'),ref('mrp.mrp_bom_sidepanel0'),ref('mrp.mrp_bom_defaultbomforshelfofcm1'),ref('mrp.mrp_bom_sidepanel3')], {}, {})
if tools.config['test_report_directory']:
file(os.path.join(tools.config['test_report_directory'], 'mrp-bom_structure_report.'+format), 'wb+').write(data)
-
In order to test the PDF reports defined on a MRP, we will print Production Order Report
-
!python {model: mrp.production}: |
import netsvc, tools, os
(data, format) = netsvc.LocalService('report.mrp.production.order').create(cr, uid, [ref('mrp.mrp_production_mo1')], {}, {})
if tools.config['test_report_directory']:
file(os.path.join(tools.config['test_report_directory'], 'mrp-production_order_report.'+format), 'wb+').write(data)
-
Print Product Price Report through the wizard
-
!python {model: product.product}: |
ctx={}
ctx.update({'model': 'product.product','active_ids': [1,2,3,5]})
data_dict = {'number': 1}
from tools import test_reports
test_reports.try_report_action(cr, uid, 'action_view_mrp_product_price_wizard',wiz_data=data_dict, context=ctx, our_module='mrp')
-
Print Work Center Load Report through the wizard
-
!python {model: mrp.workcenter}: |
ctx={}
ctx.update({'model': 'mrp.workcenter','active_ids': [ref('mrp_workcenter_0'),ref('mrp_workcenter_1')]})
data_dict = {'time_unit': 'day', 'measure_unit': 'hours'}
from tools import test_reports
test_reports.try_report_action(cr, uid, 'action_mrp_workcenter_load_wizard',wiz_data=data_dict, context=ctx, our_module='mrp')
+27
View File
@@ -0,0 +1,27 @@
-
In order to test process of production order, I create Bill of material of Shelf 100cm.
-
!record {model: mrp.bom, id: mrp_bom_defaultbomforshelfofcm0}:
product_id: product.product_product_shelfofcm0
-
!record {model: mrp.bom, id: mrp_bom_assemblysection1}:
routing_id: mrp.mrp_routing_0
-
!record {model: mrp.bom, id: mrp_bom_rearpanelarm1}:
routing_id: mrp.mrp_routing_0
-
I create Production Order of Shelf 100cm to produce 5.0 Dozen PCE.
-
!record {model: mrp.production, id: mrp_production_shelf100cm}:
location_src_id: stock.stock_location_stock
location_dest_id: stock.stock_location_output
product_id: product.product_product_shelfofcm0
bom_id: mrp_bom_defaultbomforshelfofcm0
routing_id: mrp.mrp_routing_1
product_uom: product.product_uom_dozen
product_qty: 5.0
-
!record {model: mrp.workcenter, id: mrp_workcenter_0}:
product_id: product.product_assembly
+309
View File
@@ -0,0 +1,309 @@
-
I compute the production order.
-
!python {model: mrp.production}: |
order = self.browse(cr, uid, ref("mrp_production_shelf100cm"), context=context)
order.action_compute(context=context)
-
I check production lines after compute.
-
!python {model: mrp.production}: |
order = self.browse(cr, uid, ref("mrp_production_shelf100cm"), context=context)
assert len(order.product_lines) == 5, "Production lines are not generated proper."
factor = 12.0*5.0
sidepanel = False
woodlintelm = False
woodmm0 = False
woodmm10 = False
metalcleats = False
for line in order.product_lines:
if line.product_id.id == ref('product.product_product_sidepanel0'): #SIDEPAN 2 PCE
assert not sidepanel, "Production line is already generated for SIDEPAN."
assert line.product_qty == (2.0*factor), "Qty is not correspond."
assert line.product_uom.id == ref('product.product_uom_unit'), "UOM is not correspond"
sidepanel = True
elif line.product_id.id == ref('product.product_product_woodlintelm0'): #LIN40 4*0.25 Meter
assert not woodlintelm, "Production line is already generated for LIN40."
assert line.product_qty == (4*0.25*factor), "Qty is not correspond."
assert line.product_uom.id == ref('product.product_uom_meter'), "UOM is not correspond"
woodlintelm = True
elif line.product_id.id == ref('product.product_product_woodmm0'): #WOOD002 0.25 m
assert not woodmm0, "Production line is already generated for WOOD002."
assert line.product_qty == (0.25*factor), "Qty is not correspond."
assert line.product_uom.id == ref('product.product_uom_meter'), "UOM is not correspond"
woodmm0 = True
elif line.product_id.id == ref('product.product_product_metalcleats0'): #METC000 4*3 PCE
assert not metalcleats, "Production line is already generated for METC000."
assert line.product_qty == (4*3*factor), "Qty is not correspond."
assert line.product_uom.id == ref('product.product_uom_unit'), "UOM is not correspond"
metalcleats = True
elif line.product_id.id == ref('product.product_product_woodmm10'): #WOOD010 0.083*3 m
assert not woodmm10, "Production line is already generated for WOOD010."
assert line.product_qty == (0.083*3*factor), "Qty is not correspond."
assert line.product_uom.id == ref('product.product_uom_meter'), "UOM is not correspond"
woodmm10 = True
else:
raise AssertionError('unknown order line: %s' % line)
assert sidepanel, "Production line is not generated for SIDEPAN."
assert woodlintelm, "Production line is not generated for LIN40."
assert woodmm0, "Production line is not generated for WOOD002."
assert metalcleats, "Production line is not generated for METC000."
assert woodmm10, "Production line is not generated for WOOD010."
-
Now I check workcenter lines.
-
!python {model: mrp.production}: |
order = self.browse(cr, uid, ref("mrp_production_shelf100cm"), context=context)
assert len(order.workcenter_lines), "Workcenter lines are not generated proper."
for line in order.workcenter_lines:
wc = line.workcenter_id
hours = ((wc.time_start or 0.0)+(wc.time_stop or 0.0)+line.cycle*(wc.time_cycle or 0.0)) * (wc.time_efficiency or 1.0)
factor = 5*12
d, m = divmod(factor, wc.capacity_per_cycle)
cycle = (d + (m and 1.0 or 0.0))
if line.name == "Short time assembly - Assembly Section":
assert line.sequence, "Sequence is not correspond: %s" % (line.name)
assert line.cycle == (4*cycle), "Cycle is not correspond: %s" % (line.name)
assert line.hour == (2*cycle*4 + hours), "Hours is not correspond: %s"% (line.name)
elif line.name == "Short time assembly - Rear Panel SHE100":
assert line.sequence, "Sequence is not correspond: %s" % (line.name)
assert line.cycle == (1*cycle), "Cycle is not correspond: %s" % (line.name)
assert line.hour == (2*cycle + hours), "Hours is not correspond: %s"% (line.name)
elif line.name == "long time assembly - Shelf of 100cm":
assert line.sequence, "Sequence is not correspond: %s" % (line.name)
assert line.cycle == (2*cycle), "Cycle is not correspond: %s" % (line.name)
assert line.hour == (5*cycle + hours), "Hours is not correspond: %s"% (line.name)
elif line.name == "Testing - Shelf of 100cm":
assert line.sequence, "Sequence is not correspond: %s" % (line.name)
assert line.cycle == (1*cycle), "Cycle is not correspond: %s" % (line.name)
assert line.hour == (1*cycle + hours), "Hours is not correspond: %s"% (line.name)
elif line.name == "Packing - Shelf of 100cm":
assert line.sequence, "Sequence is not correspond: %s" % (line.name)
assert line.cycle == (1*cycle), "Cycle is not correspond: %s" % (line.name)
assert line.hour == (0.5*cycle + hours), "Hours is not correspond: %s"% (line.name)
else:
raise AssertionError('unknown workcenter line: %s' % line)
-
I confirm the Production Order.
-
!workflow {model: mrp.production, action: button_confirm, ref: mrp_production_shelf100cm}
-
I check details of Produce Move of Production Order to trace Final Product.
-
!python {model: mrp.production}: |
order = self.browse(cr, uid, ref("mrp_production_shelf100cm"))
assert order.state == 'confirmed', "Production order should be confirmed."
assert order.move_created_ids, "Trace Record is not created for Final Product."
move = order.move_created_ids[0]
source_location_id = order.product_id.product_tmpl_id.property_stock_production.id
assert move.date == order.date_planned, "Planned date is not correspond."
assert move.product_id.id == order.product_id.id, "Product is not correspond."
assert move.product_uom.id == order.product_uom.id, "UOM is not correspond."
assert move.product_qty == order.product_qty, "Qty is not correspond."
assert move.product_uos_qty == order.product_uos and order.product_uos_qty or order.product_qty, "UOS qty is not correspond."
if order.product_uos:
assert move.product_uos.id == order.product_uos.id, "UOS is not correspond."
assert move.location_id.id == source_location_id, "Source Location is not correspond."
assert move.location_dest_id.id == order.location_dest_id.id, "Destination Location is not correspond."
routing_loc = None
if order.bom_id.routing_id and order.bom_id.routing_id.location_id:
routing_loc = order.bom_id.routing_id.location_id.id
date_planned = order.date_planned
for move_line in order.move_lines:
for order_line in order.product_lines:
if move_line.product_id.type not in ('product', 'consu'):
continue
if move_line.product_id.id == order_line.product_id.id:
assert move_line.date == date_planned, "Planned date is not correspond in 'To consume line'."
assert move_line.product_qty == order_line.product_qty, "Qty is not correspond in 'To consume line'."
assert move_line.product_uom.id == order_line.product_uom.id, "UOM is not correspond in 'To consume line'."
assert move_line.product_uos_qty == order_line.product_uos and order_line.product_uos_qty or order_line.product_qty, "UOS qty is not correspond in 'To consume line'."
if order_line.product_uos:
assert move_line.product_uos.id == order_line.product_uos.id, "UOS is not correspond in 'To consume line'."
assert move_line.location_id.id == routing_loc or order.location_src_id.id, "Source location is not correspond in 'To consume line'."
assert move_line.location_dest_id.id == source_location_id, "Destination Location is not correspond in 'To consume line'."
-
I check details of an Internal Shipment after confirmed production order to bring components in Raw Materials Location.
-
!python {model: mrp.production}: |
procurement = self.pool.get('procurement.order')
order = self.browse(cr, uid, ref("mrp_production_shelf100cm"))
assert order.picking_id, 'Internal Shipment should be created!'
routing_loc = None
pick_type = 'internal'
address_id = False
if order.bom_id.routing_id and order.bom_id.routing_id.location_id:
routing_loc = order.bom_id.routing_id.location_id
if routing_loc.usage <> 'internal':
pick_type = 'out'
address_id = routing_loc.address_id and routing_loc.address_id.id or False
routing_loc = routing_loc.id
assert order.picking_id.type == pick_type, "Shipment should be Internal."
assert order.picking_id.address_id.id == address_id, "Shipment Address is not correspond with Adderss of Routing Location."
date_planned = order.date_planned
for move_line in order.picking_id.move_lines:
for order_line in order.product_lines:
if move_line.product_id.type not in ('product', 'consu'):
continue
if move_line.product_id.id == order_line.product_id.id:
assert move_line.date == date_planned, "Planned date is not correspond."
assert move_line.product_qty == order_line.product_qty, "Qty is not correspond."
assert move_line.product_uom.id == order_line.product_uom.id, "UOM is not correspond."
assert move_line.product_uos_qty == order_line.product_uos and order_line.product_uos_qty or order_line.product_qty, "UOS qty is not correspond."
if order_line.product_uos:
assert move_line.product_uos.id == order_line.product_uos.id, "UOS is not correspond."
assert move_line.location_id.id == order.location_src_id.id, "Source location is not correspond."
assert move_line.location_dest_id.id == routing_loc or order.location_src_id.id, "Destination Location is not correspond."
procurement_ids = procurement.search(cr, uid, [('move_id','=',move_line.id)])
assert procurement_ids, "Procurement should be created for shipment line of raw materials."
shipment_procurement = procurement.browse(cr, uid, procurement_ids[0], context=context)
assert shipment_procurement.date_planned == date_planned, "Planned date is not correspond in procurement."
assert shipment_procurement.product_id.id == order_line.product_id.id, "Product is not correspond in procurement."
assert shipment_procurement.product_qty == order_line.product_qty, "Qty is not correspond in procurement."
assert shipment_procurement.product_uom.id == order_line.product_uom.id, "UOM is not correspond in procurement."
assert shipment_procurement.product_uos_qty == order_line.product_uos and order_line.product_uos_qty or order_line.product_qty, "UOS qty is not correspond in procurement."
if order_line.product_uos:
assert shipment_procurement.product_uos.id == order_line.product_uos.id, "UOS is not correspond in procurement."
assert shipment_procurement.location_id.id == order.location_src_id.id, "Location is not correspond in procurement."
assert shipment_procurement.procure_method == order_line.product_id.procure_method, "Procure method is not correspond in procurement."
-
I change production qty with 3 Dozen Shelf 100cm.
-
!python {model: change.production.qty}: |
context.update({'active_id': ref('mrp_production_shelf100cm')})
-
!record {model: change.production.qty, id: mrp_production_qty}:
product_qty: 3.0
-
!python {model: change.production.qty}: |
self.change_prod_qty(cr, uid, [ref("mrp_production_qty")], context=context)
-
I check qty after changed in production order.
-
!python {model: mrp.production}: |
order = self.browse(cr, uid, ref("mrp_production_shelf100cm"))
assert order.product_qty == 3, "Qty is not changed in order."
move = order.move_created_ids[0]
assert move.product_qty == order.product_qty, "Qty is not changed in move line."
-
I run scheduler.
-
!python {model: procurement.order}: |
self.run_scheduler(cr, uid)
-
The production order is Waiting Goods, I forcefully done internal shipment.
-
!python {model: mrp.production}: |
self.force_production(cr, uid, [ref("mrp_production_shelf100cm")])
-
I check that production order in ready state after forcefully done internal shipment.
-
!python {model: mrp.production}: |
order = self.browse(cr, uid, ref("mrp_production_shelf100cm"))
assert order.state == 'ready', 'Production order should be in Ready State.'
assert order.picking_id.state == 'done', 'Internal shipment should be done.'
-
Now I start production.
-
!workflow {model: mrp.production, action: button_produce, ref: mrp_production_shelf100cm}
-
I check that production order in production state after start production.
-
!python {model: mrp.production}: |
order = self.browse(cr, uid, ref("mrp_production_shelf100cm"))
assert order.state == 'in_production', 'Production order should be in production State.'
-
I consume raw materials and put one material in scrap location due to waste it.
-
!python {model: mrp.production}: |
scrap_location_ids = self.pool.get('stock.location').search(cr, uid, [('scrap_location','=',True)])
scrap_location_id = scrap_location_ids[0]
order = self.browse(cr, uid, ref("mrp_production_shelf100cm"))
for move in order.move_lines:
move.action_consume(move.product_qty)
if move.product_id.id == ref("product.product_product_metalcleats0"):
move.action_scrap(5.0, scrap_location_id)
-
I produce product.
-
!python {model: mrp.product.produce}: |
context.update({'active_id': ref('mrp_production_shelf100cm')})
-
!record {model: mrp.product.produce, id: mrp_product_produce1}:
mode: 'consume_produce'
-
!python {model: mrp.product.produce}: |
self.do_produce(cr, uid, [ref('mrp_product_produce1')], context=context)
-
I check production order after produced.
-
!python {model: mrp.production}: |
order = self.browse(cr, uid, ref("mrp_production_shelf100cm"))
assert order.state == 'done', "Production order should be closed."
-
I check Total Costs at End of Production.
-
!python {model: mrp.production}: |
order = self.browse(cr, uid, ref("mrp_production_shelf100cm"))
account_analytic_line = self.pool.get('account.analytic.line')
def rounding(f, r):
import math
if not r:
return f
return math.ceil(f / r) * r
for wc_line in order.workcenter_lines:
wc = wc_line.workcenter_id
accounts = [wc.costs_hour_account_id, wc.costs_cycle_account_id]
cost_per_cyle = wc_line.cycle * wc.costs_cycle
cost_per_hours = wc_line.hour * wc.costs_hour
if accounts and wc.costs_journal_id and wc.costs_general_account_id and (cost_per_cyle or cost_per_hours):
line_ids = account_analytic_line.search(cr, uid, [('name','ilike',wc_line.name)])
assert line_ids, 'Costs lines are not generated.'
for line in account_analytic_line.browse(cr, uid, line_ids, context=context):
if wc.costs_hour_account_id and line.account_id.id == wc.costs_hour_account_id.id:
assert rounding(line.unit_amount, 3) == rounding(wc_line.hour, 3), "Cost Unit Amount is not correspond."
assert rounding(line.amount, 3) == rounding(cost_per_hours, 3), "Cost amount is not correspond."
elif wc.costs_cycle_account_id and line.account_id.id == wc.costs_cycle_account_id.id:
assert rounding(line.unit_amount, 3) == rounding(wc_line.cycle, 3), "Cost Unit Amount is not correspond."
assert rounding(line.amount, 3) == rounding(cost_per_cyle, 3), "Cost Amount is not correspond."
else:
raise AssertionError('unknown cost line: %s' % line)
assert line.general_account_id.id == wc.costs_general_account_id.id, "General Account is not correspond."
assert line.journal_id.id == wc.costs_journal_id.id, "Account Journal is not correspond."
assert line.product_id.id == wc.product_id.id, "Product is not correspond."
assert line.product_uom_id.id == wc.product_id.uom_id.id, "UOM is not correspond."
-
I print a "BOM Structure".
-
!python {model: mrp.production}: |
import netsvc, tools, os
order = self.browse(cr, uid, ref("mrp_production_shelf100cm"))
(data, format) = netsvc.LocalService('report.bom.structure').create(cr, uid, [order.bom_id.id], {}, {})
if tools.config['test_report_directory']:
file(os.path.join(tools.config['test_report_directory'], 'mrp-bom_structure_report.'+format), 'wb+').write(data)
-
I print "Production Order".
-
!python {model: mrp.production}: |
import netsvc, tools, os
(data, format) = netsvc.LocalService('report.mrp.production.order').create(cr, uid, [ref("mrp_production_shelf100cm")], {}, {})
if tools.config['test_report_directory']:
file(os.path.join(tools.config['test_report_directory'], 'mrp-production_order_report.'+format), 'wb+').write(data)
-
I print "Work Center Load Report".
-
!python {model: mrp.workcenter}: |
ctx = context.copy()
ctx.update({'model': 'mrp.workcenter','active_ids': [ref('mrp_workcenter_0'),ref('mrp_workcenter_1')]})
data_dict = {'time_unit': 'day', 'measure_unit': 'hours'}
from tools import test_reports
test_reports.try_report_action(cr, uid, 'action_mrp_workcenter_load_wizard',wiz_data=data_dict, context=ctx, our_module='mrp')
+5 -16
View File
@@ -60,22 +60,11 @@ class mrp_product_produce(osv.osv_memory):
}
def do_produce(self, cr, uid, ids, context=None):
""" To check the product type
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: the ID or list of IDs if we want more than one
@param context: A standard dictionary
@return:
"""
if context is None:
context = {}
prod_obj = self.pool.get('mrp.production')
move_ids = context.get('active_ids', [])
for data in self.browse(cr, uid, ids, context=context):
for move_id in move_ids:
prod_obj.action_produce(cr, uid, move_id,
data.product_qty, data.mode, context=context)
production_id = context.get('active_id', False)
assert production_id, "Production Id should be specified in context as a Active ID"
data = self.browse(cr, uid, ids[0], context=context)
self.pool.get('mrp.production').action_produce(cr, uid, production_id,
data.product_qty, data.mode, context=context)
return {}
mrp_product_produce()
+5 -2
View File
@@ -65,8 +65,11 @@ So that we can compare the theoretic delay and real delay.
'process/mrp_operation_process.xml',
'mrp_operations_workflow_instance.xml'
],
'demo_xml': ['mrp_operation_data.xml'],
'test': ['test/mrp_operations.yml', 'test/mrp_operations_report.yml','test/mrp_operation_test.yml'],
'demo_xml': ['mrp_operation_data.xml',
'mrp_operations_demo.yml'],
'test': [
'test/workcenter_operations.yml',
],
'installable': True,
'active': False,
'certificate': '0056233813133',
+4 -3
View File
@@ -350,6 +350,7 @@ class mrp_production(osv.osv):
if l.production_id and (l.production_id.date_start < po.date_finished):
self.write(cr, uid, [l.production_id.id], {'date_start': po.date_finished})
break
return True
def write(self, cr, uid, ids, vals, context=None, update=True, mini=True):
@@ -371,13 +372,13 @@ class mrp_production(osv.osv):
pass
return result
def action_compute(self, cr, uid, ids, properties=[]):
def action_compute(self, cr, uid, ids, properties=[], context=None):
""" Computes bills of material of a product and planned date of work order.
@param properties: List containing dictionaries of properties.
@return: No. of products.
"""
result = super(mrp_production, self).action_compute(cr, uid, ids, properties=properties)
self._compute_planned_workcenter(cr, uid, ids, context={})
result = super(mrp_production, self).action_compute(cr, uid, ids, properties=properties, context=context)
self._compute_planned_workcenter(cr, uid, ids, context=context)
return result
mrp_production()
@@ -0,0 +1,24 @@
-
!record {model: mrp.production, id: mrp_production_op}:
location_src_id: stock.stock_location_stock
product_id: product.product_product_cpu3
product_qty: 5.0
allow_reorder: True
-
!record {model: mrp.production, id: mrp_production_op1}:
location_src_id: stock.stock_location_stock
product_id: product.product_product_cpu3
product_qty: 2.0
-
!function {model: mrp.production, name: action_compute, id: mrp_production_op1}:
- model: mrp.production
eval: "[obj(ref('mrp_production_op1')).id]"
-
!workflow {model: mrp.production, action: button_confirm, ref: mrp_production_op1}
-
!record {model: mrp.production, id: mrp_production_mo1}:
location_src_id: stock.stock_location_stock
product_id: product.product_product_cpu_gen
product_qty: 5.0
-
!workflow {model: mrp.production, action: button_confirm, ref: mrp_production_mo1}
@@ -1,56 +0,0 @@
-
In order to test mrp_operations module in OpenERP,
I create a production order.
-
!record {model: mrp.production, id: mrp_production_mo1}:
company_id: base.main_company
date_planned: !eval datetime.today().strftime("%Y-%m-%d %H:%M:%S")
location_dest_id: stock.stock_location_stock
location_src_id: stock.stock_location_stock
name: MO/01234567
product_id: product.product_product_pc1
product_qty: 5.0
product_uom: product.product_uom_unit
product_uos_qty: 5.0
-
Now I confirm the production order.
-
!workflow {model: mrp.production, action: button_confirm, ref: mrp_production_mo1}
-
I check that there is one Work order generated related to the production order.
-
!python {model: mrp.production.workcenter.line}: |
from tools.translate import _
order_id = self.search(cr, uid, [('production_id','=', ref('mrp_production_mo1')),('state','=','draft')])
assert order_id, _('No work order defined for this production order!')
-
The scheduler runs.
-
!function {model: procurement.order, name: run_scheduler}:
- model: procurement.order
search: "[('state','=','confirmed')]"
-
I am checking Internal picking.
-
!python {model: mrp.production}: |
from tools.translate import _
pick_ids = self.browse(cr, uid, ref("mrp_production_mo1"))
assert pick_ids.picking_id.id, _('No Internal Picking generated!')
-
In order to cancel the MO, first cancel its picking
-
!python {model: stock.picking}: |
mrp_obj = self.pool.get('mrp.production')
mo = mrp_obj.browse(cr, uid, ref("mrp_production_mo1"))
self.action_cancel(cr, uid, [mo.picking_id.id], context=None)
-
Then cancel The Manufacturing order.
-
!workflow {model: mrp.production, action: button_cancel, ref: mrp_production_mo1}
-
I check that there is one Work order generated related to the production order that is cancelled or not.
-
!python {model: mrp.production.workcenter.line}: |
from tools.translate import _
order_id = self.search(cr, uid, [('production_id','=', ref('mrp_production_mo1')),('state','=','cancel')])
assert order_id, _('Work order is not cancelled for this production order!')
@@ -1,158 +0,0 @@
-
In order to test mrp_operations module in OpenERP I will put a Production order
and check its effects on Work orders.
-
I create a production order.
-
!record {model: mrp.production, id: mrp_production_mo0}:
company_id: base.main_company
date_planned: !eval datetime.today().strftime("%Y-%m-%d %H:%M:%S")
location_dest_id: stock.stock_location_stock
location_src_id: stock.stock_location_stock
name: MO/0123456
product_id: product.product_product_pc1
product_qty: 5.0
product_uom: product.product_uom_unit
product_uos_qty: 5.0
allow_reorder: True
-
I am computing the data.
-
!python {model: mrp.production}: |
self.action_compute(cr, uid, [ref("mrp_production_mo0")], {"lang": "en_US", "tz":
False, "search_default_current": 1, "active_model": "ir.ui.menu", "active_ids":
[ref("mrp.menu_mrp_production_action")], "active_id": ref("mrp.menu_mrp_production_action"),
})
-
Now I confirm my production order.
-
!workflow {model: mrp.production, action: button_confirm, ref: mrp_production_mo0}
-
I check that there is one Work order generated related to my production order.
-
!python {model: mrp.production.workcenter.line}: |
from tools.translate import _
order_id = self.search(cr, uid, [('production_id','=', ref('mrp_production_mo0')),('state','=','draft')])
assert order_id, _('No Work order define for this production order!')
-
The scheduler runs.
-
!function {model: procurement.order, name: run_scheduler}:
- model: procurement.order
search: "[('state','=','confirmed')]"
-
I am checking Internal picking.
-
!python {model: stock.picking}: |
from tools.translate import _
pick_ids = self.search(cr, uid, [('state','!=','done'),('type','=','internal')])
assert pick_ids, _('No Internal Pickings!')
-
I see that there is a manufacturing order for the sub product CPU_GEN of PC1 with ready state.
-
!python {model: mrp.production}: |
from tools.translate import _
order_ids = self.search(cr, uid, [('state','=','ready'),('origin','like','%MO/0123456')])
assert order_ids, _('No new manufacturing order!')
-
I check that there one more work order created for new production order.
-
!python {model: mrp.production.workcenter.line}: |
from tools.translate import _
prod_obj = self.pool.get('mrp.production')
prod_order_ids = prod_obj.search(cr, uid, [('state','=','ready'),('origin','like','%MO/0123456')])
workorder_id = self.search(cr, uid, [('production_id','=', prod_order_ids[0]),('state','=','draft')])
assert workorder_id, _('No Work order define for this production order!')
-
I start the second production order of the CPU_GEN product.
-
!python {model: mrp.production}: |
import netsvc
wf_service = netsvc.LocalService("workflow")
prod_order_ids = self.search(cr, uid, [('state','=','ready'),('origin','like','%MO/0123456')])
for po in prod_order_ids:
wf_service.trg_validate(uid, 'mrp.production', po, 'button_produce', cr)
-
I am creating a mrp.product.produce record
-
!record {model: mrp.product.produce, id: mrp_product_produce_0}:
mode: consume_produce
product_qty: 5.0
-
I produce the product CPU_GEN.
-
!python {model: mrp.product.produce}: |
prod_obj = self.pool.get('mrp.production')
prod_order_ids = prod_obj.search(cr, uid, [('origin','like','%MO/0123456')])
self.do_produce(cr, uid, [ref("mrp_product_produce_0")], {"lang": "en_US", "tz":
False, "search_default_current": 1, "active_model": "mrp.production", "active_ids":
prod_order_ids, "active_id": prod_order_ids[0], })
-
I check that my production order and its related work order is in done state.
-
!python {model: mrp.production.workcenter.line}: |
from tools.translate import _
prod_obj = self.pool.get('mrp.production')
prod_order_ids = prod_obj.search(cr, uid, [('origin','like','%MO/0123456')])
assert prod_order_ids, _('Workorder not found')
workorder_id = self.search(cr, uid, [('production_id','=', prod_order_ids[0])])
workorder_bro = self.browse(cr, uid, workorder_id[0])
assert workorder_bro.state == 'done', _('Work order is not done! It is %s') % workorder_bro.state
-
Now I check my original production order is now ready.
-
!python {model: mrp.production}: |
from tools.translate import _
prod_ids = self.search(cr, uid, [('id','=',ref('mrp_production_mo0')),('state','=','ready')])
assert prod_ids, _('Production order is not ready!')
-
I check that both internal pickings are done.
-
!python {model: stock.picking}: |
from tools.translate import _
pick_ids = self.search(cr, uid, [('state','=','done'),('type','=','internal')])
assert pick_ids, _('Internal pickings are not done!')
-
Now I start my first production order.
-
!workflow {model: mrp.production, action: button_produce, ref: mrp_production_mo0}
-
I check that the related work order is in progress state.
-
!python {model: mrp.production.workcenter.line}: |
from tools.translate import _
order_id = self.search(cr, uid, [('production_id','=', ref('mrp_production_mo0')),('state','=','startworking')])
assert order_id, _('Work order not started yet!')
-
I am creating a mrp.product.produce record.
-
!record {model: mrp.product.produce, id: mrp_product_produce_0}:
mode: consume_produce
product_qty: 5.0
-
I produce the product PC1.
-
!python {model: mrp.product.produce}: |
prod_obj = self.pool.get('mrp.production')
prod_order_ids = prod_obj.search(cr, uid, [('state','=','in_production')])
self.do_produce(cr, uid, [ref("mrp_product_produce_0")], {"lang": "en_US", "tz":
False, "search_default_current": 1, "active_model": "mrp.production", "active_ids":
[ref("mrp_production_mo0")], "active_id": ref("mrp_production_mo0"), })
-
I check the related work order is done.
-
!python {model: mrp.production.workcenter.line}: |
from tools.translate import _
order_id = self.search(cr, uid, [('production_id','=', ref('mrp_production_mo0')),('state','=','done')])
assert order_id, _('Work order not done yet!')
-
Calculates start date for stock moves finding interval from resource calendar.
-
!python {model: mrp.production}: |
self._move_pass(cr, uid, [ref('mrp_production_mo0')], context=None)
-
Calculates planned end date of production order.
-
!python {model: mrp.production}: |
mo = self.browse(cr, uid, ref("mrp_production_mo0"))
self._production_date_end(cr, uid, [ref("mrp_production_mo0")], mo.date_planned, False, context=None)
@@ -1,17 +0,0 @@
-
In order to test the PDF reports defined on a MRP Operations, we will print a Barcode Report
-
!python {model: mrp_operations.operation.code}: |
import netsvc, tools, os
(data, format) = netsvc.LocalService('report.mrp.code.barcode').create(cr, uid, [ref('mrp_operations.mrp_op_1'),ref('mrp_operations.mrp_op_2'),ref('mrp_operations.mrp_op_3'),ref('mrp_operations.mrp_op_4'),ref('mrp_operations.mrp_op_5')], {}, {})
if tools.config['test_report_directory']:
file(os.path.join(tools.config['test_report_directory'], 'mrp_operations-barcode_report.'+format), 'wb+').write(data)
-
In order to test the PDF reports defined on a MRP Operations, we will print Workcenter's Barcode Report
-
!python {model: mrp.workcenter}: |
import netsvc, tools, os
(data, format) = netsvc.LocalService('report.mrp.wc.barcode').create(cr, uid, [ref('mrp.mrp_workcenter_0'),ref('mrp.mrp_workcenter_1')], {}, {})
if tools.config['test_report_directory']:
file(os.path.join(tools.config['test_report_directory'], 'mrp_operations-workcenter_barcode_report.'+format), 'wb+').write(data)
@@ -0,0 +1,120 @@
-
I compute the production order.
-
!python {model: mrp.production}: |
order = self.browse(cr, uid, ref("mrp.mrp_production_shelf100cm"), context=context)
order.action_compute(context=context)
-
I check planned date in workcenter lines of production order.
-
!python {model: mrp.production}: |
order = self.browse(cr, uid, ref("mrp.mrp_production_shelf100cm"), context=context)
for line in order.workcenter_lines:
#TODO: to check start date of next line should be end of date of previous line.
assert line.date_planned, "Planned Start date is not computed: %s" %(line)
assert line.date_planned_end, "Planned End date is not computed: %s" %(line)
-
I confirm the Production Order.
-
!workflow {model: mrp.production, action: button_confirm, ref: mrp.mrp_production_shelf100cm}
-
I run scheduler.
-
!python {model: procurement.order}: |
self.run_scheduler(cr, uid)
-
I forcefully close internal shipment.
-
!python {model: mrp.production}: |
self.force_production(cr, uid, [ref("mrp.mrp_production_shelf100cm")])
-
I start production.
-
!workflow {model: mrp.production, action: button_produce, ref: mrp.mrp_production_shelf100cm}
-
Production start on first work center, so I start work operation on first work center.
-
!python {model: mrp.production}: |
import netsvc
order = self.browse(cr, uid, ref("mrp.mrp_production_shelf100cm"), context=context)
wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, 'mrp.production.workcenter.line', order.workcenter_lines[0].id, 'button_start_working', cr)
-
Now I pause first work operation due to technical fault of work center.
-
!python {model: mrp.production}: |
import netsvc
order = self.browse(cr, uid, ref("mrp.mrp_production_shelf100cm"), context=context)
wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, 'mrp.production.workcenter.line', order.workcenter_lines[0].id, 'button_pause', cr)
wf_service.trg_validate(uid, 'mrp.production.workcenter.line', order.workcenter_lines[0].id, 'button_resume', cr)
-
I resume first work operation.
-
!python {model: mrp.production}: |
import netsvc
order = self.browse(cr, uid, ref("mrp.mrp_production_shelf100cm"), context=context)
wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, 'mrp.production.workcenter.line', order.workcenter_lines[0].id, 'button_resume', cr)
-
I cancel first work operation.
-
!python {model: mrp.production}: |
import netsvc
order = self.browse(cr, uid, ref("mrp.mrp_production_shelf100cm"), context=context)
wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, 'mrp.production.workcenter.line', order.workcenter_lines[0].id, 'button_cancel', cr)
-
I reset first work operation and start after resolve techninal fault of work center.
-
!python {model: mrp.production}: |
import netsvc
order = self.browse(cr, uid, ref("mrp.mrp_production_shelf100cm"), context=context)
wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, 'mrp.production.workcenter.line', order.workcenter_lines[0].id, 'button_draft', cr)
wf_service.trg_validate(uid, 'mrp.production.workcenter.line', order.workcenter_lines[0].id, 'button_start_working', cr)
-
Now Finished work of first work operation so I close that operation.
-
!python {model: mrp.production}: |
import netsvc
order = self.browse(cr, uid, ref("mrp.mrp_production_shelf100cm"), context=context)
wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, 'mrp.production.workcenter.line', order.workcenter_lines[0].id, 'button_done', cr)
-
Now I close other operations after start one by one.
-
!python {model: mrp.production}: |
import netsvc
order = self.browse(cr, uid, ref("mrp.mrp_production_shelf100cm"), context=context)
wf_service = netsvc.LocalService("workflow")
for work_line in order.workcenter_lines[1:]:
wf_service.trg_validate(uid, 'mrp.production.workcenter.line', work_line.id, 'button_start_working', cr)
wf_service.trg_validate(uid, 'mrp.production.workcenter.line', work_line.id, 'button_done', cr)
-
I check that the production order is now done.
-
!python {model: mrp.production}: |
order = self.browse(cr, uid, ref("mrp.mrp_production_shelf100cm"), context=context)
print order.state
assert order.state == 'done', "Production should be closed after finished all operations."
-
I print a Barcode Report of Operation line.
-
!python {model: mrp_operations.operation.code}: |
import netsvc, tools, os
(data, format) = netsvc.LocalService('report.mrp.code.barcode').create(cr, uid, [ref('mrp_operations.mrp_op_1'),ref('mrp_operations.mrp_op_2'),ref('mrp_operations.mrp_op_3'),ref('mrp_operations.mrp_op_4'),ref('mrp_operations.mrp_op_5')], {}, {})
if tools.config['test_report_directory']:
file(os.path.join(tools.config['test_report_directory'], 'mrp_operations-barcode_report.'+format), 'wb+').write(data)
-
I print Workcenter's Barcode Report.
-
!python {model: mrp.workcenter}: |
import netsvc, tools, os
(data, format) = netsvc.LocalService('report.mrp.wc.barcode').create(cr, uid, [ref('mrp.mrp_workcenter_0'),ref('mrp.mrp_workcenter_1')], {}, {})
if tools.config['test_report_directory']:
file(os.path.join(tools.config['test_report_directory'], 'mrp_operations-workcenter_barcode_report.'+format), 'wb+').write(data)
+25 -2
View File
@@ -442,6 +442,16 @@
<field name="type">product</field>
<field name="categ_id" ref="product_category_shelves0"/>
</record>
<record id="product_product_span100" model="product.product">
<field name="default_code">SPAN100</field>
<field name="supply_method">produce</field>
<field eval="'make_to_order'" name="procure_method"/>
<field name="uom_id" ref="product_uom_unit"/>
<field name="uom_po_id" ref="product_uom_unit"/>
<field name="name">Shelf Panel</field>
<field name="type">product</field>
<field name="categ_id" ref="product_category_shelves0"/>
</record>
<record id="product_product_woodmm0" model="product.product">
<field name="default_code">WOOD002</field>
<field name="supply_method">buy</field>
@@ -455,6 +465,19 @@
<field name="categ_id" ref="product_category_rawmaterial0"/>
</record>
<record id="product_product_woodmm10" model="product.product">
<field name="default_code">WOOD010</field>
<field name="supply_method">buy</field>
<field name="standard_price">7.0</field>
<field name="uom_id" ref="product_uom_meter"/>
<field name="uom_po_id" ref="product_uom_meter"/>
<field name="name">Wood 10mm</field>
<field eval="2" name="seller_delay"/>
<field eval="7.0" name="sale_delay"/>
<field name="type">product</field>
<field name="categ_id" ref="product_category_rawmaterial0"/>
</record>
<record id="product_product_kitchendesignproject0" model="product.product">
<field name="default_code">PROJ</field>
<field name="supply_method">produce</field>
@@ -509,7 +532,7 @@
<record id="product_product_rearpanelarm0" model="product.product">
<field name="default_code">RPAN100</field>
<field name="supply_method">buy</field>
<field name="supply_method">produce</field>
<field name="standard_price">10.0</field>
<field eval="0" name="sale_ok"/>
<field name="uom_id" ref="product_uom_unit"/>
@@ -548,7 +571,7 @@
<record id="product_product_shelf0" model="product.product">
<field name="default_code">RCK100</field>
<field name="supply_method">buy</field>
<field name="supply_method">produce</field>
<field name="standard_price">5.0</field>
<field eval="0" name="sale_ok"/>
<field name="uom_id" ref="product_uom_unit"/>