diff --git a/shop/api/v1/serializers.py b/shop/api/v1/serializers.py index fc3962a..9216c96 100644 --- a/shop/api/v1/serializers.py +++ b/shop/api/v1/serializers.py @@ -42,6 +42,7 @@ class ProductPriceSerializer(serializers.ModelSerializer): model = ProductPrice fields = ( "price", + "current", "date", "tax", "price_with_tax", @@ -121,6 +122,7 @@ class CreateProductSerializer(serializers.ModelSerializer): date=timezone.now(), price=validated_data.get("price"), tax=validated_data.get("tax"), + current=True, ) return instance diff --git a/shop/api/v1/viewsets.py b/shop/api/v1/viewsets.py index c887cd8..fd492dc 100644 --- a/shop/api/v1/viewsets.py +++ b/shop/api/v1/viewsets.py @@ -90,7 +90,9 @@ class ProductPriceViewSet(ModelViewSet): return self.serializer_class def perform_create(self, serializer): - serializer.save(product_id=self.kwargs.get("product_id")) + product = get_object_or_404(Product, pk=self.kwargs.get("product_id")) + product.prices.all().update(current=False) + serializer.save(product=product, current=True) class ProductBatchViewSet(ModelViewSet): @@ -115,6 +117,7 @@ class TaxViewSet(ModelViewSet): serializer_class = TaxSerializer queryset = Tax.objects.all() permission_classes = (IsAdminUser,) + search_fields = ('code', ) class OrderViewSet(ModelViewSet): 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 new file mode 100644 index 0000000..d6a352e --- /dev/null +++ b/shop/migrations/0009_brand_creation_date_brand_last_modification_date_and_more.py @@ -0,0 +1,145 @@ +# 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 97cd9d7..bf065ac 100644 --- a/shop/models.py +++ b/shop/models.py @@ -6,6 +6,18 @@ from django.utils import timezone from django.utils.text import gettext_lazy as _ +class TimestampedModel(models.Model): + 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") + ) + + class Meta: + abstract = True + + class Tag(models.Model): name = models.CharField(max_length=16) @@ -17,7 +29,7 @@ class Tag(models.Model): verbose_name_plural = _("etiquetas") -class Product(models.Model): +class Product(TimestampedModel): name = models.CharField( max_length=96, blank=False, @@ -55,7 +67,7 @@ class Product(models.Model): @property def price(self): - return self.prices.last() + return self.prices.filter(current=True).first() class Meta: verbose_name = _("producto") @@ -63,7 +75,7 @@ class Product(models.Model): ordering = ("-id",) -class ProductPrice(models.Model): +class ProductPrice(TimestampedModel): price = models.DecimalField( max_digits=11, decimal_places=2, verbose_name=_("Precio") ) @@ -79,6 +91,7 @@ class ProductPrice(models.Model): on_delete=models.PROTECT, verbose_name=_("Impuesto aplicable"), ) + current = models.BooleanField(default=False, verbose_name=_('Es el precio actual')) def __str__(self): return f"{self.price} - {self.tax.code}" @@ -93,7 +106,7 @@ class ProductPrice(models.Model): verbose_name_plural = _("precio de producto") -class ProductBatch(models.Model): +class ProductBatch(TimestampedModel): code = models.CharField( max_length=32, unique=True, db_index=True, verbose_name=_("Código") ) @@ -106,9 +119,6 @@ class ProductBatch(models.Model): default=Decimal("1"), 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") ) @@ -128,7 +138,7 @@ class ProductBatch(models.Model): verbose_name_plural = _("remesas de productos") -class Tax(models.Model): +class Tax(TimestampedModel): code = models.CharField( max_length=8, blank=False, unique=True, verbose_name=_("Código de impuesto") ) @@ -144,7 +154,7 @@ class Tax(models.Model): verbose_name_plural = _("impuestos") -class Customer(models.Model): +class Customer(TimestampedModel): vat_id = models.CharField( max_length=32, blank=False, @@ -171,7 +181,7 @@ class Customer(models.Model): verbose_name_plural = _("clientes") -class Provider(models.Model): +class Provider(TimestampedModel): vat_id = models.CharField( max_length=32, blank=False, @@ -203,7 +213,7 @@ class Provider(models.Model): verbose_name_plural = _("proveedores") -class Brand(models.Model): +class Brand(TimestampedModel): name = models.CharField( max_length=100, unique=True, blank=False, null=False, verbose_name=_("Nombre") ) @@ -213,7 +223,7 @@ class Brand(models.Model): verbose_name_plural = _("marcas") -class OrderLine(models.Model): +class OrderLine(TimestampedModel): order = models.ForeignKey( "shop.Order", on_delete=models.CASCADE, @@ -274,7 +284,7 @@ class OrderLine(models.Model): verbose_name_plural = _("líneas de pedido") -class Order(models.Model): +class Order(TimestampedModel): class Statuses(models.TextChoices): STATUS_PENDING = "PEN", _("Pendiente de pago") STATUS_PAID = "PAI", _("Pagado") @@ -292,13 +302,6 @@ class Order(models.Model): max_length=3, default=Statuses.STATUS_PENDING, verbose_name=_("Estado") ) - 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") - ) - base_total = models.DecimalField( default=Decimal("0"), max_digits=13,