You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

245 lines
8.8 KiB

from django.shortcuts import render,redirect,get_object_or_404
from django.http import HttpResponse
from django.contrib.auth.forms import AuthenticationForm, UserCreationForm
from django.contrib.auth import login, logout, authenticate
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from .models import RegistrarCompra, RegistroPagos
from .forms import RegistrarCompraForm, RegistroPagosForm
from django.template.loader import get_template
from xhtml2pdf import pisa
import openpyxl
from django import forms
import csv
# Create your views here.
def base(request):
return render(request, 'index.html')
class CustomUserCreationForm(UserCreationForm):
email = forms.EmailField(required=True, help_text="Introduce un correo electrónico válido.")
class Meta:
model = User
fields = ('username', 'email', 'password1', 'password2')
def save(self, commit=True):
user = super().save(commit=False)
user.email = self.cleaned_data["email"]
if commit:
user.save()
return user
def signup(request):
if request.method == 'POST':
form = CustomUserCreationForm(request.POST)
# Verificamos si el formulario es válido
if form.is_valid():
# Guardamos el usuario si todo está bien
form.save()
# Mensaje de éxito
return redirect('signin') # Redirige a la página de inicio de sesión
else:
# Si el formulario no es válido, mostramos los errores en los campos específicos
if 'username' not in form.cleaned_data:
form.add_error('username', 'El nombre de usuario es obligatorio.')
if 'email' not in form.cleaned_data:
form.add_error('email', 'El correo electrónico es obligatorio.')
if 'password1' not in form.cleaned_data:
form.add_error('password1', 'La contraseña es obligatoria.')
if 'password2' not in form.cleaned_data:
form.add_error('password2', 'Debes confirmar la contraseña.')
return render(request, 'singup.html', {'form': form})
else:
# Si es un GET, mostramos un formulario vacío
form = CustomUserCreationForm()
return render(request, 'singup.html', {'form': form})
def signin(request):
if request.method == 'GET':
return render ( request, 'index.html',{
'form': AuthenticationForm
})
else:
user=authenticate(request, username=request.POST['username'], password=request.POST['password'])
if user is None:
return render ( request, 'index.html',{
'form': AuthenticationForm ,
'error': 'Username or password is incorrect'
})
else:
login(request, user)
return redirect('lista_compras')
def signout(request):
logout(request)
return redirect('signin')
@login_required
def crear_compra(request):
if request.method == 'POST':
form = RegistrarCompraForm(request.POST)
if form.is_valid():
# Guardamos el formulario y asignamos el usuario autenticado al campo 'user_compra'
compra = form.save(commit=False) # No guardamos todavía en la base de datos
compra.user_compra = request.user # Asignamos el usuario autenticado
compra.save() # Guardamos la compra en la base de datos
return redirect('lista_compras') # Redirige a una vista que liste las compras
else:
form = RegistrarCompraForm()
return render(request, 'crear_compra.html', {'form': form})
@login_required
def registrar_pago(request, compra_id):
compra = get_object_or_404(RegistrarCompra, id=compra_id, user_compra=request.user) # Filtrar por el usuario
# Calcular el total pagado actual (monto_pagado + monto_extra)
pagos = compra.pagos.all()
total_pagado = sum(pago.monto_pagado + pago.monto_extra for pago in pagos)
# Calcular el monto restante de la compra
restante = compra.monto_pago - total_pagado
if request.method == 'POST':
form = RegistroPagosForm(request.POST)
if form.is_valid():
pago = form.save(commit=False)
# Verificar si el nuevo pago no excede el monto restante
total_nuevo_pago = pago.monto_pagado + pago.monto_extra
if total_pagado + total_nuevo_pago > compra.monto_pago:
form.add_error(None, "El pago total no puede superar el monto de la compra.")
else:
pago.registro_compra = compra # Relacionar con la compra específica
pago.user = request.user # Asignar el usuario autenticado
pago.save()
return redirect('detalle_compra', compra_id=compra.id) # Redirige a la vista de detalle de la compra
else:
form = RegistroPagosForm()
return render(request, 'registrar_pago.html', {'form': form, 'compra': compra, 'restante': restante})
@login_required
def detalle_compra(request, compra_id):
compra = get_object_or_404(RegistrarCompra, id=compra_id, user_compra=request.user) # Filtrar por el usuario
pagos = compra.pagos.all() # Obtén todos los pagos relacionados con esta compra
# Calcular el total pagado (monto_pagado + monto_extra)
total_pagado = sum(pago.monto_pagado + pago.monto_extra for pago in pagos)
# Calcular el monto restante
restante = max(0, compra.monto_pago - total_pagado)
# Calcular el estado
estado = compra.calcular_estado() # Utilizamos el método que definimos en el modelo
context = {
'compra': compra,
'pagos': pagos,
'total_pagado': total_pagado,
'restante': restante,
'estado': estado,
}
return render(request, 'detalle_compra.html', context)
@login_required
def lista_compras(request):
compras = RegistrarCompra.objects.filter(user_compra=request.user) # Filtrar por el usuario actual
compras_con_estado = [
{
'compra': compra,
'estado': compra.calcular_estado(), # Calcula el estado de la compra
'restante': compra.calcular_restante(), # Calcula el monto restante
}
for compra in compras
]
return render(request, 'lista_compras.html', {'compras_con_estado': compras_con_estado})
def generar_pdf(template_src, context_dict={}):
template = get_template(template_src)
html = template.render(context_dict)
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'inline; filename="detalle_compra.pdf"'
pisa_status = pisa.CreatePDF(html, dest=response)
if pisa_status.err:
return HttpResponse('Error al generar el PDF', content_type='text/plain')
return response
def reporte_detalle_compra(request, compra_id):
compra = get_object_or_404(RegistrarCompra, id=compra_id)
pagos = compra.pagos.all()
total_pagado = sum(pago.total_pagado for pago in pagos)
restante = max(0, compra.monto_pago - total_pagado)
context = {
'compra': compra,
'pagos': pagos,
'total_pagado': total_pagado,
'restante': restante,
}
return generar_pdf('detalle_compra_pdf.html', context)
def exportar_excel_detalle_compra(request, compra_id):
compra = get_object_or_404(RegistrarCompra, id=compra_id)
pagos = compra.pagos.all()
# Crear el archivo de Excel
wb = openpyxl.Workbook()
ws = wb.active
ws.title = "Detalle de Compra"
# Escribir encabezados
ws.append(["Fecha de Pago", "Monto Pagado", "Monto Extra", "Observaciones"])
# Agregar los datos de los pagos
for pago in pagos:
ws.append([
pago.fecha_pago,
float(pago.monto_pagado),
float(pago.monto_extra),
pago.observaciones,
])
# Configurar la respuesta HTTP
response = HttpResponse(content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
response['Content-Disposition'] = f'attachment; filename="detalle_compra_{compra.id}.xlsx"'
wb.save(response)
return response
def exportar_csv_detalle_compra(request, compra_id):
compra = get_object_or_404(RegistrarCompra, id=compra_id)
pagos = compra.pagos.all()
# Configurar la respuesta HTTP
response = HttpResponse(content_type="text/csv")
response['Content-Disposition'] = f'attachment; filename="detalle_compra_{compra.id}.csv"'
# Crear el escritor CSV
writer = csv.writer(response)
writer.writerow(["Fecha de Pago", "Monto Pagado", "Monto Extra", "Observaciones"]) # Encabezados
# Agregar los datos de los pagos
for pago in pagos:
writer.writerow([
pago.fecha_pago,
float(pago.monto_pagado),
float(pago.monto_extra),
pago.observaciones,
])
return response