From 8b9b17a79deccd537a894f2218f5ee6d4e676d65 Mon Sep 17 00:00:00 2001 From: fjrodriguez Date: Wed, 3 May 2023 11:06:27 -0600 Subject: [PATCH] Ultimo Commit antes del apagon (Respaldo) --- Admin/settings.py | 3 +- Admin/urls.py | 1 + Clientes/views.py | 16 +-- IMMEX/__init__.py | 0 IMMEX/admin.py | 5 + IMMEX/apps.py | 6 + IMMEX/forms.py | 24 ++++ IMMEX/migrations/0001_initial.py | 42 ++++++ IMMEX/migrations/__init__.py | 0 IMMEX/models.py | 25 ++++ IMMEX/serializers.py | 7 + IMMEX/tests.py | 3 + IMMEX/urls.py | 10 ++ IMMEX/views.py | 91 +++++++++++++ Sistemas/urls.py | 3 +- Sistemas/views.py | 23 ++++ Templates/IMMEX/xclientes/edit_cliente.html | 97 ++++++++++++++ Templates/IMMEX/xclientes/lista.html | 35 +++++ .../IMMEX/xclientes/sistema_create_IMMEX.html | 121 ++++++++++++++++++ .../IMMEX/xclientes/sistema_create_from.html | 0 Templates/sidebar.html | 20 ++- 21 files changed, 515 insertions(+), 17 deletions(-) create mode 100644 IMMEX/__init__.py create mode 100644 IMMEX/admin.py create mode 100644 IMMEX/apps.py create mode 100644 IMMEX/forms.py create mode 100644 IMMEX/migrations/0001_initial.py create mode 100644 IMMEX/migrations/__init__.py create mode 100644 IMMEX/models.py create mode 100644 IMMEX/serializers.py create mode 100644 IMMEX/tests.py create mode 100644 IMMEX/urls.py create mode 100644 IMMEX/views.py create mode 100644 Templates/IMMEX/xclientes/edit_cliente.html create mode 100644 Templates/IMMEX/xclientes/lista.html create mode 100644 Templates/IMMEX/xclientes/sistema_create_IMMEX.html create mode 100644 Templates/IMMEX/xclientes/sistema_create_from.html diff --git a/Admin/settings.py b/Admin/settings.py index 5c813c8..593a461 100644 --- a/Admin/settings.py +++ b/Admin/settings.py @@ -15,7 +15,7 @@ BASE_DIR = Path(__file__).resolve().parent.parent SECRET_KEY = os.getenv("adminAS_KEY") # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = False +DEBUG = True ALLOWED_HOSTS = ['*'] # Application definition @@ -34,6 +34,7 @@ INSTALLED_APPS = [ 'widget_tweaks', 'Clientes', + 'IMMEX', 'Sistemas', ] REST_FRAMEWORK = { diff --git a/Admin/urls.py b/Admin/urls.py index 49e0e97..bc8f4b1 100644 --- a/Admin/urls.py +++ b/Admin/urls.py @@ -31,6 +31,7 @@ urlpatterns = [ path('accounts/', include('allauth.urls')), path('DRF_Token/', obtain_auth_token, name='DRF_Token'), path('', include('Clientes.urls')), + path('IMMEX/', include('IMMEX.urls')), path('sistemas/',include('Sistemas.urls')), path('403/', permission_denied_view), diff --git a/Clientes/views.py b/Clientes/views.py index b796310..cc3a725 100644 --- a/Clientes/views.py +++ b/Clientes/views.py @@ -419,17 +419,15 @@ class CancelaTimbre(APIView): obj={'uuid':f'{timbre.uuid}_','rfcc':timbre.rfcc,'fecha':timbre.fecha,'folio':timbre.folio, 'serie':timbre.serie,'tipo':'Cancela','rfcp':timbre.rfcp,'modo':'Normal'} else: - - fecha=request.data.get('fecha', None) folio=request.data.get('folio', None) - serie=request.data.get('serie', None) + serie=request.data.get('serie', '') rfcp_encoded=request.data.get('rfcp', None) - + rfcp = urllib.parse.unquote(rfcp_encoded) obj={'uuid':f'{UUID}_','rfcc':rfcc,'fecha':fecha,'folio':folio, - 'serie':serie,'tipo':'Cancela','rfcp':rfcp,'modo':'Normal' + 'serie':serie ,'tipo':'Cancela','rfcp':rfcp,'modo':'Normal' } cancelaTimbre = Timbres.objects.create(**obj) @@ -526,12 +524,12 @@ class ClientesCreateView(UserPassesTestMixin,LoginRequiredMixin,CreateView): form_class = ClienteForm success_url='/' template_name='Clientes/edit_cliente.html' - def test_func(self): - #self.request.user.groups.all() + + def test_func(self): return self.request.user.groups.filter(name= 'admin_soft') def form_valid(self, form): - response = super().form_valid(form) + response = super().form_valid(form) if self.request.headers.get('X-Requested-With') == 'XMLHttpRequest': data={ 'id':self.object.id, @@ -542,7 +540,7 @@ class ClientesCreateView(UserPassesTestMixin,LoginRequiredMixin,CreateView): return JsonResponse(data) else: return response - + def form_invalid(self,form): response = super().form_invalid(form) if self.request.headers.get('X-Requested-With') == 'XMLHttpRequest': diff --git a/IMMEX/__init__.py b/IMMEX/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/IMMEX/admin.py b/IMMEX/admin.py new file mode 100644 index 0000000..79f3127 --- /dev/null +++ b/IMMEX/admin.py @@ -0,0 +1,5 @@ +from django.contrib import admin +from . models import Sistemas_por_cliente_A24, ClientesA24 + +admin.site.register(Sistemas_por_cliente_A24) +admin.site.register(ClientesA24) diff --git a/IMMEX/apps.py b/IMMEX/apps.py new file mode 100644 index 0000000..5b7c69a --- /dev/null +++ b/IMMEX/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class ImmexConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'IMMEX' diff --git a/IMMEX/forms.py b/IMMEX/forms.py new file mode 100644 index 0000000..9d1ea2c --- /dev/null +++ b/IMMEX/forms.py @@ -0,0 +1,24 @@ +from django import forms +from .models import ClientesA24 +from datetime import datetime + +class ClienteForm_IMMEX(forms.ModelForm): + fecha_baja = forms.DateField( + required=False, + initial=datetime.now(), + input_formats=["%Y-%m-%d"], + widget=forms.DateInput(attrs={'type':'date'},format="%Y-%m-%d") + ) + + class Meta: + model = ClientesA24 + fields = ('RFC','Nombre','Activo','fecha_baja', ) + + def clean(self): + super(ClienteForm_IMMEX,self).clean() + Activo = self.cleaned_data.get("Activo") + fecha_baja = self.cleaned_data.get("fecha_baja") + + if Activo and fecha_baja: + self._errors['fecha_baja'] = self.error_class(["El parametro activo no puede estar seleccionado si hay fecha de baja"]) + return self.cleaned_data \ No newline at end of file diff --git a/IMMEX/migrations/0001_initial.py b/IMMEX/migrations/0001_initial.py new file mode 100644 index 0000000..5263cef --- /dev/null +++ b/IMMEX/migrations/0001_initial.py @@ -0,0 +1,42 @@ +# Generated by Django 4.1.3 on 2023-04-26 16:55 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('Sistemas', '0019_alter_device_options'), + ] + + operations = [ + migrations.CreateModel( + name='ClientesA24', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('RFC', models.CharField(max_length=13, unique=True)), + ('Nombre', models.CharField(max_length=100)), + ('Activo', models.BooleanField(default=False)), + ('fecha_baja', models.DateField(blank=True, null=True)), + ], + options={ + 'ordering': ('-Activo', 'RFC'), + }, + ), + migrations.CreateModel( + name='Sistemas_por_cliente_A24', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('num_licencias', models.IntegerField(default=1)), + ('cliente', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='cliente_spc_IMMEX', to='IMMEX.clientesa24')), + ('id_sistema', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sistema_spc_IMMEX', to='Sistemas.sistema')), + ], + options={ + 'ordering': ('-cliente', 'id_sistema'), + 'unique_together': {('id_sistema', 'cliente')}, + }, + ), + ] diff --git a/IMMEX/migrations/__init__.py b/IMMEX/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/IMMEX/models.py b/IMMEX/models.py new file mode 100644 index 0000000..69cdf65 --- /dev/null +++ b/IMMEX/models.py @@ -0,0 +1,25 @@ +from django.db import models +from Sistemas.models import Sistema + + +class ClientesA24(models.Model): + RFC = models.CharField(max_length=13, unique=True) + Nombre = models.CharField(max_length=100) + Activo = models.BooleanField(default=False) + fecha_baja = models.DateField(blank=True,null=True) + class Meta: + ordering = ('-Activo','RFC',) + def __str__(self): + return self.Nombre + +class Sistemas_por_cliente_A24(models.Model): + id_sistema= models.ForeignKey(Sistema, related_name='sistema_spc_IMMEX', on_delete=models.CASCADE) + cliente = models.ForeignKey(ClientesA24, related_name='cliente_spc_IMMEX', on_delete=models.CASCADE) + num_licencias= models.IntegerField(default=1) + def __str__(self): + return f'{self.cliente.Nombre}' + class Meta: + ordering= ('-cliente','id_sistema') + unique_together = ('id_sistema', 'cliente') + + \ No newline at end of file diff --git a/IMMEX/serializers.py b/IMMEX/serializers.py new file mode 100644 index 0000000..5b62537 --- /dev/null +++ b/IMMEX/serializers.py @@ -0,0 +1,7 @@ +from rest_framework import serializers +from .models import ClientesA24 + +class ClientesA24Serailizer(serializers.ModelSerializer): + class Meta: + model =ClientesA24 + fields = ('RFC', 'Nombre','Activo','fecha_baja',) \ No newline at end of file diff --git a/IMMEX/tests.py b/IMMEX/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/IMMEX/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/IMMEX/urls.py b/IMMEX/urls.py new file mode 100644 index 0000000..2ebf636 --- /dev/null +++ b/IMMEX/urls.py @@ -0,0 +1,10 @@ +from django.urls import path +from . import views + +urlpatterns = [ + path('', views.Sistemas_xCliente_IMMEX_ListView.as_view(), name='sistemasXcli_IMMEX'), + path('create_sistema/',views.Sistemas_xCliente_IMMEX_CreateView.as_view(), name='create_sistemaIMMEX'), + path('create_Cliente/', views.ClientesIMMEX_CreateView.as_view(), name='ClientesIMMEX_Create'), + path('checkRfcA24/', views.Check_IMMEX_RFC.as_view(), name='checkRfcA24' ), + +] \ No newline at end of file diff --git a/IMMEX/views.py b/IMMEX/views.py new file mode 100644 index 0000000..7b7ebee --- /dev/null +++ b/IMMEX/views.py @@ -0,0 +1,91 @@ +from django.shortcuts import render + +from django.http import JsonResponse +from django.urls import reverse_lazy +from Sistemas.models import Sistema +from .models import Sistemas_por_cliente_A24, ClientesA24 +from django.views.generic.edit import CreateView +from django.views.generic.list import ListView +from django.contrib import messages +from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin + +from .forms import ClienteForm_IMMEX +from .serializers import ClientesA24Serailizer + +from rest_framework.views import APIView +from rest_framework.response import Response + +from rest_framework.permissions import IsAuthenticated +from Sistemas.permissions import ItsAdminToken + +import urllib.parse +import traceback + +class Sistemas_xCliente_IMMEX_ListView(UserPassesTestMixin,LoginRequiredMixin, ListView): + model = Sistemas_por_cliente_A24 + paginate_by = 100 + template_name = 'IMMEX/xclientes/lista.html' + def test_func(self): + res = self.request.user.groups.filter(name= 'admin_soft') + if not res: + messages.error(self.request, 'Lo sentimos. La página que buscas no está disponible o no cuentas con los permisos.') + return res + +class Sistemas_xCliente_IMMEX_CreateView(UserPassesTestMixin,LoginRequiredMixin,CreateView): + model = Sistemas_por_cliente_A24 + fields = ['id_sistema', 'cliente', 'num_licencias'] + template_name = 'IMMEX/xclientes/sistema_create_IMMEX.html' + success_url = reverse_lazy('sistemasXcli_IMMEX') + def test_func(self): + res = self.request.user.groups.filter(name= 'admin_soft') + if not res: + messages.error(self.request, 'Lo sentimos. La página que buscas no está disponible o no cuentas con los permisos.') + return res + +class ClientesIMMEX_CreateView(CreateView): + model = ClientesA24 + form_class = ClienteForm_IMMEX + success_url = '/IMMEX/' + template_name = 'IMMEX/xclientes/edit_cliente.html' + def form_valid(self, form): + + response = super().form_valid(form) + if self.request.headers.get('X-Requested-With') == 'XMLHttpRequest': + data={ + 'id':self.object.id, + 'RFC':self.object.RFC, + 'Nombre':self.object.Nombre, + 'Activo':self.object.Activo, + } + return JsonResponse(data) + else: + return response + + def form_invalid(self,form): + response = super().form_invalid(form) + if self.request.headers.get('X-Requested-With') == 'XMLHttpRequest': + errors = form.errors.as_text() + return JsonResponse({'errors':f'{errors}'},status=200,content_type='application/json') + else: + return response + +"""---------API VIEWS---------""" +class Check_IMMEX_RFC(APIView): + """Verifica que el cliente pueda Timbrar""" + permission_classes = (IsAuthenticated,ItsAdminToken,) + + def post(self,request,*args, **kwargs): + rfc= request.data.get('RFC') + try: + clienteA24 , created = ClientesA24.objects.get_or_create(RFC=rfc) + serializer = ClientesA24Serailizer(clienteA24) + + if created: + clienteA24.Activo =True + clienteA24.Nombre = rfc + clienteA24.save() + if not serializer.is_valid: + return Response({'Error':f'{serializer.errors}','isError':True},status=200) + return Response(serializer.data) + except Exception as E: + return Response({'Error':f'check_RFC:{E} RFC:{rfc}','isError':True}) \ No newline at end of file diff --git a/Sistemas/urls.py b/Sistemas/urls.py index 777a246..281004c 100644 --- a/Sistemas/urls.py +++ b/Sistemas/urls.py @@ -17,12 +17,12 @@ from .views import ( CheckVersionView, UploadZipVersionView, Sistema_CreateView, + Custom_Login, #function download_version_FromServer, uploadZipViewHTML, - ) urlpatterns = [ path('',SistemasXCliente_ListView.as_view(),name='lista_sistmas'), @@ -39,4 +39,5 @@ urlpatterns = [ path('download_version_FromServer/',download_version_FromServer, name='downloadVersionFromServer'), path('uploadZip/', UploadZipVersionView.as_view(), name='uploadZip'), path('uploadZip2/', uploadZipViewHTML, name="uploadZipViewHTML"), + path('login/', Custom_Login.as_view(), name="Customlogin"), ] \ No newline at end of file diff --git a/Sistemas/views.py b/Sistemas/views.py index e863013..07705f9 100644 --- a/Sistemas/views.py +++ b/Sistemas/views.py @@ -15,6 +15,8 @@ from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated from rest_framework import status, permissions from django.contrib.auth.models import User +from django.contrib.auth import authenticate, login + from django.contrib import messages from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin @@ -221,6 +223,7 @@ class Sistema_CreateView(CreateView): ========================= API Views ''' + class GetDeviceToken(APIView): """Recobra el Token DRF del Device""" authentication_classes= [TokenAuthentication] @@ -344,3 +347,23 @@ class CheckVersionView(APIView): except Exception as ex: BitacoraErrores.objects.create(level=2, message=str(ex), traceback=traceback.format_exc(), view='Sistemas.CheckVersionView') return Response({'Error':f'{ex}','isError':True}) + + +class Custom_Login(APIView): + """Autentica al device""" + authentication_classes= [TokenAuthentication] + permissions_classes=[IsAuthenticated, HasAuthorizationHeader] + + def post(self, request): + username = request.data.get('username') + password = request.data.get('password') + try: + user = authenticate(request, username=username,password=password) + if user is not None: + login(request,user) + return Response({'access':True}) + else: + return Response({'access':False}) + except Exception as ex: + BitacoraErrores.objects.create(level=2, message=str(ex), traceback=traceback.format_exc(), view='Sistemas.Custom_Login') + return Response({'access':False}) \ No newline at end of file diff --git a/Templates/IMMEX/xclientes/edit_cliente.html b/Templates/IMMEX/xclientes/edit_cliente.html new file mode 100644 index 0000000..1a799c0 --- /dev/null +++ b/Templates/IMMEX/xclientes/edit_cliente.html @@ -0,0 +1,97 @@ +{% extends 'base.html' %} +{% load widget_tweaks %} + +{% block title %}Add Cliente IMMEX {% endblock title %} + +{% block content %} +
+ {% csrf_token %} +
+ + {% render_field form.RFC id+="add" id+=form.RFC.name placeholder=form.RFC.label class="form-control" type="text" autocomplete="off" %} +
+
+ + {% render_field form.Nombre id+="add" id+=form.Nombre.name placeholder=form.Nombre.label class="form-control" type="text" autocomplete="off" %} +
+ +
+ {% render_field form.Activo class+="form-checkbox" type="checkbox" %} + +
+
+ {% render_field form.fecha_baja.label %} + {% render_field form.fecha_baja placeholder=form.fecha_baja.label class+="form-control" type="date" %} +
+ +
+{% endblock content %} + + +{% block scripts %} + +{% endblock scripts %} + \ No newline at end of file diff --git a/Templates/IMMEX/xclientes/lista.html b/Templates/IMMEX/xclientes/lista.html new file mode 100644 index 0000000..1846741 --- /dev/null +++ b/Templates/IMMEX/xclientes/lista.html @@ -0,0 +1,35 @@ +{% extends "base.html" %} + + +{% block title %} + Sistemas Clientes IMMEX +{% endblock title %} + + + +{% block content %} + + + + + + + + + + + + + {% for row in object_list %} + + + + + + + + {% endfor %} + +
#SistemaClienteNo. LicenciasAgregar Sistema por cliente
{{row.id}}{{row.id_sistema}}{{row.cliente}}{{row.num_licencias}}Detalles
+{% endblock content %} + diff --git a/Templates/IMMEX/xclientes/sistema_create_IMMEX.html b/Templates/IMMEX/xclientes/sistema_create_IMMEX.html new file mode 100644 index 0000000..1fd1efa --- /dev/null +++ b/Templates/IMMEX/xclientes/sistema_create_IMMEX.html @@ -0,0 +1,121 @@ +{% extends 'base.html' %} + + +{% block content %} +

