Feat: importando productos desde csv.
This commit is contained in:
		
							
								
								
									
										4
									
								
								tienda_ilusion/don_confiao/example_products.csv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								tienda_ilusion/don_confiao/example_products.csv
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
"producto","unidad","precio","categorias"
 | 
			
		||||
"Aceite de Coco Artesanal 500ml","Unidad", 50000,"Aceites&Alimentos"
 | 
			
		||||
"Café 500ml","Unidad", 14000,"Cafes&Alimentos"
 | 
			
		||||
"Café 250ml","Unidad", 7000,"Cafes&Alimentos"
 | 
			
		||||
		
		
			
  | 
							
								
								
									
										4
									
								
								tienda_ilusion/don_confiao/forms.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								tienda_ilusion/don_confiao/forms.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
from django import forms
 | 
			
		||||
 | 
			
		||||
class ImportProductsForm(forms.Form):
 | 
			
		||||
    csv_file = forms.FileField()
 | 
			
		||||
@@ -0,0 +1,30 @@
 | 
			
		||||
# Generated by Django 5.0.6 on 2024-06-29 18:55
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ('don_confiao', '0008_alter_sale_phone_alter_saleline_description'),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name='ProductCategory',
 | 
			
		||||
            fields=[
 | 
			
		||||
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
 | 
			
		||||
                ('name', models.CharField(max_length=100)),
 | 
			
		||||
            ],
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name='Product',
 | 
			
		||||
            fields=[
 | 
			
		||||
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
 | 
			
		||||
                ('name', models.CharField(max_length=100)),
 | 
			
		||||
                ('price', models.DecimalField(decimal_places=2, max_digits=9)),
 | 
			
		||||
                ('measuring_unit', models.CharField(choices=[('UNIT', 'Unit')], default='UNIT', max_length=20)),
 | 
			
		||||
                ('categories', models.ManyToManyField(to='don_confiao.productcategory')),
 | 
			
		||||
            ],
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
from django.db import models
 | 
			
		||||
 | 
			
		||||
from django.utils.translation import gettext_lazy as _
 | 
			
		||||
 | 
			
		||||
class Sale(models.Model):
 | 
			
		||||
 | 
			
		||||
@@ -16,3 +16,25 @@ class SaleLine(models.Model):
 | 
			
		||||
    quantity = models.IntegerField(null=True)
 | 
			
		||||
    unit_price = models.DecimalField(max_digits=9, decimal_places=2)
 | 
			
		||||
    description = models.CharField(max_length=255, null=True, blank=True)
 | 
			
		||||
 | 
			
		||||
class MeasuringUnits(models.TextChoices):
 | 
			
		||||
    UNIT = 'UNIT', _('Unit')
 | 
			
		||||
 | 
			
		||||
class ProductCategory(models.Model):
 | 
			
		||||
    name = models.CharField(max_length=100)
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return self.name
 | 
			
		||||
 | 
			
		||||
class Product(models.Model):
 | 
			
		||||
    name = models.CharField(max_length=100)
 | 
			
		||||
    price = models.DecimalField(max_digits=9, decimal_places=2)
 | 
			
		||||
    measuring_unit = models.CharField(
 | 
			
		||||
        max_length=20,
 | 
			
		||||
        choices=MeasuringUnits.choices,
 | 
			
		||||
        default=MeasuringUnits.UNIT
 | 
			
		||||
    )
 | 
			
		||||
    categories = models.ManyToManyField(ProductCategory)
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return self.name
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,10 @@
 | 
			
		||||
{% if form.is_multipart %}
 | 
			
		||||
    <form enctype="multipart/form-data" method="post">
 | 
			
		||||
{% else %}
 | 
			
		||||
    <form method="post">
 | 
			
		||||
{% endif %}
 | 
			
		||||
 | 
			
		||||
{% csrf_token %}
 | 
			
		||||
{{ form }}
 | 
			
		||||
<input type="submit" value="Importar">
 | 
			
		||||
</form>
 | 
			
		||||
@@ -3,4 +3,5 @@
 | 
			
		||||
<ul>
 | 
			
		||||
    <li><a href='./comprar'>Comprar</a></li>
 | 
			
		||||
    <li><a href='./compras'>Compras</a></li>
 | 
			
		||||
    <li><a href='./productos_index'>Productos</a></li>
 | 
			
		||||
</ul>
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,12 @@
 | 
			
		||||
