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('

Reconciliaciones

') 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 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, "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 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()