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.contrib import messages from django.http import HttpResponse,JsonResponse from django.contrib.auth.decorators import login_required from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.db.models import Q from django.views.generic.edit import CreateView,UpdateView from django.views.generic.list import ListView 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 .serailizers import ClienteSerializer from .forms import ClienteForm,EmailForm from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated from rest_framework import status #EXCEL from openpyxl import Workbook from openpyxl.styles import Alignment, Border, Font, PatternFill, Side #email from django.core.mail import EmailMessage from django.conf import settings from io import BytesIO def read_env_file(): try: #env_file = os.listdir(settings.BASE_DIR) storage = FileSystemStorage(location=settings.BASE_DIR) env_file= os.path.join(settings.BASE_DIR,'.env') lista =['asds', 'asdasd','sss','com' ,'pol.com'] if storage.exists(env_file): with open(env_file, 'r') as file: data = file.read() data =re.findall('"([^"]*)"',data) for x in lista: data.append(x) res= ' '.join(data) final = '"'+res+'"' with open(env_file, 'w') as newFile: newFile.write("export hosts="+final) except: pass @sync_to_async(thread_sensitive=False) @login_required @is_staff_access() def send_timbres_Email(request): req = request.method if req == "POST": form = EmailForm(request.POST, request.FILES) if not form.is_valid(): messages.add_message(request, messages.ERROR, f'{form.errors}') return redirect('index') today = datetime.date.today() year = today.year RFC = request.GET.get('RFC', None) if req=='GET' else form.cleaned_data["RFC"] mes = request.GET.get('mes', None) if req=='GET' else form.cleaned_data["mes"] if mes is None or mes =='None': mes = today.month Cli = Clientes.objects.get(RFC=RFC) subject = f'Timbres del Mes:{mes} RFC:{RFC}' if req=='GET' else ( form.cleaned_data["subject"] if 'subject' in form.cleaned_data.keys() else '' ) message = 'Envio de timbres por AS_Admin' if req=='GET' else ( form.cleaned_data["message"] if 'message' in form.cleaned_data.keys() else '' ) if req=='POST': email = form.cleaned_data["email"] if 'email' in form.cleaned_data.keys() else '' emails = [Cli.email] if req=='GET' else [ Cli.email, email ] if len(emails) ==0 : messages.add_message(request, messages.ERROR, f'La lista de correos esta vacia, favor de agregar un correo.') return redirect('index') 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) if mes is not None and RFC is not None: objeto_a_trabajar = Timbres.objects.filter(rfcc=RFC, created_at__range=[dat,findate]) else: objeto_a_trabajar = Clientes.objects.all() for i,ii in enumerate(objeto_a_trabajar): ii.timbres_X_MES(mes=mes ) wb = Workbook() ws = wb.active if RFC is not None: #Encabezado ws['A1']='RFC_EXPEDIDO' ws['B1']='UUID' ws['C1']='Fecha' for q,qq in enumerate(objeto_a_trabajar,start=2): ws['A' + str(q)] = qq.rfcc ws['B'+ str(q)] = qq.uuid ws['C'+ str(q)] = qq.fecha else:#cuando no es pro RFC y es para contabilizar los timbres del mes de cada cliente ws['A1']='RFC_EXPEDIDO' ws['B1']='Nombre' ws['C1']='Timbres' for q,qq in enumerate(objeto_a_trabajar,start=2): ws['A' + str(q)] = qq.RFC ws['B'+ str(q)] = qq.Nombre ws['C'+ str(q)] = qq.conteo_mes nombre_archivo = f"Timbres_{RFC if RFC is not None else 'Clientes_MES'}_{str(mes)}_AÑO_{str(year)}.xlsx" response = HttpResponse(content_type="application/ms-excel") contenido = "attachment; filename = {0}".format(nombre_archivo) response["Content-Disposition"] = contenido wb.save(response) files = BytesIO(response.content) try: mail = EmailMessage(subject,message,settings.EMAIL_HOST_USER,emails) mail.attach(filename='Timbres.xls',content=files.getbuffer(),mimetype='application/vnd.ms-excel') adjunto = request.FILES.getlist('adjunto') if req=='POST' and len(adjunto) >0: total = functools.reduce(lambda a, b: a+b,[adj.size for adj in adjunto]) total += files.getbuffer().nbytes if total > 2.5e+7: messages.add_message(request, messages.ERROR, f'Se excedio el limite de 25 MegaBytes para los adjuntos') return redirect('index') try: for adj in adjunto: mail.attach(filename=adj.name,content=adj.read(),mimetype=adj.content_type) except Exception as E: messages.add_message(request, messages.ERROR, f'Error Adjuntos {E}') return redirect('index') mail.send() messages.success(request, 'Email Enviado correctamente.') except Exception as E: messages.error(request, f'Email no se envio correctamente.{E}') return redirect('index') @login_required def index(request): #read_env_file() clientes_list = Clientes.objects.all() PAC = request.GET.get('PAC',None) mes = request.GET.get('mes', None) today = datetime.date.today() year = request.GET.get('year',None) if year is None or year =='None': year= today.year if mes is None or mes =='None': mes = today.month page = request.GET.get('page', 1) search = request.GET.get('search',None) rfcc = request.GET.get('rfcc', None) filters = {key:value[0] for (key,value) in dict(request.GET).items() if value !=[""] or value!=None} filters.pop('page', '') filters.pop('datepicker','') filters.pop('datepickerFin','') filters.pop('mes','') filters.pop('year','') if PAC=='00': filters.pop('PAC') PAC=None if rfcc and search: clientes_list = Clientes.objects.filter(Q(RFC__icontains=search)) met = iter(clientes_list) while met: try: c = next(met) c.timbres_X_MES(mes=mes,year=year, PAC=PAC) except StopIteration: break clientes_list =pageFunc(page,clientes_list,20) context = { 'lista':clientes_list, 'mes':mes, 'year':year, 'filters':filters, 'emailForm':EmailForm(), } return render(request,'Clientes/index.html',context) def pageFunc(page,qs,per_page): paginator = Paginator(qs,per_page) try: qs = paginator.page(page) except PageNotAnInteger: qs = Paginator.page(1) except EmptyPage: qs = paginator.page(paginator.num_pages) return qs @login_required @is_staff_access() def timbres_cliente(request, RFC): if request.user.is_staff: lista = Timbres.objects.filter(rfcc=RFC) else: lista = Timbres.objects.filter(rfcc=RFC,modo='Normal') mes = request.GET.get('mes', None) year = request.GET.get('year',None) if year is None or year=='': today= datetime.date.today() year =today.year search = request.GET.get('search',None) page = request.GET.get('page', 1) datepicker = request.GET.get('datepicker', None) datepickerFin = request.GET.get('datepickerFin', None) tipo = request.GET.get('tipo',None) PAC= request.GET.get('PAC',None) if PAC is not None and PAC !='00': lista = lista.filter(rfcp=PAC) filters = {key:value[0] for (key,value) in dict(request.GET).items() if value !=[""]} filters.pop('page', '') if 'PAC' not in filters: filters['PAC']='00' if 'mes' not in filters: filters['mes']='00' if tipo and search is not None: lista = lista.filter(Q(tipo__icontains=search)) if datepicker and datepickerFin: # inicio = [int(i) for i in datepicker.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("-")] #start = datetime.datetime(inicio[2],inicio[0],inicio[1]) start = datetime.datetime(inicio[0],inicio[1],inicio[2]) start += datetime.timedelta(days=0) # end = datetime.datetime(fin[2],fin[0],fin[1]) end = datetime.datetime(fin[0],fin[1],fin[2]) end += datetime.timedelta(days=1) lista = lista.filter(created_at__range=[start, end]) if mes is None or mes =='None' or mes=='': mes='00' #Todos 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]) else: lista = lista.filter(created_at__year=int(year)) conteo = lista.count() lista =pageFunc(page,lista,50) context ={ 'lista':lista, 'conteo':conteo, 'RFC':RFC, 'PAC':PAC, 'filters':filters } return render(request, 'Clientes/timbres_cliente.html', context) @sync_to_async(thread_sensitive=False) @login_required @is_staff_access() def export_Excel(request): RFC = request.GET.get('RFC', None) mes = request.GET.get('mes',None) today = datetime.date.today() month = today.month year = today.year if mes is None or mes =='None' or mes=='': mes = month 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) if mes is not None and RFC is not None: objeto_a_trabajar = Timbres.objects.filter(rfcc=RFC, created_at__range=[dat,findate]) else: objeto_a_trabajar = Clientes.objects.all() for i,ii in enumerate(objeto_a_trabajar): ii.timbres_X_MES(mes=mes ) wb = Workbook() ws = wb.active if RFC is not None: #Encabezado ws['A1']='RFC_EXPEDIDO' ws['B1']='UUID' ws['C1']='Fecha' for q,qq in enumerate(objeto_a_trabajar,start=2): ws['A' + str(q)] = qq.rfcc ws['B'+ str(q)] = qq.uuid ws['C'+ str(q)] = qq.fecha else:#cuando no es pro RFC y es para contabilizar los timbres del mes de cada cliente ws['A1']='RFC_EXPEDIDO' ws['B1']='Nombre' ws['C1']='Timbres' for q,qq in enumerate(objeto_a_trabajar,start=2): ws['A' + str(q)] = qq.RFC ws['B'+ str(q)] = qq.Nombre ws['C'+ str(q)] = qq.conteo_mes nombre_archivo = f"Timbres_{RFC if RFC is not None else 'Clientes_MES'}_{str(mes)}_AÑO_{str(year)}.xlsx" response = HttpResponse(content_type="application/ms-excel") contenido = "attachment; filename = {0}".format(nombre_archivo) response["Content-Disposition"] = contenido wb.save( 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}) @login_required #@is_staff_access() def PACS_Retrive_RFCS(request): timbres = {} status = 200 if request.method == 'GET': RFC= request.GET.get('RFC','') if RFC !='': timbres =list(Timbres.objects.values('rfcp').filter(rfcc__in=[RFC])) else: timbres =list(Timbres.objects.values('rfcp').filter(rfcp__isnull=False)) else: status=403 return JsonResponse({'PACS':timbres},status=status) #-----------------------------------API VIEWS #-------------------------------------------- class check_RFC(APIView): permission_classes = (IsAuthenticated,) def get(self,request): rfc = request.GET.get('RFC', None) try: cliente, created = Clientes.objects.get_or_create(RFC=rfc) serializer = ClienteSerializer(cliente) if created: cliente.Activo=True cliente.save() if not serializer.is_valid: return Response(serializer.errors,status=400) return Response(serializer.data) except Exception as E: return Response({'Error':f'check_RFC:{E} RFC:{rfc}','isError':True}) class add_timbre2(APIView): permission_classes = (IsAuthenticated,) def get(self,request): uuid= request.GET.get('uuid', None) rfcc= request.GET.get('rfcc', None) fecha=request.GET.get('fecha', None) folio=request.GET.get('folio', None) serie=request.GET.get('serie', None) tipo=request.GET.get('tipo', None) rfcp=request.GET.get('rfcp', None) modo=request.GET.get('modo', None) obj={'uuid':uuid,'rfcc':rfcc,'fecha':fecha,'folio':folio, 'serie':serie,'tipo':tipo,'rfcp':rfcp,'modo':modo } try: obj = Timbres.objects.create(**obj) return Response({'data':'ok'}) except Exception as e: obj = ErroresTimbres.objects.create( uuid=uuid, description=e, rfcc=rfcc, folio=folio, modo=modo ) return Response({'Error':f'{e}'}) class saldo_funct2(APIView): permission_classes =(IsAuthenticated,) def get(self, request): timbres = request.GET.get('num',None) try: Saldo = saldoModel.objects.first() Saldo.saldo=timbres Saldo.save() except: Saldo = saldoModel.objects.create(saldo=int(timbres)) Saldo.save() content = {'data':Saldo.saldo} return Response(content) class check_host(APIView): permission_classes = (IsAuthenticated,) def post(self,request, format=None): data = request.data return Response(data) #---------------------------CLASS BASED VIEWS #-------------------------------------------- class ErroresTimbresListView(LoginRequiredMixin,ListView): model = ErroresTimbres paginate_by = 100 template_name = 'Clientes/Errores_Timbres_list.html' class ClientesUpdateView(UserPassesTestMixin,LoginRequiredMixin,UpdateView): model= Clientes form_class=ClienteForm success_url='/' template_name='Clientes/edit_cliente.html' def test_func(self): res = self.request.user.groups.filter(name= 'admin_soft') if not res: messages.error(self.request, f'Lo sentimos. La página que buscas no está disponible, no cuentas con los permisos.') return res class ClientesCreateView(UserPassesTestMixin,LoginRequiredMixin,CreateView): model = Clientes form_class = ClienteForm success_url='/' template_name='Clientes/edit_cliente.html' def test_func(self): #self.request.user.groups.all() return self.request.user.groups.filter(name= 'admin_soft')