From 5a76e7c0c5b4a559b43801be36fb63e2b1c4806f Mon Sep 17 00:00:00 2001 From: Naresh Choksy Date: Tue, 23 Sep 2008 15:50:09 +0530 Subject: [PATCH] Add a graph and calendar view,changed workflow,added delay calculation,restricted operations,changed all 'operation' tag to 'Work Order' added buttons in list view,removed extra delay field bzr revid: nch@tinyerp.com-20080923102009-tnsfvdhhnvg7qdjl --- addons/mrp_operations/__init__.py | 0 addons/mrp_operations/__terp__.py | 0 addons/mrp_operations/i18n/cs_CZ.po | 0 addons/mrp_operations/i18n/de_DE.po | 0 addons/mrp_operations/i18n/es_AR.po | 0 addons/mrp_operations/i18n/es_ES.po | 0 addons/mrp_operations/i18n/fr_FR.po | 0 addons/mrp_operations/i18n/hu_HU.po | 0 addons/mrp_operations/i18n/it_IT.po | 0 addons/mrp_operations/i18n/mrp_operations.pot | 0 addons/mrp_operations/i18n/nl_NL.po | 0 addons/mrp_operations/i18n/pt_BR.po | 0 addons/mrp_operations/i18n/pt_PT.po | 0 addons/mrp_operations/i18n/ro_RO.po | 0 addons/mrp_operations/i18n/ru_RU.po | 0 addons/mrp_operations/i18n/sv_SE.po | 0 addons/mrp_operations/i18n/zh_CN.po | 0 addons/mrp_operations/i18n/zh_TW.po | 0 addons/mrp_operations/mrp_operation_data.xml | 26 ++- addons/mrp_operations/mrp_operations.py | 213 +++++++++++++++--- .../mrp_operations/mrp_operations_report.xml | 0 addons/mrp_operations/mrp_operations_view.xml | 60 +++-- .../mrp_operations_workflow.xml | 30 ++- addons/mrp_operations/report/__init__.py | 0 .../mrp_operations/report/mrp_code_barcode.py | 0 .../report/mrp_code_barcode.rml | 0 .../mrp_operations/report/mrp_wc_barcode.py | 0 .../mrp_operations/report/mrp_wc_barcode.rml | 0 .../security/ir.model.access.csv | 0 29 files changed, 264 insertions(+), 65 deletions(-) mode change 100644 => 100755 addons/mrp_operations/__init__.py mode change 100644 => 100755 addons/mrp_operations/__terp__.py mode change 100644 => 100755 addons/mrp_operations/i18n/cs_CZ.po mode change 100644 => 100755 addons/mrp_operations/i18n/de_DE.po mode change 100644 => 100755 addons/mrp_operations/i18n/es_AR.po mode change 100644 => 100755 addons/mrp_operations/i18n/es_ES.po mode change 100644 => 100755 addons/mrp_operations/i18n/fr_FR.po mode change 100644 => 100755 addons/mrp_operations/i18n/hu_HU.po mode change 100644 => 100755 addons/mrp_operations/i18n/it_IT.po mode change 100644 => 100755 addons/mrp_operations/i18n/mrp_operations.pot mode change 100644 => 100755 addons/mrp_operations/i18n/nl_NL.po mode change 100644 => 100755 addons/mrp_operations/i18n/pt_BR.po mode change 100644 => 100755 addons/mrp_operations/i18n/pt_PT.po mode change 100644 => 100755 addons/mrp_operations/i18n/ro_RO.po mode change 100644 => 100755 addons/mrp_operations/i18n/ru_RU.po mode change 100644 => 100755 addons/mrp_operations/i18n/sv_SE.po mode change 100644 => 100755 addons/mrp_operations/i18n/zh_CN.po mode change 100644 => 100755 addons/mrp_operations/i18n/zh_TW.po mode change 100644 => 100755 addons/mrp_operations/mrp_operation_data.xml mode change 100644 => 100755 addons/mrp_operations/mrp_operations.py mode change 100644 => 100755 addons/mrp_operations/mrp_operations_report.xml mode change 100644 => 100755 addons/mrp_operations/mrp_operations_view.xml mode change 100644 => 100755 addons/mrp_operations/mrp_operations_workflow.xml mode change 100644 => 100755 addons/mrp_operations/report/__init__.py mode change 100644 => 100755 addons/mrp_operations/report/mrp_code_barcode.py mode change 100644 => 100755 addons/mrp_operations/report/mrp_code_barcode.rml mode change 100644 => 100755 addons/mrp_operations/report/mrp_wc_barcode.py mode change 100644 => 100755 addons/mrp_operations/report/mrp_wc_barcode.rml mode change 100644 => 100755 addons/mrp_operations/security/ir.model.access.csv diff --git a/addons/mrp_operations/__init__.py b/addons/mrp_operations/__init__.py old mode 100644 new mode 100755 diff --git a/addons/mrp_operations/__terp__.py b/addons/mrp_operations/__terp__.py old mode 100644 new mode 100755 diff --git a/addons/mrp_operations/i18n/cs_CZ.po b/addons/mrp_operations/i18n/cs_CZ.po old mode 100644 new mode 100755 diff --git a/addons/mrp_operations/i18n/de_DE.po b/addons/mrp_operations/i18n/de_DE.po old mode 100644 new mode 100755 diff --git a/addons/mrp_operations/i18n/es_AR.po b/addons/mrp_operations/i18n/es_AR.po old mode 100644 new mode 100755 diff --git a/addons/mrp_operations/i18n/es_ES.po b/addons/mrp_operations/i18n/es_ES.po old mode 100644 new mode 100755 diff --git a/addons/mrp_operations/i18n/fr_FR.po b/addons/mrp_operations/i18n/fr_FR.po old mode 100644 new mode 100755 diff --git a/addons/mrp_operations/i18n/hu_HU.po b/addons/mrp_operations/i18n/hu_HU.po old mode 100644 new mode 100755 diff --git a/addons/mrp_operations/i18n/it_IT.po b/addons/mrp_operations/i18n/it_IT.po old mode 100644 new mode 100755 diff --git a/addons/mrp_operations/i18n/mrp_operations.pot b/addons/mrp_operations/i18n/mrp_operations.pot old mode 100644 new mode 100755 diff --git a/addons/mrp_operations/i18n/nl_NL.po b/addons/mrp_operations/i18n/nl_NL.po old mode 100644 new mode 100755 diff --git a/addons/mrp_operations/i18n/pt_BR.po b/addons/mrp_operations/i18n/pt_BR.po old mode 100644 new mode 100755 diff --git a/addons/mrp_operations/i18n/pt_PT.po b/addons/mrp_operations/i18n/pt_PT.po old mode 100644 new mode 100755 diff --git a/addons/mrp_operations/i18n/ro_RO.po b/addons/mrp_operations/i18n/ro_RO.po old mode 100644 new mode 100755 diff --git a/addons/mrp_operations/i18n/ru_RU.po b/addons/mrp_operations/i18n/ru_RU.po old mode 100644 new mode 100755 diff --git a/addons/mrp_operations/i18n/sv_SE.po b/addons/mrp_operations/i18n/sv_SE.po old mode 100644 new mode 100755 diff --git a/addons/mrp_operations/i18n/zh_CN.po b/addons/mrp_operations/i18n/zh_CN.po old mode 100644 new mode 100755 diff --git a/addons/mrp_operations/i18n/zh_TW.po b/addons/mrp_operations/i18n/zh_TW.po old mode 100644 new mode 100755 diff --git a/addons/mrp_operations/mrp_operation_data.xml b/addons/mrp_operations/mrp_operation_data.xml old mode 100644 new mode 100755 index 0d5899c6014..7ce25b6d250 --- a/addons/mrp_operations/mrp_operation_data.xml +++ b/addons/mrp_operations/mrp_operation_data.xml @@ -3,21 +3,31 @@ - Normal Start - nstart + Start + start start - Normal Stop - nstop - stop + Pause + pause + pause - Broken Stop - broken - stop + Cancel + cancel + cancel + + + Resume + resume + resume + + + Finished + done + done diff --git a/addons/mrp_operations/mrp_operations.py b/addons/mrp_operations/mrp_operations.py old mode 100644 new mode 100755 index 9946713efe8..a8c62321d19 --- a/addons/mrp_operations/mrp_operations.py +++ b/addons/mrp_operations/mrp_operations.py @@ -31,7 +31,7 @@ from osv import fields from osv import osv import ir - +import datetime import netsvc import time from mx import DateTime @@ -50,41 +50,58 @@ class mrp_production_workcenter_line(osv.osv): _inherit = 'mrp.production.workcenter.line' _name = 'mrp.production.workcenter.line' _description = 'Production workcenters used' - - def _calc_delay(self, cr, uid, ids, name, arg, context={}): - result = {} - for obj in self.browse(cr, uid, ids, context): - if obj.date_start and obj.date_finnished: - diff = DateTime.strptime(obj.date_finnished, '%Y-%m-%d %H:%M:%S') - DateTime.strptime(obj.date_start, '%Y-%m-%d %H:%M:%S') - result[obj.id]=diff.day - else: - result[obj.id] = 0 - return result - _columns = { - 'state': fields.selection([('draft','Draft'),('confirm', 'Confirm'),('cancel','Canceled'),('done','Done')],'Status', readonly=True), - 'date_start': fields.datetime('Start Date'), - 'date_finnished': fields.datetime('End Date'), - 'delay': fields.function(_calc_delay, method=True, string='Delay', help="This is delay between operation start and stop in this workcenter"), - 'delay': fields.float('delay', required=True), + 'state': fields.selection([('draft','Draft'),('startworking', 'In Progress'),('pause','Pause'),('cancel','Canceled'),('done','Finished')],'Status', readonly=True), + 'date_start': fields.datetime('Start Date'), + 'date_finnished': fields.datetime('End Date'), + 'delay': fields.char('Delay',size=128,help="This is delay between operation start and stop in this workcenter",readonly=True), + 'product':fields.related('production_id','product_id',type='many2one',relation='product.product',string='Product'), + 'qty':fields.related('production_id','product_qty',type='float',string='Qty'), + 'uom':fields.related('production_id','product_uom',type='many2one',relation='product.uom',string='UOM'), + + } _defaults = { 'state': lambda *a: 'draft', - 'delay': lambda *a: 0.0 + 'delay': lambda *a: '0 Days 00 hrs and 00 mins' } + def modify_production_order_state(self,cr,uid,ids,action): + wf_service = netsvc.LocalService("workflow") + oper_obj=self.browse(cr,uid,ids)[0] + prod_obj=self.pool.get('mrp.production').browse(cr,uid,[oper_obj.production_id.id])[0] + if action=='start': + if prod_obj.state =='ready': + wf_service.trg_validate(uid, 'mrp.production', prod_obj.id, 'button_produce', cr) + elif prod_obj.state =='in_production': + return + else: + raise osv.except_osv(_('Error!'),_('Production Order Cannot start in [%s] state')%(prod_obj.state,)) + else: + oper_ids=self.search(cr,uid,[('production_id','=',prod_obj.id)]) + obj=self.browse(cr,uid,oper_ids) + flag=True + for line in obj: + if line.state!='done': + flag=False + if flag: + wf_service.trg_validate(uid, 'mrp.production', oper_obj.production_id.id, 'button_produce_done', cr) + return + def action_draft(self, cr, uid, ids): self.write(cr, uid, ids, {'state':'draft'}) # self.write(cr, uid, ids, {'state':'draft','date_start':None}) return True - def action_confirm(self, cr, uid, ids): - self.write(cr, uid, ids, {'state':'confirm'}) + def action_start_working(self, cr, uid, ids): + self.modify_production_order_state(cr,uid,ids,'start') + self.write(cr, uid, ids, {'state':'startworking'}) # self.write(cr, uid, ids, {'state':'confirm','date_start':DateTime.now().strftime('%Y-%m-%d %H:%M:%S')}) return True def action_done(self, cr, uid, ids): self.write(cr, uid, ids, {'state':'done'}) + self.modify_production_order_state(cr,uid,ids,'done') # self.write(cr, uid, ids, {'state':'done','date_finnished':DateTime.now().strftime('%Y-%m-%d %H:%M:%S')}) return True @@ -92,6 +109,16 @@ class mrp_production_workcenter_line(osv.osv): self.write(cr, uid, ids, {'state':'cancel'}) # self.write(cr, uid, ids, {'state':'cancel','date_start':None}) return True + + def action_pause(self, cr, uid, ids): + print "callled THE ACTUAL PAUSE" + self.write(cr, uid, ids, {'state':'pause'}) +# self.write(cr, uid, ids, {'state':'draft','date_start':None}) + return True + + def action_resume(self, cr, uid, ids): + self.write(cr, uid, ids, {'state':'startworking'}) + return True mrp_production_workcenter_line() @@ -100,18 +127,18 @@ class mrp_production(osv.osv): _inherit = 'mrp.production' _description = 'Production' - def action_confirm(self, cr, uid, ids): - obj=self.browse(cr,uid,ids)[0] - for workcenter_line in obj.workcenter_lines: - tmp=self.pool.get('mrp.production.workcenter.line').action_confirm(cr,uid,[workcenter_line.id]) - return super(mrp_production,self).action_confirm(cr,uid,ids) +# def action_confirm(self, cr, uid, ids): +# obj=self.browse(cr,uid,ids)[0] +# for workcenter_line in obj.workcenter_lines: +# tmp=self.pool.get('mrp.production.workcenter.line').action_start_working(cr,uid,[workcenter_line.id]) +# return super(mrp_production,self).action_confirm(cr,uid,ids) def action_production_end(self, cr, uid, ids): obj=self.browse(cr,uid,ids)[0] for workcenter_line in obj.workcenter_lines: tmp=self.pool.get('mrp.production.workcenter.line').action_done(cr,uid,[workcenter_line.id]) return super(mrp_production,self).action_production_end(cr,uid,ids) - +# def action_cancel(self, cr, uid, ids): obj=self.browse(cr,uid,ids)[0] for workcenter_line in obj.workcenter_lines: @@ -125,7 +152,7 @@ class mrp_operations_operation_code(osv.osv): _columns={ 'name': fields.char('Operation Name',size=64, required=True), 'code': fields.char('Code', size=16, required=True), - 'start_stop': fields.selection([('start','Start'),('stop','Stop'),('done','Done')], 'Status', required=True), + 'start_stop': fields.selection([('start','Start'),('pause','Pause'),('resume','Resume'),('cancel','Cancel'),('done','Done')], 'Status', required=True), } mrp_operations_operation_code() @@ -143,23 +170,142 @@ class mrp_operations_operation(osv.osv): res[operation.id]=operation.production_id.date_planned return res + def calc_delay(self,cr,uid,vals): + code_lst=[] + time_lst=[] + + code_ids=self.pool.get('mrp_operations.operation.code').search(cr,uid,[('id','=',vals['code_id'])]) + code=self.pool.get('mrp_operations.operation.code').browse(cr,uid,code_ids)[0] + + oper_ids=self.search(cr,uid,[('production_id','=',vals['production_id']),('workcenter_id','=',vals['workcenter_id'])]) + oper_objs=self.browse(cr,uid,oper_ids) + + for oper in oper_objs: + code_lst.append(oper.code_id.start_stop) + time_lst.append(oper.date_start) + + code_lst.append(code.start_stop) + time_lst.append(vals['date_start']) + h=m=s=days=0 + for i in range(0,len(code_lst)): + if code_lst[i]=='pause' or code_lst[i]=='done' or code_lst[i]=='cancel': + if code_lst[i]=='cancel' and code_lst[i-1]=='pause': + continue + a=datetime.datetime(int(time_lst[i-1][0:4]),int(time_lst[i-1][5:7]),int(time_lst[i-1][8:10]),int(time_lst[i-1][11:13]),int(time_lst[i-1][14:16]),int(time_lst[i-1][17:19])) + b=datetime.datetime(int(time_lst[i][0:4]),int(time_lst[i][5:7]),int(time_lst[i][8:10]),int(time_lst[i][11:13]),int(time_lst[i][14:16]),int(time_lst[i][17:19])) + diff =b-a + min, sec = divmod(diff.seconds, 60) + hrs, min = divmod(min, 60) + days+=diff.days + h+=hrs + m+=min + s+=sec + if s>=60: + m+=1 + s=0 + if m>=60: + h+=1 + m=0 + if h>=24: + days+=1 + h=0 + delay=str(days) +" Days "+ str(h) + " hrs and " + str(m)+ " mins" + return delay + + def check_operation(self,cr,uid,vals): + code_ids=self.pool.get('mrp_operations.operation.code').search(cr,uid,[('id','=',vals['code_id'])]) + code=self.pool.get('mrp_operations.operation.code').browse(cr,uid,code_ids)[0] + code_lst = [] + oper_ids=self.search(cr,uid,[('production_id','=',vals['production_id']),('workcenter_id','=',vals['workcenter_id'])]) + oper_objs=self.browse(cr,uid,oper_ids) + + if not oper_objs: + if code.start_stop!='start': + raise osv.except_osv(_('Sorry!'),_('Operation is not started yet !')) + return False + else: + for oper in oper_objs: + code_lst.append(oper.code_id.start_stop) + if code.start_stop=='start': + if 'start' in code_lst: + raise osv.except_osv(_('Sorry!'),_('Operation has already started !' 'You can either Pause /Finish/Cancel the operation')) + return False + if code.start_stop=='pause': + if code_lst[len(code_lst)-1]!='resume' and code_lst[len(code_lst)-1]!='start': + raise osv.except_osv(_('Error!'),_('You cannot Pause the Operation other then Start/Resume state !')) + return False + if code.start_stop=='resume': + if code_lst[len(code_lst)-1]!='pause': + raise osv.except_osv(_('Error!'),_(' You cannot Resume the operation other then Pause state !')) + return False + + if code.start_stop=='done': + if code_lst[len(code_lst)-1]!='start' and code_lst[len(code_lst)-1]!='resume': + raise osv.except_osv(_('Sorry!'),_('You cannot finish the operation without Starting/Resuming it !')) + return False + if 'cancel' in code_lst: + raise osv.except_osv(_('Sorry!'),_('Operation is Already Cancelled !')) + return False + if code.start_stop=='cancel': + if not 'start' in code_lst : + raise osv.except_osv(_('Error!'),_('There is no Operation to be cancelled !')) + return False + if 'done' in code_lst: + raise osv.except_osv(_('Error!'),_('Operation is already finished !')) + return False + return True + + def write(self, cr, uid, ids, vals, context=None): + oper_objs=self.browse(cr,uid,ids)[0] + vals['production_id']=oper_objs.production_id.id + vals['workcenter_id']=oper_objs.workcenter_id.id + + if 'code_id' in vals: + self.check_operation(cr, uid, vals) + + if 'date_start' in vals: + vals['date_start']=vals['date_start'] + vals['code_id']=oper_objs.code_id.id + delay=self.calc_delay(cr, uid, vals) + wc_op_id=self.pool.get('mrp.production.workcenter.line').search(cr,uid,[('workcenter_id','=',vals['workcenter_id']),('production_id','=',vals['production_id'])]) + self.pool.get('mrp.production.workcenter.line').write(cr,uid,wc_op_id,{'delay':delay}) + + return super(mrp_operations_operation, self).write(cr, uid, ids, vals, context=context) + def create(self, cr, uid, vals, context=None): wf_service = netsvc.LocalService('workflow') code_ids=self.pool.get('mrp_operations.operation.code').search(cr,uid,[('id','=',vals['code_id'])]) code=self.pool.get('mrp_operations.operation.code').browse(cr,uid,code_ids)[0] - if code.start_stop=='start' or code.start_stop=='stop' or code.start_stop=='done': - wc_op_id=self.pool.get('mrp.production.workcenter.line').search(cr,uid,[('workcenter_id','=',vals['workcenter_id']),('production_id','=',vals['production_id'])]) + wc_op_id=self.pool.get('mrp.production.workcenter.line').search(cr,uid,[('workcenter_id','=',vals['workcenter_id']),('production_id','=',vals['production_id'])]) + if code.start_stop in ('start','done','pause','cancel','resume'): if not wc_op_id: production_obj=self.pool.get('mrp.production').browse(cr,uid,vals['production_id']) wc_op_id.append(self.pool.get('mrp.production.workcenter.line').create(cr,uid,{'production_id':vals['production_id'],'name':production_obj.product_id.name,'workcenter_id':vals['workcenter_id']})) + if code.start_stop=='start': - tmp=self.pool.get('mrp.production.workcenter.line').action_confirm(cr,uid,wc_op_id[0]) + tmp=self.pool.get('mrp.production.workcenter.line').action_start_working(cr,uid,wc_op_id) + if code.start_stop=='done': tmp=self.pool.get('mrp.production.workcenter.line').action_done(cr,uid,wc_op_id) - if code.start_stop=='stop': self.pool.get('mrp.production').write(cr,uid,vals['production_id'],{'date_finnished':DateTime.now().strftime('%Y-%m-%d %H:%M:%S')}) + + if code.start_stop=='pause': + print "in PAUSE" + tmp=self.pool.get('mrp.production.workcenter.line').action_pause(cr,uid,wc_op_id) + + if code.start_stop=='resume': + tmp=self.pool.get('mrp.production.workcenter.line').action_resume(cr,uid,wc_op_id) + + if code.start_stop=='cancel': + tmp=self.pool.get('mrp.production.workcenter.line').action_cancel(cr,uid,wc_op_id) + + if not self.check_operation(cr, uid, vals): + return + delay=self.calc_delay(cr, uid, vals) + self.pool.get('mrp.production.workcenter.line').write(cr,uid,wc_op_id,{'delay':delay}) + return super(mrp_operations_operation, self).create(cr, uid, vals, context=context) - + _columns={ 'production_id':fields.many2one('mrp.production','Production',required=True), 'workcenter_id':fields.many2one('mrp.workcenter','Workcenter',required=True), @@ -168,6 +314,9 @@ class mrp_operations_operation(osv.osv): 'date_finished': fields.datetime('End Date'), 'order_date': fields.function(_get_order_date,method=True,string='Order Date',type='date',store={'mrp.production':(['date_planned'],_order_date_search_production)}), } + _defaults={ + 'date_start': lambda *a:DateTime.now().strftime('%Y-%m-%d %H:%M:%S') + } mrp_operations_operation() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mrp_operations/mrp_operations_report.xml b/addons/mrp_operations/mrp_operations_report.xml old mode 100644 new mode 100755 diff --git a/addons/mrp_operations/mrp_operations_view.xml b/addons/mrp_operations/mrp_operations_view.xml old mode 100644 new mode 100755 index 661bce2776f..d9063f6c2d1 --- a/addons/mrp_operations/mrp_operations_view.xml +++ b/addons/mrp_operations/mrp_operations_view.xml @@ -9,6 +9,11 @@ tree +