<form action="{% url 'don_confiao:import_products' %}" method="post">
 | 
			
		||||
    {% csrf_token %}
 | 
			
		||||
    <fieldset>
 | 
			
		||||
        <legend><h1>Importar Productos</h1></legend>
 | 
			
		||||
        <div class="error_message">
 | 
			
		||||
            {% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
 | 
			
		||||
        </div>
 | 
			
		||||
        <label for="products_csv">Archivo CSV</label>
 | 
			
		||||
        <input type="file" accept="text/plain, .csv" name="choice" id="products_csv" value="{{ choice.id }}"></br>
 | 
			
		||||
        <input type="submit" value="Importar">
 | 
			
		||||
    </fieldset>
 | 
			
		||||
</form>
 | 
			
		||||
							
								
								
									
										29
									
								
								tienda_ilusion/don_confiao/test_products.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								tienda_ilusion/don_confiao/test_products.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
import os
 | 
			
		||||
import json
 | 
			
		||||
 | 
			
		||||
class TestProducts(TestCase):
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        self.client = Client()
 | 
			
		||||
 | 
			
		||||
    def test_import_products(self):
 | 
			
		||||
        app_name = "don_confiao"
 | 
			
		||||
        app_dir = os.path.join(settings.BASE_DIR, app_name)
 | 
			
		||||
        example_csv = os.path.join(app_dir, 'example_products.csv')
 | 
			
		||||
        products_in_example = 3
 | 
			
		||||
        with open(example_csv, 'rb') as csv:
 | 
			
		||||
            response = self.client.post(
 | 
			
		||||
                "/don_confiao/importar_productos",
 | 
			
		||||
                {"csv_file": csv}
 | 
			
		||||
            )
 | 
			
		||||
            products_response = self.client.get("/don_confiao/productos")
 | 
			
		||||
            products = json.loads(products_response.content.decode('utf-8'))
 | 
			
		||||
            self.assertEqual(
 | 
			
		||||
                len(products),
 | 
			
		||||
                products_in_example
 | 
			
		||||
            )
 | 
			
		||||
@@ -2,9 +2,12 @@ from django.urls import path
 | 
			
		||||
 | 
			
		||||
from . import views
 | 
			
		||||
 | 
			
		||||
app_name = 'don_confiao'
 | 
			
		||||
urlpatterns = [
 | 
			
		||||
    path("", views.index, name="wellcome"),
 | 
			
		||||
    path("comprar", views.buy, name="buy"),
 | 
			
		||||
    path("compras", views.purchases, name="purchases"),
 | 
			
		||||
    path("productos", views.products, name="products"),
 | 
			
		||||
    path("productos_index", views.products_index, name="products_index"),
 | 
			
		||||
    path("importar_productos", views.import_products, name="import_products")
 | 
			
		||||
]
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,12 @@
 | 
			
		||||
from django.shortcuts import render
 | 
			
		||||
from django.http import HttpResponse, JsonResponse
 | 
			
		||||
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
 | 
			
		||||
from django.template import loader
 | 
			
		||||
 | 
			
		||||
from .models import Sale
 | 
			
		||||
from .models import Sale, Product
 | 
			
		||||
from .forms import ImportProductsForm
 | 
			
		||||
 | 
			
		||||
import csv
 | 
			
		||||
import io
 | 
			
		||||
 | 
			
		||||
def index(request):
 | 
			
		||||
    return render(request, 'don_confiao/index.html')
 | 
			
		||||
@@ -22,18 +25,42 @@ def purchases(request):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def products(request):
 | 
			
		||||
    products = [
 | 
			
		||||
        {
 | 
			
		||||
            "name": "Aceite de Coco Artesanal 500ml",
 | 
			
		||||
            "price_list": 50000,
 | 
			
		||||
            "uom": "Unit",
 | 
			
		||||
            "category": "Aceites"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "Cafe 500ml",
 | 
			
		||||
            "price_list": 14000,
 | 
			
		||||
            "uom": "Unit",
 | 
			
		||||
            "category": "Cafes"
 | 
			
		||||
        },
 | 
			
		||||
    ]
 | 
			
		||||
    return JsonResponse(products, safe=False)
 | 
			
		||||
    rproducts = []
 | 
			
		||||
    products = Product.objects.all()
 | 
			
		||||
    for product in products:
 | 
			
		||||
        rproduct = {
 | 
			
		||||
            "name": product.name,
 | 
			
		||||
            "price_list": product.price,
 | 
			
		||||
            "uom": product.measuring_unit,
 | 
			
		||||
            "category": ""#.join('&', [c for c in product.categories])
 | 
			
		||||
        }
 | 
			
		||||
        rproducts.append(rproduct)
 | 
			
		||||
 | 
			
		||||
    return JsonResponse(rproducts, safe=False)
 | 
			
		||||
 | 
			
		||||
def products_index(request):
 | 
			
		||||
    return render(request, 'don_confiao/products_index.html')
 | 
			
		||||
 | 
			
		||||
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_index")
 | 
			
		||||
    else:
 | 
			
		||||
        form = ImportProductsForm()
 | 
			
		||||
    return render(
 | 
			
		||||
        request,
 | 
			
		||||
        "don_confiao/import_products.html",
 | 
			
		||||
        {'form': form}
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
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 = Product()
 | 
			
		||||
        product.name = row['producto']
 | 
			
		||||
        product.price = row['precio']
 | 
			
		||||
        product.measuring_unit = row['unidad']
 | 
			
		||||
        product.save()
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user