diff --git a/INSIGHTSAPI/coexistence_committee/migrations/0003_auto_20241007_1158.py b/INSIGHTSAPI/coexistence_committee/migrations/0003_auto_20241007_1158.py index 4a02cca..2bcdb3e 100644 --- a/INSIGHTSAPI/coexistence_committee/migrations/0003_auto_20241007_1158.py +++ b/INSIGHTSAPI/coexistence_committee/migrations/0003_auto_20241007_1158.py @@ -29,6 +29,7 @@ def create_default_groups(apps, schema_editor): ).first() if hr_manager and sst_manager: hr_manager.groups.add(sst) + sst_manager.groups.add(sst) else: if not "test" in sys.argv: print("User not found for HR Manager or SST Manager") diff --git a/INSIGHTSAPI/coexistence_committee/views.py b/INSIGHTSAPI/coexistence_committee/views.py index bebe626..529f2d0 100644 --- a/INSIGHTSAPI/coexistence_committee/views.py +++ b/INSIGHTSAPI/coexistence_committee/views.py @@ -52,6 +52,8 @@ def create(self, request, *args, **kwargs): sst_mails = [ user.email for user in User.objects.filter(groups__name="SST") if user.email ] + if not sst_mails: + return Response({"error": "No hay usuarios en el grupo SST"}, status=500) send_mail( "New complaint", diff --git a/INSIGHTSAPI/operational_risk/management/commands/upload_events.py b/INSIGHTSAPI/operational_risk/management/commands/upload_events.py new file mode 100644 index 0000000..2364a71 --- /dev/null +++ b/INSIGHTSAPI/operational_risk/management/commands/upload_events.py @@ -0,0 +1,97 @@ +import logging +import os + +import pandas as pd +from django.core.management.base import BaseCommand +from ftfy import fix_text + +from operational_risk.models import ( + EventClass, + Events, + Level, + LostType, + Process, + ProductLine, +) + +logger = logging.getLogger("requests") + + +class Command(BaseCommand): + """Class to update the events from an Excel file""" + + help = "Update the events from an Excel file" + + def handle(self, *args, **options): + """Method to handle the command""" + + # Load Excel file (update path as needed) + file_path = os.path.join(os.getcwd(), "Eventos 2023.xlsx") + + # Read each sheet into a pandas DataFrame + df = pd.read_excel(file_path, sheet_name=None) + + # Iterate over each row + for event_row in df["Hoja1"].to_dict(orient="records"): + # Fix text only for string values, skip others + event_row = { + k: fix_text(v) if isinstance(v, str) else v + for k, v in event_row.items() + } + + event_class = EventClass.objects.get(name=event_row["Clase de Evento"]) + level = None + nivel = event_row["Nivel"].upper() + if nivel == "BAJO": + level, _ = Level.objects.get_or_create(name="BAJO") + elif nivel == "MEDIO": + level, _ = Level.objects.get_or_create(name="MEDIO") + elif nivel == "ALTO": + level, _ = Level.objects.get_or_create(name="ALTO") + + process = Process.objects.get(name=event_row["Proceso"]) + product = ProductLine.objects.get(name=event_row["Producto"]) + + dates = [ + "Fecha de Inicio", + "Fecha de Fin", + "Fecha de Descubrimiento", + "Fecha de Atención", + "Fecha de Cierre", + ] + for date in dates: + if event_row[date] == "0000-00-00": + event_row[date] = None + else: + event_row[date] = pd.to_datetime(event_row[date], dayfirst=True) + + event_row["critico"] = bool(event_row["Clasificación"] == "CRITICO") + event_row["estado"] = event_row["Estado Actual"] != "CERRADO" + + Events.objects.create( + start_date=event_row["Fecha de Inicio"], + end_date=event_row["Fecha de Fin"], + discovery_date=event_row["Fecha de Descubrimiento"], + accounting_date=event_row["Fecha de Atención"], + currency=event_row["Divisa"], + quantity=event_row["Cuantía"], + recovered_quantity=event_row["Cuantía Total Recuperada"], + recovered_quantity_by_insurance=event_row["Cuantía Rec. x Seguros"], + event_class=event_class, + reported_by=event_row["Reportado Por"], + critical=event_row["critico"], + level=level, + plan=event_row["Plan"], + event_title=event_row["Evento"], + public_accounts_affected=event_row["Cuentas PUC Afectadas"], + process=process, + lost_type=LostType.objects.get(name=event_row["Tipo de Perdida"]), + description=event_row["Descripción del Evento"], + product=product, + close_date=event_row["Fecha de Cierre"], + learning=event_row["Aprendizaje"], + status=event_row["estado"], + ) + print(f"Event {event_row['Evento']} updated") + + self.stdout.write(self.style.SUCCESS("Events updated")) diff --git a/INSIGHTSAPI/operational_risk/models.py b/INSIGHTSAPI/operational_risk/models.py index f27521b..09836d0 100644 --- a/INSIGHTSAPI/operational_risk/models.py +++ b/INSIGHTSAPI/operational_risk/models.py @@ -1,4 +1,5 @@ """Models for operational risk app.""" + from django.db import models @@ -51,6 +52,7 @@ def __str__(self): """Return the name of the product line.""" return str(self.name) + class Events(models.Model): """Model definition for operational events.""" diff --git a/INSIGHTSAPI/pqrs/models.py b/INSIGHTSAPI/pqrs/models.py index af53258..db869f2 100644 --- a/INSIGHTSAPI/pqrs/models.py +++ b/INSIGHTSAPI/pqrs/models.py @@ -1,6 +1,7 @@ """This module represents the pqrs models. """ -from django.db import models + from django.core.exceptions import ValidationError +from django.db import models def validate_max_length_1000(value): diff --git a/INSIGHTSAPI/pqrs/views.py b/INSIGHTSAPI/pqrs/views.py index 7050dea..ddb5375 100644 --- a/INSIGHTSAPI/pqrs/views.py +++ b/INSIGHTSAPI/pqrs/views.py @@ -1,23 +1,22 @@ """This module contains the PQRS viewset.""" -import sys import logging -from rest_framework import viewsets -from rest_framework import status -from rest_framework.response import Response -from rest_framework.permissions import IsAuthenticated -from django.core.mail import EmailMessage -from django.core.mail import mail_admins +import sys + from django.conf import settings -from .models import Complaint, Congratulation, Suggestion, Other +from django.core.mail import EmailMessage, mail_admins +from rest_framework import status, viewsets +from rest_framework.permissions import IsAuthenticated +from rest_framework.response import Response + +from .models import Complaint, Congratulation, Other, Suggestion from .serializers import ( ComplaintSerializer, CongratulationSerializer, - SuggestionSerializer, OtherSerializer, + SuggestionSerializer, ) - logger = logging.getLogger("requests") @@ -45,19 +44,19 @@ def create(self, request, *args, **kwargs): if not "description" in self.request.data: return Response({"error": "La descripción es requerida"}, status=400) response = super().create(request, *args, **kwargs) - + if response.status_code == status.HTTP_201_CREATED: options = { "TEST": settings.EMAIL_FOR_TEST, "EJECUTIVO": "PABLO.CASTANEDA@CYC-BPO.COM", "GERENCIA GENERAL": "CESAR.GARZON@CYC-BPO.COM", - "GERENCIA DE RIESGO Y CONTROL INTERNO": "MARIO.GIRON@CYC-BPO.COM", + "GERENCIA DE RIESGO Y CONTROL INTERNO": "ANGELICA.RINCON@CYC-BPO.COM", "GERENCIA GESTIÓN HUMANA": "JEANNETH.PINZON@CYC-BPO.COM", "GERENCIA DE PLANEACIÓN": "ANGELA.DURAN@CYC-BPO.COM", "GERENCIA ADMINISTRATIVA": "MELIDA.SANDOVAL@CYC-BPO.COM", "GERENCIA DE LEGAL Y RIESGO": "DIEGO.GONZALEZ@CYC-BPO.COM", "GERENCIA DE OPERACIONES": "ADRIANA.PAEZ@CYC-BPO.COM", - "GERENCIA DE MERCADEO": "HECTOR.SOTELO@CYC-BPO.COM", + "RECURSOS FÍSICOS": "", } email = options.get(self.request.data["area"].upper()) if not email: