71
71
select id from (select distinct slh.id as child_id from hr_department slp
72
72
left outer join hr_department slh on slh.parent_id between slp.id and slh.parent_id
73
where slh.parent_id =%s) as hijos join hr_department as hrd ON hrd.id = hijos.child_id
73
where slh.parent_id =%s) as hijos join hr_department as hrd ON hrd.id = hijos.child_id
74
74
or hrd.parent_id = hijos.child_id
76
76
ids.append(departamento_id)
78
78
ids_fech = cr.fetchall()
80
80
ids = ids + [id[0] for id in ids_fech]
84
84
def _get_trabajadores_nomina(self, cr, uid, group_name, param_nomina=None, context=None):
86
parameter_obj = self.pool.get('hr.parameters')
87
parameters_id = parameter_obj.search(cr, uid, [('type', '=', 'cargar_sobretiempos_nomina')])
90
parameters_brw = parameter_obj.browse(cr, uid, parameters_id)[0]
91
param_nomina = parameters_brw.check_cargar_sobretiempos_nomina
93
grupo = self._get_grupo_id(cr, uid, group_name)
95
grupos_usuario = self._get_grupos_usuario(cr, uid, context)
96
if grupo in grupos_usuario:
86
parameter_obj = self.pool.get('hr.parameters')
87
parameters_id = parameter_obj.search(cr, uid, [('type', '=', 'cargar_sobretiempos_nomina')])
90
parameters_brw = parameter_obj.browse(cr, uid, parameters_id)[0]
91
param_nomina = parameters_brw.check_cargar_sobretiempos_nomina
93
grupo = self._get_grupo_id(cr, uid, group_name)
95
grupos_usuario = self._get_grupos_usuario(cr, uid, context)
96
if grupo in grupos_usuario:
100
100
def _get_subordinados_ids(self, cr, uid, ids, field_name, arg, context):
102
102
obj_employee = self.pool.get('hr.employee')
103
103
obj_department = self.pool.get('hr.department')
104
104
load_nom = self._get_trabajadores_nomina(cr, uid, 'group_sisb_horas_extras_th', param_nomina=None, context=None)
105
params = [] if uid ==1 or load_nom else [('user_id', '=', uid)]
105
params = [] if uid == 1 or load_nom else [('user_id', '=', uid)]
106
106
emp_id = obj_employee.search(cr, uid, params)
107
107
subordinado = emp_id
108
if uid !=1 and not load_nom:
108
if uid != 1 and not load_nom:
109
109
busqueda_recursiva_emp = self.search_childs_department
110
110
subordinado = subordinado + busqueda_recursiva_emp(cr, uid, emp_id)
111
111
subordinado = list(set(subordinado))
113
if emp_id[0] in subordinado:
114
subordinado.remove(emp_id[0])
113
if emp_id[0] in subordinado:
114
subordinado.remove(emp_id[0])
115
115
subordinado = str(subordinado)
117
117
res[i] = subordinado
120
120
def _get_back_draft(self, cr, uid, ids, field_name, arg, context):
122
122
brw = self.browse(cr, uid, ids)
123
123
grupo = self._get_grupo_id(cr, uid, 'group_sisb_horas_extras_volver_borrador')
124
124
grupos_usuario = self._get_grupos_usuario(cr, uid, context)
127
if (uid == 1 and i.state in ['confirmed','cancel', 'processing']) or (grupo in grupos_usuario and i.state in ['confirmed','cancel', 'processing']) or i.state == 'confirmed' :
127
if (uid == 1 and i.state in ['confirmed', 'processing']) or (grupo in grupos_usuario and i.state in ['confirmed', 'processing']) or i.state == 'confirmed':
133
133
def _get_department(self, cr, uid):
135
if uid == 1: return res
136
137
obj_employee = self.pool.get('hr.employee')
137
138
params = [('user_id', '=', uid)]
138
139
emp_id = obj_employee.search(cr, uid, params)
139
140
emp_brw = obj_employee.browse(cr, uid, emp_id)
141
res = emp_brw[0].department_id.id
142
res = emp_brw[0].department_id.id
143
raise osv.except_osv(_('Error'), _('El usuario conectado debe poseer un perfil asociado en Talento Humano'))
144
raise osv.except_osv(_('Error'), _('El usuario conectado debe poseer un perfil asociado en Talento Humano'))
146
147
def _get_grupos_usuario(self, cr, uid, context=None):
147
148
return [group.id for group in self.pool.get('res.users').browse(cr, uid, uid, context=None).groups_id]
149
150
def _get_grupo_id(self, cr, uid, group_name, context=None):
150
151
"""Devuelve el id del grupo 'group_name'. Devuelve False en caso de no existir """
151
152
model_data_obj = self.pool.get('ir.model.data')
152
grupo_search = model_data_obj.search(cr, 1, [('name','=',group_name),('model','=','res.groups')], context=None)
153
grupo_search = model_data_obj.search(cr, 1, [('name', '=', group_name), ('model', '=', 'res.groups')], context=None)
153
154
grupo = model_data_obj.read(cr, 1, grupo_search, ['res_id'], context)[0]['res_id']
159
'name': fields.char('name', size=64),
160
'user_id': fields.many2one('res.users', 'Usuario', readonly=True),
161
'department_id':fields.many2one('hr.department', 'Departamento', readonly=True),
162
'observacion': fields.text('Observacion'),
163
'fecha': fields.date('Fecha', required=True, readonly=True),
164
'referencia': fields.char('Referencia', size=64, required=True, readonly=True),
165
'permitidos': fields.function(_get_subordinados_ids, string='Permitidos', method=True, type='text', store=False, ),
166
'permitir_back_draf': fields.function(_get_back_draft, string='Volver a borrador', method=True, type='boolean', store=False),
167
'state': fields.selection([('draft','Borrador'), ('confirmed','Confirmado'),('approved','Aprobado'),
168
('processing','Procesado'), ('exception','Excepcion'), ('load','Cargado'),
169
('done','Listo'), ('cancel','Cancelado')],'Estado', readonly=True),
173
'fecha': lambda *a : datetime.datetime.now().strftime("%Y-%m-%d"),
174
'state': lambda *a : 'draft',
175
'referencia': lambda *a: 'ST-#',
176
'user_id': lambda self, cr, uid, context=None: uid,
177
'department_id': lambda self, cr, uid, context=None: self._get_department(cr, uid)
180
horas_extras_planificacion()
160
'name': fields.char('name', size=64),
161
'user_id': fields.many2one('res.users', 'Usuario', readonly=True),
162
'department_id': fields.many2one('hr.department', 'Departamento', readonly=True),
163
'observacion': fields.text('Observacion'),
164
'fecha': fields.date('Fecha', required=True, readonly=True),
165
'referencia': fields.char('Referencia', size=64, required=True, readonly=True),
166
'permitidos': fields.function(_get_subordinados_ids, string='Permitidos', method=True, type='text', store=False, ),
167
'permitir_back_draf': fields.function(_get_back_draft, string='Volver a borrador', method=True, type='boolean', store=False),
168
'state': fields.selection([('draft', 'Borrador'), ('confirmed', 'Confirmado'), ('approved', 'Aprobado'),
169
('processing', 'Procesado'), ('exception', 'Excepcion'), ('load', 'Cargado'),
170
('done', 'Listo'), ('cancel', 'Cancelado')], 'Estado', readonly=True),
174
'fecha': lambda *a: datetime.datetime.now().strftime("%Y-%m-%d"),
175
'state': lambda *a: 'draft',
176
'referencia': lambda *a: 'ST-#',
177
'user_id': lambda self, cr, uid, context=None: uid,
178
'department_id': lambda self, cr, uid, context=None: self._get_department(cr, uid)
182
horas_extras_planificacion()
183
185
class horas_extras_planificacion_lineas(osv.osv):
185
187
_name = 'horas.extras.planificacion.lineas'
186
188
_description = 'Horas extras lineas'
189
191
def _calc_turno(self, cr, uid, ids, field_name, args, context=None):
191
193
brw = self.browse(cr, uid, ids, context=context)
193
195
hsw_obj = self.pool.get('hr.shift.week')
195
197
hsw_id = hsw_obj.search(cr, uid, [('employee_id', '=', i.empleado_id.id), ('period_id.date_start', '<=', i.fecha_desde), ('period_id.date_end', '>=', i.fecha_desde)], context=context)
196
res[i.id] = hsw_obj.read(cr, uid, hsw_id, context=context)[0][days[datetime.datetime.strptime(i.fecha_desde, '%Y-%m-%d').weekday()]+'_hours_day_id'][1] if hsw_id else None
198
res[i.id] = hsw_obj.read(cr, uid, hsw_id, context=context)[0][days[datetime.datetime.strptime(i.fecha_desde, '%Y-%m-%d').weekday()] + '_hours_day_id'][1] if hsw_id else None
200
'name': fields.char('Lineas de horas extras', size=64),
201
'empleado_id': fields.many2one('hr.employee', 'Trabajador', required=True),
202
'department_id':fields.related('empleado_id', 'department_id', relation='hr.department', string="Departamento",
203
type='many2one', store=True, readonly=True, select=False),
204
'fecha_desde': fields.date('Fecha desde', required=True),
205
'fecha_hasta': fields.date('Fecha hasta', required=True),
206
'hora_desde': fields.time('Hora desde', required=True),
207
'hora_hasta': fields.time('Hora hasta', required=True),
208
'serv_comida': fields.boolean('Servicio de comida'),
209
'horas_extras_planificacion_id': fields.many2one('horas.extras.planificacion', 'Referencia', readonly=True),
210
'motivo_id': fields.many2one('horas.extras.planificacion.tipos', 'Motivo', required=True),
211
'excepciones': fields.boolean('excepciones'),
212
'turno_id': fields.function(_calc_turno, method=True, string='Turno calculado', type='meny2one', relation='hr.hour.per.day'),
213
'state': fields.selection([('draft','Borrador'), ('confirmed','Confirmado'),('approved','Aprobado'),
214
('processing','Procesado'), ('exception','Excepcion'), ('load','Cargado'), ('done','Listo'),
215
('cancel','Cancelado')],'Estado', readonly=True),
202
'name': fields.char('Lineas de horas extras', size=64),
203
'empleado_id': fields.many2one('hr.employee', 'Trabajador', required=True),
204
'department_id': fields.related('empleado_id', 'department_id', relation='hr.department', string="Departamento",
205
type='many2one', store=True, readonly=True, select=False),
206
'fecha_desde': fields.date('Fecha desde', required=True),
207
'fecha_hasta': fields.date('Fecha hasta', required=True),
208
'hora_desde': fields.time('Hora desde', required=True),
209
'hora_hasta': fields.time('Hora hasta', required=True),
210
'horas_extras_planificacion_id': fields.many2one('horas.extras.planificacion', 'Referencia', readonly=True),
211
'motivo_id': fields.many2one('horas.extras.planificacion.tipos', 'Motivo', required=True),
212
'excepciones': fields.boolean('excepciones'),
213
'turno_id': fields.function(_calc_turno, method=True, string='Turno calculado', type='meny2one', relation='hr.hour.per.day'),
214
'state': fields.selection([('draft', 'Borrador'), ('confirmed', 'Confirmado'), ('approved', 'Aprobado'),
215
('processing', 'Procesado'), ('exception', 'Excepcion'), ('exceed', 'Excedido'), ('load', 'Cargado'), ('done', 'Listo'),
216
('cancel', 'Cancelado')], 'Estado', readonly=True),
217
'exceed': fields.boolean("Excedido")
218
'state': lambda *a : 'draft',
219
'excepciones': lambda *a: False,
220
'serv_comida': lambda *a: False,
220
'state': lambda *a: 'draft',
221
'excepciones': lambda *a: False,
223
225
def _check_hour(self, cr, uid, ids, conetxt=None):
224
226
convert_datetime = self.convert_datetime
225
227
hel_brw = self.browse(cr, uid, ids)
226
228
for i in hel_brw:
227
fecha_desde = "%s %s"%(i.fecha_desde, i.hora_desde)
228
fecha_hasta = "%s %s"%(i.fecha_hasta, i.hora_hasta)
229
if fecha_desde and fecha_hasta:
230
hora_inicio =convert_datetime(fecha_desde, tipo='object')
231
hora_fin = convert_datetime(fecha_hasta, tipo='object')
232
if hora_fin <= hora_inicio:
229
fecha_desde = "%s %s" % (i.fecha_desde, i.hora_desde)
230
fecha_hasta = "%s %s" % (i.fecha_hasta, i.hora_hasta)
231
if fecha_desde and fecha_hasta:
232
hora_inicio = convert_datetime(fecha_desde, tipo='object')
233
hora_fin = convert_datetime(fecha_hasta, tipo='object')
234
if hora_fin <= hora_inicio:
236
238
def _check_24(self, cr, uid, ids, conetxt=None):
237
239
hel_brw = self.browse(cr, uid, ids)
238
240
convert_datetime = self.convert_datetime
239
241
for i in hel_brw:
240
fecha_desde = "%s %s"%(i.fecha_desde, i.hora_desde)
241
fecha_hasta = "%s %s"%(i.fecha_hasta, i.hora_hasta)
242
if fecha_desde and fecha_hasta:
243
hora_inicio = convert_datetime(fecha_desde, tipo='object')
244
hora_fin = convert_datetime(fecha_hasta, tipo='object')
245
total_horas = abs(hora_fin - hora_inicio)
246
days = total_horas.days * 24
247
hours = total_horas.seconds / 3600.0
242
fecha_desde = "%s %s" % (i.fecha_desde, i.hora_desde)
243
fecha_hasta = "%s %s" % (i.fecha_hasta, i.hora_hasta)
244
if fecha_desde and fecha_hasta:
245
hora_inicio = convert_datetime(fecha_desde, tipo='object')
246
hora_fin = convert_datetime(fecha_hasta, tipo='object')
247
total_horas = abs(hora_fin - hora_inicio)
248
days = total_horas.days * 24
249
hours = total_horas.seconds / 3600.0
253
255
def _check_last_hour(self, cr, uid, ids, context=None):
254
256
hel_brw = self.browse(cr, uid, ids)
255
257
convert_datetime = self.convert_datetime
256
258
now = datetime.datetime.now()
257
259
last = now - timedelta(days=1)
258
260
for i in hel_brw:
259
fecha_desde = "%s %s"%(i.fecha_desde, i.hora_desde)
260
fecha_hasta = "%s %s"%(i.fecha_hasta, i.hora_hasta)
261
if fecha_desde and fecha_hasta:
262
hora_inicio = convert_datetime(fecha_desde, tipo='object')
263
hora_fin = convert_datetime(fecha_hasta, tipo='object')
264
if hora_inicio > last and hora_fin > now:
268
_constraints = [(_check_hour,'La Hora final del sobretiempo no puede ser menor o igual a la hora de inicio', ['hora_hasta']),
269
(_check_24,'Las lineas de sobretiempos no puede ser mayor de 24 horas', ['hora_hasta']),
270
(_check_last_hour,'Las lineas de sobretiempos no puede ser mayor a la fecha actual', ['hora_hasta']),]
261
fecha_desde = "%s %s" % (i.fecha_desde, i.hora_desde)
262
fecha_hasta = "%s %s" % (i.fecha_hasta, i.hora_hasta)
263
if fecha_desde and fecha_hasta:
264
hora_inicio = convert_datetime(fecha_desde, tipo='object')
265
hora_fin = convert_datetime(fecha_hasta, tipo='object')
266
if hora_inicio > last and hora_fin > now:
270
_constraints = [(_check_hour, 'La Hora final del sobretiempo no puede ser menor o igual a la hora de inicio', ['hora_hasta']),
271
(_check_24, 'Las lineas de sobretiempos no puede ser mayor de 24 horas', ['hora_hasta']),
272
(_check_last_hour, 'Las lineas de sobretiempos no puede ser mayor a la fecha actual', ['hora_hasta']), ]
273
274
def onchange_fecha(self, cr, uid, ids, fecha_desde):
276
result = {'value': {'fecha_hasta':fecha_desde}}
277
result = {'value': {'fecha_hasta': fecha_desde}}
279
280
def onchange_hora(self, cr, uid, ids, hora_desde):
282
result = {'value': {'hora_hasta':hora_desde}}
283
result = {'value': {'hora_hasta': hora_desde}}
285
286
def convert_datetime(self, value_date, tipo='object', format_inp=None):
287
format_inp = "%Y-%m-%d %H:%M:%S"
288
value_date = datetime.datetime.strptime(value_date, format_inp)
289
d = {'date':value_date.strftime("%Y-%m-%d"),
290
'time':value_date.strftime("%H:%M:%S"),
291
'object': value_date}
294
def _validate_hour_lines(self,cr, uid, ids, emp_id, fecha_desde, fecha_hasta, hora_desde, hora_hasta):
295
date_desde = "%s %s"%(fecha_desde, hora_desde)
296
date_hasta = "%s %s"%(fecha_hasta, hora_hasta)
288
format_inp = "%Y-%m-%d %H:%M:%S"
289
value_date = datetime.datetime.strptime(value_date, format_inp)
290
d = {'date': value_date.strftime("%Y-%m-%d"),
291
'time': value_date.strftime("%H:%M:%S"),
292
'object': value_date}
295
def _validate_hour_lines(self, cr, uid, ids, emp_id, fecha_desde, fecha_hasta, hora_desde, hora_hasta):
296
date_desde = "%s %s" % (fecha_desde, hora_desde)
297
date_hasta = "%s %s" % (fecha_hasta, hora_hasta)
299
(select id, fecha_desde + hora_desde as date_desde, fecha_hasta + hora_hasta as date_hasta
300
from horas_extras_planificacion_lineas
300
(select id, fecha_desde + hora_desde as date_desde, fecha_hasta + hora_hasta as date_hasta
301
from horas_extras_planificacion_lineas
301
302
where empleado_id = %s) as hxl
302
where (('%s' BETWEEN hxl.date_desde and hxl.date_hasta)
303
or ('%s' BETWEEN hxl.date_desde and hxl.date_hasta))
305
"""%(emp_id,date_desde,date_hasta, ids)
303
where (('%s' BETWEEN hxl.date_desde and hxl.date_hasta)
304
or ('%s' BETWEEN hxl.date_desde and hxl.date_hasta))
306
""" % (emp_id, date_desde, date_hasta, ids)
307
308
validar = cr.fetchall()
308
309
validar = [t for i in validar for t in i]
322
323
nomina_emp = emp_brw.hr_payroll_id.id
323
324
for i in hel_brw:
324
325
if nomina_emp != i.empleado_id.hr_payroll_id.id:
328
def create(self, cr, uid, vals, context=None):
329
emp_id = vals['empleado_id']
330
horas_extras_planificacion_id = vals['horas_extras_planificacion_id']
329
def diff_hours(self, hour_start, hour_end):
330
hd = datetime.datetime.strptime(hour_start, '%H:%M:%S')
331
hh = datetime.datetime.strptime(hour_end, '%H:%M:%S')
332
return (hh - hd).seconds / float(3600)
334
def validate_lines(self, cr, uid, vals, cid=0, context=None):
335
emp_id = vals['empleado_id'] if type(vals['empleado_id']) == int else vals.empleado_id.id
336
horas_extras_planificacion_id = vals['horas_extras_planificacion_id'] if type(vals['horas_extras_planificacion_id']) == int else vals.horas_extras_planificacion_id.id
331
337
fecha_desde = vals['fecha_desde']
332
338
fecha_hasta = vals['fecha_hasta']
333
339
hora_desde = vals['hora_desde']
334
hora_hasta = vals['hora_hasta']
335
lines_ids = self.pool.get('horas.extras.planificacion.lineas').search(cr, uid, [('horas_extras_planificacion_id','=',vals['horas_extras_planificacion_id'])])
340
hora_hasta = vals['hora_hasta']
341
dept_obj = self.pool.get('hr.employee').browse(cr, uid, emp_id, context=context).department_id
342
# Validando que no exceda de las horas diarias permitidas por el departamento
343
week_lines = self.search(cr, uid, ['&', '&', '&', '|', ('state', 'not in', ['draft', 'cancel']), ('horas_extras_planificacion_id', '=', horas_extras_planificacion_id), ('fecha_desde', '=', fecha_desde), ('empleado_id', '=', emp_id), ('id', '!=', cid)], context=context)
344
sum_hours = sum(self.diff_hours(l.hora_desde, l.hora_hasta) for l in self.browse(cr, uid, week_lines, context=context))
345
if sum_hours + self.diff_hours(hora_desde, hora_hasta) > dept_obj.hours_per_day:
347
# Validando que no pase de las horas semanales permitidas por el departamento
348
day = datetime.datetime.strptime(fecha_desde, '%Y-%m-%d')
349
weekstart = day - timedelta(days=day.weekday())
350
weekend = day + timedelta(days=6 - day.weekday())
351
week_lines = self.search(cr, uid, ['&', '&', '&', '&', '|', ('state', 'not in', ['draft', 'cancel']), ('horas_extras_planificacion_id', '=', horas_extras_planificacion_id), ('fecha_desde', '>=', weekstart.strftime('%Y-%m-%d')), ('fecha_desde', '<=', weekend.strftime('%Y-%m-%d')), ('empleado_id', '=', emp_id), ('id', '!=', cid)], context=context)
352
sum_hours = sum(self.diff_hours(l.hora_desde, l.hora_hasta) for l in self.browse(cr, uid, week_lines, context=context))
353
if sum_hours + self.diff_hours(hora_desde, hora_hasta) > dept_obj.hours_per_week:
355
# Validando que no exceda de las horas mensuales para todos los trabajadores del departamento
356
monthstart = day - timedelta(days=day.day - 1)
357
next_month = day.replace(day=28) + timedelta(days=4)
358
monthend = next_month - timedelta(days=next_month.day)
359
while dept_obj: # Iterando por cada departamento, desde el actual hasta sus padres
360
depts_ids = pending_ids = dept_obj.child_ids
361
while pending_ids: # Haciendo la búsqueda hacia sus hijos
362
pending_ids = reduce(lambda x, y: x + y, [c.child_ids for c in pending_ids], [])
363
depts_ids += pending_ids
364
depts_ids = [i.id for i in depts_ids] + [dept_obj.id]
365
week_lines = self.search(cr, uid, ['&', '&', '&', '&', '|', ('state', 'not in', ['draft', 'cancel']), ('horas_extras_planificacion_id', '=', horas_extras_planificacion_id), ('fecha_desde', '>=', monthstart.strftime('%Y-%m-%d')), ('fecha_desde', '<=', monthend.strftime('%Y-%m-%d')), ('empleado_id.department_id', 'in', depts_ids), ('id', '!=', cid)], context=context)
366
sum_hours = sum(self.diff_hours(l.hora_desde, l.hora_hasta) for l in self.browse(cr, uid, week_lines, context=context))
367
if sum_hours + self.diff_hours(hora_desde, hora_hasta) > dept_obj.hours_per_dept:
370
dept_obj = dept_obj.parent_id
373
def create(self, cr, uid, vals, context=None):
374
lines_ids = self.search(cr, uid, [('horas_extras_planificacion_id', '=', vals['horas_extras_planificacion_id'])])
337
376
check_nomina = self._check_nomina(cr, uid, lines_ids, vals['empleado_id'])
338
377
if not check_nomina:
339
raise osv.except_osv(_('Error'), _('Los trabajadores deben pertenecer a una misma nomina por hoja'))
340
return super(horas_extras_planificacion_lineas, self).create(cr, uid, vals, context=None)
378
raise osv.except_osv(_('Error'), _('Los trabajadores deben pertenecer a una misma nomina por hoja'))
379
return super(horas_extras_planificacion_lineas, self).create(cr, uid, vals, context=context)
381
def write(self, cr, uid, ids, vals, context=None):
382
ids = [ids] if type(ids) != list else ids
383
for record in self.browse(cr, uid, ids, context=context):
384
lines_ids = self.search(cr, uid, [('horas_extras_planificacion_id', '=', record.horas_extras_planificacion_id.id)])
386
check_nomina = self._check_nomina(cr, uid, lines_ids, record.empleado_id.id)
388
raise osv.except_osv(_('Error'), _('Los trabajadores deben pertenecer a una misma nomina por hoja'))
389
super(horas_extras_planificacion_lineas, self).write(cr, uid, record.id, vals, context=context)
342
392
def copy(self, cr, uid, id, default=None, context=None):
343
393
raise osv.except_osv(_('Accion no permitida!'), _('No se pueden duplicar las lineas de sobretiempos'))
409
470
raise osv.except_osv(_('Error'), _('No existe periodo creado en Talento Humano para el dia actual'))
410
471
if line.fecha_hasta >= period.date_start:
411
raise osv.except_osv(_('Error'), _('No se puede %s sobretiempo al empleado %s en el periodo actual de la nomina')%(proccess_name, line.empleado_id.name))
472
raise osv.except_osv(_('Error'), _('No se puede %s sobretiempo al empleado %s en el periodo actual de la nomina') % (proccess_name, line.empleado_id.name))
412
473
if datetime.datetime.strptime(period.date_start, '%Y-%m-%d') - timedelta(days=allowed_days) > datetime.datetime.strptime(line.fecha_desde, '%Y-%m-%d'):
413
raise osv.except_osv(_('Error'), _('No se puede %s sobretiempo al empleado %s porque ha excedido el periodo permitido por nomina')%(proccess_name, line.empleado_id.name))
474
raise osv.except_osv(_('Error'), _('No se puede %s sobretiempo al empleado %s fuera de los periodos configurados por nomina') % (proccess_name, line.empleado_id.name))
475
return func(*args, **kargs)
418
def confirmed(self, cr, uid, ids, context = None):
479
def confirmed(self, cr, uid, ids, context=None):
480
validar = self.pool.get('horas.extras.planificacion.lineas').validate_lines
419
481
# Validando que no vaya a saltar el flujo
420
482
if not isinstance(ids, list):
422
for record in self.browse(cr,uid,ids):
423
if record.state != 'draft': return False
424
#Fin de la validacion
425
lines_obj = self.pool.get('horas.extras.planificacion.lineas')
426
lines_id = lines_obj.search(cr, uid, [('horas_extras_planificacion_id','=',ids)])
484
for record in self.browse(cr, uid, ids):
485
if record.state != 'draft':
487
# Fin de la validacion
488
group_id = self.pool.get('ir.model.data').search(cr, uid, [('name', '=', 'group_sisb_horas_extras_autoriza_exceso')])
489
group_id = self.pool.get('ir.model.data').browse(cr, uid, group_id[0]).res_id
490
autoriza = True if group_id in map(int, self.pool.get('res.users').browse(cr, uid, uid).groups_id) else False
492
lines_obj = self.pool.get('horas.extras.planificacion.lineas')
493
lines_id = lines_obj.search(cr, uid, [('horas_extras_planificacion_id', '=', ids)])
427
494
line_brw = lines_obj.browse(cr, uid, lines_id)
429
raise osv.except_osv(_('Error'), _('No hay lineas cargadas'))
496
raise osv.except_osv(_('Error'), _('No hay lineas cargadas'))
430
497
for i in line_brw:
431
498
emp_id = i.empleado_id.id
432
fecha_desde=i.fecha_desde
433
fecha_hasta=i.fecha_hasta
434
hora_desde=i.hora_desde
435
hora_hasta=i.hora_hasta
499
fecha_desde = i.fecha_desde
500
fecha_hasta = i.fecha_hasta
501
hora_desde = i.hora_desde
502
hora_hasta = i.hora_hasta
436
503
lines_obj._validate_hour_lines(cr, uid, i.id, emp_id, fecha_desde, fecha_hasta, hora_desde, hora_hasta)
504
if not validar(cr, uid, i, cid=i.id, context=context):
506
lines_obj.log(cr, uid, i.id, 'Se autorizo sobretiempo con exceso a %s (%s) desde %s %s hasta %s %s' % (i.empleado_id.name, i.empleado_id.cod_number, i.fecha_desde, i.hora_desde, i.fecha_hasta, i.hora_hasta))
508
raise osv.except_osv(_('Error'), _('No se puede confirmar sobretiempo al empleado %s porque ha excedido las horas permitidas') % i.empleado_id.name)
437
509
vals = {'state': 'confirmed'}
438
510
if self.browse(cr, uid, ids[0]).referencia == 'ST-#':
439
511
vals.update({'referencia': self.pool.get('ir.sequence').get(cr, uid, 'sobretiempos_tseq')})
440
512
self.write(cr, uid, ids, vals)
441
self.write_state_lines(cr, uid, ids,'confirmed')
513
self.write_state_lines(cr, uid, ids, 'confirmed')
514
lines_obj.write(cr, uid, lines_id, {'exceed': False}, context=context)
444
def write_state_lines(self, cr ,uid, ids, state, lines=None, field=None):
517
def write_state_lines(self, cr, uid, ids, state, lines=None, field=None):
445
518
horas_extras_lines_obj = self.pool.get('horas.extras.planificacion.lineas')
446
519
brw = self.browse(cr, uid, ids)[0]
448
lines = [obj.id for obj in brw.planificacion_lineas_ids]
521
lines = [obj.id for obj in brw.planificacion_lineas_ids]
451
write_id = horas_extras_lines_obj.write(cr, uid, lines, {field:state})
524
write_id = horas_extras_lines_obj.write(cr, uid, lines, {field: state})
454
def back_draft(self, cr, uid, ids, context = None):
527
def back_draft(self, cr, uid, ids, context=None):
455
528
# Validando que no vaya a saltar el flujo
456
529
if not isinstance(ids, list):
458
for record in self.browse(cr,uid,ids):
459
if record.state not in ['confirmed', 'processing']: return False
460
#Fin de la validacion
531
for record in self.browse(cr, uid, ids):
532
if record.state not in ['confirmed', 'processing']:
534
# Fin de la validacion
461
535
self.write(cr, uid, ids, {'state': 'draft'})
462
self.write_state_lines(cr, uid, ids,'draft')
536
self.write_state_lines(cr, uid, ids, 'draft')
463
537
horas_extras_calc_obj = self.pool.get('horas.extras.planificacion.calculos')
464
calc_ids = horas_extras_calc_obj.search(cr, uid, [('horas_extras_planificacion_id','in',ids)])
538
calc_ids = horas_extras_calc_obj.search(cr, uid, [('horas_extras_planificacion_id', 'in', ids)])
466
horas_extras_calc_obj.unlink(cr, uid, calc_ids)
540
horas_extras_calc_obj.unlink(cr, uid, calc_ids)
469
def cancel(self, cr, uid, ids, context = None):
543
def cancel(self, cr, uid, ids, context=None):
470
544
for i in self.browse(cr, uid, ids):
471
if not i.nota_nomina:
472
raise osv.except_osv(_('Error'), _('Debe colocar una observacion para poder cancelar la hoja de sobretiempo'))
545
if not i.nota_nomina:
546
raise osv.except_osv(_('Error'), _('Debe colocar una observacion para poder cancelar la hoja de sobretiempo'))
473
547
self.write(cr, uid, ids, {'state': 'cancel'})
474
self.write_state_lines(cr, uid, ids,'cancel')
548
self.write_state_lines(cr, uid, ids, 'cancel')
478
def approved(self, cr, uid, ids, context = None):
552
def approved(self, cr, uid, ids, context=None):
479
553
# Validando que no vaya a saltar el flujo
480
554
if not isinstance(ids, list):
482
for record in self.browse(cr,uid,ids):
483
if record.state != 'confirmed': return False
484
#Fin de la validacion
556
for record in self.browse(cr, uid, ids):
557
if record.state != 'confirmed':
559
# Fin de la validacion
485
560
self.write(cr, uid, ids, {'state': 'approved'})
486
self.write_state_lines(cr, uid, ids,'approved')
561
self.write_state_lines(cr, uid, ids, 'approved')
489
564
def chequear_turno(self, cr, uid, ids, date_start, date_end, emp_id):
490
shitf_week_obj = self.pool.get('horas.extras.wizard.concept.variable')
491
shitf_week = shitf_week_obj.get_shitf_week(cr, uid, ids, date_start, date_end, emp_id)
565
shitf_week_obj = self.pool.get('horas.extras.wizard.concept.variable')
566
shitf_week = shitf_week_obj.get_shitf_week(cr, uid, ids, date_start, date_end, emp_id)
494
569
def calcular_cantidad_conceptos(self, cr, uid, ids, date_start, date_end, emp_id, line_id, shift_id=None):
495
570
horas_extras_obj = self.pool.get('horas.extras.wizard.concept.variable')
496
571
value = horas_extras_obj.calcular_sobretiempo(cr, uid, ids, date_start, date_end, emp_id, ids, shift_id=shift_id)
499
def processing(self, cr, uid, ids, context = None):
574
def processing(self, cr, uid, ids, context=None):
500
575
# Validando que no vaya a saltar el flujo
501
576
if not isinstance(ids, list):
503
for record in self.browse(cr,uid,ids):
504
if record.state != 'approved': return False
505
#Fin de la validacion
578
for record in self.browse(cr, uid, ids):
579
if record.state != 'approved':
581
# Fin de la validacion
506
582
self.write(cr, uid, ids, {'state': 'processing'})
508
for i in self.browse(cr, uid, ids, context):
509
for line in i.planificacion_lineas_ids:
510
dict_emp_values[line.empleado_id.id] = {}
512
for i in self.browse(cr, uid, ids, context):
513
for line in i.planificacion_lineas_ids:
514
fecha_desde = "%s %s"%(line.fecha_desde, line.hora_desde)
515
fecha_hasta = "%s %s"%(line.fecha_hasta, line.hora_hasta)
584
for i in self.browse(cr, uid, ids, context):
585
for line in i.planificacion_lineas_ids:
586
dict_emp_values[line.empleado_id.id] = {}
588
for i in self.browse(cr, uid, ids, context):
589
for line in i.planificacion_lineas_ids:
590
fecha_desde = "%s %s" % (line.fecha_desde, line.hora_desde)
591
fecha_hasta = "%s %s" % (line.fecha_hasta, line.hora_hasta)
516
592
if not self.chequear_turno(cr, uid, ids, fecha_desde, fecha_hasta, line.empleado_id.id):
517
self.write_state_lines(cr, uid, ids, 'exception', lines=line.id)
518
self.write_state_lines(cr, uid, ids, True, lines=line.id, field='excepciones')
593
self.write_state_lines(cr, uid, ids, 'exception', lines=line.id)
594
self.write_state_lines(cr, uid, ids, True, lines=line.id, field='excepciones')
520
self.write_state_lines(cr, uid, ids,'processing', lines=line.id)
596
self.write_state_lines(cr, uid, ids, 'processing', lines=line.id)
521
597
valor = self.calcular_cantidad_conceptos(cr, uid, ids, fecha_desde, fecha_hasta, line.empleado_id.id, line.id, None)
522
for concepto in valor:
523
if not concepto in dict_emp_values[line.empleado_id.id]:
524
dict_emp_values[line.empleado_id.id][concepto] = valor[concepto]
598
for concepto in valor:
599
if concepto not in dict_emp_values[line.empleado_id.id]:
600
dict_emp_values[line.empleado_id.id][concepto] = valor[concepto]
526
602
dict_emp_values[line.empleado_id.id][concepto] += valor[concepto]
528
604
horas_extras_calc_obj = self.pool.get('horas.extras.planificacion.calculos')
530
606
for emp in dict_emp_values:
531
vals = {'trabajador_id':emp, 'horas_extras_planificacion_id':ids[0]}
607
vals = {'trabajador_id': emp, 'horas_extras_planificacion_id': ids[0]}
532
608
for c in dict_emp_values[emp]:
533
vals['concept_id'] = c
609
vals['concept_id'] = c
534
610
vals['value'] = dict_emp_values[emp][c]
535
horas_extras_calc_obj.create(cr, uid, vals)
611
horas_extras_calc_obj.create(cr, uid, vals)
538
614
def unlink(self, cr, uid, ids, context=None):
539
615
if not isinstance(ids, list):
541
617
brw = self.browse(cr, uid, ids)
542
618
if brw[0].planificacion_lineas_ids:
543
raise osv.except_osv(_('Accion no permitida!'), _('Solo se pueden eliminar hojas vacias'))
619
raise osv.except_osv(_('Accion no permitida!'), _('Solo se pueden eliminar hojas vacias'))
544
620
if brw[0].referencia != 'ST-#':
545
raise osv.except_osv(_('Accion no permitida!'), _('No se pueden borrar hojas con numero de referencia asignado'))
621
raise osv.except_osv(_('Accion no permitida!'), _('No se pueden borrar hojas con numero de referencia asignado'))
546
622
return super(horas_extras_planificacion, self).unlink(cr, uid, ids, context)
548
624
def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False):
551
load_nom = self._get_trabajadores_nomina(cr, uid, 'group_sisb_horas_extras_th', param_nomina=False)
552
hr_user = self._get_trabajadores_nomina(cr, uid, 'group_hr_user', param_nomina=True)
553
if (uid <> 1 and not load_nom and not hr_user):
627
load_nom = self._get_trabajadores_nomina(cr, uid, 'group_sisb_horas_extras_th', param_nomina=False)
628
hr_user = self._get_trabajadores_nomina(cr, uid, 'group_hr_user', param_nomina=True)
629
if (uid != 1 and not load_nom and not hr_user):
554
630
lista = self.validar_departamentos(cr, uid)
555
631
dic = 'department_id', 'in', lista
557
633
return super(horas_extras_planificacion, self).search(cr, uid, args, offset, limit, order, context, count)
559
635
def write(self, cr, uid, ids, values, context=None):
560
636
if context is None: