- 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
131 lines
3.7 KiB
Python
131 lines
3.7 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.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
|
|
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 products(request):
|
|
return JsonResponse(Product.to_list(), safe=False)
|
|
|
|
|
|
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 sales_to_tryton_csv(sales):
|
|
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",
|
|
]
|
|
|
|
csv_data = [tryton_sales_header]
|
|
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.strftime("%Y-%m-%d"),
|
|
"Contado",
|
|
"Almacén",
|
|
"Peso colombiano",
|
|
first_sale_line.product.name,
|
|
first_sale_line.quantity,
|
|
first_sale_line.unit_price,
|
|
"Unidad",
|
|
"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:
|
|
csv_data.append(row)
|
|
|
|
return csv_data
|