* Fix sendmail/scheduled-mails placeholders
* Add event_or_subevent to context
* Add placeholders to tests
* fix and improve test
* Revert "fix and improve test"
This reverts commit 874a11e982.
* undo placeholder-tests
* add test
* New CheckoutSession model, created and deleted throught cart lifetime but only used for order-level question answers so far
* Order-level QuestionAnswers (relations to CheckoutSession / Order)
* New container_type field on Question model to specify whether Question belongs to order or orderposition
* Order-level questions are currently experimental, UI is hidden behind feature flag
---------
Co-authored-by: Richard Schreiber <schreiber@pretix.eu>
* Fix safari blocking widget opening error url in new tab (Z#23243124)
* Fix autofocus in vue3 widget
autofocus no longer works as the elements are added dynamically
* fix eslint
* rename v-focus to v-autofocus
---------
Co-authored-by: Richard Schreiber <schreiber@rami.io>
* move payment into pending on PENDING_REVIEW webhook
* mark approved payment as pending
* extend BasePaymentProvider to gate aborting pending payments on a payment per payment basis
* add timeout to paypal after which a pending payment can be canceled
* formatting
* add missing negation
* cleanup abort_pending_allowed methods
* Apply suggestions from code review
Co-authored-by: pajowu <pajowu@pajowu.de>
* check all capture elements
* rename method and change defaults
* remove left over Constant
* flake8 .
---------
Co-authored-by: pajowu <pajowu@pajowu.de>
* initial implementation
* factor out _resolve_base_date
* add js to prevent illegal inputs
* fix tests
* Update src/pretix/base/reldate.py
Co-authored-by: Raphael Michel <michel@pretix.eu>
* Apply suggestions from code review
Co-authored-by: Raphael Michel <mail@raphaelmichel.de>
* move js includes of to fragment_js.html
* add type annotations
* moves logic from RelativeDateWrapper into RelativeDate and adds BaseChoice for configuring which models attributes support which relationship
* fix tests
* test upgrade behaviour
* Apply suggestions from code review
Co-authored-by: Raphael Michel <mail@raphaelmichel.de>
* move reldate.js include in correct file
* add OptionAttrsSelect to allow select options with their own attributes per value
* add a little bit of information to the tests for future reference
* rewrite reldate.js use data-attributes
* general cleanup
* add test for order.subevents cases
* use correct choice format
* remove order.subevent variants
* various cleanup
* Apply suggestions from code review
Co-authored-by: Raphael Michel <mail@raphaelmichel.de>
* remove empty docstrings
* add depreciation warning
* change event listener to pretix:bind-forms
---------
Co-authored-by: Raphael Michel <michel@pretix.eu>
Co-authored-by: Raphael Michel <mail@raphaelmichel.de>
* store the state of the payment regardless of the state
control.html shows the banner that the payment is in review depending on payment.info
* handle capture ressource
* Update src/pretix/plugins/paypal2/views.py
Co-authored-by: Phin Wolkwitz <wolkwitz@pretix.eu>
* add test
* cleanup logic regarding uninteresting resource_type
* store payment.info during _execute_payment asap
---------
Co-authored-by: Phin Wolkwitz <wolkwitz@pretix.eu>
All of our API endpoints that do something in the system do at least two
SQL queries, one for the actual change and one for the log entry. Often
many more. We want all of this to happen in a transaction so we know an
API call was executed or not at all, not half-way.
* rders: Fix N+1 query issues on order detail and change page
There is one I couldn't fix: Loading the list of tax rules for every
select box on the OrderChange page. Unfortunately, Django has a
cache-breaking .all() in ModelChoiceField and that would need nasty
patching that didn't feel worth it
* Fix isort
* Fix N+1 query in gate call
* Fix leftovers
* Add local cache for objects referenced in log entries
* Update src/pretix/control/views/orders.py
* Event-dashboard: Lazy-load warnings
I don't like this, it's not pretty, but we have no quick way of fixing
the overpaid orders check otherwise and a slow query on the event
dashboard feels really bad, because even if you don't wanna see the
dashboard ou are always going through it in navigation and that can get
very annoying very quickly.
* Update src/pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
Co-authored-by: pajowu <engelhardt@pretix.eu>
---------
Co-authored-by: pajowu <engelhardt@pretix.eu>
After enforcing this on application level in commit 4c37351, we can now also add
a unique constraint on DB level and a migration to fix any left over non-unique entries.
---------
Co-authored-by: Raphael Michel <mail@raphaelmichel.de>
This changes the API of pretix.control.signals.event_dashboard_widgets and
pretix.control.signals.user_dashboard_widgets, such that the "content" key of
returned dictionaries must contain a SafeString if HTML therein is to be
rendered.
* Fix crash in rebooking if addon has hidden_if_item_available
* Move get_grouped_items into its own file and rename to prepare_item_list_for_shop
(but keep a reference under original name for plugin compatibility)
* Make Item[Variation].unavailability_reason helper functions next to get_grouped_items
* Use current_unavailability_reason attribute instead of unavailability_reason()
* Add test case for:
Order has product with addon 1; Addon 1 is hidden if Addon 2 is available; When order is changed, Addon 1 should not be removable
* Fix special case if addon product is now set to require a voucher (vouchers for addons are not supported)
---------
Co-authored-by: Kara Engelhardt <engelhardt@pretix.eu>
* Add proper CSP policy for HTML email preview
* Handle safe types centrally
* Precompile schema validation function to get rid of ajv2020
* Fix tests
* adjust more tests
* Fix customer views using wrong csrf middleware
This lead to persistent csrf validation errors if the token from the cookie expired, which could only be solved by clearing cookies.
* Remove unneccesary csrf_protect decorators
* Fix typo
Co-authored-by: Raphael Michel <michel@pretix.eu>
---------
Co-authored-by: Raphael Michel <michel@pretix.eu>
As a security precaution, we change the contract of some signals such that a
SafeString needs to be returned if HTML should be rendered without further
escaping.
Before, the `{% signal ... %}` and `{% eventsignal ... %}` template tags
called mark_safe themselves on all strings returned from signals. That could
lead to unsafe coding practices, where untrusted values are interpolated into
HTML format strings. However, such interpolations should usually be performed
using helpers such Django's format_html, which automatically escapes inputs
and returns a SafeString.
Now, we call conditional_escape on signal results, so that any HTML not explicitly
marked as safe gets escaped.
Most plugins are not affected by this change as they return a SafeString as a
result of Template.render already.
* Drop nullability on Order.organizer and OrderPosition.organizer
* Rebase migration and add autoclean
* Utilize new relationship for scopes
* Declare reverse noop
* Update src/pretix/base/migrations/0302_resolve_duplicate_codes_and_secrets.py
Co-authored-by: Martin Gross <gross@rami.io>
* Update src/pretix/base/migrations/0302_resolve_duplicate_codes_and_secrets.py
Co-authored-by: Martin Gross <gross@rami.io>
---------
Co-authored-by: Martin Gross <gross@rami.io>
* Add trace IDs from request to celery task
Celery tasks will log the request ID they were triggered from:
[2026-07-02 10:33:17,614: INFO/MainProcess] Task pretix.base.services.orders.cancel_order[5f3104b3-0a54-4e49-921e-c866c4dc4c6d] received
[2026-07-02 10:33:17,614: INFO/MainProcess] Task 5f3104b3-0a54-4e49-921e-c866c4dc4c6d has trace 4d389638-00ab-4c4d-bdec-d73ac322bf44
Nested celery tasks will then contain both the request ID as well as the previous tasks:
[2026-07-02 10:33:18,354: INFO/MainProcess] Task pretix.base.services.notifications.notify[d52a3a49-9c89-4f67-bdde-9f773586fc07] received
[2026-07-02 10:33:18,354: INFO/MainProcess] Task d52a3a49-9c89-4f67-bdde-9f773586fc07 has trace 4d389638-00ab-4c4d-bdec-d73ac322bf44 5f3104b3-0a54-4e49-921e-c866c4dc4c6d
* Apply suggestion from @luelista
Co-authored-by: luelista <weller@rami.io>
---------
Co-authored-by: luelista <weller@rami.io>
This is a follow-up for #6318, basically the same problem but in a
neighboring query.
Performance comparison for real-world event with 13k subevents:
In [15]: %time get_grouped_items(e, subevent=se, channel=e.organizer.sales_channels.get(identifier="web"))
CPU times: user 49.1 ms, sys: 3.79 ms, total: 52.9 ms
Wall time: 1.12 s
Out[15]: ([<Item: xxx>], True
In [16]: %time get_grouped_items_patched(e, subevent=se, channel=e.organizer.sales_channels.get(identifier="web"))
CPU times: user 30.2 ms, sys: 445 μs, total: 30.6 ms
Wall time: 45.3 ms
Out[16]: ([<Item: xxx>], True)
During our [2026-06-27 incident](https://pretix.eu/about/en/blog/20260630-pretix-hosted-outage/),
we noticed that pretix is using redis at import time. This means that
gunicorn and celery process were unable to start on servers who could
currently not reach redis. This is kinda mitigated through auto-restart
on systemd or docker level, but that's not really how it is supposed to
work. Celery even has smart retry/reconnect logic that becomes pointless
this way.
* Improve subject lines for admin-facing emails
A few of the current subjects are ambiguous about the expected
action, and some omit context that would help in an inbox preview
(which event, which address). The rewrites bring them closer to
common conventions in modern transactional email (verb-led,
recipient-addressed, with recipient-meaningful variables). Two
themes:
- Action-required emails lead with the action verb. "Reset your
password", "Confirm event cancellation and bulk refund", and
"Confirm <address> as a sender address" tell the recipient up
front what's expected, where "Password recovery", "Bulk-refund
confirmation" and "Sender address verification" did not.
- Surface the relevant variable when the email is about something
specific. "Data shredding completed for <event>" is more useful
than the generic version when an admin manages several events.
"You've been invited to join <organizer>" names the inviting
organizer. "Confirm <address> as a sender address" names the
address.
The remaining rewrites are lighter rewordings. "New sign-in to
your account" replaces "Login from new source detected" because
"source" is jargon a non-technical recipient wouldn't recognise.
"Changes to your account" replaces "Account information changed"
because the possessive frames the email as being about the
recipient's own account.
Also fixes a hardcoded "pretix" in the confirmation-code subject.
* Standardise admin email sign-offs as "Thanks, The <instance> Team"
The current sign-offs ("Best regards, Your <instance> team") have
a formal tone. A review of the last ~20 transactional emails in
my inbox showed most senders use something friendlier:
- Thanks: Deliveroo, Starling Bank, GitHub, Cloudflare
- Thank you: AWS
- Sincerely: Google Workspace
A small minority (e.g., Sentry) had no sign-off at all. "Thanks"
was the most common, and among that group "The <instance> Team"
was the consistent phrasing rather than "Your <instance> team".
Two templates (cancel_confirm, export_failed) didn't have a
sign-off; they now get one for consistency. Notification emails
are deliberately excluded: they're system alerts rather than
direct correspondence.
* Add anti-phishing notice to admin emails containing confirmation codes
Three admin emails send the recipient a confirmation code to
enter back into a form: confirmation_code, email_setup, and
cancel_confirm. Only confirmation_code had an anti-phishing
warning, and its wording was awkward ("Please do never give this
code to another person. Our support team will never ask for this
code.").
This commit standardises the warning across all three:
> Don't share this code with anyone. The <instance> team will
> never ask you for it.
* Add structured details to login-notice email
The single-sentence body ("The login was performed using <agent>
on <os> from <country>.") is replaced with a labelled bullet list:
Time, Browser, Operating system, Device, Country.
Time and Device are new fields. Device is omitted when ua-parser
can't identify the device, Country when GeoIP isn't available,
so the user only sees fields with real values.
* Restructure notification.txt for clearer layout
- Attributes: bullet list instead of paragraph-per-attribute.
- Actions: label gets a colon, URL on its own paragraph (was
4-space-indented code block).
- Footer: separated by --- and bulleted (manage / disable
links). "Click here X" phrasing dropped (incidentally moots
a missing-"to" typo).
- Minor whitespace fix: detail-block endif now matches the
placement of the rest of the template.
notification.html's footer text is also updated, only to match
the new .txt wording (link labels and intro line). No
structural changes to the HTML template.
* Improve confirmation-code email reason strings
- Drop the redundant "to confirm" opener.
- Replace hardcoded "your pretix account" in email_verify
with "{instance}".
* Polish admin email body copy
A small wording and formatting pass on the admin email bodies,
in three loosely-grouped themes:
1. Sentence case for body text (previously lowercase after
"Hello,"), matching standard English convention.
2. Light restructuring where helpful: bullet lists for sets
of labelled facts; 4-space-indented code blocks for codes
the recipient is meant to type back.
3. Phrasing polish. Some sentences tightened or shortened.
Largely matters of taste, but generally read smoother.
---------
Co-authored-by: Raphael Michel <michel@pretix.eu>
* Add event placeholder support to more fields
I found it useful to be able to use the `{event}` placeholder in
some fields such as the "End of presale text" because I don't need
to fix the texts creating a new event by cloning another event.
I made placeholders available to the other fields as well (where not too
difficult). Specifically `presale_has_ended_text`, `voucher_explanation_text`
`banner_text`, `banner_text_bottom` and `event_info_text`.
In addition, I grouped them under a new `texts` variable in the `context`
(including `frontpage_text` which was part of the root `context` previously).
* change compute location
---------
Co-authored-by: Raphael Michel <michel@rami.io>
* Improve SSO one-time token error message
Replace the generic 'invalid one-time token' message shown after failed
SSO login attempts with a clearer, user-facing explanation of what went
wrong and how to recover.
* Remove unneeded classes from headings
Co-authored-by: Raphael Michel <mail@raphaelmichel.de>
* Apply suggestions from code review
Added `trimmed` to translation blocks
Co-authored-by: Raphael Michel <mail@raphaelmichel.de>
* Reword SSO error template for improved translation clarity
---------
Co-authored-by: Raphael Michel <mail@raphaelmichel.de>
* Add Docker secrets support in config
* ruff format
* Remove gracefully fallback exception handling
* Add support for loading secret fallbacks from environment file
* Fix EPC QR beneficiary escaping
* Fix EPC QR script encoding
Keep EPC QR helper output as a plain string and serialize payment QR payloads as JSON script data before the QR replacement JavaScript parses them. This preserves apostrophes without relying on mark_safe in the helper.
Assisted-by: OpenAI GPT-5 <noreply@openai.com>
* "type safety"
---------
Co-authored-by: Puneet Dixit <236133619+puneetdixit200@users.noreply.github.com>
Co-authored-by: Raphael Michel <michel@rami.io>
* use cookieretry only on presale event pages
* use csrfcookieretry only on event index page
* include static tag
* include csrfcookieretry in order.html as well
* Update src/pretix/static/pretixpresale/js/csrfcookieretry.js
Co-authored-by: Richard Schreiber <schreiber@pretix.eu>
---------
Co-authored-by: Richard Schreiber <schreiber@pretix.eu>
We initially didn't do this for two reasons:
- Performance implications of calling the settings store for every event
that shows up in the calendar. As of d43e85da, we need that anyways.
- Performance implications of filtering in Python except SQL but... it
can't really be worse than not filtering at all.
- We don't easily know if it's valid for all events so we can't stop
rendering the unused calendar rows. That's an acceptable issue for
now, still better than nothing. We can always optimize later.
So we might as well implement it.
Knowing what file a string comes from is useful, but the line number is less
useful and changes a lot, causing very unreadable diffs of translation
files. I propose we drop them and only include the file names
- Add central framebreaker page via safelink helper
- Update paypal, paypal2 and stripe plugins to use central framebreaker
- Add CSP header to cookies.html
---------
Co-authored-by: Mira Weller <weller@pretix.eu>
* Check for duplicate codes in import
* Check for existing codes instead of failing on db-level
* as we do not lock, catch IntegrityErrors due to race-conditions on import
* fix flake8
* Fix handling country=None in AttendeeProfile describe
* Update checkoutflow.py
* fix more occurences
* handle country=None in InvoiceAddress even if it is not allowed
* SSRF protection: Edge case handling for CGNAT and v4/v6 mapping (Z#23236468)
* SMTP SSRF protection: Edge case handling for CGNAT and v4/v6 mapping (#6264)
---------
Co-authored-by: pajowu <engelhardt@pretix.eu>
* load errors.js as standard and make it coop with async_task_replace_page
* scope down event
* Update src/pretix/static/pretixbase/js/asynctask.js
Co-authored-by: pajowu <engelhardt@pretix.eu>
* drop the jquery dependency for error.js
Co-authored-by: pajowu <pajowu@pajowu.de>
* include errors.js in error.html
* include errors.js in control base.html
* Update src/pretix/static/pretixbase/js/asynctask.js
Co-authored-by: Richard Schreiber <schreiber@pretix.eu>
* put errors.js in an IIFE call
---------
Co-authored-by: pajowu <engelhardt@pretix.eu>
Co-authored-by: pajowu <pajowu@pajowu.de>
Co-authored-by: Richard Schreiber <schreiber@pretix.eu>
* Accounting report: Correctly split subevents with same label (Z#23237301)
* Accountingreport: Fix crash for single events
---------
Co-authored-by: Kara Engelhardt <engelhardt@pretix.eu>
For wheel the setuptools documentation notes:
> Historically this documentation has unnecessarily listed wheel in
> the requires list, and many projects still do that. This is not
> recommended, as the backend no longer requires the wheel package,
> and listing it explicitly causes it to be unnecessarily required for
> source distribution builds.
https://setuptools.pypa.io/en/latest/userguide/quickstart.html#basic-use
For setuptools-rust I could not find any Rust extension that need to be
built. The introduction goes back to c132ccd14, where css-inline, a rust
component, was added as a dependency.
* Teams: Add a note to the degree of isolation between permissions
* Update src/pretix/control/templates/pretixcontrol/organizers/team_edit.html
Co-authored-by: pajowu <engelhardt@pretix.eu>
---------
Co-authored-by: pajowu <engelhardt@pretix.eu>
* Add Reusable Media Exchange to Checkin API
* isort
* Remove debugging leftover
* Apply suggestions from code review
Co-authored-by: robbi5 <maxi@richt.name>
* Add media_exchange_supported to CheckinRPCRedeemInputSerializer
* SecurityProfiles: Add api-v1:reusablemedia-lookup and -detail for SCAN
* Simplify media exchange checks
* Apply suggestions from code review
Co-authored-by: Raphael Michel <mail@raphaelmichel.de>
* Wording: re-usable --> reusable
* Deny checkins if media-exchange is required but device does not support it.
* Remove media_exchange_supported-Flag: Checkin will always be denied if media needs to be exchanged; apps will fall back to explanation text
* CheckinRPC: Also perform media exchange
* Use media_policy from item, not as a checkinrpc parameter
* my own review notes
* Fixes, cleanup, rebase
* block expired media
* Fix query
* add logging
* Refactor link_action into media policy, gift card support
* Block illegal policy-type combination
* Drop add_to_reusable_medium, decide all by policy
* Fix test failure
* fix test on postgres
* Expose reusable_media_usage_enforced to devies
* Explicitly set update view
---------
Co-authored-by: robbi5 <maxi@richt.name>
Co-authored-by: Maximilian Richt <richt@pretix.eu>
Co-authored-by: Raphael Michel <mail@raphaelmichel.de>
Co-authored-by: Raphael Michel <michel@rami.io>
Co-authored-by: Raphael Michel <michel@pretix.eu>
* change linked orderpositions to many-to-many
* Update media views to list ops
* return last op as fallback for linked_orderposition
* add multi-op to export
* update media-API
* fix media-view filter
* update control media forms
* fix API orders
* fix API orders matching media
* remove cached_property linked_orderposition - keep only in API
* fix media-issue signal
* adapt checkin API for multiple orderpositions
* remove unneeded comment
* fix create/update logging
* fix tests
* fix more tests
* fix code style
* add label to reusablemedium
* fix migration NOT NULL
* fix tests
* update docs
* clarify docs updating multiple linked_orderpositions
* clarify docs
* no need to prefetch linked_orderpositions
* improve readability
* select_related order instead prefetch
* add filter based on op.valid_from/until
* rename secret to claim_token
* Update docs for claim_token
* unifiy deprecated style
* Update reusablemedia.rst
* Update reusablemedia.rst
* Update reusablemedia.rst
* fix missing claim_token in serializer
* fix flake8
* add add_to_reusable_medium to order-serializer
* fix tests regarding claim_token
* fix flake8
* Clarify docs
* list ops comma-separated in export
* Add test for order-API add_to_reusable_medium
* fix linked_orderpositions filter in checkinrpc
* add test
* Add help-text
* fix multi-op media filter
* fix flake8
* improve check
* Fix sorting of reusable media type in overview
* Add copy and qr button to reusable medium detail view
* Rebase against origin/master
* Add logentrytype reusable_medium.linked_orderposition.removed
* add missing label_from_instance for SafeOrderPositionMultipleChoiceField
* add tests for create with linked_orderposition
* API add test for fallback-values in medium patch
* fix flake8
* Fix indentation
* fix migrations numbering
* fix test
* unify qutation marks
* fix flake8
* micro-improve linked_op-removal-logging
* simplify filter instead of annotate/get
* Do not translate API-errors
Co-authored-by: Raphael Michel <michel@pretix.eu>
* Fix typos in doc
Co-authored-by: Raphael Michel <mail@raphaelmichel.de>
* Update versionchanged in docs
Co-authored-by: Raphael Michel <michel@pretix.eu>
* Change log to always added not changed
* Add test for checkinrpc for ops out of timerang or canceled
* improve tests mixing ops from different organizers
* Fix logging of changed order_positions
* properly log added/removed when using UI
* refactor logging code
* unify logging adding/removing ops via API
* fix flake8
* remove unnecessary prefetch as already prefetched
* optimize fetching ops
* combine addon match and time-based validity match
* fix combined valid and product check
* re-number migrations
* Apply suggestion from @raphaelm
Co-authored-by: Raphael Michel <michel@pretix.eu>
* fix flake8
* New attempt at logic
* Improve op_candidate-selection for error message if no op matches check-in
* Fix typo
* fix valid_from start time being included
* use the datetime parameter for the comparison time so that the simulator works too
---------
Co-authored-by: Maximilian Richt <richt@pretix.eu>
Co-authored-by: Martin Gross <gross@rami.io>
Co-authored-by: Raphael Michel <michel@pretix.eu>
Co-authored-by: Raphael Michel <mail@raphaelmichel.de>
* Add optional filters for organizer and event-permission on event-typeahead
* include _none option only if no search query given
Co-authored-by: luelista <weller@rami.io>
* allow _none in Select2, add ModelChoiceFieldWithNone
* fix flake8
---------
Co-authored-by: luelista <weller@rami.io>
Due to a Safari bug, in some browser, two csrftoken cookies with different values
exist: one unpartitioned, one partitioned ("CHIPS"). This function generates an
additional Set-Cookie header to get rid of the unpartitioned one.
As Django usually only allows one Set-Cookie header per cookie name, we
need to manually create a cookie 'Morsel' for the deletion and store it
in the HttpResponse's cookie dictionary under a different name, so it is
not overwritten by the actual, correct Set-Cookie header. This works
because the code in django.core.handlers.wsgi/asgi, that generates the
actual Set-Cookie headers, only iterates over cookie.values(), ignoring
the keys.
* Force async_task_is_download to be downloaded if in iframe (Z#23234427)
* Update src/pretix/static/pretixbase/js/asynctask.js
Co-authored-by: luelista <weller@rami.io>
---------
Co-authored-by: luelista <weller@rami.io>
* Improve error messages for name-parts inputs (Z#23234440)
* fix isort after flake8
* correct spelling of .med in user-provided title/name
* fix search instead of match
* setup vite and integrate fully with django
- vite starts with `python manage.py runserver`
- add templatetags to simply load vite hmr and entry points
- add eslint (recheck rules)
- enable non-strict ts
* better syntax for cors header setting
* migrate checkin rules editor to vue3
- move constants to a module
- move reading from and writing to non-vue html to django interop module
- switch to composition api and script setup sfc with pug
- use optional chaining operators a lot to simplify code
* migrate webcheckin plugin to vite+vue3
- migrate vue sfcs to script setup and pug
- move fetch calls into a api.ts module
- move common formatting and i18n strings into module
* fix migration error
* first draft migrating widget to vue3/vite
* first couple widget e2e tests
courtesy of claude
most of the tests don't work yet
* test file is not actually used
* drop widget_ prefix from e2e test fixtures
* add test for complete widget journey for simple event
* switch timezone in e2e tests to Europe/Berlin
* make dates in e2e tests relative
* migrate widget bugfix #5886
* start testing event series widget
* working vite widget setup for prod (untested), local dev (with or without dev server) and pytests, with flags for running the old version or the vite version
* simplify e2e test iframe check
* less flaky e2e tests
* top level await in iife build mode is not supported, so let's do import.meta.glob instead (we just need the build step not to see await, the code doesn't actually ever get loaded because it's DEV only)
* fix inconsistencies from automatic migration
* Allow gradual rollout of new vite-based widget by adding urls to an allowlist that gets checked against the "Origin" http header of request fetching the widget js
* add e2e tests for widget button, testing empty cart, adding specific items, and subevents
* remove janky claude testts again
* resolve migration TODOs: properly refocus parent on navigations
* use `npm run dev:control` for the vite dev server for admin components
* upgrade npm dependencies
* fix js linter errors
* fix python linter errors
* build all control vue components
* add new js config files to check-manifest ignore
* working prod build
acutal serving of built assets not tested yet
* fix templatetag paths to match what's in the vite mantifest
* add missing quotes around 'unsafe-eval' cors value
* remove now unused old vue2 tooling
* try fixing e2e test ci
* fix flake8 error
* check if vite build artefacts are in the wheel
* add license headers
* remove dom manipilation code necessary for `div.pretix-widget-compat` to work. No longer needed for vue3
* remove superfluous `createElement` calls
They might have been there because of IE, which is no longer relevant
* make widget dev mode parametizable through query params and document the usage and those params
* fix rst syntax
* remove migration todos file
Co-authored-by: luelista <mira@teamwiki.de>
* rearrange dockerfile commands for smaller image, thanks @luelista
* Update .gitignore, adding .vite
Co-authored-by: luelista <mira@teamwiki.de>
* add eslint CI
* make vue dev work in plugins
* fix docker build
* rebuild vite setup to support static prod plugins and dynamic hmr plugin development
* use toml for vite plugin config instead of standalone json file
* Add widget changes from #6047, #6149
* Allow buttons to reuse cart (Z#23226853)
* Always keep cart of buttons with items set
* widget: handle cart if not same-site (#6149)
---------
Co-authored-by: luelista <mira@teamwiki.de>
Co-authored-by: Kara Engelhardt <engelhardt@pretix.eu>
Sets SameSite for cookie if page is secure, so cookie can be read even if not same-site. Also stores cart-id in vue state, so correct cart is used even if cookies to not work
The old code relied on the `Voucher.redeemed` value obtained *before*
the lock was taken, not afterwards.
The change in services/orders.py is functionally pointless, but it makes
the pattern of "fill availability only after lock" clearer and might
avoid introducing similar bugs in the future.
* Turn attendee emails on by default for new events (Z#23213656)
I think the thing that makes me most unhappy is that *most* organizers will
probably want to turn off mail_send_order_paid_attendee when they set
ticket_download_pending and I don't think organizers will remember that, but
it also seems complex and weird to create an automatism for it?
* Update src/pretix/base/models/event.py
Co-authored-by: Martin Gross <gross@rami.io>
---------
Co-authored-by: Martin Gross <gross@rami.io>
* Subevents: Allow to skip conflicting dates in bulk-creation
* Update src/pretix/control/templates/pretixcontrol/subevents/bulk.html
* Fix overlap calc for consecutive subevents
* Add test for skipping conflicting dates in bulk-creation
---------
Co-authored-by: Richard Schreiber <schreiber@pretix.eu>
Co-authored-by: Richard Schreiber <schreiber@rami.io>
Co-authored-by: Kara Engelhardt <engelhardt@pretix.eu>
* Display invoice and tickets inline in browser (Z#23225892)
* Use FileResponse filename for AnswerDownload
* Use inline for PDF-view in pretix-control editor
* use as_attachment for API FileResponses
* do not ignore csp even for disposition=inline
* use as_attachment for file responses in control
* remove unused code
* improve code style
* Invoice preview inline
* do not force download on tickets in backend
* do not force download on AnswerDownload
* imrpove code style
* improve code style
* fix missing int str conversion
* Apply suggestions from code review
Co-authored-by: luelista <mira@teamwiki.de>
---------
Co-authored-by: luelista <mira@teamwiki.de>
* Group waiting list product choices by category
Use optgroups to group products by category in the waiting list selection
dropdown.
Products are normally separated in the UI by category grouping, but this
context is lost in the waiting list form. When multiple products share the
same name, this can make it difficult for customers to distinguish between
them.
* Add tests for waiting list initial selection with optgroups
Verify that the initial product selection (via `?item=` and `?var=`
query parameters) works correctly when choices are grouped by category
into `<optgroup>`s. Covers both plain items and items with variations.
A non-empty string is truthy, making the the for-loop useless, as the first item in inspect.stack() is always the for-loop itself, which then lead to the function returning immediately.
This commit
* fixes this typo
* changes the loop to ignore the first element of instpect.stack() (which is the loop itself)
* ignores django-internal code
This should create something similar to what I suspect the code was intended to do originally.
* Do not create useless cart session accessing invoice address
* Skip useless code paths in CartMixin
* Do not create cart session on view with active session
* Create regression tests
for pat in 'static.dist/vite/widget/widget.js' 'static.dist/vite/control/assets/checkinrules/main-' 'static.dist/vite/control/assets/webcheckin/main-'; do
Welcome to pretix, we are happy that you would like to contribute.
Before you do so, please make sure to read the following documents:
* We've got a contributors guide in [our documentation](https://docs.pretix.eu/dev/development/contribution/) together with notes on the [development setup](https://docs.pretix.eu/dev/development/setup.html).
- [Code of Conduct](https://docs.pretix.eu/dev/development/contribution/codeofconduct.html)
* Please note that we have a [Code of Conduct](https://docs.pretix.eu/dev/development/contribution/codeofconduct.html) in place that applies to all project contributions, including issues, pull requests, etc.
* Before we can accept a PR from you we'll need you to sign [our CLA](https://pretix.eu/about/en/cla). You can find more information about the how and why in our [License FAQ](https://docs.pretix.eu/trust/licensing/faq/) and in our [license change blog post](https://pretix.eu/about/en/blog/20210412-license/).
Before we can accept your first PR we'll need you to sign [our **Contributor License Agreement** (CLA)](https://pretix.eu/about/en/cla).
You can find more information about the how and why in our [License FAQ](https://docs.pretix.eu/trust/licensing/faq/) and in our [license change blog post](https://pretix.eu/about/en/blog/20210412-license/).
**Before contributing new functionality, always open a discussion first.**
Triggers generation of new ``secret`` and ``web_secret`` attributes for both the order and all order positions.
Ticket secrets of order positions that have been used to issue a gift card can not
be changed. Only the link (``web_secret``) will be changed in this case.
**Example request**:
..sourcecode::http
@@ -895,6 +898,9 @@ Generating new secrets
Triggers generation of a new ``secret`` and ``web_secret`` attribute for a single order position.
Ticket secrets of order positions that have been used to issue a gift card can not
be changed. Only the link (``web_secret``) will be changed in this case.
**Example request**:
..sourcecode::http
@@ -1069,7 +1075,7 @@ Creating orders
*``valid_from`` (optional, if both ``valid_from`` and ``valid_until`` are **missing** (not ``null``) the availability will be computed from the given product)
*``valid_until`` (optional, if both ``valid_from`` and ``valid_until`` are **missing** (not ``null``) the availability will be computed from the given product)
*``requested_valid_from`` (optional, can be set **instead** of ``valid_from`` and ``valid_until`` to signal a user choice for the start time that may or may not be respected)
*``use_reusable_medium`` (optional, causes the new ticket to take over the given reusable medium, identified by its ID)
*``use_reusable_medium`` (optional, causes the new ticket to be connected to the given reusable medium, identified by its ID)
*``discount`` (optional, only possible if ``price`` is set; attention: if this is set to not-``null`` on any position, automatic calculation of discounts will not run)
*``order`` (mandatory, specified as a string mapping to a ``code``)
*``addon_to`` (optional, specified as an integer mapping to the ``positionid`` of the parent position)
*``addon_to`` (optional, specified as an integer mapping to ``positionid`` - the number of the position within the order, see :ref:`_order-position-resource` - of the parent position)
*``item`` (mandatory)
@@ -2342,7 +2348,7 @@ otherwise, such as splitting an order or changing fees.
Every discussion, issue, and pull request is read and reviewed by humans (and sometimes machines, too).
We ask you to respect the time and effort put in by these humans by not sending low-effort, unqualified work, since it puts the burden of validation on the maintainer.
Therefore, the pretix project has strict rules for AI usage:
-**All AI usage in any form must be disclosed.** You must state the tool you used (e.g. Claude Code, Cursor, Amp) along with the extent that the work was AI-assisted.
-**The human-in-the-loop must fully understand all code.** If you can't explain what your changes do and how they interact with the greater system without the aid of AI tools, do not contribute to this project.
-**Issues and discussions can use AI assistance but must have a full human-in-the-loop.** This means that any content generated with AI must have been reviewed and edited by a human before submission. AI is very good at being overly verbose and including noise that distracts from the main point. Humans must do their research and trim this down.
-**No AI-generated media is allowed (art, images, videos, audio, etc.).** Text and code are the only acceptable AI-generated content, per the other rules in this policy.
-**Bad AI drivers will be excluded from the project.** People who produce bad contributions that are clearly AI (slop) will be blocked from our organization without warning.
This policy was inspired by the `ghostty project`_.
You are interested in contributing to pretix? That is awesome!
If you’re new to contributing to open source software, don’t be afraid. We’ll happily review your code and give you
constructive and friendly feedback on your changes.
constructive and friendly feedback on your changes. Every contribution should go through the following steps.
First of all, you'll need pretix running locally on your machine. Head over to :ref:`devsetup` to learn how to do this.
Discussion & Design
-------------------
pretix is a large and mature project with more of a decade of history and hopefully many more decades to come.
Keeping pretix in good shape over long timeframes is first and foremost a fight against complexity.
With every additional feature, complexity grows, and both features and complexity are hard to remove.
Even if you are doing the initial work of the contribution, accepting the contribution is not free for us.
Not only will we need to maintain the feature, but every feature adds cost to the maintenance of every other feature it interacts with, and every feature adds effort for users to understand how pretix works.
Therefore, we must carefully select what features we add, based on how well they fit the system in general and of how much use they will be to our larger user base.
We strongly ask you to **create a discussion on GitHub for every new feature idea** outlining the use case and the proposed implementation design.
Pull requests without prior discussion will likely just be closed.
For bug fixes and very minor changes, you can skip this step and open a PR right away.
Development
-----------
To develop your contribution, you'll need pretix running locally on your machine. Head over to :ref:`devsetup` to learn how to do this.
If you run into any problems on your way, please do not hesitate to ask us anytime!
Please note that we bound ourselves to a :ref:`coc` that applies to all communication around the project. You can be
assured that we will not tolerate any form of harassment.
While developing, please have a look at our :ref:`aipolicy` and our guidelines on :ref:`codestyle`.
Sending a patch
---------------
If you improved pretix in any way, we'd be very happy if you contribute it
back to the main code base! The easiest way to do so is to `create a pull request`_
on our `GitHub repository`_.
Once you have a first draft of your changes, please `create a pull request`_ on our `GitHub repository`_.
We recommend that you create a feature branch for every issue you work on so the changes can
be reviewed individually.
@@ -25,14 +41,17 @@ Please use the test suite to check whether your changes break any existing featu
the code style checks to confirm you are consistent with pretix's coding style. You'll
find instructions on this in the :ref:`checksandtests` section of the development setup guide.
We automatically run the tests and the code style check on every pull request on Travis CI and we won’t
We automatically run the tests and the code style check on every pull request through GitHub Actions and we won’t
accept any pull requests without all tests passing. However, if you don't find out *why* they are not passing,
just send the pull request and tell us – we'll be glad to help.
If you add a new feature, please include appropriate documentation into your patch. If you fix a bug,
please include a regression test, i.e. a test that fails without your changes and passes after applying your changes.
Again: If you get stuck, do not hesitate to contact any of us, or Raphael personally at mail@raphaelmichel.de.
Again: If you get stuck, do not hesitate to contact us through GitHub discussions.
Please note that we bound ourselves to a :ref:`coc` that applies to all communication around the project. You can be
assured that we will not tolerate any form of harassment.
.._create a pull request: https://help.github.com/articles/creating-a-pull-request/
sql="INSERT INTO pretixbase_reusablemedium_linked_orderpositions (reusablemedium_id, orderposition_id) SELECT id, linked_orderposition_id FROM pretixbase_reusablemedium WHERE linked_orderposition_id IS NOT NULL;",
reverse_sql="DELETE FROM pretixbase_reusablemedium_linked_orderpositions;",
logger.error(f"Found {row['c']} tickets with with the same secret \"{row['secret']}\" in organizer {row['order__event__organizer_id']}, all except one will be changed")
logger.error(f"Found {row['c']} orders with with the same code \"{row['code']}\" in organizer {row['event__organizer_id']}, all except one will be changed")
fori,ainenumerate(affected):
ifi>0:
iflen(a.code)>16-len(str(a.pk)):
raiseValueError(f"Cannot auto-fix order with duplicate code {a.code}, order code is too long already")
"SET organizer_id = (SELECT e.organizer_id FROM pretixbase_event e WHERE e.id = pretixbase_order.event_id) "
"WHERE pretixbase_order.organizer_id IS NULL;",
migrations.RunSQL.noop,
),
migrations.RunSQL(
"UPDATE pretixbase_orderposition "
"SET organizer_id = (SELECT e.organizer_id FROM pretixbase_order o LEFT JOIN pretixbase_event e ON e.id = o.event_id WHERE o.id = pretixbase_orderposition.order_id) "
"WHERE pretixbase_orderposition.organizer_id IS NULL;",
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.