More changes

This commit is contained in:
Raphael Michel
2025-09-08 19:39:17 +02:00
parent dabdac6ff2
commit 1662c65b9b
4 changed files with 76 additions and 27 deletions

View File

@@ -666,6 +666,10 @@ class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer):
has_taxes = any(il.tax_value for il in self.invoice.lines.all()) or self.invoice.reverse_charge
header_dates = self._date_range_in_header()
tz = self.invoice.event.timezone
has_multiple_service_dates = len(set(
(il.period_start, il.period_end) for il in self.invoice.lines.all()
)) > 1
request_show_service_date = False
story = [
NextPageTemplate('FirstPage'),
@@ -741,7 +745,7 @@ class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer):
period_line = ""
else:
period_line = f"\n{date_format(day(period_start), 'SHORT_DATE_FORMAT')} {date_format(day(period_end), 'SHORT_DATE_FORMAT')}"
period_line = f"{date_format(day(period_start), 'SHORT_DATE_FORMAT')} {date_format(day(period_end), 'SHORT_DATE_FORMAT')}"
elif period_start or period_end:
# It's a single-day period
@@ -765,12 +769,17 @@ class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer):
period_line = ""
else:
period_line = f"\n{date_format(delivery_day, 'SHORT_DATE_FORMAT')}"
period_line = date_format(delivery_day, 'SHORT_DATE_FORMAT')
else:
# No period known
period_line = ""
description += period_line
if not has_multiple_service_dates and period_line:
# Group together at the end of the invoice
request_show_service_date = period_line
else:
description += "\n" + period_line
lines = list(lines)
if has_taxes:
if len(lines) > 1:
@@ -884,6 +893,12 @@ class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer):
story.append(Spacer(1, 10 * mm))
if request_show_service_date:
story.append(FontFallbackParagraph(
self._normalize(pgettext('invoice', 'Invoice period: {daterange}').format(daterange=request_show_service_date)),
self.stylesheet['Normal']
))
if self.invoice.payment_provider_text:
story.append(FontFallbackParagraph(
self._normalize(self.invoice.payment_provider_text),

View File

@@ -1,49 +1,60 @@
# Generated by Django 4.2.17 on 2025-09-08 08:14
from django.core.cache import cache
from django.db import migrations
def set_default_cardtypes(apps, schema_editor):
def set_invoice_period(apps, schema_editor):
EventSettingsStore = apps.get_model("pretixbase", "Event_SettingsStore")
ev_seen = set()
insert_queue = []
flush_queue = []
def store():
EventSettingsStore.objects.bulk_create(
insert_queue,
update_conflicts=True,
update_fields=["value"],
unique_fields=["object", "key"],
)
for f in flush_queue:
cache.delete(f)
flush_queue.clear()
insert_queue.clear()
# Existing events that use pretix-zugferd and have explicitly disabled delivery dates
for ev in EventSettingsStore.objects.filter(key="zugferd_include_delivery_date", value="False"):
for setting in EventSettingsStore.objects.filter(key="zugferd_include_delivery_date", value="False"):
flush_queue.append("hierarkey_{}_{}".format("event", setting.object_id))
insert_queue.append(
EventSettingsStore(
object_id=ev.object_id,
object_id=setting.object_id,
key="invoice_period",
value="invoice_date",
)
)
ev_seen.add(ev.object_id)
ev_seen.add(setting.object_id)
if len(insert_queue) > 1000:
EventSettingsStore.objects.bulk_create(insert_queue, ignore_conflicts=True)
insert_queue.clear()
store()
# Existing events that previously hid their date on invoices
# Ignore series as it doesn't make sense for them
for ev in EventSettingsStore.objects.filter(key="show_dates_on_frontpage", value="False",
object__has_subevents=False):
if ev.object_id in ev_seen:
for setting in EventSettingsStore.objects.filter(key="show_dates_on_frontpage", value="False"):
if setting.object_id in ev_seen:
continue
flush_queue.append("hierarkey_{}_{}".format("event", setting.object_id))
insert_queue.append(
EventSettingsStore(
object_id=ev.object_id,
object_id=setting.object_id,
key="invoice_period",
value="auto_no_event",
)
)
ev_seen.add(ev.object_id)
ev_seen.add(setting.object_id)
if len(insert_queue) > 1000:
EventSettingsStore.objects.bulk_create(insert_queue, ignore_conflicts=True)
insert_queue.clear()
store()
EventSettingsStore.objects.bulk_create(insert_queue, ignore_conflicts=True)
store()
class Migration(migrations.Migration):
@@ -62,4 +73,8 @@ class Migration(migrations.Migration):
old_name="event_date_from",
new_name="period_start",
),
migrations.RunPython(
set_invoice_period,
migrations.RunPython.noop,
)
]

