Compare commits

...

4 Commits

Author SHA1 Message Date
Raphael Michel
b560c0e3a8 Update src/pretix/base/migrations/0285_voucher_created.py
Co-authored-by: luelista <weller@rami.io>
2025-08-08 15:57:04 +02:00
Raphael Michel
69fa883409 Update doc/api/resources/vouchers.rst
Co-authored-by: luelista <weller@rami.io>
2025-08-08 14:17:24 +02:00
Raphael Michel
bd9a4ba0ba Migration fix 2025-08-08 11:30:33 +02:00
Raphael Michel
991271a87c Voucher: Add creation date (Z#23202621) 2025-08-08 11:19:39 +02:00
5 changed files with 58 additions and 1 deletions

View File

@@ -14,6 +14,7 @@ The voucher resource contains the following public fields:
Field Type Description
===================================== ========================== =======================================================
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
max_usages integer The maximum number of times this voucher can be
redeemed (default: 1).
@@ -84,6 +85,7 @@ Endpoints
"results": [
{
"id": 1,
"created": "2020-09-18T14:17:40.971519Z",
"code": "43K6LKM37FBVR2YG",
"max_usages": 1,
"redeemed": 0,
@@ -156,6 +158,7 @@ Endpoints
{
"id": 1,
"created": "2020-09-18T14:17:40.971519Z",
"code": "43K6LKM37FBVR2YG",
"max_usages": 1,
"redeemed": 0,
@@ -228,6 +231,7 @@ Endpoints
{
"id": 1,
"created": "2020-09-18T14:17:40.971519Z",
"code": "43K6LKM37FBVR2YG",
"max_usages": 1,
"redeemed": 0,
@@ -321,6 +325,7 @@ Endpoints
[
{
"id": 1,
"created": "2020-09-18T14:17:40.971519Z",
"code": "43K6LKM37FBVR2YG",
}, …
@@ -367,6 +372,7 @@ Endpoints
{
"id": 1,
"created": "2020-09-18T14:17:40.971519Z",
"code": "43K6LKM37FBVR2YG",
"max_usages": 1,
"redeemed": 0,

View File

@@ -70,7 +70,7 @@ class VoucherSerializer(I18nAwareModelSerializer):
class Meta:
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',
'tag', 'comment', 'subevent', 'show_hidden_items', 'seat', 'all_addons_included',
'all_bundles_included', 'budget', 'budget_used')

View File

@@ -0,0 +1,46 @@
# 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 = None
for v in Voucher.objects.filter(created__isnull=True).iterator():
if not ct:
# "Lazy-loading" to prevent this to be executed on new DBs where the content type does not yet
# exist -- but also no vouchers do
ct = ContentType.objects.get(app_label='pretixbase', model='voucher')
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 (%)')),
)
created = models.DateTimeField(
auto_now_add=True,
)
event = models.ForeignKey(
Event,
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['item'] = item.pk
res['id'] = voucher.pk
res['created'] = voucher.created.isoformat().replace('+00:00', 'Z')
res['code'] = voucher.code
q2 = copy.copy(quota)
q2.pk = None
@@ -264,6 +265,7 @@ def test_voucher_detail(token_client, organizer, event, voucher, item):
res['item'] = item.pk
res['id'] = voucher.pk
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,
voucher.pk))