@@ -88,10 +88,11 @@
|
||||
'board_manufacturing_demo.xml'
|
||||
],
|
||||
'test': [
|
||||
'test/mrp_procurement.yml',
|
||||
'test/mrp_packs.yml',
|
||||
'test/mrp_phantom_bom.yml',
|
||||
'test/mrp_production_order.yml',
|
||||
'test/mrp_procurement.yml'
|
||||
|
||||
],
|
||||
'installable': True,
|
||||
'active': False,
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<field name="name">res.company.mrp.config</field>
|
||||
<field name="model">res.company</field>
|
||||
<field name="type">form</field>
|
||||
<field name="priority">22</field>
|
||||
<field name="inherit_id" ref="base.view_company_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<page string="Configuration" position="inside">
|
||||
|
||||
+2
-2
@@ -459,9 +459,9 @@ class mrp_production(osv.osv):
|
||||
help="This is the internal picking list that brings the finished product to the production plan"),
|
||||
'move_prod_id': fields.many2one('stock.move', 'Move product', readonly=True),
|
||||
'move_lines': many2many_domain('stock.move', 'mrp_production_move_ids', 'production_id', 'move_id', 'Products to Consume', domain=[('state','not in', ('done', 'cancel'))], states={'done':[('readonly',True)]}),
|
||||
'move_lines2': many2many_domain('stock.move', 'mrp_production_move_ids', 'production_id', 'move_id', 'Consumed Products', domain=[('state','in', ('done', 'cancel'))], readonly=True),
|
||||
'move_lines2': many2many_domain('stock.move', 'mrp_production_move_ids', 'production_id', 'move_id', 'Consumed Products', domain=[('state','in', ('done', 'cancel'))]),
|
||||
'move_created_ids': one2many_domain('stock.move', 'production_id', 'Moves Created', domain=[('state','not in', ('done', 'cancel'))], states={'done':[('readonly',True)]}),
|
||||
'move_created_ids2': one2many_domain('stock.move', 'production_id', 'Moves Created', domain=[('state','in', ('done', 'cancel'))], readonly=True),
|
||||
'move_created_ids2': one2many_domain('stock.move', 'production_id', 'Moves Created', domain=[('state','in', ('done', 'cancel'))]),
|
||||
'product_lines': fields.one2many('mrp.production.product.line', 'production_id', 'Scheduled goods'),
|
||||
'workcenter_lines': fields.one2many('mrp.production.workcenter.line', 'production_id', 'Work Centers Utilisation'),
|
||||
'state': fields.selection([('draft','Draft'),('picking_except', 'Picking Exception'),('confirmed','Waiting Goods'),('ready','Ready to Produce'),('in_production','In Production'),('cancel','Cancelled'),('done','Done')],'State', readonly=True,
|
||||
|
||||
@@ -713,6 +713,9 @@
|
||||
<field name="product_qty">12.0</field>
|
||||
<field name="bom_id" ref="mrp_bom_defaultbomforshelfofcm1"/>
|
||||
</record>
|
||||
|
||||
<!-- Run Scheduler -->
|
||||
<function model="procurement.order" name="run_scheduler"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
@@ -611,11 +611,11 @@
|
||||
<tree colors="red:scraped==True;blue:state in('draft');black:state in('picking_except','confirmed','ready','in_production');gray:state in('cancel','done') " string="Consumed Products" editable="bottom">
|
||||
<field name="product_id" readonly="1"/>
|
||||
<field name="product_qty" readonly="1" string="Qty"/>
|
||||
<field name="product_uom" readonly="1" string="UOM"/>
|
||||
<field name="location_dest_id" readonly="1" string="Destination Loc."/>
|
||||
<field name="prodlot_id" />
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="scraped" invisible="1"/>
|
||||
<field name="product_uom" readonly="1" string="UOM"/>
|
||||
<field name="location_dest_id" readonly="1" string="Destination Loc."/>
|
||||
<field name="prodlot_id" />
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="scraped" invisible="1"/>
|
||||
<button
|
||||
name="%(stock.track_line)d"
|
||||
string="Split in production lots"
|
||||
@@ -661,11 +661,11 @@
|
||||
<tree colors="red:scraped==True;blue:state in('draft');black:state in('picking_except','confirmed','ready','in_production');gray:state in('cancel','done') " string="Finished Products" editable="bottom">
|
||||
<field name="product_id" readonly="1"/>
|
||||
<field name="product_qty" readonly="1" string="Qty"/>
|
||||
<field name="product_uom" readonly="1" string="UOM"/>
|
||||
<field name="location_dest_id" readonly="1" string="Destination Loc."/>
|
||||
<field name="product_uom" readonly="1" string="UOM"/>
|
||||
<field name="location_dest_id" readonly="1" string="Destination Loc."/>
|
||||
<field name="prodlot_id" />
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="scraped" invisible="1"/>
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="scraped" invisible="1"/>
|
||||
<button name="%(stock.track_line)d"
|
||||
string="Split in production lots" type="action" icon="gtk-justify-fill" states="done,cancel"/>
|
||||
<button name="%(stock.move_scrap)d"
|
||||
|
||||
@@ -142,6 +142,9 @@
|
||||
<field name="signal">subflow.done</field>
|
||||
</record>
|
||||
|
||||
<record id="procurement.trans_confirm_confirm_wait" model="workflow.transition">
|
||||
<field name="condition">not test_cancel() and not get_phantom_bom_id()</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
@@ -48,6 +48,17 @@ class procurement_order(osv.osv):
|
||||
return False
|
||||
return True
|
||||
|
||||
def get_phantom_bom_id(self, cr, uid, ids, context=None):
|
||||
for procurement in self.browse(cr, uid, ids, context=context):
|
||||
if procurement.move_id and procurement.move_id.product_id.supply_method=='produce' \
|
||||
and procurement.move_id.product_id.procure_method=='make_to_order':
|
||||
phantom_bom_id = self.pool.get('mrp.bom').search(cr, uid, [
|
||||
('product_id', '=', procurement.move_id.product_id.id),
|
||||
('bom_id', '=', False),
|
||||
('type', '=', 'phantom')])
|
||||
return phantom_bom_id
|
||||
return False
|
||||
|
||||
def action_produce_assign_product(self, cr, uid, ids, context={}):
|
||||
""" This is action which call from workflow to assign production order to procurements
|
||||
@return: True
|
||||
|
||||
@@ -175,8 +175,11 @@
|
||||
<para style="terp_default_8">
|
||||
<font color="white"> </font>
|
||||
</para>
|
||||
<blockTable colWidths="399.0,128.0" style="Table3">
|
||||
<blockTable colWidths="200.0,199.0,128.0" style="Table2">
|
||||
<tr>
|
||||
<td>
|
||||
<para style="terp_tblheader_General_Centre">Source Document</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_tblheader_General_Centre">Product </para>
|
||||
</td>
|
||||
@@ -185,8 +188,11 @@
|
||||
</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
<blockTable colWidths="399.0,129.0" style="Table5">
|
||||
<blockTable colWidths="200.0,199.0,129.0" style="Table2">
|
||||
<tr>
|
||||
<td>
|
||||
<para style="terp_default_Centre_8">[[ o.origin ]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Centre_8">[[ o.product_id.code ]] [[ o.product_id.name ]]</para>
|
||||
</td>
|
||||
@@ -201,7 +207,7 @@
|
||||
<blockTable colWidths="193.0,92.0,114.0,129.0" repeatRows="1" style="Table1">
|
||||
<tr>
|
||||
<td>
|
||||
<para style="terp_tblheader_General_Centre">Planned Date</para>
|
||||
<para style="terp_tblheader_General_Centre">Scheduled Date</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_tblheader_General_Centre">Printing date</para>
|
||||
@@ -328,6 +334,9 @@
|
||||
</blockTable>
|
||||
</section>
|
||||
</section>
|
||||
<para style="terp_default_8">
|
||||
<font color="white"> </font>
|
||||
</para>
|
||||
<section>
|
||||
<para style="terp_default_Bold_9">Consumed Products [[ o.move_lines2 ==[] and removeParentNode('section')]]</para>
|
||||
<section>
|
||||
|
||||
@@ -33,14 +33,8 @@ class StockMove(osv.osv):
|
||||
|
||||
_columns = {
|
||||
'production_id': fields.many2one('mrp.production', 'Production', select=True),
|
||||
'procurements': fields.one2many('procurement.order', 'move_id', 'Procurements'),
|
||||
}
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
default = default or {}
|
||||
default['procurements'] = []
|
||||
return super(StockMove, self).copy(cr, uid, id, default, context)
|
||||
|
||||
def _action_explode(self, cr, uid, move, context={}):
|
||||
""" Explodes pickings.
|
||||
@param move: Stock moves
|
||||
@@ -152,17 +146,6 @@ StockMove()
|
||||
class StockPicking(osv.osv):
|
||||
_inherit = 'stock.picking'
|
||||
|
||||
def test_finnished(self, cursor, user, ids):
|
||||
wf_service = netsvc.LocalService("workflow")
|
||||
res = super(StockPicking, self).test_finnished(cursor, user, ids)
|
||||
for picking in self.browse(cursor, user, ids):
|
||||
for move in picking.move_lines:
|
||||
if move.state == 'done' and move.procurements:
|
||||
for procurement in move.procurements:
|
||||
wf_service.trg_validate(user, 'procurement.order',
|
||||
procurement.id, 'button_check', cursor)
|
||||
return res
|
||||
|
||||
#
|
||||
# Explode picking by replacing phantom BoMs
|
||||
#
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
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
|
||||
@@ -19,6 +23,10 @@
|
||||
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
|
||||
@@ -87,8 +95,9 @@
|
||||
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}:
|
||||
!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'))
|
||||
|
||||
|
||||
@@ -67,7 +67,11 @@
|
||||
!record {model: product.product, id: product_product_water0}:
|
||||
categ_id: product.cat1
|
||||
name: Water
|
||||
procure_method: make_to_stock
|
||||
procure_method: make_to_order
|
||||
seller_ids:
|
||||
- delay: 1
|
||||
name: base.res_partner_agrolait
|
||||
min_qty: 2.0
|
||||
supply_method: buy
|
||||
type: consu
|
||||
uom_id: product_uom_litre0
|
||||
@@ -196,14 +200,14 @@
|
||||
-
|
||||
!python {model: procurement.order}: |
|
||||
from tools.translate import _
|
||||
proc_ids = self.search(cr, uid, [('state','!=','confirmed')])
|
||||
proc_ids = self.search(cr, uid, [('state','=','confirmed')])
|
||||
assert proc_ids, _('No Procurements!')
|
||||
-
|
||||
The scheduler runs.
|
||||
-
|
||||
!function {model: procurement.order, name: run_scheduler}:
|
||||
- model: procurement.order
|
||||
search: "[('state','=','confirmed')]"
|
||||
search: "[]"
|
||||
-
|
||||
I am checking Internal picking. I see one picking for Orange juice and its
|
||||
stock moves for Oranges, Sugar and Water made correctly.
|
||||
@@ -256,7 +260,7 @@
|
||||
-
|
||||
!python {model: stock.partial.picking}: |
|
||||
pick_obj = self.pool.get('stock.picking')
|
||||
picking_ids = pick_obj.search(cr, uid, [('address_id.name','=','Tang'),('state','=','assigned')])
|
||||
picking_ids = pick_obj.search(cr, uid, [('type','=','in'),('state','=','assigned')])
|
||||
partial = self.browse(cr, uid, 1, context)
|
||||
partial_datas = {
|
||||
'delivery_date': partial.date
|
||||
@@ -274,4 +278,29 @@
|
||||
'product_currency': m.product_currency
|
||||
})
|
||||
pick_obj.do_partial(cr, uid, picking_ids, partial_datas, context=context)
|
||||
|
||||
-
|
||||
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}: |
|
||||
from tools.translate import _
|
||||
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}: |
|
||||
from tools.translate import _
|
||||
pick_ids = self.search(cr, uid, [('state','=','ready'),('id','=',ref('mrp_production_mo0'))])
|
||||
assert pick_ids, _('Manufacturing order is not ready!')
|
||||
-
|
||||
I start the production order.
|
||||
-
|
||||
!workflow {model: mrp.production, action: button_produce, ref: mrp_production_mo0}
|
||||
|
||||
|
||||
|
||||
@@ -343,4 +343,4 @@
|
||||
prod_obj = self.pool.get('mrp.production')
|
||||
prod_ids = prod_obj.search(cr, uid, [('product_id.name','=','Shirt')])
|
||||
self.do_produce(cr, uid, [1], context={'active_ids': prod_ids})
|
||||
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
-
|
||||
!python {model: procurement.order}: |
|
||||
from tools.translate import _
|
||||
proc_ids = self.search(cr, uid, [('state','!=','confirmed')])
|
||||
proc_ids = self.search(cr, uid, [('state','=','confirmed')])
|
||||
assert proc_ids, _('No Procurements!')
|
||||
-
|
||||
The scheduler runs.
|
||||
@@ -110,6 +110,8 @@
|
||||
assert order_ids, _('No manufacturing order!')
|
||||
-
|
||||
I start producing that product first. So I marked it as started.
|
||||
-
|
||||
!workflow {model: mrp.production, action: button_produce, ref: mrp_production_mo0}
|
||||
-
|
||||
I create record for producing products with quantity 5.00.
|
||||
-
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<field name="name">res.company.mrp.config</field>
|
||||
<field name="model">res.company</field>
|
||||
<field name="type">form</field>
|
||||
<field name="priority">17</field>
|
||||
<field name="inherit_id" ref="base.view_company_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<page string="Configuration" position="inside">
|
||||
|
||||
@@ -60,6 +60,21 @@ class mrp_property(osv.osv):
|
||||
'composition': lambda *a: 'min',
|
||||
}
|
||||
mrp_property()
|
||||
|
||||
class StockMove(osv.osv):
|
||||
_inherit = 'stock.move'
|
||||
|
||||
_columns= {
|
||||
'procurements': fields.one2many('procurement.order', 'move_id', 'Procurements'),
|
||||
}
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
default = default or {}
|
||||
default['procurements'] = []
|
||||
return super(StockMove, self).copy(cr, uid, id, default, context)
|
||||
|
||||
StockMove()
|
||||
|
||||
class procurement_order(osv.osv):
|
||||
"""
|
||||
Procurement Orders
|
||||
@@ -464,6 +479,21 @@ class procurement_order(osv.osv):
|
||||
|
||||
procurement_order()
|
||||
|
||||
class StockPicking(osv.osv):
|
||||
_inherit = 'stock.picking'
|
||||
|
||||
def test_finnished(self, cursor, user, ids):
|
||||
wf_service = netsvc.LocalService("workflow")
|
||||
res = super(StockPicking, self).test_finnished(cursor, user, ids)
|
||||
for picking in self.browse(cursor, user, ids):
|
||||
for move in picking.move_lines:
|
||||
if move.state == 'done' and move.procurements:
|
||||
for procurement in move.procurements:
|
||||
wf_service.trg_validate(user, 'procurement.order',
|
||||
procurement.id, 'button_check', cursor)
|
||||
return res
|
||||
|
||||
StockPicking()
|
||||
|
||||
class stock_warehouse_orderpoint(osv.osv):
|
||||
"""
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<field name="name">res.company.mrp.config</field>
|
||||
<field name="model">res.company</field>
|
||||
<field name="type">form</field>
|
||||
<field name="priority">19</field>
|
||||
<field name="inherit_id" ref="base.view_company_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<page string="Configuration" position="inside">
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<field name="name">res.company.mrp.config</field>
|
||||
<field name="model">res.company</field>
|
||||
<field name="type">form</field>
|
||||
<field name="priority">24</field>
|
||||
<field name="inherit_id" ref="base.view_company_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<page string="Configuration" position="inside">
|
||||
|
||||
+4
-5
@@ -694,15 +694,14 @@ class sale_order(osv.osv):
|
||||
self.pool.get('sale.order.line').write(cr, uid, [line.id], {'procurement_id': proc_id})
|
||||
|
||||
val = {}
|
||||
if picking_id:
|
||||
wf_service = netsvc.LocalService("workflow")
|
||||
wf_service.trg_validate(uid, 'stock.picking', picking_id, 'button_confirm', cr)
|
||||
|
||||
for proc_id in proc_ids:
|
||||
wf_service = netsvc.LocalService("workflow")
|
||||
wf_service.trg_validate(uid, 'procurement.order', proc_id, 'button_confirm', cr)
|
||||
wf_service.trg_validate(uid, 'procurement.order', proc_id, 'button_check', cr)
|
||||
|
||||
if picking_id:
|
||||
wf_service = netsvc.LocalService("workflow")
|
||||
wf_service.trg_validate(uid, 'stock.picking', picking_id, 'button_confirm', cr)
|
||||
|
||||
if order.state == 'shipping_except':
|
||||
val['state'] = 'progress'
|
||||
|
||||
|
||||
@@ -2,15 +2,6 @@
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
|
||||
<!--Resource: res.company-->
|
||||
|
||||
<record id="res_company_shop_sale0" model="res.company">
|
||||
<field eval="5.0" name="security_lead"/>
|
||||
<field name="partner_id" ref="stock.res_partner_tinyshop0"/>
|
||||
<field name="parent_id" ref="stock.res_company_shop0"/>
|
||||
<field eval=""""Shop 1"""" name="name"/>
|
||||
</record>
|
||||
|
||||
<!--Resource: sale.order-->
|
||||
|
||||
<record id="order" model="sale.order">
|
||||
|
||||
Reference in New Issue
Block a user