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