diff --git a/cosiap_api/dynamic_tables/views.py b/cosiap_api/dynamic_tables/views.py index 8dac577efd5adc78a2f80e130314a12b0b43e580..64cee79762a5d6f74e43983e8500471f7c0a2008 100644 --- a/cosiap_api/dynamic_tables/views.py +++ b/cosiap_api/dynamic_tables/views.py @@ -11,6 +11,7 @@ from datetime import timedelta, datetime from notificaciones.mensajes import Mensaje from django.core.exceptions import ValidationError import json +from users.models import Solicitante from django.utils.encoding import force_bytes from django.utils.http import urlsafe_base64_encode from solicitudes.models import Solicitud @@ -38,6 +39,25 @@ class DynamicTableAPIView(BasePermissionAPIView): dynamic_form_exist = False + def check_user_permissions(self, request, pk): + ''' + Verificamos el acceso de un usuario a una instancia en específico + ''' + user = request.user + + if not user.is_staff: + solicitante = Solicitante.objects.get(id=user.id) + if self.model_class == Solicitud: + instance = get_object_or_404(self.model_class, pk=pk, solicitante = solicitante) + else: + if solicitante.id == pk: + instance = get_object_or_404(self.model_class, pk=solicitante.id) + else: + instance = None + else: + instance = get_object_or_404(self.model_class, pk=pk) + return instance + def get_configuracion_reporte(self, request): ''' Crear una configuración con los datos actuales de la request, sobrescribiendo los predeterminados si se proporcionan. @@ -90,26 +110,38 @@ class DynamicTableAPIView(BasePermissionAPIView): ''' response_data = {} + if pk is not None: - # Recuperar la instancia y extraer los datos - instance = get_object_or_404(self.model_class, pk=pk) - if self.dynamic_form_exist: - serializer = DynamicTableDynamicForm(model_class=self.model_class) - else: - serializer = DynamicTable(model_class=self.model_class) - instance_data = serializer.retrieve_instance_data(instance) - return Response(instance_data, status=status.HTTP_200_OK) + try: + instance = self.check_user_permissions(request, pk) + if instance is not None: + if self.dynamic_form_exist: + serializer = DynamicTableDynamicForm(model_class=self.model_class) + else: + serializer = DynamicTable(model_class=self.model_class) + instance_data = serializer.retrieve_instance_data(instance) + return Response(instance_data, status=status.HTTP_200_OK) + else: + Mensaje.error(response_data, 'No tienes permisos para realizar esta acción.') + return Response(response_data, status = status.HTTP_400_BAD_REQUEST) + except Exception as e: + Mensaje.error(response_data, str(e)) + return Response(response_data, status = status.HTTP_400_BAD_REQUEST) try: - configuracion_reporte = self.get_configuracion_reporte(request) - if self.dynamic_form_exist: - serializer = DynamicTableDynamicForm(instance=configuracion_reporte, model_class=self.model_class) + if user.is_staff: + configuracion_reporte = self.get_configuracion_reporte(request) + if self.dynamic_form_exist: + serializer = DynamicTableDynamicForm(instance=configuracion_reporte, model_class=self.model_class) + else: + serializer = DynamicTable(instance=configuracion_reporte,model_class=self.model_class) + data = serializer.get_data(configuracion_reporte) + available_columns = serializer.get_available_columns(configuracion_reporte) + available_filters = serializer.get_available_filters(configuracion_reporte) + response_data = {'data': data, 'available_filters': available_filters, 'available_columns': available_columns} + return Response(response_data, status=status.HTTP_200_OK) else: - serializer = DynamicTable(instance=configuracion_reporte,model_class=self.model_class) - data = serializer.get_data(configuracion_reporte) - available_columns = serializer.get_available_columns(configuracion_reporte) - available_filters = serializer.get_available_filters(configuracion_reporte) - response_data = {'data': data, 'available_filters': available_filters, 'available_columns': available_columns} - return Response(response_data, status=status.HTTP_200_OK) + Mensaje.error(response_data, 'No tienes permisos para realizar esta acción.') + return Response(response_data, status=status.HTTP_400_BAD_REQUEST) except Exception as e: Mensaje.error(response_data, str(e)) return Response(response_data, status=status.HTTP_400_BAD_REQUEST) @@ -124,7 +156,14 @@ class DynamicTableAPIView(BasePermissionAPIView): instance = None # Obtener la instancia del modelo por el id proporcionado en la URL o un 404 en caso de no existir if pk is not None: - instance = get_object_or_404(self.model_class, pk=pk) + try: + instance = self.check_user_permissions(request, pk) + if instance is None: + Mensaje.error(response_data, 'No tienes permisos para realizar esta acción.') + return Response(response_data, status = status.HTTP_400_BAD_REQUEST) + except Exception as e: + Mensaje.error(response_data, str(e)) + return Response(response_data, status = status.HTTP_400_BAD_REQUEST) # Obtener datos de actualización del request field_updates = request.data.get('field_updates', {}) @@ -232,7 +271,7 @@ class ReporteAPIView(BasePermissionAPIView): configuracion_reporte = serializer.save() Mensaje.success(response_data, 'Reporte creado con exito.') return Response(response_data, status=status.HTTP_200_OK) - else: + else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) def put(self, request, pk, *args, **kwargs): diff --git a/cosiap_api/solicitudes/migrations/0003_solicitud_solicitante_cascade.py b/cosiap_api/solicitudes/migrations/0003_solicitud_solicitante_cascade.py new file mode 100644 index 0000000000000000000000000000000000000000..058003a9a47258c398742e97ab93c91b45a378a7 --- /dev/null +++ b/cosiap_api/solicitudes/migrations/0003_solicitud_solicitante_cascade.py @@ -0,0 +1,26 @@ +# Generated by Django 5.0.7 on 2024-08-30 02:14 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('modalidades', '0002_delete_montomodalidad_model'), + ('solicitudes', '0002_initial'), + ('users', '0002_datos_bancarios_Set_null'), + ] + + operations = [ + migrations.AlterField( + model_name='solicitud', + name='modalidad', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='modalidades.modalidad', verbose_name='Modalidad'), + ), + migrations.AlterField( + model_name='solicitud', + name='solicitante', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='users.solicitante', verbose_name='Solicitante'), + ), + ] diff --git a/cosiap_api/solicitudes/migrations/0004_solicitud_status_choices.py b/cosiap_api/solicitudes/migrations/0004_solicitud_status_choices.py new file mode 100644 index 0000000000000000000000000000000000000000..09abbed51bf825e7bfb8e3915e016ab7888757e3 --- /dev/null +++ b/cosiap_api/solicitudes/migrations/0004_solicitud_status_choices.py @@ -0,0 +1,18 @@ +# Generated by Django 5.0.7 on 2024-08-30 02:17 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('solicitudes', '0003_solicitud_solicitante_cascade'), + ] + + operations = [ + migrations.AlterField( + model_name='solicitud', + name='status', + field=models.CharField(choices=[('1', 'En revisión'), ('2', 'Aprobado'), ('3', 'Rechazado')], max_length=255, verbose_name='Status'), + ), + ] diff --git a/cosiap_api/solicitudes/models.py b/cosiap_api/solicitudes/models.py index 403913f95c37a8a1979839342fabeff83be30d1b..5bb62a63be7e8df8e3873a75514b4c5022c4a540 100644 --- a/cosiap_api/solicitudes/models.py +++ b/cosiap_api/solicitudes/models.py @@ -107,16 +107,22 @@ class Solicitud(models.Model): - solicitante (Relación con un modelo Solicitante, requerido. Al eliminar, se establece como nulo.) """ - status = models.CharField(verbose_name='Status', max_length=255) + STATUS_CHOICES = [ + ('1', 'En revisión'), + ('2', 'Aprobado'), + ('3', 'Rechazado'), + ] + + status = models.CharField(verbose_name='Status', max_length=255, choices= STATUS_CHOICES) solicitud_n = models.IntegerField(verbose_name='Num. Solicitud', null=True, blank=True, unique=True) minuta = models.ForeignKey(Minuta, verbose_name='Minuta', on_delete=models.SET_NULL, null=True, blank=True) convenio = models.OneToOneField(Convenio, verbose_name='Convenio', on_delete=models.SET_NULL, null=True, blank=True) monto_solicitado = models.FloatField(verbose_name='Monto Solicitado', default=0.0) monto_aprobado = models.FloatField(verbose_name='Monto Aprobado', default=0.0) - modalidad = models.ForeignKey(Modalidad, verbose_name='Modalidad', on_delete=models.SET_NULL, null=True, blank=True) + modalidad = models.ForeignKey(Modalidad, verbose_name='Modalidad', on_delete=models.CASCADE, null=True, blank=True) timestamp = models.DateTimeField(verbose_name='Timestamp', auto_now_add=True) observacion = models.TextField(verbose_name='Observación', null=True, blank=True) - solicitante = models.ForeignKey(Solicitante, verbose_name='Solicitante', on_delete=models.SET_NULL, null=True, blank=True) + solicitante = models.ForeignKey(Solicitante, verbose_name='Solicitante', on_delete=models.CASCADE, null=True, blank=True) registro_formulario = models.OneToOneField(RegistroFormulario, on_delete=models.SET_NULL, null=True, blank=True) def save(self, *args, **kwargs): diff --git a/cosiap_api/solicitudes/views.py b/cosiap_api/solicitudes/views.py index f7d3d225fb021781cfddfa7c80446cbf804ad7e8..f03f6f96d24137c51bab9ec3ace158f810682201 100644 --- a/cosiap_api/solicitudes/views.py +++ b/cosiap_api/solicitudes/views.py @@ -4,7 +4,7 @@ from dynamic_tables.views import DynamicTableAPIView from .models import Solicitud -from users.permisos import es_admin +from users.permisos import es_admin, primer_login from rest_framework.permissions import IsAuthenticated from datetime import timedelta, datetime from common.views import BasePermissionAPIView @@ -33,8 +33,6 @@ class SolicitudAPIView(DynamicTableAPIView): ''' - permission_classes_list = [AllowAny] - model_class = Solicitud model_name = 'Solicitud' columns = '__all__' @@ -52,48 +50,33 @@ class SolicitarAPIView(BasePermissionAPIView): Clase para manejar la lógica de la creación y edición de solicitudes ''' - permission_classes_create = [IsAuthenticated] - permission_classes_update = [IsAuthenticated] + permission_classes_create = [IsAuthenticated, primer_login] + permission_classes_update = [IsAuthenticated, primer_login] permission_classes_list = [IsAuthenticated] def get(self, request, *args, **kwargs): ''' Metodo GET para obtener el formulario a contestar de la modalidad - o la vista detallada de la solicitud (para solicitante) ''' data = {} try: solicitante = Solicitante.objects.get(id=request.user.id) + modalidad_id = request.query_params.get('modalidad_id', None) + modalidad = Modalidad.objects.get(id=modalidad_id) - if 'pk' in kwargs: - solicitud_id = kwargs['pk'] - try: - solicitud = Solicitud.objects.get(id=solicitud_id, solicitante=solicitante) - data["monto_solicitado"] = solicitud.monto_solicitado - form = RespuestaFormularioSerializer(solicitud, dynamic_form_source='modalidad__dynamic_form') - data["formulario"] = form.data - return Response(data, status=status.HTTP_200_OK) - - except Solicitud.DoesNotExist: - Mensaje.error(data, 'No tienes permiso para ver esta solicitud o no existe.') - return Response(data, status=status.HTTP_404_NOT_FOUND) - else: - modalidad_id = request.query_params.get('modalidad_id', None) - modalidad = Modalidad.objects.get(id=modalidad_id) - - # Crear una solicitud temporal - solicitud_temporal = Solicitud( - solicitante=solicitante, - modalidad=modalidad, - ) + # Crear una solicitud temporal + solicitud_temporal = Solicitud( + solicitante=solicitante, + modalidad=modalidad, + ) - # Serializar el formulario basado en la modalidad - form = RespuestaFormularioSerializer(solicitud_temporal, dynamic_form_source='modalidad__dynamic_form') - form_data = form.data - return Response(form_data, status=status.HTTP_200_OK) + # Serializar el formulario basado en la modalidad + form = RespuestaFormularioSerializer(solicitud_temporal, dynamic_form_source='modalidad__dynamic_form') + form_data = form.data + return Response(form_data, status=status.HTTP_200_OK) except Modalidad.DoesNotExist: Mensaje.error(data, 'Modalidad no encontrada.') @@ -134,7 +117,7 @@ class SolicitarAPIView(BasePermissionAPIView): solicitante=solicitante, monto_solicitado=monto_solicitado, modalidad=modalidad, - status='Pendiente' + status='1' ) nueva_solicitud.solicitud_n = nueva_solicitud.id nueva_solicitud.save() @@ -180,7 +163,7 @@ class SolicitarAPIView(BasePermissionAPIView): with transaction.atomic(): solicitud.monto_solicitado = monto_solicitado - solicitud.status = 'Pendiente' + solicitud.status = '1' solicitud.save() registro_formulario = solicitud.registro_formulario diff --git a/cosiap_api/users/migrations/0002_datos_bancarios_Set_null.py b/cosiap_api/users/migrations/0002_datos_bancarios_Set_null.py new file mode 100644 index 0000000000000000000000000000000000000000..45910c8debf4a1dc1fbdcc522f81cbd2cf1e36d9 --- /dev/null +++ b/cosiap_api/users/migrations/0002_datos_bancarios_Set_null.py @@ -0,0 +1,24 @@ +# Generated by Django 5.0.7 on 2024-08-30 02:09 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='solicitante', + name='datos_bancarios', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='users.datosbancarios', verbose_name='Datos Bancarios'), + ), + migrations.AlterField( + model_name='solicitante', + name='municipio', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='users.municipio', verbose_name='Municipio'), + ), + ] diff --git a/cosiap_api/users/migrations/0003_solicitante_blank_true.py b/cosiap_api/users/migrations/0003_solicitante_blank_true.py new file mode 100644 index 0000000000000000000000000000000000000000..dde85906eb702fe612006dc27dfe17b13a25e214 --- /dev/null +++ b/cosiap_api/users/migrations/0003_solicitante_blank_true.py @@ -0,0 +1,56 @@ +# Generated by Django 5.0.7 on 2024-08-30 18:08 + +import common.nombres_archivos +import django.core.validators +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0002_datos_bancarios_Set_null'), + ] + + operations = [ + migrations.AlterField( + model_name='solicitante', + name='INE', + field=models.FileField(blank=True, null=True, upload_to=common.nombres_archivos.nombre_archivo_ine, verbose_name='INE'), + ), + migrations.AlterField( + model_name='solicitante', + name='RFC', + field=models.CharField(blank=True, max_length=13, null=True, unique=True, validators=[django.core.validators.RegexValidator('^([A-ZÑ&]{3,4}) ?(?:- ?)?(\\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\\d|3[01])) ?(?:- ?)?([A-Z\\d]{2})([A\\d])$', 'Debe ser un RFC válido.')], verbose_name='RFC'), + ), + migrations.AlterField( + model_name='solicitante', + name='ap_paterno', + field=models.CharField(blank=True, max_length=50, null=True, verbose_name='Apellido Paterno'), + ), + migrations.AlterField( + model_name='solicitante', + name='codigo_postal', + field=models.CharField(blank=True, max_length=5, null=True, verbose_name='Código Postal'), + ), + migrations.AlterField( + model_name='solicitante', + name='direccion', + field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Dirección'), + ), + migrations.AlterField( + model_name='solicitante', + name='municipio', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='users.municipio', verbose_name='Municipio'), + ), + migrations.AlterField( + model_name='solicitante', + name='poblacion', + field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Población'), + ), + migrations.AlterField( + model_name='solicitante', + name='telefono', + field=models.CharField(blank=True, max_length=10, null=True, verbose_name='Teléfono'), + ), + ] diff --git a/cosiap_api/users/models.py b/cosiap_api/users/models.py index 0e90249a82ab521a22623d8c3519345059da37bb..86a9ddfea5b274386072003c02028a3614e64aca 100644 --- a/cosiap_api/users/models.py +++ b/cosiap_api/users/models.py @@ -133,25 +133,25 @@ class Solicitante(Usuario): RFC_REGEX = r'^([A-ZÑ&]{3,4}) ?(?:- ?)?(\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])) ?(?:- ?)?([A-Z\d]{2})([A\d])$' # campos para los apellidos - ap_paterno = models.CharField(verbose_name='Apellido Paterno',max_length=50, null=True, blank=False) + ap_paterno = models.CharField(verbose_name='Apellido Paterno',max_length=50, null=True, blank=True) # campo de apellido materno es opcional ap_materno = models.CharField(verbose_name='Apellido Materno', max_length=50, null=True, blank=True) # campo para telefono, longitud maxima de 10 - telefono = models.CharField(verbose_name='Teléfono', max_length=10, null=True, blank=False) + telefono = models.CharField(verbose_name='Teléfono', max_length=10, null=True, blank=True) # campo para el RFC, longitud de 13 - RFC = models.CharField(verbose_name='RFC', max_length=13, validators=[RegexValidator(RFC_REGEX,'Debe ser un RFC válido.')], unique=True, null=True, blank=False) + RFC = models.CharField(verbose_name='RFC', max_length=13, validators=[RegexValidator(RFC_REGEX,'Debe ser un RFC válido.')], unique=True, null=True, blank=True) # campo para la dirección - direccion = models.CharField(verbose_name='Dirección', max_length=255, null=True, blank=False) + direccion = models.CharField(verbose_name='Dirección', max_length=255, null=True, blank=True) # campo para el código postal, longitud 5 - codigo_postal = models.CharField(verbose_name='Código Postal', max_length=5, null=True, blank=False) + codigo_postal = models.CharField(verbose_name='Código Postal', max_length=5, null=True, blank=True) # relación con el municipio mediante llave foránea - municipio = models.ForeignKey(Municipio, verbose_name="Municipio",null=True, blank=False, on_delete=models.CASCADE) + municipio = models.ForeignKey(Municipio, verbose_name="Municipio",null=True, blank=True, on_delete=models.SET_NULL) # campo para la poblacion - poblacion = models.CharField(verbose_name='Población', max_length=255, null=True, blank=False) + poblacion = models.CharField(verbose_name='Población', max_length=255, null=True, blank=True) # campo de relacion uno a uno con los datos bancarios - datos_bancarios = models.OneToOneField(DatosBancarios, verbose_name="Datos Bancarios",null=True, blank=True, on_delete=models.CASCADE ) + datos_bancarios = models.OneToOneField(DatosBancarios, verbose_name="Datos Bancarios",null=True, blank=True, on_delete=models.SET_NULL) # campo para la identificación oficial - INE = models.FileField(verbose_name='INE', upload_to= nombre_archivo_ine , null=True, blank=False) + INE = models.FileField(verbose_name='INE', upload_to= nombre_archivo_ine , null=True, blank=True) def __str__(self): return self.nombre diff --git a/cosiap_api/users/serializers.py b/cosiap_api/users/serializers.py index 7fbbef75585332f3a821420a3e5fb7df96bfafac..99c061cb3bc29baadccdb02fb9976337af44ffd5 100644 --- a/cosiap_api/users/serializers.py +++ b/cosiap_api/users/serializers.py @@ -83,6 +83,38 @@ class DatosBancariosSerializer(serializers.ModelSerializer): model = DatosBancarios # indicamos los fields que el usuario debe ingresar fields = ['nombre_banco', 'cuenta_bancaria', 'clabe_bancaria', 'doc_estado_cuenta', 'doc_constancia_sat', 'codigo_postal_fiscal', 'regimen'] + extra_kwargs = {'nombre_banco': {'required': False}, 'cuenta_bancaria': {'required': False},'clabe_bancaria': {'required': False}, + 'doc_estado_cuenta': {'required': False}, 'doc_constancia_sat': {'required': False},'codigo_postal_fiscal': {'required': False}, + 'regimen': {'required': False} + } + + def create(self, validated_data): + ''' + Función create para crear una instancia de datos bancarios + ''' + + datos_bancarios = DatosBancarios.objects.create( + **validated_data + ) + + return datos_bancarios + + def update(self, instance, validated_data): + ''' + Función para actualizar una instancia de datos bancarios + ''' + + instance.nombre_banco = validated_data.get('nombre_banco', instance.nombre_banco) + instance.cuenta_bancaria = validated_data.get('cuenta_bancaria', instance.cuenta_bancaria) + instance.clabe_bancaria = validated_data.get('clabe_bancaria', instance.clabe_bancaria) + instance.doc_estado_cuenta = validated_data.get('doc_estado_cuenta', instance.doc_estado_cuenta) + instance.doc_constancia_sat = validated_data.get('doc_constancia_sat', instance.doc_constancia_sat) + instance.codigo_postal_fiscal = validated_data.get('codigo_postal_fiscal', instance.codigo_postal_fiscal) + instance.regimen = validated_data.get('regimen', instance.regimen) + + instance.save() + + return instance # Serializer para el registro y actualización de los datos del solicitante @@ -92,7 +124,7 @@ class SolicitanteSerializer(serializers.ModelSerializer): model = Solicitante # indicamos los campos que debe ingresar el usuario fields = ['ap_paterno', 'ap_materno', 'telefono', 'RFC', 'direccion', 'codigo_postal', 'municipio', 'poblacion', 'INE'] - # Agregamos validadores para asegurar que los campos requeridos no estén vacíos + # Agregamos validadores para asegurar que los campos puedan estar vacíos extra_kwargs = {'ap_paterno': {'required': False}, 'ap_materno': {'required': False},'telefono': {'required': False},'RFC': {'required': False}, 'direccion': {'required': False},'codigo_postal': {'required': False},'municipio': {'required': False},'poblacion': {'required': False}, 'INE': {'required': False} diff --git a/cosiap_api/users/urls.py b/cosiap_api/users/urls.py index c2c03ae04bf8476b31637938be3231909705088a..87e664c81bcecbea661883c221bbc3d5c5dc14ac 100644 --- a/cosiap_api/users/urls.py +++ b/cosiap_api/users/urls.py @@ -18,6 +18,7 @@ urlpatterns = [ path('/', views.UsuarioAPIView.as_view(), name = 'usuarios_pk'), path('solicitantes/', views.SolicitanteAPIView.as_view(), name = 'solicitantes'), path('solicitantes/', views.SolicitanteAPIView.as_view(), name = 'solicitantes_pk'), + path('datos-bancarios/', views.DatosBancariosAPIView.as_view(), name = 'datos_bancarios'), path('verificar-correo///', views.VerificarCorreo.as_view(), name='verificar_correo'), path('restablecer-password/', views.ResetPassword.as_view(), name='reset_password'), path('nueva-password///', views.NuevaPassword.as_view(), name='nueva_password'), diff --git a/cosiap_api/users/views.py b/cosiap_api/users/views.py index ea93c6296eea46d80450ac945b3803e447d7d817..24a0a4848a21f2f44f58414be6df6e18e8567af3 100644 --- a/cosiap_api/users/views.py +++ b/cosiap_api/users/views.py @@ -7,9 +7,9 @@ from rest_framework import status, permissions from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.permissions import AllowAny, IsAuthenticated -from .models import Usuario, Solicitante +from .models import Usuario, Solicitante, DatosBancarios from django.contrib import messages -from .serializers import UsuarioSerializer, SolicitanteSerializer +from .serializers import UsuarioSerializer, SolicitanteSerializer, DatosBancariosSerializer from django.contrib.auth import authenticate from django.core.mail import send_mail from django.conf import settings @@ -180,6 +180,82 @@ class UsuarioAPIView(DynamicTableAPIView): return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) +class DatosBancariosAPIView(BasePermissionAPIView): + ''' + Clase para manejar la obtención, creación y edición de los datos bancarios del solicitante. + ''' + + permission_classes_list = [IsAuthenticated] + permission_classes_create = [IsAuthenticated] + permission_classes_update = [IsAuthenticated] + + def get(self, request, *args, **kwargs): + ''' + Función get para obtener los datos bancarios del solicitante que realiza la petición. + ''' + data = {} + + try: + user = request.user + solicitante = Solicitante.objects.get(id = user.id) + # obtenemos los datos bancarios asociados al solicitante + datos_bancarios = DatosBancarios.objects.get(solicitante = solicitante) + serializer = DatosBancariosSerializer(instance = datos_bancarios) + data['data'] = serializer.data + return Response(data, status = status.HTTP_200_OK) + except Exception as e: + Mensaje.error(data, str(e)) + return Response(data, status = status.HTTP_400_BAD_REQUEST) + + def post(self, request, *args, **kwargs): + ''' + Función post para crear una nueva instancia de datos bancarios asociada al solicitante + ''' + + data = {} + + try: + user = request.user + solicitante = Solicitante.objects.get(id = user.id) + if solicitante.datos_bancarios: + Mensaje.error(data, 'El solicitante ya tiene datos bancarios registrados.') + return Response(data, status=status.HTTP_400_BAD_REQUEST) + serializer = DatosBancariosSerializer(data= request.data) + if serializer.is_valid(): + serializer.save() + solicitante.datos_bancarios = serializer.instance + solicitante.save() + Mensaje.success(data, 'Datos bancaros registrados.') + return Response(data, status = status.HTTP_201_CREATED) + else: + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + except Exception as e: + Mensaje.error(data, str(e)) + return Response(data, status = status.HTTP_400_BAD_REQUEST) + + def put(self, request, *args, **kwargs): + ''' + Método put para manejar la edición de los datos bancarios + ''' + + try: + user = request.user + solicitante = Solicitante.objects.get(id = user.id) + # obtenemos los datos bancarios asociados al solicitante + datos_bancarios = DatosBancarios.objects.get(solicitante = solicitante) + serializer = DatosBancariosSerializer(instance = datos_bancarios, data=request.data) + if serializer.is_valid(): + # guardamos los cambios + serializer.save() + Mensaje.success(response_data, 'Datos bancarios actualizados.') + return Response(response_data, status=status.HTTP_200_OK) + else: + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + except Exception as e: + Mensaje.error(data, str(e)) + return Response(data, status = status.HTTP_400_BAD_REQUEST) + + class SolicitanteAPIView(DynamicTableAPIView): """ Clase Solicitante @@ -192,7 +268,7 @@ class SolicitanteAPIView(DynamicTableAPIView): Herencia: - BasePermissionAPIView (Heréda de la clase con los permisos predefinidos) """ - permission_classes_list = [IsAuthenticated, es_admin] + permission_classes_list = [IsAuthenticated] permission_classes_create = [IsAuthenticated] permission_classes_update = [IsAuthenticated] permission_classes_delete = [IsAuthenticated]