2009-10-13 05:58:37 +00:00
# -*- coding: utf-8 -*-
2008-08-24 14:45:43 +00:00
##############################################################################
2009-11-13 05:41:16 +00:00
#
2009-10-14 11:15:34 +00:00
# OpenERP, Open Source Management Solution
2010-01-12 09:18:39 +00:00
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
2008-08-24 14:45:43 +00:00
#
2008-11-03 19:18:56 +00:00
# This program is free software: you can redistribute it and/or modify
2009-10-14 11:15:34 +00:00
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
2008-08-24 14:45:43 +00:00
#
2008-11-03 19:18:56 +00:00
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2009-10-14 11:15:34 +00:00
# GNU Affero General Public License for more details.
2008-08-24 14:45:43 +00:00
#
2009-10-14 11:15:34 +00:00
# You should have received a copy of the GNU Affero General Public License
2009-11-13 05:41:16 +00:00
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2008-08-24 14:45:43 +00:00
#
##############################################################################
from osv import fields
from osv import osv
import ir
2008-09-23 10:20:09 +00:00
import datetime
2008-08-24 14:45:43 +00:00
import netsvc
import time
from mx import DateTime
2009-03-06 22:18:24 +00:00
from tools . translate import _
2008-08-24 14:45:43 +00:00
#----------------------------------------------------------
2009-12-14 14:56:27 +00:00
# Work Centers
2008-08-24 14:45:43 +00:00
#----------------------------------------------------------
# capacity_hour : capacity per hour. default: 1.0.
# Eg: If 5 concurrent operations at one time: capacity = 5 (because 5 employees)
# unit_per_cycle : how many units are produced for one cycle
2009-05-29 22:52:55 +00:00
class stock_move ( osv . osv ) :
_inherit = ' stock.move '
_columns = {
' move_dest_id_lines ' : fields . one2many ( ' stock.move ' , ' move_dest_id ' , ' Children Moves ' )
}
stock_move ( )
2008-08-24 14:45:43 +00:00
class mrp_production_workcenter_line ( osv . osv ) :
2009-05-31 09:31:26 +00:00
def _get_date_date ( self , cr , uid , ids , field_name , arg , context ) :
2010-05-25 12:36:48 +00:00
""" Finds starting date.
@return : Dictionary of values .
"""
2009-05-31 09:31:26 +00:00
res = { }
for op in self . browse ( cr , uid , ids , context = context ) :
if op . date_start :
res [ op . id ] = op . date_start [ : 10 ]
else :
res [ op . id ] = False
return res
2010-05-25 12:36:48 +00:00
2009-05-29 22:52:55 +00:00
def _get_date_end ( self , cr , uid , ids , field_name , arg , context ) :
2010-05-25 12:36:48 +00:00
""" Finds ending date.
@return : Dictionary of values .
"""
2009-06-08 12:18:17 +00:00
res = { }
2009-05-29 22:52:55 +00:00
for op in self . browse ( cr , uid , ids , context = context ) :
2010-07-15 10:32:13 +00:00
res [ op . id ] = False
2009-06-08 12:18:17 +00:00
if op . date_planned :
d = DateTime . strptime ( op . date_planned , ' % Y- % m- %d % H: % M: % S ' )
2010-01-12 05:32:48 +00:00
i = self . pool . get ( ' resource.calendar ' ) . interval_get ( cr , uid , op . workcenter_id . calendar_id . id or False , d , op . hour or 0.0 )
2009-06-08 12:18:17 +00:00
if i :
res [ op . id ] = i [ - 1 ] [ 1 ] . strftime ( ' % Y- % m- %d % H: % M: % S ' )
else :
res [ op . id ] = op . date_planned
2009-05-29 22:52:55 +00:00
return res
2010-05-25 12:36:48 +00:00
2008-08-24 14:45:43 +00:00
_inherit = ' mrp.production.workcenter.line '
2009-11-26 13:54:00 +00:00
_order = " sequence, date_planned "
2010-05-25 12:36:48 +00:00
2008-08-24 14:45:43 +00:00
_columns = {
2009-12-29 12:25:25 +00:00
' state ' : fields . selection ( [ ( ' draft ' , ' Draft ' ) , ( ' startworking ' , ' In Progress ' ) , ( ' pause ' , ' Pause ' ) , ( ' cancel ' , ' Canceled ' ) , ( ' done ' , ' Finished ' ) ] , ' State ' , readonly = True ,
help = " * When a work order is created it is set in ' Draft ' state. \n " \
" * When user sets work order in start mode that time it will be set in ' In Progress ' state. \n " \
" * When work order is in running mode, during that time if user wants to stop or to make changes in order then can set in ' Pause ' state. \n " \
" * When the user cancels the work order it will be set in ' Canceled ' state. \n " \
" * When order is completely processed that time it is set in ' Finished ' state. " ) ,
2009-05-31 09:31:26 +00:00
' date_start_date ' : fields . function ( _get_date_date , method = True , string = ' Start Date ' , type = ' date ' ) ,
2009-11-26 13:54:00 +00:00
' date_planned ' : fields . datetime ( ' Scheduled Date ' ) ,
2009-05-29 22:52:55 +00:00
' date_planned_end ' : fields . function ( _get_date_end , method = True , string = ' End Date ' , type = ' datetime ' ) ,
2008-09-23 10:20:09 +00:00
' date_start ' : fields . datetime ( ' Start Date ' ) ,
' date_finnished ' : fields . datetime ( ' End Date ' ) ,
2009-12-21 09:50:54 +00:00
' delay ' : fields . float ( ' Working Hours ' , help = " This is lead time between operation start and stop in this workcenter " , readonly = True ) ,
2009-05-29 22:52:55 +00:00
' production_state ' : fields . related ( ' production_id ' , ' state ' ,
type = ' selection ' ,
2009-11-13 05:41:16 +00:00
selection = [ ( ' draft ' , ' Draft ' ) , ( ' picking_except ' , ' Picking Exception ' ) , ( ' confirmed ' , ' Waiting Goods ' ) , ( ' ready ' , ' Ready to Produce ' ) , ( ' in_production ' , ' In Production ' ) , ( ' cancel ' , ' Canceled ' ) , ( ' done ' , ' Done ' ) ] ,
2009-12-21 09:50:54 +00:00
string = ' Production State ' , readonly = True ) ,
2009-05-29 22:52:55 +00:00
' product ' : fields . related ( ' production_id ' , ' product_id ' , type = ' many2one ' , relation = ' product.product ' , string = ' Product ' ,
readonly = True ) ,
' qty ' : fields . related ( ' production_id ' , ' product_qty ' , type = ' float ' , string = ' Qty ' , readonly = True ) ,
' uom ' : fields . related ( ' production_id ' , ' product_uom ' , type = ' many2one ' , relation = ' product.uom ' , string = ' UOM ' , readonly = True ) ,
2008-08-24 14:45:43 +00:00
}
2010-05-25 12:36:48 +00:00
2008-08-24 14:45:43 +00:00
_defaults = {
' state ' : lambda * a : ' draft ' ,
2009-05-29 22:52:55 +00:00
' delay ' : lambda * a : 0.0
2008-08-24 14:45:43 +00:00
}
2010-05-25 12:36:48 +00:00
def modify_production_order_state ( self , cr , uid , ids , action ) :
""" Modifies production order state if work order state is changed.
@param action : Action to perform .
@return : Nothing
"""
2008-09-23 10:20:09 +00:00
wf_service = netsvc . LocalService ( " workflow " )
2010-05-25 12:36:48 +00:00
oper_obj = self . browse ( cr , uid , ids ) [ 0 ]
prod_obj = oper_obj . production_id
if action == ' start ' :
2009-01-26 22:57:42 +00:00
if prod_obj . state == ' confirmed ' :
self . pool . get ( ' mrp.production ' ) . force_production ( cr , uid , [ prod_obj . id ] )
wf_service . trg_validate ( uid , ' mrp.production ' , prod_obj . id , ' button_produce ' , cr )
elif prod_obj . state == ' ready ' :
2008-09-23 10:20:09 +00:00
wf_service . trg_validate ( uid , ' mrp.production ' , prod_obj . id , ' button_produce ' , cr )
elif prod_obj . state == ' in_production ' :
return
else :
2009-03-06 22:18:24 +00:00
raise osv . except_osv ( _ ( ' Error! ' ) , _ ( ' Production Order Cannot start in [ %s ] state ' ) % ( prod_obj . state , ) )
2008-09-23 10:20:09 +00:00
else :
2010-05-25 12:36:48 +00:00
oper_ids = self . search ( cr , uid , [ ( ' production_id ' , ' = ' , prod_obj . id ) ] )
obj = self . browse ( cr , uid , oper_ids )
flag = True
2008-09-23 10:20:09 +00:00
for line in obj :
2010-05-25 12:36:48 +00:00
if line . state != ' done ' :
flag = False
2008-09-23 10:20:09 +00:00
if flag :
wf_service . trg_validate ( uid , ' mrp.production ' , oper_obj . production_id . id , ' button_produce_done ' , cr )
return
2008-10-21 09:33:53 +00:00
2009-05-29 22:52:55 +00:00
def write ( self , cr , uid , ids , vals , context = { } , update = True ) :
result = super ( mrp_production_workcenter_line , self ) . write ( cr , uid , ids , vals , context = context )
2010-07-28 07:22:38 +00:00
prod_obj = self . pool . get ( ' mrp.production ' )
2009-05-29 22:52:55 +00:00
if vals . get ( ' date_planned ' , False ) and update :
pids = { }
2009-05-31 09:22:26 +00:00
pids2 = { }
2009-05-29 22:52:55 +00:00
for prod in self . browse ( cr , uid , ids , context = context ) :
2009-05-31 09:22:26 +00:00
if prod . production_id . workcenter_lines :
2009-05-31 22:05:07 +00:00
dstart = min ( vals [ ' date_planned ' ] , prod . production_id . workcenter_lines [ 0 ] [ ' date_planned ' ] )
2010-07-28 07:22:38 +00:00
prod_obj . write ( cr , uid , [ prod . production_id . id ] , { ' date_start ' : dstart } , context = context , mini = False )
2009-05-29 22:52:55 +00:00
return result
2008-08-24 14:45:43 +00:00
def action_draft ( self , cr , uid , ids ) :
2010-05-25 12:36:48 +00:00
""" Sets state to draft.
@return : True
"""
2008-08-24 14:45:43 +00:00
self . write ( cr , uid , ids , { ' state ' : ' draft ' } )
return True
2008-09-23 10:20:09 +00:00
def action_start_working ( self , cr , uid , ids ) :
2010-05-25 12:36:48 +00:00
""" Sets state to start working and writes starting date.
@return : True
"""
self . modify_production_order_state ( cr , uid , ids , ' start ' )
2009-05-29 22:52:55 +00:00
self . write ( cr , uid , ids , { ' state ' : ' startworking ' , ' date_start ' : time . strftime ( ' % Y- % m- %d % H: % M: % S ' ) } )
2008-08-24 14:45:43 +00:00
return True
def action_done ( self , cr , uid , ids ) :
2010-05-25 12:36:48 +00:00
""" Sets state to done, writes finish date and calculates delay.
@return : True
"""
2009-12-10 12:46:54 +00:00
delay = 0.0
date_now = time . strftime ( ' % Y- % m- %d % H: % M: % S ' )
obj_line = self . browse ( cr , uid , ids [ 0 ] )
date_start = datetime . datetime . strptime ( obj_line . date_start , ' % Y- % m- %d % H: % M: % S ' )
date_finished = datetime . datetime . strptime ( date_now , ' % Y- % m- %d % H: % M: % S ' )
delay + = ( date_finished - date_start ) . days * 24
delay + = ( date_finished - date_start ) . seconds / float ( 60 * 60 )
self . write ( cr , uid , ids , { ' state ' : ' done ' , ' date_finnished ' : date_now , ' delay ' : delay } )
2008-09-23 10:20:09 +00:00
self . modify_production_order_state ( cr , uid , ids , ' done ' )
2008-08-24 14:45:43 +00:00
return True
def action_cancel ( self , cr , uid , ids ) :
2010-05-25 12:36:48 +00:00
""" Sets state to cancel.
@return : True
"""
2008-08-24 14:45:43 +00:00
self . write ( cr , uid , ids , { ' state ' : ' cancel ' } )
return True
2008-10-21 09:33:53 +00:00
2008-09-23 10:20:09 +00:00
def action_pause ( self , cr , uid , ids ) :
2010-05-25 12:36:48 +00:00
""" Sets state to pause.
@return : True
"""
2008-09-23 10:20:09 +00:00
self . write ( cr , uid , ids , { ' state ' : ' pause ' } )
return True
2008-10-21 09:33:53 +00:00
2008-09-23 10:20:09 +00:00
def action_resume ( self , cr , uid , ids ) :
2010-05-25 12:36:48 +00:00
""" Sets state to startworking.
@return : True
"""
2008-09-23 10:20:09 +00:00
self . write ( cr , uid , ids , { ' state ' : ' startworking ' } )
return True
2008-08-24 14:45:43 +00:00
mrp_production_workcenter_line ( )
class mrp_production ( osv . osv ) :
_inherit = ' mrp.production '
2009-05-31 09:22:26 +00:00
_columns = {
' allow_reorder ' : fields . boolean ( ' Free Serialisation ' , help = " Check this to be able to move independently all production orders, without moving dependent ones. " ) ,
}
2008-08-24 14:45:43 +00:00
2009-05-29 22:52:55 +00:00
def _production_date_end ( self , cr , uid , ids , prop , unknow_none , context = { } ) :
2010-05-25 12:36:48 +00:00
""" Calculates planned end date of production order.
@return : Dictionary of values
"""
2009-05-29 22:52:55 +00:00
result = { }
for prod in self . browse ( cr , uid , ids , context = context ) :
result [ prod . id ] = prod . date_planned
for line in prod . workcenter_lines :
result [ prod . id ] = max ( line . date_planned_end , result [ prod . id ] )
return result
2008-08-24 14:45:43 +00:00
def action_production_end ( self , cr , uid , ids ) :
2010-05-25 12:36:48 +00:00
""" Finishes work order if production order is done.
@return : Super method
"""
obj = self . browse ( cr , uid , ids ) [ 0 ]
2010-07-28 07:22:38 +00:00
wf_service = netsvc . LocalService ( " workflow " )
2008-08-24 14:45:43 +00:00
for workcenter_line in obj . workcenter_lines :
2010-07-26 11:09:01 +00:00
wf_service . trg_validate ( uid , ' mrp.production.workcenter.line ' , workcenter_line . id , ' button_done ' , cr )
2010-05-25 12:36:48 +00:00
return super ( mrp_production , self ) . action_production_end ( cr , uid , ids )
2010-04-13 06:19:07 +00:00
def action_in_production ( self , cr , uid , ids ) :
""" Changes state to In Production and writes starting date.
@return : True
"""
obj = self . browse ( cr , uid , ids ) [ 0 ]
2010-07-28 07:22:38 +00:00
wf_service = netsvc . LocalService ( " workflow " )
2010-04-13 06:19:07 +00:00
for workcenter_line in obj . workcenter_lines :
2010-07-26 11:09:01 +00:00
wf_service . trg_validate ( uid , ' mrp.production.workcenter.line ' , workcenter_line . id , ' button_start_working ' , cr )
2010-04-13 06:19:07 +00:00
return super ( mrp_production , self ) . action_in_production ( cr , uid , ids )
2008-08-24 14:45:43 +00:00
def action_cancel ( self , cr , uid , ids ) :
2010-05-25 12:36:48 +00:00
""" Cancels work order if production order is canceled.
@return : Super method
"""
obj = self . browse ( cr , uid , ids ) [ 0 ]
2010-07-28 07:22:38 +00:00
wf_service = netsvc . LocalService ( " workflow " )
2008-08-24 14:45:43 +00:00
for workcenter_line in obj . workcenter_lines :
2010-07-26 11:09:01 +00:00
wf_service . trg_validate ( uid , ' mrp.production.workcenter.line ' , workcenter_line . id , ' button_cancel ' , cr )
2008-08-24 14:45:43 +00:00
return super ( mrp_production , self ) . action_cancel ( cr , uid , ids )
2009-05-31 22:05:07 +00:00
def _compute_planned_workcenter ( self , cr , uid , ids , context = { } , mini = False ) :
2010-05-25 12:36:48 +00:00
""" Computes planned and finished dates for work order.
@return : Calculated date
"""
2009-05-29 22:52:55 +00:00
dt_end = DateTime . now ( )
for po in self . browse ( cr , uid , ids , context = context ) :
dt_end = DateTime . strptime ( po . date_start or po . date_planned , ' % Y- % m- %d % H: % M: % S ' )
if not po . date_start :
self . write ( cr , uid , [ po . id ] , {
' date_start ' : po . date_planned
} , context = context , update = False )
old = None
for wci in range ( len ( po . workcenter_lines ) ) :
wc = po . workcenter_lines [ wci ]
if ( old is None ) or ( wc . sequence > old ) :
dt = dt_end
2009-05-31 09:22:26 +00:00
if context . get ( ' __last_update ' ) :
del context [ ' __last_update ' ]
2009-05-31 22:05:07 +00:00
if ( wc . date_planned < dt . strftime ( ' % Y- % m- %d % H: % M: % S ' ) ) or mini :
2009-05-31 09:22:26 +00:00
self . pool . get ( ' mrp.production.workcenter.line ' ) . write ( cr , uid , [ wc . id ] , {
' date_planned ' : dt . strftime ( ' % Y- % m- %d % H: % M: % S ' )
} , context = context , update = False )
2010-01-12 05:32:48 +00:00
i = self . pool . get ( ' resource.calendar ' ) . interval_get (
2009-05-31 09:22:26 +00:00
cr ,
uid ,
2010-01-12 05:32:48 +00:00
wc . workcenter_id . calendar_id and wc . workcenter_id . calendar_id . id or False ,
2009-05-31 09:22:26 +00:00
dt ,
wc . hour or 0.0
)
if i :
dt_end = max ( dt_end , i [ - 1 ] [ 1 ] )
else :
dt_end = DateTime . strptime ( wc . date_planned_end , ' % Y- % m- %d % H: % M: % S ' )
old = wc . sequence or 0
2009-05-29 22:52:55 +00:00
super ( mrp_production , self ) . write ( cr , uid , [ po . id ] , {
' date_finnished ' : dt_end
} )
return dt_end
def _move_pass ( self , cr , uid , ids , context = { } ) :
2010-05-25 12:36:48 +00:00
""" Calculates start date for stock moves finding interval from resource calendar.
@return : True
"""
2009-05-29 22:52:55 +00:00
for po in self . browse ( cr , uid , ids , context ) :
2009-05-31 09:22:26 +00:00
if po . allow_reorder :
continue
2009-05-29 22:52:55 +00:00
todo = po . move_lines
dt = DateTime . strptime ( po . date_start , ' % Y- % m- %d % H: % M: % S ' )
while todo :
l = todo . pop ( 0 )
if l . state in ( ' done ' , ' cancel ' , ' draft ' ) :
continue
todo + = l . move_dest_id_lines
2010-05-25 12:36:48 +00:00
if l . production_id and ( l . production_id . date_finnished > dt ) :
2009-05-31 09:22:26 +00:00
if l . production_id . state not in ( ' done ' , ' cancel ' ) :
for wc in l . production_id . workcenter_lines :
2010-01-12 05:32:48 +00:00
i = self . pool . get ( ' resource.calendar ' ) . interval_min_get (
2009-11-13 05:41:16 +00:00
cr ,
uid ,
2010-01-12 05:32:48 +00:00
wc . workcenter_id . calendar_id . id or False ,
2009-05-31 09:22:26 +00:00
dt , wc . hour or 0.0
)
2009-05-31 22:05:07 +00:00
dt = i [ 0 ] [ 0 ]
2010-05-25 12:36:48 +00:00
if l . production_id . date_start > dt . strftime ( ' % Y- % m- %d % H: % M: % S ' ) :
2009-05-31 22:05:07 +00:00
self . write ( cr , uid , [ l . production_id . id ] , { ' date_start ' : dt . strftime ( ' % Y- % m- %d % H: % M: % S ' ) } , mini = True )
2009-05-29 22:52:55 +00:00
return True
def _move_futur ( self , cr , uid , ids , context = { } ) :
2010-05-25 12:36:48 +00:00
""" Calculates start date for stock moves.
@return : True
"""
2009-05-29 22:52:55 +00:00
for po in self . browse ( cr , uid , ids , context ) :
2009-05-31 09:22:26 +00:00
if po . allow_reorder :
continue
2009-05-29 22:52:55 +00:00
for line in po . move_created_ids :
l = line
while l . move_dest_id :
l = l . move_dest_id
if l . state in ( ' done ' , ' cancel ' , ' draft ' ) :
break
2009-05-31 09:22:26 +00:00
if l . production_id . state in ( ' done ' , ' cancel ' ) :
break
2010-05-25 12:36:48 +00:00
if l . production_id and ( l . production_id . date_start < po . date_finnished ) :
self . write ( cr , uid , [ l . production_id . id ] , { ' date_start ' : po . date_finnished } )
2009-05-29 22:52:55 +00:00
break
2009-05-31 22:05:07 +00:00
def write ( self , cr , uid , ids , vals , context = { } , update = True , mini = True ) :
2009-05-29 22:52:55 +00:00
direction = { }
if vals . get ( ' date_start ' , False ) :
for po in self . browse ( cr , uid , ids , context = context ) :
direction [ po . id ] = cmp ( po . date_start , vals . get ( ' date_start ' , False ) )
result = super ( mrp_production , self ) . write ( cr , uid , ids , vals , context = context )
if ( vals . get ( ' workcenter_lines ' , False ) or vals . get ( ' date_start ' , False ) ) and update :
2009-05-31 22:05:07 +00:00
self . _compute_planned_workcenter ( cr , uid , ids , context = context , mini = mini )
2009-05-29 22:52:55 +00:00
for d in direction :
2010-05-25 12:36:48 +00:00
if direction [ d ] == 1 :
2009-05-29 22:52:55 +00:00
# the production order has been moved to the passed
self . _move_pass ( cr , uid , [ d ] , context = context )
pass
2010-05-25 12:36:48 +00:00
elif direction [ d ] == - 1 :
2009-05-29 22:52:55 +00:00
self . _move_futur ( cr , uid , [ d ] , context = context )
# the production order has been moved to the future
pass
return result
def action_compute ( self , cr , uid , ids , properties = [ ] ) :
2010-05-25 12:36:48 +00:00
""" Computes bills of material of a product and planned date of work order.
@param properties : List containing dictionaries of properties .
@return : No . of products .
"""
2009-05-29 22:52:55 +00:00
result = super ( mrp_production , self ) . action_compute ( cr , uid , ids , properties = properties )
self . _compute_planned_workcenter ( cr , uid , ids , context = { } )
return result
2008-08-24 14:45:43 +00:00
mrp_production ( )
class mrp_operations_operation_code ( osv . osv ) :
_name = " mrp_operations.operation.code "
_columns = {
' name ' : fields . char ( ' Operation Name ' , size = 64 , required = True ) ,
' code ' : fields . char ( ' Code ' , size = 16 , required = True ) ,
2009-09-24 10:46:21 +00:00
' start_stop ' : fields . selection ( [ ( ' start ' , ' Start ' ) , ( ' pause ' , ' Pause ' ) , ( ' resume ' , ' Resume ' ) , ( ' cancel ' , ' Cancelled ' ) , ( ' done ' , ' Done ' ) ] , ' Status ' , required = True ) ,
2008-08-24 14:45:43 +00:00
}
mrp_operations_operation_code ( )
class mrp_operations_operation ( osv . osv ) :
_name = " mrp_operations.operation "
2008-10-21 09:33:53 +00:00
2008-12-09 12:05:11 +00:00
def _order_date_search_production ( self , cr , uid , ids , context = None ) :
2010-05-25 12:36:48 +00:00
""" Finds operations for a production order.
@return : List of ids
"""
operation_ids = self . pool . get ( ' mrp_operations.operation ' ) . search ( cr , uid , [ ( ' production_id ' , ' = ' , ids [ 0 ] ) ] , context = context )
2008-09-01 08:35:16 +00:00
return operation_ids
2008-10-21 09:33:53 +00:00
2008-09-01 08:35:16 +00:00
def _get_order_date ( self , cr , uid , ids , field_name , arg , context ) :
2010-05-25 12:36:48 +00:00
""" Calculates planned date for an operation.
@return : Dictionary of values
"""
2008-09-01 08:35:16 +00:00
res = { }
2010-05-25 12:36:48 +00:00
operation_obj = self . browse ( cr , uid , ids , context = context )
2008-09-01 08:35:16 +00:00
for operation in operation_obj :
2010-05-25 12:36:48 +00:00
res [ operation . id ] = operation . production_id . date_planned
2008-09-01 08:35:16 +00:00
return res
2008-10-21 09:33:53 +00:00
2010-05-25 12:36:48 +00:00
def calc_delay ( self , cr , uid , vals ) :
""" Calculates delay of work order.
@return : Delay
"""
code_lst = [ ]
time_lst = [ ]
2008-10-21 09:33:53 +00:00
2010-05-25 12:36:48 +00:00
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 ]
2008-10-21 09:33:53 +00:00
2010-05-25 12:36:48 +00:00
oper_ids = self . search ( cr , uid , [ ( ' production_id ' , ' = ' , vals [ ' production_id ' ] ) , ( ' workcenter_id ' , ' = ' , vals [ ' workcenter_id ' ] ) ] )
oper_objs = self . browse ( cr , uid , oper_ids )
2008-10-21 09:33:53 +00:00
2008-09-23 10:20:09 +00:00
for oper in oper_objs :
code_lst . append ( oper . code_id . start_stop )
time_lst . append ( oper . date_start )
2008-10-21 09:33:53 +00:00
2008-09-23 10:20:09 +00:00
code_lst . append ( code . start_stop )
time_lst . append ( vals [ ' date_start ' ] )
2009-05-29 22:52:55 +00:00
diff = 0
2008-09-23 10:20:09 +00:00
for i in range ( 0 , len ( code_lst ) ) :
2010-05-25 12:36:48 +00:00
if code_lst [ i ] == ' pause ' or code_lst [ i ] == ' done ' or code_lst [ i ] == ' cancel ' :
2009-05-29 22:52:55 +00:00
if not i : continue
if code_lst [ i - 1 ] not in ( ' resume ' , ' start ' ) :
2008-09-23 10:20:09 +00:00
continue
2009-11-11 12:37:41 +00:00
a = datetime . datetime . strptime ( time_lst [ i - 1 ] , ' % Y- % m- %d % H: % M: % S ' )
b = datetime . datetime . strptime ( time_lst [ i ] , ' % Y- % m- %d % H: % M: % S ' )
2009-05-29 22:52:55 +00:00
diff + = ( b - a ) . days * 24
2009-12-10 12:46:54 +00:00
diff + = ( b - a ) . seconds / float ( 60 * 60 )
2009-05-29 22:52:55 +00:00
return diff
2008-10-21 09:33:53 +00:00
2010-05-25 12:36:48 +00:00
def check_operation ( self , cr , uid , vals ) :
""" Finds which operation is called ie. start, pause, done, cancel.
@param vals : Dictionary of values .
@return : True or False
"""
2008-09-23 10:20:09 +00:00
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 )
2008-10-21 09:33:53 +00:00
2008-09-23 10:20:09 +00:00
if not oper_objs :
if code . start_stop != ' start ' :
raise osv . except_osv ( _ ( ' Sorry! ' ) , _ ( ' Operation is not started yet ! ' ) )
return False
2008-10-21 09:33:53 +00:00
else :
2008-09-23 10:20:09 +00:00
for oper in oper_objs :
code_lst . append ( oper . code_id . start_stop )
if code . start_stop == ' start ' :
2008-10-21 09:33:53 +00:00
if ' start ' in code_lst :
2008-09-23 10:20:09 +00:00
raise osv . except_osv ( _ ( ' Sorry! ' ) , _ ( ' Operation has already started ! ' ' You can either Pause /Finish/Cancel the operation ' ) )
return False
if code . start_stop == ' pause ' :
2008-10-21 09:33:53 +00:00
if code_lst [ len ( code_lst ) - 1 ] != ' resume ' and code_lst [ len ( code_lst ) - 1 ] != ' start ' :
2008-09-23 10:20:09 +00:00
raise osv . except_osv ( _ ( ' Error! ' ) , _ ( ' You cannot Pause the Operation other then Start/Resume state ! ' ) )
return False
2008-10-21 09:33:53 +00:00
if code . start_stop == ' resume ' :
if code_lst [ len ( code_lst ) - 1 ] != ' pause ' :
2008-09-23 10:20:09 +00:00
raise osv . except_osv ( _ ( ' Error! ' ) , _ ( ' You cannot Resume the operation other then Pause state ! ' ) )
return False
2008-10-21 09:33:53 +00:00
2008-09-23 10:20:09 +00:00
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
2008-10-21 09:33:53 +00:00
2008-09-23 10:20:09 +00:00
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
2008-10-21 09:33:53 +00:00
2008-09-23 10:20:09 +00:00
if ' code_id ' in vals :
self . check_operation ( cr , uid , vals )
2008-10-21 09:33:53 +00:00
2008-09-23 10:20:09 +00:00
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 } )
2008-10-21 09:33:53 +00:00
2008-09-23 10:20:09 +00:00
return super ( mrp_operations_operation , self ) . write ( cr , uid , ids , vals , context = context )
2008-10-21 09:33:53 +00:00
2008-08-24 14:45:43 +00:00
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 ]
2008-09-23 10:20:09 +00:00
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 ' ) :
2008-08-24 14:45:43 +00:00
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 ' :
2008-09-23 10:20:09 +00:00
tmp = self . pool . get ( ' mrp.production.workcenter.line ' ) . action_start_working ( cr , uid , wc_op_id )
2008-10-21 09:33:53 +00:00
wf_service . trg_validate ( uid , ' mrp.production.workcenter.line ' , wc_op_id [ 0 ] , ' button_start_working ' , cr )
2009-12-10 12:46:54 +00:00
2008-10-21 09:33:53 +00:00
2008-08-24 14:45:43 +00:00
if code . start_stop == ' done ' :
tmp = self . pool . get ( ' mrp.production.workcenter.line ' ) . action_done ( cr , uid , wc_op_id )
2008-10-21 09:33:53 +00:00
wf_service . trg_validate ( uid , ' mrp.production.workcenter.line ' , wc_op_id [ 0 ] , ' button_done ' , cr )
2008-08-24 14:45:43 +00:00
self . pool . get ( ' mrp.production ' ) . write ( cr , uid , vals [ ' production_id ' ] , { ' date_finnished ' : DateTime . now ( ) . strftime ( ' % Y- % m- %d % H: % M: % S ' ) } )
2008-10-21 09:33:53 +00:00
2008-09-23 10:20:09 +00:00
if code . start_stop == ' pause ' :
tmp = self . pool . get ( ' mrp.production.workcenter.line ' ) . action_pause ( cr , uid , wc_op_id )
2008-10-21 09:33:53 +00:00
wf_service . trg_validate ( uid , ' mrp.production.workcenter.line ' , wc_op_id [ 0 ] , ' button_pause ' , cr )
2008-09-23 10:20:09 +00:00
if code . start_stop == ' resume ' :
tmp = self . pool . get ( ' mrp.production.workcenter.line ' ) . action_resume ( cr , uid , wc_op_id )
2008-10-21 09:33:53 +00:00
wf_service . trg_validate ( uid , ' mrp.production.workcenter.line ' , wc_op_id [ 0 ] , ' button_resume ' , cr )
2008-09-23 10:20:09 +00:00
if code . start_stop == ' cancel ' :
tmp = self . pool . get ( ' mrp.production.workcenter.line ' ) . action_cancel ( cr , uid , wc_op_id )
2008-10-21 09:33:53 +00:00
wf_service . trg_validate ( uid , ' mrp.production.workcenter.line ' , wc_op_id [ 0 ] , ' button_cancel ' , cr )
2008-09-23 10:20:09 +00:00
if not self . check_operation ( cr , uid , vals ) :
return
delay = self . calc_delay ( cr , uid , vals )
2009-12-10 12:46:54 +00:00
line_vals = { }
line_vals [ ' delay ' ] = delay
if vals . get ( ' date_start ' , False ) :
if code . start_stop == ' done ' :
line_vals [ ' date_finnished ' ] = vals [ ' date_start ' ]
elif code . start_stop == ' start ' :
line_vals [ ' date_start ' ] = vals [ ' date_start ' ]
2008-10-21 09:33:53 +00:00
2009-12-10 12:46:54 +00:00
self . pool . get ( ' mrp.production.workcenter.line ' ) . write ( cr , uid , wc_op_id , line_vals , context = context )
return super ( mrp_operations_operation , self ) . create ( cr , uid , vals , context = context )
2008-10-21 09:33:53 +00:00
2008-08-24 14:45:43 +00:00
_columns = {
' production_id ' : fields . many2one ( ' mrp.production ' , ' Production ' , required = True ) ,
2009-12-14 14:56:27 +00:00
' workcenter_id ' : fields . many2one ( ' mrp.workcenter ' , ' Work Center ' , required = True ) ,
2008-08-24 14:45:43 +00:00
' code_id ' : fields . many2one ( ' mrp_operations.operation.code ' , ' Code ' , required = True ) ,
2008-09-01 08:35:16 +00:00
' date_start ' : fields . datetime ( ' Start Date ' ) ,
' date_finished ' : fields . datetime ( ' End Date ' ) ,
2008-12-15 08:06:40 +00:00
' order_date ' : fields . function ( _get_order_date , method = True , string = ' Order Date ' , type = ' date ' , store = { ' mrp.production ' : ( _order_date_search_production , [ ' date_planned ' ] , 10 ) } ) ,
2008-08-24 14:45:43 +00:00
}
2008-09-23 10:20:09 +00:00
_defaults = {
2009-05-29 22:52:55 +00:00
' date_start ' : lambda * a : DateTime . now ( ) . strftime ( ' % Y- % m- %d % H: % M: % S ' )
}
2008-08-24 14:45:43 +00:00
mrp_operations_operation ( )
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: