Martín Miranda

Merge branch 'validacion' into 'develop'

Validacion



See merge request !19
1 -from rest_framework import viewsets, mixins, status 1 +from rest_framework import viewsets, mixins, status, serializers
2 from rest_framework.response import Response 2 from rest_framework.response import Response
3 from rest_framework.authentication import SessionAuthentication, BasicAuthentication 3 from rest_framework.authentication import SessionAuthentication, BasicAuthentication
4 from rest_framework.permissions import IsAuthenticated 4 from rest_framework.permissions import IsAuthenticated
5 from rest_framework.decorators import action 5 from rest_framework.decorators import action
6 from datetime import datetime 6 from datetime import datetime
7 7
8 -from .models import Edicto  
9 -from .serializer import EdictoSerializer 8 +from .models import Edicto, Precio
  9 +from .serializer import EdictoSerializer, PrecioSerializer
10 from .utils import contador 10 from .utils import contador
11 11
12 12
@@ -38,3 +38,22 @@ class EdictoViewSet(mixins.CreateModelMixin, @@ -38,3 +38,22 @@ class EdictoViewSet(mixins.CreateModelMixin,
38 edicto = self.request.data.get('cuerpo_edicto') 38 edicto = self.request.data.get('cuerpo_edicto')
39 cantidad_palabras = contador(edicto) 39 cantidad_palabras = contador(edicto)
40 serializer.save(cantidad_palabras=cantidad_palabras) 40 serializer.save(cantidad_palabras=cantidad_palabras)
  41 +
  42 +
  43 +class PrecioViewSet(mixins.CreateModelMixin,
  44 + mixins.RetrieveModelMixin,
  45 + mixins.ListModelMixin,
  46 + viewsets.GenericViewSet):
  47 +
  48 + queryset = Precio.objects.all().order_by('id')
  49 + serializer_class = PrecioSerializer
  50 + authentication_classes = [SessionAuthentication, BasicAuthentication]
  51 + permission_classes = [IsAuthenticated]
  52 +
  53 + def create(self, request, *args, **kwargs):
  54 + user = request.user
  55 +
  56 + if not user.is_staff:
  57 + raise serializers.ValidationError("El usuario no es parte del personal designado.")
  58 +
  59 + return super().create(request, *args, **kwargs)
@@ -17,3 +17,15 @@ STATUS_CHOICE = [ @@ -17,3 +17,15 @@ STATUS_CHOICE = [
17 17
18 18
19 EXTENSIONES_VALIDAS = ["pdf", "docx", "jpg", "jpeg", "png"] 19 EXTENSIONES_VALIDAS = ["pdf", "docx", "jpg", "jpeg", "png"]
  20 +
  21 +
  22 +PESOS = 'peso_argentino'
  23 +DOLAR = 'dolar'
  24 +EURO = 'euro'
  25 +
  26 +
  27 +MONEDA = [
  28 + (PESOS, _('peso_argentino')),
  29 + (DOLAR, _('dolar')),
  30 + (EURO, _('euro')),
  31 + ]
1 -# Generated by Django 4.1.9 on 2023-07-03 22:26 1 +# Generated by Django 4.1.9 on 2023-07-30 21:21
2 2
3 from django.conf import settings 3 from django.conf import settings
4 from django.db import migrations, models 4 from django.db import migrations, models
5 import django.db.models.deletion 5 import django.db.models.deletion
6 -import edicto.utils  
7 6
8 7
9 class Migration(migrations.Migration): 8 class Migration(migrations.Migration):
@@ -11,7 +10,6 @@ class Migration(migrations.Migration): @@ -11,7 +10,6 @@ class Migration(migrations.Migration):
11 initial = True 10 initial = True
12 11
13 dependencies = [ 12 dependencies = [
14 - ('organismo', '0002_organismo_es_publico'),  
15 migrations.swappable_dependency(settings.AUTH_USER_MODEL), 13 migrations.swappable_dependency(settings.AUTH_USER_MODEL),
16 ] 14 ]
17 15
@@ -37,14 +35,15 @@ class Migration(migrations.Migration): @@ -37,14 +35,15 @@ class Migration(migrations.Migration):
37 fields=[ 35 fields=[
38 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 36 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
39 ('cuerpo_edicto', models.TextField()), 37 ('cuerpo_edicto', models.TextField()),
40 - ('archivo', models.FileField(upload_to='uploads/%Y/%m/%d/', validators=[edicto.utils.valid_extension])),  
41 - ('dias_plubicar', models.FloatField(default=0.0)),  
42 - ('cantidad_sellos', models.FloatField(default=0.0)),  
43 - ('estado', models.CharField(choices=[('iniciado', 'iniciado'), ('pendiente_de_pago', 'pendiente_de_pago'), ('publicado', 'publicado'), ('rechazado', 'rechazado')], default='inciado', max_length=150)), 38 + ('archivo', models.FileField(upload_to='uploads/%Y/%m/%d/')),
  39 + ('dias_publicar', models.PositiveIntegerField()),
  40 + ('cantidad_sellos', models.PositiveIntegerField()),
  41 + ('estado', models.CharField(choices=[('iniciado', 'iniciado'), ('pendiente_de_pago', 'pendiente_de_pago'), ('publicado', 'publicado'), ('aprobado', 'aprobado'), ('rechazado', 'rechazado')], default='inciado', max_length=150)),
44 ('cantidad_palabras', models.IntegerField()), 42 ('cantidad_palabras', models.IntegerField()),
45 - ('cantidad_copias', models.IntegerField()),  
46 - ('fecha_publicacion', models.DateTimeField()),  
47 - ('organismo', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='organismo.organismo', verbose_name='Organismo')), 43 + ('cantidad_copias', models.PositiveIntegerField()),
  44 + ('fecha_publicacion', models.DateField()),
  45 + ('fecha_creacion', models.DateTimeField(auto_now_add=True)),
  46 + ('fecha_modificacion', models.DateTimeField(auto_now_add=True)),
48 ('usuario', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Usuario')), 47 ('usuario', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Usuario')),
49 ], 48 ],
50 options={ 49 options={
@@ -57,8 +56,8 @@ class Migration(migrations.Migration): @@ -57,8 +56,8 @@ class Migration(migrations.Migration):
57 fields=[ 56 fields=[
58 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 57 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
59 ('resultado', models.FloatField()), 58 ('resultado', models.FloatField()),
60 - ('numero_comprobante', models.CharField(max_length=300)),  
61 - ('fecha_pago', models.DateTimeField()), 59 + ('numero_comprobante', models.CharField(max_length=300, null=True)),
  60 + ('fecha_pago', models.DateTimeField(null=True)),
62 ('edicto', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='edicto.edicto')), 61 ('edicto', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='edicto.edicto')),
63 ], 62 ],
64 options={ 63 options={
1 -# Generated by Django 4.1.9 on 2023-07-12 12:00 1 +# Generated by Django 4.1.9 on 2023-08-02 11:36
2 2
3 from django.db import migrations, models 3 from django.db import migrations, models
4 4
@@ -11,13 +11,13 @@ class Migration(migrations.Migration): @@ -11,13 +11,13 @@ class Migration(migrations.Migration):
11 11
12 operations = [ 12 operations = [
13 migrations.AlterField( 13 migrations.AlterField(
14 - model_name='comprobantepago',  
15 - name='fecha_pago',  
16 - field=models.DateTimeField(null=True), 14 + model_name='precio',
  15 + name='vigencia_desde',
  16 + field=models.DateField(),
17 ), 17 ),
18 migrations.AlterField( 18 migrations.AlterField(
19 - model_name='comprobantepago',  
20 - name='numero_comprobante',  
21 - field=models.CharField(max_length=300, null=True), 19 + model_name='precio',
  20 + name='vigencia_hasta',
  21 + field=models.DateField(),
22 ), 22 ),
23 ] 23 ]
1 -# Generated by Django 4.1.9 on 2023-07-24 14:46 1 +# Generated by Django 4.1.9 on 2023-08-02 12:21
2 2
3 from django.db import migrations, models 3 from django.db import migrations, models
4 4
@@ -6,13 +6,13 @@ from django.db import migrations, models @@ -6,13 +6,13 @@ from django.db import migrations, models
6 class Migration(migrations.Migration): 6 class Migration(migrations.Migration):
7 7
8 dependencies = [ 8 dependencies = [
9 - ('edicto', '0007_alter_edicto_cantidad_palabras_alter_edicto_usuario'), 9 + ('edicto', '0002_alter_precio_vigencia_desde_and_more'),
10 ] 10 ]
11 11
12 operations = [ 12 operations = [
13 migrations.AlterField( 13 migrations.AlterField(
14 - model_name='edicto',  
15 - name='cantidad_palabras',  
16 - field=models.IntegerField(), 14 + model_name='precio',
  15 + name='moneda',
  16 + field=models.CharField(choices=[('peso_argentino', 'peso_argentino'), ('dolar', 'dolar'), ('euro', 'euro')], default='peso_argentino', max_length=50),
17 ), 17 ),
18 ] 18 ]
1 -# Generated by Django 4.1.9 on 2023-07-13 11:49  
2 -  
3 -from django.db import migrations, models  
4 -import django.utils.timezone  
5 -  
6 -  
7 -class Migration(migrations.Migration):  
8 -  
9 - dependencies = [  
10 - ('edicto', '0002_alter_comprobantepago_fecha_pago_and_more'),  
11 - ]  
12 -  
13 - operations = [  
14 - migrations.AddField(  
15 - model_name='edicto',  
16 - name='fecha_creacion',  
17 - field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),  
18 - preserve_default=False,  
19 - ),  
20 - migrations.AddField(  
21 - model_name='edicto',  
22 - name='fecha_modificacion',  
23 - field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),  
24 - preserve_default=False,  
25 - ),  
26 - migrations.AlterField(  
27 - model_name='edicto',  
28 - name='estado',  
29 - field=models.CharField(choices=[('iniciado', 'iniciado'), ('pendiente_de_pago', 'pendiente_de_pago'), ('publicado', 'publicado'), ('aprobado', 'aprobado'), ('rechazado', 'rechazado')], default='inciado', max_length=150),  
30 - ),  
31 - ]  
1 -# Generated by Django 4.1.9 on 2023-07-17 12:04  
2 -  
3 -from django.db import migrations  
4 -  
5 -  
6 -class Migration(migrations.Migration):  
7 -  
8 - dependencies = [  
9 - ('edicto', '0003_edicto_fecha_creacion_edicto_fecha_modificacion_and_more'),  
10 - ]  
11 -  
12 - operations = [  
13 - migrations.RemoveField(  
14 - model_name='edicto',  
15 - name='organismo',  
16 - ),  
17 - ]  
1 -# Generated by Django 4.1.9 on 2023-07-20 15:14  
2 -  
3 -from django.db import migrations, models  
4 -  
5 -  
6 -class Migration(migrations.Migration):  
7 -  
8 - dependencies = [  
9 - ('edicto', '0004_remove_edicto_organismo'),  
10 - ]  
11 -  
12 - operations = [  
13 - migrations.RemoveField(  
14 - model_name='edicto',  
15 - name='dias_plubicar',  
16 - ),  
17 - migrations.AddField(  
18 - model_name='edicto',  
19 - name='dias_publicar',  
20 - field=models.IntegerField(default=0),  
21 - ),  
22 - migrations.AlterField(  
23 - model_name='edicto',  
24 - name='cantidad_palabras',  
25 - field=models.IntegerField(null=True),  
26 - ),  
27 - migrations.AlterField(  
28 - model_name='edicto',  
29 - name='cantidad_sellos',  
30 - field=models.IntegerField(default=0),  
31 - ),  
32 - ]  
1 -# Generated by Django 4.1.9 on 2023-07-22 16:07  
2 -  
3 -from django.conf import settings  
4 -from django.db import migrations, models  
5 -import django.db.models.deletion  
6 -  
7 -  
8 -class Migration(migrations.Migration):  
9 -  
10 - dependencies = [  
11 - migrations.swappable_dependency(settings.AUTH_USER_MODEL),  
12 - ('edicto', '0005_remove_edicto_dias_plubicar_edicto_dias_publicar_and_more'),  
13 - ]  
14 -  
15 - operations = [  
16 - migrations.AlterField(  
17 - model_name='edicto',  
18 - name='usuario',  
19 - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Usuario'),  
20 - ),  
21 - ]  
1 -# Generated by Django 4.1.9 on 2023-07-24 14:46  
2 -  
3 -from django.conf import settings  
4 -from django.db import migrations, models  
5 -import django.db.models.deletion  
6 -  
7 -  
8 -class Migration(migrations.Migration):  
9 -  
10 - dependencies = [  
11 - migrations.swappable_dependency(settings.AUTH_USER_MODEL),  
12 - ('edicto', '0006_alter_edicto_usuario'),  
13 - ]  
14 -  
15 - operations = [  
16 - migrations.AlterField(  
17 - model_name='edicto',  
18 - name='cantidad_palabras',  
19 - field=models.IntegerField(default=0),  
20 - ),  
21 - migrations.AlterField(  
22 - model_name='edicto',  
23 - name='usuario',  
24 - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Usuario'),  
25 - ),  
26 - ]  
1 -# Generated by Django 4.1.9 on 2023-07-25 13:01  
2 -  
3 -from django.db import migrations, models  
4 -  
5 -  
6 -class Migration(migrations.Migration):  
7 -  
8 - dependencies = [  
9 - ('edicto', '0008_alter_edicto_cantidad_palabras'),  
10 - ]  
11 -  
12 - operations = [  
13 - migrations.AlterField(  
14 - model_name='edicto',  
15 - name='cantidad_sellos',  
16 - field=models.IntegerField(),  
17 - ),  
18 - migrations.AlterField(  
19 - model_name='edicto',  
20 - name='dias_publicar',  
21 - field=models.IntegerField(),  
22 - ),  
23 - migrations.AlterField(  
24 - model_name='edicto',  
25 - name='fecha_publicacion',  
26 - field=models.DateField(),  
27 - ),  
28 - ]  
1 -# Generated by Django 4.1.9 on 2023-07-25 13:32  
2 -  
3 -from django.conf import settings  
4 -from django.db import migrations, models  
5 -import django.db.models.deletion  
6 -  
7 -  
8 -class Migration(migrations.Migration):  
9 -  
10 - dependencies = [  
11 - migrations.swappable_dependency(settings.AUTH_USER_MODEL),  
12 - ('edicto', '0009_alter_edicto_cantidad_sellos_and_more'),  
13 - ]  
14 -  
15 - operations = [  
16 - migrations.AlterField(  
17 - model_name='edicto',  
18 - name='cantidad_copias',  
19 - field=models.PositiveIntegerField(),  
20 - ),  
21 - migrations.AlterField(  
22 - model_name='edicto',  
23 - name='cantidad_palabras',  
24 - field=models.PositiveIntegerField(),  
25 - ),  
26 - migrations.AlterField(  
27 - model_name='edicto',  
28 - name='cantidad_sellos',  
29 - field=models.PositiveIntegerField(),  
30 - ),  
31 - migrations.AlterField(  
32 - model_name='edicto',  
33 - name='dias_publicar',  
34 - field=models.PositiveIntegerField(),  
35 - ),  
36 - migrations.AlterField(  
37 - model_name='edicto',  
38 - name='usuario',  
39 - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Usuario'),  
40 - ),  
41 - ]  
1 -# Generated by Django 4.1.9 on 2023-07-25 13:43  
2 -  
3 -from django.db import migrations, models  
4 -  
5 -  
6 -class Migration(migrations.Migration):  
7 -  
8 - dependencies = [  
9 - ('edicto', '0010_alter_edicto_cantidad_copias_and_more'),  
10 - ]  
11 -  
12 - operations = [  
13 - migrations.AlterField(  
14 - model_name='edicto',  
15 - name='cantidad_palabras',  
16 - field=models.IntegerField(),  
17 - ),  
18 - ]  
1 from django.db import models 1 from django.db import models
2 2
3 -from .constants import STATUS_CHOICE 3 +from .constants import STATUS_CHOICE, MONEDA
4 4
5 from usuario.models import Usuario 5 from usuario.models import Usuario
6 6
@@ -9,10 +9,10 @@ from usuario.models import Usuario @@ -9,10 +9,10 @@ from usuario.models import Usuario
9 9
10 class Precio (models.Model): 10 class Precio (models.Model):
11 precio = models.FloatField(max_length=50, blank=False, null=False) 11 precio = models.FloatField(max_length=50, blank=False, null=False)
12 - vigencia_desde = models.DateTimeField()  
13 - vigencia_hasta = models.DateTimeField() 12 + vigencia_desde = models.DateField()
  13 + vigencia_hasta = models.DateField()
14 usuario = models.ForeignKey(Usuario, on_delete=models.CASCADE) 14 usuario = models.ForeignKey(Usuario, on_delete=models.CASCADE)
15 - moneda = models.CharField(max_length=50, blank=False, null=False) 15 + moneda = models.CharField(max_length=50, blank=False, null=False, choices=MONEDA, default='peso_argentino')
16 precio_ejemplar = models.FloatField(max_length=50, blank=False, null=False) 16 precio_ejemplar = models.FloatField(max_length=50, blank=False, null=False)
17 17
18 class Meta: 18 class Meta:
@@ -24,7 +24,7 @@ class Precio (models.Model): @@ -24,7 +24,7 @@ class Precio (models.Model):
24 24
25 25
26 class Edicto(models.Model): 26 class Edicto(models.Model):
27 - usuario = models.ForeignKey(Usuario, on_delete=models.CASCADE, verbose_name='Usuario', null=True) 27 + usuario = models.ForeignKey(Usuario, on_delete=models.CASCADE, verbose_name='Usuario')
28 cuerpo_edicto = models.TextField(blank=False, null=False) 28 cuerpo_edicto = models.TextField(blank=False, null=False)
29 archivo = models.FileField(upload_to="uploads/%Y/%m/%d/", null=False, blank=False) 29 archivo = models.FileField(upload_to="uploads/%Y/%m/%d/", null=False, blank=False)
30 dias_publicar = models.PositiveIntegerField(blank=False, null=False) 30 dias_publicar = models.PositiveIntegerField(blank=False, null=False)
1 from rest_framework import serializers 1 from rest_framework import serializers
  2 +
2 from .constants import EXTENSIONES_VALIDAS 3 from .constants import EXTENSIONES_VALIDAS
3 4
4 -from .models import Edicto 5 +from .models import Edicto, Precio, ComprobantePago
5 6
6 7
7 class EdictoSerializer(serializers.ModelSerializer): 8 class EdictoSerializer(serializers.ModelSerializer):
@@ -26,3 +27,25 @@ class EdictoSerializer(serializers.ModelSerializer): @@ -26,3 +27,25 @@ class EdictoSerializer(serializers.ModelSerializer):
26 if extension.lower() not in EXTENSIONES_VALIDAS: 27 if extension.lower() not in EXTENSIONES_VALIDAS:
27 raise serializers.ValidationError("Archivos permitidos: .pdf, .docx, .jpg, .jpeg, .png") 28 raise serializers.ValidationError("Archivos permitidos: .pdf, .docx, .jpg, .jpeg, .png")
28 return value 29 return value
  30 +
  31 +
  32 +class PrecioSerializer(serializers.ModelSerializer):
  33 + class Meta:
  34 + model = Precio
  35 + fields = ('usuario',
  36 + 'moneda',
  37 + 'precio',
  38 + 'precio_ejemplar',
  39 + 'vigencia_desde',
  40 + 'vigencia_hasta',
  41 + )
  42 +
  43 + def validate(self, data):
  44 + request = self.context.get('request')
  45 + user = request.user if request else None
  46 + if not user or user.is_anonymous:
  47 + raise serializers.ValidationError("El usuario debe estar autenticado.")
  48 + if not user.is_staff:
  49 + raise serializers.ValidationError("El usuario no es parte del personal designado.")
  50 +
  51 + return data
1 -from django.core.exceptions import ValidationError  
2 import re 1 import re
3 2
4 3
5 -def valid_extension(value):  
6 - if (not value.name.endswith('.pdf') and  
7 - not value.name.endswith('.docx') and  
8 - not value.name.endswith('.jpeg') and  
9 - not value.name.endswith('.png') and  
10 - not value.name.endswith('.jpg')):  
11 - raise ValidationError("Archivos permitidos: .pdf, .docx, .jpg, .jpeg, .png")  
12 -  
13 -  
14 def contador(edicto): 4 def contador(edicto):
15 numeros = re.findall(r'\b\d+(?:\.\d+)?\b', edicto) 5 numeros = re.findall(r'\b\d+(?:\.\d+)?\b', edicto)
16 - expresiones = re.findall(r'[(\[{](.*?)[)\]}]', edicto) 6 + expresiones = re.findall(r'\(\.\.\.', edicto)
17 texto = edicto.split() 7 texto = edicto.split()
18 cantidad_palabras = len(texto) 8 cantidad_palabras = len(texto)
19 - cantidad_numeros = len(numeros) 9 + cantidad_numeros = len(numeros) - 1
20 cantidad_expresiones = len(expresiones) 10 cantidad_expresiones = len(expresiones)
21 total_edicto = cantidad_palabras + cantidad_numeros + cantidad_expresiones 11 total_edicto = cantidad_palabras + cantidad_numeros + cantidad_expresiones
22 return total_edicto 12 return total_edicto
@@ -9,3 +9,4 @@ router = routers.DefaultRouter() @@ -9,3 +9,4 @@ router = routers.DefaultRouter()
9 router.register(prefix='usuario', viewset=usuario_api.UsuarioViewSet) 9 router.register(prefix='usuario', viewset=usuario_api.UsuarioViewSet)
10 router.register(prefix='organismo', viewset=organismo_api.OrganismoViewSet) 10 router.register(prefix='organismo', viewset=organismo_api.OrganismoViewSet)
11 router.register(prefix='edicto', viewset=edicto_api.EdictoViewSet) 11 router.register(prefix='edicto', viewset=edicto_api.EdictoViewSet)
  12 +router.register(prefix='precio', viewset=edicto_api.PrecioViewSet)