Create a new Sistema IMMEX por cliente

+
+ + {% csrf_token %} + {% if form.non_field_errors %} + + {% endif %} +
+
+
+ {{ form.id_sistema.label }} + {{ form.id_sistema }} + + {% if form.id_sistema.errors %} +
    + {% for error in form.id_sistema.errors %} +
  • {{ error }}
  • + {% endfor %} +
+ {% endif %} +
+
+ +
+ {{ form.cliente.label}} + {{ form.cliente }} + + {% if form.cliente.errors %} +
    + {% for error in form.cliente.errors %} +
  • {{ error }}
  • + {% endfor %} +
+ {% endif %} +
+ +
+ {{ form.num_licencias.label }} + {{ form.num_licencias }} + {% if form.num_licencias.errors %} +
    + {% for error in form.num_licencias.errors %} +
  • {{ error }}
  • + {% endfor %} +
+ {% endif %} +
+ + +
+
+{% endblock content %} + + +{% block scripts %} + +{% endblock scripts %} + \ No newline at end of file diff --git a/Templates/IMMEX/xclientes/sistema_create_from.html b/Templates/IMMEX/xclientes/sistema_create_from.html new file mode 100644 index 0000000..e69de29 diff --git a/Templates/sidebar.html b/Templates/sidebar.html index 8f80a76..2833abf 100644 --- a/Templates/sidebar.html +++ b/Templates/sidebar.html @@ -1,14 +1,16 @@ +{% with request_path=request.path|slice:'/' %} + + \ No newline at end of file + +{% endwith%} \ No newline at end of file