mirror of
https://github.com/pretix/pretix.git
synced 2026-05-18 17:24:03 +00:00
More changes
This commit is contained in:
@@ -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
|
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()
|
header_dates = self._date_range_in_header()
|
||||||
tz = self.invoice.event.timezone
|
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 = [
|
story = [
|
||||||
NextPageTemplate('FirstPage'),
|
NextPageTemplate('FirstPage'),
|
||||||
@@ -741,7 +745,7 @@ class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer):
|
|||||||
period_line = ""
|
period_line = ""
|
||||||
|
|
||||||
else:
|
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:
|
elif period_start or period_end:
|
||||||
# It's a single-day period
|
# It's a single-day period
|
||||||
@@ -765,12 +769,17 @@ class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer):
|
|||||||
period_line = ""
|
period_line = ""
|
||||||
|
|
||||||
else:
|
else:
|
||||||
period_line = f"\n{date_format(delivery_day, 'SHORT_DATE_FORMAT')}"
|
period_line = date_format(delivery_day, 'SHORT_DATE_FORMAT')
|
||||||
else:
|
else:
|
||||||
# No period known
|
# No period known
|
||||||
period_line = ""
|
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)
|
lines = list(lines)
|
||||||
if has_taxes:
|
if has_taxes:
|
||||||
if len(lines) > 1:
|
if len(lines) > 1:
|
||||||
@@ -884,6 +893,12 @@ class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer):
|
|||||||
|
|
||||||
story.append(Spacer(1, 10 * mm))
|
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:
|
if self.invoice.payment_provider_text:
|
||||||
story.append(FontFallbackParagraph(
|
story.append(FontFallbackParagraph(
|
||||||
self._normalize(self.invoice.payment_provider_text),
|
self._normalize(self.invoice.payment_provider_text),
|
||||||
|
|||||||
@@ -1,49 +1,60 @@
|
|||||||
# Generated by Django 4.2.17 on 2025-09-08 08:14
|
# Generated by Django 4.2.17 on 2025-09-08 08:14
|
||||||
|
from django.core.cache import cache
|
||||||
from django.db import migrations
|
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")
|
EventSettingsStore = apps.get_model("pretixbase", "Event_SettingsStore")
|
||||||
ev_seen = set()
|
ev_seen = set()
|
||||||
insert_queue = []
|
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
|
# 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(
|
insert_queue.append(
|
||||||
EventSettingsStore(
|
EventSettingsStore(
|
||||||
object_id=ev.object_id,
|
object_id=setting.object_id,
|
||||||
key="invoice_period",
|
key="invoice_period",
|
||||||
value="invoice_date",
|
value="invoice_date",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
ev_seen.add(ev.object_id)
|
ev_seen.add(setting.object_id)
|
||||||
|
|
||||||
if len(insert_queue) > 1000:
|
if len(insert_queue) > 1000:
|
||||||
EventSettingsStore.objects.bulk_create(insert_queue, ignore_conflicts=True)
|
store()
|
||||||
insert_queue.clear()
|
|
||||||
|
|
||||||
# Existing events that previously hid their date on invoices
|
# Existing events that previously hid their date on invoices
|
||||||
# Ignore series as it doesn't make sense for them
|
for setting in EventSettingsStore.objects.filter(key="show_dates_on_frontpage", value="False"):
|
||||||
for ev in EventSettingsStore.objects.filter(key="show_dates_on_frontpage", value="False",
|
if setting.object_id in ev_seen:
|
||||||
object__has_subevents=False):
|
|
||||||
if ev.object_id in ev_seen:
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
flush_queue.append("hierarkey_{}_{}".format("event", setting.object_id))
|
||||||
insert_queue.append(
|
insert_queue.append(
|
||||||
EventSettingsStore(
|
EventSettingsStore(
|
||||||
object_id=ev.object_id,
|
object_id=setting.object_id,
|
||||||
key="invoice_period",
|
key="invoice_period",
|
||||||
value="auto_no_event",
|
value="auto_no_event",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
ev_seen.add(ev.object_id)
|
ev_seen.add(setting.object_id)
|
||||||
|
|
||||||
if len(insert_queue) > 1000:
|
if len(insert_queue) > 1000:
|
||||||
EventSettingsStore.objects.bulk_create(insert_queue, ignore_conflicts=True)
|
store()
|
||||||
insert_queue.clear()
|
|
||||||
|
|
||||||
EventSettingsStore.objects.bulk_create(insert_queue, ignore_conflicts=True)
|
store()
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
@@ -62,4 +73,8 @@ class Migration(migrations.Migration):
|
|||||||
old_name="event_date_from",
|
old_name="event_date_from",
|
||||||
new_name="period_start",
|
new_name="period_start",
|
||||||
),
|
),
|
||||||
|
migrations.RunPython(
|
||||||
|
set_invoice_period,
|
||||||
|
migrations.RunPython.noop,
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ def build_invoice(invoice: Invoice) -> Invoice:
|
|||||||
|
|
||||||
min_period_start = None
|
min_period_start = None
|
||||||
max_period_end = None
|
max_period_end = None
|
||||||
|
now_dt = now()
|
||||||
|
|
||||||
with (language(invoice.locale, invoice.event.settings.region)):
|
with (language(invoice.locale, invoice.event.settings.region)):
|
||||||
invoice.invoice_from = invoice.event.settings.get('invoice_address_from')
|
invoice.invoice_from = invoice.event.settings.get('invoice_address_from')
|
||||||
@@ -272,7 +273,7 @@ def build_invoice(invoice: Invoice) -> Invoice:
|
|||||||
location=_location_oneliner(location)
|
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)
|
min_period_start = min(min_period_start or period_start, period_start)
|
||||||
max_period_end = min(max_period_end or period_end, period_end)
|
max_period_end = min(max_period_end or period_end, period_end)
|
||||||
|
|
||||||
@@ -376,7 +377,7 @@ def build_cancellation(invoice: Invoice):
|
|||||||
return 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 invoice.event.settings.invoice_period in ("auto", "auto_no_event"):
|
||||||
if position.valid_from or position.valid_until:
|
if position.valid_from or position.valid_until:
|
||||||
period_start = position.valid_from or now()
|
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()):
|
elif memberships := list(position.granted_memberships.all()):
|
||||||
period_start = min(m.date_start for m in memberships)
|
period_start = min(m.date_start for m in memberships)
|
||||||
period_end = max(m.date_end for m in memberships)
|
period_end = max(m.date_end for m in memberships)
|
||||||
elif invoice.event.has_subevents and position.subevent:
|
elif invoice.event.has_subevents:
|
||||||
period_start = position.subevent.date_from
|
if position.subevent:
|
||||||
period_end = position.subevent.date_to
|
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":
|
elif invoice.event.settings.invoice_period == "auto_no_event":
|
||||||
period_start = now()
|
period_start = invoice_dt
|
||||||
period_end = now()
|
period_end = invoice_dt
|
||||||
else:
|
else:
|
||||||
period_start = invoice.event.date_from
|
period_start = invoice.event.date_from
|
||||||
period_end = invoice.event.date_to
|
period_end = invoice.event.date_to
|
||||||
@@ -404,7 +411,7 @@ def _service_period_for_position(invoice, position):
|
|||||||
period_start = invoice.event.date_from
|
period_start = invoice.event.date_from
|
||||||
period_end = invoice.event.date_to
|
period_end = invoice.event.date_to
|
||||||
elif invoice.event.settings.invoice_period == "invoice_date":
|
elif invoice.event.settings.invoice_period == "invoice_date":
|
||||||
period_start = period_end = now()
|
period_start = period_end = invoice_dt
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Invalid invoice period setting '{invoice.event.settings.invoice_period}'")
|
raise ValueError(f"Invalid invoice period setting '{invoice.event.settings.invoice_period}'")
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,18 @@
|
|||||||
{% bootstrap_field form.invoice_email_organizer layout="control" %}
|
{% bootstrap_field form.invoice_email_organizer layout="control" %}
|
||||||
{% bootstrap_field form.invoice_language layout="control" %}
|
{% bootstrap_field form.invoice_language layout="control" %}
|
||||||
{% bootstrap_field form.invoice_period 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_include_free layout="control" %}
|
||||||
{% bootstrap_field form.invoice_show_payments layout="control" %}
|
{% bootstrap_field form.invoice_show_payments layout="control" %}
|
||||||
{% bootstrap_field form.invoice_reissue_after_modify layout="control" %}
|
{% bootstrap_field form.invoice_reissue_after_modify layout="control" %}
|
||||||
|
|||||||
Reference in New Issue
Block a user