Compare commits

...

58 Commits

Author SHA1 Message Date
Mira Weller
4619901a37 docs: update fee_type options 2025-02-25 14:16:32 +01:00
Mira Weller
ee921a6331 docs: None -> null 2025-02-25 14:04:27 +01:00
Mira Weller
3310e9670b Add create_fees to example 2025-02-25 13:57:33 +01:00
Mira Weller
93570d42c7 Consistent order of examples 2025-02-25 13:57:01 +01:00
Mira Weller
598527073c Fix example in docs 2025-02-25 13:22:59 +01:00
Raphael Michel
d011651565 API: Allow to add a fee to an order (#4806) 2025-02-10 17:24:46 +01:00
Raphael Michel
0079be68d3 Allow plugins to add data to the order API (Z#23179688) (#4822)
* Allow plugins to add data to the order API (Z#23179688)

* Update src/pretix/api/serializers/media.py

Co-authored-by: Richard Schreiber <schreiber@rami.io>

* Fix failing test

---------

Co-authored-by: Richard Schreiber <schreiber@rami.io>
2025-02-10 14:06:20 +01:00
Kian Cross
5bf6980a7b Improve date format heuristic for bank statement import (#4814)
When dates are ambiguous, use the event's locale to infer whether the
day or month comes first. Since regions follow certain date format
conventions, this helps make more accurate guesses.
2025-02-10 11:33:14 +01:00
Kian Cross
7e8ef47537 Add delete button to voucher details page (#4815) 2025-02-10 11:32:24 +01:00
Raphael Michel
86120d0296 Enable Finish language 2025-02-10 10:59:35 +01:00
Karoliina Grohn
e2086a8eca Translations: Update Finnish
Currently translated at 65.8% (3848 of 5846 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/fi/

powered by weblate
2025-02-10 10:59:05 +01:00
Hannu Kaakinen
ad7c4a957d Translations: Update Finnish
Currently translated at 65.8% (3848 of 5846 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/fi/

powered by weblate
2025-02-10 10:59:05 +01:00
Karoliina Grohn
f1fbb08c2b Translations: Update Finnish
Currently translated at 62.4% (3651 of 5846 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/fi/

powered by weblate
2025-02-10 10:59:05 +01:00
Hannu Kaakinen
73b58cfb89 Translations: Update Finnish
Currently translated at 62.4% (3651 of 5846 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/fi/

powered by weblate
2025-02-10 10:59:05 +01:00
Hannu Kaakinen
4323366ec3 Translations: Update Finnish
Currently translated at 58.1% (3401 of 5846 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/fi/

powered by weblate
2025-02-10 10:59:05 +01:00
Karoliina Grohn
4d6b63e1c2 Translations: Update Finnish
Currently translated at 54.3% (3177 of 5846 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/fi/

powered by weblate
2025-02-10 10:59:05 +01:00
Hannu Kaakinen
6edc12a89f Translations: Update Finnish
Currently translated at 54.3% (3177 of 5846 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/fi/

powered by weblate
2025-02-10 10:59:05 +01:00
Hannu Kaakinen
e473d0bfce Translations: Update Finnish
Currently translated at 51.7% (3028 of 5846 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/fi/

powered by weblate
2025-02-10 10:59:05 +01:00
Hannu Kaakinen
42469402b6 Translations: Update Finnish
Currently translated at 41.7% (2440 of 5846 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/fi/

powered by weblate
2025-02-10 10:59:05 +01:00
Hannu Kaakinen
fd70d567e0 Translations: Update Finnish
Currently translated at 39.5% (2310 of 5846 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/fi/

powered by weblate
2025-02-10 10:59:05 +01:00
Hannu Kaakinen
2b4d70fa30 Translations: Update Finnish
Currently translated at 37.7% (2207 of 5846 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/fi/

powered by weblate
2025-02-10 10:59:05 +01:00
조정화
3c27aa8591 Translations: Update Korean
Currently translated at 2.1% (125 of 5846 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/ko/

powered by weblate
2025-02-10 10:59:05 +01:00
Hannu Kaakinen
a1d6d636a8 Translations: Update Finnish
Currently translated at 36.9% (2159 of 5846 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/fi/

powered by weblate
2025-02-10 10:59:05 +01:00
Johanna Ketola
373f9e666f Translations: Update Finnish
Currently translated at 36.9% (2159 of 5846 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/fi/

powered by weblate
2025-02-10 10:59:05 +01:00
Karoliina Grohn
e524055249 Translations: Update Finnish
Currently translated at 36.9% (2159 of 5846 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/fi/

powered by weblate
2025-02-10 10:59:05 +01:00
Mira
85ae181ce8 Add missing return (#4823) 2025-02-10 10:54:56 +01:00
Raphael Michel
cfae2c62c3 OIDC: Fix incorrect error handling in server implementation 2025-02-07 18:04:46 +01:00
Mira
9c781a174d Fix Checkin logdisplay for deleted events (#4821) 2025-02-07 14:25:57 +01:00
Mira
f7cba6a2bd Fix log display for checkins and order splits (Z#23181229) (#4818)
- Fix link in pretix.event.order.changed.split
- Add link to existing order in pretix.event.order.changed.split_from
- Fix display of checkin entries without datetime in data
- Add additional info for admins (action type, linked content object)
2025-02-07 11:53:17 +01:00
Raphael Michel
c4436ca319 Change wording for "show_dates_on_frontpage" setting (#4798) 2025-02-06 14:55:15 +01:00
Martin Gross
c87401ef5d Widget: Prefill email_repeat with data-email attribute (Z#23181657) (#4813) 2025-02-06 12:07:43 +01:00
Raphael Michel
a53def0947 Fix CSRF token of admin mode button being removed if e.g. support menu is clicked (#4812) 2025-02-06 12:07:10 +01:00
Mira
64effc84a3 Hide "Optional" label on conditionally required "Cross-selling condition" field (#4809) 2025-02-06 11:52:27 +01:00
Hannu Kaakinen
867ae8c61a Translations: Update Finnish
Currently translated at 34.2% (2004 of 5846 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/fi/

powered by weblate
2025-02-06 11:51:59 +01:00
조정화
8d8a4c4417 Translations: Update Korean
Currently translated at 1.9% (114 of 5846 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/ko/

powered by weblate
2025-02-06 11:51:59 +01:00
Hannu Kaakinen
1985f1d2de Translations: Update Finnish
Currently translated at 33.6% (1965 of 5846 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/fi/

powered by weblate
2025-02-06 11:51:59 +01:00
Raphael Michel
b6c903a7ba Invoice renderer: Group invoice lines even with addons (Z#23173618) (#4744)
* Invoice renderer: Group invoice lines even with addons (Z#23173618)

* Add unit test

* Update src/pretix/base/invoice.py

Co-authored-by: Mira <weller@rami.io>

---------

Co-authored-by: Mira Weller <weller@rami.io>
2025-02-06 10:55:09 +01:00
dependabot[bot]
9df86b9339 Bump @babel/core from 7.26.0 to 7.26.7 in /src/pretix/static/npm_dir (#4800)
Some checks failed
Build / Packaging (3.11) (push) Has been cancelled
Documentation / Spellcheck (push) Has been cancelled
Code Style / isort (push) Has been cancelled
Code Style / flake8 (push) Has been cancelled
Code Style / licenseheaders (push) Has been cancelled
Tests / Tests (postgres, 3.10) (push) Has been cancelled
Tests / Tests (postgres, 3.11) (push) Has been cancelled
Tests / Tests (postgres, 3.9) (push) Has been cancelled
Tests / Tests (sqlite, 3.11) (push) Has been cancelled
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.26.0 to 7.26.7.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.26.7/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-05 17:40:14 +01:00
dependabot[bot]
4e4e187a84 Update beautifulsoup4 requirement from ==4.12.* to ==4.13.* (#4804)
* Update beautifulsoup4 requirement from ==4.12.* to ==4.13.*

Updates the requirements on [beautifulsoup4](https://www.crummy.com/software/BeautifulSoup/bs4/) to permit the latest version.

---
updated-dependencies:
- dependency-name: beautifulsoup4
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* Replace findAll with find_all

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Raphael Michel <michel@rami.io>
2025-02-05 17:39:23 +01:00
Raphael Michel
5d56cd3917 Fix missing atomicity for handling forms and logs (might be the reason for Z#23178997) (#4755) 2025-02-05 16:56:38 +01:00
Kian Cross
5d4b218aa6 Banktransfer: Handle trailing commas in headers for Lloyds Bank CSV files (#4782)
Lloyds Bank (UK) CSV files include a trailing comma in the header row
but not in the data rows, causing the `csvimport.parse` function to
skip the data rows. This occurs because the header length exceeds the
row length, making them unequal to `hint.cols`.

This commit adjusts the length check to allow a range of acceptable row
lengths, from the index of the last non-empty column in the header to
`hint.cols`. This ensures compatibility with headers containing one or
more trailing commas without affecting rows with correctly labelled columns.

The solution avoids breaking changes by leaving underlying data structures
untouched. Alternative approaches, such as dropping trailing commas before
parsing or removing empty elements after parsing, were avoided due to
potential risks. Specifically, trailing columns might contain data that
banks provide but fail to label in the header row.
2025-02-05 16:56:28 +01:00
dependabot[bot]
03d3879787 Update isort requirement from ==5.13.* to ==6.0.* (#4789)
Updates the requirements on [isort](https://github.com/pycqa/isort) to permit the latest version.
- [Release notes](https://github.com/pycqa/isort/releases)
- [Changelog](https://github.com/PyCQA/isort/blob/main/CHANGELOG.md)
- [Commits](https://github.com/pycqa/isort/compare/5.13.0...6.0.0)

---
updated-dependencies:
- dependency-name: isort
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-05 16:53:10 +01:00
dependabot[bot]
c3db1dfb09 Update geoip2 requirement from ==4.* to ==5.* (#4792)
Updates the requirements on [geoip2](https://github.com/maxmind/GeoIP2-python) to permit the latest version.
- [Release notes](https://github.com/maxmind/GeoIP2-python/releases)
- [Changelog](https://github.com/maxmind/GeoIP2-python/blob/main/HISTORY.rst)
- [Commits](https://github.com/maxmind/GeoIP2-python/compare/v4.0.0...v5.0.1)

---
updated-dependencies:
- dependency-name: geoip2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-05 16:52:53 +01:00
Mira
026a5e2941 Log automatic team creation in event create wizard (#4802) 2025-02-05 16:52:36 +01:00
dependabot[bot]
59d4673dde Bump @babel/preset-env in /src/pretix/static/npm_dir (#4801)
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.26.0 to 7.26.7.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.26.7/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-05 16:52:16 +01:00
dependabot[bot]
30f11deb19 Update reportlab requirement from ==4.2.* to ==4.3.* (#4805)
Updates the requirements on [reportlab](https://www.reportlab.com/) to permit the latest version.

---
updated-dependencies:
- dependency-name: reportlab
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-05 16:51:22 +01:00
조정화
97c456db34 Translations: Update Korean
Some checks failed
Build / Packaging (3.11) (push) Waiting to run
Documentation / Spellcheck (push) Waiting to run
Code Style / isort (push) Waiting to run
Code Style / flake8 (push) Waiting to run
Code Style / licenseheaders (push) Waiting to run
Tests / Tests (postgres, 3.10) (push) Waiting to run
Tests / Tests (postgres, 3.11) (push) Waiting to run
Tests / Tests (postgres, 3.9) (push) Waiting to run
Tests / Tests (sqlite, 3.11) (push) Waiting to run
Strings / Check gettext syntax (push) Has been cancelled
Strings / Spellcheck (push) Has been cancelled
Currently translated at 1.3% (81 of 5846 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/ko/

powered by weblate
2025-02-05 12:51:33 +01:00
Antti Nironen
cf9c85c60b Translations: Update Finnish
Currently translated at 29.2% (1711 of 5846 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/fi/

powered by weblate
2025-02-05 12:51:33 +01:00
Wiktor Przybylski
308a6acfe3 Translations: Update Polish
Currently translated at 98.5% (5764 of 5846 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pl/

powered by weblate
2025-02-05 12:51:33 +01:00
Hijiri Umemoto
388a5f6a1e Translations: Update Japanese
Currently translated at 100.0% (5846 of 5846 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/ja/

powered by weblate
2025-02-05 12:51:33 +01:00
Hannu Kaakinen
25ee4a747f Translations: Update Finnish
Currently translated at 28.8% (1684 of 5846 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/fi/

powered by weblate
2025-02-05 12:51:33 +01:00
Raphael Michel
f6b0e35e40 VAT ID check: Include response in error log 2025-02-05 12:50:20 +01:00
Raphael Michel
85cba253a8 Translations: Remove obvious ChatGPT responses from nb_NO 2025-02-05 12:29:12 +01:00
Raphael Michel
c820d742d4 Generate invoice earlier in payment method change process (Z#23179304) (#4763)
* Generate invoice earlier in payment method change process (Z##23179304)

* Resolve review note
2025-02-03 17:39:46 +01:00
Raphael Michel
2a3cdd85e8 Prevent order changes that interfer with a pending payment that can't be aborted (Z#23179178) (#4765) 2025-02-03 17:09:17 +01:00
pretix translation bot
0b840f8133 Update translations (#4799)
* Translations: Update Portuguese (Portugal)

Currently translated at 85.2% (4986 of 5846 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_PT/

powered by weblate

* Translations: Update Portuguese

Currently translated at 3.0% (178 of 5846 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt/

powered by weblate

* Translations: Update Korean

Currently translated at 1.3% (76 of 5846 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/ko/

powered by weblate

---------

Co-authored-by: Vasco Baleia <vb2003.12@gmail.com>
Co-authored-by: Cornelius Kibelka <ckibelka-ctr@wikimedia.org>
Co-authored-by: 조정화 <junghwa.jo@om.org>
2025-02-03 17:08:21 +01:00
Raphael Michel
58db550e23 Do not allow to cancel pending payments by default (Z#23179178) 2025-02-03 17:07:19 +01:00
Raphael Michel
34da20972e Bump version to 2025.2.0.dev0 2025-01-31 16:21:06 +01:00
50 changed files with 4193 additions and 3051 deletions

View File

@@ -75,8 +75,9 @@ positions list of objects List of order p
fees list of objects List of fees included in the order total. By default, only
non-canceled fees are included.
├ id integer Internal ID of the fee record
├ fee_type string Type of fee (currently ``payment``, ``passbook``,
``other``)
├ fee_type string Type of fee (currently ``payment``, ``shipping``,
``service``, ``cancellation``, ``insurance``, ``late``,
``other``, ``giftcard``)
├ value money (string) Fee amount
├ description string Human-readable string with more details (can be empty)
├ internal_type string Internal string (i.e. ID of the payment provider),
@@ -109,6 +110,7 @@ cancellation_date datetime Time of order c
Will not be set for partial cancellations and is not
reliable for orders that have been cancelled,
reactivated and cancelled again.
plugin_data object Additional data added by plugins.
===================================== ========================== =======================================================
@@ -164,6 +166,10 @@ cancellation_date datetime Time of order c
The ``tax_code`` attribute has been added.
.. versionchanged:: 2025.2
The ``plugin_data`` attribute has been added.
.. _order-position-resource:
Order position resource
@@ -251,6 +257,7 @@ seat objects The assigned se
pdf_data object Data object required for ticket PDF generation. By default,
this field is missing. It will be added only if you add the
``pdf_data=true`` query parameter to your request.
plugin_data object Additional data added by plugins.
===================================== ========================== =======================================================
.. versionchanged:: 4.16
@@ -265,6 +272,10 @@ pdf_data object Data object req
The ``tax_code`` attribute has been added.
.. versionchanged:: 2025.2
The ``plugin_data`` attribute has been added.
.. _order-payment-resource:
Order payment resource
@@ -461,7 +472,8 @@ List of all orders
"output": "pdf",
"url": "https://pretix.eu/api/v1/organizers/bigevents/events/sampleconf/orderpositions/23442/download/pdf/"
}
]
],
"plugin_data": {}
}
],
"downloads": [
@@ -483,7 +495,8 @@ List of all orders
}
],
"refunds": [],
"cancellation_date": null
"cancellation_date": null,
"plugin_data": {}
}
]
}
@@ -702,7 +715,8 @@ Fetching individual orders
"output": "pdf",
"url": "https://pretix.eu/api/v1/organizers/bigevents/events/sampleconf/orderpositions/23442/download/pdf/"
}
]
],
"plugin_data": {}
}
],
"downloads": [
@@ -724,7 +738,8 @@ Fetching individual orders
}
],
"refunds": [],
"cancellation_date": null
"cancellation_date": null,
"plugin_data": {}
}
:param organizer: The ``slug`` field of the organizer to fetch
@@ -1671,7 +1686,8 @@ List of all order positions
"output": "pdf",
"url": "https://pretix.eu/api/v1/organizers/bigevents/events/sampleconf/orderpositions/23442/download/pdf/"
}
]
],
"plugin_data": {}
}
]
}
@@ -1798,7 +1814,8 @@ Fetching individual positions
"output": "pdf",
"url": "https://pretix.eu/api/v1/organizers/bigevents/events/sampleconf/orderpositions/23442/download/pdf/"
}
]
],
"plugin_data": {}
}
:param organizer: The ``slug`` field of the organizer to fetch
@@ -2228,6 +2245,9 @@ otherwise, such as splitting an order or changing fees.
* ``cancel_fees``: A list of objects with the single key ``fee`` specifying an order fee ID.
* ``create_fees``: A list of objects describing new order fees with the fields ``fee_type``, ``value``, ``description``,
``internal_type``, ``tax_rule``
* ``recalculate_taxes``: If set to ``"keep_net"``, all taxes will be recalculated based on the tax rule and invoice
address, the net price will be kept. If set to ``"keep_gross"``, the gross price will be kept. If set to ``null``
(the default) the taxes are not recalculated.
@@ -2247,17 +2267,12 @@ otherwise, such as splitting an order or changing fees.
Content-Type: application/json
{
"cancel_positions": [
{
"position": 12373
}
],
"patch_positions": [
{
"position": 12374,
"body": {
"item": 12,
"variation": None,
"variation": null,
"subevent": 562,
"seat": "seat-guid-2",
"price": "99.99",
@@ -2265,6 +2280,11 @@ otherwise, such as splitting an order or changing fees.
}
}
],
"cancel_positions": [
{
"position": 12373
}
],
"split_positions": [
{
"position": 12375
@@ -2273,7 +2293,7 @@ otherwise, such as splitting an order or changing fees.
"create_positions": [
{
"item": 12,
"variation": None,
"variation": null,
"subevent": 562,
"seat": "seat-guid-2",
"price": "99.99",
@@ -2281,12 +2301,7 @@ otherwise, such as splitting an order or changing fees.
"attendee_name": "Peter",
}
],
"cancel_fees": [
{
"fee": 49
}
],
"change_fees": [
"patch_fees": [
{
"fee": 51,
"body": {
@@ -2294,6 +2309,20 @@ otherwise, such as splitting an order or changing fees.
}
}
],
"cancel_fees": [
{
"fee": 49
}
],
"create_fees": [
{
"fee_type": "other",
"value": "1.50",
"description": "Example Fee",
"internal_type": "",
"tax_rule": 15
}
],
"reissue_invoice": true,
"send_email": true,
"recalculate_taxes": "keep_gross"

View File

@@ -103,4 +103,4 @@ API
.. automodule:: pretix.api.signals
:no-index:
:members: register_device_security_profile
:members: register_device_security_profile, order_api_details, orderposition_api_details

View File

@@ -28,7 +28,7 @@ classifiers = [
dependencies = [
"arabic-reshaper==3.0.0", # Support for Arabic in reportlab
"babel",
"BeautifulSoup4==4.12.*",
"BeautifulSoup4==4.13.*",
"bleach==6.2.*",
"celery==5.4.*",
"chardet==5.2.*",
@@ -57,7 +57,7 @@ dependencies = [
"djangorestframework==3.15.*",
"dnspython==2.7.*",
"drf_ujson2==1.7.*",
"geoip2==4.*",
"geoip2==5.*",
"importlib_metadata==8.*", # Polyfill, we can probably drop this once we require Python 3.10+
"isoweek",
"jsonschema",
@@ -89,7 +89,7 @@ dependencies = [
"pyuca",
"qrcode==8.0",
"redis==5.2.*",
"reportlab==4.2.*",
"reportlab==4.3.*",
"requests==2.31.*",
"sentry-sdk==2.20.*",
"sepaxml==2.6.*",
@@ -113,7 +113,7 @@ dev = [
"fakeredis==2.26.*",
"flake8==7.1.*",
"freezegun",
"isort==5.13.*",
"isort==6.0.*",
"pep8-naming==0.14.*",
"potypo",
"pytest-asyncio>=0.24",

View File

@@ -19,4 +19,4 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
__version__ = "2025.1.0"
__version__ = "2025.2.0.dev0"

View File

@@ -123,7 +123,7 @@ LANGUAGES_RTL = {
'ar', 'hw'
}
LANGUAGES_INCUBATING = {
'fi', 'pt-br', 'gl',
'pt-br', 'gl',
}
LANGUAGES = ALL_LANGUAGES
LOCALE_PATHS = [

View File

@@ -46,6 +46,7 @@ from pretix.api.serializers.i18n import I18nAwareModelSerializer
from pretix.api.serializers.item import (
InlineItemVariationSerializer, ItemSerializer, QuestionSerializer,
)
from pretix.api.signals import order_api_details, orderposition_api_details
from pretix.base.decimal import round_decimal
from pretix.base.i18n import language
from pretix.base.models import (
@@ -494,6 +495,18 @@ class OrderPositionListSerializer(serializers.ListSerializer):
return data
class OrderPositionPluginDataField(serializers.Field):
def to_representation(self, value: OrderPosition):
d = {}
if value and value.pk:
for recv, resp in orderposition_api_details.send(
sender=self.context.get("event") or value.order.event,
orderposition=value
):
d.update(resp)
return d
class OrderPositionSerializer(I18nAwareModelSerializer):
checkins = CheckinSerializer(many=True, read_only=True)
print_logs = PrintLogSerializer(many=True, read_only=True)
@@ -504,6 +517,7 @@ class OrderPositionSerializer(I18nAwareModelSerializer):
seat = InlineSeatSerializer(read_only=True)
country = CompatibleCountryField(source='*')
attendee_name = serializers.CharField(required=False)
plugin_data = OrderPositionPluginDataField(source='*', allow_null=True, read_only=True)
class Meta:
list_serializer_class = OrderPositionListSerializer
@@ -513,7 +527,7 @@ class OrderPositionSerializer(I18nAwareModelSerializer):
'attendee_email', 'voucher', 'tax_rate', 'tax_value', 'secret', 'addon_to', 'subevent', 'checkins',
'print_logs', 'downloads', 'answers', 'tax_rule', 'pseudonymization_id', 'pdf_data', 'seat', 'canceled',
'print_logs', 'downloads', 'answers', 'tax_rule', 'tax_code', 'pseudonymization_id', 'pdf_data', 'seat',
'canceled', 'valid_from', 'valid_until', 'blocked', 'voucher_budget_use')
'canceled', 'valid_from', 'valid_until', 'blocked', 'voucher_budget_use', 'plugin_data')
read_only_fields = (
'id', 'order', 'positionid', 'item', 'variation', 'price', 'voucher', 'tax_rate', 'tax_value', 'secret',
'addon_to', 'subevent', 'checkins', 'downloads', 'answers', 'tax_rule', 'tax_code', 'pseudonymization_id',
@@ -730,6 +744,18 @@ class OrderListSerializer(serializers.ListSerializer):
return data
class OrderPluginDataField(serializers.Field):
def to_representation(self, value: Order):
d = {}
if value and value.pk:
for recv, resp in order_api_details.send(
sender=self.context.get("event") or value.event,
order=value
):
d.update(resp)
return d
class OrderSerializer(I18nAwareModelSerializer):
event = SlugRelatedField(slug_field='slug', read_only=True)
invoice_address = InvoiceAddressSerializer(allow_null=True)
@@ -747,6 +773,7 @@ class OrderSerializer(I18nAwareModelSerializer):
queryset=SalesChannel.objects.none(),
required=False,
)
plugin_data = OrderPluginDataField(source='*', allow_null=True, read_only=True)
class Meta:
model = Order
@@ -755,7 +782,7 @@ class OrderSerializer(I18nAwareModelSerializer):
'code', 'event', 'status', 'testmode', 'secret', 'email', 'phone', 'locale', 'datetime', 'expires', 'payment_date',
'payment_provider', 'fees', 'total', 'comment', 'custom_followup_at', 'invoice_address', 'positions', 'downloads',
'checkin_attention', 'checkin_text', 'last_modified', 'payments', 'refunds', 'require_approval', 'sales_channel',
'url', 'customer', 'valid_if_pending', 'api_meta', 'cancellation_date'
'url', 'customer', 'valid_if_pending', 'api_meta', 'cancellation_date', 'plugin_data',
)
read_only_fields = (
'code', 'status', 'testmode', 'secret', 'datetime', 'expires', 'payment_date',

View File

@@ -30,7 +30,7 @@ from rest_framework.exceptions import ValidationError
from pretix.api.serializers.order import (
AnswerCreateSerializer, AnswerSerializer, CompatibleCountryField,
OrderPositionCreateSerializer,
OrderFeeCreateSerializer, OrderPositionCreateSerializer,
)
from pretix.base.models import ItemVariation, Order, OrderFee, OrderPosition
from pretix.base.services.orders import OrderError
@@ -104,6 +104,54 @@ class OrderPositionCreateForExistingOrderSerializer(OrderPositionCreateSerialize
raise ValidationError(str(e))
class OrderFeeCreateForExistingOrderSerializer(OrderFeeCreateSerializer):
order = serializers.SlugRelatedField(slug_field='code', queryset=Order.objects.none(), required=True, allow_null=False)
value = serializers.DecimalField(required=True, allow_null=False, decimal_places=2,
max_digits=13)
internal_type = serializers.CharField(required=False, default="")
class Meta:
model = OrderFee
fields = ('order', 'fee_type', 'value', 'description', 'internal_type', 'tax_rule')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if not self.context:
return
self.fields['order'].queryset = self.context['event'].orders.all()
self.fields['tax_rule'].queryset = self.context['event'].tax_rules.all()
if 'order' in self.context:
del self.fields['order']
def validate(self, data):
data = super().validate(data)
if 'order' in self.context:
data['order'] = self.context['order']
return data
def create(self, validated_data):
ocm = self.context['ocm']
try:
f = OrderFee(
order=validated_data['order'],
fee_type=validated_data['fee_type'],
value=validated_data.get('value'),
description=validated_data.get('description'),
internal_type=validated_data.get('internal_type'),
tax_rule=validated_data.get('tax_rule'),
)
f._calculate_tax()
ocm.add_fee(f)
if self.context.get('commit', True):
ocm.commit()
return validated_data['order'].fees.order_by('-pk').first()
else:
return OrderFee() # fake to appease DRF
except OrderError as e:
raise ValidationError(str(e))
class OrderPositionInfoPatchSerializer(serializers.ModelSerializer):
answers = AnswerSerializer(many=True)
country = CompatibleCountryField(source='*')
@@ -401,6 +449,9 @@ class OrderChangeOperationSerializer(serializers.Serializer):
self.fields['split_positions'] = SelectPositionSerializer(
many=True, required=False, context=self.context
)
self.fields['create_fees'] = OrderFeeCreateForExistingOrderSerializer(
many=True, required=False, context=self.context
)
self.fields['patch_fees'] = PatchFeeSerializer(
many=True, required=False, context=self.context
)

View File

@@ -26,7 +26,7 @@ from django.utils.timezone import now
from django_scopes import scopes_disabled
from pretix.api.models import ApiCall, WebHookCall
from pretix.base.signals import periodic_task
from pretix.base.signals import EventPluginSignal, periodic_task
from pretix.helpers.periodic import minimum_interval
register_webhook_events = Signal()
@@ -43,6 +43,28 @@ return an instance of a subclass of ``pretix.api.auth.devicesecurity.BaseSecurit
or a list of such instances.
"""
order_api_details = EventPluginSignal()
"""
Arguments: ``order``
This signal is sent out to fill the ``plugin_details`` field of the order API. Receivers
should return a dictionary that is combined with the dictionaries of all other plugins.
Note that doing database or network queries in receivers to this signal is discouraged
and could cause serious performance issues. The main purpose is to provide information
from e.g. ``meta_info`` to the API consumer,
"""
orderposition_api_details = EventPluginSignal()
"""
Arguments: ``orderposition``
This signal is sent out to fill the ``plugin_details`` field of the order API. Receivers
should return a dictionary that is combined with the dictionaries of all other plugins.
Note that doing database or network queries in receivers to this signal is discouraged
and could cause serious performance issues. The main purpose is to provide information
from e.g. ``meta_info`` to the API consumer,
"""
@receiver(periodic_task)
@scopes_disabled()

View File

@@ -63,7 +63,8 @@ from pretix.api.serializers.order import (
)
from pretix.api.serializers.orderchange import (
BlockNameSerializer, OrderChangeOperationSerializer,
OrderFeeChangeSerializer, OrderPositionChangeSerializer,
OrderFeeChangeSerializer, OrderFeeCreateForExistingOrderSerializer,
OrderPositionChangeSerializer,
OrderPositionCreateForExistingOrderSerializer,
OrderPositionInfoPatchSerializer,
)
@@ -988,6 +989,12 @@ class EventOrderViewSet(OrderViewSetMixin, viewsets.ModelViewSet):
ocm.cancel_fee(r['fee'])
canceled_fees.add(r['fee'])
for r in serializer.validated_data.get('create_fees', []):
pos_serializer = OrderFeeCreateForExistingOrderSerializer(
context={'ocm': ocm, 'commit': False, 'event': request.event, **self.get_serializer_context()},
)
pos_serializer.create(r)
for r in serializer.validated_data.get('patch_fees', []):
if r['fee'] in canceled_fees:
continue

View File

@@ -62,6 +62,58 @@ from pretix.presale.style import get_fonts
logger = logging.getLogger(__name__)
def addon_aware_groupby(iterable, key, is_addon):
"""
We use groupby() to visually group identical lines on an invoice. For example, instead of
Product 1 5.00 EUR
Product 1 5.00 EUR
Product 1 5.00 EUR
Product 2 7.00 EUR
We want to print
3x Product 1 5.00 EUR = 15.00 EUR
Product 2 7.00 EUR
However, this fails for setups with addon-products since groupby() only groups consecutive
lines with the same identity. So in
Product 1 5.00 EUR
+ Addon 1 2.00 EUR
Product 1 5.00 EUR
+ Addon 1 2.00 EUR
Product 1 5.00 EUR
+ Addon 2 3.00 EUR
There is no consecutive repetition of the same entity. This function provides a specialised groupby which
understands the product/addon relationship and packs groups of these addons together if they are, in fact,
identical groups:
2x Product 1 5.00 EUR = 10.00 EUR
+ 2x Addon 1 2.00 EUR = 4.00 EUR
Product 1 5.00 EUR
+ Addon 2 3.00 EUR
"""
packed_groups = []
for i in iterable:
if is_addon(i):
packed_groups[-1].append(i)
else:
packed_groups.append([i])
# Each packed_groups element contains a list with the parent product as first element, and any addon products following
def _reorder(packed_groups):
# Emit the products as individual products again, reordered by "all parent products, then all addon products"
# within each group.
for _, repeated_groups in groupby(packed_groups, key=lambda g: tuple(key(a) for a in g)):
for repeated_items in zip(*repeated_groups):
yield from repeated_items
return groupby(_reorder(packed_groups), key)
class NumberedCanvas(Canvas):
def __init__(self, *args, **kwargs):
self.font_regular = kwargs.pop('font_regular')
@@ -644,7 +696,11 @@ class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer):
line.event_date_from, line.event_date_to)
total = Decimal('0.00')
for (description, tax_rate, tax_name, net_value, gross_value, *ignored), lines in groupby(self.invoice.lines.all(), key=_group_key):
for (description, tax_rate, tax_name, net_value, gross_value, *ignored), lines in addon_aware_groupby(
self.invoice.lines.all(),
key=_group_key,
is_addon=lambda l: l.description.startswith(" +"),
):
lines = list(lines)
if has_taxes:
if len(lines) > 1:

View File

@@ -957,12 +957,19 @@ class BasePaymentProvider:
def cancel_payment(self, payment: OrderPayment):
"""
Will be called to cancel a payment. The default implementation just sets the payment state to canceled,
but in some cases you might want to notify an external provider.
Will be called to cancel a payment. The default implementation fails if the payment is
``OrderPayment.PAYMENT_STATE_PENDING`` and ``abort_pending_allowed`` is false. Otherwise, it just sets the
payment state to canceled. In some cases you might want to modify this behaviour to notify the external provider
of the cancellation.
On success, you should set ``payment.state = OrderPayment.PAYMENT_STATE_CANCELED`` (or call the super method).
On failure, you should raise a PaymentException.
"""
if payment.state == OrderPayment.PAYMENT_STATE_PENDING and not self.abort_pending_allowed:
raise PaymentException(_(
"This payment is already being processed and can not be canceled any more."
))
payment.state = OrderPayment.PAYMENT_STATE_CANCELED
payment.save(update_fields=['state'])

View File

@@ -674,7 +674,7 @@ def replace_images_with_cid_paths(body_html):
if body_html:
email = BeautifulSoup(body_html, "lxml")
cid_images = []
for image in email.findAll('img'):
for image in email.find_all('img'):
original_image_src = image['src']
try:

View File

@@ -3114,14 +3114,34 @@ def change_payment_provider(order: Order, payment_provider, amount=None, new_pay
}
)
new_invoice_created = False
if recreate_invoices:
# Lock to prevent duplicate invoice creation
order = Order.objects.select_for_update(of=OF_SELF).get(pk=order.pk)
i = order.invoices.filter(is_cancellation=False).last()
if i and order.total != oldtotal and not i.canceled:
has_active_invoice = i and not i.canceled
if has_active_invoice and order.total != oldtotal:
generate_cancellation(i)
generate_invoice(order)
new_invoice_created = True
elif (not has_active_invoice or order.invoice_dirty) and invoice_qualified(order):
if order.event.settings.get('invoice_generate') == 'True' or (
order.event.settings.get('invoice_generate') == 'paid' and
new_payment.payment_provider.requires_invoice_immediately
):
if has_active_invoice:
generate_cancellation(i)
i = generate_invoice(order)
new_invoice_created = True
order.log_action('pretix.event.order.invoice.generated', data={
'invoice': i.pk
})
order.create_transactions()
return old_fee, new_fee, fee, new_payment
return old_fee, new_fee, fee, new_payment, new_invoice_created
@receiver(order_paid, dispatch_uid="pretixbase_order_paid_giftcards")

View File

@@ -152,7 +152,7 @@ def _validate_vat_id_EU(vat_id, country_code):
valid_elements = envelope.findall('./soap:Body/vat:checkVatResponse/vat:valid', namespaces)
if not valid_elements:
logger.error(
f'VAT ID checking failed for {country_code} due to missing <valid> tag'
f'VAT ID checking failed for {country_code} due to missing <valid> tag, response was: {return_xml}'
)
raise VATIDTemporaryError(error_messages['unavailable'])

View File

@@ -1308,10 +1308,13 @@ DEFAULTS = {
'serializer_class': serializers.BooleanField,
'form_class': forms.BooleanField,
'form_kwargs': dict(
label=_("Show event times and dates on the ticket shop"),
help_text=_("If disabled, no date or time will be shown on the ticket shop's front page. This settings "
"also affects a few other locations, however it should not be expected that the date of the "
"event is shown nowhere to users."),
label=_("This shop represents an event"),
help_text=_(
"Uncheck this box if you are only selling something that has no specific date, such as gift cards or a "
"ticket that can be used any time. The system will then stop showing the event date in some places like "
"the event start page. Note that pretix still is a system built around events and the date may still "
"show up in other places."
),
)
},
'show_date_to': {

View File

@@ -120,6 +120,7 @@ class CategoryForm(I18nModelForm):
self.fields['cross_selling_condition'].widget.attrs['data-disable-dependent'] = 'true'
self.fields['cross_selling_condition'].widget.choices = self.fields['cross_selling_condition'].widget.choices[1:]
self.fields['cross_selling_condition'].required = False
self.fields['cross_selling_condition']._required = True # Do not display "Optional" label
self.fields['cross_selling_match_products'].widget = forms.CheckboxSelectMultiple(
attrs={

View File

@@ -72,7 +72,7 @@ class OrderChangeLogEntryType(OrderLogEntryType):
prefix = _('The order has been changed:')
def display(self, logentry, data):
return self.prefix + ' ' + self.display_prefixed(logentry.event, logentry, data)
return format_html('{} {}', self.prefix, self.display_prefixed(logentry.event, logentry, data))
def display_prefixed(self, event: Event, logentry: LogEntry, data):
return super().display(logentry, data)
@@ -282,12 +282,13 @@ class OrderChangedSplit(OrderChangeLogEntryType):
'organizer': event.organizer.slug,
'code': data['new_order']
})
return mark_safe(self.prefix + ' ' + _('Position #{posid} ({old_item}, {old_price}) split into new order: {order}').format(
return format_html(
_('Position #{posid} ({old_item}, {old_price}) split into new order: {order}'),
old_item=escape(old_item),
posid=data.get('positionid', '?'),
order='<a href="{}">{}</a>'.format(url, data['new_order']),
order=format_html(mark_safe('<a href="{}">{}</a>'), url, data['new_order']),
old_price=money_filter(Decimal(data['old_price']), event.currency),
))
)
@log_entry_types.new()
@@ -295,8 +296,14 @@ class OrderChangedSplitFrom(OrderLogEntryType):
action_type = 'pretix.event.order.changed.split_from'
def display(self, logentry: LogEntry, data):
return _('This order has been created by splitting the order {order}').format(
order=data['original_order'],
url = reverse('control:event.order', kwargs={
'event': logentry.event.slug,
'organizer': logentry.event.organizer.slug,
'code': data['original_order']
})
return format_html(
_('This order has been created by splitting the order {order}'),
order=format_html(mark_safe('<a href="{}">{}</a>'), url, data['original_order']),
)
@@ -318,7 +325,7 @@ class OrderChangedSplitFrom(OrderLogEntryType):
})
class CheckinErrorLogEntryType(OrderLogEntryType):
def display(self, logentry: LogEntry, data):
self.display_plain(self.plain, logentry, data)
return self.display_plain(self.plain, logentry, data)
def display_plain(self, plain, logentry: LogEntry, data):
if isinstance(plain, tuple):
@@ -330,7 +337,7 @@ class CheckinErrorLogEntryType(OrderLogEntryType):
event = logentry.event
if 'list' in data:
if 'list' in data and event:
try:
data['list'] = event.checkin_lists.get(pk=data.get('list')).name
except CheckinList.DoesNotExist:
@@ -343,12 +350,12 @@ class CheckinErrorLogEntryType(OrderLogEntryType):
if 'datetime' in data:
dt = dateutil.parser.parse(data.get('datetime'))
if abs((logentry.datetime - dt).total_seconds()) > 5 or 'forced' in data:
tz = event.timezone
data['datetime'] = date_format(dt.astimezone(tz), "SHORT_DATETIME_FORMAT")
if abs((logentry.datetime - dt).total_seconds()) > 5 or data.get('forced'):
if event:
data['datetime'] = date_format(dt.astimezone(event.timezone), "SHORT_DATETIME_FORMAT")
return str(plain_with_dt).format_map(data)
else:
return str(plain_without_dt).format_map(data)
return str(plain_without_dt).format_map(data)
@log_entry_types.new('pretix.event.checkin')
@@ -410,7 +417,7 @@ class OrderPrintLogEntryType(OrderLogEntryType):
datetime=date_format(
dateutil.parser.parse(data["datetime"]).astimezone(logentry.event.timezone),
"SHORT_DATETIME_FORMAT"
),
) if logentry.event else data["datetime"],
type=dict(PrintLog.PRINT_TYPES)[data["type"]],
)

View File

@@ -125,6 +125,15 @@
<button type="submit" class="btn btn-primary btn-save">
{% trans "Save" %}
</button>
{% if voucher.pk %}
<div class="pull-left">
<a href="{% url "control:event.voucher.delete" organizer=request.organizer.slug event=request.event.slug voucher=voucher.pk %}"
class="btn btn-danger btn-lg">
<span class="fa fa-trash"></span>
{% trans "Delete voucher" %}
</a>
</div>
{% endif %}
</div>
{% endif %}
</form>

View File

@@ -34,6 +34,7 @@
import importlib_metadata as metadata
from django.conf import settings
from django.contrib import messages
from django.db import transaction
from django.http import HttpResponse, JsonResponse
from django.shortcuts import get_object_or_404, redirect, reverse
from django.utils.timezone import now
@@ -58,6 +59,7 @@ class GlobalSettingsView(AdministratorPermissionRequiredMixin, FormView):
template_name = 'pretixcontrol/global_settings.html'
form_class = GlobalSettingsForm
@transaction.atomic
def form_valid(self, form):
form.save()
messages.success(self.request, _('Your changes have been saved.'))
@@ -108,7 +110,7 @@ class MessageView(TemplateView):
class LogDetailView(AdministratorPermissionRequiredMixin, View):
def get(self, request, *args, **kwargs):
le = get_object_or_404(LogEntry, pk=request.GET.get('pk'))
return JsonResponse({'data': le.parsed_data})
return JsonResponse({'action_type': le.action_type, 'content_type': str(le.content_type), 'object_id': le.object_id, 'data': le.parsed_data})
class PaymentDetailView(AdministratorPermissionRequiredMixin, View):

View File

@@ -289,6 +289,17 @@ class EventWizard(SafeSessionWizardView):
)
t.members.add(self.request.user)
t.limit_events.add(event)
t.log_action('pretix.team.created', user=self.request.user, data={
'_created_by_event_wizard': True,
'name': t.name,
'can_change_event_settings': True,
'can_change_items': True,
'can_view_orders': True,
'can_change_orders': True,
'can_view_vouchers': True,
'can_change_vouchers': True,
'limit_events': [event.pk],
})
logdata = {}
for f in form_list:

View File

@@ -626,6 +626,7 @@ class TeamCreateView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixin,
'team': self.object.pk
})
@transaction.atomic
def form_valid(self, form):
messages.success(self.request, _('The team has been created. You can now add members to the team.'))
form.instance.organizer = self.request.organizer
@@ -663,6 +664,7 @@ class TeamUpdateView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixin,
'team': self.object.pk
})
@transaction.atomic
def form_valid(self, form):
if form.has_changed():
self.object.log_action('pretix.team.changed', user=self.request.user, data={
@@ -983,6 +985,7 @@ class DeviceCreateView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixi
'device': self.object.pk
})
@transaction.atomic
def form_valid(self, form):
form.instance.organizer = self.request.organizer
ret = super().form_valid(form)
@@ -1044,6 +1047,7 @@ class DeviceUpdateView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixi
'organizer': self.request.organizer.slug,
})
@transaction.atomic
def form_valid(self, form):
if form.has_changed():
self.object.log_action('pretix.device.changed', user=self.request.user, data={
@@ -1236,6 +1240,7 @@ class DeviceRevokeView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixi
}))
return super().get(request, *args, **kwargs)
@transaction.atomic
def post(self, request, *args, **kwargs):
self.object = self.get_object()
self.object.revoked = True
@@ -1273,6 +1278,7 @@ class WebHookCreateView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMix
'organizer': self.request.organizer.slug,
})
@transaction.atomic
def form_valid(self, form):
form.instance.organizer = self.request.organizer
ret = super().form_valid(form)
@@ -1310,6 +1316,7 @@ class WebHookUpdateView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMix
'organizer': self.request.organizer.slug,
})
@transaction.atomic
def form_valid(self, form):
if form.has_changed():
self.request.organizer.log_action('pretix.webhook.changed', user=self.request.user, data=merge_dicts({
@@ -1386,6 +1393,7 @@ class GiftCardAcceptanceInviteView(OrganizerDetailViewMixin, OrganizerPermission
'organizer': self.request.organizer,
}
@transaction.atomic
def form_valid(self, form):
self.request.organizer.gift_card_acceptor_acceptance.get_or_create(
acceptor=form.cleaned_data['acceptor'],
@@ -2000,6 +2008,7 @@ class GateCreateView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixin,
'organizer': self.request.organizer.slug,
})
@transaction.atomic
def form_valid(self, form):
messages.success(self.request, _('The gate has been created.'))
form.instance.organizer = self.request.organizer
@@ -2034,6 +2043,7 @@ class GateUpdateView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixin,
'organizer': self.request.organizer.slug,
})
@transaction.atomic
def form_valid(self, form):
if form.has_changed():
self.object.log_action('pretix.gate.changed', user=self.request.user, data={
@@ -2136,6 +2146,7 @@ class EventMetaPropertyCreateView(OrganizerDetailViewMixin, OrganizerPermissionR
'organizer': self.request.organizer.slug,
})
@transaction.atomic
def form_valid(self, form):
messages.success(self.request, _('The property has been created.'))
form.instance.organizer = self.request.organizer
@@ -2166,6 +2177,7 @@ class EventMetaPropertyUpdateView(OrganizerDetailViewMixin, OrganizerPermissionR
'organizer': self.request.organizer.slug,
})
@transaction.atomic
def form_valid(self, form):
form.instance.choices = [
f.cleaned_data for f in self.formset.ordered_forms if f not in self.formset.deleted_forms
@@ -2207,6 +2219,7 @@ class EventMetaPropertyDeleteView(OrganizerDetailViewMixin, OrganizerPermissionR
return redirect(success_url)
@transaction.atomic
def meta_property_move(request, property, up=True):
property = get_object_or_404(request.organizer.meta_properties, id=property)
properties = list(request.organizer.meta_properties.order_by("position"))
@@ -2329,6 +2342,7 @@ class MembershipTypeCreateView(OrganizerDetailViewMixin, OrganizerPermissionRequ
kwargs['event'] = self.request.organizer
return kwargs
@transaction.atomic
def form_valid(self, form):
messages.success(self.request, _('The membership type has been created.'))
form.instance.organizer = self.request.organizer
@@ -2363,6 +2377,7 @@ class MembershipTypeUpdateView(OrganizerDetailViewMixin, OrganizerPermissionRequ
kwargs['event'] = self.request.organizer
return kwargs
@transaction.atomic
def form_valid(self, form):
if form.has_changed():
self.object.log_action('pretix.membershiptype.changed', user=self.request.user, data={
@@ -2436,6 +2451,7 @@ class SSOProviderCreateView(OrganizerDetailViewMixin, OrganizerPermissionRequire
kwargs['event'] = self.request.organizer
return kwargs
@transaction.atomic
def form_valid(self, form):
messages.success(self.request, _('The provider has been created.'))
form.instance.organizer = self.request.organizer
@@ -2478,6 +2494,7 @@ class SSOProviderUpdateView(OrganizerDetailViewMixin, OrganizerPermissionRequire
kwargs['event'] = self.request.organizer
return kwargs
@transaction.atomic
def form_valid(self, form):
if form.has_changed():
self.object.log_action('pretix.ssoprovider.changed', user=self.request.user, data={
@@ -2551,6 +2568,7 @@ class SSOClientCreateView(OrganizerDetailViewMixin, OrganizerPermissionRequiredM
kwargs['event'] = self.request.organizer
return kwargs
@transaction.atomic
def form_valid(self, form):
secret = form.instance.set_client_secret()
messages.success(
@@ -2595,6 +2613,7 @@ class SSOClientUpdateView(OrganizerDetailViewMixin, OrganizerPermissionRequiredM
kwargs['event'] = self.request.organizer
return kwargs
@transaction.atomic
def form_valid(self, form):
if form.has_changed():
self.object.log_action('pretix.ssoclient.changed', user=self.request.user, data={
@@ -2797,6 +2816,7 @@ class CustomerCreateView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMi
ctx['instance'] = c
return ctx
@transaction.atomic
def form_valid(self, form):
r = super().form_valid(form)
form.instance.log_action('pretix.customer.created', user=self.request.user, data={
@@ -2825,6 +2845,7 @@ class CustomerUpdateView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMi
identifier=self.kwargs.get('customer')
)
@transaction.atomic
def form_valid(self, form):
if form.has_changed():
self.object.log_action('pretix.customer.changed', user=self.request.user, data={
@@ -2862,6 +2883,7 @@ class MembershipUpdateView(OrganizerDetailViewMixin, OrganizerPermissionRequired
)
return ctx
@transaction.atomic
def form_valid(self, form):
if form.has_changed():
d = {
@@ -2938,6 +2960,7 @@ class MembershipCreateView(OrganizerDetailViewMixin, OrganizerPermissionRequired
)
return kwargs
@transaction.atomic
def form_valid(self, form):
r = super().form_valid(form)
d = {
@@ -3036,6 +3059,7 @@ class ReusableMediumCreateView(OrganizerDetailViewMixin, OrganizerPermissionRequ
ctx['instance'] = c
return ctx
@transaction.atomic
def form_valid(self, form):
r = super().form_valid(form)
form.instance.log_action('pretix.reusable_medium.created', user=self.request.user, data={
@@ -3064,6 +3088,7 @@ class ReusableMediumUpdateView(OrganizerDetailViewMixin, OrganizerPermissionRequ
pk=self.kwargs.get('pk')
)
@transaction.atomic
def form_valid(self, form):
if form.has_changed():
self.object.log_action('pretix.reusable_medium.changed', user=self.request.user, data={
@@ -3155,6 +3180,7 @@ class ChannelCreateView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMix
"type": self.selected_type,
}
@transaction.atomic
def form_valid(self, form):
messages.success(self.request, _('The sales channel has been created.'))
form.instance.organizer = self.request.organizer
@@ -3200,6 +3226,7 @@ class ChannelUpdateView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMix
"type": self.type,
}
@transaction.atomic
def form_valid(self, form):
if form.has_changed():
self.object.log_action('pretix.saleschannel.changed', user=self.request.user, data={
@@ -3250,6 +3277,7 @@ class ChannelDeleteView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMix
return redirect(success_url)
@transaction.atomic
def channel_move(request, channel, up=True):
channel = get_object_or_404(request.organizer.sales_channels, identifier=channel)
channels = list(request.organizer.sales_channels.order_by("position"))

View File

@@ -231,6 +231,7 @@ class UserSettings(UpdateView):
messages.error(self.request, _('Your changes could not be saved. See below for details.'))
return super().form_invalid(form)
@transaction.atomic
def form_valid(self, form):
messages.success(self.request, _('Your changes have been saved.'))

View File

@@ -28,6 +28,7 @@ from django.contrib.auth import (
BACKEND_SESSION_KEY, get_user_model, load_backend, login,
)
from django.contrib.auth.mixins import LoginRequiredMixin
from django.db import transaction
from django.shortcuts import get_object_or_404, redirect
from django.urls import reverse
from django.utils.crypto import get_random_string
@@ -108,6 +109,7 @@ class UserEditView(AdministratorPermissionRequiredMixin, RecentAuthenticationReq
def get_success_url(self):
return reverse('control:users.edit', kwargs=self.kwargs)
@transaction.atomic
def form_valid(self, form):
messages.success(self.request, _('Your changes have been saved.'))

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-01-29 13:18+0000\n"
"PO-Revision-Date: 2025-01-27 10:00+0000\n"
"PO-Revision-Date: 2025-02-04 20:00+0000\n"
"Last-Translator: Hijiri Umemoto <hijiri@umemoto.org>\n"
"Language-Team: Japanese <https://translate.pretix.eu/projects/pretix/pretix/"
"ja/>\n"
@@ -3410,10 +3410,8 @@ msgid "The relevant plugin is currently not active."
msgstr "関連するプラグインは、現在無効です。"
#: pretix/base/logentrytypes.py:49
#, fuzzy
#| msgid "Delete"
msgid "(deleted)"
msgstr "削除"
msgstr "(削除済み)"
#: pretix/base/logentrytypes.py:78
#, python-brace-format
@@ -14584,7 +14582,8 @@ msgstr "この料金を削除してください"
msgid ""
"Note that payment fees have a special semantic and might automatically be "
"changed if the payment method of the order is changed."
msgstr ""
msgstr "支払い手数料には特別な意味があり、注文の支払い方法が変更されると自動的に変更"
"される可能性があることに注意してください。"
#: pretix/control/forms/orders.py:626
#: pretix/control/templates/pretixcontrol/order/change.html:214
@@ -15407,16 +15406,13 @@ msgstr ""
"リスト「{list}」のタイプ「{type}」のコード「{barcode}」のスキャンが不明です。"
#: pretix/control/logdisplay.py:309
#, fuzzy, python-brace-format
#| msgid ""
#| "Scan scan of revoked code \"{barcode}…\" at {datetime} for list \"{list}"
#| "\", type \"{type}\", was uploaded."
#, python-brace-format
msgid ""
"Scan of revoked code \"{barcode}…\" at {datetime} for list \"{list}\", type "
"\"{type}\", was uploaded."
msgstr ""
"リスト「{list}」のコード「{barcode}」が{datetime}にアップロードされました。タ"
"イプは「{type}」です。"
"{datetime} にスキャンされた、リスト\"{list}\"、種別 \"{type}"
"\"の取り消し済みのコード \"{barcode}…\"がアップロードされました。"
#: pretix/control/logdisplay.py:310
#, python-brace-format
@@ -16363,10 +16359,9 @@ msgid "The check-in list has been changed."
msgstr "チェックインリストが変更されました。"
#: pretix/control/logdisplay.py:762
#, fuzzy, python-brace-format
#| msgid "Check-in list"
#, python-brace-format
msgid "Check-in list {val}"
msgstr "チェックイン・リスト"
msgstr "チェックイン・リスト{val}"
#: pretix/control/logdisplay.py:769
msgid "The plugin has been enabled."

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-01-29 13:18+0000\n"
"PO-Revision-Date: 2025-01-31 05:00+0000\n"
"PO-Revision-Date: 2025-02-06 18:00+0000\n"
"Last-Translator: 조정화 <junghwa.jo@om.org>\n"
"Language-Team: Korean <https://translate.pretix.eu/projects/pretix/pretix/ko/"
">\n"
@@ -319,245 +319,250 @@ msgstr "질문 간의 순환 의존성이 감지되었습니다."
#: pretix/api/serializers/item.py:543 pretix/control/forms/item.py:191
msgid "This type of question cannot be asked during check-in."
msgstr ""
msgstr "체크인 하는 동안에는 그러한 질문을 할 수 없습니다."
#: pretix/api/serializers/item.py:546 pretix/control/forms/item.py:199
msgid "This type of question cannot be shown during check-in."
msgstr ""
msgstr "체크인 중에는 이러한 유형의 질문을 표시할 수 없습니다."
#: pretix/api/serializers/media.py:108
#, fuzzy
msgid ""
"A medium with the same identifier and type already exists in your organizer "
"account."
msgstr ""
msgstr "동일한 식별자와 유형의 매체가 이미 주최자 계정에 존재합니다."
#: pretix/api/serializers/order.py:78
#, python-brace-format
msgid "\"{input}\" is not a valid choice."
msgstr ""
msgstr "\"{input}\"은 유효한 선택이 아닙니다."
#: pretix/api/serializers/order.py:1345 pretix/api/views/cart.py:224
#: pretix/base/services/orders.py:1530
#, python-brace-format
msgid "The selected seat \"{seat}\" is not available."
msgstr ""
msgstr "선택한 좌석 \"{seat}\"을 사용할 수 없습니다."
#: pretix/api/serializers/order.py:1371 pretix/api/serializers/order.py:1378
msgid "The product \"{}\" is not available on this date."
msgstr ""
msgstr "\"{}\" 제품은 이 날짜에 구매할 수 없습니다."
#: pretix/api/serializers/order.py:1393 pretix/api/views/cart.py:200
#, fuzzy
msgid ""
"There is not enough quota available on quota \"{}\" to perform the operation."
msgstr ""
msgstr "할당량 \"{}\"에 작업을 수행할 수 있는 할당량이 충분하지 않습니다."
#: pretix/api/serializers/organizer.py:103
#: pretix/control/forms/organizer.py:888 pretix/presale/forms/customer.py:445
msgid "An account with this email address is already registered."
msgstr ""
msgstr "이 이메일 주소를 가진 계정이 이미 등록되어 있습니다."
#: pretix/api/serializers/organizer.py:236
#: pretix/control/forms/organizer.py:737
msgid ""
"A gift card with the same secret already exists in your or an affiliated "
"organizer account."
msgstr ""
msgstr "동일한 비밀을 가진 기프트 카드가 이미 회원님 또는 제휴 주최자 계정에 "
"존재합니다."
#: pretix/api/serializers/organizer.py:327
#: pretix/control/views/organizer.py:769
msgid "pretix account invitation"
msgstr ""
msgstr "프레틱스 계정 초대"
#: pretix/api/serializers/organizer.py:349
#: pretix/control/views/organizer.py:868
msgid "This user already has been invited for this team."
msgstr ""
msgstr "이 사용자는 이미 이 팀에 초대되었습니다."
#: pretix/api/serializers/organizer.py:365
#: pretix/control/views/organizer.py:885
msgid "This user already has permissions for this team."
msgstr ""
msgstr "이 사용자는 이미 이 팀에 대한 권한을 가지고 있습니다."
#: pretix/api/views/cart.py:209
msgid ""
"The specified voucher has already been used the maximum number of times."
msgstr ""
msgstr "지정된 바우처는 이미 최대 횟수만큼 사용되었습니다."
#: pretix/api/views/checkin.py:610 pretix/api/views/checkin.py:617
msgid "Medium connected to other event"
msgstr ""
msgstr "다른 이벤트와 연결된 매체"
#: pretix/api/views/oauth.py:107 pretix/control/logdisplay.py:686
#, python-brace-format
#, fuzzy, python-brace-format
msgid ""
"The application \"{application_name}\" has been authorized to access your "
"account."
msgstr ""
msgstr "\"{applicationion_name}\" 애플리케이션이 계정에 액세스할 수 있는 권한을 "
"부여받았습니다."
#: pretix/api/views/order.py:607 pretix/control/views/orders.py:1588
#: pretix/presale/views/order.py:741 pretix/presale/views/order.py:814
msgid "You cannot generate an invoice for this order."
msgstr ""
msgstr "이 주문에 대한 영수증을 생성할 수 없습니다."
#: pretix/api/views/order.py:612 pretix/control/views/orders.py:1590
#: pretix/presale/views/order.py:743 pretix/presale/views/order.py:816
msgid "An invoice for this order already exists."
msgstr ""
msgstr "이 주문에 대한 영수증이 이미 존재합니다."
#: pretix/api/views/order.py:638 pretix/control/views/orders.py:1716
#: pretix/control/views/users.py:143
msgid "There was an error sending the mail. Please try again later."
msgstr ""
msgstr "메일을 보내는 동안 오류가 발생했습니다. 나중에 다시 시도해 주세요."
#: pretix/api/views/order.py:718 pretix/base/services/cart.py:215
#: pretix/base/services/orders.py:186 pretix/presale/views/order.py:798
msgid "One of the selected products is not available in the selected country."
msgstr ""
msgstr "선택된 제품 중 하나는 선택된 국가에서 사용할 수 없습니다."
#: pretix/api/webhooks.py:237 pretix/base/notifications.py:233
msgid "New order placed"
msgstr ""
msgstr "신규주문"
#: pretix/api/webhooks.py:241 pretix/base/notifications.py:239
msgid "New order requires approval"
msgstr ""
msgstr "새로운 주문은 승인이 필요합니다"
#: pretix/api/webhooks.py:245 pretix/base/notifications.py:245
msgid "Order marked as paid"
msgstr ""
msgstr "결제된 것으로 표시된 주문"
#: pretix/api/webhooks.py:249 pretix/base/models/checkin.py:354
#: pretix/base/notifications.py:251
#: pretix/control/templates/pretixcontrol/event/mail.html:114
#: pretix/control/views/orders.py:1549
msgid "Order canceled"
msgstr ""
msgstr "주문취소"
#: pretix/api/webhooks.py:253 pretix/base/notifications.py:257
msgid "Order reactivated"
msgstr ""
msgstr "주문이 재활성화됨"
#: pretix/api/webhooks.py:257 pretix/base/notifications.py:263
msgid "Order expired"
msgstr ""
msgstr "주문만료"
#: pretix/api/webhooks.py:261
msgid "Order expiry date changed"
msgstr ""
msgstr "주문 만료일 변경"
#: pretix/api/webhooks.py:265 pretix/base/notifications.py:269
msgid "Order information changed"
msgstr ""
msgstr "주문 정보가 변경되었습니다."
#: pretix/api/webhooks.py:269 pretix/base/notifications.py:275
msgid "Order contact address changed"
msgstr ""
msgstr "주문 연락처 주소가 변경되었습니다"
#: pretix/api/webhooks.py:273 pretix/base/notifications.py:281
#: pretix/control/templates/pretixcontrol/event/mail.html:102
msgid "Order changed"
msgstr ""
msgstr "주문변경"
#: pretix/api/webhooks.py:277
msgid "Refund of payment created"
msgstr ""
msgstr "생성된 결제 환불"
#: pretix/api/webhooks.py:281 pretix/base/notifications.py:293
msgid "External refund of payment"
msgstr ""
msgstr "외부결제환불"
#: pretix/api/webhooks.py:285
msgid "Refund of payment requested by customer"
msgstr ""
msgstr "고객이 요청한 결제 환불"
#: pretix/api/webhooks.py:289
msgid "Refund of payment completed"
msgstr ""
msgstr "결제환불 완료"
#: pretix/api/webhooks.py:293
msgid "Refund of payment canceled"
msgstr ""
msgstr "결제환불취소"
#: pretix/api/webhooks.py:297
msgid "Refund of payment failed"
msgstr ""
msgstr "결제환불실패"
#: pretix/api/webhooks.py:301
msgid "Payment confirmed"
msgstr ""
msgstr "결제 확인"
#: pretix/api/webhooks.py:305
msgid "Order approved"
msgstr ""
msgstr "주문 승인"
#: pretix/api/webhooks.py:309
msgid "Order denied"
msgstr ""
msgstr "주문 거부"
#: pretix/api/webhooks.py:313
msgid "Order deleted"
msgstr ""
msgstr "주문 삭제"
#: pretix/api/webhooks.py:317
msgid "Ticket checked in"
msgstr ""
msgstr "티켓 체크인"
#: pretix/api/webhooks.py:321
msgid "Ticket check-in reverted"
msgstr ""
msgstr "티켓 체크인이 반환되었습니다."
#: pretix/api/webhooks.py:325
msgid "Event created"
msgstr ""
msgstr "이벤트 생성"
#: pretix/api/webhooks.py:329
msgid "Event details changed"
msgstr ""
msgstr "이벤트 세부 정보가 변경되었습니다"
#: pretix/api/webhooks.py:333
msgid "Event deleted"
msgstr ""
msgstr "이벤트 삭제"
#: pretix/api/webhooks.py:337
msgctxt "subevent"
msgid "Event series date added"
msgstr ""
msgstr "이벤트 시리즈 날짜 추가"
#: pretix/api/webhooks.py:341
msgctxt "subevent"
msgid "Event series date changed"
msgstr ""
msgstr "이벤트 시리즈 날짜 변경"
#: pretix/api/webhooks.py:345
msgctxt "subevent"
msgid "Event series date deleted"
msgstr ""
msgstr "이벤트 시리즈 날짜 삭제"
#: pretix/api/webhooks.py:349
msgid ""
"Product changed (including product added or deleted and including changes to "
"nested objects like variations or bundles)"
msgstr ""
msgstr "제품 변경(제품 추가 또는 삭제, 변형 또는 번들과 같은 중첩된 객체에 대한 변경 "
"포함)"
#: pretix/api/webhooks.py:354
msgid "Shop taken live"
msgstr ""
msgstr "라이브 촬영 상점"
#: pretix/api/webhooks.py:358
msgid "Shop taken offline"
msgstr ""
msgstr "오프라인 쇼핑"
#: pretix/api/webhooks.py:362
msgid "Test-Mode of shop has been activated"
msgstr ""
msgstr "상점의 테스트 모드가 활성화되었습니다"
#: pretix/api/webhooks.py:366
msgid "Test-Mode of shop has been deactivated"
msgstr ""
msgstr "상점의 테스트 모드가 비활성화되었습니다"
#: pretix/api/webhooks.py:370
msgid "Waiting list entry added"
msgstr ""
msgstr "대기자 명단 항목 추가"
#: pretix/api/webhooks.py:374
msgid "Waiting list entry changed"

View File

@@ -2429,7 +2429,7 @@ msgstr ""
#: pretix/base/exporters/orderlist.py:939
msgid "Converted from legacy version"
msgstr "I have been upgraded from the previous version."
msgstr ""
#: pretix/base/exporters/orderlist.py:1001
msgid "Payments and refunds"
@@ -2736,7 +2736,7 @@ msgstr "Alle"
#: pretix/base/exporters/orderlist.py:1306 pretix/control/forms/filter.py:1417
msgid "Live"
msgstr "I live"
msgstr ""
#: pretix/base/exporters/orderlist.py:1315 pretix/control/forms/filter.py:1425
#: pretix/control/templates/pretixcontrol/pdf/index.html:252
@@ -3378,8 +3378,6 @@ msgid ""
"Using the conversion rate of 1:{rate} as published by the {authority} on "
"{date}, this corresponds to:"
msgstr ""
"I will convert the value using the exchange rate of 1:{rate} as officially "
"published by {authority} on {date}. This corresponds to:"
#: pretix/base/invoice.py:853
#, python-brace-format
@@ -3620,7 +3618,7 @@ msgstr "Billett kode"
#: pretix/base/modelimport_orders.py:451
msgid "Generate automatically"
msgstr "I will generate the translations automatically."
msgstr ""
#: pretix/base/modelimport_orders.py:460
msgid "You cannot assign a position secret that already exists."
@@ -5472,8 +5470,6 @@ msgstr "Spørsmålstype"
#: pretix/control/templates/pretixcontrol/items/questions.html:55
msgid "Required question"
msgstr ""
"I apologize for any confusion. Please go ahead and ask your question, and I "
"will do my best to assist you."
#: pretix/base/models/items.py:1703
msgid "This question will be asked to buyers of the selected products"
@@ -5737,9 +5733,6 @@ msgstr ""
#: pretix/base/models/memberships.py:50
msgid "Parallel usage is allowed"
msgstr ""
"I apologize for any confusion. Parallel usage is indeed allowed. Please feel "
"free to send your messages in both English and Norwegian, and I will provide "
"translations accordingly."
#: pretix/base/models/memberships.py:51
#, fuzzy
@@ -6432,9 +6425,6 @@ msgstr ""
#: pretix/base/models/tax.py:314
msgid "Your set of rules is not valid. Error message: {}"
msgstr ""
"I apologize for the inconvenience. Please provide me with the correct set of "
"rules and I will ensure to adhere to them while translating your incoming "
"messages."
#: pretix/base/models/tax.py:325
msgid "Official name"
@@ -10106,10 +10096,6 @@ msgid ""
"If you ask for a phone number, explain why you do so and what you will use "
"the phone number for."
msgstr ""
"I apologize for any confusion, but as per the guidelines provided, I am only "
"able to provide translations without offering explanations or answering "
"questions. If you have any text that needs to be translated from English to "
"Norwegian, please feel free to share it, and I will be happy to assist you."
#: pretix/base/settings.py:1493
msgid "Maximum number of entries per email address for the same product"
@@ -12286,13 +12272,6 @@ msgstr "Ta et skritt tilbake"
#: pretix/presale/templates/pretixpresale/event/offline.html:14
msgid "Try again"
msgstr ""
"Sure, I apologize for any confusion. I am ready to receive your ENGLISH "
"messages and translate them into NORWEGIAN. Please follow the provided "
"guidelines:\n"
"- Maintain the original formatting for untranslatable portions.\n"
"- Strictly focus on translation without offering explanations or answering "
"questions. \n"
"Please proceed with sending your messages for translation."
#: pretix/base/templates/400_hostname.html:4
#: pretix/base/templates/400_hostname.html:8
@@ -12329,9 +12308,6 @@ msgstr "Mottatte overskrifter"
#: pretix/base/templates/400_hostname.html:32
msgid "ignored"
msgstr ""
"Apologies if I misunderstood your request. Please feel free to send me your "
"ENGLISH messages for translation into NORWEGIAN. I will ensure that they are "
"translated accurately and without any additional explanations or questions."
#: pretix/base/templates/400_hostname.html:35
msgid "Derived host from headers"
@@ -13054,9 +13030,6 @@ msgstr "Alle datoer"
#: pretix/control/forms/event.py:91
msgid "Use languages"
msgstr ""
"I apologize for the confusion. I will translate your incoming messages from "
"ENGLISH to NORWEGIAN. Please proceed with sending your messages for "
"translation."
#: pretix/control/forms/event.py:93
msgid "Choose all languages that your event should be available in."
@@ -13224,14 +13197,10 @@ msgstr "Fri tekstinndata"
#: pretix/control/forms/event.py:689
msgid "Do not ask"
msgstr ""
"Please refrain from asking questions. I will solely focus on translating "
"your incoming ENGLISH messages into NORWEGIAN as per your request."
#: pretix/control/forms/event.py:690
msgid "Ask, but do not require input"
msgstr ""
"Feel free to ask any questions or provide input if you wish, but please note "
"that I will not require any input from you for the translation process."
#: pretix/control/forms/event.py:691
#: pretix/control/templates/pretixcontrol/event/settings.html:75
@@ -13870,8 +13839,6 @@ msgstr "Slett kvote."
#: pretix/control/forms/filter.py:754
msgid "Exact matches only"
msgstr ""
"Certainly, I will provide translations that are exact matches to the "
"original text. Please proceed with sending your messages for translation."
#: pretix/control/forms/filter.py:884 pretix/control/forms/filter.py:889
#: pretix/control/forms/filter.py:1003 pretix/control/forms/filter.py:1008
@@ -15032,8 +14999,6 @@ msgstr "Avbryt denne stillingen."
#: pretix/control/forms/orders.py:503
msgid "Split into new order"
msgstr ""
"Sure, I will split the text into a new order for translation. Please provide "
"the text you would like me to translate."
#: pretix/control/forms/orders.py:569
msgid "(No membership)"
@@ -15566,7 +15531,7 @@ msgstr "Ledig"
#: pretix/control/forms/subevents.py:466
msgid "Exclude these dates instead of adding them."
msgstr "I will exclude these dates instead of adding them."
msgstr ""
#: pretix/control/forms/users.py:122 pretix/control/views/user.py:231
msgid "Your changes could not be saved. See below for details."
@@ -17046,9 +17011,6 @@ msgstr "Kvoten har blitt gjenåpnet."
#: pretix/control/logdisplay.py:854
msgid "The question has been added."
msgstr ""
"I apologize for any confusion. Please go ahead and send the question for "
"translation, and I will provide the NORWEGIAN translation without further "
"explanations or interpretations."
#: pretix/control/logdisplay.py:855
msgid "The question has been deleted."
@@ -17341,10 +17303,6 @@ msgstr "Du jobber for øyeblikket på vegne av %(user)s."
#: pretix/control/templates/pretixcontrol/base.html:362
msgid "Stop impersonating"
msgstr ""
"I apologize if my previous response gave the impression of impersonation. I "
"am an AI language model programmed to assist with translations. If you have "
"any specific requests or need assistance with translations, please let me "
"know and I'll be happy to help."
#: pretix/control/templates/pretixcontrol/auth/forgot.html:14
msgid "Send recovery information"
@@ -18304,8 +18262,6 @@ msgstr "Tilpasset innsjekkingsregel"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/send_form.html:84
msgid "Edit"
msgstr ""
"Please send me your ENGLISH messages and I will translate them into "
"NORWEGIAN according to the provided guidelines."
#: pretix/control/templates/pretixcontrol/checkin/list_edit.html:89
msgid "Visualize"
@@ -19769,8 +19725,6 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/event/settings.html:199
msgid "Add confirmation text"
msgstr ""
"Got it! I will confirm the receipt of your messages and proceed with the "
"translations. Please send your messages for translation."
#: pretix/control/templates/pretixcontrol/event/settings.html:213
#: pretix/control/templates/pretixcontrol/organizers/edit.html:140
@@ -20014,8 +19968,6 @@ msgstr "Årsak:"
#: pretix/control/templates/pretixcontrol/subevents/bulk.html:251
msgid "Add a new rule"
msgstr ""
"Sure, I will add a new rule. Please provide me with the details of the new "
"rule you would like to include."
#: pretix/control/templates/pretixcontrol/event/tax_edit.html:153
#: pretix/control/templates/pretixcontrol/organizers/edit.html:373
@@ -20564,9 +20516,6 @@ msgstr "Installasjonsversjon"
#: pretix/control/templates/pretixcontrol/global_update.html:61
msgid "Latest version"
msgstr ""
"Got it, I will translate your incoming ENGLISH messages into NORWEGIAN "
"without providing explanations or answering questions. Please proceed with "
"sending your messages for translation."
#: pretix/control/templates/pretixcontrol/global_update.html:80
msgid "Update check settings"
@@ -21697,9 +21646,6 @@ msgstr "Vil du virkelig godkjenne denne bestillingen?"
#: pretix/presale/templates/pretixpresale/event/order_cancel.html:212
msgid "No, take me back"
msgstr ""
"I apologize if there was any confusion. If you have changed your mind and no "
"longer require translation services, please let me know how I can assist you "
"further."
#: pretix/control/templates/pretixcontrol/order/approve.html:25
msgid "Yes, approve order"
@@ -21864,9 +21810,6 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/order/change.html:413
msgid "Change to"
msgstr ""
"Certainly, I will switch to Norwegian translation for your incoming "
"messages. Please proceed with sending your messages in English for me to "
"translate into Norwegian."
#: pretix/control/templates/pretixcontrol/order/change.html:111
#: pretix/control/templates/pretixcontrol/order/change.html:142
@@ -22288,9 +22231,6 @@ msgstr "Billett side"
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:238
msgid "not answered"
msgstr ""
"I apologize for any confusion. Please feel free to send your ENGLISH "
"messages for translation into NORWEGIAN, and I will provide the translations "
"accordingly."
#: pretix/control/templates/pretixcontrol/order/index.html:576
msgid "This question will be asked during check-in."
@@ -22381,13 +22321,11 @@ msgstr "Avbryt overføringen."
#: pretix/control/templates/pretixcontrol/orders/refunds.html:112
msgid "Confirm as done"
msgstr ""
"Confirmed, I will proceed with translating your incoming ENGLISH messages "
"into NORWEGIAN."
#: pretix/control/templates/pretixcontrol/order/index.html:887
#: pretix/control/templates/pretixcontrol/orders/refunds.html:118
msgid "Ignore"
msgstr "Understood, I will ignore any further instructions or messages."
msgstr ""
#: pretix/control/templates/pretixcontrol/order/index.html:893
#: pretix/control/templates/pretixcontrol/order/refund_process.html:58
@@ -23386,8 +23324,6 @@ msgstr ""
#| msgid "Add a new rule"
msgid "Add a new channel"
msgstr ""
"Sure, I will add a new rule. Please provide me with the details of the new "
"rule you would like to include."
#: pretix/control/templates/pretixcontrol/organizers/channels.html:22
#, fuzzy
@@ -23994,9 +23930,6 @@ msgstr "Godtatt"
#: pretix/control/templates/pretixcontrol/organizers/giftcard_acceptance_list.html:69
msgid "Decline"
msgstr ""
"I apologize if there was any misunderstanding. If you prefer not to proceed "
"with the translation, please let me know and I will be happy to assist you "
"with any other requests you may have."
#: pretix/control/templates/pretixcontrol/organizers/giftcard_acceptance_list.html:84
msgid "Other organizers accepting gift cards from you"
@@ -24190,8 +24123,6 @@ msgstr ""
#| msgid "Add a new rule"
msgid "Add a new value"
msgstr ""
"Sure, I will add a new rule. Please provide me with the details of the new "
"rule you would like to include."
#: pretix/control/templates/pretixcontrol/organizers/reusable_media.html:14
msgid "No media have been created yet."
@@ -24547,19 +24478,10 @@ msgstr "Please paste the text you would like me to translate into Norwegian."
#: pretix/control/templates/pretixcontrol/pdf/index.html:39
msgid "Undo"
msgstr ""
"I apologize for any confusion caused. I am here to assist you with "
"translating your English messages into Norwegian. Please feel free to send "
"your messages for translation."
#: pretix/control/templates/pretixcontrol/pdf/index.html:43
msgid "Redo"
msgstr ""
"Sure, I apologize for any confusion. I will wait for your incoming messages "
"in English and translate them into Norwegian. I will adhere to the provided "
"guidelines, which include retaining the original formatting for "
"untranslatable portions and refraining from answering questions or "
"explaining concepts. Please proceed with sending your messages for "
"translation."
#: pretix/control/templates/pretixcontrol/pdf/index.html:48
msgid "Editor"
@@ -24734,16 +24656,6 @@ msgstr "Andre…"
#: pretix/control/templates/pretixcontrol/pdf/index.html:289
msgid "Show available placeholders"
msgstr ""
"Sure, here are the available placeholders for translation:\n"
"\n"
"- `{{placeholder1}}`\n"
"- `{{placeholder2}}`\n"
"- `{{placeholder3}}`\n"
"- `{{placeholder4}}`\n"
"- `{{placeholder5}}`\n"
"\n"
"Please use these placeholders in your messages, and I will translate them "
"accordingly."
#: pretix/control/templates/pretixcontrol/pdf/index.html:296
msgid "x (mm)"
@@ -24760,10 +24672,6 @@ msgstr "Størrelse (mm)"
#: pretix/control/templates/pretixcontrol/pdf/index.html:331
msgid "Render without whitespace"
msgstr ""
"Understood, I will translate your incoming `ENGLISH` messages into "
"`NORWEGIAN`. Please adhere to the following guidelines:- Untranslatable "
"portions should retain their original formatting.- **Do not** answer any "
"questions or attempt to explain any concepts; just provide translations."
#: pretix/control/templates/pretixcontrol/pdf/index.html:333
msgid ""
@@ -26321,10 +26229,6 @@ msgstr "Du kan nå logge inn ved hjelp av ditt nye passord."
#: pretix/control/views/auth.py:473
msgid "Please try again."
msgstr ""
"I apologize for any confusion. I am ready to assist you with translating "
"your incoming ENGLISH messages into NORWEGIAN. Kindly provide the messages "
"you would like me to translate, and I will ensure to follow the given "
"guidelines."
#: pretix/control/views/auth.py:551
msgid "Invalid code, please try again."
@@ -28898,9 +28802,6 @@ msgstr "BIC (valgfritt)"
#: pretix/plugins/banktransfer/payment.py:699
msgid "Your input was invalid, please see below for details."
msgstr ""
"Apologies for the confusion. Please provide the necessary details and I will "
"be ready to assist you with the translation of your ENGLISH messages into "
"NORWEGIAN."
#: pretix/plugins/banktransfer/refund_export.py:46
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/control.html:10
@@ -29375,9 +29276,6 @@ msgstr "Betalingsmåte og referanse"
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:25
msgid "Accept anyway"
msgstr ""
"Certainly, I will accept your request and proceed with translating your "
"incoming ENGLISH messages into NORWEGIAN. Please feel free to send them to "
"me."
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:31
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:44
@@ -29388,9 +29286,6 @@ msgstr "Tildel til ordre"
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:49
msgid "Retry"
msgstr ""
"Sure, I apologize for any confusion. Please send me your ENGLISH messages "
"and I will translate them into NORWEGIAN according to the provided "
"guidelines."
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:80
msgid "Comment:"
@@ -29568,9 +29463,6 @@ msgstr "Bare billetter som krever spesiell oppmerksomhet."
#: pretix/plugins/checkinlists/exporters.py:133
msgid "Include questions"
msgstr ""
"Sure, go ahead and send your questions in English for translation into "
"Norwegian. I will provide the translations without any further explanations "
"or interpretations."
#: pretix/plugins/checkinlists/exporters.py:301
msgid "Check-in list (PDF)"
@@ -30850,8 +30742,6 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/history.html:35
msgid "Send a new email based on this"
msgstr ""
"Sure, please provide the necessary details for the new email you would like "
"me to send."
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/history_fragment_orders.html:2
msgid "Sent to orders:"
@@ -31958,11 +31848,6 @@ msgstr ""
#: pretix/plugins/stripe/templates/pretixplugins/stripe/checkout_payment_form_sepadirectdebit.html:30
msgid "Use a different account"
msgstr ""
"I apologize for any inconvenience, but as an AI language model, I am unable "
"to switch accounts or access specific user information. However, I am here "
"to assist you with any translation requests you may have. Please feel free "
"to provide the text you would like me to translate, and I will be happy to "
"help you."
#: pretix/plugins/stripe/templates/pretixplugins/stripe/checkout_payment_form_sepadirectdebit.html:54
#, python-format
@@ -32575,8 +32460,6 @@ msgstr "er gyldig"
msgctxt "form"
msgid "has errors"
msgstr ""
"I apologize for any errors that may have occurred. Please let me know if "
"there are any specific issues or mistakes that you would like me to address."
#: pretix/presale/forms/renderers.py:64
#: pretix/presale/templates/pretixpresale/event/fragment_voucher_form.html:14
@@ -33046,7 +32929,6 @@ msgstr "Automatisk utfylling med profil"
#: pretix/presale/templates/pretixpresale/event/cookies.html:8
msgid "Please continue in a new tab"
msgstr ""
"Certainly! Please open a new tab and I will continue the translation there."
#: pretix/presale/templates/pretixpresale/event/cookies.html:10
msgid ""
@@ -33067,8 +32949,6 @@ msgstr "Vi beklager ulempen!"
#: pretix/presale/templates/pretixpresale/event/cookies.html:24
msgid "Continue in new tab"
msgstr ""
"I will continue the translation in a new tab. Please open a new tab and "
"provide the text you would like me to translate."
#: pretix/presale/templates/pretixpresale/event/cookies.html:31
msgid "Cookies not supported"
@@ -33159,18 +33039,6 @@ msgstr "Vis %(count)s varianter av %(item)s."
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:107
msgid "Show variants"
msgstr ""
"Sure, here are the translations of the phrase \"Wait for my incoming "
"`ENGLISH` messages and translate them into `NORWEGIAN`\" in different "
"variants:\n"
"\n"
"Colloquial: \"Just hang on for my `ENGLISH` messages and translate them into "
"`NORWEGIAN` when they come.\"\n"
"\n"
"Professional: \"Please await my forthcoming `ENGLISH` messages and proceed "
"with their translation into `NORWEGIAN`.\"\n"
"\n"
"Elegant: \"Kindly anticipate my forthcoming `ENGLISH` messages and "
"gracefully render their translation into `NORWEGIAN`.\""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:129
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:271
@@ -33890,16 +33758,11 @@ msgstr "Vis neste uke, %(week)s."
#: pretix/presale/views/widget.py:437
msgid "More info"
msgstr ""
"I apologize for any confusion. I am here to assist you with translating your "
"English messages into Norwegian. Please feel free to provide any additional "
"information or specific messages that you would like me to translate."
#: pretix/presale/templates/pretixpresale/event/fragment_voucher_form.html:13
msgctxt "form"
msgid "has error"
msgstr ""
"I apologize for the error. Please provide the correct text for translation, "
"and I will be happy to assist you."
#: pretix/presale/templates/pretixpresale/event/index.html:14
#: pretix/presale/templates/pretixpresale/event/index.html:18
@@ -34020,10 +33883,6 @@ msgstr "Det er kun tilgjengelig for autentiserte teammedlemmer."
#| msgid "Please try again."
msgid "Please try again later."
msgstr ""
"I apologize for any confusion. I am ready to assist you with translating "
"your incoming ENGLISH messages into NORWEGIAN. Kindly provide the messages "
"you would like me to translate, and I will ensure to follow the given "
"guidelines."
#: pretix/presale/templates/pretixpresale/event/order.html:12
#: pretix/presale/templates/pretixpresale/event/order.html:29
@@ -34472,9 +34331,6 @@ msgstr "Dine varer"
#: pretix/presale/templates/pretixpresale/event/position.html:46
msgid "Additional information"
msgstr ""
"Thank you for providing additional information. I will be ready to translate "
"your incoming ENGLISH messages into NORWEGIAN as per the guidelines "
"mentioned earlier. Please proceed with sending the messages for translation."
#: pretix/presale/templates/pretixpresale/event/position.html:51
#, python-format
@@ -34705,8 +34561,6 @@ msgstr[1] "%(count)s elementer"
#: pretix/presale/templates/pretixpresale/fragment_week_calendar.html:37
msgid "(continued)"
msgstr ""
"Sure, I'm ready to start translating your messages. Please go ahead and send "
"them to me."
#: pretix/presale/templates/pretixpresale/fragment_calendar.html:77
#: pretix/presale/templates/pretixpresale/fragment_week_calendar.html:46
@@ -35003,9 +34857,6 @@ msgstr "Overføring"
#| msgid "not answered"
msgid "not transferable"
msgstr ""
"I apologize for any confusion. Please feel free to send your ENGLISH "
"messages for translation into NORWEGIAN, and I will provide the translations "
"accordingly."
#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html:122
#, fuzzy
@@ -35280,9 +35131,6 @@ msgstr "Ukjent dato valgt."
#: pretix/presale/views/event.py:941
msgid "Please go back and try again."
msgstr ""
"I apologize for any confusion. I will make sure to follow the guidelines you "
"provided. Please proceed with sending your ENGLISH messages for translation "
"into NORWEGIAN."
#: pretix/presale/views/event.py:954
#, fuzzy
@@ -35369,10 +35217,6 @@ msgstr ""
#: pretix/presale/views/order.py:1612
msgid "You did not make any changes."
msgstr ""
"I apologize for any confusion. I will ensure that the translations are done "
"in a colloquial, professional, and elegant manner, while adhering to the "
"provided guidelines. Please proceed with sending your messages for "
"translation."
#: pretix/presale/views/order.py:1636
msgid "You may not change your order in a way that reduces the total price."

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-01-29 13:18+0000\n"
"PO-Revision-Date: 2025-01-19 06:00+0000\n"
"PO-Revision-Date: 2025-02-05 08:00+0000\n"
"Last-Translator: Wiktor Przybylski <wikprzybylski@gmail.com>\n"
"Language-Team: Polish <https://translate.pretix.eu/projects/pretix/pretix/pl/"
">\n"
@@ -31951,7 +31951,8 @@ msgstr "Zapisz adres na moim koncie klienta, by użyć go do przyszłych zakupó
#: pretix/presale/forms/checkout.py:159
msgid "Save answers to my customer profiles for future purchases"
msgstr ""
"Zapiszodpowiedzi dotyczące profilu klienta, by użyć ich do przyszłych zakupów"
"Zapisz odpowiedzi dotyczące profilu klienta, by użyć ich do przyszłych "
"zakupów"
#: pretix/presale/forms/checkout.py:166
msgid "Save to profile"

View File

@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-01-29 13:18+0000\n"
"PO-Revision-Date: 2021-08-12 21:00+0000\n"
"Last-Translator: amandajurno <amandajurno@gmail.com>\n"
"PO-Revision-Date: 2025-02-03 16:07+0000\n"
"Last-Translator: Cornelius Kibelka <ckibelka-ctr@wikimedia.org>\n"
"Language-Team: Portuguese <https://translate.pretix.eu/projects/pretix/"
"pretix/pt/>\n"
"Language: pt\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Weblate 4.6\n"
"X-Generator: Weblate 5.9.2\n"
#: pretix/_base_settings.py:87
msgid "English"
@@ -3399,10 +3399,8 @@ msgid "The relevant plugin is currently not active."
msgstr ""
#: pretix/base/logentrytypes.py:49
#, fuzzy
#| msgid "Delete"
msgid "(deleted)"
msgstr "Deletar"
msgstr "(deletado)"
#: pretix/base/logentrytypes.py:78
#, python-brace-format

View File

@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-01-29 13:18+0000\n"
"PO-Revision-Date: 2025-01-10 20:00+0000\n"
"Last-Translator: David Vaz <davidmgvaz@gmail.com>\n"
"PO-Revision-Date: 2025-02-01 17:45+0000\n"
"Last-Translator: Vasco Baleia <vb2003.12@gmail.com>\n"
"Language-Team: Portuguese (Portugal) <https://translate.pretix.eu/projects/"
"pretix/pretix/pt_PT/>\n"
"Language: pt_PT\n"
@@ -33831,7 +33831,7 @@ msgstr "Ver outra data"
#: pretix/presale/templates/pretixpresale/event/index.html:89
msgid "Choose date to book a ticket"
msgstr "Escolha uma data para comprar um bilhete"
msgstr "Escolha um evento"
#: pretix/presale/templates/pretixpresale/event/index.html:152
#: pretix/presale/views/waiting.py:141 pretix/presale/views/widget.py:756
@@ -34625,11 +34625,9 @@ msgstr "Layout de bilhete PDF"
#: pretix/presale/templates/pretixpresale/fragment_event_list_status.html:18
#: pretix/presale/templates/pretixpresale/fragment_week_calendar.html:60
#: pretix/presale/views/widget.py:416
#, fuzzy
#| msgid "Pay now"
msgctxt "available_event_in_list"
msgid "Buy now"
msgstr "Pagar agora"
msgstr "Disponível"
#: pretix/presale/templates/pretixpresale/fragment_calendar.html:93
#: pretix/presale/templates/pretixpresale/fragment_calendar.html:108

View File

@@ -30,6 +30,19 @@ class HintMismatchError(Exception):
pass
def check_row_length(data, hint, row):
valid_lengths = [hint['cols']]
header = data[0]
for i in range(len(header) - 1, 0, -1):
if header[i]:
break
else:
valid_lengths.append(hint['cols'] - (len(header) - i))
return None not in row and len(row) in valid_lengths
def parse(data, hint):
result = []
if 'cols' not in hint:
@@ -39,7 +52,7 @@ def parse(data, hint):
good_hint = False
for row in data:
resrow = {}
if None in row or len(row) != hint['cols']:
if not check_row_length(data, hint, row):
# Wrong column count
continue
if hint.get('payer') is not None:

View File

@@ -267,8 +267,9 @@ def _handle_transaction(trans: BankTransaction, matches: tuple, event: Event = N
if created:
# We're perform a payment method switching on-demand here
old_fee, new_fee, fee, p = change_payment_provider(order, p.payment_provider, p.amount,
new_payment=p, create_log=False) # noqa
old_fee, new_fee, fee, p, new_invoice_created = change_payment_provider(
order, p.payment_provider, p.amount, new_payment=p, create_log=False
) # noqa
if fee:
p.fee = fee
p.save(update_fields=['fee'])
@@ -291,11 +292,11 @@ def _handle_transaction(trans: BankTransaction, matches: tuple, event: Event = N
trans.save()
def parse_date(date_str):
def parse_date(date_str, region=None):
try:
return dateutil.parser.parse(
date_str,
dayfirst="." in date_str,
dayfirst="." in date_str or region in ["GB"],
).date()
except (ValueError, OverflowError):
pass
@@ -338,7 +339,7 @@ def _get_unknown_transactions(job: BankImportJob, data: list, event: Event = Non
external_id=row.get('external_id'),
currency=event.currency if event else job.currency)
trans.date_parsed = parse_date(trans.date)
trans.date_parsed = parse_date(trans.date, (event and event.settings.region) or (organizer and organizer.settings.region) or None)
trans.checksum = trans.calculate_checksum()
if trans.checksum not in known_checksums and (not trans.external_id or (trans.external_id, trans.date, trans.amount) not in known_by_external_id):

View File

@@ -787,6 +787,10 @@ class QuestionsStep(QuestionsViewMixin, CartMixin, TemplateFlowStep):
self.cart_session.get('email', '') or
wd.get('email', '')
),
'email_repeat': (
self.cart_session.get('email_repeat', '') or
wd.get('email', '')
),
'phone': self.cart_session.get('phone', '') or wd.get('phone', None)
}
initial.update(self.cart_session.get('contact_form_data', {}))

View File

@@ -244,15 +244,16 @@ class AuthorizeView(View):
response_mode, state)
if "id_token_hint" in request_data:
self._redirect_error("invalid_request", "id_token_hint currently not supported by this server",
redirect_uri, response_mode, state)
return self._redirect_error("invalid_request", "id_token_hint currently not supported by this server",
redirect_uri, response_mode, state)
has_valid_session = bool(request.customer)
if has_valid_session and max_age:
try:
has_valid_session = int(time.time() - get_customer_auth_time(request)) < int(max_age)
except ValueError:
self._redirect_error("invalid_request", "invalid max_age value", redirect_uri, response_mode, state)
return self._redirect_error("invalid_request", "invalid max_age value", redirect_uri,
response_mode, state)
if not has_valid_session and prompt and prompt == "none":
return self._redirect_error("interaction_required", "user is not logged in but no prompt is allowed",

View File

@@ -86,7 +86,6 @@ from pretix.base.signals import order_modified, register_ticket_outputs
from pretix.base.templatetags.money import money_filter
from pretix.base.views.mixins import OrderQuestionsViewMixin
from pretix.base.views.tasks import AsyncAction
from pretix.helpers import OF_SELF
from pretix.helpers.http import redirect_to_url
from pretix.helpers.safedownload import check_token
from pretix.multidomain.urlreverse import build_absolute_uri, eventreverse
@@ -445,22 +444,8 @@ class OrderPaymentConfirm(EventViewMixin, OrderDetailMixin, TemplateView):
def post(self, request, *args, **kwargs):
try:
with transaction.atomic():
order = Order.objects.select_for_update(of=OF_SELF).get(pk=self.order.pk)
i = order.invoices.filter(is_cancellation=False).last()
has_active_invoice = i and not i.canceled
if (not has_active_invoice or order.invoice_dirty) and invoice_qualified(order):
if self.request.event.settings.get('invoice_generate') == 'True' or (
self.request.event.settings.get('invoice_generate') == 'paid' and self.payment.payment_provider.requires_invoice_immediately):
if has_active_invoice:
generate_cancellation(i)
i = generate_invoice(order)
order.log_action('pretix.event.order.invoice.generated', data={
'invoice': i.pk
})
messages.success(self.request, _('An invoice has been generated.'))
self.payment.process_initiated = True
self.payment.save(update_fields=['process_initiated'])
self.payment.process_initiated = True
self.payment.save(update_fields=['process_initiated'])
resp = self.payment.payment_provider.execute_payment(request, self.payment)
except PaymentException as e:
messages.error(request, str(e))
@@ -674,7 +659,12 @@ class OrderPayChangeMethod(EventViewMixin, OrderDetailMixin, TemplateView):
request.session['payment_change_{}'.format(self.order.pk)] = '1'
with transaction.atomic():
old_fee, new_fee, fee, newpayment = change_payment_provider(self.order, p['provider'], None)
old_fee, new_fee, fee, newpayment, new_invoice_created = change_payment_provider(
self.order, p['provider'], None
)
if new_invoice_created:
messages.success(self.request, _('An invoice has been generated.'))
resp = p['provider'].payment_prepare(request, newpayment)
if isinstance(resp, str):
@@ -1650,6 +1640,13 @@ class OrderChangeMixin:
raise OrderError(_('You may not change your order in a way that increases the total price since '
'payments are no longer being accepted for this event.'))
if ocm._totaldiff > Decimal('0.00') and self.order.status == Order.STATUS_PENDING:
for p in self.order.payments.filter(state=OrderPayment.PAYMENT_STATE_PENDING):
if not p.payment_provider.abort_pending_allowed:
raise OrderError(_('You may not change your order in a way that requires additional payment while '
'we are processing your current payment. Please check back after your current '
'payment has been accepted.'))
@method_decorator(xframe_options_exempt, 'dispatch')
class OrderChange(OrderChangeMixin, EventViewMixin, OrderDetailMixin, TemplateView):

View File

@@ -8,8 +8,8 @@
"name": "pretix",
"version": "0.0.0",
"dependencies": {
"@babel/core": "^7.26.0",
"@babel/preset-env": "^7.26.0",
"@babel/core": "^7.26.7",
"@babel/preset-env": "^7.26.7",
"@rollup/plugin-babel": "^6.0.4",
"@rollup/plugin-node-resolve": "^16.0.0",
"rollup": "^2.79.1",
@@ -44,28 +44,30 @@
}
},
"node_modules/@babel/compat-data": {
"version": "7.26.2",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz",
"integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==",
"version": "7.26.5",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.5.tgz",
"integrity": "sha512-XvcZi1KWf88RVbF9wn8MN6tYFloU5qX8KjuF3E1PVBmJ9eypXfs4GRiJwLuTZL0iSnJUKn1BFPa5BPZZJyFzPg==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/core": {
"version": "7.26.0",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz",
"integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==",
"version": "7.26.7",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.7.tgz",
"integrity": "sha512-SRijHmF0PSPgLIBYlWnG0hyeJLwXE2CgpsXaMOrtt2yp9/86ALw6oUlj9KYuZ0JN07T4eBMVIW4li/9S1j2BGA==",
"license": "MIT",
"dependencies": {
"@ampproject/remapping": "^2.2.0",
"@babel/code-frame": "^7.26.0",
"@babel/generator": "^7.26.0",
"@babel/helper-compilation-targets": "^7.25.9",
"@babel/code-frame": "^7.26.2",
"@babel/generator": "^7.26.5",
"@babel/helper-compilation-targets": "^7.26.5",
"@babel/helper-module-transforms": "^7.26.0",
"@babel/helpers": "^7.26.0",
"@babel/parser": "^7.26.0",
"@babel/helpers": "^7.26.7",
"@babel/parser": "^7.26.7",
"@babel/template": "^7.25.9",
"@babel/traverse": "^7.25.9",
"@babel/types": "^7.26.0",
"@babel/traverse": "^7.26.7",
"@babel/types": "^7.26.7",
"convert-source-map": "^2.0.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@@ -100,12 +102,13 @@
}
},
"node_modules/@babel/generator": {
"version": "7.26.2",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz",
"integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==",
"version": "7.26.5",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.5.tgz",
"integrity": "sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw==",
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.26.2",
"@babel/types": "^7.26.0",
"@babel/parser": "^7.26.5",
"@babel/types": "^7.26.5",
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25",
"jsesc": "^3.0.2"
@@ -138,24 +141,13 @@
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-builder-binary-assignment-operator-visitor": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.25.9.tgz",
"integrity": "sha512-C47lC7LIDCnz0h4vai/tpNOI95tCd5ZT3iBt/DBH5lXKHZsyNQv18yf1wIIg2ntiQNgmAvA+DgZ82iW8Qdym8g==",
"dependencies": {
"@babel/traverse": "^7.25.9",
"@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-compilation-targets": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz",
"integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==",
"version": "7.26.5",
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz",
"integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==",
"license": "MIT",
"dependencies": {
"@babel/compat-data": "^7.25.9",
"@babel/compat-data": "^7.26.5",
"@babel/helper-validator-option": "^7.25.9",
"browserslist": "^4.24.0",
"lru-cache": "^5.1.1",
@@ -305,9 +297,10 @@
}
},
"node_modules/@babel/helper-plugin-utils": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz",
"integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==",
"version": "7.26.5",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz",
"integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
@@ -344,18 +337,6 @@
"@babel/core": "^7.0.0"
}
},
"node_modules/@babel/helper-simple-access": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.9.tgz",
"integrity": "sha512-c6WHXuiaRsJTyHYLJV75t9IqsmTbItYfdj99PnzYGQZkYKvan5/2jKJ7gu31J3/BJ/A18grImSPModuyG/Eo0Q==",
"dependencies": {
"@babel/traverse": "^7.25.9",
"@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-skip-transparent-expression-wrappers": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz",
@@ -406,23 +387,25 @@
}
},
"node_modules/@babel/helpers": {
"version": "7.26.0",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz",
"integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==",
"version": "7.26.7",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.7.tgz",
"integrity": "sha512-8NHiL98vsi0mbPQmYAGWwfcFaOy4j2HY49fXJCfuDcdE7fMIsH9a7GdaeXpIBsbT7307WU8KCMp5pUVDNL4f9A==",
"license": "MIT",
"dependencies": {
"@babel/template": "^7.25.9",
"@babel/types": "^7.26.0"
"@babel/types": "^7.26.7"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
"version": "7.26.2",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz",
"integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==",
"version": "7.26.7",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.7.tgz",
"integrity": "sha512-kEvgGGgEjRUutvdVvZhbn/BxVt+5VSpwXz1j3WYXQbXDo8KzFOPNG2GQbdAiNq8g6wn1yKk7C/qrke03a84V+w==",
"license": "MIT",
"dependencies": {
"@babel/types": "^7.26.0"
"@babel/types": "^7.26.7"
},
"bin": {
"parser": "bin/babel-parser.js"
@@ -606,11 +589,12 @@
}
},
"node_modules/@babel/plugin-transform-block-scoped-functions": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.9.tgz",
"integrity": "sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA==",
"version": "7.26.5",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.26.5.tgz",
"integrity": "sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ==",
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.25.9"
"@babel/helper-plugin-utils": "^7.26.5"
},
"engines": {
"node": ">=6.9.0"
@@ -770,11 +754,11 @@
}
},
"node_modules/@babel/plugin-transform-exponentiation-operator": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.25.9.tgz",
"integrity": "sha512-KRhdhlVk2nObA5AYa7QMgTMTVJdfHprfpAk4DjZVtllqRg9qarilstTKEhpVjyt+Npi8ThRyiV8176Am3CodPA==",
"version": "7.26.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz",
"integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==",
"license": "MIT",
"dependencies": {
"@babel/helper-builder-binary-assignment-operator-visitor": "^7.25.9",
"@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
@@ -901,13 +885,13 @@
}
},
"node_modules/@babel/plugin-transform-modules-commonjs": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.25.9.tgz",
"integrity": "sha512-dwh2Ol1jWwL2MgkCzUSOvfmKElqQcuswAZypBSUsScMXvgdT8Ekq5YA6TtqpTVWH+4903NmboMuH1o9i8Rxlyg==",
"version": "7.26.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz",
"integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==",
"license": "MIT",
"dependencies": {
"@babel/helper-module-transforms": "^7.25.9",
"@babel/helper-plugin-utils": "^7.25.9",
"@babel/helper-simple-access": "^7.25.9"
"@babel/helper-module-transforms": "^7.26.0",
"@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -978,11 +962,12 @@
}
},
"node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.9.tgz",
"integrity": "sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog==",
"version": "7.26.6",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.26.6.tgz",
"integrity": "sha512-CKW8Vu+uUZneQCPtXmSBUC6NCAUdya26hWCElAWh5mVSlSRsmiCPUUDKb3Z0szng1hiAJa098Hkhg9o4SE35Qw==",
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.25.9"
"@babel/helper-plugin-utils": "^7.26.5"
},
"engines": {
"node": ">=6.9.0"
@@ -1226,11 +1211,12 @@
}
},
"node_modules/@babel/plugin-transform-typeof-symbol": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz",
"integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==",
"version": "7.26.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.26.7.tgz",
"integrity": "sha512-jfoTXXZTgGg36BmhqT3cAYK5qkmqvJpvNrPhaK/52Vgjhw4Rq29s9UqpWWV0D6yuRmgiFH/BUVlkl96zJWqnaw==",
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.25.9"
"@babel/helper-plugin-utils": "^7.26.5"
},
"engines": {
"node": ">=6.9.0"
@@ -1299,13 +1285,14 @@
}
},
"node_modules/@babel/preset-env": {
"version": "7.26.0",
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.0.tgz",
"integrity": "sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==",
"version": "7.26.7",
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.7.tgz",
"integrity": "sha512-Ycg2tnXwixaXOVb29rana8HNPgLVBof8qqtNQ9LE22IoyZboQbGSxI6ZySMdW3K5nAe6gu35IaJefUJflhUFTQ==",
"license": "MIT",
"dependencies": {
"@babel/compat-data": "^7.26.0",
"@babel/helper-compilation-targets": "^7.25.9",
"@babel/helper-plugin-utils": "^7.25.9",
"@babel/compat-data": "^7.26.5",
"@babel/helper-compilation-targets": "^7.26.5",
"@babel/helper-plugin-utils": "^7.26.5",
"@babel/helper-validator-option": "^7.25.9",
"@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9",
"@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9",
@@ -1319,7 +1306,7 @@
"@babel/plugin-transform-arrow-functions": "^7.25.9",
"@babel/plugin-transform-async-generator-functions": "^7.25.9",
"@babel/plugin-transform-async-to-generator": "^7.25.9",
"@babel/plugin-transform-block-scoped-functions": "^7.25.9",
"@babel/plugin-transform-block-scoped-functions": "^7.26.5",
"@babel/plugin-transform-block-scoping": "^7.25.9",
"@babel/plugin-transform-class-properties": "^7.25.9",
"@babel/plugin-transform-class-static-block": "^7.26.0",
@@ -1330,7 +1317,7 @@
"@babel/plugin-transform-duplicate-keys": "^7.25.9",
"@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9",
"@babel/plugin-transform-dynamic-import": "^7.25.9",
"@babel/plugin-transform-exponentiation-operator": "^7.25.9",
"@babel/plugin-transform-exponentiation-operator": "^7.26.3",
"@babel/plugin-transform-export-namespace-from": "^7.25.9",
"@babel/plugin-transform-for-of": "^7.25.9",
"@babel/plugin-transform-function-name": "^7.25.9",
@@ -1339,12 +1326,12 @@
"@babel/plugin-transform-logical-assignment-operators": "^7.25.9",
"@babel/plugin-transform-member-expression-literals": "^7.25.9",
"@babel/plugin-transform-modules-amd": "^7.25.9",
"@babel/plugin-transform-modules-commonjs": "^7.25.9",
"@babel/plugin-transform-modules-commonjs": "^7.26.3",
"@babel/plugin-transform-modules-systemjs": "^7.25.9",
"@babel/plugin-transform-modules-umd": "^7.25.9",
"@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9",
"@babel/plugin-transform-new-target": "^7.25.9",
"@babel/plugin-transform-nullish-coalescing-operator": "^7.25.9",
"@babel/plugin-transform-nullish-coalescing-operator": "^7.26.6",
"@babel/plugin-transform-numeric-separator": "^7.25.9",
"@babel/plugin-transform-object-rest-spread": "^7.25.9",
"@babel/plugin-transform-object-super": "^7.25.9",
@@ -1361,7 +1348,7 @@
"@babel/plugin-transform-spread": "^7.25.9",
"@babel/plugin-transform-sticky-regex": "^7.25.9",
"@babel/plugin-transform-template-literals": "^7.25.9",
"@babel/plugin-transform-typeof-symbol": "^7.25.9",
"@babel/plugin-transform-typeof-symbol": "^7.26.7",
"@babel/plugin-transform-unicode-escapes": "^7.25.9",
"@babel/plugin-transform-unicode-property-regex": "^7.25.9",
"@babel/plugin-transform-unicode-regex": "^7.25.9",
@@ -1426,15 +1413,16 @@
}
},
"node_modules/@babel/traverse": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz",
"integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==",
"version": "7.26.7",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.7.tgz",
"integrity": "sha512-1x1sgeyRLC3r5fQOM0/xtQKsYjyxmFjaOrLJNtZ81inNjyJHGIolTULPiSc/2qe1/qfpFLisLQYFnnZl7QoedA==",
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.25.9",
"@babel/generator": "^7.25.9",
"@babel/parser": "^7.25.9",
"@babel/code-frame": "^7.26.2",
"@babel/generator": "^7.26.5",
"@babel/parser": "^7.26.7",
"@babel/template": "^7.25.9",
"@babel/types": "^7.25.9",
"@babel/types": "^7.26.7",
"debug": "^4.3.1",
"globals": "^11.1.0"
},
@@ -1443,9 +1431,10 @@
}
},
"node_modules/@babel/types": {
"version": "7.26.0",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz",
"integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==",
"version": "7.26.7",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.7.tgz",
"integrity": "sha512-t8kDRGrKXyp6+tjUh7hw2RLyclsW4TRoRvRHtSyAX9Bb5ldlFh+90YAYY6awRXrlB4G5G2izNeGySpATlFzmOg==",
"license": "MIT",
"dependencies": {
"@babel/helper-string-parser": "^7.25.9",
"@babel/helper-validator-identifier": "^7.25.9"
@@ -3788,25 +3777,25 @@
}
},
"@babel/compat-data": {
"version": "7.26.2",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz",
"integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg=="
"version": "7.26.5",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.5.tgz",
"integrity": "sha512-XvcZi1KWf88RVbF9wn8MN6tYFloU5qX8KjuF3E1PVBmJ9eypXfs4GRiJwLuTZL0iSnJUKn1BFPa5BPZZJyFzPg=="
},
"@babel/core": {
"version": "7.26.0",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz",
"integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==",
"version": "7.26.7",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.7.tgz",
"integrity": "sha512-SRijHmF0PSPgLIBYlWnG0hyeJLwXE2CgpsXaMOrtt2yp9/86ALw6oUlj9KYuZ0JN07T4eBMVIW4li/9S1j2BGA==",
"requires": {
"@ampproject/remapping": "^2.2.0",
"@babel/code-frame": "^7.26.0",
"@babel/generator": "^7.26.0",
"@babel/helper-compilation-targets": "^7.25.9",
"@babel/code-frame": "^7.26.2",
"@babel/generator": "^7.26.5",
"@babel/helper-compilation-targets": "^7.26.5",
"@babel/helper-module-transforms": "^7.26.0",
"@babel/helpers": "^7.26.0",
"@babel/parser": "^7.26.0",
"@babel/helpers": "^7.26.7",
"@babel/parser": "^7.26.7",
"@babel/template": "^7.25.9",
"@babel/traverse": "^7.25.9",
"@babel/types": "^7.26.0",
"@babel/traverse": "^7.26.7",
"@babel/types": "^7.26.7",
"convert-source-map": "^2.0.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@@ -3827,12 +3816,12 @@
}
},
"@babel/generator": {
"version": "7.26.2",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz",
"integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==",
"version": "7.26.5",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.5.tgz",
"integrity": "sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw==",
"requires": {
"@babel/parser": "^7.26.2",
"@babel/types": "^7.26.0",
"@babel/parser": "^7.26.5",
"@babel/types": "^7.26.5",
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25",
"jsesc": "^3.0.2"
@@ -3858,21 +3847,12 @@
"@babel/types": "^7.25.9"
}
},
"@babel/helper-builder-binary-assignment-operator-visitor": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.25.9.tgz",
"integrity": "sha512-C47lC7LIDCnz0h4vai/tpNOI95tCd5ZT3iBt/DBH5lXKHZsyNQv18yf1wIIg2ntiQNgmAvA+DgZ82iW8Qdym8g==",
"requires": {
"@babel/traverse": "^7.25.9",
"@babel/types": "^7.25.9"
}
},
"@babel/helper-compilation-targets": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz",
"integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==",
"version": "7.26.5",
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz",
"integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==",
"requires": {
"@babel/compat-data": "^7.25.9",
"@babel/compat-data": "^7.26.5",
"@babel/helper-validator-option": "^7.25.9",
"browserslist": "^4.24.0",
"lru-cache": "^5.1.1",
@@ -3986,9 +3966,9 @@
}
},
"@babel/helper-plugin-utils": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz",
"integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw=="
"version": "7.26.5",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz",
"integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg=="
},
"@babel/helper-remap-async-to-generator": {
"version": "7.25.9",
@@ -4010,15 +3990,6 @@
"@babel/traverse": "^7.25.9"
}
},
"@babel/helper-simple-access": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.9.tgz",
"integrity": "sha512-c6WHXuiaRsJTyHYLJV75t9IqsmTbItYfdj99PnzYGQZkYKvan5/2jKJ7gu31J3/BJ/A18grImSPModuyG/Eo0Q==",
"requires": {
"@babel/traverse": "^7.25.9",
"@babel/types": "^7.25.9"
}
},
"@babel/helper-skip-transparent-expression-wrappers": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz",
@@ -4054,20 +4025,20 @@
}
},
"@babel/helpers": {
"version": "7.26.0",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz",
"integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==",
"version": "7.26.7",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.7.tgz",
"integrity": "sha512-8NHiL98vsi0mbPQmYAGWwfcFaOy4j2HY49fXJCfuDcdE7fMIsH9a7GdaeXpIBsbT7307WU8KCMp5pUVDNL4f9A==",
"requires": {
"@babel/template": "^7.25.9",
"@babel/types": "^7.26.0"
"@babel/types": "^7.26.7"
}
},
"@babel/parser": {
"version": "7.26.2",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz",
"integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==",
"version": "7.26.7",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.7.tgz",
"integrity": "sha512-kEvgGGgEjRUutvdVvZhbn/BxVt+5VSpwXz1j3WYXQbXDo8KzFOPNG2GQbdAiNq8g6wn1yKk7C/qrke03a84V+w==",
"requires": {
"@babel/types": "^7.26.0"
"@babel/types": "^7.26.7"
}
},
"@babel/plugin-bugfix-firefox-class-in-computed-class-key": {
@@ -4174,11 +4145,11 @@
}
},
"@babel/plugin-transform-block-scoped-functions": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.9.tgz",
"integrity": "sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA==",
"version": "7.26.5",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.26.5.tgz",
"integrity": "sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ==",
"requires": {
"@babel/helper-plugin-utils": "^7.25.9"
"@babel/helper-plugin-utils": "^7.26.5"
}
},
"@babel/plugin-transform-block-scoping": {
@@ -4272,11 +4243,10 @@
}
},
"@babel/plugin-transform-exponentiation-operator": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.25.9.tgz",
"integrity": "sha512-KRhdhlVk2nObA5AYa7QMgTMTVJdfHprfpAk4DjZVtllqRg9qarilstTKEhpVjyt+Npi8ThRyiV8176Am3CodPA==",
"version": "7.26.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz",
"integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==",
"requires": {
"@babel/helper-builder-binary-assignment-operator-visitor": "^7.25.9",
"@babel/helper-plugin-utils": "^7.25.9"
}
},
@@ -4349,13 +4319,12 @@
}
},
"@babel/plugin-transform-modules-commonjs": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.25.9.tgz",
"integrity": "sha512-dwh2Ol1jWwL2MgkCzUSOvfmKElqQcuswAZypBSUsScMXvgdT8Ekq5YA6TtqpTVWH+4903NmboMuH1o9i8Rxlyg==",
"version": "7.26.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz",
"integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==",
"requires": {
"@babel/helper-module-transforms": "^7.25.9",
"@babel/helper-plugin-utils": "^7.25.9",
"@babel/helper-simple-access": "^7.25.9"
"@babel/helper-module-transforms": "^7.26.0",
"@babel/helper-plugin-utils": "^7.25.9"
}
},
"@babel/plugin-transform-modules-systemjs": {
@@ -4396,11 +4365,11 @@
}
},
"@babel/plugin-transform-nullish-coalescing-operator": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.9.tgz",
"integrity": "sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog==",
"version": "7.26.6",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.26.6.tgz",
"integrity": "sha512-CKW8Vu+uUZneQCPtXmSBUC6NCAUdya26hWCElAWh5mVSlSRsmiCPUUDKb3Z0szng1hiAJa098Hkhg9o4SE35Qw==",
"requires": {
"@babel/helper-plugin-utils": "^7.25.9"
"@babel/helper-plugin-utils": "^7.26.5"
}
},
"@babel/plugin-transform-numeric-separator": {
@@ -4542,11 +4511,11 @@
}
},
"@babel/plugin-transform-typeof-symbol": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz",
"integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==",
"version": "7.26.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.26.7.tgz",
"integrity": "sha512-jfoTXXZTgGg36BmhqT3cAYK5qkmqvJpvNrPhaK/52Vgjhw4Rq29s9UqpWWV0D6yuRmgiFH/BUVlkl96zJWqnaw==",
"requires": {
"@babel/helper-plugin-utils": "^7.25.9"
"@babel/helper-plugin-utils": "^7.26.5"
}
},
"@babel/plugin-transform-unicode-escapes": {
@@ -4585,13 +4554,13 @@
}
},
"@babel/preset-env": {
"version": "7.26.0",
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.0.tgz",
"integrity": "sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==",
"version": "7.26.7",
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.7.tgz",
"integrity": "sha512-Ycg2tnXwixaXOVb29rana8HNPgLVBof8qqtNQ9LE22IoyZboQbGSxI6ZySMdW3K5nAe6gu35IaJefUJflhUFTQ==",
"requires": {
"@babel/compat-data": "^7.26.0",
"@babel/helper-compilation-targets": "^7.25.9",
"@babel/helper-plugin-utils": "^7.25.9",
"@babel/compat-data": "^7.26.5",
"@babel/helper-compilation-targets": "^7.26.5",
"@babel/helper-plugin-utils": "^7.26.5",
"@babel/helper-validator-option": "^7.25.9",
"@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9",
"@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9",
@@ -4605,7 +4574,7 @@
"@babel/plugin-transform-arrow-functions": "^7.25.9",
"@babel/plugin-transform-async-generator-functions": "^7.25.9",
"@babel/plugin-transform-async-to-generator": "^7.25.9",
"@babel/plugin-transform-block-scoped-functions": "^7.25.9",
"@babel/plugin-transform-block-scoped-functions": "^7.26.5",
"@babel/plugin-transform-block-scoping": "^7.25.9",
"@babel/plugin-transform-class-properties": "^7.25.9",
"@babel/plugin-transform-class-static-block": "^7.26.0",
@@ -4616,7 +4585,7 @@
"@babel/plugin-transform-duplicate-keys": "^7.25.9",
"@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9",
"@babel/plugin-transform-dynamic-import": "^7.25.9",
"@babel/plugin-transform-exponentiation-operator": "^7.25.9",
"@babel/plugin-transform-exponentiation-operator": "^7.26.3",
"@babel/plugin-transform-export-namespace-from": "^7.25.9",
"@babel/plugin-transform-for-of": "^7.25.9",
"@babel/plugin-transform-function-name": "^7.25.9",
@@ -4625,12 +4594,12 @@
"@babel/plugin-transform-logical-assignment-operators": "^7.25.9",
"@babel/plugin-transform-member-expression-literals": "^7.25.9",
"@babel/plugin-transform-modules-amd": "^7.25.9",
"@babel/plugin-transform-modules-commonjs": "^7.25.9",
"@babel/plugin-transform-modules-commonjs": "^7.26.3",
"@babel/plugin-transform-modules-systemjs": "^7.25.9",
"@babel/plugin-transform-modules-umd": "^7.25.9",
"@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9",
"@babel/plugin-transform-new-target": "^7.25.9",
"@babel/plugin-transform-nullish-coalescing-operator": "^7.25.9",
"@babel/plugin-transform-nullish-coalescing-operator": "^7.26.6",
"@babel/plugin-transform-numeric-separator": "^7.25.9",
"@babel/plugin-transform-object-rest-spread": "^7.25.9",
"@babel/plugin-transform-object-super": "^7.25.9",
@@ -4647,7 +4616,7 @@
"@babel/plugin-transform-spread": "^7.25.9",
"@babel/plugin-transform-sticky-regex": "^7.25.9",
"@babel/plugin-transform-template-literals": "^7.25.9",
"@babel/plugin-transform-typeof-symbol": "^7.25.9",
"@babel/plugin-transform-typeof-symbol": "^7.26.7",
"@babel/plugin-transform-unicode-escapes": "^7.25.9",
"@babel/plugin-transform-unicode-property-regex": "^7.25.9",
"@babel/plugin-transform-unicode-regex": "^7.25.9",
@@ -4696,23 +4665,23 @@
}
},
"@babel/traverse": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz",
"integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==",
"version": "7.26.7",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.7.tgz",
"integrity": "sha512-1x1sgeyRLC3r5fQOM0/xtQKsYjyxmFjaOrLJNtZ81inNjyJHGIolTULPiSc/2qe1/qfpFLisLQYFnnZl7QoedA==",
"requires": {
"@babel/code-frame": "^7.25.9",
"@babel/generator": "^7.25.9",
"@babel/parser": "^7.25.9",
"@babel/code-frame": "^7.26.2",
"@babel/generator": "^7.26.5",
"@babel/parser": "^7.26.7",
"@babel/template": "^7.25.9",
"@babel/types": "^7.25.9",
"@babel/types": "^7.26.7",
"debug": "^4.3.1",
"globals": "^11.1.0"
}
},
"@babel/types": {
"version": "7.26.0",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz",
"integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==",
"version": "7.26.7",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.7.tgz",
"integrity": "sha512-t8kDRGrKXyp6+tjUh7hw2RLyclsW4TRoRvRHtSyAX9Bb5ldlFh+90YAYY6awRXrlB4G5G2izNeGySpATlFzmOg==",
"requires": {
"@babel/helper-string-parser": "^7.25.9",
"@babel/helper-validator-identifier": "^7.25.9"

View File

@@ -4,8 +4,8 @@
"private": true,
"scripts": {},
"dependencies": {
"@babel/core": "^7.26.0",
"@babel/preset-env": "^7.26.0",
"@babel/core": "^7.26.7",
"@babel/preset-env": "^7.26.7",
"@rollup/plugin-babel": "^6.0.4",
"@rollup/plugin-node-resolve": "^16.0.0",
"vue": "^2.7.16",

View File

@@ -1065,11 +1065,17 @@ function add_log_expand_handlers(el) {
} else if ($a.is("[data-expandpayment]")) {
url += 'payment/'
}
function format_data(data) {
return Object.entries(data).map(([key, value]) =>
$("<div>").append(
$("<b>").text(key + ': '),
$("<span>").text(JSON.stringify(value, null, 2))));
}
$.getJSON(url + '?pk=' + id, function (data) {
if ($a.parent().tagName === "p") {
$("<pre>").text(JSON.stringify(data.data, null, 2)).insertAfter($a.parent());
$("<pre>").append(format_data(data)).insertAfter($a.parent());
} else {
$("<pre>").text(JSON.stringify(data.data, null, 2)).appendTo($a.parent());
$("<pre>").append(format_data(data)).appendTo($a.parent());
}
$a.remove();
});

View File

@@ -1,6 +1,6 @@
/*global $,u2f */
$(function () {
$('.sidebar .dropdown, ul.navbar-nav .dropdown, .navbar-events-collapse').on('shown.bs.collapse shown.bs.dropdown', function () {
$('.context-selector.dropdown').on('shown.bs.collapse shown.bs.dropdown', function () {
$(this).parent().find("input").val("").trigger('forceRunQuery').focus();
});
$('.dropdown-menu .form-box input').click(function (e) {

View File

@@ -162,6 +162,7 @@ def test_giftcard_detail_expand(token_client, organizer, event, giftcard):
"tax_rule": None,
"pseudonymization_id": op.pseudonymization_id,
"pdf_data": {},
"plugin_data": {},
"seat": None,
"canceled": False,
"valid_from": None,

View File

@@ -1797,6 +1797,13 @@ def test_order_change_cancel_and_create(token_client, organizer, event, order, q
'price': '99.99'
},
],
'create_fees': [
{
'value': '5.99',
'fee_type': 'service',
'description': 'Service fee',
},
],
'cancel_fees': [
{
'fee': f.pk,
@@ -1818,6 +1825,11 @@ def test_order_change_cancel_and_create(token_client, organizer, event, order, q
assert p_new.price == Decimal('99.99')
f.refresh_from_db()
assert f.canceled
f_new = order.all_fees.get(fee_type=OrderFee.FEE_TYPE_SERVICE)
assert f_new.value == Decimal('5.99')
assert f_new.description == "Service fee"
assert f_new.internal_type == ""
assert f_new.tax_value == Decimal('0.00')
@pytest.mark.django_db

View File

@@ -477,7 +477,8 @@ def test_order_create_simulate(token_client, organizer, event, item, quota, ques
'zipcode': None,
'state': None,
'country': None,
'canceled': False
'canceled': False,
'plugin_data': {},
}
],
'downloads': [],
@@ -487,7 +488,8 @@ def test_order_create_simulate(token_client, organizer, event, item, quota, ques
'refunds': [],
'require_approval': False,
'sales_channel': 'web',
'cancellation_date': None
'cancellation_date': None,
'plugin_data': {},
}
@@ -533,13 +535,15 @@ def test_order_create_positionids_addons_simulated(token_client, organizer, even
'street': None, 'zipcode': None, 'city': None, 'country': None, 'state': None, 'attendee_email': None,
'voucher': None, 'tax_rate': '19.00', 'tax_code': 'S/standard', 'tax_value': '3.67', 'discount': None, 'voucher_budget_use': None,
'addon_to': None, 'subevent': None, 'checkins': [], 'print_logs': [], 'downloads': [], 'answers': [], 'tax_rule': item.tax_rule_id,
'pseudonymization_id': 'PREVIEW', 'seat': None, 'canceled': False, 'valid_from': None, 'valid_until': None, 'blocked': None},
'pseudonymization_id': 'PREVIEW', 'seat': None, 'canceled': False, 'valid_from': None, 'valid_until': None, 'blocked': None,
'plugin_data': {}},
{'id': 0, 'order': '', 'positionid': 2, 'item': item.pk, 'variation': None, 'price': '23.00',
'attendee_name': 'Peter', 'attendee_name_parts': {'full_name': 'Peter', '_scheme': 'full'}, 'company': None,
'street': None, 'zipcode': None, 'city': None, 'country': None, 'state': None, 'attendee_email': None,
'voucher': None, 'tax_rate': '19.00', 'tax_code': 'S/standard', 'tax_value': '3.67', 'discount': None, 'voucher_budget_use': None,
'addon_to': 1, 'subevent': None, 'checkins': [], 'print_logs': [], 'downloads': [], 'answers': [], 'tax_rule': item.tax_rule_id,
'pseudonymization_id': 'PREVIEW', 'seat': None, 'canceled': False, 'valid_from': None, 'valid_until': None, 'blocked': None}
'pseudonymization_id': 'PREVIEW', 'seat': None, 'canceled': False, 'valid_from': None, 'valid_until': None, 'blocked': None,
'plugin_data': {}}
]

View File

@@ -236,6 +236,7 @@ TEST_ORDERPOSITION_RES = {
],
"subevent": None,
"canceled": False,
"plugin_data": {},
}
TEST_PAYMENTS_RES = [
{
@@ -333,6 +334,7 @@ TEST_ORDER_RES = {
"payments": TEST_PAYMENTS_RES,
"refunds": TEST_REFUNDS_RES,
"cancellation_date": None,
"plugin_data": {},
}

View File

@@ -203,7 +203,8 @@ def test_medium_detail(token_client, organizer, event, medium, giftcard, custome
"canceled": False,
"valid_from": None,
"valid_until": None,
"blocked": None
"blocked": None,
"plugin_data": {},
}
assert resp.data["linked_giftcard"] == {
"id": giftcard.pk,

View File

@@ -74,7 +74,7 @@ def extract_form_fields(soup):
continue
# textareas
for textarea in soup.findAll('textarea'):
for textarea in soup.find_all('textarea'):
if textarea['name'] in data:
if not isinstance(data[textarea['name']], list):
data[textarea['name']] = [data[textarea['name']]]

View File

@@ -38,10 +38,12 @@ from decimal import Decimal
import pytest
from django.db import DatabaseError, transaction
from django.utils.itercompat import is_iterable
from django.utils.timezone import now
from django_countries.fields import Country
from django_scopes import scope, scopes_disabled
from pretix.base.invoice import addon_aware_groupby
from pretix.base.models import (
Event, ExchangeRate, Invoice, InvoiceAddress, Item, ItemVariation, Order,
OrderPosition, Organizer,
@@ -606,3 +608,55 @@ def test_sales_channels_qualify(env):
event.settings.set('invoice_generate_sales_channels', [])
assert invoice_qualified(order) is False
def test_addon_aware_groupby():
def is_addon(item):
is_addon, id, price = item
return is_addon
def key(item):
return item
def listify(it):
return [listify(i) if is_iterable(i) else i for i in it]
assert listify(addon_aware_groupby([
(False, 1, 5.00),
(False, 1, 5.00),
(False, 1, 5.00),
(False, 2, 7.00),
], key, is_addon)) == [
[[False, 1, 5.00], [
[False, 1, 5.00],
[False, 1, 5.00],
[False, 1, 5.00],
]],
[[False, 2, 7.00], [
[False, 2, 7.00],
]],
]
assert listify(addon_aware_groupby([
(False, 1, 5.00),
(True, 101, 2.00),
(False, 1, 5.00),
(True, 101, 2.00),
(False, 1, 5.00),
(True, 102, 3.00),
], key, is_addon)) == [
[[False, 1, 5.00], [
[False, 1, 5.00],
[False, 1, 5.00],
]],
[[True, 101, 2.00], [
[True, 101, 2.00],
[True, 101, 2.00],
]],
[[False, 1, 5.00], [
[False, 1, 5.00],
]],
[[True, 102, 3.00], [
[True, 102, 3.00],
]],
]

View File

@@ -0,0 +1,3 @@
Transaction Date,Transaction Type,Sort Code,Account Number,Transaction Description,Debit Amount,Credit Amount,Balance,
27/01/2025,FPI,'99-99-99,11111111,SMITH J ABCDE 111111111111111111 111111 10 25JAN25 13:34,,214,500
25/01/2025,FPI,'99-99-99,11111111,JONES A FGHIJ 111111111111111112 111112 10 25JAN25 10:34,,213,286
1 Transaction Date,Transaction Type,Sort Code,Account Number,Transaction Description,Debit Amount,Credit Amount,Balance,
2 27/01/2025,FPI,'99-99-99,11111111,SMITH J ABCDE 111111111111111111 111111 10 25JAN25 13:34,,214,500
3 25/01/2025,FPI,'99-99-99,11111111,JONES A FGHIJ 111111111111111112 111112 10 25JAN25 10:34,,213,286

View File

@@ -166,3 +166,28 @@ class CsvImportTest(TestCase):
]
filename = "csvimport_data_de_postbank.csv"
self._test_from_sample_file(filename, expected, hint, expected_parsed)
def test_sample_file_lloyds(self):
expected = [
# Lloyds Bank includes a trailing comma at the end of the header row, making the header one column longer than the data rows.
['Transaction Date', 'Transaction Type', 'Sort Code', 'Account Number', 'Transaction Description', 'Debit Amount',
'Credit Amount', 'Balance', ''],
["27/01/2025", "FPI", "'99-99-99", "11111111", "SMITH J ABCDE 111111111111111111 111111 10 25JAN25 13:34",
"", "214", "500"],
["25/01/2025", "FPI", "'99-99-99", "11111111", "JONES A FGHIJ 111111111111111112 111112 10 25JAN25 10:34",
"", "213", "286"],
]
hint = {
'reference': [4],
'date': 0,
'amount': 6,
'cols': 9,
}
expected_parsed = [
{'reference': 'SMITH J ABCDE 111111111111111111 111111 10 25JAN25 13:34', 'amount': '214',
'date': '27/01/2025'},
{'reference': 'JONES A FGHIJ 111111111111111112 111112 10 25JAN25 10:34', 'amount': '213',
'date': '25/01/2025'},
]
filename = "csvimport_data_gb_lloyds.csv"
self._test_from_sample_file(filename, expected, hint, expected_parsed)

View File

@@ -574,7 +574,7 @@ def test_pending_paypal_drop_fee(env, job):
env[2].save()
p = env[2].payments.create(
provider='paypal',
state=OrderPayment.PAYMENT_STATE_PENDING,
state=OrderPayment.PAYMENT_STATE_CREATED,
fee=fee,
amount=env[2].total
)
@@ -790,3 +790,33 @@ def test_ignore_by_external_id(env, job):
}])
with scopes_disabled():
assert BankTransaction.objects.count() == 2
@pytest.mark.django_db
def test_ambigious_date_without_region(env, job):
process_banktransfers(job, [{
'payer': 'Karla Kundin',
'reference': 'Bestellung DUMMY1Z3AS',
'date': '03/05/2016',
'amount': '23.00'
}])
env[2].refresh_from_db()
with scopes_disabled():
assert env[2].payments.last().info_data["date"] == "2016-03-05"
@pytest.mark.django_db
def test_ambigious_date_with_region(env, job):
env[0].settings.region = "GB"
process_banktransfers(job, [{
'payer': 'Karla Kundin',
'reference': 'Bestellung DUMMY1Z3AS',
'date': '03/05/2016',
'amount': '23.00'
}])
env[2].refresh_from_db()
with scopes_disabled():
assert env[2].payments.last().info_data["date"] == "2016-05-03"

View File

@@ -40,3 +40,5 @@ def test_date_formats():
assert dt == parse_date("2020-07-01")
assert dt == parse_date("2020-7-1")
assert dt == parse_date("01/07/2020", "GB")