Esempio n. 1
0
def evolucion_registros_x_estado(start_date, ends_date):
    estados = Estado.objects.values_list('codigo', flat=True)
    qs = RegistroAsistencia.objects.filter(
            asistencia__fecha__gte=start_date,
            asistencia__fecha__lte=ends_date).values_list(
            'asistencia__fecha', 'estado__codigo').annotate(cant=Count('estado_id'))

    processed = defaultdict(dict)
    esto = []
    for it in qs:
        processed[it[0]][it[1]]=it[2]
        if it[1] not in esto:
            esto.append(it[1])

    report = []
    for est in esto:
        series = {}
        series["key"] = est
        series["values"] = list()
        for day in daterange(start_date, ends_date):
            val = processed.get(day, {}).get(est, 0)
            series["values"].append({'x': day.isoformat(), 'y': val})

        report.append(series)

    return report
Esempio n. 2
0
def get_datos_porcentuales(start, end):
    estados = Estado.objects.values_list('codigo', flat=True)
    qs = RegistroAsistencia.objects.filter(
        asistencia__fecha__gte=start,
        asistencia__fecha__lte=end
    ).values_list('asistencia__fecha', 'estado__codigo').annotate(cant=Count('pk')).order_by('asistencia__fecha')

    totales = dict(RegistroAsistencia.objects.filter(
        asistencia__fecha__gte=start,
        asistencia__fecha__lte=end
    ).values_list('asistencia__fecha').annotate(cant=Count('pk')).order_by('asistencia__fecha'))

    totales_rango = dict(RegistroAsistencia.objects.filter(
        asistencia__fecha__gte=start,
        asistencia__fecha__lte=end
    ).values_list('estado__codigo').annotate(cant=Count('pk')))
    total_rango = sum([v for k,v in totales_rango.items()])

    processed = defaultdict(dict)

    for it in qs:
        processed[it[0]][it[1]]=it[2]

    report = list()
    header = ["Fecha", ]
    header.extend(estados)
    report.append(header)

    totales_row = ["Totales", False,]

    for day in daterange(start, end):
        aux = list()
        aux.append(day)
        aux.append(day.isoweekday() in [6,7])
        data = processed.get(day, {})
        total = totales.get(day, 0)
        for est in estados:
            if total == 0:
                aux.append(0)
            else:
                aux.append(processed.get(day, {}).get(est, 0) * 100 / total)
        report.append(aux)

    for est in estados:
        if total_rango == 0:
            totales_row.append(0)
        else:
            totales_row.append(totales_rango.get(est, 0) / total_rango)
    report.append(totales_row)

    for k,v in totales_rango.items():
        totales_rango[k] = v / total_rango * 100 if total_rango != 0 else 0
    return report, totales_rango
Esempio n. 3
0
def evolucion_registros_asistencia(start_date, ends_date):
    """
    Devuelve los datos para el gráfico de codigo de barras con los presentes y ausentes
    """
    qs = RegistroAsistencia.objects.select_related('estado', 'persona').filter(
            asistencia__fecha__gte=start_date,
            asistencia__fecha__lte=ends_date).values_list(
            'asistencia__fecha', 'estado__no_ocioso').annotate(cant=Count('estado_id'))

    processed = defaultdict(dict)

    for it in qs:
        processed[it[0]][it[1]]=it[2]

    report = list()
    data_table = list()
    for day in daterange(start_date, ends_date):
        aux = list()
        aux.append(day)
        aux.append(processed.get(day, {}).get(True, 0))
        aux.append(processed.get(day, {}).get(False, 0))
        data_table.append(aux)

    for est in ["Presentes", "Ausentes"]:
        series = dict()
        series["key"] = est
        series["values"] = list()
        for day in daterange(start_date, ends_date):
            if est == "Presentes":
                val = processed.get(day, {}).get(True, 0)
            else:
                val = processed.get(day, {}).get(False, 0)
            # desconozco porque debe sumar un día para que sea correcto el gráfico
            series["values"].append({'x': (day+ timedelta(days=1)).isoformat(), 'y': val})

        report.append(series)

    return report, data_table
