diff --git a/addons/mrp/__openerp__.py b/addons/mrp/__openerp__.py
index f114660aecf..8d1fb018987 100644
--- a/addons/mrp/__openerp__.py
+++ b/addons/mrp/__openerp__.py
@@ -90,7 +90,6 @@ Dashboard provided by this module:
],
'demo_xml': [
'mrp_demo.xml',
- 'mrp_production_order_demo.yml'
],
'test': [
'test/order_demo.yml',
diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py
index 07c46c13017..d2760deedbd 100644
--- a/addons/mrp/mrp.py
+++ b/addons/mrp/mrp.py
@@ -312,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]
@@ -579,7 +580,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.
@@ -957,7 +958,7 @@ class mrp_production(osv.osv):
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 = move_obj.create(cr, uid, {
+ move_id = stock_move.create(cr, uid, {
'name': move_name,
'date': production.date_planned,
'product_id': production_line.product_id.id,
@@ -971,7 +972,7 @@ class mrp_production(osv.osv):
'state': 'waiting',
'company_id': production.company_id.id,
})
- production.write('move_lines': [(4, move_id)]}, context=context)
+ production.write({'move_lines': [(4, move_id)]}, context=context)
return move_id
def action_confirm(self, cr, uid, ids, context=None):
diff --git a/addons/mrp/mrp_demo.xml b/addons/mrp/mrp_demo.xml
index 4386c492b1f..45958601f05 100644
--- a/addons/mrp/mrp_demo.xml
+++ b/addons/mrp/mrp_demo.xml
@@ -559,73 +559,160 @@
-
+
+
Default BOM for Shelf of 100cm
SHE100
- 129
+ 10
1.0
-
- Assembly Section
- 123
-
-
- 4.0
-
-
-
+
+
Side Panel
- 125
+ 101
2.0
-
- Metal Cleats
- 127
-
+
+ Assembly Section
+ 102
+
- 12.0
+ 4.0
+ phantom
- 131
+ 103
1.0
Rear panel SHE100
+ phantom
- 133
+ 104
3.0
- Shelf 100
+ RCK100
+ phantom
+
+
+
+
+ 133
+
+
+ 1.0
+ RCK100
+
+
+ 1331
+
+
+
+ 1.0
+ phantom
+ SPAN100
+
+
+ 1332
+
+
+
+ 4.0
+ METC000
+
+
+
+ 135
+
+
+ 1.0
+ SPAN100
+
+
+ 1351
+
+
+
+ 0.083
+ WOOD010
+
+
+
+ Assembly Section
+ 123
+
+
+ 1.0
+
- 135
+ 1231
-
- 1.0
-
- Wood Lintel 4m
+ 0.25
+
+ Wood Lintel 0.25m
+
+
+ 131
+
+
+ 1.0
+ Rear panel SHE100
+
+
+ 1311
+
+
+
+ 0.25
+ WOOD002 0.25m
+
+
Default BOM for Shelf of 200cm
@@ -636,34 +723,14 @@
1.0
-
- Default BOM for KIT Shelf of 100cm
- SHE100KIT
- 139
-
-
- 1.0
- phantom
-
-
-
- Assembly Section
- 143
-
-
- 4.0
-
-
-
-
- Side Panel
- 145
-
-
- 2.0
-
-
-
+
147
@@ -709,18 +776,54 @@
+
+ Default BOM for KIT Shelf of 100cm
+ SHE100KIT
+ 139
+
+
+ 1.0
+ phantom
+
+
+
+
+
+ Assembly Section
+ 143
+
+
+ 4.0
+
+
+
+
+ Side Panel
+ 145
+
+
+ 2.0
+
+
+
+
+
- t
-
+ Dozen
+
bigger
-
- 5
+
+ 3
@@ -755,9 +858,10 @@
-
+
+ 1.0
@@ -769,7 +873,7 @@
-
+
@@ -784,7 +888,7 @@
-
+
@@ -874,7 +978,7 @@
-
+
@@ -889,7 +993,7 @@
-
+
diff --git a/addons/mrp/test/cancel_order.yml b/addons/mrp/test/cancel_order.yml
index 76f3a9cec3c..d10b8c1780b 100644
--- a/addons/mrp/test/cancel_order.yml
+++ b/addons/mrp/test/cancel_order.yml
@@ -1,28 +1,25 @@
-
- In order to test effect of cancelling Internal picking on production order, I first confirm order for PC3.
+ I first confirm order for shirt.
-
- !workflow {model: mrp.production, action: button_confirm, ref: mrp_production_order3}
--
- I check that the related internal picking is waiting availability.
--
- !assert {model: mrp.production, id: mrp_production_order3}:
- - picking_id.state == 'confirmed'
+ !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_order3')).picking_id.id]"
+ 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_order3}
+ !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_order3}:
+ !assert {model: mrp.production, id: mrp_production_shirt}:
- state == 'cancel'
-
- I remove this production order.
+ I remove cancelled production order.
-
- !delete {model: mrp.production, id: mrp_production_order3}
+ !python {model: mrp.production}: |
+ order = self.browse(cr, uid, ref("mrp_production_shirt"), context=context)
+ self.unlink(cr, uid, [order.id])
diff --git a/addons/mrp/test/order_demo.yml b/addons/mrp/test/order_demo.yml
index 4064262c78f..5015f604ce4 100644
--- a/addons/mrp/test/order_demo.yml
+++ b/addons/mrp/test/order_demo.yml
@@ -1,12 +1,16 @@
-
- !record {model: mrp.bom, id: mrp_bom_metalcleats3}:
- product_id: product.product_product_metalcleats0
-
+ In order to test process of production order, I create Bill of material of Shelf 100cm.
-
- !record {model: mrp.production, id: mrp_production_shelf}:
+ !record {model: mrp.bom, id: mrp_bom_defaultbomforshelfofcm0}:
+ product_id: product.product_product_shelfofcm0
+-
+ 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
+ product_uom: product.product_uom_dozen
product_qty: 5.0
diff --git a/addons/mrp/test/order_process.yml b/addons/mrp/test/order_process.yml
index bced289a2d9..ce1b8864422 100644
--- a/addons/mrp/test/order_process.yml
+++ b/addons/mrp/test/order_process.yml
@@ -1,11 +1,11 @@
-
- I change production qty with 3 Dozen Shelf 100cm.
+ I change production qty with 5 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
+ product_qty: 5.0
-
!python {model: change.production.qty}: |
self.change_prod_qty(cr, uid, [ref("mrp_production_qty")], context=context)
@@ -14,38 +14,58 @@
-
!python {model: mrp.production}: |
order = self.browse(cr, uid, ref("mrp_production_shelf100cm"))
- assert move.product_uom.id == ref("product.product_uom_dozen"), "UOM is not correspond."
- assert move.product_qty == 3, "Qty is not changed."
+ assert order.product_uom.id == ref("product.product_uom_dozen"), "UOM is not correspond."
+ assert order.product_qty == 5, "Qty is not changed."
-
I compute the production order.
-
!python {model: mrp.production}: |
order = self.browse(cr, uid, ref("mrp_production_shelf100cm"), context=context)
- order.action_compute()
+ 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.move_lines), "Production lines are not generated."
- for line in order.move_lines:
- if line.product_id.id == ref('product.product_product_assemblysection0'):
- assert line.product_qty == (4.0*3.0*12.0), "Qty is not correspond."
+ assert len(order.product_lines) == 5, "Production lines are not generated proper."
+ 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*12.0*5.0), "Qty is not correspond."
assert line.product_uom.id == ref('product.product_uom_unit'), "UOM is not correspond"
- elif line.product_id.id == ref('product.product_product_sidepanel0'):
- assert line.product_qty == (2.0*3.0*12.0), "Qty is not correspond."
- assert line.product_uom.id == ref('product.product_uom_unit'), "UOM is not correspond"
- elif line.product_id.id == ref('product.product_product_metalcleats0'):
- assert line.product_qty == (12.0*3.0*12.0), "Qty is not correspond."
- assert line.product_uom.id == ref('product.product_uom_unit'), "UOM is not correspond"
- elif line.product_id.id == ref('product.product_product_rearpanelarm0'):
- assert line.product_qty == (1.0*3.0*12.0), "Qty is not correspond."
- assert line.product_uom.id == ref('product.product_uom_unit'), "UOM is not correspond"
- elif line.product_id.id == ref('product.product_product_shelf0'):
- assert line.product_qty == (3.0*3.0*12.0), "Qty 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*12.0*5.0), "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*12.0*5.0), "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*12.0*5.0), "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*12.0*5.0), "Qty is not correspond."
+ assert line.product_uom.id == ref('product.product_uom_meter'), "UOM is not correspond"
+ woodmm10 = True
else:
- assert_exception("Lines are not correspond.")
+ 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."
-
I confirm the Production Order.
-
@@ -63,25 +83,27 @@
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 == order.product_uos, "UOS is not correspond."
- assert move.product_uos_qty == order.product_uos_qty, "UOS 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 production.bom_id.routing_id and production.bom_id.routing_id.location_id:
- routing_loc = production.bom_id.routing_id.location_id.id
-
+ 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 line.product_id.type not in ('product', 'consu'):
+ 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 False, "UOS qty is not correspond in 'To consume line'."
- assert move_line.product_uos == order_line.product_uos and order_line.product_uos.id or False, "UOS is not correspond in 'To consume line'."
- assert move_line.location_id.id == routing_loc or production.location_src_id.id, "Source location 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'."
-
@@ -95,37 +117,39 @@
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 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 == address_id, "Shipment Address is not correspond with Adderss of Routing Location."
- date_planned = production.date_planned
+ 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 line.product_id.type not in ('product', 'consu'):
+ 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 False, "UOS qty is not correspond."
- assert move_line.product_uos == order_line.product_uos and order_line.product_uos.id or False, "UOS is not correspond."
- assert move_line.location_id.id == production.location_src_id.id, "Source location is not correspond."
- assert move_line.location_dest_id.id == routing_loc or production.location_src_id.id, "Destination Location is not correspond."
- procurement_ids = procurement.search(cr, uid, [('move_id','=',move_line.id)]
+ 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_qty or False, "UOS qty is not correspond in procurement."
- assert shipment_procurement.product_uos.id == order_line.product_uos and order_line.product_uos.id or False, "UOS is not correspond in procurement."
- assert shipment_procurement.location_id.id == production.location_src_id.id, "Location 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."
@@ -181,8 +205,9 @@
-
I check production order after produced.
-
- !assert {model: mrp.production, id: mrp_production_shelf100cm}:
- - state == 'done'
+ !python {model: mrp.production}: |
+ order = self.browse(cr, uid, ref("mrp_production_shelf100cm"))
+ assert order.state == 'done', "Production order should be closed."
-
I print a "BOM Structure".
diff --git a/addons/mrp/wizard/mrp_product_produce.py b/addons/mrp/wizard/mrp_product_produce.py
index 4ae4a254d49..db4d6e77691 100644
--- a/addons/mrp/wizard/mrp_product_produce.py
+++ b/addons/mrp/wizard/mrp_product_produce.py
@@ -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')
- production_ids = context.get('active_ids', [])
- for data in self.browse(cr, uid, ids, context=context):
- for production_id in production_ids:
- prod_obj.action_produce(cr, uid, production_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()
diff --git a/addons/product/product_demo.xml b/addons/product/product_demo.xml
index 3aebec13715..99347667f80 100644
--- a/addons/product/product_demo.xml
+++ b/addons/product/product_demo.xml
@@ -442,6 +442,16 @@
product
+
+ SPAN100
+ produce
+
+
+
+ Shelf Panel
+ product
+
+
WOOD002
buy
@@ -455,6 +465,19 @@
+
+ WOOD010
+ buy
+ 7.0
+
+
+ Wood 10mm
+
+
+ product
+
+
+
PROJ
produce
@@ -509,7 +532,7 @@
RPAN100
- buy
+ produce
10.0
@@ -548,7 +571,7 @@
RCK100
- buy
+ produce
5.0