This repository has been archived on 2025-08-29. You can view files and clone it, but cannot push or open issues or pull requests.
Files

240 lines
7.0 KiB
Python

from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
from django.views.generic import ListView
from django.db import transaction
from .models import (
Sale, SaleLine, Product, Customer, ProductCategory, Payment, PaymentMethods, ReconciliationJar)
from .forms import (
ImportProductsForm,
ImportCustomersForm,
PurchaseForm,
SaleLineFormSet,
PurchaseSummaryForm)
import csv
import io
import json
from decimal import Decimal
class DecimalEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, Decimal):
return float(obj)
return json.JSONEncoder.default(self, obj)
def index(request):
return render(request, 'don_confiao/index.html')
def buy(request):
if request.method == "POST":
sale_form = PurchaseForm(request.POST)
line_formset = SaleLineFormSet(request.POST)
sale_summary_form = PurchaseSummaryForm(request.POST)
forms_are_valid = all([
sale_form.is_valid(),
line_formset.is_valid(),
sale_summary_form.is_valid()
])
payment_method = request.POST.get('payment_method')
valid_payment_methods = [PaymentMethods.CASH]
valid_payment_method = payment_method in valid_payment_methods
if forms_are_valid:
with transaction.atomic():
sale = sale_form.save()
line_formset.instance = sale
line_formset.save()
Payment.total_payment_from_sale(
payment_method,
sale
)
return HttpResponseRedirect("compras")
else:
sale_form = PurchaseForm()
line_formset = SaleLineFormSet()
sale_summary_form = PurchaseSummaryForm()
return render(
request,
'don_confiao/purchase.html',
{
'sale_form': sale_form,
'linea_formset': line_formset,
'summary_form': sale_summary_form,
'list_products': json.dumps(Product.to_list(), cls=DecimalEncoder),
}
)
def purchases(request):
purchases = Sale.objects.all()
context = {
"purchases": purchases,
}
return render(request, 'don_confiao/purchases.html', context)
def products(request):
return JsonResponse(Product.to_list(), safe=False)
def import_products(request):
if request.method == "POST":
form = ImportProductsForm(request.POST, request.FILES)
if form.is_valid():
handle_import_products_file(request.FILES["csv_file"])
return HttpResponseRedirect("productos")
else:
form = ImportProductsForm()
return render(
request,
"don_confiao/import_products.html",
{'form': form}
)
def import_customers(request):
if request.method == "POST":
form = ImportCustomersForm(request.POST, request.FILES)
if form.is_valid():
handle_import_customers_file(request.FILES["csv_file"])
return HttpResponseRedirect("productos")
else:
form = ImportCustomersForm()
return render(
request,
"don_confiao/import_customers.html",
{'form': form}
)
def reconciliations(request):
return HttpResponse('<h1>Reconciliaciones</h1>')
def purchase_summary(request, id):
purchase = Sale.objects.get(pk=id)
return render(
request,
"don_confiao/purchase_summary.html",
{
"purchase": purchase
}
)
def _categories_from_csv_string(categories_string, separator="&"):
categories = categories_string.split(separator)
clean_categories = [c.strip() for c in categories]
return [_category_from_name(category) for category in clean_categories]
def _category_from_name(name):
return ProductCategory.objects.get_or_create(name=name)[0]
def handle_import_products_file(csv_file):
data = io.StringIO(csv_file.read().decode('utf-8'))
reader = csv.DictReader(data, quotechar='"')
for row in reader:
product, created = Product.objects.update_or_create(
name=row['producto'],
defaults={
'price': row['precio'],
'measuring_unit': row['unidad']
}
)
categories = _categories_from_csv_string(row["categorias"])
product.categories.clear()
for category in categories:
product.categories.add(category)
def handle_import_customers_file(csv_file):
data = io.StringIO(csv_file.read().decode('utf-8'))
reader = csv.DictReader(data, quotechar='"')
for row in reader:
customer, created = Customer.objects.update_or_create(
name=row['nombre'],
defaults={
'email': row['correo'],
'phone': row['telefono']
}
)
def exportar_ventas_para_tryton(request):
tryton_sales_header = [
"Tercero",
"Dirección de facturación",
"Dirección de envío",
"Descripción",
"Referencia",
"Fecha venta",
"Plazo de pago",
"Almacén",
"Moneda",
"Líneas/Producto",
"Líneas/Cantidad",
"Líneas/Precio unitario",
"Líneas/Unidad",
"Empresa",
"Tienda",
"Terminal de venta",
"Autorecogida",
"Comentario"
]
if request.method == "GET":
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = "attachment; filename=sales.csv"
writer = csv.writer(response)
writer.writerow(tryton_sales_header)
sales = Sale.objects.all()
for sale in sales:
sale_lines = SaleLine.objects.filter(sale=sale.id)
if not sale_lines:
continue
lines = []
first_sale_line = sale_lines[0]
customer_info = [sale.customer.name] * 3 + [sale.description] * 2
first_line = customer_info + [
sale.date,
"Contado",
"Almacén",
"Peso colombiano",
first_sale_line.product.name,
first_sale_line.quantity,
"Unidad",
first_sale_line.unit_price,
"TIENDA LA ILUSIÓN",
"Tienda La Ilusion",
"La Ilusion",
True,
sale.description]
lines.append(first_line)
for line in sale_lines[1:]:
lines.append([""]*9+[
line.product.name,
line.quantity,
line.unit_price,
"Unidad"]+[""]*5)
for row in lines:
writer.writerow(row)
return response
class ProductListView(ListView):
model = Product
template_model = 'don_confiao/product_list.html'
def get_queryset(self):
name = self.request.GET.get('name')
if name:
return Product.objects.filter(name__icontains=name)
return Product.objects.all()