Voucher: Add creation date (Z#23202621)

This commit is contained in:
Raphael Michel
2025-08-08 11:19:39 +02:00
parent b4264c0ae7
commit 991271a87c
5 changed files with 54 additions and 2 deletions

View File

@@ -14,6 +14,7 @@ The voucher resource contains the following public fields:
Field Type Description Field Type Description
===================================== ========================== ======================================================= ===================================== ========================== =======================================================
id integer Internal ID of the voucher id integer Internal ID of the voucher
created datetime The creation date of the voucher. For vouchers created before pretix 2025.7.0, this is guessed retroactively and might not be accurate.
code string The voucher code that is required to redeem the voucher code string The voucher code that is required to redeem the voucher
max_usages integer The maximum number of times this voucher can be max_usages integer The maximum number of times this voucher can be
redeemed (default: 1). redeemed (default: 1).
@@ -84,7 +85,7 @@ Endpoints
"results": [ "results": [
{ {
"id": 1, "id": 1,
"code": "43K6LKM37FBVR2YG", "created": "2020-09-18T14:17:40.971519Z",
"max_usages": 1, "max_usages": 1,
"redeemed": 0, "redeemed": 0,
"valid_until": null, "valid_until": null,
@@ -156,6 +157,7 @@ Endpoints
{ {
"id": 1, "id": 1,
"created": "2020-09-18T14:17:40.971519Z",
"code": "43K6LKM37FBVR2YG", "code": "43K6LKM37FBVR2YG",
"max_usages": 1, "max_usages": 1,
"redeemed": 0, "redeemed": 0,
@@ -228,6 +230,7 @@ Endpoints
{ {
"id": 1, "id": 1,
"created": "2020-09-18T14:17:40.971519Z",
"code": "43K6LKM37FBVR2YG", "code": "43K6LKM37FBVR2YG",
"max_usages": 1, "max_usages": 1,
"redeemed": 0, "redeemed": 0,
@@ -321,6 +324,7 @@ Endpoints
[ [
{ {
"id": 1, "id": 1,
"created": "2020-09-18T14:17:40.971519Z",
"code": "43K6LKM37FBVR2YG", "code": "43K6LKM37FBVR2YG",
}, … }, …
@@ -367,6 +371,7 @@ Endpoints
{ {
"id": 1, "id": 1,
"created": "2020-09-18T14:17:40.971519Z",
"code": "43K6LKM37FBVR2YG", "code": "43K6LKM37FBVR2YG",
"max_usages": 1, "max_usages": 1,
"redeemed": 0, "redeemed": 0,

View File

@@ -70,7 +70,7 @@ class VoucherSerializer(I18nAwareModelSerializer):
class Meta: class Meta:
model = Voucher model = Voucher
fields = ('id', 'code', 'max_usages', 'redeemed', 'min_usages', 'valid_until', 'block_quota', fields = ('id', 'created', 'code', 'max_usages', 'redeemed', 'min_usages', 'valid_until', 'block_quota',
'allow_ignore_quota', 'price_mode', 'value', 'item', 'variation', 'quota', 'allow_ignore_quota', 'price_mode', 'value', 'item', 'variation', 'quota',
'tag', 'comment', 'subevent', 'show_hidden_items', 'seat', 'all_addons_included', 'tag', 'comment', 'subevent', 'show_hidden_items', 'seat', 'all_addons_included',
'all_bundles_included', 'budget', 'budget_used') 'all_bundles_included', 'budget', 'budget_used')

View File

@@ -0,0 +1,42 @@
# Generated by Django 4.2.16 on 2025-08-08 09:13
from django.db import migrations, models
from django.db.models import Min
from django.utils.timezone import now
def backfill_voucher_created(apps, schema_editor):
Voucher = apps.get_model("pretixbase", "Voucher")
LogEntry = apps.get_model("pretixbase", "LogEntry")
ContentType = apps.get_model("contenttypes", "ContentType")
ct = ContentType.objects.get(app_label='pretixbase', model='voucher')
for v in Voucher.objects.filter(created__isnull=True).iterator():
v.created = LogEntry.objects.filter(
content_type=ct,
object_id=v.pk,
).aggregate(m=Min("datetime"))["m"] or now()
v.save(update_fields=["created"])
class Migration(migrations.Migration):
dependencies = [
("pretixbase", "0284_ordersyncresult_ordersyncqueue"),
]
operations = [
migrations.AddField(
model_name="voucher",
name="created",
field=models.DateTimeField(auto_now_add=True, null=True),
),
migrations.RunPython(
backfill_voucher_created,
migrations.RunPython.noop,
),
migrations.AlterField(
model_name="voucher",
name="created",
field=models.DateTimeField(auto_now_add=True),
),
]

View File

@@ -174,6 +174,9 @@ class Voucher(LoggedModel):
('percent', _('Reduce product price by (%)')), ('percent', _('Reduce product price by (%)')),
) )
created = models.DateTimeField(
auto_now_add=True,
)
event = models.ForeignKey( event = models.ForeignKey(
Event, Event,
on_delete=models.CASCADE, on_delete=models.CASCADE,

View File

@@ -91,6 +91,7 @@ def test_voucher_list(token_client, organizer, event, voucher, item, quota, sube
res = dict(TEST_VOUCHER_RES) res = dict(TEST_VOUCHER_RES)
res['item'] = item.pk res['item'] = item.pk
res['id'] = voucher.pk res['id'] = voucher.pk
res['created'] = voucher.created.isoformat().replace('+00:00', 'Z')
res['code'] = voucher.code res['code'] = voucher.code
q2 = copy.copy(quota) q2 = copy.copy(quota)
q2.pk = None q2.pk = None
@@ -264,6 +265,7 @@ def test_voucher_detail(token_client, organizer, event, voucher, item):
res['item'] = item.pk res['item'] = item.pk
res['id'] = voucher.pk res['id'] = voucher.pk
res['code'] = voucher.code res['code'] = voucher.code
res['created'] = voucher.created.isoformat().replace('+00:00', 'Z')
resp = token_client.get('/api/v1/organizers/{}/events/{}/vouchers/{}/'.format(organizer.slug, event.slug, resp = token_client.get('/api/v1/organizers/{}/events/{}/vouchers/{}/'.format(organizer.slug, event.slug,
voucher.pk)) voucher.pk))