diff --git a/estudio_socio_economico/templatetags/custom_filters.py b/estudio_socio_economico/templatetags/custom_filters.py index 5de4e1c229636eb86d0a065b836dd8d81a59db42..382ea64b9f7267b38b81eedbffc558afb8305901 100644 --- a/estudio_socio_economico/templatetags/custom_filters.py +++ b/estudio_socio_economico/templatetags/custom_filters.py @@ -5,8 +5,6 @@ from django.db import models from django import forms from django.utils.timesince import timesince from django.utils import timezone -from datetime import datetime -from datetime import date register = template.Library() logger = logging.getLogger(__name__) diff --git a/modalidades/models.py b/modalidades/models.py index e1b6a46ec727cbce0e965e253178db77c2ba37c0..39575b6de8c488118e6206326fc9c3223272ee46 100644 --- a/modalidades/models.py +++ b/modalidades/models.py @@ -3,9 +3,8 @@ import os from uuid import uuid4 from django.conf import settings from django.utils.translation import gettext_lazy as _ -from datetime import datetime -from datetime import date from django.utils.timezone import now +from django.utils import timezone from django.core.exceptions import ValidationError from django.db.models.signals import post_save from django.dispatch import receiver @@ -32,9 +31,9 @@ def modalidadMediaPath(instance, filename): def ciclo_actual_genNombre(): - now = datetime.now() - mes = (now.month) % 12 - año = now.year + ((now.month) // 12) + ahora = now() + mes = ahora.month + año = ahora.year # Determinar el ciclo actual if mes >= 8: ciclo = "Agosto - Diciembre" @@ -43,16 +42,16 @@ def ciclo_actual_genNombre(): return f"{ciclo} {año}" def ciclo_actual(): - # Obtener el último ciclo disponible - ultimoCiclo = Ciclo.objects.order_by('-id').first() - nombreCiclo = ciclo_actual_genNombre() - - # Verificar si el último ciclo está disponible - if ultimoCiclo and ultimoCiclo.nombre == nombreCiclo: - return ultimoCiclo - # Si no hay ciclos disponibles o el último ciclo no está disponible, crear uno nuevo - nuevo_ciclo = Ciclo.objects.create(nombre=nombreCiclo) - return nuevo_ciclo + # Obtener el último ciclo disponible + convocatoria = Convocatoria.get_object() + + #verificamos si el ciclo actual todavia esta bigente + if now() < convocatoria.fecha_nuevo_ciclo: + return Ciclo.objects.order_by('-id').first() + else: + nombreCiclo = ciclo_actual_genNombre() + nuevo_ciclo = Ciclo.objects.create(nombre=nombreCiclo) + return nuevo_ciclo def getCiclo(index=0): if index == 0: @@ -80,6 +79,12 @@ class Ciclo(models.Model): def __str__(self): return f'{self.nombre}' +#reciber para aztualizar otros modelos cuando inicia un nuevo ciclo +@receiver(post_save, sender=Ciclo) +def nuevo_ciclo(sender, instance, created, **kwargs): + if created: + pass + class SingletonModel(models.Model): @@ -117,7 +122,7 @@ class Convocatoria(SingletonModel): ultimo_ciclo_publicado = models.ForeignKey(Ciclo, on_delete=models.SET_NULL, verbose_name=_("Ultimo ciclo publicado"), null=True, blank=True) def __str__(self): - return f'Convocatoria {self.fecha_inicio} // {self.fecha_cierre}' #date.today() + return f'Convocatoria {self.fecha_inicio} // {self.fecha_cierre}' #now().date() @property def mostrar_precio(self): @@ -125,23 +130,23 @@ class Convocatoria(SingletonModel): @property def fecha_convocatoria(self): - if (date.today() >= self.fecha_inicio) and (date.today() <= self.fecha_cierre): + if (now().date() >= self.fecha_inicio) and (now().date() <= self.fecha_cierre): return True else: return False @property def mensaje_estado_convocatoria(self): - if date.today() == self.fecha_cierre: + if now().date() == self.fecha_cierre: return f'Último día de convocatoria.' - elif date.today() < self.fecha_inicio: - dias_restantes = (self.fecha_inicio - date.today()).days + elif now().date() < self.fecha_inicio: + dias_restantes = (self.fecha_inicio - now().date()).days if dias_restantes < 2: return f'Falta {dias_restantes} día para que inicie la convocatoria.' else: return f'Faltan {dias_restantes} días para que inicie la convocatoria.' - elif date.today() <= self.fecha_cierre: - dias_restantes = (self.fecha_cierre - date.today()).days+1 + elif now().date() <= self.fecha_cierre: + dias_restantes = (self.fecha_cierre - now().date()).days+1 if dias_restantes < 2: return f'Queda {dias_restantes} día para que la convocatoria termine.' else: diff --git a/solicitudes/templates/estadisticas/ebase.html b/solicitudes/templates/estadisticas/ebase.html index c64ad91901f1c55838eb91213c8b5ad4a912a054..ed1bf001d71183d1c6a404b519a6be1f62d84f5d 100644 --- a/solicitudes/templates/estadisticas/ebase.html +++ b/solicitudes/templates/estadisticas/ebase.html @@ -106,7 +106,7 @@ no es necesario heredar de ella si se busca otra cosa o se quiere contruir la pr {% endfor %} - {% elif conjuntoEst.tipo == 'lista' %} + {% elif conjuntoEst.tipo == 'list' %}
{{ conjuntoEst.dataLabel }} diff --git a/solicitudes/viewsAdmin.py b/solicitudes/viewsAdmin.py index 297cdbfacff395a15356ea80a44458dc0c834927..443a4e01b02cc5f21628d3bcc650670232208e7b 100644 --- a/solicitudes/viewsAdmin.py +++ b/solicitudes/viewsAdmin.py @@ -15,7 +15,7 @@ from django.db.models import Count from zipfile import ZipFile import uuid from openpyxl import Workbook -from datetime import date +from django.utils.timezone import now from collections import Counter from usuarios.decorators import user_passes_test, user_passes_test_httpresponse, usuarioEsAdmin @@ -339,22 +339,61 @@ def estadisticaSolicitudes(request): }) #llenando el conjunto estadistico de el Total de invercion - montos = MontoModalidad.objects.filter(ciclo = ultimoCiclo).values('modalidad__nombre','monto') - montos = {monto['modalidad__nombre']: monto['monto'] for monto in montos} - valoresFrecuencias = queryset.filter(estado=Solicitud.ESTADO_CHOICES[3][0]).values('modalidad__nombre').annotate(frecuencia=Count('modalidad__nombre')) + #print(estadistica_filtro == TODOS_STR) + if estadistica_filtro == TODOS_STR: + montos = MontoModalidad.objects.filter().values('modalidad__nombre','ciclo','monto') + else: + montos = MontoModalidad.objects.filter(ciclo = estadistica_filtro).values('modalidad__nombre','ciclo','monto') + #[print(monto) for monto in montos] + #nerar un diccionario anidado de 2 dimenciones para usar las claves de ciclo y modalidad + print(montos) + dictMontos = {} + for monto in montos: + print(monto) + ciclo = monto['ciclo'] + modalidad_nombre = monto['modalidad__nombre'] + monto_valor = monto['monto'] + # Verificar si el ciclo ya existe en el diccionario anidado + if ciclo not in dictMontos: + dictMontos[ciclo] = {} # Inicializar un nuevo diccionario para este ciclo + # Agregar la modalidad y el monto al diccionario interno correspondiente al ciclo + dictMontos[ciclo][modalidad_nombre] = monto_valor + valoresFrecuencias = queryset.filter(estado=Solicitud.ESTADO_CHOICES[3][0]).values('modalidad__nombre','ciclo').annotate(frecuencia=Count('modalidad__nombre')) + #[print(frec) for frec in valoresFrecuencias] + print(dictMontos) valoresFrecuencias = sorted(valoresFrecuencias, key=lambda x: x['frecuencia'], reverse=True) - labels = [item['modalidad__nombre']+':' for item in valoresFrecuencias ] - total = 0 - totales = [] + labels = {} + labels['total'] = 'Total:' + for item in valoresFrecuencias: + nuevaLabel = f"{item['modalidad__nombre']}:" + if item['modalidad__nombre'] not in labels: + labels[item['modalidad__nombre']] = nuevaLabel + totales = {} + totales['total'] = 0 for item in valoresFrecuencias: - totales.append( f"${(item['frecuencia'] * montos[item['modalidad__nombre']]):,.2f}") - total += item['frecuencia'] * montos[item['modalidad__nombre']] - labels.insert(0, 'Total:') - totales.insert(0, f'${total:,.2f}') + cicloItem = item['ciclo'] + nombreItem = item['modalidad__nombre'] + valMonto = dictMontos.get(cicloItem, None) + if valMonto: + valMonto = valMonto.get(nombreItem, None) + if valMonto: + if nombreItem in totales: + totales[nombreItem] += item['frecuencia'] * valMonto # f"${(item['frecuencia'] * valMonto):,.2f}" + else: + totales[nombreItem] = item['frecuencia'] * valMonto + totales['total'] += item['frecuencia'] * valMonto + #else: + # totales[nombreItem] = f"NA" + for clave, valor in totales.items(): + if valor == 0: + totales[clave] = f"NA" + else: + totales[clave] = f"${(valor):,.2f}" + zipped_values = ((labels[key], totales[key]) for key in labels.keys() & totales.keys()) conjuntosEstadisticos.append({ - 'tipo': 'lista', + 'tipo': 'list', 'dataLabel': f'Dinero invertido: {getChoicesEtiqueta(choices=cicloChoices,valor=estadistica_filtro)}', - 'data': zip(labels, totales) + 'data': zipped_values }) tituloEst = componerTitulo(getChoicesEtiqueta(choices=cicloChoices,valor=estadistica_filtro), campo_estadistica_original) @@ -792,7 +831,7 @@ def generarConcentradoXlsx(ciclo): #Edad try: - hoy = date.today() + hoy = now().date() fecha_nacimiento = solicitud.solicitante.fecha_nacimiento edad = round((hoy - fecha_nacimiento).days / 365.25) values.append(edad) diff --git a/usuarios/models.py b/usuarios/models.py index 8b0ff256422c7895511ab9b946ffe714db2e929e..a210971ac47c9c0c8c375cf1c6e7ee7719ab2900 100644 --- a/usuarios/models.py +++ b/usuarios/models.py @@ -5,7 +5,6 @@ from django.core.validators import RegexValidator from django.core.validators import MinLengthValidator, MaxLengthValidator from django.core.exceptions import ValidationError from django.db.models import Q -from datetime import datetime from django.core.validators import MaxValueValidator, MinValueValidator from modalidades.models import Ciclo