refactor: split models into modules, remove template-based views, and clean up code style
- Split monolithic models.py into models/ package (customers, products, sales, payments, admin) - Removed forms.py, all HTML templates, and associated template-based views - Added api/ package with CatalogSaleView placeholder - Updated all imports across project to use new model paths - Removed obsolete tests (form, export, purchase, summary tests) - Removed template-based URL patterns, kept only API endpoints - Standardized string quotes (single to double) and reformatted code
This commit is contained in:
@@ -3,14 +3,11 @@ 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)
|
||||
from .models.sales import Sale, SaleLine
|
||||
from .models.customers import Customer
|
||||
from .models.sales import Sale, SaleLine, Payment
|
||||
from .models.products import Product, ProductCategory
|
||||
from .models.payments import PaymentMethods, ReconciliationJar
|
||||
|
||||
import csv
|
||||
import io
|
||||
@@ -26,105 +23,13 @@ class DecimalEncoder(json.JSONEncoder):
|
||||
|
||||
|
||||
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)
|
||||
return render(request, "don_confiao/index.html")
|
||||
|
||||
|
||||
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]
|
||||
@@ -136,33 +41,32 @@ def _category_from_name(name):
|
||||
|
||||
|
||||
def handle_import_products_file(csv_file):
|
||||
data = io.StringIO(csv_file.read().decode('utf-8'))
|
||||
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'],
|
||||
name=row["producto"],
|
||||
defaults={
|
||||
'price': row['precio'],
|
||||
'measuring_unit': row['unidad']
|
||||
}
|
||||
"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'))
|
||||
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']
|
||||
}
|
||||
name=row["nombre"],
|
||||
defaults={"email": row["correo"], "phone": row["telefono"]},
|
||||
)
|
||||
|
||||
|
||||
def sales_to_tryton_csv(sales):
|
||||
tryton_sales_header = [
|
||||
"Tercero",
|
||||
@@ -182,7 +86,7 @@ def sales_to_tryton_csv(sales):
|
||||
"Tienda",
|
||||
"Terminal de venta",
|
||||
"Autorecogida",
|
||||
"Comentario"
|
||||
"Comentario",
|
||||
]
|
||||
|
||||
csv_data = [tryton_sales_header]
|
||||
@@ -194,7 +98,7 @@ def sales_to_tryton_csv(sales):
|
||||
first_sale_line = sale_lines[0]
|
||||
customer_info = [sale.customer.name] * 3 + [sale.description] * 2
|
||||
first_line = customer_info + [
|
||||
sale.date.strftime('%Y-%m-%d'),
|
||||
sale.date.strftime("%Y-%m-%d"),
|
||||
"Contado",
|
||||
"Almacén",
|
||||
"Peso colombiano",
|
||||
@@ -206,39 +110,21 @@ def sales_to_tryton_csv(sales):
|
||||
"Tienda La Ilusion",
|
||||
"La Ilusion",
|
||||
True,
|
||||
sale.description]
|
||||
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)
|
||||
lines.append(
|
||||
[""] * 9
|
||||
+ [
|
||||
line.product.name,
|
||||
line.quantity,
|
||||
line.unit_price,
|
||||
"Unidad",
|
||||
]
|
||||
+ [""] * 5
|
||||
)
|
||||
for row in lines:
|
||||
csv_data.append(row)
|
||||
|
||||
return csv_data
|
||||
|
||||
|
||||
def exportar_ventas_para_tryton(request):
|
||||
if request.method == "GET":
|
||||
response = HttpResponse(content_type='text/csv')
|
||||
response['Content-Disposition'] = "attachment; filename=sales.csv"
|
||||
sales = Sale.objects.all()
|
||||
csv_data = sales_to_tryton_csv(sales)
|
||||
writer = csv.writer(response)
|
||||
for row in csv_data:
|
||||
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()
|
||||
|
||||
Reference in New Issue
Block a user