Save product unit price in basket item

This commit is contained in:
Gabriel Augendre 2022-04-27 20:46:02 +02:00
parent 6fc9522ca0
commit 394882f541
5 changed files with 77 additions and 11 deletions

View file

@ -51,13 +51,19 @@ class BasketForm(forms.ModelForm):
def save(self, commit=True):
instance: Basket = super().save(commit=True)
name: str
products = {product.id: product for product in Product.objects.all()}
for name, value in self.cleaned_data.items():
if name.startswith(PREFIX):
product_id = int(name.removeprefix(PREFIX))
product = products[product_id]
if value > 0:
instance.items.update_or_create(
product_id=product_id, defaults={"quantity": value}
product=product,
defaults={
"quantity": value,
"unit_price_cents": product.unit_price_cents,
},
)
if value == 0:
instance.items.filter(product_id=product_id).delete()
instance.items.filter(product=product).delete()
return instance

View file

@ -41,7 +41,10 @@ class Command(BaseCommand):
product = random.choice(products)
items.append(
BasketItem(
product=product, basket=basket, quantity=random.randint(1, 3)
product=product,
basket=basket,
quantity=random.randint(1, 3),
unit_price_cents=product.unit_price_cents,
)
)
BasketItem.objects.bulk_create(items)

View file

@ -0,0 +1,35 @@
# Generated by Django 4.0.4 on 2022-04-27 18:30
from django.db import migrations, models
def forwards(apps, schema_editor):
BasketItem = apps.get_model("purchase", "BasketItem")
items = (
BasketItem.objects.using(schema_editor.connection.alias)
.all()
.select_related("product")
)
for item in items:
item.unit_price_cents = item.product.unit_price_cents
BasketItem.objects.bulk_update(items, ["unit_price_cents"])
class Migration(migrations.Migration):
dependencies = [
("purchase", "0005_alter_basket_options_alter_basketitem_options_and_more"),
]
operations = [
migrations.AddField(
model_name="basketitem",
name="unit_price_cents",
field=models.PositiveIntegerField(
help_text="product's unit price in cents at the time of purchase",
null=True,
verbose_name="unit price (cents)",
),
),
migrations.RunPython(forwards, migrations.RunPython.noop),
]

View file

@ -0,0 +1,21 @@
# Generated by Django 4.0.4 on 2022-04-27 18:41
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("purchase", "0006_basketitem_unit_price_cents"),
]
operations = [
migrations.AlterField(
model_name="basketitem",
name="unit_price_cents",
field=models.PositiveIntegerField(
help_text="product's unit price in cents at the time of purchase",
verbose_name="unit price (cents)",
),
),
]

View file

@ -23,7 +23,7 @@ class PaymentMethodQuerySet(models.QuerySet):
turnover=Coalesce(
Sum(
F("baskets__items__quantity")
* F("baskets__items__product__unit_price_cents")
* F("baskets__items__unit_price_cents")
),
0,
)
@ -65,7 +65,8 @@ class ProductQuerySet(models.QuerySet):
def with_turnover(self):
return self.annotate(
turnover=Coalesce(
Sum(F("basket_items__quantity") * F("unit_price_cents")), 0
Sum(F("basket_items__quantity") * F("basket_items__unit_price_cents")),
0,
)
)
@ -140,9 +141,7 @@ class Product(Model):
class BasketQuerySet(models.QuerySet):
def priced(self) -> BasketQuerySet:
return self.annotate(
price=Coalesce(
Sum(F("items__quantity") * F("items__product__unit_price_cents")), 0
)
price=Coalesce(Sum(F("items__quantity") * F("items__unit_price_cents")), 0)
)
def average_basket(self) -> float:
@ -183,9 +182,7 @@ class Basket(Model):
class BasketItemQuerySet(models.QuerySet):
def priced(self):
return self.annotate(
price=Coalesce(F("quantity") * F("product__unit_price_cents"), 0)
)
return self.annotate(price=Coalesce(F("quantity") * F("unit_price_cents"), 0))
class BasketItem(Model):
@ -202,6 +199,10 @@ class BasketItem(Model):
verbose_name=_("basket"),
)
quantity = models.PositiveIntegerField(verbose_name=_("quantity"))
unit_price_cents = models.PositiveIntegerField(
verbose_name=_("unit price (cents)"),
help_text=_("product's unit price in cents at the time of purchase"),
)
objects = BasketItemQuerySet.as_manager()