diff --git a/doc/api/resources/item_variations.rst b/doc/api/resources/item_variations.rst index 441e0201d4..3ffa5d373e 100644 --- a/doc/api/resources/item_variations.rst +++ b/doc/api/resources/item_variations.rst @@ -18,12 +18,18 @@ default_price money (string) The price set d price money (string) The price used for this variation. This is either the same as ``default_price`` if that value is set or equal to the item's ``default_price`` (read-only). +original_price money (string) An original price, shown for comparison, not used + for price calculations (or ``null``). active boolean If ``false``, this variation will not be sold or shown. description multi-lingual string A public description of the variation. May contain Markdown syntax or can be ``null``. position integer An integer, used for sorting ===================================== ========================== ======================================================= +.. versionchanged:: 2.7 + + The attribute ``original_price`` has been added. + .. versionchanged:: 1.12 This resource has been added. @@ -67,7 +73,8 @@ Endpoints }, "position": 0, "default_price": "223.00", - "price": 223.0 + "price": 223.0, + "original_price": null, }, { "id": 3, @@ -120,6 +127,7 @@ Endpoints }, "default_price": "10.00", "price": "10.00", + "original_price": null, "active": true, "description": null, "position": 0 @@ -167,6 +175,7 @@ Endpoints "value": {"en": "Student"}, "default_price": "10.00", "price": "10.00", + "original_price": null, "active": true, "description": null, "position": 0 @@ -216,6 +225,7 @@ Endpoints "value": {"en": "Student"}, "default_price": "10.00", "price": "10.00", + "original_price": null, "active": false, "description": null, "position": 1 diff --git a/doc/api/resources/items.rst b/doc/api/resources/items.rst index 6b6adef442..a6cf5db0c9 100644 --- a/doc/api/resources/items.rst +++ b/doc/api/resources/items.rst @@ -82,6 +82,8 @@ variations list of objects A list with one ├ price money (string) The price used for this variation. This is either the same as ``default_price`` if that value is set or equal to the item's ``default_price``. +├ original_price money (string) An original price, shown for comparison, not used + for price calculations (or ``null``). ├ active boolean If ``false``, this variation will not be sold or shown. ├ description multi-lingual string A public description of the variation. May contain Markdown syntax or can be ``null``. @@ -106,6 +108,10 @@ bundles list of objects Definition of b taxation. This is not added to the price. ===================================== ========================== ======================================================= +.. versionchanged:: 2.7 + + The attribute ``original_price`` has been added for ``variations``. + .. versionchanged:: 1.7 The attribute ``tax_rule`` has been added. ``tax_rate`` is kept for compatibility. The attribute @@ -208,6 +214,7 @@ Endpoints "value": {"en": "Student"}, "default_price": "10.00", "price": "10.00", + "original_price": null, "active": true, "description": null, "position": 0 @@ -216,6 +223,7 @@ Endpoints "value": {"en": "Regular"}, "default_price": null, "price": "23.00", + "original_price": null, "active": true, "description": null, "position": 1 @@ -297,6 +305,7 @@ Endpoints "value": {"en": "Student"}, "default_price": "10.00", "price": "10.00", + "original_price": null, "active": true, "description": null, "position": 0 @@ -305,6 +314,7 @@ Endpoints "value": {"en": "Regular"}, "default_price": null, "price": "23.00", + "original_price": null, "active": true, "description": null, "position": 1 @@ -366,6 +376,7 @@ Endpoints "value": {"en": "Student"}, "default_price": "10.00", "price": "10.00", + "original_price": null, "active": true, "description": null, "position": 0 @@ -374,6 +385,7 @@ Endpoints "value": {"en": "Regular"}, "default_price": null, "price": "23.00", + "original_price": null, "active": true, "description": null, "position": 1 @@ -424,6 +436,7 @@ Endpoints "value": {"en": "Student"}, "default_price": "10.00", "price": "10.00", + "original_price": null, "active": true, "description": null, "position": 0 @@ -432,6 +445,7 @@ Endpoints "value": {"en": "Regular"}, "default_price": null, "price": "23.00", + "original_price": null, "active": true, "description": null, "position": 1 @@ -513,6 +527,7 @@ Endpoints "value": {"en": "Student"}, "default_price": "10.00", "price": "10.00", + "original_price": null, "active": true, "description": null, "position": 0 @@ -521,6 +536,7 @@ Endpoints "value": {"en": "Regular"}, "default_price": null, "price": "23.00", + "original_price": null, "active": true, "description": null, "position": 1 diff --git a/src/pretix/api/serializers/item.py b/src/pretix/api/serializers/item.py index 3906421b23..092c0b6fe2 100644 --- a/src/pretix/api/serializers/item.py +++ b/src/pretix/api/serializers/item.py @@ -19,7 +19,7 @@ class InlineItemVariationSerializer(I18nAwareModelSerializer): class Meta: model = ItemVariation fields = ('id', 'value', 'active', 'description', - 'position', 'default_price', 'price') + 'position', 'default_price', 'price', 'original_price') class ItemVariationSerializer(I18nAwareModelSerializer): @@ -29,7 +29,7 @@ class ItemVariationSerializer(I18nAwareModelSerializer): class Meta: model = ItemVariation fields = ('id', 'value', 'active', 'description', - 'position', 'default_price', 'price') + 'position', 'default_price', 'price', 'original_price') class InlineItemBundleSerializer(serializers.ModelSerializer): diff --git a/src/pretix/base/migrations/0117_auto_20190418_1149.py b/src/pretix/base/migrations/0117_auto_20190418_1149.py new file mode 100644 index 0000000000..885d5ba24a --- /dev/null +++ b/src/pretix/base/migrations/0117_auto_20190418_1149.py @@ -0,0 +1,23 @@ +# Generated by Django 2.2 on 2019-04-18 11:49 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('pretixbase', '0116_auto_20190402_0722'), + ] + + operations = [ + migrations.AddField( + model_name='itemvariation', + name='original_price', + field=models.DecimalField(blank=True, decimal_places=2, help_text='If set, this will be displayed next to ' + 'the current price to show that the ' + 'current price is a discounted one. ' + 'This is just a cosmetic setting and ' + 'will not actually impact pricing.', + max_digits=7, null=True, verbose_name='Original price'), + ), + ] diff --git a/src/pretix/base/models/items.py b/src/pretix/base/models/items.py index 618ea3a9ac..0ee55bd05c 100644 --- a/src/pretix/base/models/items.py +++ b/src/pretix/base/models/items.py @@ -550,6 +550,8 @@ class ItemVariation(models.Model): :type active: bool :param default_price: This variation's default price :type default_price: decimal.Decimal + :param original_price: The item's "original" price. Will not be used for any calculations, will just be shown. + :type original_price: decimal.Decimal """ item = models.ForeignKey( Item, @@ -578,6 +580,13 @@ class ItemVariation(models.Model): null=True, blank=True, verbose_name=_("Default price"), ) + original_price = models.DecimalField( + verbose_name=_('Original price'), + blank=True, null=True, + max_digits=7, decimal_places=2, + help_text=_('If set, this will be displayed next to the current price to show that the current price is a ' + 'discounted one. This is just a cosmetic setting and will not actually impact pricing.') + ) class Meta: verbose_name = _("Product variation") diff --git a/src/pretix/control/forms/item.py b/src/pretix/control/forms/item.py index 4e22d3318c..e217081a6e 100644 --- a/src/pretix/control/forms/item.py +++ b/src/pretix/control/forms/item.py @@ -463,6 +463,7 @@ class ItemVariationForm(I18nModelForm): 'value', 'active', 'default_price', + 'original_price', 'description', ] diff --git a/src/pretix/control/templates/pretixcontrol/item/variations.html b/src/pretix/control/templates/pretixcontrol/item/variations.html index 2f52011afb..2fc4b88c66 100644 --- a/src/pretix/control/templates/pretixcontrol/item/variations.html +++ b/src/pretix/control/templates/pretixcontrol/item/variations.html @@ -45,6 +45,7 @@ {% bootstrap_form_errors form %} {% bootstrap_field form.active layout="control" %} {% bootstrap_field form.default_price addon_after=request.event.currency layout="control" %} + {% bootstrap_field form.original_price addon_after=request.event.currency layout="control" %} {% bootstrap_field form.description layout="control" %} @@ -78,6 +79,7 @@
{% bootstrap_field formset.empty_form.active layout="control" %} {% bootstrap_field formset.empty_form.default_price addon_after=request.event.currency layout="control" %} + {% bootstrap_field formset.empty_form.original_price addon_after=request.event.currency layout="control" %} {% bootstrap_field formset.empty_form.description layout="control" %}
diff --git a/src/pretix/presale/templates/pretixpresale/event/index.html b/src/pretix/presale/templates/pretixpresale/event/index.html index 210b655878..c71c9607bd 100644 --- a/src/pretix/presale/templates/pretixpresale/event/index.html +++ b/src/pretix/presale/templates/pretixpresale/event/index.html @@ -270,7 +270,10 @@ {% endif %}
- {% if item.original_price %} + {% if var.original_price %} + {{ var.original_price|money:event.currency }} + + {% elif item.original_price %} {{ item.original_price|money:event.currency }} {% endif %} @@ -294,7 +297,7 @@ {% else %} {{ var.display_price.gross|money:event.currency }} {% endif %} - {% if item.original_price %} + {% if item.original_price or var.original_price %} {% endif %} {% if item.includes_mixed_tax_rate %} diff --git a/src/tests/api/test_items.py b/src/tests/api/test_items.py index 5bd4950ba3..992f32fcd9 100644 --- a/src/tests/api/test_items.py +++ b/src/tests/api/test_items.py @@ -319,6 +319,7 @@ def test_item_detail_variations(token_client, organizer, event, team, item): "active": True, "description": None, "position": 0, + "original_price": None }] res["has_variations"] = True resp = token_client.get('/api/v1/organizers/{}/events/{}/items/{}/'.format(organizer.slug, event.slug, @@ -941,7 +942,8 @@ TEST_VARIATIONS_RES = { "description": None, "position": 0, "default_price": None, - "price": "23.00" + "price": "23.00", + "original_price": None } TEST_VARIATIONS_UPDATE = { @@ -952,6 +954,7 @@ TEST_VARIATIONS_UPDATE = { "description": None, "position": 1, "default_price": "20.0", + "original_price": None } @@ -987,6 +990,7 @@ def test_variations_create(token_client, organizer, event, item, variation): "description": None, "position": 1, "default_price": None, + "original_price": "23.42", "price": 23.0 }, format='json' @@ -1025,6 +1029,7 @@ def test_variations_update(token_client, organizer, event, item, item3, variatio res["id"] = variation.pk res["price"] = "20.00" res["default_price"] = "20.00" + res["original_price"] = "50.00" resp = token_client.patch( '/api/v1/organizers/{}/events/{}/items/{}/variations/{}/'.format(organizer.slug, event.slug, item.pk, variation.pk), { @@ -1032,7 +1037,8 @@ def test_variations_update(token_client, organizer, event, item, item3, variatio "en": "ChildC2" }, "position": 1, - "default_price": "20.00" + "default_price": "20.00", + "original_price": "50.00" }, format='json' )