View File

@@ -84,6 +84,7 @@ def build_invoice(invoice: Invoice) -> Invoice:
min_period_start = None
max_period_end = None
now_dt = now()
with (language(invoice.locale, invoice.event.settings.region)):
invoice.invoice_from = invoice.event.settings.get('invoice_address_from')
@@ -272,7 +273,7 @@ def build_invoice(invoice: Invoice) -> Invoice:
location=_location_oneliner(location)
)
period_start, period_end = _service_period_for_position(invoice, p)
period_start, period_end = _service_period_for_position(invoice, p, now_dt)
min_period_start = min(min_period_start or period_start, period_start)
max_period_end = min(max_period_end or period_end, period_end)
@@ -376,7 +377,7 @@ def build_cancellation(invoice: Invoice):
return invoice
def _service_period_for_position(invoice, position):
def _service_period_for_position(invoice, position, invoice_dt):
if invoice.event.settings.invoice_period in ("auto", "auto_no_event"):
if position.valid_from or position.valid_until:
period_start = position.valid_from or now()
@@ -384,12 +385,18 @@ def _service_period_for_position(invoice, position):
elif memberships := list(position.granted_memberships.all()):
period_start = min(m.date_start for m in memberships)
period_end = max(m.date_end for m in memberships)
elif invoice.event.has_subevents and position.subevent:
period_start = position.subevent.date_from
period_end = position.subevent.date_to
elif invoice.event.has_subevents:
if position.subevent:
period_start = position.subevent.date_from
period_end = position.subevent.date_to
else:
# Currently impossible case, but might not be in the future and never makes
# sense to use the event date here
period_start = invoice_dt
period_end = invoice_dt
elif invoice.event.settings.invoice_period == "auto_no_event":
period_start = now()
period_end = now()
period_start = invoice_dt
period_end = invoice_dt
else:
period_start = invoice.event.date_from
period_end = invoice.event.date_to
@@ -404,7 +411,7 @@ def _service_period_for_position(invoice, position):
period_start = invoice.event.date_from
period_end = invoice.event.date_to
elif invoice.event.settings.invoice_period == "invoice_date":
period_start = period_end = now()
period_start = period_end = invoice_dt
else:
raise ValueError(f"Invalid invoice period setting '{invoice.event.settings.invoice_period}'")

View File

@@ -16,6 +16,18 @@
{% bootstrap_field form.invoice_email_organizer layout="control" %}
{% bootstrap_field form.invoice_language layout="control" %}
{% bootstrap_field form.invoice_period layout="control" %}
{% if not request.event.settings.show_dates_on_frontpage %}
<div data-display-dependency="input[name=invoice_period][value=auto],input[name=invoice_period][value=event_date]">
<div class="alert alert-warning dynamic">
{% blocktrans trimmed %}
You configured that your shop is not an event and the event date should not be shown.
Therefore, we recommend that you set the date of service to a different option.
{% endblocktrans %}
</div>
</div>
{% endif %}
{% bootstrap_field form.invoice_include_free layout="control" %}
{% bootstrap_field form.invoice_show_payments layout="control" %}
{% bootstrap_field form.invoice_reissue_after_modify layout="control" %}