mirror of
https://github.com/pretix/pretix.git
synced 2026-05-06 15:24:02 +00:00
Free price: Allow to suggest a different price than the minimum (#3666)
* Free price: Allow to suggest a different price than the minimum * Full implementation * Widget tests * Add min values to titles
This commit is contained in:
@@ -59,7 +59,7 @@ class InlineItemVariationSerializer(I18nAwareModelSerializer):
|
||||
class Meta:
|
||||
model = ItemVariation
|
||||
fields = ('id', 'value', 'active', 'description',
|
||||
'position', 'default_price', 'price', 'original_price', 'require_approval',
|
||||
'position', 'default_price', 'price', 'original_price', 'free_price_suggestion', 'require_approval',
|
||||
'require_membership', 'require_membership_types', 'require_membership_hidden',
|
||||
'checkin_attention', 'available_from', 'available_until',
|
||||
'sales_channels', 'hide_without_voucher', 'meta_data')
|
||||
@@ -83,7 +83,7 @@ class ItemVariationSerializer(I18nAwareModelSerializer):
|
||||
class Meta:
|
||||
model = ItemVariation
|
||||
fields = ('id', 'value', 'active', 'description',
|
||||
'position', 'default_price', 'price', 'original_price', 'require_approval',
|
||||
'position', 'default_price', 'price', 'original_price', 'free_price_suggestion', 'require_approval',
|
||||
'require_membership', 'require_membership_types', 'require_membership_hidden',
|
||||
'checkin_attention', 'available_from', 'available_until',
|
||||
'sales_channels', 'hide_without_voucher', 'meta_data')
|
||||
@@ -234,8 +234,8 @@ class ItemSerializer(I18nAwareModelSerializer):
|
||||
class Meta:
|
||||
model = Item
|
||||
fields = ('id', 'category', 'name', 'internal_name', 'active', 'sales_channels', 'description',
|
||||
'default_price', 'free_price', 'tax_rate', 'tax_rule', 'admission', 'personalized',
|
||||
'position', 'picture', 'available_from', 'available_until',
|
||||
'default_price', 'free_price', 'free_price_suggestion', 'tax_rate', 'tax_rule', 'admission',
|
||||
'personalized', 'position', 'picture', 'available_from', 'available_until',
|
||||
'require_voucher', 'hide_without_voucher', 'allow_cancel', 'require_bundling',
|
||||
'min_per_order', 'max_per_order', 'checkin_attention', 'has_variations', 'variations',
|
||||
'addons', 'bundles', 'original_price', 'require_approval', 'generate_tickets',
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# Generated by Django 4.2.4 on 2023-10-25 12:01
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("pretixbase", "0247_checkinlist"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="item",
|
||||
name="free_price_suggestion",
|
||||
field=models.DecimalField(decimal_places=2, max_digits=13, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="itemvariation",
|
||||
name="free_price_suggestion",
|
||||
field=models.DecimalField(decimal_places=2, max_digits=13, null=True),
|
||||
),
|
||||
]
|
||||
@@ -431,6 +431,12 @@ class Item(LoggedModel):
|
||||
"additional donations for your event. This is currently not supported for products that are "
|
||||
"bought as an add-on to other products.")
|
||||
)
|
||||
free_price_suggestion = models.DecimalField(
|
||||
verbose_name=_("Suggested price"),
|
||||
help_text=_("This price will be used as the default value of the input field. The user can choose a lower "
|
||||
"value, but not lower than the price this product would have without the free price option."),
|
||||
max_digits=13, decimal_places=2, null=True, blank=True,
|
||||
)
|
||||
tax_rule = models.ForeignKey(
|
||||
'TaxRule',
|
||||
verbose_name=_('Sales tax'),
|
||||
@@ -1021,6 +1027,12 @@ class ItemVariation(models.Model):
|
||||
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.')
|
||||
)
|
||||
free_price_suggestion = models.DecimalField(
|
||||
verbose_name=_("Suggested price"),
|
||||
help_text=_("This price will be used as the default value of the input field. The user can choose a lower "
|
||||
"value, but not lower than the price this product would have without the free price option."),
|
||||
max_digits=13, decimal_places=2, null=True, blank=True,
|
||||
)
|
||||
require_approval = models.BooleanField(
|
||||
verbose_name=_('Require approval'),
|
||||
default=False,
|
||||
|
||||
@@ -577,6 +577,8 @@ class ItemUpdateForm(I18nModelForm):
|
||||
)
|
||||
self.fields['category'].widget.choices = self.fields['category'].choices
|
||||
|
||||
self.fields['free_price_suggestion'].widget.attrs['data-display-dependency'] = '#id_free_price'
|
||||
|
||||
qs = self.event.organizer.membership_types.all()
|
||||
if qs:
|
||||
self.fields['require_membership_types'].queryset = qs
|
||||
@@ -664,6 +666,7 @@ class ItemUpdateForm(I18nModelForm):
|
||||
'picture',
|
||||
'default_price',
|
||||
'free_price',
|
||||
'free_price_suggestion',
|
||||
'tax_rule',
|
||||
'available_from',
|
||||
'available_until',
|
||||
@@ -797,6 +800,8 @@ class ItemVariationForm(I18nModelForm):
|
||||
del self.fields['require_membership']
|
||||
del self.fields['require_membership_types']
|
||||
|
||||
self.fields['free_price_suggestion'].widget.attrs['data-display-dependency'] = '#id_free_price'
|
||||
|
||||
self.meta_fields = []
|
||||
meta_defaults = {}
|
||||
if self.instance.pk:
|
||||
@@ -829,6 +834,7 @@ class ItemVariationForm(I18nModelForm):
|
||||
'value',
|
||||
'active',
|
||||
'default_price',
|
||||
'free_price_suggestion',
|
||||
'original_price',
|
||||
'description',
|
||||
'require_approval',
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
{% bootstrap_field form.active layout="control" %}
|
||||
{% bootstrap_field form.value layout="control" %}
|
||||
{% bootstrap_field form.default_price addon_after=request.event.currency layout="control" %}
|
||||
{% bootstrap_field form.free_price_suggestion 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" %}
|
||||
{% if form.meta_fields %}
|
||||
@@ -170,6 +171,7 @@
|
||||
{% bootstrap_field formset.empty_form.active layout="control" %}
|
||||
{% bootstrap_field formset.empty_form.value layout="control" %}
|
||||
{% bootstrap_field formset.empty_form.default_price addon_after=request.event.currency layout="control" %}
|
||||
{% bootstrap_field formset.empty_form.free_price_suggestion 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" %}
|
||||
{% if formset.empty_form.meta_fields %}
|
||||
|
||||
@@ -147,6 +147,7 @@
|
||||
{% bootstrap_field form.default_price addon_after=request.event.currency layout="control" %}
|
||||
{% bootstrap_field form.tax_rule layout="control" %}
|
||||
{% bootstrap_field form.free_price layout="control" %}
|
||||
{% bootstrap_field form.free_price_suggestion addon_after=request.event.currency layout="control" %}
|
||||
{% bootstrap_field form.original_price addon_after=request.event.currency layout="control" %}
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
|
||||
@@ -570,7 +570,7 @@ class AddOnsStep(CartMixin, AsyncAction, TemplateFlowStep):
|
||||
rate=a.tax_rate,
|
||||
)
|
||||
else:
|
||||
v.initial_price = v.display_price
|
||||
v.initial_price = v.suggested_price
|
||||
i.expand = any(v.initial for v in i.available_variations)
|
||||
else:
|
||||
i.initial = len(current_addon_products[i.pk, None])
|
||||
@@ -584,7 +584,7 @@ class AddOnsStep(CartMixin, AsyncAction, TemplateFlowStep):
|
||||
rate=a.tax_rate,
|
||||
)
|
||||
else:
|
||||
i.initial_price = i.display_price
|
||||
i.initial_price = i.suggested_price
|
||||
|
||||
if items:
|
||||
formsetentry['categories'].append({
|
||||
|
||||
@@ -139,7 +139,15 @@
|
||||
placeholder="0"
|
||||
min="{% if event.settings.display_net_prices %}{{ var.display_price.net|money_numberfield:event.currency }}{% else %}{{ var.display_price.gross|money_numberfield:event.currency }}{% endif %}"
|
||||
name="cp_{{ form.pos.pk }}_variation_{{ item.id }}_{{ var.id }}_price"
|
||||
title="{% blocktrans trimmed with item=var.value %}Modify price for {{ item }}{% endblocktrans %}"
|
||||
{% if var.initial_price.gross != var.display_price.gross %}
|
||||
{% if event.settings.display_net_prices %}
|
||||
title="{% blocktrans trimmed with item=var.value price=var.display_price.net|money:event.currency %}Modify price for {{ item }}, at least {{ price }}{% endblocktrans %}"
|
||||
{% else %}
|
||||
title="{% blocktrans trimmed with item=var.value price=var.display_price.gross|money:event.currency %}Modify price for {{ item }}, at least {{ price }}{% endblocktrans %}"
|
||||
{% endif %}
|
||||
{% else %}
|
||||
title="{% blocktrans trimmed with item=var.value %}Modify price for {{ item }}{% endblocktrans %}"
|
||||
{% endif %}
|
||||
step="any"
|
||||
value="{% if event.settings.display_net_prices %}{{ var.initial_price.net|money_numberfield:event.currency }}{% else %}{{ var.initial_price.gross|money_numberfield:event.currency }}{% endif %}"
|
||||
>
|
||||
@@ -268,7 +276,15 @@
|
||||
id="price-item-{{ form.pos.pk }}-{{ item.pk }}"
|
||||
min="{% if event.settings.display_net_prices %}{{ item.display_price.net|money_numberfield:event.currency }}{% else %}{{ item.display_price.gross|money_numberfield:event.currency }}{% endif %}"
|
||||
name="cp_{{ form.pos.pk }}_item_{{ item.id }}_price"
|
||||
title="{% blocktrans trimmed with item=item.name %}Modify price for {{ item }}{% endblocktrans %}"
|
||||
{% if item.initial_price.gross != item.display_price.gross %}
|
||||
{% if event.settings.display_net_prices %}
|
||||
title="{% blocktrans trimmed with item=item.name price=item.display_price.net|money:event.currency %}Modify price for {{ item }}, at least {{ price }}{% endblocktrans %}"
|
||||
{% else %}
|
||||
title="{% blocktrans trimmed with item=item.name price=item.display_price.gross|money:event.currency %}Modify price for {{ item }}, at least {{ price }}{% endblocktrans %}"
|
||||
{% endif %}
|
||||
{% else %}
|
||||
title="{% blocktrans trimmed with item=item.name %}Modify price for {{ item }}{% endblocktrans %}"
|
||||
{% endif %}
|
||||
value="{% if event.settings.display_net_prices %}{{ item.initial_price.net|money_numberfield:event.currency }}{% else %}{{ item.initial_price.gross|money_numberfield:event.currency }}{% endif %}"
|
||||
step="any">
|
||||
</div>
|
||||
|
||||
@@ -138,9 +138,17 @@
|
||||
placeholder="0"
|
||||
min="{% if event.settings.display_net_prices %}{{ var.display_price.net|money_numberfield:event.currency }}{% else %}{{ var.display_price.gross|money_numberfield:event.currency }}{% endif %}"
|
||||
name="price_{{ item.id }}_{{ var.id }}"
|
||||
title="{% blocktrans trimmed with item=var.value %}Modify price for {{ item }}{% endblocktrans %}"
|
||||
{% if var.suggested_price.gross != var.display_price.gross %}
|
||||
{% if event.settings.display_net_prices %}
|
||||
title="{% blocktrans trimmed with item=var.value price=var.display_price.net|money:event.currency %}Modify price for {{ item }}, at least {{ price }}{% endblocktrans %}"
|
||||
{% else %}
|
||||
title="{% blocktrans trimmed with item=var.value price=var.display_price.gross|money:event.currency %}Modify price for {{ item }}, at least {{ price }}{% endblocktrans %}"
|
||||
{% endif %}
|
||||
{% else %}
|
||||
title="{% blocktrans trimmed with item=var.value %}Modify price for {{ item }}{% endblocktrans %}"
|
||||
{% endif %}
|
||||
step="any"
|
||||
value="{% if event.settings.display_net_prices %}{{ var.display_price.net|money_numberfield:event.currency }}{% else %}{{ var.display_price.gross|money_numberfield:event.currency }}{% endif %}"
|
||||
value="{% if event.settings.display_net_prices %}{{ var.suggested_price.net|money_numberfield:event.currency }}{% else %}{{ var.suggested_price.gross|money_numberfield:event.currency }}{% endif %}"
|
||||
>
|
||||
</div>
|
||||
<p>
|
||||
@@ -284,8 +292,16 @@
|
||||
{% if not ev.presale_is_running %}disabled{% endif %}
|
||||
min="{% if event.settings.display_net_prices %}{{ item.display_price.net|money_numberfield:event.currency }}{% else %}{{ item.display_price.gross|money_numberfield:event.currency }}{% endif %}"
|
||||
name="price_{{ item.id }}"
|
||||
title="{% blocktrans trimmed with item=item.name %}Modify price for {{ item }}{% endblocktrans %}"
|
||||
value="{% if event.settings.display_net_prices %}{{ item.display_price.net|money_numberfield:event.currency }}{% else %}{{ item.display_price.gross|money_numberfield:event.currency }}{% endif %}"
|
||||
{% if item.suggested_price.gross != item.display_price.gross %}
|
||||
{% if event.settings.display_net_prices %}
|
||||
title="{% blocktrans trimmed with item=item.name price=item.display_price.net|money:event.currency %}Modify price for {{ item }}, at least {{ price }}{% endblocktrans %}"
|
||||
{% else %}
|
||||
title="{% blocktrans trimmed with item=item.name price=item.display_price.gross|money:event.currency %}Modify price for {{ item }}, at least {{ price }}{% endblocktrans %}"
|
||||
{% endif %}
|
||||
{% else %}
|
||||
title="{% blocktrans trimmed with item=item.name %}Modify price for {{ item }}{% endblocktrans %}"
|
||||
{% endif %}
|
||||
value="{% if event.settings.display_net_prices %}{{ item.suggested_price.net|money_numberfield:event.currency }}{% else %}{{ item.suggested_price.gross|money_numberfield:event.currency }}{% endif %}"
|
||||
step="any">
|
||||
</div>
|
||||
<p>
|
||||
|
||||
@@ -166,8 +166,16 @@
|
||||
placeholder="0"
|
||||
min="{% if event.settings.display_net_prices %}{{ var.display_price.net|stringformat:"0.2f" }}{% else %}{{ var.display_price.gross|stringformat:"0.2f" }}{% endif %}"
|
||||
name="price_{{ item.id }}_{{ var.id }}"
|
||||
title="{% blocktrans trimmed with item=var.value %}Modify price for {{ item }}{% endblocktrans %}"
|
||||
value="{% if event.settings.display_net_prices %}{{var.display_price.net|stringformat:"0.2f" }}{% else %}{{ var.display_price.gross|stringformat:"0.2f" }}{% endif %}"
|
||||
{% if var.suggested_price.gross != var.display_price.gross %}
|
||||
{% if event.settings.display_net_prices %}
|
||||
title="{% blocktrans trimmed with item=var.value price=var.display_price.net|money:event.currency %}Modify price for {{ item }}, at least {{ price }}{% endblocktrans %}"
|
||||
{% else %}
|
||||
title="{% blocktrans trimmed with item=var.value price=var.display_price.gross|money:event.currency %}Modify price for {{ item }}, at least {{ price }}{% endblocktrans %}"
|
||||
{% endif %}
|
||||
{% else %}
|
||||
title="{% blocktrans trimmed with item=var.value %}Modify price for {{ item }}{% endblocktrans %}"
|
||||
{% endif %}
|
||||
value="{% if event.settings.display_net_prices %}{{var.suggested_price.net|stringformat:"0.2f" }}{% else %}{{ var.suggested_price.gross|stringformat:"0.2f" }}{% endif %}"
|
||||
step="any">
|
||||
</div>
|
||||
<p>
|
||||
@@ -309,8 +317,16 @@
|
||||
<input type="number" class="form-control input-item-price" placeholder="0"
|
||||
min="{% if event.settings.display_net_prices %}{{ item.display_price.net|stringformat:"0.2f" }}{% else %}{{ item.display_price.gross|stringformat:"0.2f" }}{% endif %}"
|
||||
name="price_{{ item.id }}"
|
||||
title="{% blocktrans trimmed with item=item.name %}Modify price for {{ item }}{% endblocktrans %}"
|
||||
value="{% if event.settings.display_net_prices %}{{ item.display_price.net|stringformat:"0.2f" }}{% else %}{{ item.display_price.gross|stringformat:"0.2f" }}{% endif %}"
|
||||
{% if item.suggested_price.gross != item.display_price.gross %}
|
||||
{% if event.settings.display_net_prices %}
|
||||
title="{% blocktrans trimmed with item=item.name price=item.display_price.net|money:event.currency %}Modify price for {{ item }}, at least {{ price }}{% endblocktrans %}"
|
||||
{% else %}
|
||||
title="{% blocktrans trimmed with item=item.name price=item.display_price.gross|money:event.currency %}Modify price for {{ item }}, at least {{ price }}{% endblocktrans %}"
|
||||
{% endif %}
|
||||
{% else %}
|
||||
title="{% blocktrans trimmed with item=item.name %}Modify price for {{ item }}{% endblocktrans %}"
|
||||
{% endif %}
|
||||
value="{% if event.settings.display_net_prices %}{{ item.suggested_price.net|stringformat:"0.2f" }}{% else %}{{ item.suggested_price.gross|stringformat:"0.2f" }}{% endif %}"
|
||||
step="any">
|
||||
</div>
|
||||
<p>
|
||||
|
||||
@@ -300,6 +300,10 @@ def get_grouped_items(event, subevent=None, voucher=None, channel='web', require
|
||||
price = original_price
|
||||
|
||||
item.display_price = item.tax(price, currency=event.currency, include_bundled=True)
|
||||
if item.free_price and item.free_price_suggestion is not None:
|
||||
item.suggested_price = item.tax(max(price, item.free_price_suggestion), currency=event.currency, include_bundled=True)
|
||||
else:
|
||||
item.suggested_price = item.display_price
|
||||
|
||||
if price != original_price:
|
||||
item.original_price = item.tax(original_price, currency=event.currency, include_bundled=True)
|
||||
@@ -346,6 +350,15 @@ def get_grouped_items(event, subevent=None, voucher=None, channel='web', require
|
||||
|
||||
var.display_price = var.tax(price, currency=event.currency, include_bundled=True)
|
||||
|
||||
if item.free_price and var.free_price_suggestion is not None:
|
||||
var.suggested_price = item.tax(max(price, var.free_price_suggestion), currency=event.currency,
|
||||
include_bundled=True)
|
||||
elif item.free_price and item.free_price_suggestion is not None:
|
||||
var.suggested_price = item.tax(max(price, item.free_price_suggestion), currency=event.currency,
|
||||
include_bundled=True)
|
||||
else:
|
||||
var.suggested_price = var.display_price
|
||||
|
||||
if price != original_price:
|
||||
var.original_price = var.tax(original_price, currency=event.currency, include_bundled=True)
|
||||
else:
|
||||
|
||||
@@ -1355,7 +1355,7 @@ class OrderChangeMixin:
|
||||
rate=a.tax_rate,
|
||||
)
|
||||
else:
|
||||
v.initial_price = v.display_price
|
||||
v.initial_price = v.suggested_price
|
||||
i.expand = any(v.initial for v in i.available_variations)
|
||||
else:
|
||||
i.initial = len(current_addon_products[i.pk, None])
|
||||
@@ -1369,7 +1369,7 @@ class OrderChangeMixin:
|
||||
rate=a.tax_rate,
|
||||
)
|
||||
else:
|
||||
i.initial_price = i.display_price
|
||||
i.initial_price = i.suggested_price
|
||||
|
||||
if items:
|
||||
p.addon_form['categories'].append({
|
||||
|
||||
@@ -274,6 +274,7 @@ class WidgetAPIProductList(EventListMixin, View):
|
||||
'order_min': item.min_per_order,
|
||||
'order_max': item.order_max if not item.has_variations else None,
|
||||
'price': price_dict(item, item.display_price) if not item.has_variations else None,
|
||||
'suggested_price': price_dict(item, item.suggested_price) if not item.has_variations else None,
|
||||
'min_price': item.min_price if item.has_variations else None,
|
||||
'max_price': item.max_price if item.has_variations else None,
|
||||
'allow_waitinglist': item.allow_waitinglist,
|
||||
@@ -296,6 +297,7 @@ class WidgetAPIProductList(EventListMixin, View):
|
||||
'order_max': var.order_max,
|
||||
'description': str(rich_text(var.description, safelinks=False)) if var.description else None,
|
||||
'price': price_dict(item, var.display_price),
|
||||
'suggested_price': price_dict(item, var.suggested_price),
|
||||
'original_price': (
|
||||
(
|
||||
var.original_price.net
|
||||
|
||||
@@ -336,7 +336,7 @@ Vue.component('pricebox', {
|
||||
+ '<div v-if="free_price">'
|
||||
+ '{{ $root.currency }} '
|
||||
+ '<input type="number" class="pretix-widget-pricebox-price-input" placeholder="0" '
|
||||
+ ' :min="display_price_nonlocalized" :value="display_price_nonlocalized" :name="field_name"'
|
||||
+ ' :min="display_price_nonlocalized" :value="suggested_price_nonlocalized" :name="field_name"'
|
||||
+ ' step="any" aria-label="'+strings.price+'">'
|
||||
+ '</div>'
|
||||
+ '<small class="pretix-widget-pricebox-tax" v-if="price.rate != \'0.00\' && price.gross != \'0.00\'">'
|
||||
@@ -347,6 +347,7 @@ Vue.component('pricebox', {
|
||||
price: Object,
|
||||
free_price: Boolean,
|
||||
field_name: String,
|
||||
suggested_price: Object,
|
||||
original_price: String,
|
||||
mandatory_priced_addons: Boolean,
|
||||
},
|
||||
@@ -365,6 +366,17 @@ Vue.component('pricebox', {
|
||||
return parseFloat(this.price.gross).toFixed(2);
|
||||
}
|
||||
},
|
||||
suggested_price_nonlocalized: function () {
|
||||
var price = this.suggested_price;
|
||||
if (price === null) {
|
||||
price = this.price;
|
||||
}
|
||||
if (this.$root.display_net_prices) {
|
||||
return parseFloat(price.net).toFixed(2);
|
||||
} else {
|
||||
return parseFloat(price.gross).toFixed(2);
|
||||
}
|
||||
},
|
||||
original_line: function () {
|
||||
return this.$root.currency + " " + floatformat(parseFloat(this.original_price), 2);
|
||||
},
|
||||
@@ -420,7 +432,7 @@ Vue.component('variation', {
|
||||
// Price
|
||||
+ '<div class="pretix-widget-item-price-col">'
|
||||
+ '<pricebox :price="variation.price" :free_price="item.free_price" :original_price="orig_price" '
|
||||
+ ' :mandatory_priced_addons="item.mandatory_priced_addons"'
|
||||
+ ' :mandatory_priced_addons="item.mandatory_priced_addons" :suggested_price="variation.suggested_price"'
|
||||
+ ' :field_name="\'price_\' + item.id + \'_\' + variation.id" v-if="$root.showPrices">'
|
||||
+ '</pricebox>'
|
||||
+ '<span v-if="!$root.showPrices"> </span>'
|
||||
@@ -478,7 +490,7 @@ Vue.component('item', {
|
||||
// Price
|
||||
+ '<div class="pretix-widget-item-price-col">'
|
||||
+ '<pricebox :price="item.price" :free_price="item.free_price" v-if="!item.has_variations && $root.showPrices"'
|
||||
+ ' :mandatory_priced_addons="item.mandatory_priced_addons"'
|
||||
+ ' :mandatory_priced_addons="item.mandatory_priced_addons" :suggested_price="item.suggested_price"'
|
||||
+ ' :field_name="\'price_\' + item.id" :original_price="item.original_price">'
|
||||
+ '</pricebox>'
|
||||
+ '<div class="pretix-widget-pricebox" v-if="item.has_variations && $root.showPrices">{{ pricerange }}</div>'
|
||||
|
||||
Reference in New Issue
Block a user