import netsvc
import time
from mx import DateTime
+from tools.translate import _
#----------------------------------------------------------
# Workcenters
'cycle_nbr': fields.float('Number of Cycle', required=True,
help="A cycle is defined in the workcenter definition."),
'hour_nbr': fields.float('Number of Hours', required=True),
- 'routing_id': fields.many2one('mrp.routing', 'Parent Routing', select=True),
+ 'routing_id': fields.many2one('mrp.routing', 'Parent Routing', select=True, ondelete='cascade'),
'note': fields.text('Description')
}
_defaults = {
def _check_recursion(self, cr, uid, ids):
level = 500
while len(ids):
- cr.execute('select distinct bom_id from mrp_bom where id in ('+','.join(map(str,ids))+')')
+ cr.execute('select distinct bom_id from mrp_bom where id in %s', (tuple(ids),))
ids = filter(None, map(lambda x:x[0], cr.fetchall()))
if not level:
return False
result2 = result2 + res[1]
return result, result2
- def set_indices(self, cr, uid, ids, context = {}):
- if not ids or (ids and not ids[0]):
- return True
- res = self.read(cr, uid, ids, ['revision_ids', 'revision_type'])
- rev_ids = res[0]['revision_ids']
- idx = 1
- new_idx = []
- for rev_id in rev_ids:
- if res[0]['revision_type'] == 'numeric':
- self.pool.get('mrp.bom.revision').write(cr, uid, [rev_id], {'indice' : idx})
- else:
- self.pool.get('mrp.bom.revision').write(cr, uid, [rev_id], {'indice' : "%c"%(idx+96,)})
- idx+=1
- return True
-
mrp_bom()
class mrp_bom_revision(osv.osv):
_description = 'Production'
_date_name = 'date_planned'
- def _get_sale_order(self,cr,uid,ids,field_name=False):
- move_obj=self.pool.get('stock.move')
- def get_parent_move(move_id):
- move = move_obj.browse(cr,uid,move_id)
- if move.move_dest_id:
- return get_parent_move(move.move_dest_id.id)
- return move_id
- productions=self.read(cr,uid,ids,['id','move_prod_id'])
- res={}
- for production in productions:
- res[production['id']]=False
- if production.get('move_prod_id',False):
- parent_move_line=get_parent_move(production['move_prod_id'][0])
- if parent_move_line:
- move = move_obj.browse(cr,uid,parent_move_line)
- if field_name=='name':
- res[production['id']]=move.sale_line_id and move.sale_line_id.order_id.name or False
- if field_name=='client_order_ref':
- res[production['id']]=move.sale_line_id and move.sale_line_id.order_id.client_order_ref or False
- return res
-
def _production_calc(self, cr, uid, ids, prop, unknow_none, context={}):
result = {}
for prod in self.browse(cr, uid, ids, context=context):
result[prod.id]['cycle_total'] += wc.cycle
return result
+ def _production_date_end(self, cr, uid, ids, prop, unknow_none, context={}):
+ result = {}
+ for prod in self.browse(cr, uid, ids, context=context):
+ result[prod.id] = prod.date_planned
+ return result
+
def _production_date(self, cr, uid, ids, prop, unknow_none, context={}):
result = {}
for prod in self.browse(cr, uid, ids, context=context):
result[prod.id] = prod.date_planned[:10]
return result
- def _sale_name_calc(self, cr, uid, ids, prop, unknow_none, unknow_dict):
- return self._get_sale_order(cr,uid,ids,field_name='name')
-
- def _sale_ref_calc(self, cr, uid, ids, prop, unknow_none, unknow_dict):
- return self._get_sale_order(cr,uid,ids,field_name='client_order_ref')
-
_columns = {
'name': fields.char('Reference', size=64, required=True),
'origin': fields.char('Origin', size=64),
'priority': fields.selection([('0','Not urgent'),('1','Normal'),('2','Urgent'),('3','Very Urgent')], 'Priority'),
'product_id': fields.many2one('product.product', 'Product', required=True, domain=[('type','<>','service')]),
- 'product_qty': fields.float('Product Qty', required=True),
- 'product_uom': fields.many2one('product.uom', 'Product UOM', required=True),
- 'product_uos_qty': fields.float('Product Qty'),
- 'product_uos': fields.many2one('product.uom', 'Product UOM'),
+ 'product_qty': fields.float('Product Qty', required=True, states={'draft':[('readonly',False)]}, readonly=True),
+ 'product_uom': fields.many2one('product.uom', 'Product UOM', required=True, states={'draft':[('readonly',False)]}, readonly=True),
+ 'product_uos_qty': fields.float('Product UoS Qty', states={'draft':[('readonly',False)]}, readonly=True),
+ 'product_uos': fields.many2one('product.uom', 'Product UoS', states={'draft':[('readonly',False)]}, readonly=True),
'location_src_id': fields.many2one('stock.location', 'Raw Materials Location', required=True,
help="Location where the system will look for products used in raw materials."),
'location_dest_id': fields.many2one('stock.location', 'Finished Products Location', required=True,
help="Location where the system will stock the finished products."),
- 'date_planned_date': fields.function(_production_date, method=True, type='date', string='Planned Date'),
+ 'date_planned_end': fields.function(_production_date_end, method=True, type='date', string='Scheduled End'),
+ 'date_planned_date': fields.function(_production_date, method=True, type='date', string='Scheduled Date'),
'date_planned': fields.datetime('Scheduled date', required=True, select=1),
'date_start': fields.datetime('Start Date'),
'date_finnished': fields.datetime('End Date'),
'hour_total': fields.function(_production_calc, method=True, type='float', string='Total Hours', multi='workorder'),
'cycle_total': fields.function(_production_calc, method=True, type='float', string='Total Cycles', multi='workorder'),
- 'sale_name': fields.function(_sale_name_calc, method=True, type='char', string='Sale Name'),
- 'sale_ref': fields.function(_sale_ref_calc, method=True, type='char', string='Sale Ref'),
}
_defaults = {
'priority': lambda *a: '1',
default.update({
'name': self.pool.get('ir.sequence').get(cr, uid, 'mrp.production'),
'move_lines' : [],
+ 'move_created_ids': [],
+ 'state': 'draft'
})
return super(mrp_production, self).copy(cr, uid, id, default, context)
result = {'product_uom':uom}
return {'value':result}
+ def bom_id_change(self, cr, uid, ids, product):
+ if not product:
+ return {}
+ res = self.pool.get('mrp.bom').read(cr, uid, [product], ['routing_id'])[0]
+ routing_id = res['routing_id'] and res['routing_id'][0]
+ result = {'routing_id':routing_id}
+ return {'value':result}
+
def action_picking_except(self, cr, uid, ids):
self.write(cr, uid, ids, {'state':'picking_except'})
return True
self.write(cr, uid, [production.id], {'bom_id': bom_id, 'routing_id': routing_id})
if not bom_id:
- raise osv.except_osv('Error', "Couldn't find bill of material for product")
+ raise osv.except_osv(_('Error'), _("Couldn't find bill of material for product"))
#if bom_point.routing_id and bom_point.routing_id.location_id:
# self.write(cr, uid, [production.id], {'location_src_id': bom_point.routing_id.location_id.id})
#TODO Review materials in function in_prod and prod_end.
def action_production_end(self, cr, uid, ids):
- move_ids = []
+# move_ids = []
for production in self.browse(cr, uid, ids):
for res in production.move_lines:
for move in production.move_created_ids:
cr.execute('INSERT INTO stock_move_history_ids \
(parent_id, child_id) VALUES (%s,%s)',
(res.id, move.id))
- move_ids.append(res.id)
+# move_ids.append(res.id)
vals= {'state':'confirmed'}
new_moves = [x.id for x in production.move_created_ids]
self.pool.get('stock.move').write(cr, uid, new_moves, vals)
self.pool.get('stock.move').check_assign(cr, uid, new_moves)
self.pool.get('stock.move').action_done(cr, uid, new_moves)
self._costs_generate(cr, uid, production)
- self.pool.get('stock.move').action_done(cr, uid, move_ids)
+# self.pool.get('stock.move').action_done(cr, uid, move_ids)
self.write(cr, uid, ids, {'state': 'done'})
return True
class mrp_production_workcenter_line(osv.osv):
_name = 'mrp.production.workcenter.line'
- _description = 'Production workcenters used'
+ _description = 'Work Orders'
+ _order = 'sequence'
_columns = {
- 'name': fields.char('Name', size=64, required=True),
+ 'name': fields.char('Work Order', size=64, required=True),
'workcenter_id': fields.many2one('mrp.workcenter', 'Workcenter', required=True),
'cycle': fields.float('Nbr of cycle', digits=(16,2)),
'hour': fields.float('Nbr of hour', digits=(16,2)),
'sequence': fields.integer('Sequence', required=True),
- 'production_id': fields.many2one('mrp.production', 'Production Order', select=True),
+ 'production_id': fields.many2one('mrp.production', 'Production Order', select=True, ondelete='cascade'),
}
_defaults = {
'sequence': lambda *a: 1,
'date_planned': fields.datetime('Scheduled date', required=True),
'date_close': fields.datetime('Date Closed'),
'product_id': fields.many2one('product.product', 'Product', required=True),
- 'product_qty': fields.float('Quantity', required=True),
- 'product_uom': fields.many2one('product.uom', 'Product UoM', required=True),
- 'product_uos_qty': fields.float('UoS Quantity'),
- 'product_uos': fields.many2one('product.uom', 'Product UoS'),
+ 'product_qty': fields.float('Quantity', required=True, states={'draft':[('readonly',False)]}, readonly=True),
+ 'product_uom': fields.many2one('product.uom', 'Product UoM', required=True, states={'draft':[('readonly',False)]}, readonly=True),
+ 'product_uos_qty': fields.float('UoS Quantity', states={'draft':[('readonly',False)]}, readonly=True),
+ 'product_uos': fields.many2one('product.uom', 'Product UoS', states={'draft':[('readonly',False)]}, readonly=True),
'move_id': fields.many2one('stock.move', 'Reservation', ondelete='set null'),
'bom_id': fields.many2one('mrp.bom', 'BoM', ondelete='cascade', select=True),
('cancel','Cancel'),
('ready','Ready'),
('done','Done'),
- ('waiting','Waiting')], 'Status')
+ ('waiting','Waiting')], 'Status', required=True),
+ 'note' : fields.text('Note'),
}
_defaults = {
'state': lambda *a: 'draft',
return True
return False
+ 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 check_move_cancel(self, cr, uid, ids, context={}):
res = True
+ ok = False
for procurement in self.browse(cr, uid, ids, context):
if procurement.move_id:
+ ok = True
if not procurement.move_id.state=='cancel':
res = False
- return res
+ return res and ok
def check_move_done(self, cr, uid, ids, context={}):
res = True
def action_confirm(self, cr, uid, ids, context={}):
for procurement in self.browse(cr, uid, ids):
+ if procurement.product_qty <= 0.00:
+ raise osv.except_osv(_('Data Insufficient !'), _('Please check the Quantity of Procurement Order(s), it should not be less than 1!'))
if procurement.product_id.type in ('product', 'consu'):
if not procurement.move_id:
source = procurement.location_id.id
})
self.write(cr, uid, [procurement.id], {'move_id': id, 'close_move':1})
else:
- # TODO: check this
- if procurement.procure_method=='make_to_stock' and procurement.move_id.state in ('waiting',):
- id = self.pool.get('stock.move').write(cr, uid, [procurement.move_id.id], {'state':'confirmed'})
+ if procurement.procure_method=='make_to_stock' and procurement.move_id.state in ('draft','waiting',):
+ # properly call action_confirm() on stock.move to abide by the location chaining etc.
+ id = self.pool.get('stock.move').action_confirm(cr, uid, [procurement.move_id.id], context=context)
self.write(cr, uid, ids, {'state':'confirmed','message':''})
return True
- def action_move_assigned(self, cr, uid, ids):
+ def action_move_assigned(self, cr, uid, ids, context={}):
self.write(cr, uid, ids, {'state':'running','message':_('from stock: products assigned.')})
return True
[produce_id], properties=[x.id for x in procurement.property_ids])
wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, 'mrp.production', produce_id, 'button_confirm', cr)
+ self.pool.get('stock.move').write(cr, uid, [res_id],
+ {'location_id':procurement.location_id.id})
return produce_id
def action_po_assign(self, cr, uid, ids, context={}):
newdate = DateTime.strptime(procurement.date_planned, '%Y-%m-%d %H:%M:%S')
newdate = newdate - DateTime.RelativeDateTime(days=company.po_lead)
- context.update({'lang':partner.lang})
+ newdate = newdate - procurement.product_id.seller_ids[0].delay
+
+ #Passing partner_id to context for purchase order line integrity of Line name
+ context.update({'lang':partner.lang, 'partner_id':partner_id})
+
product=self.pool.get('product.product').browse(cr,uid,procurement.product_id.id,context=context)
line = {
- 'name': product.name,
+ 'name': product.partner_ref,
'product_qty': qty,
'product_id': procurement.product_id.id,
'product_uom': uom_id,
def action_cancel(self, cr, uid, ids):
todo = []
+ todo2 = []
for proc in self.browse(cr, uid, ids):
- if proc.move_id and proc.move_id.state=='waiting':
- todo.append(proc.move_id.id)
+ if proc.close_move and proc.move_id:
+ if proc.move_id.state not in ('done','cancel'):
+ todo2.append(proc.move_id.id)
+ else:
+ if proc.move_id and proc.move_id.state=='waiting':
+ todo.append(proc.move_id.id)
+ if len(todo2):
+ self.pool.get('stock.move').action_cancel(cr, uid, todo2)
if len(todo):
self.pool.get('stock.move').write(cr, uid, todo, {'state':'assigned'})
self.write(cr, uid, ids, {'state':'cancel'})
-
wf_service = netsvc.LocalService("workflow")
for id in ids:
wf_service.trg_trigger(uid, 'mrp.procurement', id, cr)
-
return True
def action_check_finnished(self, cr, uid, ids):
'name': fields.char('Name', size=32, required=True),
'active': fields.boolean('Active'),
'logic': fields.selection([('max','Order to Max'),('price','Best price (not yet active!)')], 'Reordering Mode', required=True),
- 'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', required=True),
- 'location_id': fields.many2one('stock.location', 'Location', required=True),
- 'product_id': fields.many2one('product.product', 'Product', required=True, domain=[('type','=','product')]),
- 'product_uom': fields.many2one('product.uom', 'Product UOM', required=True ),
+ 'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', required=True, ondelete="cascade"),
+ 'location_id': fields.many2one('stock.location', 'Location', required=True, ondelete="cascade"),
+ 'product_id': fields.many2one('product.product', 'Product', required=True, domain=[('type','=','product')], ondelete="cascade"),
+ 'product_uom': fields.many2one('product.uom', 'Product UOM', required=True),
'product_min_qty': fields.float('Min Quantity', required=True,
help="When the virtual stock goes belong the Min Quantity, Open ERP generates "\
"a procurement to bring the virtual stock to the Max Quantity."),
"a procurement to bring the virtual stock to the Max Quantity."),
'qty_multiple': fields.integer('Qty Multiple', required=True,
help="The procurement quantity will by rounded up to this multiple."),
- 'procurement_id': fields.many2one('mrp.procurement', 'Purchase Order')
+ 'procurement_id': fields.many2one('mrp.procurement', 'Purchase Order', ondelete="set null")
}
_defaults = {
'active': lambda *a: 1,
'name': lambda x,y,z,c: x.pool.get('ir.sequence').get(y,z,'mrp.warehouse.orderpoint') or '',
'product_uom': lambda sel, cr, uid, context: context.get('product_uom', False),
}
+
+ _sql_constraints = [
+ ( 'qty_multiple_check', 'CHECK( qty_multiple > 0 )', _('Qty Multiple must be greater than zero.')),
+ ]
+
def onchange_warehouse_id(self, cr, uid, ids, warehouse_id, context={}):
if warehouse_id:
w=self.pool.get('stock.warehouse').browse(cr,uid,warehouse_id, context)
factor = move.product_qty
bom_point = self.pool.get('mrp.bom').browse(cr, uid, bis[0])
res = self.pool.get('mrp.bom')._bom_explode(cr, uid, bom_point, factor, [])
- dest = move.product_id.product_tmpl_id.property_stock_production.id
state = 'confirmed'
if move.state=='assigned':
state='assigned'
'product_qty': line['product_qty'],
'product_uos': line['product_uos'],
'product_uos_qty': line['product_uos_qty'],
- 'move_dest_id': move.id,
'state': state,
'name': line['name'],
- 'location_dest_id': dest,
'move_history_ids': [(6,0,[move.id])],
'move_history_ids2': [(6,0,[])],
'procurements': []
wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, 'mrp.procurement', proc_id, 'button_confirm', cr)
self.pool.get('stock.move').write(cr, uid, [move.id], {
- 'location_id': move.location_dest_id.id,
+ 'location_id': move.location_dest_id.id, # src and dest locations identical to have correct inventory, dummy move
'auto_validate': True,
'picking_id': False,
- 'location_id': dest,
'state': 'waiting'
})
for m in self.pool.get('mrp.procurement').search(cr, uid, [('move_id','=',move.id)], context):