Esempio n. 4
0
    def fill_resumen_dias_trabajados(self, context):
        """
        Muestra un reporte de con el detalle de asistencia cada dia (dentro del rango de fechas)
        por persona para un proyecto seleccionado.
        """
        worksheet_s_name = "Resumen RRHH"
        worksheet_s = self.workbook.add_worksheet(worksheet_s_name)
        fechas = context["filter"].form.cleaned_data["fecha"]
        start_date = fechas.start
        end_date = fechas.stop
        rango_de_dias = [x for x in daterange(start_date, end_date)]

        # cabecera con logo y título "Resumen de días trabajados" - RRHH -
        # subcabecera: fecha de emisión y proyecto seleccionado
        # referencia de estados y códigos
        # encabezado de tabla
        """
        Resumen personal    | Días              | * cada estado con su acumulado
        personas            | Cada dia          | Acumulado por persona por estado
        ...
        * Total cada estado | Acumulado diario  | Totales

        """

        # formats
        header = self.workbook.add_format({
            'color': 'black',
            'align': 'center',
            'valign': 'vcenter',
            'border': 1,
            'bold': True,
            'font_size': 12,
        })
        header_date = self.workbook.add_format({
            'color': 'black',
            'align': 'center',
            'valign': 'vcenter',
            'border': 1,
            'bold': True,
            'font_size': 12,
            'num_format': 'dd/mm/yy'
        })

        normal = self.workbook.add_format({
            'color': 'black',
            'align': 'center',
            'valign': 'vcenter',
            'border': 1,
            'font_size': 9,
        })
        normal_left = self.workbook.add_format({
            'color': 'black',
            'align': 'left',
            'valign': 'vcenter',
            'border': 1,
            'font_size': 9,
        })
        normal_color = self.workbook.add_format({
            'bg_color': '#b6eda8',
            'color': 'black',
            'align': 'center',
            'valign': 'vcenter',
            'border': 1,
            'font_size': 9,
        })

        xs_total_color = self.workbook.add_format({
            'bg_color': '#c6a5a5',
            'color': 'black',
            'align': 'center',
            'valign': 'vcenter',
            'border': 1,
            'font_size': 9,
        })
        xs_total_color_left = self.workbook.add_format({
            'bg_color': '#c6a5a5',
            'color': 'black',
            'align': 'left',
            'valign': 'vcenter',
            'border': 1,
            'font_size': 9,
        })
        cant_dias = len(rango_de_dias)
        # título
        worksheet_s.merge_range(0, 0, 0, 3, "")
        worksheet_s.insert_image(0, 0, os.path.join(settings.STATIC_ROOT, "frontend/img/footer-zille.png"),
                                 {'x_offset': 15, 'y_offset': 5})
        worksheet_s.merge_range(0, 4, 0, cant_dias + 3, "RESUMEN DE DÍAS TRABAJADOS\n-RRHH-", self.style_dict["title"])

        # subtítulo
        worksheet_s.merge_range(1, 0, 1, 1, "Fecha de Emisión:", header)
        worksheet_s.merge_range(1, 2, 1, 3, datetime.now(), header_date)

        worksheet_s.merge_range(1, 4, 1, 14, "Operación (Proyecto / Servicio):", header)
        proyecto_name = str(context["filter"].form.cleaned_data["proyecto"]) if context["filter"].form.cleaned_data["proyecto"] else "Todos"
        worksheet_s.merge_range(1, 15, 1, 3 + cant_dias, proyecto_name, header)

        referencias = dict(Estado.objects.values_list("codigo", "situacion"))

        # mejorar presentación de referencias..
        # worksheet_s.write(2, 0, " ".join(["REFERENCIAS: ", ] + referencias))

        # encabezados tabla
        worksheet_s.merge_range(3 , 0, 3, 3, "RESUMEN PERSONAL DE ZILLE SRL", normal_color)
        worksheet_s.merge_range(3, 4, 3, cant_dias + 3, "MES", normal_color)

        # encabezados
        worksheet_s.write_row(4, 0, ["ITEM", "APELLIDO Y NOMBRE", "CUIL", "CATEGORÍA"], normal_color)
        worksheet_s.write_row(4, 4, [x.strftime("%d/%m") for x in rango_de_dias], normal_color)

        # encabecados estados
        i = 4
        for k, v in referencias.items():
            worksheet_s.merge_range(3, cant_dias + i, 4, cant_dias + i, "{}\n{}".format(k, v), xs_total_color)
            i += 1

        # buscamos las personas, las ordenamos por apellido
        personas = context["filter"].qs.values_list(
            'persona_id', 'persona__apellido', 'persona__nombre', 'persona__cuil', 'persona__cct__nombre').order_by(
            "persona__apellido", "persona__nombre").distinct()

        row_init_data = item = 5  # primer fila con datos

        totales_diarios = {}  # dict con una lista de asistencias por día. Key: dia, value, list de estados
        totales_por_estados = {}

        for persona in personas:
            # datos de empleado
            worksheet_s.write(item, 0, item-4, normal)  # item
            worksheet_s.write(item, 1, "{}, {}".format(persona[1], persona[2]), normal_left)  # nombre
            worksheet_s.write(item, 2, persona[3], normal)  # cuit
            worksheet_s.write(item, 3, persona[4], normal)  # categoria

            col = 4  # columna de datos de asistencia
            avance = 0  # avance de la columna
            asistencia = dict(context["filter"].qs.filter(
                persona_id=persona[0]).values_list(
                "asistencia__fecha", 'estado__codigo').order_by("asistencia__fecha"))
            totales = Counter(asistencia.values())

            # guardos los totales de esta persona, para calcular los totales por estado
            for k, total in totales.items():
                try:
                    totales_por_estados[k].append(total)
                except KeyError:
                    totales_por_estados[k] = [total, ]

            # recorremos los días
            for dia in rango_de_dias:
                # armo dict para contabilizar asistencias por día
                if dia not in totales_diarios:
                    totales_diarios[dia] = []
                totales_diarios[dia].append(asistencia.get(dia, ""))

                worksheet_s.write(item, col + avance, asistencia.get(dia, ""), normal)
                avance += 1

            # poner campos para estados y sus sumatorias
            for estado in referencias.keys():
                worksheet_s.write_formula(item, col + avance,
                                          '=COUNTIF({0}{1}:{2}{1},"{3}")'.format(
                                              self.get_c(col + 1),
                                              item + 1,
                                              self.get_c(col + avance),
                                              estado),
                                          cell_format=xs_total_color,
                                          value=totales.get(estado, 0))
                avance += 1
            item += 1

        row_fin_data = item - 1
        # lista de estados y totales diarios
        for estado in referencias.keys():
            col = 4  # columna de datos de asistencia
            avance = 0  # avance de la columna
            worksheet_s.merge_range(item, 0, item, 3, "TOTAL {}".format(referencias.get(estado)), xs_total_color_left)
            # recorremos los días
            for dia in rango_de_dias:
                totales_dia = Counter(totales_diarios.get(dia, []))
                worksheet_s.write_formula(item, col + avance,
                                          '=COUNTIF({0}{1}:{0}{2},"{3}")'.format(
                                              self.get_c(col + avance + 1),
                                              row_init_data + 1,
                                              row_fin_data + 1,
                                              estado),
                                          cell_format=xs_total_color,
                                          value=totales_dia.get(estado, 0))
                avance += 1
            if item == row_fin_data + 1:  # si es el primero de los totales, agrego los totales por estado

                for estado2 in referencias.keys():
                    total = sum(totales_por_estados.get(estado2, []))
                    # primero hago el merge de la celda
                    worksheet_s.merge_range(item, col + avance, item + 3, col + avance, "")
                    # luego aplico la formula
                    worksheet_s.write_formula(
                        item, col + avance,
                        '=SUM({0}{1}:{0}{2})'.format(self.get_c(col + avance + 1), row_init_data + 1, row_fin_data + 1),
                        cell_format=normal_color, value=total)

                    avance += 1

            item += 1

        # setear altos y  anchos
        worksheet_s.set_row(0, 45)
        worksheet_s.set_row(1, 30)
        worksheet_s.set_column(0, 0, 5)
        worksheet_s.set_column(1, 1, 35)
        worksheet_s.set_column(2, 2, 15)
        worksheet_s.set_column(3, 3, 20)
        worksheet_s.set_column(4, 4 + cant_dias, 5)
        worksheet_s.freeze_panes(5, 2)
        return self.prepare_response()