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.
 
 
 
 

377 lines
14 KiB

from django.shortcuts import render,redirect,get_object_or_404
from django.template.loader import get_template
from django.http import HttpResponse
from django.contrib import messages
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth import login, logout, authenticate
from django.db import transaction
from django.utils import timezone
from django.contrib.auth.decorators import login_required
from django.db.models import Avg, Sum
from decimal import Decimal
from django.db.models import F
from .forms import formulario_proveedor,formulario_bodega, formulario_tipo, formulario_articulo,formilario_inventario,VentaForm
from .models import proveedor, bodega, tipo_articulo, articulo,inventario,tipo_inv_movimiento,movimiento_inventario,Venta
# Create your views here.
def base(request):
return render(request, 'index.html')
def graficos_view(request):
# 1. Ventas por bodega
ventas_por_bodega = (
Venta.objects.values("bodega__nombre_bodega")
.annotate(total_ventas=Sum("total"))
)
for item in ventas_por_bodega:
item["total_ventas"] = float(Decimal(item["total_ventas"] or 0)) # Convertir a float
# 2. Inventario total por artículo
inventario_total = (
inventario.objects.values("articulo__nombre_articulo")
.annotate(total=Sum("cantidad"))
)
# 3. Ventas por artículo
ventas_por_articulo = (
Venta.objects.values("articulo__nombre_articulo")
.annotate(total=Sum("cantidad"))
)
# 4. Comparación de precios de artículos
precios_articulos = list(articulo.objects.values(
"nombre_articulo",
"precio_compra",
"precio_venta",
))
for item in precios_articulos:
item["precio_compra"] = float(Decimal(item["precio_compra"] or 0)) # Convertir a float
item["precio_venta"] = float(Decimal(item["precio_venta"] or 0)) # Convertir a float
# Calcular el total de ventas
total_ventas = Venta.objects.aggregate(total_ventas=Sum('total'))['total_ventas'] or Decimal(0)
# Calcular el total de productos en inventario
total_productos_en_inventario = inventario.objects.aggregate(total_productos=Sum('cantidad'))['total_productos'] or 0
# Calcular el total de artículos vendidos
total_articulos_vendidos = ventas_por_articulo.aggregate(total_vendidos=Sum('total'))['total_vendidos'] or 0
# Calcular el total de proveedores
total_proveedores = proveedor.objects.count()
context = {
"ventas_por_bodega": list(ventas_por_bodega),
"inventario_total": list(inventario_total),
"ventas_por_articulo": list(ventas_por_articulo),
"precios_articulos": precios_articulos,
"total_ventas": float(total_ventas), # Sumar todas las ventas totales
"total_productos_en_inventario": total_productos_en_inventario, # Número total de productos en inventario
"total_articulos_vendidos": total_articulos_vendidos, # Total de unidades vendidas
"total_proveedores": total_proveedores, # Número de proveedores
}
return render(request, "index.html", context)
def signin(request):
if request.method == 'GET':
return render ( request, 'signin.html',{
'form': AuthenticationForm
})
else:
user=authenticate(request, username=request.POST['username'], password=request.POST['password'])
if user is None:
return render ( request, 'signin.html',{
'form': AuthenticationForm ,
'error': 'Username or password is incorrect'
})
else:
login(request, user)
return redirect('home')
@login_required
def signout(request):
logout(request)
return redirect('home')
@login_required
def proveedor_registro(request):
if request.method=='GET':
return render(request, 'proveedor_nuevo.html',{
'form': formulario_proveedor
})
else:
try:
form = formulario_proveedor (request.POST)
new_proveedor=form.save(commit=False)
new_proveedor.save()
return redirect('proveedor')
except ValueError:
return render(request, 'proveedor_nuevo.html',{
'form': formulario_proveedor,
'error':'porfavor ingrese bien los datos'
})
@login_required
def proveedor_lista(request):
persona = proveedor.objects.all
return render(request,"proveedor_registro.html", {'persona':persona})
@login_required
def Proveedor_update(request,task_id):
if request.method == 'GET':
tarea = get_object_or_404 (proveedor, pk=task_id)
form = formulario_proveedor(instance=tarea)
return render(request, 'proveedor_update.html',{'tasks':tarea, 'form':form} )
else:
try:
tarea=get_object_or_404(proveedor,pk=task_id)
form = formulario_proveedor(request.POST, instance=tarea)
form.save()
return redirect('proveedor')
except ValueError:
return render(request, 'proveedor_update.html',{'tasks':tarea, 'form':form, 'error': 'error updating task'} )
@login_required
def bodega_registro(request):
if request.method=='GET':
return render(request, 'bodega_nuevo.html',{
'form': formulario_bodega
})
else:
try:
form = formulario_bodega (request.POST)
new_bodega=form.save(commit=False)
new_bodega.save()
return redirect('bodega_vista')
except ValueError:
return render(request, 'bodega_nuevo.html',{
'form': formulario_bodega,
'error':'Please provide valid data'
})
@login_required
def bodega_vista(request):
persona = bodega.objects.all
return render(request,"bodega_registro.html", {'persona':persona})
@login_required
def bodega_update(request,task_id):
if request.method == 'GET':
tarea = get_object_or_404 (bodega, pk=task_id)
form = formulario_bodega(instance=tarea)
return render(request, 'bodega_update.html',{'tasks':tarea, 'form':form} )
else:
try:
tarea=get_object_or_404(bodega,pk=task_id)
form = formulario_bodega(request.POST, instance=tarea)
form.save()
return redirect('bodega_vista')
except ValueError:
return render(request, 'bodega_update.html',{'tasks':tarea, 'form':form, 'error': 'error updating task'} )
@login_required
def tipo_registro(request):
if request.method=='GET':
return render(request, 'tipo_articulo_nuevo.html',{
'form': formulario_tipo
})
else:
try:
form = formulario_tipo (request.POST)
new_tipo=form.save(commit=False)
new_tipo.save()
return redirect('tipo_vista')
except ValueError:
return render(request, 'tipo_articulo_nuevo.html',{
'form': formulario_tipo,
'error':'Please provide valid data'
})
@login_required
def tipo_vista(request):
persona = tipo_articulo.objects.all
return render(request,"tipo_articulo_registro.html", {'persona':persona})
@login_required
def tipo_update(request,task_id):
if request.method == 'GET':
tarea = get_object_or_404 (tipo_articulo, pk=task_id)
form = formulario_tipo(instance=tarea)
return render(request, 'tipo_articulo_update.html',{'tasks':tarea, 'form':form} )
else:
try:
tarea=get_object_or_404(tipo_articulo,pk=task_id)
form = formulario_tipo(request.POST, instance=tarea)
form.save()
return redirect('tipo_vista')
except ValueError:
return render(request, 'tipo_articulo_update.html',{'tasks':tarea, 'form':form, 'error': 'error updating task'} )
@login_required
def articulo_registro(request):
if request.method=='GET':
return render(request, 'articulo_nuevo.html',{
'form': formulario_articulo
})
else:
try:
form = formulario_articulo (request.POST)
form.save()
return redirect('articulo_vista')
except ValueError:
return render(request, 'articulo_nuevo.html',{
'form': formulario_articulo,
'error':'Please provide valid data'
})
@login_required
def articulo_vista(request):
persona = articulo.objects.select_related('tipo_articulo','proveedor').all()
return render(request,"articulo_registro.html", {'persona':persona})
@login_required
def articulo_update(request,task_id):
if request.method == 'GET':
tarea = get_object_or_404 (articulo, pk=task_id)
form = formulario_articulo(instance=tarea)
return render(request, 'articulo_update.html',{'tasks':tarea, 'form':form} )
else:
try:
tarea=get_object_or_404(articulo,pk=task_id)
form = formulario_articulo(request.POST, instance=tarea)
form.save()
return redirect('articulo_vista')
except ValueError:
return render(request, 'articulo_update.html',{'tasks':tarea, 'form':form, 'error': 'error updating'} )
@login_required
def inventario_registro(request):
if request.method=='GET':
return render(request, 'inventario_nuevo.html',{
'form': formilario_inventario
})
else:
try:
form = formilario_inventario (request.POST)
form.save()
form = formilario_inventario ()
return render(request, 'inventario_nuevo.html',{
'form': formilario_inventario,
'mensaje':'Please provide valid data'
})
except ValueError:
return render(request, 'inventario_nuevo.html',{
'form': formilario_inventario,
'error':'Please provide valid data'
})
@login_required
def inventario_vista(request):
persona = inventario.objects.select_related('articulo','bodega').all()
return render(request,"inventario_registro.html", {'persona':persona})
def registrar_movimiento_y_actualizar_inventario(movimiento_data):
"""
Registra un movimiento de inventario y actualiza el inventario relacionado.
"""
try:
with transaction.atomic():
# Registrar el movimiento de inventario
movimiento = movimiento_inventario.objects.create(
articulo=movimiento_data['articulo'],
bodega=movimiento_data['bodega'],
tipo_inventario=movimiento_data['tipo_inventario'],
cantidad=movimiento_data['cantidad'],
observaciones=movimiento_data.get('observaciones', '')
)
# Buscar o crear el inventario correspondiente
inventario_obj, created = inventario.objects.get_or_create(
articulo=movimiento.articulo,
bodega=movimiento.bodega,
defaults={'cantidad': 0}
)
# Comprobación y actualización según el tipo de movimiento
if movimiento.tipo_inventario.id == 1:
inventario_obj.cantidad += movimiento.cantidad
elif movimiento.tipo_inventario.id == 2:
if inventario_obj.cantidad < movimiento.cantidad:
raise ValueError(
f"No hay suficiente stock. Disponible: {inventario_obj.cantidad}, solicitado: {movimiento.cantidad}"
)
inventario_obj.cantidad -= movimiento.cantidad
# Guardar los cambios en el inventario
inventario_obj.save()
return movimiento, inventario_obj
except Exception as e:
raise ValueError(f"Error al registrar movimiento y actualizar inventario: {str(e)}")
def nueva_venta(request):
if request.method == 'POST':
form = VentaForm(request.POST)
if form.is_valid():
venta = form.save(commit=False)
# Verificar si el artículo existe en la bodega seleccionada
try:
inventario_item = inventario.objects.get(
bodega=venta.bodega,
articulo=venta.articulo
)
except inventario.DoesNotExist:
form.add_error('articulo', 'El artículo no existe en la bodega seleccionada.')
return render(request, 'nueva_venta.html', {'form': form})
# Validar que haya suficiente cantidad en el inventario
if inventario_item.cantidad >= venta.cantidad:
# Guardar la venta
venta.save()
return redirect('lista_ventas') # Redirigir al listado de ventas
else:
form.add_error('cantidad', 'Cantidad en inventario insuficiente.')
else:
form = VentaForm()
return render(request, 'nueva_venta.html', {'form': form})
def registrar_movimiento(request):
"""
Vista para registrar un nuevo movimiento de inventario.
"""
if request.method == 'POST':
form = formilario_inventario(request.POST)
if form.is_valid():
movimiento_data = form.cleaned_data
try:
movimiento, inventario_obj = registrar_movimiento_y_actualizar_inventario(movimiento_data)
return redirect('vista_inventario_mov') # Redirigir a una página de éxito
except ValueError as e:
return render(request, 'inventario_nuevo.html', {
'form': form,
'error': str(e)
})
else:
form = formilario_inventario()
return render(request, 'inventario_nuevo.html', {'form': form})
@login_required
def vista_inventario_mov(request):
persona = movimiento_inventario.objects.select_related('articulo','bodega','tipo_inventario').all()
return render(request,"mov_inventario_registro.html", {'persona':persona})
def lista_ventas(request):
ventas = Venta.objects.all()
return render(request, 'ventas.html', {'ventas': ventas})