mirror of
https://github.com/pretix/pretix.git
synced 2026-05-05 15:14:04 +00:00
Add Order.custom_followup_at (#2124)
This commit is contained in:
@@ -654,7 +654,7 @@ class OrderSerializer(I18nAwareModelSerializer):
|
||||
model = Order
|
||||
fields = (
|
||||
'code', 'status', 'testmode', 'secret', 'email', 'phone', 'locale', 'datetime', 'expires', 'payment_date',
|
||||
'payment_provider', 'fees', 'total', 'comment', 'invoice_address', 'positions', 'downloads',
|
||||
'payment_provider', 'fees', 'total', 'comment', 'custom_followup_at', 'invoice_address', 'positions', 'downloads',
|
||||
'checkin_attention', 'last_modified', 'payments', 'refunds', 'require_approval', 'sales_channel',
|
||||
'url', 'customer'
|
||||
)
|
||||
@@ -685,7 +685,7 @@ class OrderSerializer(I18nAwareModelSerializer):
|
||||
def update(self, instance, validated_data):
|
||||
# Even though all fields that shouldn't be edited are marked as read_only in the serializer
|
||||
# (hopefully), we'll be extra careful here and be explicit about the model fields we update.
|
||||
update_fields = ['comment', 'checkin_attention', 'email', 'locale', 'phone']
|
||||
update_fields = ['comment', 'custom_followup_at', 'checkin_attention', 'email', 'locale', 'phone']
|
||||
|
||||
if 'invoice_address' in validated_data:
|
||||
iadata = validated_data.pop('invoice_address')
|
||||
@@ -925,6 +925,7 @@ class OrderCreateSerializer(I18nAwareModelSerializer):
|
||||
min_length=5
|
||||
)
|
||||
comment = serializers.CharField(required=False, allow_blank=True)
|
||||
custom_followup_at = serializers.DateField(required=False, allow_null=True)
|
||||
payment_provider = serializers.CharField(required=False, allow_null=True)
|
||||
payment_info = CompatibleJSONField(required=False)
|
||||
consume_carts = serializers.ListField(child=serializers.CharField(), required=False)
|
||||
@@ -943,7 +944,7 @@ class OrderCreateSerializer(I18nAwareModelSerializer):
|
||||
model = Order
|
||||
fields = ('code', 'status', 'testmode', 'email', 'phone', 'locale', 'payment_provider', 'fees', 'comment', 'sales_channel',
|
||||
'invoice_address', 'positions', 'checkin_attention', 'payment_info', 'payment_date', 'consume_carts',
|
||||
'force', 'send_email', 'simulate', 'customer')
|
||||
'force', 'send_email', 'simulate', 'customer', 'custom_followup_at')
|
||||
|
||||
def validate_payment_provider(self, pp):
|
||||
if pp is None:
|
||||
|
||||
@@ -692,6 +692,16 @@ class OrderViewSet(viewsets.ModelViewSet):
|
||||
}
|
||||
)
|
||||
|
||||
if 'custom_followup_at' in self.request.data and serializer.instance.custom_followup_at != self.request.data.get('custom_followup_at'):
|
||||
serializer.instance.log_action(
|
||||
'pretix.event.order.custom_followup_at',
|
||||
user=self.request.user,
|
||||
auth=self.request.auth,
|
||||
data={
|
||||
'new_custom_followup_at': self.request.data.get('custom_followup_at')
|
||||
}
|
||||
)
|
||||
|
||||
if 'checkin_attention' in self.request.data and serializer.instance.checkin_attention != self.request.data.get('checkin_attention'):
|
||||
serializer.instance.log_action(
|
||||
'pretix.event.order.checkin_attention',
|
||||
|
||||
@@ -288,6 +288,7 @@ class OrderListExporter(MultiSheetListExporter):
|
||||
headers.append(_('Sales channel'))
|
||||
headers.append(_('Requires special attention'))
|
||||
headers.append(_('Comment'))
|
||||
headers.append(_('Follow-up date'))
|
||||
headers.append(_('Positions'))
|
||||
headers.append(_('E-mail address verified'))
|
||||
headers.append(_('Payment providers'))
|
||||
@@ -393,6 +394,7 @@ class OrderListExporter(MultiSheetListExporter):
|
||||
row.append(order.sales_channel)
|
||||
row.append(_('Yes') if order.checkin_attention else _('No'))
|
||||
row.append(order.comment or "")
|
||||
row.append(order.custom_followup_at.strftime("%Y-%m-%d") if order.custom_followup_at else "")
|
||||
row.append(order.pcnt)
|
||||
row.append(_('Yes') if order.email_known_to_work else _('No'))
|
||||
row.append(', '.join([
|
||||
@@ -574,6 +576,7 @@ class OrderListExporter(MultiSheetListExporter):
|
||||
_('Seat row'),
|
||||
_('Seat number'),
|
||||
_('Order comment'),
|
||||
_('Follow-up date'),
|
||||
]
|
||||
|
||||
questions = list(Question.objects.filter(event__in=self.events))
|
||||
@@ -677,6 +680,7 @@ class OrderListExporter(MultiSheetListExporter):
|
||||
row += ['', '', '', '', '']
|
||||
|
||||
row.append(order.comment)
|
||||
row.append(order.custom_followup_at.strftime("%Y-%m-%d") if order.custom_followup_at else "")
|
||||
acache = {}
|
||||
for a in op.answers.all():
|
||||
# We do not want to localize Date, Time and Datetime question answers, as those can lead
|
||||
@@ -780,7 +784,7 @@ class PaymentListExporter(ListExporter):
|
||||
|
||||
headers = [
|
||||
_('Event slug'), _('Order'), _('Payment ID'), _('Creation date'), _('Completion date'), _('Status'),
|
||||
_('Status code'), _('Amount'), _('Payment method'), _('Comment')
|
||||
_('Status code'), _('Amount'), _('Payment method'), _('Comment'),
|
||||
]
|
||||
yield headers
|
||||
|
||||
|
||||
25
src/pretix/base/migrations/0193_auto_20210611_1355.py
Normal file
25
src/pretix/base/migrations/0193_auto_20210611_1355.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# Generated by Django 3.2.3 on 2021-06-11 13:55
|
||||
|
||||
import django.db.models.manager
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('pretixbase', '0192_checkin_more_fields'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelManagers(
|
||||
name='checkin',
|
||||
managers=[
|
||||
('all', django.db.models.manager.Manager()),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='order',
|
||||
name='custom_followup_at',
|
||||
field=models.DateField(blank=True, null=True),
|
||||
),
|
||||
]
|
||||
@@ -60,7 +60,7 @@ from django.utils.crypto import get_random_string
|
||||
from django.utils.encoding import escape_uri_path
|
||||
from django.utils.formats import date_format
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.timezone import make_aware, now
|
||||
from django.utils.timezone import get_current_timezone, make_aware, now
|
||||
from django.utils.translation import gettext_lazy as _, pgettext_lazy
|
||||
from django_countries.fields import Country
|
||||
from django_scopes import ScopedManager, scopes_disabled
|
||||
@@ -217,6 +217,11 @@ class Order(LockModel, LoggedModel):
|
||||
help_text=_("The text entered in this field will not be visible to the user and is available for your "
|
||||
"convenience.")
|
||||
)
|
||||
custom_followup_at = models.DateField(
|
||||
verbose_name=_("Follow-up date"),
|
||||
help_text=_('We\'ll show you this order to be due for a follow-up on this day.'),
|
||||
null=True, blank=True
|
||||
)
|
||||
checkin_attention = models.BooleanField(
|
||||
verbose_name=_('Requires special attention'),
|
||||
default=False,
|
||||
@@ -300,6 +305,10 @@ class Order(LockModel, LoggedModel):
|
||||
"""
|
||||
return self.all_fees(manager='objects')
|
||||
|
||||
@property
|
||||
def custom_followup_due(self):
|
||||
return self.custom_followup_at and self.custom_followup_at <= now().astimezone(get_current_timezone()).date()
|
||||
|
||||
@cached_property
|
||||
@scopes_disabled()
|
||||
def count_positions(self):
|
||||
|
||||
@@ -205,6 +205,10 @@ class OrderFilterForm(FilterForm):
|
||||
('na', _('Approved, payment pending')),
|
||||
('pa', _('Approval pending')),
|
||||
)),
|
||||
(_('Follow-up date'), (
|
||||
('custom_followup_at', _('Follow-up configured')),
|
||||
('custom_followup_due', _('Follow-up due')),
|
||||
)),
|
||||
('testmode', _('Test mode')),
|
||||
),
|
||||
required=False,
|
||||
@@ -324,6 +328,14 @@ class OrderFilterForm(FilterForm):
|
||||
status=Order.STATUS_PENDING,
|
||||
require_approval=False
|
||||
)
|
||||
elif s == 'custom_followup_at':
|
||||
qs = qs.filter(
|
||||
custom_followup_at__isnull=False
|
||||
)
|
||||
elif s == 'custom_followup_due':
|
||||
qs = qs.filter(
|
||||
custom_followup_at__lte=now().astimezone(get_current_timezone()).date()
|
||||
)
|
||||
elif s == 'testmode':
|
||||
qs = qs.filter(
|
||||
testmode=True
|
||||
|
||||
@@ -230,12 +230,13 @@ class ExporterForm(forms.Form):
|
||||
class CommentForm(I18nModelForm):
|
||||
class Meta:
|
||||
model = Order
|
||||
fields = ['comment', 'checkin_attention']
|
||||
fields = ['comment', 'checkin_attention', 'custom_followup_at']
|
||||
widgets = {
|
||||
'comment': forms.Textarea(attrs={
|
||||
'rows': 3,
|
||||
'class': 'helper-width-100',
|
||||
}),
|
||||
'custom_followup_at': DatePickerWidget(),
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -360,6 +360,7 @@ def pretixcontrol_logentry_display(sender: Event, logentry: LogEntry, **kwargs):
|
||||
'pretix.event.order.invoice.regenerated': _('The invoice has been regenerated.'),
|
||||
'pretix.event.order.invoice.reissued': _('The invoice has been reissued.'),
|
||||
'pretix.event.order.comment': _('The order\'s internal comment has been updated.'),
|
||||
'pretix.event.order.custom_followup_at': _('The order\'s follow-up date has been updated.'),
|
||||
'pretix.event.order.checkin_attention': _('The order\'s flag to require attention at check-in has been '
|
||||
'toggled.'),
|
||||
'pretix.event.order.payment.changed': _('A new payment {local_id} has been started instead of the previous one.'),
|
||||
|
||||
@@ -890,10 +890,9 @@
|
||||
<form class="form" method="post"
|
||||
action="{% url "control:event.order.comment" event=request.event.slug organizer=request.event.organizer.slug code=order.code %}">
|
||||
{% csrf_token %}
|
||||
<div class="row">
|
||||
{% bootstrap_field comment_form.comment layout="horizontal" show_help=True show_label=False horizontal_field_class="col-md-12" %}
|
||||
{% bootstrap_field comment_form.checkin_attention layout="horizontal" show_help=True show_label=False horizontal_field_class="col-md-12" %}
|
||||
</div>
|
||||
{% bootstrap_field comment_form.comment show_help=True show_label=False %}
|
||||
{% bootstrap_field comment_form.custom_followup_at %}
|
||||
{% bootstrap_field comment_form.checkin_attention show_help=True show_label=False %}
|
||||
<button class="btn btn-default">
|
||||
{% trans "Update comment" %}
|
||||
</button>
|
||||
|
||||
@@ -134,6 +134,11 @@
|
||||
{% if o.testmode %}
|
||||
<span class="label label-warning">{% trans "TEST MODE" %}</span>
|
||||
{% endif %}
|
||||
{% if o.custom_followup_due %}
|
||||
<span class="label label-danger">{% blocktrans with date=o.custom_followup_at|date:"SHORT_DATE_FORMAT" context "followup" %}TODO {{ date }}{% endblocktrans %}</span>
|
||||
{% elif o.custom_followup_at %}
|
||||
<span class="label label-default">{% blocktrans with date=o.custom_followup_at|date:"SHORT_DATE_FORMAT" context "followup" %}TODO {{ date }}{% endblocktrans %}</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{{ o.email|default_if_none:"" }}
|
||||
|
||||
@@ -69,6 +69,11 @@
|
||||
{% if o.testmode %}
|
||||
<span class="label label-warning">{% trans "TEST MODE" %}</span>
|
||||
{% endif %}
|
||||
{% if o.custom_followup_due %}
|
||||
<span class="label label-danger">{% blocktrans with date=o.custom_followup_at|date:"SHORT_DATE_FORMAT" context "followup" %}TODO {{ date }}{% endblocktrans %}</span>
|
||||
{% elif o.custom_followup_at %}
|
||||
<span class="label label-default">{% blocktrans with date=o.custom_followup_at|date:"SHORT_DATE_FORMAT" context "followup" %}TODO {{ date }}{% endblocktrans %}</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ o.event.name }}</td>
|
||||
<td>
|
||||
|
||||
@@ -303,6 +303,7 @@ class OrderDetail(OrderView):
|
||||
ctx['invoices'] = list(self.order.invoices.all().select_related('event'))
|
||||
ctx['comment_form'] = CommentForm(initial={
|
||||
'comment': self.order.comment,
|
||||
'custom_followup_at': self.order.custom_followup_at,
|
||||
'checkin_attention': self.order.checkin_attention
|
||||
})
|
||||
ctx['display_locale'] = dict(settings.LANGUAGES)[self.object.locale or self.request.event.settings.locale]
|
||||
@@ -487,12 +488,21 @@ class OrderComment(OrderView):
|
||||
'new_comment': form.cleaned_data.get('comment')
|
||||
})
|
||||
|
||||
if form.cleaned_data.get('custom_followup_at') != self.order.custom_followup_at:
|
||||
self.order.custom_followup_at = form.cleaned_data.get('custom_followup_at')
|
||||
self.order.log_action('pretix.event.order.custom_followup_at', user=self.request.user, data={
|
||||
'new_custom_followup_at': form.cleaned_data.get('custom_followup_at')
|
||||
})
|
||||
|
||||
if form.cleaned_data.get('checkin_attention') != self.order.checkin_attention:
|
||||
self.order.checkin_attention = form.cleaned_data.get('checkin_attention')
|
||||
self.order.log_action('pretix.event.order.checkin_attention', user=self.request.user, data={
|
||||
'new_value': form.cleaned_data.get('checkin_attention')
|
||||
})
|
||||
self.order.save(update_fields=['checkin_attention', 'comment'])
|
||||
print(self.order.custom_followup_at)
|
||||
self.order.save(update_fields=['checkin_attention', 'comment', 'custom_followup_at'])
|
||||
self.order.refresh_from_db()
|
||||
print(self.order.custom_followup_at)
|
||||
messages.success(self.request, _('The comment has been updated.'))
|
||||
else:
|
||||
messages.error(self.request, _('Could not update the comment.'))
|
||||
|
||||
@@ -256,6 +256,7 @@ TEST_ORDER_RES = {
|
||||
"payment_provider": "banktransfer",
|
||||
"total": "23.00",
|
||||
"comment": "",
|
||||
"custom_followup_at": None,
|
||||
"checkin_attention": False,
|
||||
"invoice_address": {
|
||||
"last_modified": "2017-12-01T10:00:00Z",
|
||||
@@ -1739,6 +1740,7 @@ def test_order_create_simulate(token_client, organizer, event, item, quota, ques
|
||||
],
|
||||
'total': '23.25',
|
||||
'comment': '',
|
||||
"custom_followup_at": None,
|
||||
'invoice_address': {
|
||||
'is_business': False,
|
||||
'company': 'Sample company',
|
||||
@@ -4202,6 +4204,7 @@ def test_order_update_allowed_fields(token_client, organizer, event, order):
|
||||
organizer.slug, event.slug, order.code
|
||||
), format='json', data={
|
||||
'comment': 'Here is a comment',
|
||||
'custom_followup_at': '2021-06-12',
|
||||
'checkin_attention': True,
|
||||
'email': 'foo@bar.com',
|
||||
'phone': '+4962219999',
|
||||
@@ -4224,6 +4227,7 @@ def test_order_update_allowed_fields(token_client, organizer, event, order):
|
||||
assert resp.status_code == 200
|
||||
order.refresh_from_db()
|
||||
assert order.comment == 'Here is a comment'
|
||||
assert order.custom_followup_at.isoformat() == '2021-06-12'
|
||||
assert order.checkin_attention
|
||||
assert order.email == 'foo@bar.com'
|
||||
assert order.phone == '+4962219999'
|
||||
@@ -4236,6 +4240,7 @@ def test_order_update_allowed_fields(token_client, organizer, event, order):
|
||||
assert order.invoice_address.city == "Paris"
|
||||
with scopes_disabled():
|
||||
assert order.all_logentries().get(action_type='pretix.event.order.comment')
|
||||
assert order.all_logentries().get(action_type='pretix.event.order.custom_followup_at')
|
||||
assert order.all_logentries().get(action_type='pretix.event.order.checkin_attention')
|
||||
assert order.all_logentries().get(action_type='pretix.event.order.contact.changed')
|
||||
assert order.all_logentries().get(action_type='pretix.event.order.phone.changed')
|
||||
|
||||
Reference in New Issue
Block a user