From ea9830a9762c567118995735c90991cab833a68a Mon Sep 17 00:00:00 2001 From: Pablo Moreno Date: Tue, 21 May 2024 19:36:28 +0200 Subject: [PATCH] feat: added sku and resetted migrations --- shop/api/v1/serializers.py | 6 + shop/migrations/0001_initial.py | 369 ++++++++++++++++-- ...it_order_status_product_images_and_more.py | 40 -- shop/migrations/0003_provider_productbatch.py | 114 ------ shop/migrations/0004_productbatch_provider.py | 25 -- ...5_tag_alter_product_images_product_tags.py | 41 -- ...ons_alter_productbatch_options_and_more.py | 47 --- ...er_options_alter_order_options_and_more.py | 86 ---- shop/migrations/0008_product_brand.py | 25 -- ...e_brand_last_modification_date_and_more.py | 147 ------- shop/models.py | 8 + shop/tests/test_api_products.py | 10 + shop/tests/test_shop_models.py | 3 + shop/utils.py | 4 +- tpv/migrations/0001_initial.py | 2 +- 15 files changed, 355 insertions(+), 572 deletions(-) delete mode 100644 shop/migrations/0002_remove_product_unit_order_status_product_images_and_more.py delete mode 100644 shop/migrations/0003_provider_productbatch.py delete mode 100644 shop/migrations/0004_productbatch_provider.py delete mode 100644 shop/migrations/0005_tag_alter_product_images_product_tags.py delete mode 100644 shop/migrations/0006_alter_product_options_alter_productbatch_options_and_more.py delete mode 100644 shop/migrations/0007_brand_alter_customer_options_alter_order_options_and_more.py delete mode 100644 shop/migrations/0008_product_brand.py delete mode 100644 shop/migrations/0009_brand_creation_date_brand_last_modification_date_and_more.py diff --git a/shop/api/v1/serializers.py b/shop/api/v1/serializers.py index 9216c96..8b7a185 100644 --- a/shop/api/v1/serializers.py +++ b/shop/api/v1/serializers.py @@ -67,6 +67,7 @@ class ProductSerializer(serializers.ModelSerializer): model = Product fields = ( "id", + "sku", "name", "description", "stock", @@ -86,6 +87,7 @@ class ListProductSerializer(serializers.ModelSerializer): model = Product fields = ( "id", + "sku", "name", "description", "stock", @@ -106,6 +108,7 @@ class CreateProductSerializer(serializers.ModelSerializer): def create(self, validated_data): instance = Product.objects.create( + sku=validated_data.get("sku"), name=validated_data.get("name"), description=validated_data.get("description"), stock=validated_data.get("stock"), @@ -124,12 +127,14 @@ class CreateProductSerializer(serializers.ModelSerializer): tax=validated_data.get("tax"), current=True, ) + return instance class Meta: model = Product fields = ( "id", + "sku", "name", "description", "stock", @@ -147,6 +152,7 @@ class UpdateProductSerializer(serializers.ModelSerializer): model = Product fields = ( "id", + "sku", "name", "description", "stock", diff --git a/shop/migrations/0001_initial.py b/shop/migrations/0001_initial.py index 5a2bec8..4a7ebf2 100644 --- a/shop/migrations/0001_initial.py +++ b/shop/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 5.0.3 on 2024-04-24 14:00 +# Generated by Django 5.0.6 on 2024-05-21 17:19 import django.db.models.deletion import django.utils.timezone @@ -11,9 +11,47 @@ class Migration(migrations.Migration): initial = True - dependencies = [] + dependencies = [ + ("files", "0001_initial"), + ] operations = [ + migrations.CreateModel( + name="Brand", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "creation_date", + models.DateTimeField( + auto_now_add=True, verbose_name="Fecha de creación" + ), + ), + ( + "last_modification_date", + models.DateTimeField( + auto_now=True, verbose_name="Fecha de última modificación" + ), + ), + ( + "name", + models.CharField( + max_length=100, unique=True, verbose_name="Nombre" + ), + ), + ], + options={ + "verbose_name": "marca", + "verbose_name_plural": "marcas", + }, + ), migrations.CreateModel( name="Customer", fields=[ @@ -26,6 +64,18 @@ class Migration(migrations.Migration): verbose_name="ID", ), ), + ( + "creation_date", + models.DateTimeField( + auto_now_add=True, verbose_name="Fecha de creación" + ), + ), + ( + "last_modification_date", + models.DateTimeField( + auto_now=True, verbose_name="Fecha de última modificación" + ), + ), ( "vat_id", models.CharField( @@ -47,12 +97,12 @@ class Migration(migrations.Migration): ("zip", models.CharField(max_length=32, verbose_name="Código postal")), ], options={ - "verbose_name": "Cliente", - "verbose_name_plural": "Clientes", + "verbose_name": "cliente", + "verbose_name_plural": "clientes", }, ), migrations.CreateModel( - name="Product", + name="Provider", fields=[ ( "id", @@ -63,38 +113,72 @@ class Migration(migrations.Migration): verbose_name="ID", ), ), - ("name", models.CharField(max_length=96, verbose_name="Nombre")), ( - "description", + "creation_date", + models.DateTimeField( + auto_now_add=True, verbose_name="Fecha de creación" + ), + ), + ( + "last_modification_date", + models.DateTimeField( + auto_now=True, verbose_name="Fecha de última modificación" + ), + ), + ( + "vat_id", + models.CharField( + max_length=32, + unique=True, + verbose_name="Documento de identidad", + ), + ), + ("name", models.CharField(max_length=64, verbose_name="Nombre")), + ( + "email", + models.EmailField( + max_length=254, verbose_name="E-mail de contacto" + ), + ), + ( + "phone", models.CharField( blank=True, default="", - max_length=1000, - verbose_name="Descripción", - ), - ), - ( - "stock", - models.DecimalField( - decimal_places=4, - default=Decimal("0"), - max_digits=13, - verbose_name="Stock", - ), - ), - ( - "unit", - models.CharField( - choices=[("UNIT", "Unidad"), ("KG", "kg"), ("L", "L")], - default="UNIT", - max_length=6, - verbose_name="Unidad de medida", + max_length=16, + null=True, + verbose_name="Teléfono de contacto", ), ), + ("address", models.CharField(max_length=255, verbose_name="Dirección")), + ("city", models.CharField(max_length=64, verbose_name="Ciudad")), + ("state", models.CharField(max_length=64, verbose_name="Región")), + ("country", models.CharField(max_length=64, verbose_name="País")), + ("zip", models.CharField(max_length=32, verbose_name="Código postal")), ], options={ - "verbose_name": "Producto", - "verbose_name_plural": "Productos", + "verbose_name": "proveedor", + "verbose_name_plural": "proveedores", + }, + ), + migrations.CreateModel( + name="Tag", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=16)), + ], + options={ + "verbose_name": "etiqueta", + "verbose_name_plural": "etiquetas", + "ordering": ("name",), }, ), migrations.CreateModel( @@ -109,6 +193,18 @@ class Migration(migrations.Migration): verbose_name="ID", ), ), + ( + "creation_date", + models.DateTimeField( + auto_now_add=True, verbose_name="Fecha de creación" + ), + ), + ( + "last_modification_date", + models.DateTimeField( + auto_now=True, verbose_name="Fecha de última modificación" + ), + ), ( "code", models.CharField( @@ -123,8 +219,8 @@ class Migration(migrations.Migration): ), ], options={ - "verbose_name": "Impuesto", - "verbose_name_plural": "Impuestos", + "verbose_name": "impuesto", + "verbose_name_plural": "impuestos", }, ), migrations.CreateModel( @@ -139,12 +235,6 @@ class Migration(migrations.Migration): verbose_name="ID", ), ), - ( - "uuid", - models.UUIDField( - db_index=True, default=uuid.uuid4, verbose_name="UUID" - ), - ), ( "creation_date", models.DateTimeField( @@ -157,6 +247,18 @@ class Migration(migrations.Migration): auto_now=True, verbose_name="Fecha de última modificación" ), ), + ( + "uuid", + models.UUIDField( + db_index=True, default=uuid.uuid4, verbose_name="UUID" + ), + ), + ( + "status", + models.CharField( + default="PEN", max_length=3, verbose_name="Estado" + ), + ), ( "base_total", models.DecimalField( @@ -239,8 +341,88 @@ class Migration(migrations.Migration): ), ], options={ - "verbose_name": "Pedido", - "verbose_name_plural": "Pedidos", + "verbose_name": "pedido", + "verbose_name_plural": "pedidos", + }, + ), + migrations.CreateModel( + name="Product", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "creation_date", + models.DateTimeField( + auto_now_add=True, verbose_name="Fecha de creación" + ), + ), + ( + "last_modification_date", + models.DateTimeField( + auto_now=True, verbose_name="Fecha de última modificación" + ), + ), + ( + "sku", + models.CharField( + max_length=64, unique=True, verbose_name="Código de referencia" + ), + ), + ("name", models.CharField(max_length=96, verbose_name="Nombre")), + ( + "description", + models.CharField( + blank=True, + default="", + max_length=1000, + verbose_name="Descripción", + ), + ), + ( + "stock", + models.DecimalField( + decimal_places=4, + default=Decimal("0"), + max_digits=13, + verbose_name="Stock", + ), + ), + ("is_digital_asset", models.BooleanField(default=False)), + ("url", models.URLField(blank=True, verbose_name="URL de descarga")), + ( + "brand", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="shop.brand", + verbose_name="Marca", + ), + ), + ( + "images", + models.ManyToManyField( + blank=True, to="files.fileupload", verbose_name="Imágenes" + ), + ), + ( + "tags", + models.ManyToManyField( + blank=True, to="shop.tag", verbose_name="Etiquetas" + ), + ), + ], + options={ + "verbose_name": "producto", + "verbose_name_plural": "productos", + "ordering": ("-id",), }, ), migrations.CreateModel( @@ -255,6 +437,18 @@ class Migration(migrations.Migration): verbose_name="ID", ), ), + ( + "creation_date", + models.DateTimeField( + auto_now_add=True, verbose_name="Fecha de creación" + ), + ), + ( + "last_modification_date", + models.DateTimeField( + auto_now=True, verbose_name="Fecha de última modificación" + ), + ), ( "quantity", models.DecimalField( @@ -314,8 +508,79 @@ class Migration(migrations.Migration): ), ], options={ - "verbose_name": "Línea de pedido", - "verbose_name_plural": "Líneas de pedido", + "verbose_name": "línea de pedido", + "verbose_name_plural": "líneas de pedido", + }, + ), + migrations.CreateModel( + name="ProductBatch", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "creation_date", + models.DateTimeField( + auto_now_add=True, verbose_name="Fecha de creación" + ), + ), + ( + "last_modification_date", + models.DateTimeField( + auto_now=True, verbose_name="Fecha de última modificación" + ), + ), + ( + "code", + models.CharField( + db_index=True, max_length=32, unique=True, verbose_name="Código" + ), + ), + ( + "quantity", + models.DecimalField( + decimal_places=4, + default=Decimal("1"), + max_digits=13, + verbose_name="Cantidad", + ), + ), + ( + "expiration_date", + models.DateField( + blank=True, + null=True, + verbose_name="Fecha de caducidad / consumo preferente", + ), + ), + ( + "product", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="shop.product", + verbose_name="Producto", + ), + ), + ( + "provider", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="shop.provider", + verbose_name="Proveedor", + ), + ), + ], + options={ + "verbose_name": "remesa de producto", + "verbose_name_plural": "remesas de productos", }, ), migrations.CreateModel( @@ -330,6 +595,18 @@ class Migration(migrations.Migration): verbose_name="ID", ), ), + ( + "creation_date", + models.DateTimeField( + auto_now_add=True, verbose_name="Fecha de creación" + ), + ), + ( + "last_modification_date", + models.DateTimeField( + auto_now=True, verbose_name="Fecha de última modificación" + ), + ), ( "price", models.DecimalField( @@ -342,6 +619,12 @@ class Migration(migrations.Migration): default=django.utils.timezone.now, verbose_name="Fecha" ), ), + ( + "current", + models.BooleanField( + default=False, verbose_name="Es el precio actual" + ), + ), ( "product", models.ForeignKey( @@ -361,8 +644,8 @@ class Migration(migrations.Migration): ), ], options={ - "verbose_name": "Precio de producto", - "verbose_name_plural": "Precio de producto", + "verbose_name": "precio de producto", + "verbose_name_plural": "precio de producto", }, ), ] diff --git a/shop/migrations/0002_remove_product_unit_order_status_product_images_and_more.py b/shop/migrations/0002_remove_product_unit_order_status_product_images_and_more.py deleted file mode 100644 index 89932b4..0000000 --- a/shop/migrations/0002_remove_product_unit_order_status_product_images_and_more.py +++ /dev/null @@ -1,40 +0,0 @@ -# Generated by Django 5.0.3 on 2024-05-04 22:12 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("files", "0001_initial"), - ("shop", "0001_initial"), - ] - - operations = [ - migrations.RemoveField( - model_name="product", - name="unit", - ), - migrations.AddField( - model_name="order", - name="status", - field=models.CharField(default="PEN", max_length=3, verbose_name="Estado"), - ), - migrations.AddField( - model_name="product", - name="images", - field=models.ManyToManyField( - blank=True, to="files.fileupload", verbose_name="Imágenes" - ), - ), - migrations.AddField( - model_name="product", - name="is_digital_asset", - field=models.BooleanField(default=False), - ), - migrations.AddField( - model_name="product", - name="url", - field=models.URLField(blank=True, verbose_name="URL de descarga"), - ), - ] diff --git a/shop/migrations/0003_provider_productbatch.py b/shop/migrations/0003_provider_productbatch.py deleted file mode 100644 index 4f3f491..0000000 --- a/shop/migrations/0003_provider_productbatch.py +++ /dev/null @@ -1,114 +0,0 @@ -# Generated by Django 5.0.3 on 2024-05-12 23:18 - -import django.db.models.deletion -from decimal import Decimal -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("shop", "0002_remove_product_unit_order_status_product_images_and_more"), - ] - - operations = [ - migrations.CreateModel( - name="Provider", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "vat_id", - models.CharField( - max_length=32, - unique=True, - verbose_name="Documento de identidad", - ), - ), - ("name", models.CharField(max_length=64, verbose_name="Nombre")), - ( - "email", - models.EmailField( - max_length=254, verbose_name="E-mail de contacto" - ), - ), - ( - "phone", - models.CharField( - blank=True, - default="", - max_length=16, - null=True, - verbose_name="Teléfono de contacto", - ), - ), - ("address", models.CharField(max_length=255, verbose_name="Dirección")), - ("city", models.CharField(max_length=64, verbose_name="Ciudad")), - ("state", models.CharField(max_length=64, verbose_name="Región")), - ("country", models.CharField(max_length=64, verbose_name="País")), - ("zip", models.CharField(max_length=32, verbose_name="Código postal")), - ], - options={ - "verbose_name": "Proveedor", - "verbose_name_plural": "Proveedores", - }, - ), - migrations.CreateModel( - name="ProductBatch", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "code", - models.CharField( - db_index=True, max_length=32, unique=True, verbose_name="Código" - ), - ), - ( - "quantity", - models.DecimalField( - decimal_places=4, - default=Decimal("1"), - max_digits=13, - verbose_name="Cantidad", - ), - ), - ( - "creation_date", - models.DateTimeField( - auto_now_add=True, verbose_name="Fecha de creación" - ), - ), - ( - "expiration_date", - models.DateField( - blank=True, - null=True, - verbose_name="Fecha de caducidad / consumo preferente", - ), - ), - ( - "product", - models.ForeignKey( - on_delete=django.db.models.deletion.PROTECT, - to="shop.product", - verbose_name="Producto", - ), - ), - ], - ), - ] diff --git a/shop/migrations/0004_productbatch_provider.py b/shop/migrations/0004_productbatch_provider.py deleted file mode 100644 index 4f32db3..0000000 --- a/shop/migrations/0004_productbatch_provider.py +++ /dev/null @@ -1,25 +0,0 @@ -# Generated by Django 5.0.6 on 2024-05-14 15:54 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("shop", "0003_provider_productbatch"), - ] - - operations = [ - migrations.AddField( - model_name="productbatch", - name="provider", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - to="shop.provider", - verbose_name="Proveedor", - ), - ), - ] diff --git a/shop/migrations/0005_tag_alter_product_images_product_tags.py b/shop/migrations/0005_tag_alter_product_images_product_tags.py deleted file mode 100644 index 8f81c63..0000000 --- a/shop/migrations/0005_tag_alter_product_images_product_tags.py +++ /dev/null @@ -1,41 +0,0 @@ -# Generated by Django 5.0.6 on 2024-05-14 16:04 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("files", "0001_initial"), - ("shop", "0004_productbatch_provider"), - ] - - operations = [ - migrations.CreateModel( - name="Tag", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("name", models.CharField(max_length=16)), - ], - ), - migrations.AlterField( - model_name="product", - name="images", - field=models.ManyToManyField( - to="files.fileupload", verbose_name="Imágenes" - ), - ), - migrations.AddField( - model_name="product", - name="tags", - field=models.ManyToManyField(to="shop.tag", verbose_name="Etiquetas"), - ), - ] diff --git a/shop/migrations/0006_alter_product_options_alter_productbatch_options_and_more.py b/shop/migrations/0006_alter_product_options_alter_productbatch_options_and_more.py deleted file mode 100644 index 1aed582..0000000 --- a/shop/migrations/0006_alter_product_options_alter_productbatch_options_and_more.py +++ /dev/null @@ -1,47 +0,0 @@ -# Generated by Django 5.0.6 on 2024-05-17 00:13 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("files", "0001_initial"), - ("shop", "0005_tag_alter_product_images_product_tags"), - ] - - operations = [ - migrations.AlterModelOptions( - name="product", - options={ - "ordering": ("id",), - "verbose_name": "Producto", - "verbose_name_plural": "Productos", - }, - ), - migrations.AlterModelOptions( - name="productbatch", - options={ - "verbose_name": "Remesa de producto", - "verbose_name_plural": "Remesas de productos", - }, - ), - migrations.AlterModelOptions( - name="tag", - options={"verbose_name": "Etiqueta", "verbose_name_plural": "Etiquetas"}, - ), - migrations.AlterField( - model_name="product", - name="images", - field=models.ManyToManyField( - blank=True, to="files.fileupload", verbose_name="Imágenes" - ), - ), - migrations.AlterField( - model_name="product", - name="tags", - field=models.ManyToManyField( - blank=True, to="shop.tag", verbose_name="Etiquetas" - ), - ), - ] diff --git a/shop/migrations/0007_brand_alter_customer_options_alter_order_options_and_more.py b/shop/migrations/0007_brand_alter_customer_options_alter_order_options_and_more.py deleted file mode 100644 index 1ffbf88..0000000 --- a/shop/migrations/0007_brand_alter_customer_options_alter_order_options_and_more.py +++ /dev/null @@ -1,86 +0,0 @@ -# Generated by Django 5.0.6 on 2024-05-19 14:58 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("shop", "0006_alter_product_options_alter_productbatch_options_and_more"), - ] - - operations = [ - migrations.CreateModel( - name="Brand", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "name", - models.CharField( - max_length=100, unique=True, verbose_name="Nombre" - ), - ), - ], - options={ - "verbose_name": "marca", - "verbose_name_plural": "marcas", - }, - ), - migrations.AlterModelOptions( - name="customer", - options={"verbose_name": "cliente", "verbose_name_plural": "clientes"}, - ), - migrations.AlterModelOptions( - name="order", - options={"verbose_name": "pedido", "verbose_name_plural": "pedidos"}, - ), - migrations.AlterModelOptions( - name="orderline", - options={ - "verbose_name": "línea de pedido", - "verbose_name_plural": "líneas de pedido", - }, - ), - migrations.AlterModelOptions( - name="product", - options={ - "ordering": ("-id",), - "verbose_name": "producto", - "verbose_name_plural": "productos", - }, - ), - migrations.AlterModelOptions( - name="productbatch", - options={ - "verbose_name": "remesa de producto", - "verbose_name_plural": "remesas de productos", - }, - ), - migrations.AlterModelOptions( - name="productprice", - options={ - "verbose_name": "precio de producto", - "verbose_name_plural": "precio de producto", - }, - ), - migrations.AlterModelOptions( - name="provider", - options={"verbose_name": "proveedor", "verbose_name_plural": "proveedores"}, - ), - migrations.AlterModelOptions( - name="tag", - options={"verbose_name": "etiqueta", "verbose_name_plural": "etiquetas"}, - ), - migrations.AlterModelOptions( - name="tax", - options={"verbose_name": "impuesto", "verbose_name_plural": "impuestos"}, - ), - ] diff --git a/shop/migrations/0008_product_brand.py b/shop/migrations/0008_product_brand.py deleted file mode 100644 index 2fe5aca..0000000 --- a/shop/migrations/0008_product_brand.py +++ /dev/null @@ -1,25 +0,0 @@ -# Generated by Django 5.0.6 on 2024-05-19 15:21 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("shop", "0007_brand_alter_customer_options_alter_order_options_and_more"), - ] - - operations = [ - migrations.AddField( - model_name="product", - name="brand", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - to="shop.brand", - verbose_name="Marca", - ), - ), - ] diff --git a/shop/migrations/0009_brand_creation_date_brand_last_modification_date_and_more.py b/shop/migrations/0009_brand_creation_date_brand_last_modification_date_and_more.py deleted file mode 100644 index 002a645..0000000 --- a/shop/migrations/0009_brand_creation_date_brand_last_modification_date_and_more.py +++ /dev/null @@ -1,147 +0,0 @@ -# Generated by Django 5.0.6 on 2024-05-19 18:38 - -import django.utils.timezone -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("shop", "0008_product_brand"), - ] - - operations = [ - migrations.AddField( - model_name="brand", - name="creation_date", - field=models.DateTimeField( - auto_now_add=True, - default=django.utils.timezone.now, - verbose_name="Fecha de creación", - ), - preserve_default=False, - ), - migrations.AddField( - model_name="brand", - name="last_modification_date", - field=models.DateTimeField( - auto_now=True, verbose_name="Fecha de última modificación" - ), - ), - migrations.AddField( - model_name="customer", - name="creation_date", - field=models.DateTimeField( - auto_now_add=True, - default=django.utils.timezone.now, - verbose_name="Fecha de creación", - ), - preserve_default=False, - ), - migrations.AddField( - model_name="customer", - name="last_modification_date", - field=models.DateTimeField( - auto_now=True, verbose_name="Fecha de última modificación" - ), - ), - migrations.AddField( - model_name="orderline", - name="creation_date", - field=models.DateTimeField( - auto_now_add=True, - default=django.utils.timezone.now, - verbose_name="Fecha de creación", - ), - preserve_default=False, - ), - migrations.AddField( - model_name="orderline", - name="last_modification_date", - field=models.DateTimeField( - auto_now=True, verbose_name="Fecha de última modificación" - ), - ), - migrations.AddField( - model_name="product", - name="creation_date", - field=models.DateTimeField( - auto_now_add=True, - default=django.utils.timezone.now, - verbose_name="Fecha de creación", - ), - preserve_default=False, - ), - migrations.AddField( - model_name="product", - name="last_modification_date", - field=models.DateTimeField( - auto_now=True, verbose_name="Fecha de última modificación" - ), - ), - migrations.AddField( - model_name="productbatch", - name="last_modification_date", - field=models.DateTimeField( - auto_now=True, verbose_name="Fecha de última modificación" - ), - ), - migrations.AddField( - model_name="productprice", - name="creation_date", - field=models.DateTimeField( - auto_now_add=True, - default=django.utils.timezone.now, - verbose_name="Fecha de creación", - ), - preserve_default=False, - ), - migrations.AddField( - model_name="productprice", - name="current", - field=models.BooleanField( - default=False, verbose_name="Es el precio actual" - ), - ), - migrations.AddField( - model_name="productprice", - name="last_modification_date", - field=models.DateTimeField( - auto_now=True, verbose_name="Fecha de última modificación" - ), - ), - migrations.AddField( - model_name="provider", - name="creation_date", - field=models.DateTimeField( - auto_now_add=True, - default=django.utils.timezone.now, - verbose_name="Fecha de creación", - ), - preserve_default=False, - ), - migrations.AddField( - model_name="provider", - name="last_modification_date", - field=models.DateTimeField( - auto_now=True, verbose_name="Fecha de última modificación" - ), - ), - migrations.AddField( - model_name="tax", - name="creation_date", - field=models.DateTimeField( - auto_now_add=True, - default=django.utils.timezone.now, - verbose_name="Fecha de creación", - ), - preserve_default=False, - ), - migrations.AddField( - model_name="tax", - name="last_modification_date", - field=models.DateTimeField( - auto_now=True, verbose_name="Fecha de última modificación" - ), - ), - ] diff --git a/shop/models.py b/shop/models.py index 9fb07cb..573a42f 100644 --- a/shop/models.py +++ b/shop/models.py @@ -27,9 +27,17 @@ class Tag(models.Model): class Meta: verbose_name = _("etiqueta") verbose_name_plural = _("etiquetas") + ordering = ("name",) class Product(TimestampedModel): + sku = models.CharField( + max_length=64, + blank=False, + null=False, + unique=True, + verbose_name=_("Código de referencia"), + ) name = models.CharField( max_length=96, blank=False, diff --git a/shop/tests/test_api_products.py b/shop/tests/test_api_products.py index 029386d..9a8fc4c 100644 --- a/shop/tests/test_api_products.py +++ b/shop/tests/test_api_products.py @@ -1,3 +1,5 @@ +import random +import string from decimal import Decimal from rest_framework import status @@ -19,8 +21,12 @@ class TestProductsAPI(APITestCase, TestUserAuthenticationMixin): ) self.tag = Tag.objects.create(name="Alimentos") + def get_random_sku(self): + return ''.join(random.choices(string.ascii_uppercase, k=16)) + def create_products(self): self.product = Product.objects.create( + sku=self.get_random_sku(), name="Papafritas", description="Las mejores papafritas", is_digital_asset=False, @@ -52,6 +58,7 @@ class TestProductsAPI(APITestCase, TestUserAuthenticationMixin): response = self.client.post( "/api/v1/shop/products/", { + "sku": self.get_random_sku(), "name": "Papafritas", "description": "Las mejores papafritas", "is_digital_asset": False, @@ -73,6 +80,7 @@ class TestProductsAPI(APITestCase, TestUserAuthenticationMixin): response = self.client.post( "/api/v1/shop/products/", { + "sku": self.get_random_sku(), "name": "Papafritas", "description": "Las mejores papafritas", "is_digital_asset": False, @@ -103,6 +111,7 @@ class TestProductsAPI(APITestCase, TestUserAuthenticationMixin): response = self.client.post( "/api/v1/shop/products/", { + "sku": self.get_random_sku(), "name": "Papafritas", "description": "Las mejores papafritas", "is_digital_asset": False, @@ -142,6 +151,7 @@ class TestProductsAPI(APITestCase, TestUserAuthenticationMixin): response = self.client.post( "/api/v1/shop/products/", { + "sku": self.get_random_sku(), "name": "Papafritas", "description": "Las mejores papafritas", "is_digital_asset": False, diff --git a/shop/tests/test_shop_models.py b/shop/tests/test_shop_models.py index 2ec83f5..849abb2 100644 --- a/shop/tests/test_shop_models.py +++ b/shop/tests/test_shop_models.py @@ -14,14 +14,17 @@ class ShopModelsTest(TestCase): def create_products(self): self.potatoes = Product.objects.create( + sku='0000001', name="Patatas", stock=Decimal("100.00"), ) self.gasoline = Product.objects.create( + sku='0000002', name="Gasolina", stock=Decimal("800.00"), ) self.usb_c = Product.objects.create( + sku='0000003', name="Cable USB-C", stock=Decimal("5.00"), ) diff --git a/shop/utils.py b/shop/utils.py index b4365c5..9440675 100644 --- a/shop/utils.py +++ b/shop/utils.py @@ -1,8 +1,6 @@ from decimal import Decimal -from typing import Iterable -from shop.models import OrderLine, Tax, Product, Order, Customer -from django.db.models import QuerySet +from shop.models import OrderLine, Product, Order, Customer def create_order_line_for_product(product: Product, quantity: Decimal, order: Order): diff --git a/tpv/migrations/0001_initial.py b/tpv/migrations/0001_initial.py index 2966dd4..f56db61 100644 --- a/tpv/migrations/0001_initial.py +++ b/tpv/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 5.0.3 on 2024-03-24 19:19 +# Generated by Django 5.0.6 on 2024-05-21 17:19 import tpv.models import uuid