from django.shortcuts import render, redirect, get_object_or_404 from django.urls import reverse_lazy, reverse from django.views import View from django.contrib import messages from datetime import datetime from django.contrib.auth.views import LogoutView, LoginView from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.decorators import login_required from django.contrib.auth import logout from django.conf import settings from django.http import HttpRequest, HttpResponse, QueryDict, HttpResponseRedirect, JsonResponse from django.template.loader import get_template from django.contrib.messages.views import SuccessMessageMixin from xhtml2pdf import pisa from django.contrib.staticfiles import finders from django.views.generic.edit import CreateView, UpdateView, DeleteView from django.views.generic import RedirectView from django.db.models import Sum, F from django.contrib.auth.models import User from .models import Unidad, Articulo, ArticuloUnidad, Comprobante , PruebaUnidad from .forms import FormUnidad, FormArticulo, FormEnvio, FormComprobante # vista de inventario class VistaInventario(LoginRequiredMixin,View): def get(self, request, *args, **kwargs): articulo = Articulo.objects.all() unidades = Unidad.objects.all().count() usuarios = User.objects.all().count() context = {'articulo':articulo, 'unidades':unidades, 'usuarios':usuarios} return render(request, 'articulos/index.html', context) class CrearArticulo(LoginRequiredMixin, CreateView): form_class = FormArticulo initial = {"key": "value"} template_name = "articulos/crear.html" def get(self, request, *args, **kwargs): form = self.form_class(initial=self.initial) context = {'formulario_articulo':form} return render(request, self.template_name, context) def post(self, request, *args, **kwargs): form =self.form_class(request.POST) if form.is_valid(): form.save() return redirect('articulos') else: messages.error(request, "esto es una prueba de falla") context = {"form": form} return render(request, self.template_name, context ) class EditarVista(LoginRequiredMixin, UpdateView): model = Articulo form_class = FormArticulo template_name = "articulos/editar.html" def get(self, request, *args, **kwargs): self.object = self.get_object() return super().get(request, self.template_name, *args, **kwargs) def get_initial(self): initial = super().get_initial() # initial['serial'] = self.object.serial return initial def form_valid(self, formulario_articulo): self.object = formulario_articulo.save() return redirect('articulos') @login_required def eliminar(request, id): try: articulo = Articulo.objects.get(id=id) articulo.delete() messages.success(request, "Registro eliminado correctamente.") except Articulo.DoesNotExist: messages.error(request, 'Algo Salio Mal') return redirect('articulos') class ComprobanteVista(LoginRequiredMixin, View): def get(self, request, *args, **kwargs): try: fecha = datetime.now().date() unidad = ArticuloUnidad.objects.first() articulos = ArticuloUnidad.objects.all() comprobante = Comprobante.objects.first() total_precios = ArticuloUnidad.objects.annotate(total=Sum(F("cantidad") * F("precio"))).aggregate(total_sum=Sum("total"))["total_sum"] template_path = "articulos/comprobante.html" context = { "articulos": articulos, "total_precios": total_precios, "comprobante": comprobante, "unidad": unidad, "fecha": fecha, } response = HttpResponse(content_type="application/pdf") response["Content-Disposition"] = 'attachment; filename="comprobantes.pdf"' template = get_template(template_path) html = template.render(context) # Crear el PDF pisa_status = pisa.CreatePDF(html, dest=response) if pisa_status.err: messages.error(request, "Hubo errores al generar el PDF.") return render(request, "articulos/comprobante.html", {"html": html}) return response except Comprobante.DoesNotExist: messages.error(request, "El comprobante no existe.") return render(request, "articulos/comprobante.html") except Exception as e: messages.error(request, f"Ocurrió un error: {e}") return render(request, "articulos/comprobante.html") # ---------- fin de la vista inventario # inicio de la vista de envio de articulos class VistaEnvio(LoginRequiredMixin, CreateView): form_class = FormEnvio initial = {"key": "value"} template_name = "envios/envio_articulo.html" def get(self, request , *args, **kwargs): articulo = Articulo.objects.all() articulos_c = ArticuloUnidad.objects.all() comprobantes = Comprobante.objects.all() total_precios = ArticuloUnidad.objects.annotate(total=Sum(F("cantidad") * F("precio"))).aggregate(total_sum=Sum("total"))["total_sum"] unidades = Unidad.objects.all() context= { "articulo": articulo, "unidades": unidades, "articulos_c": articulos_c, "total_precios": total_precios, "comprobantes": comprobantes, } return render(request, self.template_name, context) def post(self, request, *args, **kwargs): formulario_envio = self.form_class(request.POST) if formulario_envio.is_valid(): unidad = formulario_envio.cleaned_data["unidad"] cantidad = formulario_envio.cleaned_data["cantidad"] articulo = formulario_envio.cleaned_data["articulo"] comprobante = formulario_envio.cleaned_data["comprobante"] if articulo.cantidad >= cantidad: articulo.cantidad -= cantidad articulo.save() ArticuloUnidad.objects.create( movimiento="Envío", articulo=articulo, unidad=unidad, cantidad=cantidad, unidad_medida=articulo.unidad_medida, precio=articulo.precio, serial=articulo.serial, marca=articulo.marca, description=articulo.description, modelo=articulo.modelo, ) PruebaUnidad.objects.create( movimiento="Envío", articulo=articulo, unidad=unidad, cantidad=cantidad, unidad_medida=articulo.unidad_medida, precio=articulo.precio, serial=articulo.serial, marca=articulo.marca, comprobante = comprobante, description=articulo.description, modelo=articulo.modelo, ) messages.success(request, "Se Inserto con Exito") return redirect("envio_articulo") else: messages.error(request, "No hay suficientes articulos") return redirect("envio_articulo") else: formulario_comprobante = FormComprobante(request.POST) if formulario_comprobante.is_valid(): formulario_comprobante.save() return redirect("envio_articulo") else: context = { "formulario_envio": formulario_envio, "formulario_comprobante": formulario_comprobante, } return render(request, self.template_name, context) class BorrarVistaComprobante(LoginRequiredMixin, View): template_name = "envios/borrartodo.html" success_url = reverse_lazy("envio_articulo") def get(self, request): return render(request, self.template_name) def post(self, request): Comprobante.objects.all().delete() ArticuloUnidad.objects.all().delete() return HttpResponseRedirect(reverse_lazy("envio_articulo")) # fin de la vista de articulos class VistaUnidad(LoginRequiredMixin, View): def get(self, request, *args, **kwargs): unidad = Unidad.objects.all() context = {'unidad':unidad} return render(request, 'unidad/unidad_index.html',context) class CrearUnidad(LoginRequiredMixin, CreateView): form_class = FormUnidad initial = {"key": "value"} template_name = "unidad/crear_unidad.html" def get(self, request, *args, **kwargs): formulario_unidad = self.form_class(initial=self.initial) context = {'formulario_unidad':formulario_unidad} return render(request, self.template_name, context) def post(self, request, *args, **kwargs): formulario_unidad = self.form_class(request.POST) if formulario_unidad.is_valid(): formulario_unidad.save() return redirect('unidad') return render(request, self.template_name, {'formulario_unidad':formulario_unidad}) class UnidadArticulo(LoginRequiredMixin, View): def get(self, request, id): unidad= Unidad.objects.get(pk=id) articulo = PruebaUnidad.objects.filter(unidad=unidad) context={'articulo':articulo} return render(request, 'subunidad/unidad_articulo.html',context) class EditarVistaUnidad(LoginRequiredMixin, UpdateView): model = Unidad form_class = FormUnidad template_name = "unidad/editar_unidad.html" def get(self, request, *args, **kwargs): self.object = self.get_object() return super().get(request, self.template_name, *args, **kwargs) def get_initial(self): initial = super().get_initial() return initial def form_valid(self, form): self.object = form.save() return redirect('unidad') class EliminarVistaUnidad(LoginRequiredMixin, DeleteView): model = Unidad template_name = "unidad/eliminar_unidad.html" success_url = reverse_lazy('unidad') class AccesoVista(LoginView): login_url = "registration/login.html" redirect_field_name = "redirect_to" class CerrarVista(RedirectView): def get(self, request): logout(request) return redirect("login") class Admin(View): def get(self, request, *args, **kwargs): return render(request, 'administrador/admin.html')