From 193c1824227cc6063716683447fbd2a7e742aeff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=AD=C3=B0ir=20Valberg=20Gu=C3=B0mundsson?= Date: Sat, 21 Apr 2018 17:00:39 +0200 Subject: [PATCH] Add stock_amount to product and reflect it in product detail template. (#213) --- .../migrations/0054_auto_20180415_1159.py | 34 +++++++++++++++++++ src/shop/models.py | 30 +++++++++++++++- src/shop/templates/product_detail.html | 9 +++++ 3 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 src/shop/migrations/0054_auto_20180415_1159.py diff --git a/src/shop/migrations/0054_auto_20180415_1159.py b/src/shop/migrations/0054_auto_20180415_1159.py new file mode 100644 index 00000000..51f19464 --- /dev/null +++ b/src/shop/migrations/0054_auto_20180415_1159.py @@ -0,0 +1,34 @@ +# Generated by Django 2.0.4 on 2018-04-15 16:59 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('shop', '0053_auto_20180318_0906'), + ] + + operations = [ + migrations.AddField( + model_name='product', + name='stock_amount', + field=models.IntegerField(blank=True, help_text='Initial amount available in stock if there is a limited supply, e.g. fridge space', null=True), + ), + migrations.AlterField( + model_name='epaypayment', + name='order', + field=models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='shop.Order'), + ), + migrations.AlterField( + model_name='invoice', + name='customorder', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='shop.CustomOrder'), + ), + migrations.AlterField( + model_name='invoice', + name='order', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='shop.Order'), + ), + ] diff --git a/src/shop/models.py b/src/shop/models.py index 9ea27135..cca68232 100644 --- a/src/shop/models.py +++ b/src/shop/models.py @@ -318,6 +318,15 @@ class Product(CreatedUpdatedModel, UUIDModel): blank=True ) + stock_amount = models.IntegerField( + help_text=( + 'Initial amount available in stock if there is a limited ' + 'supply, e.g. fridge space' + ), + null=True, + blank=True + ) + objects = ProductQuerySet.as_manager() def __str__(self): @@ -333,8 +342,17 @@ class Product(CreatedUpdatedModel, UUIDModel): ) def is_available(self): + """ Is the product available or not? + + Checks for the following: + + - Whether now is in the self.available_in + - If a stock is defined, that there are items left + """ now = timezone.now() - return now in self.available_in + time_available = now in self.available_in + stock_available = (self.stock_amount - self.left_in_stock()) > 0 + return time_available and stock_available def is_old(self): now = timezone.now() @@ -346,6 +364,16 @@ class Product(CreatedUpdatedModel, UUIDModel): now = timezone.now() return self.available_in.lower > now + def left_in_stock(self): + sold = OrderProductRelation.objects.filter( + product=self, + order__paid=True, + ).aggregate(Sum('quantity'))['quantity__sum'] + + total_left = self.stock_amount - (sold or 0) + + return total_left + class OrderProductRelation(CreatedUpdatedModel): order = models.ForeignKey('shop.Order', on_delete=models.PROTECT) diff --git a/src/shop/templates/product_detail.html b/src/shop/templates/product_detail.html index 488cce74..25799e63 100644 --- a/src/shop/templates/product_detail.html +++ b/src/shop/templates/product_detail.html @@ -25,6 +25,15 @@
+ {% if product.stock_amount %} +

+ Availability
+ {{ product.left_in_stock }} available
+

+ +
+ {% endif %} +

Add to order

{% if user.is_authenticated %}