mirror of
https://github.com/pretix/pretix.git
synced 2025-12-18 16:12:26 +00:00
Compare commits
7 Commits
api-expand
...
manual-fee
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d66a351f0 | ||
|
|
b61faf7e29 | ||
|
|
b1c2b0b827 | ||
|
|
8e47c00167 | ||
|
|
cac9a39ae2 | ||
|
|
6f0d813cfc | ||
|
|
839aca6561 |
@@ -609,6 +609,49 @@ class OrderFeeChangeForm(forms.Form):
|
|||||||
change_decimal_field(self.fields['value'], instance.order.event.currency)
|
change_decimal_field(self.fields['value'], instance.order.event.currency)
|
||||||
|
|
||||||
|
|
||||||
|
class OrderFeeAddForm(forms.Form):
|
||||||
|
fee_type = forms.ChoiceField(choices=OrderFee.FEE_TYPES)
|
||||||
|
value = forms.DecimalField(
|
||||||
|
max_digits=13, decimal_places=2,
|
||||||
|
localize=True,
|
||||||
|
label=_('Price'),
|
||||||
|
help_text=_("including all taxes"),
|
||||||
|
)
|
||||||
|
tax_rule = forms.ModelChoiceField(
|
||||||
|
TaxRule.objects.none(),
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
description = forms.CharField(required=False)
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
order = kwargs.pop('order')
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.fields['tax_rule'].queryset = order.event.tax_rules.all()
|
||||||
|
change_decimal_field(self.fields['value'], order.event.currency)
|
||||||
|
|
||||||
|
|
||||||
|
class OrderFeeAddFormset(forms.BaseFormSet):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.order = kwargs.pop('order', None)
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def _construct_form(self, i, **kwargs):
|
||||||
|
kwargs['order'] = self.order
|
||||||
|
return super()._construct_form(i, **kwargs)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def empty_form(self):
|
||||||
|
form = self.form(
|
||||||
|
auto_id=self.auto_id,
|
||||||
|
prefix=self.add_prefix('__prefix__'),
|
||||||
|
empty_permitted=True,
|
||||||
|
use_required_attribute=False,
|
||||||
|
order=self.order,
|
||||||
|
)
|
||||||
|
self.add_fields(form, None)
|
||||||
|
return form
|
||||||
|
|
||||||
|
|
||||||
class OrderContactForm(forms.ModelForm):
|
class OrderContactForm(forms.ModelForm):
|
||||||
regenerate_secrets = forms.BooleanField(required=False, label=_('Invalidate secrets'),
|
regenerate_secrets = forms.BooleanField(required=False, label=_('Invalidate secrets'),
|
||||||
help_text=_('Regenerates the order and ticket secrets. You will '
|
help_text=_('Regenerates the order and ticket secrets. You will '
|
||||||
|
|||||||
@@ -296,11 +296,11 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
|
||||||
<div class="formset" data-formset data-formset-prefix="{{ add_formset.prefix }}">
|
<div class="formset" data-formset data-formset-prefix="{{ add_position_formset.prefix }}">
|
||||||
{{ add_formset.management_form }}
|
{{ add_position_formset.management_form }}
|
||||||
{% bootstrap_formset_errors add_formset %}
|
{% bootstrap_formset_errors add_position_formset %}
|
||||||
<div data-formset-body>
|
<div data-formset-body>
|
||||||
{% for add_form in add_formset %}
|
{% for add_form in add_position_formset %}
|
||||||
<div class="panel panel-default items" data-formset-form data-subevent="0">
|
<div class="panel panel-default items" data-formset-form data-subevent="0">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h3 class="panel-title">
|
<h3 class="panel-title">
|
||||||
@@ -351,25 +351,25 @@
|
|||||||
</button>
|
</button>
|
||||||
{% trans "Add product" %}
|
{% trans "Add product" %}
|
||||||
<div class="sr-only">
|
<div class="sr-only">
|
||||||
{{ add_formset.empty_form.id }}
|
{{ add_position_formset.empty_form.id }}
|
||||||
{% bootstrap_field add_formset.empty_form.DELETE form_group_class="" layout="inline" %}
|
{% bootstrap_field add_position_formset.empty_form.DELETE form_group_class="" layout="inline" %}
|
||||||
</div>
|
</div>
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="form-horizontal">
|
<div class="form-horizontal">
|
||||||
{% bootstrap_field add_formset.empty_form.itemvar layout="control" %}
|
{% bootstrap_field add_position_formset.empty_form.itemvar layout="control" %}
|
||||||
{% bootstrap_field add_formset.empty_form.price addon_after=request.event.currency layout="control" %}
|
{% bootstrap_field add_position_formset.empty_form.price addon_after=request.event.currency layout="control" %}
|
||||||
{% if add_formset.empty_form.addon_to %}
|
{% if add_position_formset.empty_form.addon_to %}
|
||||||
{% bootstrap_field add_formset.empty_form.addon_to layout="control" %}
|
{% bootstrap_field add_position_formset.empty_form.addon_to layout="control" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if add_formset.empty_form.subevent %}
|
{% if add_position_formset.empty_form.subevent %}
|
||||||
{% bootstrap_field add_formset.empty_form.subevent layout="control" %}
|
{% bootstrap_field add_position_formset.empty_form.subevent layout="control" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if add_formset.empty_form.used_membership %}
|
{% if add_position_formset.empty_form.used_membership %}
|
||||||
{% bootstrap_field add_formset.empty_form.used_membership layout="control" %}
|
{% bootstrap_field add_position_formset.empty_form.used_membership layout="control" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% bootstrap_field add_formset.empty_form.seat layout="control" %}
|
{% bootstrap_field add_position_formset.empty_form.seat layout="control" %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -431,13 +431,77 @@
|
|||||||
{% bootstrap_field fee.form.operation_cancel layout='inline' %}
|
{% bootstrap_field fee.form.operation_cancel layout='inline' %}
|
||||||
{% if fee.fee_type == "payment" %}
|
{% if fee.fee_type == "payment" %}
|
||||||
<em class="text-danger">
|
<em class="text-danger">
|
||||||
{% trans "Manually modifying payment fees is discouraged since they might automatically be on subsequent order changes or when choosing a different payment method." %}
|
{% trans "Manually modifying payment fees is discouraged since they might automatically be updated on subsequent order changes or when choosing a different payment method." %}
|
||||||
</em>
|
</em>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
<div class="formset" data-formset data-formset-prefix="{{ add_fee_formset.prefix }}">
|
||||||
|
{{ add_fee_formset.management_form }}
|
||||||
|
{% bootstrap_formset_errors add_fee_formset %}
|
||||||
|
<div data-formset-body>
|
||||||
|
{% for add_form in add_fee_formset %}
|
||||||
|
<div class="panel panel-default items" data-formset-form data-subevent="0">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title">
|
||||||
|
<button type="button" class="btn btn-danger btn-xs pull-right flip"
|
||||||
|
data-formset-delete-button>
|
||||||
|
<i class="fa fa-trash"></i>
|
||||||
|
</button>
|
||||||
|
{% trans "Add fee" %}
|
||||||
|
<div class="sr-only">
|
||||||
|
{{ add_form.id }}
|
||||||
|
{% bootstrap_field add_form.DELETE form_group_class="" layout="inline" %}
|
||||||
|
</div>
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="form-horizontal">
|
||||||
|
{% bootstrap_field add_form.fee_type layout='control' %}
|
||||||
|
{% bootstrap_field add_form.value addon_after=request.event.currency layout='control' %}
|
||||||
|
{% bootstrap_field add_form.tax_rule layout='control' %}
|
||||||
|
{% bootstrap_field add_form.description layout='control' %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<script type="form-template" data-formset-empty-form>
|
||||||
|
{% escapescript %}
|
||||||
|
<div class="panel panel-default items" data-formset-form data-subevent="0">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title">
|
||||||
|
<button type="button" class="btn btn-danger btn-xs pull-right flip"
|
||||||
|
data-formset-delete-button>
|
||||||
|
<i class="fa fa-trash"></i>
|
||||||
|
</button>
|
||||||
|
{% trans "Add fee" %}
|
||||||
|
<div class="sr-only">
|
||||||
|
{{ add_fee_formset.empty_form.id }}
|
||||||
|
{% bootstrap_field add_fee_formset.empty_form.DELETE form_group_class="" layout="inline" %}
|
||||||
|
</div>
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="form-horizontal">
|
||||||
|
{% bootstrap_field add_fee_formset.empty_form.fee_type layout='control' %}
|
||||||
|
{% bootstrap_field add_fee_formset.empty_form.value addon_after=request.event.currency layout='control' %}
|
||||||
|
{% bootstrap_field add_fee_formset.empty_form.tax_rule layout='control' %}
|
||||||
|
{% bootstrap_field add_fee_formset.empty_form.description layout='control' %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endescapescript %}
|
||||||
|
</script>
|
||||||
|
<p>
|
||||||
|
<button type="button" class="btn btn-primary" data-formset-add>
|
||||||
|
<i class="fa fa-plus"></i> {% trans "Add fee" %}</button>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="panel panel-default items">
|
<div class="panel panel-default items">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h3 class="panel-title">
|
<h3 class="panel-title">
|
||||||
|
|||||||
@@ -122,10 +122,11 @@ from pretix.control.forms.filter import (
|
|||||||
)
|
)
|
||||||
from pretix.control.forms.orders import (
|
from pretix.control.forms.orders import (
|
||||||
CancelForm, CommentForm, DenyForm, EventCancelForm, ExporterForm,
|
CancelForm, CommentForm, DenyForm, EventCancelForm, ExporterForm,
|
||||||
ExtendForm, MarkPaidForm, OrderContactForm, OrderFeeChangeForm,
|
ExtendForm, MarkPaidForm, OrderContactForm, OrderFeeAddForm,
|
||||||
OrderLocaleForm, OrderMailForm, OrderPositionAddForm,
|
OrderFeeAddFormset, OrderFeeChangeForm, OrderLocaleForm, OrderMailForm,
|
||||||
OrderPositionAddFormset, OrderPositionChangeForm, OrderPositionMailForm,
|
OrderPositionAddForm, OrderPositionAddFormset, OrderPositionChangeForm,
|
||||||
OrderRefundForm, OtherOperationsForm, ReactivateOrderForm,
|
OrderPositionMailForm, OrderRefundForm, OtherOperationsForm,
|
||||||
|
ReactivateOrderForm,
|
||||||
)
|
)
|
||||||
from pretix.control.forms.rrule import RRuleForm
|
from pretix.control.forms.rrule import RRuleForm
|
||||||
from pretix.control.permissions import EventPermissionRequiredMixin
|
from pretix.control.permissions import EventPermissionRequiredMixin
|
||||||
@@ -1874,18 +1875,30 @@ class OrderChange(OrderView):
|
|||||||
data=self.request.POST if self.request.method == "POST" else None)
|
data=self.request.POST if self.request.method == "POST" else None)
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def add_formset(self):
|
def add_position_formset(self):
|
||||||
ff = formset_factory(
|
ff = formset_factory(
|
||||||
OrderPositionAddForm, formset=OrderPositionAddFormset,
|
OrderPositionAddForm, formset=OrderPositionAddFormset,
|
||||||
can_order=False, can_delete=True, extra=0
|
can_order=False, can_delete=True, extra=0
|
||||||
)
|
)
|
||||||
return ff(
|
return ff(
|
||||||
prefix='add',
|
prefix='add_position',
|
||||||
order=self.order,
|
order=self.order,
|
||||||
items=self.items,
|
items=self.items,
|
||||||
data=self.request.POST if self.request.method == "POST" else None
|
data=self.request.POST if self.request.method == "POST" else None
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def add_fee_formset(self):
|
||||||
|
ff = formset_factory(
|
||||||
|
OrderFeeAddForm, formset=OrderFeeAddFormset,
|
||||||
|
can_order=False, can_delete=True, extra=0
|
||||||
|
)
|
||||||
|
return ff(
|
||||||
|
prefix='add_fee',
|
||||||
|
order=self.order,
|
||||||
|
data=self.request.POST if self.request.method == "POST" else None
|
||||||
|
)
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def items(self):
|
def items(self):
|
||||||
return self.request.event.items.prefetch_related('variations', 'tax_rule').all()
|
return self.request.event.items.prefetch_related('variations', 'tax_rule').all()
|
||||||
@@ -1914,7 +1927,8 @@ class OrderChange(OrderView):
|
|||||||
ctx = super().get_context_data(**kwargs)
|
ctx = super().get_context_data(**kwargs)
|
||||||
ctx['positions'] = self.positions
|
ctx['positions'] = self.positions
|
||||||
ctx['fees'] = self.fees
|
ctx['fees'] = self.fees
|
||||||
ctx['add_formset'] = self.add_formset
|
ctx['add_position_formset'] = self.add_position_formset
|
||||||
|
ctx['add_fee_formset'] = self.add_fee_formset
|
||||||
ctx['other_form'] = self.other_form
|
ctx['other_form'] = self.other_form
|
||||||
ctx['use_revocation_list'] = self.request.event.ticket_secret_generator.use_revocation_list
|
ctx['use_revocation_list'] = self.request.event.ticket_secret_generator.use_revocation_list
|
||||||
return ctx
|
return ctx
|
||||||
@@ -1929,12 +1943,35 @@ class OrderChange(OrderView):
|
|||||||
)
|
)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _process_add(self, ocm):
|
def _process_add_fees(self, ocm):
|
||||||
if not self.add_formset.is_valid():
|
if not self.add_fee_formset.is_valid():
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
for f in self.add_formset.forms:
|
for f in self.add_fee_formset.forms:
|
||||||
if f in self.add_formset.deleted_forms or not f.has_changed():
|
if f in self.add_fee_formset.deleted_forms or not f.has_changed():
|
||||||
|
continue
|
||||||
|
|
||||||
|
f = OrderFee(
|
||||||
|
fee_type=f.cleaned_data['fee_type'],
|
||||||
|
value=f.cleaned_data['value'],
|
||||||
|
order=ocm.order,
|
||||||
|
tax_rule=f.cleaned_data['tax_rule'],
|
||||||
|
description=f.cleaned_data['description'],
|
||||||
|
)
|
||||||
|
f._calculate_tax()
|
||||||
|
try:
|
||||||
|
ocm.add_fee(f)
|
||||||
|
except OrderError as e:
|
||||||
|
f.custom_error = str(e)
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def _process_add_positions(self, ocm):
|
||||||
|
if not self.add_position_formset.is_valid():
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
for f in self.add_position_formset.forms:
|
||||||
|
if f in self.add_position_formset.deleted_forms or not f.has_changed():
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if '-' in f.cleaned_data['itemvar']:
|
if '-' in f.cleaned_data['itemvar']:
|
||||||
@@ -1959,7 +1996,7 @@ class OrderChange(OrderView):
|
|||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _process_fees(self, ocm):
|
def _process_change_fees(self, ocm):
|
||||||
for f in self.fees:
|
for f in self.fees:
|
||||||
if not f.form.is_valid():
|
if not f.form.is_valid():
|
||||||
return False
|
return False
|
||||||
@@ -1980,7 +2017,7 @@ class OrderChange(OrderView):
|
|||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _process_change(self, ocm):
|
def _process_change_positions(self, ocm):
|
||||||
for p in self.positions:
|
for p in self.positions:
|
||||||
if not p.form.is_valid():
|
if not p.form.is_valid():
|
||||||
return False
|
return False
|
||||||
@@ -2061,7 +2098,11 @@ class OrderChange(OrderView):
|
|||||||
notify=notify,
|
notify=notify,
|
||||||
reissue_invoice=self.other_form.cleaned_data['reissue_invoice'] if self.other_form.is_valid() else True
|
reissue_invoice=self.other_form.cleaned_data['reissue_invoice'] if self.other_form.is_valid() else True
|
||||||
)
|
)
|
||||||
form_valid = self._process_add(ocm) and self._process_fees(ocm) and self._process_change(ocm) and self._process_other(ocm)
|
form_valid = (self._process_add_fees(ocm) and
|
||||||
|
self._process_add_positions(ocm) and
|
||||||
|
self._process_change_fees(ocm) and
|
||||||
|
self._process_change_positions(ocm) and
|
||||||
|
self._process_other(ocm))
|
||||||
|
|
||||||
if not form_valid:
|
if not form_valid:
|
||||||
messages.error(self.request, _('An error occurred. Please see the details below.'))
|
messages.error(self.request, _('An error occurred. Please see the details below.'))
|
||||||
|
|||||||
@@ -1309,10 +1309,14 @@ class OrderChangeTests(SoupTest):
|
|||||||
self.client.post('/control/event/{}/{}/orders/{}/change'.format(
|
self.client.post('/control/event/{}/{}/orders/{}/change'.format(
|
||||||
self.event.organizer.slug, self.event.slug, self.order.code
|
self.event.organizer.slug, self.event.slug, self.order.code
|
||||||
), {
|
), {
|
||||||
'add-TOTAL_FORMS': '0',
|
'add_fee-TOTAL_FORMS': '0',
|
||||||
'add-INITIAL_FORMS': '0',
|
'add_fee-INITIAL_FORMS': '0',
|
||||||
'add-MIN_NUM_FORMS': '0',
|
'add_fee-MIN_NUM_FORMS': '0',
|
||||||
'add-MAX_NUM_FORMS': '100',
|
'add_fee-MAX_NUM_FORMS': '100',
|
||||||
|
'add_position-TOTAL_FORMS': '0',
|
||||||
|
'add_position-INITIAL_FORMS': '0',
|
||||||
|
'add_position-MIN_NUM_FORMS': '0',
|
||||||
|
'add_position-MAX_NUM_FORMS': '100',
|
||||||
'op-{}-itemvar'.format(self.op1.pk): str(self.shirt.pk),
|
'op-{}-itemvar'.format(self.op1.pk): str(self.shirt.pk),
|
||||||
'op-{}-price'.format(self.op1.pk): str('12.00'),
|
'op-{}-price'.format(self.op1.pk): str('12.00'),
|
||||||
})
|
})
|
||||||
@@ -1341,10 +1345,14 @@ class OrderChangeTests(SoupTest):
|
|||||||
self.client.post('/control/event/{}/{}/orders/{}/change'.format(
|
self.client.post('/control/event/{}/{}/orders/{}/change'.format(
|
||||||
self.event.organizer.slug, self.event.slug, self.order.code
|
self.event.organizer.slug, self.event.slug, self.order.code
|
||||||
), {
|
), {
|
||||||
'add-TOTAL_FORMS': '0',
|
'add_fee-TOTAL_FORMS': '0',
|
||||||
'add-INITIAL_FORMS': '0',
|
'add_fee-INITIAL_FORMS': '0',
|
||||||
'add-MIN_NUM_FORMS': '0',
|
'add_fee-MIN_NUM_FORMS': '0',
|
||||||
'add-MAX_NUM_FORMS': '100',
|
'add_fee-MAX_NUM_FORMS': '100',
|
||||||
|
'add_position-TOTAL_FORMS': '0',
|
||||||
|
'add_position-INITIAL_FORMS': '0',
|
||||||
|
'add_position-MIN_NUM_FORMS': '0',
|
||||||
|
'add_position-MAX_NUM_FORMS': '100',
|
||||||
'op-{}-subevent'.format(self.op1.pk): str(se2.pk),
|
'op-{}-subevent'.format(self.op1.pk): str(se2.pk),
|
||||||
})
|
})
|
||||||
self.op1.refresh_from_db()
|
self.op1.refresh_from_db()
|
||||||
@@ -1373,10 +1381,14 @@ class OrderChangeTests(SoupTest):
|
|||||||
self.client.post('/control/event/{}/{}/orders/{}/change'.format(
|
self.client.post('/control/event/{}/{}/orders/{}/change'.format(
|
||||||
self.event.organizer.slug, self.event.slug, self.order.code
|
self.event.organizer.slug, self.event.slug, self.order.code
|
||||||
), {
|
), {
|
||||||
'add-TOTAL_FORMS': '0',
|
'add_fee-TOTAL_FORMS': '0',
|
||||||
'add-INITIAL_FORMS': '0',
|
'add_fee-INITIAL_FORMS': '0',
|
||||||
'add-MIN_NUM_FORMS': '0',
|
'add_fee-MIN_NUM_FORMS': '0',
|
||||||
'add-MAX_NUM_FORMS': '100',
|
'add_fee-MAX_NUM_FORMS': '100',
|
||||||
|
'add_position-TOTAL_FORMS': '0',
|
||||||
|
'add_position-INITIAL_FORMS': '0',
|
||||||
|
'add_position-MIN_NUM_FORMS': '0',
|
||||||
|
'add_position-MAX_NUM_FORMS': '100',
|
||||||
'op-{}-used_membership'.format(self.op1.pk): str(m_correct1.pk),
|
'op-{}-used_membership'.format(self.op1.pk): str(m_correct1.pk),
|
||||||
'op-{}-used_membership'.format(self.op2.pk): str(m_correct1.pk),
|
'op-{}-used_membership'.format(self.op2.pk): str(m_correct1.pk),
|
||||||
'op-{}-used_membership'.format(self.op3.pk): str(m_correct1.pk),
|
'op-{}-used_membership'.format(self.op3.pk): str(m_correct1.pk),
|
||||||
@@ -1389,10 +1401,14 @@ class OrderChangeTests(SoupTest):
|
|||||||
self.client.post('/control/event/{}/{}/orders/{}/change'.format(
|
self.client.post('/control/event/{}/{}/orders/{}/change'.format(
|
||||||
self.event.organizer.slug, self.event.slug, self.order.code
|
self.event.organizer.slug, self.event.slug, self.order.code
|
||||||
), {
|
), {
|
||||||
'add-TOTAL_FORMS': '0',
|
'add_fee-TOTAL_FORMS': '0',
|
||||||
'add-INITIAL_FORMS': '0',
|
'add_fee-INITIAL_FORMS': '0',
|
||||||
'add-MIN_NUM_FORMS': '0',
|
'add_fee-MIN_NUM_FORMS': '0',
|
||||||
'add-MAX_NUM_FORMS': '100',
|
'add_fee-MAX_NUM_FORMS': '100',
|
||||||
|
'add_position-TOTAL_FORMS': '0',
|
||||||
|
'add_position-INITIAL_FORMS': '0',
|
||||||
|
'add_position-MIN_NUM_FORMS': '0',
|
||||||
|
'add_position-MAX_NUM_FORMS': '100',
|
||||||
'op-{}-operation'.format(self.op1.pk): 'price',
|
'op-{}-operation'.format(self.op1.pk): 'price',
|
||||||
'op-{}-itemvar'.format(self.op1.pk): str(self.ticket.pk),
|
'op-{}-itemvar'.format(self.op1.pk): str(self.ticket.pk),
|
||||||
'op-{}-price'.format(self.op1.pk): '24.00',
|
'op-{}-price'.format(self.op1.pk): '24.00',
|
||||||
@@ -1409,10 +1425,14 @@ class OrderChangeTests(SoupTest):
|
|||||||
self.client.post('/control/event/{}/{}/orders/{}/change'.format(
|
self.client.post('/control/event/{}/{}/orders/{}/change'.format(
|
||||||
self.event.organizer.slug, self.event.slug, self.order.code
|
self.event.organizer.slug, self.event.slug, self.order.code
|
||||||
), {
|
), {
|
||||||
'add-TOTAL_FORMS': '0',
|
'add_fee-TOTAL_FORMS': '0',
|
||||||
'add-INITIAL_FORMS': '0',
|
'add_fee-INITIAL_FORMS': '0',
|
||||||
'add-MIN_NUM_FORMS': '0',
|
'add_fee-MIN_NUM_FORMS': '0',
|
||||||
'add-MAX_NUM_FORMS': '100',
|
'add_fee-MAX_NUM_FORMS': '100',
|
||||||
|
'add_position-TOTAL_FORMS': '0',
|
||||||
|
'add_position-INITIAL_FORMS': '0',
|
||||||
|
'add_position-MIN_NUM_FORMS': '0',
|
||||||
|
'add_position-MAX_NUM_FORMS': '100',
|
||||||
'op-{}-operation_cancel'.format(self.op1.pk): 'on',
|
'op-{}-operation_cancel'.format(self.op1.pk): 'on',
|
||||||
})
|
})
|
||||||
self.order.refresh_from_db()
|
self.order.refresh_from_db()
|
||||||
@@ -1424,13 +1444,17 @@ class OrderChangeTests(SoupTest):
|
|||||||
self.client.post('/control/event/{}/{}/orders/{}/change'.format(
|
self.client.post('/control/event/{}/{}/orders/{}/change'.format(
|
||||||
self.event.organizer.slug, self.event.slug, self.order.code
|
self.event.organizer.slug, self.event.slug, self.order.code
|
||||||
), {
|
), {
|
||||||
'add-TOTAL_FORMS': '1',
|
'add_fee-TOTAL_FORMS': '0',
|
||||||
'add-INITIAL_FORMS': '0',
|
'add_fee-INITIAL_FORMS': '0',
|
||||||
'add-MIN_NUM_FORMS': '0',
|
'add_fee-MIN_NUM_FORMS': '0',
|
||||||
'add-MAX_NUM_FORMS': '100',
|
'add_fee-MAX_NUM_FORMS': '100',
|
||||||
'add-0-itemvar': str(self.shirt.pk),
|
'add_position-TOTAL_FORMS': '1',
|
||||||
'add-0-do': 'on',
|
'add_position-INITIAL_FORMS': '0',
|
||||||
'add-0-price': '14.00',
|
'add_position-MIN_NUM_FORMS': '0',
|
||||||
|
'add_position-MAX_NUM_FORMS': '100',
|
||||||
|
'add_position-0-itemvar': str(self.shirt.pk),
|
||||||
|
'add_position-0-do': 'on',
|
||||||
|
'add_position-0-price': '14.00',
|
||||||
})
|
})
|
||||||
with scopes_disabled():
|
with scopes_disabled():
|
||||||
assert self.order.positions.count() == 3
|
assert self.order.positions.count() == 3
|
||||||
@@ -1453,10 +1477,14 @@ class OrderChangeTests(SoupTest):
|
|||||||
self.client.post('/control/event/{}/{}/orders/{}/change'.format(
|
self.client.post('/control/event/{}/{}/orders/{}/change'.format(
|
||||||
self.event.organizer.slug, self.event.slug, self.order.code
|
self.event.organizer.slug, self.event.slug, self.order.code
|
||||||
), {
|
), {
|
||||||
'add-TOTAL_FORMS': '0',
|
'add_fee-TOTAL_FORMS': '0',
|
||||||
'add-INITIAL_FORMS': '0',
|
'add_fee-INITIAL_FORMS': '0',
|
||||||
'add-MIN_NUM_FORMS': '0',
|
'add_fee-MIN_NUM_FORMS': '0',
|
||||||
'add-MAX_NUM_FORMS': '100',
|
'add_fee-MAX_NUM_FORMS': '100',
|
||||||
|
'add_position-TOTAL_FORMS': '0',
|
||||||
|
'add_position-INITIAL_FORMS': '0',
|
||||||
|
'add_position-MIN_NUM_FORMS': '0',
|
||||||
|
'add_position-MAX_NUM_FORMS': '100',
|
||||||
'other-recalculate_taxes': 'net',
|
'other-recalculate_taxes': 'net',
|
||||||
'op-{}-operation'.format(self.op1.pk): '',
|
'op-{}-operation'.format(self.op1.pk): '',
|
||||||
'op-{}-operation'.format(self.op2.pk): '',
|
'op-{}-operation'.format(self.op2.pk): '',
|
||||||
@@ -1489,10 +1517,14 @@ class OrderChangeTests(SoupTest):
|
|||||||
self.client.post('/control/event/{}/{}/orders/{}/change'.format(
|
self.client.post('/control/event/{}/{}/orders/{}/change'.format(
|
||||||
self.event.organizer.slug, self.event.slug, self.order.code
|
self.event.organizer.slug, self.event.slug, self.order.code
|
||||||
), {
|
), {
|
||||||
'add-TOTAL_FORMS': '0',
|
'add_fee-TOTAL_FORMS': '0',
|
||||||
'add-INITIAL_FORMS': '0',
|
'add_fee-INITIAL_FORMS': '0',
|
||||||
'add-MIN_NUM_FORMS': '0',
|
'add_fee-MIN_NUM_FORMS': '0',
|
||||||
'add-MAX_NUM_FORMS': '100',
|
'add_fee-MAX_NUM_FORMS': '100',
|
||||||
|
'add_position-TOTAL_FORMS': '0',
|
||||||
|
'add_position-INITIAL_FORMS': '0',
|
||||||
|
'add_position-MIN_NUM_FORMS': '0',
|
||||||
|
'add_position-MAX_NUM_FORMS': '100',
|
||||||
'other-recalculate_taxes': 'gross',
|
'other-recalculate_taxes': 'gross',
|
||||||
'op-{}-operation'.format(self.op1.pk): '',
|
'op-{}-operation'.format(self.op1.pk): '',
|
||||||
'op-{}-operation'.format(self.op2.pk): '',
|
'op-{}-operation'.format(self.op2.pk): '',
|
||||||
@@ -1517,10 +1549,14 @@ class OrderChangeTests(SoupTest):
|
|||||||
self.client.post('/control/event/{}/{}/orders/{}/change'.format(
|
self.client.post('/control/event/{}/{}/orders/{}/change'.format(
|
||||||
self.event.organizer.slug, self.event.slug, self.order.code
|
self.event.organizer.slug, self.event.slug, self.order.code
|
||||||
), {
|
), {
|
||||||
'add-TOTAL_FORMS': '0',
|
'add_fee-TOTAL_FORMS': '0',
|
||||||
'add-INITIAL_FORMS': '0',
|
'add_fee-INITIAL_FORMS': '0',
|
||||||
'add-MIN_NUM_FORMS': '0',
|
'add_fee-MIN_NUM_FORMS': '0',
|
||||||
'add-MAX_NUM_FORMS': '100',
|
'add_fee-MAX_NUM_FORMS': '100',
|
||||||
|
'add_position-TOTAL_FORMS': '0',
|
||||||
|
'add_position-INITIAL_FORMS': '0',
|
||||||
|
'add_position-MIN_NUM_FORMS': '0',
|
||||||
|
'add_position-MAX_NUM_FORMS': '100',
|
||||||
'op-{}-price'.format(self.op1.pk): '24.00',
|
'op-{}-price'.format(self.op1.pk): '24.00',
|
||||||
'op-{}-operation'.format(self.op2.pk): '',
|
'op-{}-operation'.format(self.op2.pk): '',
|
||||||
'op-{}-itemvar'.format(self.op2.pk): str(self.ticket.pk),
|
'op-{}-itemvar'.format(self.op2.pk): str(self.ticket.pk),
|
||||||
@@ -1544,10 +1580,14 @@ class OrderChangeTests(SoupTest):
|
|||||||
self.client.post('/control/event/{}/{}/orders/{}/change'.format(
|
self.client.post('/control/event/{}/{}/orders/{}/change'.format(
|
||||||
self.event.organizer.slug, self.event.slug, self.order.code
|
self.event.organizer.slug, self.event.slug, self.order.code
|
||||||
), {
|
), {
|
||||||
'add-TOTAL_FORMS': '0',
|
'add_fee-TOTAL_FORMS': '0',
|
||||||
'add-INITIAL_FORMS': '0',
|
'add_fee-INITIAL_FORMS': '0',
|
||||||
'add-MIN_NUM_FORMS': '0',
|
'add_fee-MIN_NUM_FORMS': '0',
|
||||||
'add-MAX_NUM_FORMS': '100',
|
'add_fee-MAX_NUM_FORMS': '100',
|
||||||
|
'add_position-TOTAL_FORMS': '0',
|
||||||
|
'add_position-INITIAL_FORMS': '0',
|
||||||
|
'add_position-MIN_NUM_FORMS': '0',
|
||||||
|
'add_position-MAX_NUM_FORMS': '100',
|
||||||
'op-{}-operation'.format(self.op1.pk): 'price',
|
'op-{}-operation'.format(self.op1.pk): 'price',
|
||||||
'op-{}-itemvar'.format(self.op1.pk): str(self.ticket.pk),
|
'op-{}-itemvar'.format(self.op1.pk): str(self.ticket.pk),
|
||||||
'op-{}-price'.format(self.op1.pk): '24.00',
|
'op-{}-price'.format(self.op1.pk): '24.00',
|
||||||
@@ -1563,6 +1603,34 @@ class OrderChangeTests(SoupTest):
|
|||||||
self.op2.refresh_from_db()
|
self.op2.refresh_from_db()
|
||||||
assert self.order.total == self.op1.price + self.op2.price
|
assert self.order.total == self.op1.price + self.op2.price
|
||||||
|
|
||||||
|
def test_add_fee_success(self):
|
||||||
|
old_total = self.order.total
|
||||||
|
r = self.client.post('/control/event/{}/{}/orders/{}/change'.format(
|
||||||
|
self.event.organizer.slug, self.event.slug, self.order.code
|
||||||
|
), {
|
||||||
|
'add_fee-TOTAL_FORMS': '1',
|
||||||
|
'add_fee-INITIAL_FORMS': '0',
|
||||||
|
'add_fee-MIN_NUM_FORMS': '0',
|
||||||
|
'add_fee-MAX_NUM_FORMS': '100',
|
||||||
|
'add_position-TOTAL_FORMS': '0',
|
||||||
|
'add_position-INITIAL_FORMS': '0',
|
||||||
|
'add_position-MIN_NUM_FORMS': '0',
|
||||||
|
'add_position-MAX_NUM_FORMS': '100',
|
||||||
|
'add_fee-0-do': 'on',
|
||||||
|
'add_fee-0-fee_type': 'other',
|
||||||
|
'add_fee-0-description': 'Surprise Fee',
|
||||||
|
'add_fee-0-value': '5.00',
|
||||||
|
})
|
||||||
|
assert r.status_code == 302
|
||||||
|
self.order.refresh_from_db()
|
||||||
|
with scopes_disabled():
|
||||||
|
fee = self.order.fees.get()
|
||||||
|
assert fee.fee_type == OrderFee.FEE_TYPE_OTHER
|
||||||
|
assert fee.description == 'Surprise Fee'
|
||||||
|
assert fee.value == Decimal('5.00')
|
||||||
|
assert not fee.canceled
|
||||||
|
assert self.order.total == old_total + 5
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
def test_check_vatid(client, env):
|
def test_check_vatid(client, env):
|
||||||
|
|||||||
@@ -405,11 +405,11 @@ class ItemDisplayTest(EventTestMixin, SoupTest):
|
|||||||
SubEventItem.objects.create(subevent=se1, item=item, price=12)
|
SubEventItem.objects.create(subevent=se1, item=item, price=12)
|
||||||
|
|
||||||
resp = self.client.get('/%s/%s/%d/' % (self.orga.slug, self.event.slug, se1.pk))
|
resp = self.client.get('/%s/%s/%d/' % (self.orga.slug, self.event.slug, se1.pk))
|
||||||
self.assertIn("12.00", resp.rendered_content)
|
self.assertIn("€12.00", resp.rendered_content)
|
||||||
self.assertNotIn("15.00", resp.rendered_content)
|
self.assertNotIn("€15.00", resp.rendered_content)
|
||||||
resp = self.client.get('/%s/%s/%d/' % (self.orga.slug, self.event.slug, se2.pk))
|
resp = self.client.get('/%s/%s/%d/' % (self.orga.slug, self.event.slug, se2.pk))
|
||||||
self.assertIn("15.00", resp.rendered_content)
|
self.assertIn("€15.00", resp.rendered_content)
|
||||||
self.assertNotIn("12.00", resp.rendered_content)
|
self.assertNotIn("€12.00", resp.rendered_content)
|
||||||
|
|
||||||
def test_subevent_net_prices(self):
|
def test_subevent_net_prices(self):
|
||||||
self.event.has_subevents = True
|
self.event.has_subevents = True
|
||||||
@@ -429,14 +429,14 @@ class ItemDisplayTest(EventTestMixin, SoupTest):
|
|||||||
|
|
||||||
resp = self.client.get('/%s/%s/%d/' % (self.orga.slug, self.event.slug, se1.pk))
|
resp = self.client.get('/%s/%s/%d/' % (self.orga.slug, self.event.slug, se1.pk))
|
||||||
doc = BeautifulSoup(resp.rendered_content, "lxml")
|
doc = BeautifulSoup(resp.rendered_content, "lxml")
|
||||||
self.assertIn("10.08", doc.text)
|
self.assertIn("€10.08", doc.text)
|
||||||
self.assertNotIn("12.00", doc.text)
|
self.assertNotIn("€12.00", doc.text)
|
||||||
self.assertNotIn("15.00", doc.text)
|
self.assertNotIn("€15.00", doc.text)
|
||||||
resp = self.client.get('/%s/%s/%d/' % (self.orga.slug, self.event.slug, se2.pk))
|
resp = self.client.get('/%s/%s/%d/' % (self.orga.slug, self.event.slug, se2.pk))
|
||||||
doc = BeautifulSoup(resp.rendered_content, "lxml")
|
doc = BeautifulSoup(resp.rendered_content, "lxml")
|
||||||
self.assertIn("12.61", doc.text)
|
self.assertIn("€12.61", doc.text)
|
||||||
self.assertNotIn("12.00", doc.text)
|
self.assertNotIn("€12.00", doc.text)
|
||||||
self.assertNotIn("15.00", doc.text)
|
self.assertNotIn("€15.00", doc.text)
|
||||||
|
|
||||||
def test_variations_subevent_disabled(self):
|
def test_variations_subevent_disabled(self):
|
||||||
self.event.has_subevents = True
|
self.event.has_subevents = True
|
||||||
|
|||||||
Reference in New Issue
Block a user