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
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 |