first of segunda

This commit is contained in:
fjrodriguez
2022-12-19 10:23:52 -06:00
parent 09d7edddd6
commit de06b3ab8b
10 changed files with 408 additions and 131 deletions

View File

@@ -9,21 +9,14 @@ import pytz
# Build paths inside the project like this: BASE_DIR / 'subdir'. # Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production # Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/ # See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret! # SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-5*mm&uf5zq@t6nrs_5z8-_qtyapm^3&yz^wqqkc_a!v(!ulj-^' SECRET_KEY = os.getenv("adminAS_KEY")
# SECURITY WARNING: don't run with debug turned on in production! # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False DEBUG = False
ALLOWED_HOSTS = ['*'] ALLOWED_HOSTS = ['*']
# Application definition # Application definition
INSTALLED_APPS = [ INSTALLED_APPS = [
'django.contrib.admin', 'django.contrib.admin',
'django.contrib.auth', 'django.contrib.auth',
@@ -57,9 +50,7 @@ MIDDLEWARE = [
'django.contrib.messages.middleware.MessageMiddleware', 'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
] ]
ROOT_URLCONF = 'Admin.urls' ROOT_URLCONF = 'Admin.urls'
TEMPLATES = [ TEMPLATES = [
{ {
'BACKEND': 'django.template.backends.django.DjangoTemplates', 'BACKEND': 'django.template.backends.django.DjangoTemplates',
@@ -118,15 +109,13 @@ EMAIL_USE_SSL=True
# Database # Database
# https://docs.djangoproject.com/en/4.1/ref/settings/#databases # https://docs.djangoproject.com/en/4.1/ref/settings/#databases
if DEBUG: if DEBUG:
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': 'django.db.backends.mysql', 'ENGINE': 'django.db.backends.mysql',
'NAME': 'cfdi_as', 'NAME': 'cfdi_as',
'USER': 'root', 'USER': 'root',
'PASSWORD': 'Soluciones28@', 'PASSWORD':os.getenv("BD_PASS"),
'HOST': '127.0.0.1', 'HOST': '127.0.0.1',
'PORT': '', 'PORT': '',
'OPTIONS': {'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"}, 'OPTIONS': {'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
@@ -138,7 +127,7 @@ else:
'ENGINE': 'django.db.backends.mysql', 'ENGINE': 'django.db.backends.mysql',
'NAME': 'fjrodriguez$cfdi_as', 'NAME': 'fjrodriguez$cfdi_as',
'USER': 'fjrodriguez', 'USER': 'fjrodriguez',
'PASSWORD': 'Soluciones28@', 'PASSWORD':os.getenv("BD_PASS"),
'HOST': 'fjrodriguez.mysql.pythonanywhere-services.com', 'HOST': 'fjrodriguez.mysql.pythonanywhere-services.com',
'PORT': '3306', 'PORT': '3306',
'OPTIONS': {'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"}, 'OPTIONS': {'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},

View File

@@ -1,9 +1,12 @@
from functools import wraps from functools import wraps
from django.contrib import messages from django.contrib import messages
from django.shortcuts import redirect from django.shortcuts import redirect
from django.http import HttpResponse from django.http import HttpResponse, JsonResponse
from django.contrib.auth import authenticate, login
from rest_framework.authtoken.models import Token
from django.contrib.auth.models import User
import base64
from django.shortcuts import get_object_or_404
def Custom_is_staff_function(user): def Custom_is_staff_function(user):
if user.is_staff: if user.is_staff:
return True return True
@@ -20,3 +23,37 @@ def is_staff_access(view_to_return="index"):
return view(request, *args, **kwargs) return view(request, *args, **kwargs)
return _wrapped_view return _wrapped_view
return decorator return decorator
#--------------------Auth basica
def auth_basic(request,*args, **kwargs):
if request.META['CONTENT_TYPE'] == 'application/json' and 'HTTP_AUTHORIZATION' in request.META.keys():
authmeth, auth = request.META['HTTP_AUTHORIZATION'].split(' ', 1)
if authmeth.lower() == 'token':
tokenA,user = auth.split(':', 1)
user = base64.b64decode(user)
user = user.decode('utf-8')
token = get_object_or_404(Token, key=tokenA)
if token and str(token.user)==user:
return True
#user= authenticate(username=token.user, password=pwd)
# print('user.is_authenticated',user.is_authenticated)
#if user.is_authenticated:
# return True
else:
return False
return False
elif request.META['CONTENT_TYPE'] == 'application/json' and 'HTTP_AUTHORIZATION' not in request.META.keys():
return request.user.is_authenticated
else:
return False
def http_basic_auth():
def decorator(view):
@wraps(view)
def _wrapped_view(request,*args, **kwargs):
if not auth_basic(request,*args, **kwargs):
return JsonResponse({'Error':'las credenciales Token:user(base64) son incorrectas.'},status=401)
return view(request, *args, **kwargs)
return _wrapped_view
return decorator

View File

@@ -41,10 +41,8 @@ class Clientes(models.Model):
email = models.EmailField(max_length=254, blank=True) email = models.EmailField(max_length=254, blank=True)
conteo_mes = models.IntegerField(blank=True,null=True,default=0) conteo_mes = models.IntegerField(blank=True,null=True,default=0)
def timbres_X_MES(self, mes): def timbres_X_MES(self, mes):
today = datetime.date.today() today = datetime.date.today()
year = today.year year = today.year
if mes==None: if mes==None:
mes = today.month mes = today.month
dat = datetime.datetime(int(year),int(mes),1) dat = datetime.datetime(int(year),int(mes),1)
@@ -52,7 +50,6 @@ class Clientes(models.Model):
findate = dat + datetime.timedelta(days=30) findate = dat + datetime.timedelta(days=30)
#findate += datetime.timedelta(days=0) #findate += datetime.timedelta(days=0)
elif dat.month in (4,6,9,11):#30 elif dat.month in (4,6,9,11):#30
findate = dat + datetime.timedelta(days=29) findate = dat + datetime.timedelta(days=29)
#findate += datetime.timedelta(days=0) #findate += datetime.timedelta(days=0)
else:#28 or 29 else:#28 or 29
@@ -60,13 +57,11 @@ class Clientes(models.Model):
findate += datetime.timedelta(days=1) findate += datetime.timedelta(days=1)
#print(f'dat {(dat)} fdate={findate}') #print(f'dat {(dat)} fdate={findate}')
cou = Timbres.objects.filter(rfcc=self.RFC, created_at__range=[dat,findate]).count() cou = Timbres.objects.filter(rfcc=self.RFC, created_at__range=[dat,findate]).count()
self.conteo_mes =cou self.conteo_mes =cou
self.save() self.save()
return cou return cou
@property @property
def timbres_mes_count(self): def timbres_mes_count(self):
today = datetime.date.today() today = datetime.date.today()
month = today.month month = today.month
year = today.year year = today.year

View File

@@ -6,6 +6,8 @@ from .views import (
ClientesCreateView, ClientesCreateView,
export_Excel, export_Excel,
send_timbres_Email, send_timbres_Email,
Retrive_Cliente_Email,
PACS_Retrive_RFCS,
#API DRF #API DRF
saldo_funct2, saldo_funct2,
@@ -25,5 +27,6 @@ urlpatterns = [
path('getActivoRFC/', check_RFC.as_view(), name='check_active_RFC'), path('getActivoRFC/', check_RFC.as_view(), name='check_active_RFC'),
path('get_saldo2/', saldo_funct2.as_view(), name='saldo_funct2'), path('get_saldo2/', saldo_funct2.as_view(), name='saldo_funct2'),
path('check_host/',check_host.as_view(),name='check_host'), path('check_host/',check_host.as_view(),name='check_host'),
path('emails_cliente/',Retrive_Cliente_Email, name='Retrive_Cliente_Email'),
path('pacs/list/',PACS_Retrive_RFCS,name='PACS_Retrive_RFCS'),
] ]

View File

@@ -1,26 +1,29 @@
import os
import re
import datetime
import functools
from asgiref.sync import sync_to_async
from django.conf import settings
from django.core.files.storage import FileSystemStorage
from django.shortcuts import render,redirect from django.shortcuts import render,redirect
from django.contrib import messages from django.contrib import messages
from django.http import HttpResponse from django.http import HttpResponse,JsonResponse
from django.http import JsonResponse
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from .custom_decorators import is_staff_access from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.db.models import Q
from django.views.generic.edit import CreateView,UpdateView
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from .custom_decorators import is_staff_access, http_basic_auth
from .models import Clientes,Timbres,saldoModel,ErroresTimbres from .models import Clientes,Timbres,saldoModel,ErroresTimbres
from .serailizers import ClienteSerializer
from .forms import ClienteForm,EmailForm
from rest_framework.views import APIView from rest_framework.views import APIView
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated from rest_framework.permissions import IsAuthenticated
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.db.models import Q
import datetime
from django.views.generic.edit import CreateView,UpdateView
from .forms import ClienteForm,EmailForm
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.mixins import UserPassesTestMixin
from asgiref.sync import sync_to_async
from django.shortcuts import get_object_or_404
from .serailizers import ClienteSerializer
#EXCEL #EXCEL
from openpyxl import Workbook from openpyxl import Workbook
from openpyxl.styles import Alignment, Border, Font, PatternFill, Side from openpyxl.styles import Alignment, Border, Font, PatternFill, Side
@@ -29,12 +32,6 @@ from openpyxl.styles import Alignment, Border, Font, PatternFill, Side
from django.core.mail import EmailMessage from django.core.mail import EmailMessage
from django.conf import settings from django.conf import settings
from io import BytesIO from io import BytesIO
import functools
from django.core.files.storage import FileSystemStorage
import os
from django.conf import settings
import re
def read_env_file(): def read_env_file():
try: try:
@@ -62,6 +59,7 @@ def read_env_file():
@sync_to_async(thread_sensitive=False) @sync_to_async(thread_sensitive=False)
@login_required @login_required
@is_staff_access()
def send_timbres_Email(request): def send_timbres_Email(request):
req = request.method req = request.method
@@ -71,6 +69,7 @@ def send_timbres_Email(request):
messages.add_message(request, messages.ERROR, f'{form.errors}') messages.add_message(request, messages.ERROR, f'{form.errors}')
return redirect('index') return redirect('index')
today = datetime.date.today() today = datetime.date.today()
year = today.year year = today.year
RFC = request.GET.get('RFC', None) if req=='GET' else form.cleaned_data["RFC"] RFC = request.GET.get('RFC', None) if req=='GET' else form.cleaned_data["RFC"]
@@ -98,7 +97,7 @@ def send_timbres_Email(request):
else: else:
findate = dat+datetime.timedelta(days=28) findate = dat+datetime.timedelta(days=28)
findate +=datetime.timedelta(days=1) findate +=datetime.timedelta(days=1)
print(f'dat{dat} findate:{findate}') #print(f'dat{dat} findate:{findate}')
if mes is not None and RFC is not None: if mes is not None and RFC is not None:
objeto_a_trabajar = Timbres.objects.filter(rfcc=RFC, created_at__range=[dat,findate]) objeto_a_trabajar = Timbres.objects.filter(rfcc=RFC, created_at__range=[dat,findate])
else: else:
@@ -163,6 +162,9 @@ def index(request):
#read_env_file() #read_env_file()
clientes_list = Clientes.objects.all() clientes_list = Clientes.objects.all()
mes = request.GET.get('mes', None) mes = request.GET.get('mes', None)
today = datetime.date.today()
if mes is None or mes =='None':
mes = today.month
page = request.GET.get('page', 1) page = request.GET.get('page', 1)
search = request.GET.get('search',None) search = request.GET.get('search',None)
rfcc = request.GET.get('rfcc', None) rfcc = request.GET.get('rfcc', None)
@@ -170,6 +172,7 @@ def index(request):
filters.pop('page', '') filters.pop('page', '')
filters.pop('datepicker','') filters.pop('datepicker','')
filters.pop('datepickerFin','') filters.pop('datepickerFin','')
filters.pop('mes','')
print('filters------',filters) print('filters------',filters)
if rfcc: if rfcc:
clientes_list = Clientes.objects.filter(Q(RFC__icontains=search)) clientes_list = Clientes.objects.filter(Q(RFC__icontains=search))
@@ -177,13 +180,11 @@ def index(request):
ii.timbres_X_MES(mes=mes) ii.timbres_X_MES(mes=mes)
clientes_list =pageFunc(page,clientes_list,20) clientes_list =pageFunc(page,clientes_list,20)
filters.pop('mes','')
context = { context = {
'lista':clientes_list, 'lista':clientes_list,
'mes':mes, 'mes':mes,
'filters':filters, 'filters':filters,
'emailForm':EmailForm(), 'emailForm':EmailForm(),
} }
return render(request,'Clientes/index.html',context) return render(request,'Clientes/index.html',context)
@@ -202,16 +203,33 @@ def pageFunc(page,qs,per_page):
@login_required @login_required
@is_staff_access() @is_staff_access()
def timbres_cliente(request, RFC): def timbres_cliente(request, RFC):
if request.user.is_staff: if request.user.is_staff:
lista = Timbres.objects.filter(rfcc=RFC) lista = Timbres.objects.filter(rfcc=RFC)
else: else:
lista = Timbres.objects.filter(rfcc=RFC,modo='Normal') lista = Timbres.objects.filter(rfcc=RFC,modo='Normal')
mes = request.GET.get('mes', None)
today= datetime.date.today()
year =today.year
if mes is None or mes =='None':
mes='00' #Todos
PAC= request.GET.get('PAC',None) PAC= request.GET.get('PAC',None)
if PAC=='01': # if PAC !="00" or PAC !="None":
lista = lista.filter(rfcp='EME000602QR9') # lista = lista.filter(rfcp=str(PAC))
if PAC=='02': # else:
lista = lista.exclude(rfcp='EME000602QR9') # lista = Timbres.objects.filter(rfcc=str(RFC))
#print(f'{PAC} filter pro pac',lista.count(), lista)
if PAC is not None and PAC !='00':
lista = lista.filter(rfcp=PAC)
search = request.GET.get('search',None) search = request.GET.get('search',None)
page = request.GET.get('page', 1) page = request.GET.get('page', 1)
datepicker = request.GET.get('datepicker', None) datepicker = request.GET.get('datepicker', None)
@@ -219,30 +237,49 @@ def timbres_cliente(request, RFC):
tipo = request.GET.get('tipo',None) tipo = request.GET.get('tipo',None)
filters = {key:value[0] for (key,value) in dict(request.GET).items() if value !=[""]} filters = {key:value[0] for (key,value) in dict(request.GET).items() if value !=[""]}
filters.pop('page', '') filters.pop('page', '')
filters.pop('PAC', '') if 'PAC' not in filters:
filters['PAC']='00'
if 'mes' not in filters:
filters['mes']='00'
if tipo and search is not None:
if tipo:
lista = lista.filter(Q(tipo__icontains=search)) lista = lista.filter(Q(tipo__icontains=search))
if datepicker and datepickerFin: if datepicker and datepickerFin:
inicio = [int(i) for i in datepicker.split("/")] # inicio = [int(i) for i in datepicker.split("/")]
fin = [int(i) for i in datepickerFin.split("/")] # fin = [int(i) for i in datepickerFin.split("/")]
inicio = [int(i) for i in datepicker.split("-")]
fin = [int(i) for i in datepickerFin.split("-")]
#print('inicio',inicio,' fin',fin) #print('inicio',inicio,' fin',fin)
#start = datetime.datetime(inicio[2],inicio[0],inicio[1])
start = datetime.datetime(inicio[0],inicio[1],inicio[2])
start = datetime.datetime(inicio[2],inicio[0],inicio[1])
start += datetime.timedelta(days=0) start += datetime.timedelta(days=0)
end = datetime.datetime(fin[2],fin[0],fin[1]) # end = datetime.datetime(fin[2],fin[0],fin[1])
end = datetime.datetime(fin[0],fin[1],fin[2])
end += datetime.timedelta(days=1) end += datetime.timedelta(days=1)
#datetime.date.today()
#print('FECHA',datetime.datetime.today(), 'HORA') #print('start',start, 'end',end)
print('start',start, 'end',end)
lista = lista.filter(created_at__range=[start, end]) lista = lista.filter(created_at__range=[start, end])
conteo = lista.count() if mes != '00':
dat = datetime.datetime(int(year), int(mes),1)
if dat.month in(1,3,5,7,8,10,12):
findate = dat +datetime.timedelta(days=30)
elif dat.month in (4,6,9,11):
findate = dat+datetime.timedelta(days=29)
else:
findate = dat+datetime.timedelta(days=28)
findate +=datetime.timedelta(days=1)
lista = lista.filter(created_at__range=[dat,findate])
conteo = lista.count()
print('conteo',conteo)
lista =pageFunc(page,lista,50) lista =pageFunc(page,lista,50)
context ={ context ={
@@ -256,6 +293,7 @@ def timbres_cliente(request, RFC):
@sync_to_async(thread_sensitive=False) @sync_to_async(thread_sensitive=False)
@login_required @login_required
@is_staff_access()
def export_Excel(request): def export_Excel(request):
RFC = request.GET.get('RFC', None) RFC = request.GET.get('RFC', None)
@@ -285,8 +323,6 @@ def export_Excel(request):
for i,ii in enumerate(objeto_a_trabajar): for i,ii in enumerate(objeto_a_trabajar):
ii.timbres_X_MES(mes=mes ) ii.timbres_X_MES(mes=mes )
wb = Workbook() wb = Workbook()
ws = wb.active ws = wb.active
@@ -312,10 +348,22 @@ def export_Excel(request):
contenido = "attachment; filename = {0}".format(nombre_archivo) contenido = "attachment; filename = {0}".format(nombre_archivo)
response["Content-Disposition"] = contenido response["Content-Disposition"] = contenido
wb.save( response) wb.save( response)
return response return response
@http_basic_auth()
def Retrive_Cliente_Email(request):
if request.method == 'GET':
clientes = list(Clientes.objects.values('email').filter(RFC=request.GET.get('RFC',None)))
return JsonResponse({'data':clientes})
def PACS_Retrive_RFCS(request):
status = 302
timbres = {}
if request.method == 'GET':
timbres =list(Timbres.objects.values('rfcp').filter(rfcp__isnull=False))
return JsonResponse({'PACS':timbres},status=status)
#-----------------------------------API VIEWS #-----------------------------------API VIEWS
#-------------------------------------------- #--------------------------------------------
class check_RFC(APIView): class check_RFC(APIView):
@@ -326,7 +374,6 @@ class check_RFC(APIView):
if created: if created:
cliente.Activo=True cliente.Activo=True
cliente.save() cliente.save()
#cliente = get_object_or_404(Clientes, RFC=rfc)
serializer = ClienteSerializer(cliente) serializer = ClienteSerializer(cliente)
return Response(serializer.data) return Response(serializer.data)
@@ -342,7 +389,6 @@ class add_timbre2(APIView):
tipo=request.GET.get('tipo', None) tipo=request.GET.get('tipo', None)
rfcp=request.GET.get('rfcp', None) rfcp=request.GET.get('rfcp', None)
modo=request.GET.get('modo', None) modo=request.GET.get('modo', None)
obj={ obj={
'uuid':uuid, 'uuid':uuid,
'rfcc':rfcc, 'rfcc':rfcc,
@@ -382,7 +428,6 @@ class saldo_funct2(APIView):
class check_host(APIView): class check_host(APIView):
permission_classes = (IsAuthenticated,) permission_classes = (IsAuthenticated,)
def post(self,request, format=None): def post(self,request, format=None):
data = request.data data = request.data
print(data) print(data)
@@ -397,13 +442,11 @@ class ClientesUpdateView(UserPassesTestMixin,LoginRequiredMixin,UpdateView):
template_name='Clientes/edit_cliente.html' template_name='Clientes/edit_cliente.html'
def test_func(self): def test_func(self):
res = self.request.user.groups.filter(name= 'admin_soft') res = self.request.user.groups.filter(name= 'admin_soft')
if not res: if not res:
messages.error(self.request, f'Lo sentimos. La página que buscas no está disponible, no cuentas con los permisos.') messages.error(self.request, f'Lo sentimos. La página que buscas no está disponible, no cuentas con los permisos.')
return res return res
class ClientesCreateView(UserPassesTestMixin,LoginRequiredMixin,CreateView): class ClientesCreateView(UserPassesTestMixin,LoginRequiredMixin,CreateView):
model = Clientes model = Clientes
form_class = ClienteForm form_class = ClienteForm

View File

@@ -119,7 +119,7 @@ Timbres disponibles Comercio Digital: {{saldo}}
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<!-- Button trigger modal --> <!-- Button trigger modal -->
<button class="btn btn-primary w-100" onclick="addValues('{{obj.RFC}}')" type="button" data-toggle="modal" data-target="#exampleModalCenter"> <button class="btn btn-primary w-100" onclick="addValues('{{obj.RFC}}'); retriveEmails('{{obj.RFC}}');" type="button" data-toggle="modal" data-target="#exampleModalCenter">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-envelope-plus" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-envelope-plus" viewBox="0 0 16 16">
<path d="M2 2a2 2 0 0 0-2 2v8.01A2 2 0 0 0 2 14h5.5a.5.5 0 0 0 0-1H2a1 1 0 0 1-.966-.741l5.64-3.471L8 9.583l7-4.2V8.5a.5.5 0 0 0 1 0V4a2 2 0 0 0-2-2H2Zm3.708 6.208L1 11.105V5.383l4.708 2.825ZM1 4.217V4a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v.217l-7 4.2-7-4.2Z"/> <path d="M2 2a2 2 0 0 0-2 2v8.01A2 2 0 0 0 2 14h5.5a.5.5 0 0 0 0-1H2a1 1 0 0 1-.966-.741l5.64-3.471L8 9.583l7-4.2V8.5a.5.5 0 0 0 1 0V4a2 2 0 0 0-2-2H2Zm3.708 6.208L1 11.105V5.383l4.708 2.825ZM1 4.217V4a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v.217l-7 4.2-7-4.2Z"/>
<path d="M16 12.5a3.5 3.5 0 1 1-7 0 3.5 3.5 0 0 1 7 0Zm-3.5-2a.5.5 0 0 0-.5.5v1h-1a.5.5 0 0 0 0 1h1v1a.5.5 0 0 0 1 0v-1h1a.5.5 0 0 0 0-1h-1v-1a.5.5 0 0 0-.5-.5Z"/> <path d="M16 12.5a3.5 3.5 0 1 1-7 0 3.5 3.5 0 0 1 7 0Zm-3.5-2a.5.5 0 0 0-.5.5v1h-1a.5.5 0 0 0 0 1h1v1a.5.5 0 0 0 1 0v-1h1a.5.5 0 0 0 0-1h-1v-1a.5.5 0 0 0-.5-.5Z"/>
@@ -136,11 +136,13 @@ Timbres disponibles Comercio Digital: {{saldo}}
</tbody> </tbody>
</table> </table>
</div> </div>
<div id='id_filters' style="display: none;">{% for i,v in filters.items %}&{{i}}={{v}}{% endfor%}</div> <div id='id_filters' style="display: none;">{% for i,v in filters.items %}&{{i}}={{v}}{% endfor%}</div>
<!-- Modal -->
<!-- Modal EMAIL-->
<div class="modal fade" data-backdrop="static" id="exampleModalCenter" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true"> <div class="modal fade" data-backdrop="static" id="exampleModalCenter" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
<form enctype="multipart/form-data" id="id_form" action="{% url 'send_timbres_Email' %}" method="post"> <form enctype="multipart/form-data" id="id_form" action="{% url 'send_timbres_Email' %}?mes={{mes}}{% for i,v in filters.items %}&{{i}}={{v}}{% endfor%}" method="post">
{% csrf_token %} {% csrf_token %}
<div class="modal-dialog modal-dialog-centered" role="document"> <div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content"> <div class="modal-content">
@@ -153,7 +155,18 @@ Timbres disponibles Comercio Digital: {{saldo}}
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="form-group">
<label for="email"><strong>Email</strong></label> <label for="email"><strong>Email</strong></label>
<input type="email" name="email" id="email_add" autocomplete="off" class="form-control" placeholder="Email"> <!--input type="email" name="email" id="email_add" autocomplete="off" class="form-control" placeholder="Email"-->
<div class="input-group mb-3">
<input type="email" name="email" id="email_add" class="form-control" placeholder="Email" aria-label="Email" aria-describedby="button-addon2">
<div class="input-group-append">
<button class="btn btn-outline-secondary" type="button" data-toggle="modal" data-target="#exampleModalCenter2" id="button-addon2" >
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-search" viewBox="0 0 16 16">
<path d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z"/>
</svg>
</button>
</div>
</div>
</div> </div>
<div class="form-group"> <div class="form-group">
@@ -167,7 +180,7 @@ Timbres disponibles Comercio Digital: {{saldo}}
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="message"><strong>Message</strong></label> <label for="message"><strong>Message</strong></label>
<textarea name="message" cols="40" rows="10" id="message_add" autocomplete="off" class="form-control" placeholder="Message" ></textarea> <textarea name="message" cols="40" rows="10" id="message_add" autocomplete="off" class="form-control" placeholder="Message" required></textarea>
</div> </div>
<div hidden class="form-group"> <div hidden class="form-group">
<label for="RFC"><strong> Rfc </strong></label> <label for="RFC"><strong> Rfc </strong></label>
@@ -190,12 +203,94 @@ Timbres disponibles Comercio Digital: {{saldo}}
</div> </div>
</form> </form>
</div> </div>
<!-- Modal LISTA EMAILS-->
<div class="modal fade bd-example-modal-lg" id="exampleModalCenter2" tabindex="-1" role="contentinfo" aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalCenterTitle">Lista email</h5>
<button id="close_emails_list" type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="table-responsive">
<table id="email_list" class="table table-hover">
<thead>
<tr>
<th scope="col">EMAIL</th>
</tr>
</thead>
<tbody id="table_body" style="cursor: pointer;">
<!--This is a exaple append js rows structure---->
<!--tr class="table_row"><td id="1">@Mark</td></tr-->
</tbody>
</table>
</div>
</div>
<div class="modal-footer">
<h1>Footer</h1>
</div>
</div>
</div>
</div>
{% endblock content %} {% endblock content %}
{% block scripts %} {% block scripts %}
<script> <script>
function retriveEmails(RFC){
fetch(`{% url 'Retrive_Cliente_Email' %}?RFC=${RFC}`,{
method: 'GET',
headers: {
'Content-Type': 'application/json',
'X-Requested-With':'XMLHttpRequest',
},
credentials:"same-origin"
})
.then(res=>{
return res.json()
})
.then(data=>{
if(table_body.querySelectorAll('tr').length >0){
const table_rows = document.querySelectorAll('.table_row')
table_rows.forEach((rem)=>{
rem.remove()
})
}
const re = Object.values(data['data'])
re.forEach((val,index)=>{
console.log('val',val.email, index)
const row = document.createElement("tr")
row.setAttribute("class","table_row")
const cell = document.createElement("td")
cell.setAttribute("id",index)
const cellText = document.createTextNode(`${val.email}`)
cell.appendChild(cellText)
row.appendChild(cell)
table_body.appendChild(row)
})
email_list.appendChild(table_body)
const table_rows = document.querySelectorAll('.table_row')
table_rows.forEach((box)=>{
box.addEventListener('click',(event)=>{
email_add.value=event.target.textContent
close_emails_list.click()
})
})
})//.then(data)
}
let filters = document.getElementById('id_filters').textContent let filters = document.getElementById('id_filters').textContent
console.log(filters)
function aclick(event,RFC ,cuantos){ function aclick(event,RFC ,cuantos){
if( parseInt(cuantos)===0){ if( parseInt(cuantos)===0){
@@ -253,7 +348,7 @@ Timbres disponibles Comercio Digital: {{saldo}}
fsize = id_adjunto.files.item(i).size fsize = id_adjunto.files.item(i).size
fsize +=fsize; fsize +=fsize;
console.log(((fsize/1024)/1024))
if( 25 <= ((fsize/1024)/1024) ){ if( 25 <= ((fsize/1024)/1024) ){
alert('Limite excedido de 25 MegaBytes adjuntos'); alert('Limite excedido de 25 MegaBytes adjuntos');
id_adjunto.value='' id_adjunto.value=''
@@ -270,8 +365,9 @@ Timbres disponibles Comercio Digital: {{saldo}}
}) })
function addValues(RFC){ function addValues(RFC){
RFC_add.value = RFC RFC_add.value = RFC
console.log('RFC', RFC)
} }
</script> </script>

View File

@@ -25,20 +25,35 @@
<th scope="col"> <th scope="col">
PAC PAC
<select id="table_select_PAC" class="form-control form-control-sm"> <select id="table_select_PAC" class="form-control form-control-sm my_event_cls">
<option value="00">Todos</option> <option value="00">Todos</option>
<option value="01">EDICOM</option> <!--option value="01">EDICOM</option>
<option value="02">Comercio Dig.</option> <option value="02">Comercio Dig.</option-->
</select> </select>
</th> </th>
<th scope="col"> <th scope="col">
<input id="table_tipo" name="tipo" value="True" type="checkbox" class="form-check-input" > <input id="table_tipo" name="tipo" value="True" type="checkbox" class="form-check-input my_event_cls" >
Tipo CFDI Tipo CFDI
</th> </th>
<th scope="col">Serie/Folio</th> <th scope="col">Serie/Folio</th>
<th scope="col"> <th scope="col">
<input id="table_fecha" name="fecha" value="True" type="checkbox" class="form-check-input" > <input id="table_fecha" name="fecha" value="True" type="checkbox" class="form-check-input my_event_cls" >
Fecha Fecha
<select id="table_select_Meses" class="form-control form-control-sm my_event_cls">
<option value="00">Todos</option>
<option value="01">Enero</option>
<option value="02">Febrero</option>
<option value="03">Marzo</option>
<option value="04">Abril</option>
<option value="05">Mayo</option>
<option value="06">Junio</option>
<option value="07">Julio</option>
<option value="08">Agosto</option>
<option value="09">Septiembre</option>
<option value="10">Octubre</option>
<option value="11">Noviembre</option>
<option value="12">Diciembre</option>
</select>
</th> </th>
</tr> </tr>
</thead> </thead>
@@ -56,28 +71,124 @@
</tbody> </tbody>
</table> </table>
<div id='id_filters' style="display: None;">{% for i,v in filters.items %}&{{i}}={{v}}{% endfor%}</div> <div id='id_filters' style="display: none;">{% for i,v in filters.items %}&{{i}}={{v}}{% endfor%}</div>
{% endblock content %} {% endblock content %}
{% block scripts %} {% block scripts %}
<script> <script>
window.addEventListener("load", (event)=>{ function get_pacs(){
let PAC = '{{PAC}}' url = "{% url 'PACS_Retrive_RFCS' %}"
if(PAC !="None"){ fetch(url, {
table_select_PAC.value=PAC method: 'GET',
headers:{
'Content-Type':'application/json',
'X-Requested-With':'XMLHttpRequest',
},
credentials:"same-origin"
})
.then(res=>{
return res.json()
})
.then(data=>{
let arr = data['PACS']
let pacs = [...new Set(arr.map((arr)=> arr.rfcp) )]
pacs.forEach((val,index)=>{
let option = document.createElement('option')
option.value=val
option.text=val
table_select_PAC.add(option)
PAC.filter(val=>val.includes('PAC'))
.forEach((val,index)=>{
table_select_PAC.value = val.split('=')[1]
})
})
})
}
</script>
<!--end functions-->
<script>
let filters = document.getElementById('id_filters').textContent
let mes = Object.values(filters.split('&'))
let PAC = Object.values(filters.split('&'))
let tipo = Object.values(filters.split('&'))
let lsearch = Object.values(filters.split('&'))
let ldatepicker = Object.values(filters.split('&'))
let ldatepickerFin = Object.values(filters.split('&'))
let anc = document.getElementById('home_id')
let ref=''
mes.filter(val=> val.length >0)
.filter(val=>val.includes('mes'))
.forEach((val,index)=>{
table_select_Meses.value= val.split('=')[1]
})
tipo.filter(val=>val.includes('tipo'))
.forEach((val,index)=>{
table_tipo.checked= val.split('=')[1] ==='on' ?true:false
})
lsearch.filter(val=>val.includes('search'))
.forEach((val,index)=>{
search.value = val.split('=')[1]
})
ldatepicker.filter(val=>val.includes('datepicker'))
.forEach((val,index)=>{
datepicker.value=val.split('=')[1]
})
ldatepickerFin.filter(val=>val.includes('datepicker'))
.forEach((val,index)=>{
datepickerFin.value=val.split('=')[1]
})
window.addEventListener('load',event=>{
get_pacs()
})
document.querySelectorAll('.my_event_cls').forEach(item=>{
if(item.id==='datepicker' || item.id==='datepickerFin'){
item.addEventListener('focusout',event=>{
ref=`?PAC=${table_select_PAC.value}`
ref+=`&mes=${table_select_Meses.value}`
ref+=`&tipo=${table_tipo.checked}`
ref+=`&search=${search.value}`
ref+=`&datepicker=${datepicker.value}`
ref+=`&datepickerFin=${datepickerFin.value}`
})
}else{
item.addEventListener('change', event=>{
ref=`?PAC=${table_select_PAC.value}`
ref+=`&mes=${table_select_Meses.value}`
ref+=`&tipo=${table_tipo.checked}`
ref+=`&search=${search.value}`
ref+=`&datepicker=${datepicker.value}`
ref+=`&datepickerFin=${datepickerFin.value}`
})
} }
}) })
let filters = document.getElementById('id_filters').textContent
table_select_PAC.addEventListener('change',(event)=>{ table_select_PAC.addEventListener('change',(event)=>{
let anc = document.getElementById('home_id')
anc.href='' anc.href=''
let url = `?PAC=${event.target.value}${filters}` anc.href=ref
anc.href=url
anc.click() anc.click()
}) })
table_select_Meses.addEventListener('change',(event)=>{
anc.href=''
anc.href=ref
console.log(ref)
anc.click()
})
table_tipo.addEventListener('click', (event)=>{ table_tipo.addEventListener('click', (event)=>{
document.getElementById('tipo').checked = table_tipo.checked? true:false; document.getElementById('tipo').checked = table_tipo.checked? true:false;

View File

@@ -2,28 +2,31 @@
<span class="navbar-text mr-2"> <span class="navbar-text mr-2">
Fecha: <strong>{{fecha|date:"d F Y"}}</strong> Fecha: <strong>{{fecha|date:"d F Y"}}</strong>
</span> </span>
<form action="{{request.path}}" method="get" class="form-inline my-2 my-lg-0"> <form action="{{request.path}}" method="get" class="form-inline my-2 my-lg-0 my_event_cls">
<input style="display:none" id="mes_id" class="form-control mr-sm-2" name="mes" type="input" aria-label="mes">
<input id="search" class="form-control mr-sm-2" name="search" type="search" placeholder="Search" aria-label="Search"> <input style="display:none" id="mes_id" class="form-control mr-sm-2 my_event_cls" name="mes" type="input" aria-label="mes">
<input id="search" class="form-control mr-sm-2 my_event_cls" name="search" type="search" placeholder="Search" aria-label="Search">
<div class="form-group form-check"> <div class="form-group form-check">
<input style="display:none" name="rfcc" type="checkbox" class="form-check-input" id="rfcc"> <input style="display:none" name="rfcc" type="checkbox" class="form-check-input my_event_cls" id="rfcc">
</div> </div>
<div class="form-group form-check"> <div class="form-group form-check">
<input style="display:none" name="tipo" type="checkbox" class="form-check-input" id="tipo"> <input style="display:none" name="tipo" type="checkbox" class="form-check-input my_event_cls" id="tipo">
</div> </div>
<div id="dates" style="display:none;" class="group-form mr-2" > <div id="dates" style="display:none;" class="group-form mr-2" >
<input class="form-control sm-2" name ="datepicker" id="datepicker" placeholder="Initial Date" /> <input type="date" class="form-control sm-2 my_event_cls" name ="datepicker" id="datepicker" placeholder="Initial Date" />
<input class="form-control sm-2" name ="datepickerFin" id="datepickerFin" placeholder="End Date" /> <input type="date" class="form-control sm-2 my_event_cls" name ="datepickerFin" id="datepickerFin" placeholder="End Date" />
<script> <script>
/*
$('#datepicker').datepicker({ $('#datepicker').datepicker({
uiLibrary: 'bootstrap4' uiLibrary: 'bootstrap4'
}); });
$('#datepickerFin').datepicker({ $('#datepickerFin').datepicker({
uiLibrary: 'bootstrap4' uiLibrary: 'bootstrap4'
}); });*/
</script> </script>
</div> </div>
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button> <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>