def total_horas_uteis(self, data_ini, data_fim): soma_dias_de_trabalho = 0 d = data_ini while d < data_fim: # é final de semana? is_final_de_semana = d.weekday() >= 5 # é feriado? is_feriado = False diaFeriado = Feriado.get_dia_de_feriado(d) # verifica se o feriado é facultativo, ou seja, com desconto de banco de horas. if diaFeriado is not None and not diaFeriado.tipo.subtrai_banco_hrs: is_feriado = True # soma os dias de trabalho if not is_final_de_semana and not is_feriado: soma_dias_de_trabalho += 1 d += timedelta(days=1) # as horas totais do período são as horas do total de dias do mes menos os finais de semana, ferias e dispensas total_horas_periodo = (soma_dias_de_trabalho * self.membro.carga_horaria * 60 * 60) return total_horas_periodo
def total_analitico_horas(self, ano, mes): controles = Controle.objects.filter(membro=self.membro_id).order_by('entrada') primeiroDiaFiltro = None if ano and ano.isdigit() and int(ano) > 0: controles = controles.filter(entrada__year=ano) primeiroControle = controles[:1].get() if mes and mes.isdigit() and int(mes) > 0: controles = controles.filter(entrada__month=mes) primeiroDiaFiltro = datetime(primeiroControle.entrada.year, int(mes), 01) else: primeiroDiaFiltro = datetime(primeiroControle.entrada.year, primeiroControle.entrada.month, 01) meses = [] if controles.exists(): ultimoControle = controles.order_by('-entrada')[:1].get() ultimoDiaFiltro = datetime(ultimoControle.entrada.year, ultimoControle.entrada.month, calendar.monthrange(ultimoControle.entrada.year, ultimoControle.entrada.month)[1], 23, 59, 59) controles = controles.order_by('-entrada') mes_anterior = date(1979, 01, 01) if controles.count() > 0: for dt in rrule(DAILY, dtstart=primeiroDiaFiltro, until=ultimoDiaFiltro): if dt.month != mes_anterior.month or dt.year != mes_anterior.year: dias = [] meses.insert(0, ({'mes': dt.month, 'ano': dt.year, 'dias': dias, 'total': 0})) mes_anterior = dt itemControle = ItemControle() itemControle.dia = date(dt.year, dt.month, dt.day) itemControle.controles = controles.filter(entrada__year=dt.year, entrada__month=dt.month, entrada__day=dt.day) # dias.append(itemControle) dias.insert(0, itemControle) total_banco_horas = 0 ferias = ControleFerias.objects.filter(ferias__membro=self.membro_id) dispensas = DispensaLegal.objects.filter(membro=self.membro_id) for m in meses: total_segundos_trabalhos_mes = 0 # total de horas de dispensas total_horas_dispensa = 0 # total de horas de ferias total_horas_ferias = 0 # ferias_ini < mes_ini < ferias_fim OR mes_ini < ferias_ini < mes_fim mes_corrente_ini = date(m['ano'], m['mes'], 01) mes_corrente_fim = mes_corrente_ini + timedelta(calendar.monthrange(m['ano'], m['mes'], )[1]) for d in m['dias']: # total de horas trabalhadas total_segundos_trabalhos_mes = total_segundos_trabalhos_mes + sum([c.segundos for c in d.controles]) # verifica se tem algum período de férias com dias úteis tirados de fato # não deve entrar na conta se forem período de férias com venda de dias, ou somente marcação de # vencimento de férias for data_ferias in ferias: d.is_ferias = data_ferias.dia_ferias(d.dia) if d.is_ferias: d.obs = u'%s Férias' % d.obs break # é final de semana? d.is_final_de_semana = d.dia.weekday() >= 5 if d.is_final_de_semana: if d.dia.weekday() == 5: d.obs = u'%s Sábado' % d.obs elif d.dia.weekday() == 6: d.obs = u'%s Domingo' % d.obs # é feriado? diaFeriado = Feriado.get_dia_de_feriado(d.dia) if diaFeriado is not None: d.obs = u'%s %s' % (d.obs, diaFeriado.tipo.nome) # este feriado é facultativo ou não? if not diaFeriado.tipo.subtrai_banco_hrs: d.is_feriado = True # é dispensa? d.is_dispensa = False horas_dispensa = 0 for dispensa in dispensas: dia_dispensa = dispensa.dia_dispensa(d.dia) if dia_dispensa['is_dispensa']: d.is_dispensa = dia_dispensa['is_dispensa'] horas_dispensa = dia_dispensa['horas'] d.obs = u'%s Dispensa %s' % (d.obs, dispensa.tipo.nome) break # soma os dias de trabalho if not d.is_final_de_semana and not d.is_feriado: # conta as horas de dispensas if d.is_dispensa: total_horas_dispensa += horas_dispensa * 3600 # conta as horas de ferias if d.is_ferias: # soma horas do dia (8h periodo completo ou 4h meio periodo) total_horas_ferias += self.membro.carga_horaria * 60 * 60 m.update({'total': total_segundos_trabalhos_mes}) if self.membro.data_inicio > mes_corrente_ini: # Leva em conta a data de admissão do membro para a contagem das horas úteis do período total_horas_periodo = self.total_horas_uteis(self.membro.data_inicio, mes_corrente_fim) else: # as horas totais do período são as horas do total de dias do mes menos os finais de semana, # ferias e dispensas total_horas_periodo = self.total_horas_uteis(mes_corrente_ini, mes_corrente_fim) m.update({'total_horas_periodo': total_horas_periodo}) total_horas_restante = total_horas_periodo - total_horas_dispensa - total_horas_ferias - \ total_segundos_trabalhos_mes m.update({'total_horas_restante': total_horas_restante}) m.update({'total_horas_dispensa': total_horas_dispensa}) m.update({'total_horas_ferias': total_horas_ferias}) # soma horas extras somente dos meses que não forem o mês em andamento total_banco_horas = 0 if datetime.now().year != c.entrada.year or datetime.now().month != c.entrada.month: total_banco_horas = -total_horas_restante m.update({'total_banco_horas': total_banco_horas}) return meses