From 7223c0c9a99f0b2266cee152406a4a1226e0cee6 Mon Sep 17 00:00:00 2001 From: sinergia Date: Fri, 12 Jul 2024 22:00:37 -0500 Subject: [PATCH 1/5] Fix: Clean Home, Crear lineas de Venta --- tienda_ilusion/don_confiao/forms.py | 2 ++ tienda_ilusion/don_confiao/models.py | 4 ++++ tienda_ilusion/don_confiao/tests/__init__.py | 1 + .../don_confiao/{ => tests}/test_products.py | 10 ++++----- .../don_confiao/{ => tests}/tests.py | 2 +- tienda_ilusion/don_confiao/views.py | 22 +++++++++++++------ 6 files changed, 27 insertions(+), 14 deletions(-) create mode 100644 tienda_ilusion/don_confiao/tests/__init__.py rename tienda_ilusion/don_confiao/{ => tests}/test_products.py (93%) rename tienda_ilusion/don_confiao/{ => tests}/tests.py (98%) diff --git a/tienda_ilusion/don_confiao/forms.py b/tienda_ilusion/don_confiao/forms.py index 4db321a..0563fa8 100644 --- a/tienda_ilusion/don_confiao/forms.py +++ b/tienda_ilusion/don_confiao/forms.py @@ -7,6 +7,7 @@ from .models import Sale, SaleLine class ImportProductsForm(forms.Form): csv_file = forms.FileField() + class PurchaseForm(forms.ModelForm): class Meta: model = Sale @@ -20,6 +21,7 @@ class PurchaseForm(forms.ModelForm): 'date': DateInput(attrs={'type': 'date'}) } + class PurchaseLineForm(forms.ModelForm): class Meta: model = SaleLine diff --git a/tienda_ilusion/don_confiao/models.py b/tienda_ilusion/don_confiao/models.py index 7d7ee0a..a3c2432 100644 --- a/tienda_ilusion/don_confiao/models.py +++ b/tienda_ilusion/don_confiao/models.py @@ -1,6 +1,7 @@ from django.db import models from django.utils.translation import gettext_lazy as _ + class Sale(models.Model): customer = models.CharField(max_length=100) @@ -23,15 +24,18 @@ class SaleLine(models.Model): def __str__(self): return f"{self.sale} - {self.product}" + class MeasuringUnits(models.TextChoices): UNIT = 'UNIT', _('Unit') + class ProductCategory(models.Model): name = models.CharField(max_length=100, unique=True) def __str__(self): return self.name + class Product(models.Model): name = models.CharField(max_length=100, unique=True) price = models.DecimalField(max_digits=9, decimal_places=2) diff --git a/tienda_ilusion/don_confiao/tests/__init__.py b/tienda_ilusion/don_confiao/tests/__init__.py new file mode 100644 index 0000000..e5a0d9b --- /dev/null +++ b/tienda_ilusion/don_confiao/tests/__init__.py @@ -0,0 +1 @@ +#!/usr/bin/env python3 diff --git a/tienda_ilusion/don_confiao/test_products.py b/tienda_ilusion/don_confiao/tests/test_products.py similarity index 93% rename from tienda_ilusion/don_confiao/test_products.py rename to tienda_ilusion/don_confiao/tests/test_products.py index 0b4e0dc..0c12f74 100644 --- a/tienda_ilusion/don_confiao/test_products.py +++ b/tienda_ilusion/don_confiao/tests/test_products.py @@ -1,13 +1,11 @@ from django.test import Client, TestCase -from django.contrib.auth.models import AnonymousUser, User from django.conf import settings - -from .views import import_products, products -from .models import ProductCategory, Product +from ..models import ProductCategory, Product import os import json + class TestProducts(TestCase): def setUp(self): self.client = Client() @@ -54,7 +52,8 @@ class TestProducts(TestCase): first_categories = {p["name"]: p["categories"] for p in first_products} self._import_csv('example_products2.csv') updated_products = self._get_products() - updated_categories = {p["name"]: p["categories"] for p in updated_products} + updated_categories = { + p["name"]: p["categories"] for p in updated_products} self.assertIn('Cafes', first_categories['Arroz']) self.assertNotIn('Granos', first_categories['Arroz']) @@ -62,7 +61,6 @@ class TestProducts(TestCase): self.assertIn('Granos', updated_categories['Arroz']) self.assertNotIn('Cafes', updated_categories['Arroz']) - def test_update_price(self): self._import_csv() first_products = self._get_products() diff --git a/tienda_ilusion/don_confiao/tests.py b/tienda_ilusion/don_confiao/tests/tests.py similarity index 98% rename from tienda_ilusion/don_confiao/tests.py rename to tienda_ilusion/don_confiao/tests/tests.py index 27b5d3e..771ec89 100644 --- a/tienda_ilusion/don_confiao/tests.py +++ b/tienda_ilusion/don_confiao/tests/tests.py @@ -1,5 +1,5 @@ from django.test import TestCase -from .models import Sale, SaleLine +from ..models import Sale, SaleLine class ConfiaoTest(TestCase): diff --git a/tienda_ilusion/don_confiao/views.py b/tienda_ilusion/don_confiao/views.py index 1904ab6..4f61508 100644 --- a/tienda_ilusion/don_confiao/views.py +++ b/tienda_ilusion/don_confiao/views.py @@ -1,6 +1,6 @@ from django.shortcuts import render -from django.http import HttpResponse, HttpResponseRedirect, JsonResponse -from django.template import loader +from django.http import HttpResponseRedirect, JsonResponse +# from django.template import loader from .models import Sale, Product, ProductCategory from .forms import ImportProductsForm, PurchaseForm, LineaFormSet @@ -8,18 +8,22 @@ from .forms import ImportProductsForm, PurchaseForm, LineaFormSet import csv import io + def index(request): return render(request, 'don_confiao/index.html') + def buy(request): if request.method == "POST": sale_form = PurchaseForm(request.POST) sale_linea_form = LineaFormSet(request.POST) - if sale_form.is_valid(): - sale_form.save() - if sale_linea_form.is_valid(): - sale_linea_form.save() - return HttpResponseRedirect("productos") + if sale_form.is_valid() and sale_linea_form.is_valid(): + sale = sale_form.save() + lines = sale_linea_form.save(commit=False) + for line in lines: + line.sale = sale + line.save() + return HttpResponseRedirect("compras") else: sale_form = PurchaseForm() sale_linea_form = LineaFormSet() @@ -32,6 +36,7 @@ def buy(request): } ) + def purchases(request): purchases = Sale.objects.all() context = { @@ -69,14 +74,17 @@ def import_products(request): {'form': form} ) + 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='"') From 6795aa3dcc0cd8bc8a3212d06f8a9d35d9940960 Mon Sep 17 00:00:00 2001 From: sinergia Date: Fri, 12 Jul 2024 22:38:07 -0500 Subject: [PATCH 2/5] feat: Se agrega testform --- tienda_ilusion/don_confiao/forms.py | 2 +- .../don_confiao/tests/tests_purchase_form.py | 33 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 tienda_ilusion/don_confiao/tests/tests_purchase_form.py diff --git a/tienda_ilusion/don_confiao/forms.py b/tienda_ilusion/don_confiao/forms.py index 0563fa8..72b4b9c 100644 --- a/tienda_ilusion/don_confiao/forms.py +++ b/tienda_ilusion/don_confiao/forms.py @@ -36,6 +36,6 @@ class PurchaseLineForm(forms.ModelForm): LineaFormSet = forms.models.inlineformset_factory( Sale, SaleLine, - extra=2, + extra=1, fields='__all__' ) diff --git a/tienda_ilusion/don_confiao/tests/tests_purchase_form.py b/tienda_ilusion/don_confiao/tests/tests_purchase_form.py new file mode 100644 index 0000000..e50849b --- /dev/null +++ b/tienda_ilusion/don_confiao/tests/tests_purchase_form.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 +from django.test import TestCase +from ..forms import PurchaseForm +# from ..models import Sale, SaleLine + +_csrf_token = \ + "bVjBevJRavxRPFOlVgAWiyh9ceuiwPlyEcmbPZprNuCGHjFZRKZrBeunJvKTRgOx" + + +class PurchaseFormTest(TestCase): + + def test_add_purchase(self): + form_data = { + "csrfmiddlewaretoken": _csrf_token, + "customer": "San Judas de Asis", + "date": "2024-07-12", + "phone": "3010101000", + "description": "Esta es una Venta", + "saleline_set-TOTAL_FORMS": "1", + "saleline_set-INITIAL_FORMS": "0", + "saleline_set-MIN_NUM_FORMS": "0", + "saleline_set-MAX_NUM_FORMS": "1000", + "saleline_set-0-product": "Papayita", + "saleline_set-0-quantity": "1", + "saleline_set-0-unit_price": "22030", + "saleline_set-0-description": "Linea de Venta", + "saleline_set-0-sale": "", + "saleline_set-0-id": "", + "form": "" + } + + purchase_form = PurchaseForm(data=form_data) + self.assertTrue(purchase_form.is_valid()) From a63ae668a20bf582e0f1049c8495f8622bda7ff2 Mon Sep 17 00:00:00 2001 From: Rodia Date: Fri, 12 Jul 2024 23:40:43 -0500 Subject: [PATCH 3/5] =?UTF-8?q?Feat(ButtonAddLine):=20A=C3=B1adir=20linea?= =?UTF-8?q?=20de=20venta=20en=20formulario=20WIP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../don_confiao/static/js/add_line.js | 18 ++++++++++++++++ .../templates/don_confiao/purchase.html | 21 ++++++++++++------- 2 files changed, 32 insertions(+), 7 deletions(-) create mode 100644 tienda_ilusion/don_confiao/static/js/add_line.js diff --git a/tienda_ilusion/don_confiao/static/js/add_line.js b/tienda_ilusion/don_confiao/static/js/add_line.js new file mode 100644 index 0000000..aed4bec --- /dev/null +++ b/tienda_ilusion/don_confiao/static/js/add_line.js @@ -0,0 +1,18 @@ +document.addEventListener('DOMContentLoaded', function(){ + var button = document.getElementById('add_line'); + var formContainer = document.getElementById('formset-container'); + var totalForms = document.getElementById('id_form-TOTAL_FORMS'); + button.addEventListener('click', function(){ + // Clonar un formulario vacío + var newForm = formContainer.querySelector('.form-container').cloneNode(true); + // Obtener el número actual de formularios + var formCount = parseInt(totalForms.value); + // Actualizar los atributos de los nuevos campos del formulario + var regex = new RegExp('__prefix__', 'g'); + newForm.innerHTML = newForm.innerHTML.replace(regex, formCount); + // Añadir el nuevo formulario al contenedor + formContainer.appendChild(newForm); + // Incrementar el total de formularios + totalForms.value = formCount + 1; + }); +}); diff --git a/tienda_ilusion/don_confiao/templates/don_confiao/purchase.html b/tienda_ilusion/don_confiao/templates/don_confiao/purchase.html index 0d2c2f4..7f6c8d9 100644 --- a/tienda_ilusion/don_confiao/templates/don_confiao/purchase.html +++ b/tienda_ilusion/don_confiao/templates/don_confiao/purchase.html @@ -1,12 +1,19 @@ +{% load static %}
- {% csrf_token %} - {{ sale_form}} + {% csrf_token %} + {{ sale_form}} {{ linea_formset.management_form }} - {% for form in linea_formset %} - - {{ form.as_table }} -
+
+ {% for form in linea_formset %} +
+ + {{ form.as_table }} +
+
{% endfor %} -
+
+ +
+
From 3e35807a87ffdc59435f4fcce73079d341ac4b87 Mon Sep 17 00:00:00 2001 From: Rodia Date: Sat, 13 Jul 2024 11:01:11 -0500 Subject: [PATCH 4/5] Feat(AddSaleLineButton): Sale Line Button --- tienda_ilusion/don_confiao/static/js/add_line.js | 2 +- tienda_ilusion/don_confiao/templates/don_confiao/purchase.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tienda_ilusion/don_confiao/static/js/add_line.js b/tienda_ilusion/don_confiao/static/js/add_line.js index aed4bec..bfb38ed 100644 --- a/tienda_ilusion/don_confiao/static/js/add_line.js +++ b/tienda_ilusion/don_confiao/static/js/add_line.js @@ -1,7 +1,7 @@ document.addEventListener('DOMContentLoaded', function(){ var button = document.getElementById('add_line'); var formContainer = document.getElementById('formset-container'); - var totalForms = document.getElementById('id_form-TOTAL_FORMS'); + var totalForms = document.getElementById('id_saleline_set-TOTAL_FORMS'); button.addEventListener('click', function(){ // Clonar un formulario vacío var newForm = formContainer.querySelector('.form-container').cloneNode(true); diff --git a/tienda_ilusion/don_confiao/templates/don_confiao/purchase.html b/tienda_ilusion/don_confiao/templates/don_confiao/purchase.html index 7f6c8d9..d174357 100644 --- a/tienda_ilusion/don_confiao/templates/don_confiao/purchase.html +++ b/tienda_ilusion/don_confiao/templates/don_confiao/purchase.html @@ -13,7 +13,7 @@ {% endfor %} - +
From 9ecd94912317c41db1a6751bfa109e1a293fcb49 Mon Sep 17 00:00:00 2001 From: Rodia Date: Sat, 13 Jul 2024 11:25:12 -0500 Subject: [PATCH 5/5] Feat(ReplaceNameIdSaleLine) --- .../don_confiao/static/js/add_line.js | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/tienda_ilusion/don_confiao/static/js/add_line.js b/tienda_ilusion/don_confiao/static/js/add_line.js index bfb38ed..4f6bc25 100644 --- a/tienda_ilusion/don_confiao/static/js/add_line.js +++ b/tienda_ilusion/don_confiao/static/js/add_line.js @@ -3,16 +3,27 @@ document.addEventListener('DOMContentLoaded', function(){ var formContainer = document.getElementById('formset-container'); var totalForms = document.getElementById('id_saleline_set-TOTAL_FORMS'); button.addEventListener('click', function(){ - // Clonar un formulario vacío var newForm = formContainer.querySelector('.form-container').cloneNode(true); - // Obtener el número actual de formularios var formCount = parseInt(totalForms.value); - // Actualizar los atributos de los nuevos campos del formulario var regex = new RegExp('__prefix__', 'g'); newForm.innerHTML = newForm.innerHTML.replace(regex, formCount); - // Añadir el nuevo formulario al contenedor + + var fields = newForm.querySelectorAll('[id^="id_saleline_set-"], [name^="saleline_set-"]'); + fields.forEach(function(field) { + var oldId = field.id; + var oldName = field.name; + + if (oldId) { + var newId = oldId.replace(/-\d+-/, '-' + formCount + '-'); + field.id = newId; + } + if (oldName) { + var newName = oldName.replace(/-\d+-/, '-' + formCount + '-'); + field.name = newName; + } + }); + formContainer.appendChild(newForm); - // Incrementar el total de formularios totalForms.value = formCount + 1; }); });