diff --git a/src/accounting/migrations/0008_alter_orderproduct_options_orderproduct_quantity.py b/src/accounting/migrations/0008_alter_orderproduct_options_orderproduct_quantity.py new file mode 100644 index 0000000..51a56e0 --- /dev/null +++ b/src/accounting/migrations/0008_alter_orderproduct_options_orderproduct_quantity.py @@ -0,0 +1,22 @@ +# Generated by Django 5.1b1 on 2024-07-28 21:20 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounting', '0007_rename_user_order_member'), + ] + + operations = [ + migrations.AlterModelOptions( + name='orderproduct', + options={'verbose_name': 'ordered products'}, + ), + migrations.AddField( + model_name='orderproduct', + name='quantity', + field=models.PositiveSmallIntegerField(default=1), + ), + ] diff --git a/src/accounting/migrations/0009_alter_orderproduct_order_alter_orderproduct_product.py b/src/accounting/migrations/0009_alter_orderproduct_order_alter_orderproduct_product.py new file mode 100644 index 0000000..ac36b45 --- /dev/null +++ b/src/accounting/migrations/0009_alter_orderproduct_order_alter_orderproduct_product.py @@ -0,0 +1,24 @@ +# Generated by Django 5.1b1 on 2024-07-28 21:27 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounting', '0008_alter_orderproduct_options_orderproduct_quantity'), + ] + + operations = [ + migrations.AlterField( + model_name='orderproduct', + name='order', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='items', to='accounting.order'), + ), + migrations.AlterField( + model_name='orderproduct', + name='product', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='accounting.product'), + ), + ] diff --git a/src/accounting/models.py b/src/accounting/models.py index 6629a2b..0aa75cc 100644 --- a/src/accounting/models.py +++ b/src/accounting/models.py @@ -88,12 +88,12 @@ class Order(CreatedModifiedAbstract): @property def total(self) -> Money: """Return the total price of the order (excl VAT).""" - return sum(order_product.price for order_product in self.order_products) + return sum(item.price * item.quantity for item in self.items.all()) @property def total_vat(self) -> Money: """Return the total VAT of the order.""" - return sum(order_product.vat for order_product in self.order_products) + return sum(item.vat * item.quantity for item in self.items.all()) @property def total_with_vat(self) -> Money: @@ -133,14 +133,24 @@ class OrderProduct(CreatedModifiedAbstract): This includes pricing information. """ - order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name="order_products") - product = models.ForeignKey(Product, related_name="order_products", on_delete=models.PROTECT) + order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name="items") + product = models.ForeignKey(Product, on_delete=models.PROTECT) price = MoneyField(max_digits=16, decimal_places=2) vat = MoneyField(max_digits=16, decimal_places=2) + quantity = models.PositiveSmallIntegerField(default=1) + + class Meta: + verbose_name = _("ordered product") + verbose_name_plural = _("ordered products") def __str__(self) -> str: return f"{self.product.name}" + @property + def total_with_vat(self) -> Money: + """Total price of this item.""" + return (self.price + self.vat) * self.quantity + class Payment(CreatedModifiedAbstract): """A payment is a transaction that is made to pay for an order.""" diff --git a/src/accounting/templates/accounting/order/detail.html b/src/accounting/templates/accounting/order/detail.html index 00c5989..cae290b 100644 --- a/src/accounting/templates/accounting/order/detail.html +++ b/src/accounting/templates/accounting/order/detail.html @@ -9,5 +9,40 @@
+ {% trans "Ordered" %}: {{ order.created }}
+ {% trans "Status" %}: {{ order.is_paid|yesno:_("paid,unpaid") }}
+
{% trans "Item" %} | +{% trans "Quantity" %} | +{% trans "Price" %} | +{% trans "VAT" %} | +{% trans "Total" %} | +
---|---|---|---|---|
{{ item.product.name }} | +{{ item.quantity }} | +{{ item.price }} | +{{ item.vat }} | +{{ item.total_with_vat }} | +