Compare commits

..
Author SHA1 Message Date
Lukas Bockstaller 9b23ae1ae5 updates mark_oder_expired() docstring to match reality 2026-10-16 12:22:36 +02:00
36 changed files with 512 additions and 754 deletions

No files matched your search

+1 -27
View File
@@ -284,10 +284,7 @@ In this algorithm, the tax value and gross total are computed from the sum of th
of some of the tickets will be changed automatically by the minimum currency unit (e.g. €0.01) such that the resulting
gross prices stay the same.
**This is a bit less confusing to consumers and the end result is still compliant to EN 16931, so we recommend this for e-invoicing when (primarily) consumers are involved.**
However, confusion for consumers can still arise when a price cannot be represented by a net price.
For example, you cannot sell a single ticket for 15.00 with a 19 % tax rate, because 12.60 * 1.19 = 14.99 and 12.61 * 1.19 = 15.01, so a total gross price of 15.00 is impossible to reach and the system will round to a different gross price.
**This is less confusing to consumers and the end result is still compliant to EN 16931, so we recommend this for e-invoicing when (primarily) consumers are involved.**
The main downside is that it might be confusing when selling to business customers, since the prices of the identical tickets appear to be different.
Full computation for the example above:
@@ -302,26 +299,3 @@ Full computation for the example above:
Ticket E 19 % 84.03 15.97 100.00
Sum 420.17 79.83 500.00
========== ========== ============================= ============================== =============
Compute taxes based on gross total
""""""""""""""""""""""""""""""""""
Algorithm identifier: ``sum_by_gross``
In this algorithm, the net prices of some the individual lines will be modified such that the end values will be consistent with a computation from the gross sum.
This will lead to different net prices to be shown for tickets of the same type, but the gross price will stay always the same.
**This is the most sensible algorithm when dealing mostly with consumer or when advertising gross prices, and you still need to issue e-invoices. Technically, it is incompliant with EN 16931, but at least for Germany, the Federal Ministry of Finance (BMF) allows to use it until end of 2027 in lieu of a better solution.**
For the example above:
========== ========== ============================= ============================== =============
Product Tax rate Net price Tax Gross price
========== ========== ============================= ============================== =============
Ticket A 19 % 84.04 (incl. 0.01 rounding) 15.96 (incl. -0.01 rounding) 100.00
Ticket B 19 % 84.04 (incl. 0.01 rounding) 15.96 (incl. -0.01 rounding) 100.00
Ticket C 19 % 84.03 15.97 100.00
Ticket D 19 % 84.03 15.97 100.00
Ticket E 19 % 84.03 15.97 100.00
Sum 420.17 79.83 500.00
========== ========== ============================= ============================== =============
+210 -156
View File
@@ -92,6 +92,40 @@
"dev": true,
"license": "(Apache-2.0 AND BSD-3-Clause)"
},
"node_modules/@emnapi/core": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
"integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
"@emnapi/wasi-threads": "1.2.1",
"tslib": "^2.4.0"
}
},
"node_modules/@emnapi/runtime": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
"integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
"tslib": "^2.4.0"
}
},
"node_modules/@emnapi/wasi-threads": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
"integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
"tslib": "^2.4.0"
}
},
"node_modules/@eslint-community/eslint-utils": {
"version": "4.9.1",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz",
@@ -349,6 +383,25 @@
"integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==",
"license": "MIT"
},
"node_modules/@napi-rs/wasm-runtime": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.5.tgz",
"integrity": "sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
"@tybys/wasm-util": "^0.10.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/Brooooooklyn"
},
"peerDependencies": {
"@emnapi/core": "^1.7.1",
"@emnapi/runtime": "^1.7.1"
}
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -388,13 +441,13 @@
}
},
"node_modules/@oxc-project/types": {
"version": "0.155.0",
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.155.0.tgz",
"integrity": "sha512-SeE8JPwW1xs1tHeNycjUtUBdhorRa8o4jlvjwk49R7/Z291i+4DQa7JJIgOm/TaYQZx+QrPQbVJ/9c8dMIZN8Q==",
"version": "0.133.0",
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.133.0.tgz",
"integrity": "sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/oxc-project"
"url": "https://github.com/sponsors/Boshen"
}
},
"node_modules/@parcel/watcher": {
@@ -718,27 +771,10 @@
"node": ">=14"
}
},
"node_modules/@rolldown/binding-android-arm-eabi": {
"version": "1.2.15",
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.15.tgz",
"integrity": "sha512-aLcgK9gIJ3YRvrrtfSBbRa27F5WrpiTaPulnFpsHPxpUHgFlSgnU4854MHwoRGEBhfRJDWCS2WQ7lIjskE9Olw==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@rolldown/binding-android-arm64": {
"version": "1.2.15",
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.15.tgz",
"integrity": "sha512-xD7DdZCrbThKuxNg7ooQmvp07ys4J/pnSEMTG3/OdOWl6daC67m/Q4fL78sRHMxTH/N4fGUbYhcPM0MF5WFHkg==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz",
"integrity": "sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==",
"cpu": [
"arm64"
],
@@ -753,9 +789,9 @@
}
},
"node_modules/@rolldown/binding-darwin-arm64": {
"version": "1.2.15",
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.15.tgz",
"integrity": "sha512-m2WuQ6r0B4OTYxyPpNLtXaMRbRDUbG8YQV2Q3KTdSSK8Th6KHCnC8jVCJt8bvYeSB5WivkkNbc85mKadaSdOxA==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.3.tgz",
"integrity": "sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==",
"cpu": [
"arm64"
],
@@ -770,9 +806,9 @@
}
},
"node_modules/@rolldown/binding-darwin-x64": {
"version": "1.2.15",
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.15.tgz",
"integrity": "sha512-5RtnsHM36nodM9WbMy+zip0LGS/G+y5wro5RHrpOlr4ac24+1zSi9kiV2MP1myZeZ/ifEHfulQcWjnAXzc2C2A==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.3.tgz",
"integrity": "sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==",
"cpu": [
"x64"
],
@@ -787,9 +823,9 @@
}
},
"node_modules/@rolldown/binding-freebsd-x64": {
"version": "1.2.15",
"resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.15.tgz",
"integrity": "sha512-g3l09pyFqhu+135JKkbkwiKGQmwU5hUMUPJ4VdBADvuqR8d33L6H578rh8m7rtxbdp+VmX/+nzI7nvhSZlzpUQ==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.3.tgz",
"integrity": "sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==",
"cpu": [
"x64"
],
@@ -804,9 +840,9 @@
}
},
"node_modules/@rolldown/binding-linux-arm-gnueabihf": {
"version": "1.2.15",
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.15.tgz",
"integrity": "sha512-nIe3VugI97nGQtspPxDqA4sXMUpeiocKIP/CqpY/u/vgbT+alX+cVxu1C/oVBPKg4feNTmYovE91v4DgXvXNwQ==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.3.tgz",
"integrity": "sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==",
"cpu": [
"arm"
],
@@ -821,9 +857,9 @@
}
},
"node_modules/@rolldown/binding-linux-arm64-gnu": {
"version": "1.2.15",
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.15.tgz",
"integrity": "sha512-iTBjXx+B5QSvgI89lJfmqh4wTh8NabR1YZIIN3hNx4zSG0EVfVqkOvLulNpG4251pbd6/IAmZ/LefVk1Y4rPhw==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.3.tgz",
"integrity": "sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==",
"cpu": [
"arm64"
],
@@ -841,9 +877,9 @@
}
},
"node_modules/@rolldown/binding-linux-arm64-musl": {
"version": "1.2.15",
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.15.tgz",
"integrity": "sha512-uN26XOnVR7rqQupG3V9oAG2EGGatWjcJHOeDOHUFCh4TBWmP2tHTFoVN13aYbwfm0aHqJAEmcwhAu6sooIjfqQ==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.3.tgz",
"integrity": "sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==",
"cpu": [
"arm64"
],
@@ -861,9 +897,9 @@
}
},
"node_modules/@rolldown/binding-linux-ppc64-gnu": {
"version": "1.2.15",
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.15.tgz",
"integrity": "sha512-9nWkcdd+H+XhaA3fQIwpHnKIrfx/PQ6rO0pivr78Og07tXlUlctBBJoEYLPfhTmCR/QxEVdn6uPjHV5SymPhdw==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.3.tgz",
"integrity": "sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==",
"cpu": [
"ppc64"
],
@@ -881,9 +917,9 @@
}
},
"node_modules/@rolldown/binding-linux-s390x-gnu": {
"version": "1.2.15",
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.15.tgz",
"integrity": "sha512-Ggh0ciFjLwIusLSLz7LZYEaGdxOAUJXI+Qu5JCbhPJJHEt8vP+IjRATTJheiJsdzzTYgUiHUiw3X1Ea3ZpMBdA==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.3.tgz",
"integrity": "sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==",
"cpu": [
"s390x"
],
@@ -901,9 +937,9 @@
}
},
"node_modules/@rolldown/binding-linux-x64-gnu": {
"version": "1.2.15",
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.15.tgz",
"integrity": "sha512-FHg60rS6DBePAYZ9X9F67x+JObFdmgn6tupA1C/a3B+CufFmTD4mX+e8M75tCiAO3foR/6xwVBI0KQiI7sn/rw==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz",
"integrity": "sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==",
"cpu": [
"x64"
],
@@ -921,9 +957,9 @@
}
},
"node_modules/@rolldown/binding-linux-x64-musl": {
"version": "1.2.15",
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.15.tgz",
"integrity": "sha512-/cvV/7v5VGz/moiz0XKRj2dE8DzsKyhIu1KpOvJGPjRywg3yscON889UGvAe8zfiJLHup7VLjBduoGWi3HusWQ==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.3.tgz",
"integrity": "sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==",
"cpu": [
"x64"
],
@@ -941,9 +977,9 @@
}
},
"node_modules/@rolldown/binding-openharmony-arm64": {
"version": "1.2.15",
"resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.15.tgz",
"integrity": "sha512-MyzC5Hrv/sm+Z7TSGKP/j8001RO2xQm1zOpCNVL4j0cY/VhBZviludA2YFQ7i4lH6ZAXxQm0lcMdBzM+99mE7w==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.3.tgz",
"integrity": "sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==",
"cpu": [
"arm64"
],
@@ -957,10 +993,29 @@
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@rolldown/binding-wasm32-wasi": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.3.tgz",
"integrity": "sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==",
"cpu": [
"wasm32"
],
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
"@emnapi/core": "1.10.0",
"@emnapi/runtime": "1.10.0",
"@napi-rs/wasm-runtime": "^1.1.4"
},
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@rolldown/binding-win32-arm64-msvc": {
"version": "1.2.15",
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.15.tgz",
"integrity": "sha512-+PgYiS+AH5omy6L45ZLxybasauJaj3M8buoT83D+nzPmCayXlxUV9hydhciCKVyIg0B/v0BtXPDE1uGqNwCPpg==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.3.tgz",
"integrity": "sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==",
"cpu": [
"arm64"
],
@@ -975,9 +1030,9 @@
}
},
"node_modules/@rolldown/binding-win32-x64-msvc": {
"version": "1.2.15",
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.15.tgz",
"integrity": "sha512-HFZd2QNQYn1JbIi+Hpd7H+r/lkWxcfIu28nirZ6eCn2LafuvmExMlb/P96Sfx5tf7pPArw39IdhmCF8vmV+NhQ==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz",
"integrity": "sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==",
"cpu": [
"x64"
],
@@ -1019,6 +1074,17 @@
"eslint": "^9.0.0 || ^10.0.0"
}
},
"node_modules/@tybys/wasm-util": {
"version": "0.10.2",
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz",
"integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
"tslib": "^2.4.0"
}
},
"node_modules/@types/esrecurse": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz",
@@ -2742,9 +2808,9 @@
}
},
"node_modules/lightningcss": {
"version": "1.33.0",
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz",
"integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==",
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
"integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==",
"dev": true,
"license": "MPL-2.0",
"dependencies": {
@@ -2758,23 +2824,23 @@
"url": "https://opencollective.com/parcel"
},
"optionalDependencies": {
"lightningcss-android-arm64": "1.33.0",
"lightningcss-darwin-arm64": "1.33.0",
"lightningcss-darwin-x64": "1.33.0",
"lightningcss-freebsd-x64": "1.33.0",
"lightningcss-linux-arm-gnueabihf": "1.33.0",
"lightningcss-linux-arm64-gnu": "1.33.0",
"lightningcss-linux-arm64-musl": "1.33.0",
"lightningcss-linux-x64-gnu": "1.33.0",
"lightningcss-linux-x64-musl": "1.33.0",
"lightningcss-win32-arm64-msvc": "1.33.0",
"lightningcss-win32-x64-msvc": "1.33.0"
"lightningcss-android-arm64": "1.32.0",
"lightningcss-darwin-arm64": "1.32.0",
"lightningcss-darwin-x64": "1.32.0",
"lightningcss-freebsd-x64": "1.32.0",
"lightningcss-linux-arm-gnueabihf": "1.32.0",
"lightningcss-linux-arm64-gnu": "1.32.0",
"lightningcss-linux-arm64-musl": "1.32.0",
"lightningcss-linux-x64-gnu": "1.32.0",
"lightningcss-linux-x64-musl": "1.32.0",
"lightningcss-win32-arm64-msvc": "1.32.0",
"lightningcss-win32-x64-msvc": "1.32.0"
}
},
"node_modules/lightningcss-android-arm64": {
"version": "1.33.0",
"resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz",
"integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==",
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz",
"integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==",
"cpu": [
"arm64"
],
@@ -2793,9 +2859,9 @@
}
},
"node_modules/lightningcss-darwin-arm64": {
"version": "1.33.0",
"resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz",
"integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==",
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz",
"integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==",
"cpu": [
"arm64"
],
@@ -2814,9 +2880,9 @@
}
},
"node_modules/lightningcss-darwin-x64": {
"version": "1.33.0",
"resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz",
"integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==",
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz",
"integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==",
"cpu": [
"x64"
],
@@ -2835,9 +2901,9 @@
}
},
"node_modules/lightningcss-freebsd-x64": {
"version": "1.33.0",
"resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz",
"integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==",
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz",
"integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==",
"cpu": [
"x64"
],
@@ -2856,9 +2922,9 @@
}
},
"node_modules/lightningcss-linux-arm-gnueabihf": {
"version": "1.33.0",
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz",
"integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==",
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz",
"integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==",
"cpu": [
"arm"
],
@@ -2877,16 +2943,13 @@
}
},
"node_modules/lightningcss-linux-arm64-gnu": {
"version": "1.33.0",
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz",
"integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==",
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz",
"integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==",
"cpu": [
"arm64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -2901,16 +2964,13 @@
}
},
"node_modules/lightningcss-linux-arm64-musl": {
"version": "1.33.0",
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz",
"integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==",
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz",
"integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==",
"cpu": [
"arm64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -2925,16 +2985,13 @@
}
},
"node_modules/lightningcss-linux-x64-gnu": {
"version": "1.33.0",
"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz",
"integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==",
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz",
"integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==",
"cpu": [
"x64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -2949,16 +3006,13 @@
}
},
"node_modules/lightningcss-linux-x64-musl": {
"version": "1.33.0",
"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz",
"integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==",
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz",
"integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==",
"cpu": [
"x64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -2973,9 +3027,9 @@
}
},
"node_modules/lightningcss-win32-arm64-msvc": {
"version": "1.33.0",
"resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz",
"integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==",
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz",
"integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==",
"cpu": [
"arm64"
],
@@ -2994,9 +3048,9 @@
}
},
"node_modules/lightningcss-win32-x64-msvc": {
"version": "1.33.0",
"resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz",
"integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==",
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz",
"integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==",
"cpu": [
"x64"
],
@@ -3297,9 +3351,9 @@
"license": "ISC"
},
"node_modules/picomatch": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz",
"integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==",
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3310,9 +3364,9 @@
}
},
"node_modules/postcss": {
"version": "8.5.31",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.31.tgz",
"integrity": "sha512-YUbWYCgErwnMAVkjUnYa+KlMBzGpHwiIt/DE7f0G33AuX2LH9UcTk6KgWxd3zRU+pN3u/C+Xl3EnMLM4Hea7Sg==",
"version": "8.5.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.29.tgz",
"integrity": "sha512-49cGhUbXj8Qenv0iTMxA1cFBzxXoctpC9Ujd77t1WcbJIr6nF/eI7g/8MgxrYldFRuAXvja7xQRwavoW7kgrxQ==",
"funding": [
{
"type": "opencollective",
@@ -3329,7 +3383,7 @@
],
"license": "MIT",
"dependencies": {
"nanoid": "^3.3.20",
"nanoid": "^3.3.19",
"picocolors": "^1.1.1",
"source-map-js": "^1.2.2"
},
@@ -3586,13 +3640,13 @@
}
},
"node_modules/rolldown": {
"version": "1.2.15",
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.15.tgz",
"integrity": "sha512-6odND+fel5zVw3I4Yc2e69gvguDnX0CAAGiNDZSq4ik5WUcaLrkD2GLuog0XcODbor31hZ5ayEMgVDno+KPV5g==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.3.tgz",
"integrity": "sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@oxc-project/types": "=0.155.0",
"@oxc-project/types": "=0.133.0",
"@rolldown/pluginutils": "^1.0.0"
},
"bin": {
@@ -3602,21 +3656,21 @@
"node": "^20.19.0 || >=22.12.0"
},
"optionalDependencies": {
"@rolldown/binding-android-arm-eabi": "1.2.15",
"@rolldown/binding-android-arm64": "1.2.15",
"@rolldown/binding-darwin-arm64": "1.2.15",
"@rolldown/binding-darwin-x64": "1.2.15",
"@rolldown/binding-freebsd-x64": "1.2.15",
"@rolldown/binding-linux-arm-gnueabihf": "1.2.15",
"@rolldown/binding-linux-arm64-gnu": "1.2.15",
"@rolldown/binding-linux-arm64-musl": "1.2.15",
"@rolldown/binding-linux-ppc64-gnu": "1.2.15",
"@rolldown/binding-linux-s390x-gnu": "1.2.15",
"@rolldown/binding-linux-x64-gnu": "1.2.15",
"@rolldown/binding-linux-x64-musl": "1.2.15",
"@rolldown/binding-openharmony-arm64": "1.2.15",
"@rolldown/binding-win32-arm64-msvc": "1.2.15",
"@rolldown/binding-win32-x64-msvc": "1.2.15"
"@rolldown/binding-android-arm64": "1.0.3",
"@rolldown/binding-darwin-arm64": "1.0.3",
"@rolldown/binding-darwin-x64": "1.0.3",
"@rolldown/binding-freebsd-x64": "1.0.3",
"@rolldown/binding-linux-arm-gnueabihf": "1.0.3",
"@rolldown/binding-linux-arm64-gnu": "1.0.3",
"@rolldown/binding-linux-arm64-musl": "1.0.3",
"@rolldown/binding-linux-ppc64-gnu": "1.0.3",
"@rolldown/binding-linux-s390x-gnu": "1.0.3",
"@rolldown/binding-linux-x64-gnu": "1.0.3",
"@rolldown/binding-linux-x64-musl": "1.0.3",
"@rolldown/binding-openharmony-arm64": "1.0.3",
"@rolldown/binding-wasm32-wasi": "1.0.3",
"@rolldown/binding-win32-arm64-msvc": "1.0.3",
"@rolldown/binding-win32-x64-msvc": "1.0.3"
}
},
"node_modules/rolldown/node_modules/@rolldown/pluginutils": {
@@ -4441,16 +4495,16 @@
"license": "MIT"
},
"node_modules/vite": {
"version": "8.3.5",
"resolved": "https://registry.npmjs.org/vite/-/vite-8.3.5.tgz",
"integrity": "sha512-z1YpjieJ9g0ebTmQpLBv/oq9E3F9EIlOe+7LahW8SrE3LTiG3udBRUXQOlYXP9b+IC2q2phHeVxj9xGlw34OEQ==",
"version": "8.0.16",
"resolved": "https://registry.npmjs.org/vite/-/vite-8.0.16.tgz",
"integrity": "sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==",
"dev": true,
"license": "MIT",
"dependencies": {
"lightningcss": "^1.33.0",
"picomatch": "^4.0.7",
"postcss": "^8.5.30",
"rolldown": "~1.2.14",
"lightningcss": "^1.32.0",
"picomatch": "^4.0.4",
"postcss": "^8.5.15",
"rolldown": "1.0.3",
"tinyglobby": "^0.2.17"
},
"bin": {
@@ -4467,7 +4521,7 @@
},
"peerDependencies": {
"@types/node": "^20.19.0 || >=22.12.0",
"@vitejs/devtools": "^0.7.1 || ^0.8.0",
"@vitejs/devtools": "^0.1.18",
"esbuild": "^0.27.0 || ^0.28.0",
"jiti": ">=1.21.0",
"less": "^4.0.0",
+6 -6
View File
@@ -38,7 +38,7 @@ dependencies = [
"defusedcsv>=3.0.0",
"dnspython==2.*",
"Django[argon2]==5.2.*,>=5.2.17",
"django-bootstrap3==26.3",
"django-bootstrap3==26.2",
"django-compressor==4.6.0",
"django-countries==9.1.*",
"django-filter==26.2",
@@ -57,7 +57,7 @@ dependencies = [
"django-redis==7.0.*",
"django-scopes==2.1.*",
"django-statici18n==2.8.*",
"djangorestframework>=3.18.3",
"djangorestframework==3.17.*",
"dnspython==2.8.*",
"drf_ujson2==1.7.*",
"geoip2==5.*",
@@ -67,7 +67,7 @@ dependencies = [
"kombu==5.6.*",
"libsass==0.23.*",
"lxml",
"markdown==3.11.2", # 3.3.5 requires importlib-metadata>=4.4, but django-bootstrap3 requires importlib-metadata<3.
"markdown==3.11", # 3.3.5 requires importlib-metadata>=4.4, but django-bootstrap3 requires importlib-metadata<3.
# We can upgrade markdown again once django-bootstrap3 upgrades or once we drop Python 3.6 and 3.7
"mt-940==4.30.*",
"oauthlib==3.3.*",
@@ -77,14 +77,14 @@ dependencies = [
"paypal-checkout-serversdk==1.0.*",
"PyJWT==2.15.*",
"phonenumberslite==9.0.*",
"Pillow==13.0.*",
"Pillow==12.3.*",
"pretix-plugin-build",
"protobuf==7.36.*",
"psycopg2-binary",
"pycountry",
"pycparser==3.11",
"pycparser==3.0",
"pycryptodome==3.24.*",
"pypdf==6.20.*",
"pypdf==6.19.*",
"python-bidi==0.6.*", # Support for Arabic in reportlab
"python-dateutil==2.9.*",
"pytz",
+1 -1
View File
@@ -76,7 +76,7 @@ class DeviceTokenAuthentication(TokenAuthentication):
except DeviceLastSeen.DoesNotExist:
# First request from device, create model, ignore result. Use get_or_create to be safe
# against concurrent create requests
DeviceLastSeen.objects.get_or_create(device=device, defaults={"last_seen": now()})
DeviceLastSeen.objects.get_or_create(device=device, last_seen=now())
else:
if now() - last_seen_obj.last_seen < timedelta(seconds=10):
# We don't need to know the last seen info of a device to more precision than this,
+3 -12
View File
@@ -35,13 +35,10 @@
import logging
from django.conf import settings
from django.core.exceptions import (
PermissionDenied, ValidationError as DjangoValidationError,
)
from django.core.exceptions import PermissionDenied
from django.db import transaction
from django.utils.crypto import get_random_string
from django.utils.functional import cached_property
from django.utils.html import strip_tags
from django.utils.translation import gettext as _
from django_countries.serializers import CountryFieldMixin
from pytz import common_timezones
@@ -221,6 +218,8 @@ class EventSerializer(SalesChannelMigrationMixin, I18nAwareModelSerializer):
if self.instance is None:
raise ValidationError(_('Events cannot be created as \'live\'. Quotas and payment must be added to the '
'event before sales can go live.'))
else:
self.instance.clean_live()
return value
@cached_property
@@ -430,14 +429,6 @@ class EventSerializer(SalesChannelMigrationMixin, I18nAwareModelSerializer):
event.set_active_plugins(plugins)
event.save()
live = validated_data.get('live') or event.live
if live:
event.refresh_from_db()
try:
event.clean_live()
except DjangoValidationError as e:
raise ValidationError({'live': [strip_tags(m) for m in e.messages]})
return event
+1 -1
View File
@@ -378,7 +378,7 @@ class ItemSerializer(SalesChannelMigrationMixin, I18nAwareModelSerializer):
def validate_bundles(self, value):
if not self.instance:
for b_data in value:
ItemBundle.clean_itemvar(self.context['event'], b_data.get('bundled_item'), b_data.get('bundled_variation'))
ItemBundle.clean_itemvar(self.context['event'], b_data['bundled_item'], b_data['bundled_variation'])
return value
def validate_addons(self, value):
+1 -5
View File
@@ -160,11 +160,7 @@ class CustomerListExporter(OrganizerLevelExportMixin, MultiSheetListExporter):
]
if name_scheme and len(name_scheme['fields']) > 1:
for k, label, w in name_scheme['fields']:
row.append(
obj.attendee_name_parts.get(k, '')
if obj.attendee_name_parts
else ''
)
row.append(obj.attendee_name_parts.get(k, ''))
yield row
def get_filename(self):
+1 -1
View File
@@ -146,7 +146,7 @@ class PeppolIdValidator:
params={"number": prefix})
if self.validate_online:
base_hostnames = ['participant.sml.prod.tech.peppol.org', 'participant.sml.test.tech.peppol.org']
base_hostnames = ['edelivery.tech.ec.europa.eu', 'acc.edelivery.tech.ec.europa.eu']
smp_id = base64.b32encode(hashlib.sha256(value.lower().encode()).digest()).decode().rstrip("=")
for base_hostname in base_hostnames:
smp_domain = f'{smp_id}.iso6523-actorid-upis.{base_hostname}'
+2 -33
View File
@@ -211,7 +211,7 @@ def apply_discounts(event: Event, sales_channel: Union[str, SalesChannel],
return [new_prices.get(idx, (p[3], None)) for idx, p in enumerate(positions)]
def apply_rounding(rounding_mode: Literal["line", "sum_by_net", "sum_by_net_only_business", "sum_by_net_keep_gross", "sum_by_gross"],
def apply_rounding(rounding_mode: Literal["line", "sum_by_net", "sum_by_net_only_business", "sum_by_net_keep_gross"],
invoice_address: Optional[InvoiceAddress], currency: str,
lines: List[Union[OrderPosition, CartPosition, OrderFee]]) -> list:
"""
@@ -227,10 +227,7 @@ def apply_rounding(rounding_mode: Literal["line", "sum_by_net", "sum_by_net_only
When rounding mode is set to ``"sum_by_net"``, the gross prices and tax values of the individual lines will be
adjusted such that the per-taxrate/taxcode subtotal is rounded correctly. The net prices will stay constant.
When rounding mode is set to ``"sum_by_gross"``, the net prices and tax values of the individual lines will be
adjusted such that the per-taxrate/taxcode subtotal is rounded correctly. The gross prices will stay constant.
:param rounding_mode: One of ``"line"``, ``"sum_by_net"``, ``"sum_by_net_only_business"``, ``"sum_by_net_keep_gross"``, or ``"sum_by_gross"``.
:param rounding_mode: One of ``"line"``, ``"sum_by_net"``, ``"sum_by_net_only_business"``, or ``"sum_by_net_keep_gross"``.
:param invoice_address: The invoice address, or ``None``
:param currency: Currency that will be used to determine rounding precision
:param lines: List of order/cart contents
@@ -324,34 +321,6 @@ def apply_rounding(rounding_mode: Literal["line", "sum_by_net", "sum_by_net_only
l.tax_value_includes_rounding_correction = Decimal("0.00")
changed.append(l)
elif rounding_mode == "sum_by_gross":
for (tax_rate, tax_code), lines in groupby(sorted(lines, key=_key), key=_key):
lines = list(sorted(lines, key=lambda l: -(l.price - l.price_includes_rounding_correction)))
net_total = sum(
l.price - l.price_includes_rounding_correction - l.tax_value + l.tax_value_includes_rounding_correction
for l in lines
)
gross_total = sum(l.price - l.price_includes_rounding_correction for l in lines)
target_net_total = round_decimal(gross_total - (gross_total * (1 - 100 / (100 + tax_rate))), currency)
diff = target_net_total - net_total
diff_sgn = -1 if diff < 0 else 1
for l in lines:
if diff:
apply_diff = diff_sgn * minimum_unit
l.price = l.price - l.price_includes_rounding_correction
l.price_includes_rounding_correction = Decimal("0.00")
l.tax_value = l.tax_value - l.tax_value_includes_rounding_correction - apply_diff
l.tax_value_includes_rounding_correction = -apply_diff
diff -= apply_diff
changed.append(l)
elif l.price_includes_rounding_correction or l.tax_value_includes_rounding_correction:
l.price = l.price - l.price_includes_rounding_correction
l.price_includes_rounding_correction = Decimal("0.00")
l.tax_value = l.tax_value - l.tax_value_includes_rounding_correction
l.tax_value_includes_rounding_correction = Decimal("0.00")
changed.append(l)
elif rounding_mode == "line":
for l in lines:
if l.price_includes_rounding_correction or l.tax_value_includes_rounding_correction:
+1 -1
View File
@@ -83,7 +83,7 @@ ROUNDING_MODES = (
('sum_by_net', _('Compute taxes based on net total')),
('sum_by_net_only_business', _('For business customers, compute taxes based on net total. For individuals, use line-based rounding')),
('sum_by_net_keep_gross', _('Compute taxes based on net total with stable gross prices')),
('sum_by_gross', _('Compute taxes based on gross total')),
# We could also have sum_by_gross, but we're not aware of any use-cases for it
)
+1 -8
View File
@@ -990,18 +990,11 @@ class TaxSettingsForm(EventSettingsValidationMixin, SettingsForm):
"invoices. This can cause the payment amount to change when the invoice address is changed."
),
"sum_by_net_keep_gross": _(
"Recommended for e-invoicing when you primarily sell to consumers and need invoices compliant with EN 16931. "
"Recommended for e-invoicing when you primarily sell to consumers. "
"The gross or net price of some products may be changed automatically to ensure correct "
"rounding of the order total. The system attempts to keep gross prices as configured whenever "
"possible. Gross prices may still change if they are impossible to derive from a rounded net price."
),
"sum_by_gross": _(
"Recommended for e-invoicing when you primarily sell to consumers or advertise gross prices. "
"The net price of some products may be changed to ensure correct rounding, while the gross "
"prices will be kept as configured. This actual payment amount always stays as expected. This is "
"technically not compliant with European e-invoicing standards, but e.g. allowed within Germany at "
"least until end of 2027."
),
}
self.fields["tax_rounding"].choices = (
(k, format_html('{}<br><span class="text-muted">{}</span>', v, help_text.get(k, "")))
+5 -16
View File
@@ -1198,7 +1198,7 @@ OrganizerFooterLinkFormset = inlineformset_factory(
class SSOProviderForm(I18nModelForm):
config_oidc_base_url = forms.URLField(
label=pgettext_lazy('sso_oidc', 'Base URL / issuer'),
label=pgettext_lazy('sso_oidc', 'Base URL'),
required=False,
)
config_oidc_client_id = forms.CharField(
@@ -1295,14 +1295,6 @@ class SSOProviderForm(I18nModelForm):
class SSOClientForm(I18nModelForm):
disp_base_url = forms.CharField(
label=_('Base URL / issuer'),
disabled=True,
)
disp_client_id = forms.CharField(
label=_('Client ID'),
disabled=True,
)
regenerate_client_secret = forms.BooleanField(
label=_('Invalidate old client secret and generate a new one'),
required=False,
@@ -1310,8 +1302,7 @@ class SSOClientForm(I18nModelForm):
class Meta:
model = CustomerSSOClient
fields = ['is_active', 'name', 'disp_base_url', 'disp_client_id', 'regenerate_client_secret',
'client_type', 'authorization_grant_type', 'redirect_uris',
fields = ['is_active', 'name', 'client_id', 'client_type', 'authorization_grant_type', 'redirect_uris',
'allowed_scopes', 'require_pkce']
widgets = {
'authorization_grant_type': forms.RadioSelect,
@@ -1326,15 +1317,13 @@ class SSOClientForm(I18nModelForm):
help_text=self.fields['allowed_scopes'].help_text,
required=self.fields['allowed_scopes'].required,
initial=self.fields['allowed_scopes'].initial,
choices=[(val, format_html('<code>{}</code> &ndash; {}', val, label)) for val, label in CustomerSSOClient.SCOPE_CHOICES],
choices=CustomerSSOClient.SCOPE_CHOICES,
widget=forms.CheckboxSelectMultiple
)
organizer = kwargs['event']
self.initial['disp_base_url'] = eventreverse_absolute(organizer, 'presale:organizer.index', {}).strip('/')
if self.instance and self.instance.pk:
self.initial['disp_client_id'] = self.instance.client_id
self.fields['client_id'].disabled = True
else:
self.initial['disp_client_id'] = _('(will be generated)')
del self.fields['client_id']
del self.fields['regenerate_client_secret']
@@ -1,29 +1,12 @@
{% extends "pretixcontrol/organizers/base.html" %}
{% load i18n %}
{% load bootstrap3 %}
{% block title %}
{% if client %}
{% trans "SSO client:" %} {{ client.name }}
{% else %}
{% trans "Create credentials for a new SSO client" %}
{% endif %}
{% endblock %}
{% block inner %}
{% if client %}
<h1>{% trans "SSO client:" %} {{ client.name }}</h1>
{% else %}
<h1>{% trans "Create credentials for a new SSO client" %}</h1>
<p>
{% blocktrans trimmed %}
After submitting this form, client credentials for your SSO client will be generated.
{% endblocktrans %}
</p>
<h1>{% trans "Create a new SSO client" %}</h1>
{% endif %}
<p>
{% blocktrans trimmed with url="https://docs.pretix.eu/guides/customer-accounts/#using-pretix-as-an-sso-provider" %}
For more information, refer to our documentation on <a href="{{ url }}">Using pretix as an SSO provider with external SSO clients</a>.
{% endblocktrans %}
</p>
<form class="form-horizontal" action="" method="post">
{% csrf_token %}
{% bootstrap_form form layout="control" %}
@@ -3,23 +3,16 @@
{% load bootstrap3 %}
{% block title %}{% trans "SSO clients" %}{% endblock %}
{% block inner %}
<h1>{% trans "SSO clients" %} <small> &mdash; {% blocktrans %}
"Login with pretix" in external systems
{% endblocktrans %}</small></h1>
<h1>{% trans "SSO clients" %}</h1>
<p>
{% blocktrans trimmed %}
You can allow your customers to log into other systems using their customer account credentials by setting up
your other systems as a Single-Sign-On (SSO) client based on OpenID Connect.
{% endblocktrans %}
</p>
<p>
{% blocktrans trimmed with url="https://docs.pretix.eu/guides/customer-accounts/#using-pretix-as-an-sso-provider" %}
For more information, refer to our documentation on <a href="{{ url }}">Using pretix as an SSO provider with external SSO clients</a>.
{% endblocktrans %}
</p>
<a href="{% url "control:organizer.ssoclient.add" organizer=request.organizer.slug %}" class="btn btn-default">
<span class="fa fa-plus"></span>
{% trans "Create credentials for a new SSO client" %}
{% trans "Create a new SSO client" %}
</a>
<table class="table table-condensed table-hover">
<thead>
@@ -1,24 +1,12 @@
{% extends "pretixcontrol/organizers/base.html" %}
{% load i18n %}
{% load bootstrap3 %}
{% block title %}
{% if provider %}
{% trans "External SSO provider:" %} {{ provider.name }}
{% else %}
{% trans "Connect to an external SSO provider" %}
{% endif %}
{% endblock %}
{% block inner %}
{% if provider %}
<h1>{% trans "External SSO provider:" %} {{ provider.name }}</h1>
<h1>{% trans "SSO provider:" %} {{ provider.name }}</h1>
{% else %}
<h1>{% trans "Connect to an external SSO provider" %}</h1>
<h1>{% trans "Create a new SSO provider" %}</h1>
{% endif %}
<p>
{% blocktrans trimmed with url="https://docs.pretix.eu/guides/customer-accounts/#using-pretix-as-an-sso-client" %}
For more information, refer to our documentation on <a href="{{ url }}" target="_blank">Using pretix as an SSO client</a>.
{% endblocktrans %}
</p>
<form class="form-horizontal" action="" method="post">
{% csrf_token %}
{% bootstrap_form form layout="control" %}
@@ -3,23 +3,16 @@
{% load bootstrap3 %}
{% block title %}{% trans "SSO providers" %}{% endblock %}
{% block inner %}
<h1>{% trans "SSO providers" %} <small> &mdash; {% blocktrans %}
Connect to an external login provider
{% endblocktrans %}</small></h1>
<h1>{% trans "SSO providers" %}</h1>
<p>
{% blocktrans trimmed %}
You can connect existing Single-Sign-On (SSO) providers to allow your customers to log in using your own
account system.
{% endblocktrans %}
</p>
<p>
{% blocktrans trimmed with url="https://docs.pretix.eu/guides/customer-accounts/#using-pretix-as-an-sso-client" %}
For more information, refer to our documentation on <a href="{{ url }}" target="_blank">Using pretix as an SSO client</a>.
{% endblocktrans %}
</p>
<a href="{% url "control:organizer.ssoprovider.add" organizer=request.organizer.slug %}" class="btn btn-default">
<span class="fa fa-plus"></span>
{% trans "Connect to an external SSO provider" %}
{% trans "Create a new SSO provider" %}
</a>
<table class="table table-condensed table-hover">
<thead>
+6 -15
View File
@@ -2817,15 +2817,10 @@ class SSOProviderCreateView(OrganizerDetailViewMixin, OrganizerPermissionRequire
return get_object_or_404(CustomerSSOProvider, organizer=self.request.organizer, pk=self.kwargs.get('provider'))
def get_success_url(self):
return reverse('control:organizer.ssoprovider.edit', kwargs={
'organizer': self.request.organizer.slug, 'provider': self.object.pk,
return reverse('control:organizer.ssoproviders', kwargs={
'organizer': self.request.organizer.slug,
})
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
ctx['redirect_uri'] = _('(will be generated)')
return ctx
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['event'] = self.request.organizer
@@ -2955,11 +2950,8 @@ class SSOClientCreateView(OrganizerDetailViewMixin, OrganizerPermissionRequiredM
secret = form.instance.set_client_secret()
messages.success(
self.request,
_('The SSO client has been created.') + ' ' +
_('Please note down the following client secret, it will never be shown again.') + '\n\n' +
_('Base URL / issuer') + f': {form.initial["disp_base_url"]}\n\n' +
_('Client ID') + f': {form.instance.client_id}\n\n' +
_('Client secret') + f': {secret}'
_('The SSO client has been created. Please note down the following client secret, it will never be shown '
'again: {secret}').format(secret=secret)
)
form.instance.organizer = self.request.organizer
ret = super().form_valid(form)
@@ -3008,9 +3000,8 @@ class SSOClientUpdateView(OrganizerDetailViewMixin, OrganizerPermissionRequiredM
secret = form.instance.set_client_secret()
messages.success(
self.request,
_('Your changes have been saved.') + ' ' +
_('Please note down the following client secret, it will never be shown again.') + '\n\n' +
_('Client secret') + f': {secret}'
_('Your changes have been saved. Please note down the following client secret, it will never be shown '
'again: {secret}').format(secret=secret)
)
else:
messages.success(
+4 -4
View File
@@ -5,8 +5,8 @@ msgstr ""
"Project-Id-Version: 1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-30 07:26+0000\n"
"PO-Revision-Date: 2026-10-13 14:40+0000\n"
"Last-Translator: Martin Gross <gross@rami.io>\n"
"PO-Revision-Date: 2026-09-30 08:06+0000\n"
"Last-Translator: Phin Wolkwitz <wolkwitz@pretix.eu>\n"
"Language-Team: German <https://translate.pretix.eu/projects/pretix/pretix/"
"de/>\n"
"Language: de\n"
@@ -14,7 +14,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 2026.10\n"
"X-Generator: Weblate 2026.9.1\n"
"X-Poedit-Bookmarks: -1,-1,904,-1,-1,-1,-1,-1,-1,-1\n"
#: pretix/_base_settings.py
@@ -34449,7 +34449,7 @@ msgstr ""
#: pretix/presale/forms/customer.py
msgid "Forgot your password?"
msgstr "Passwort vergessen?"
msgstr "Passwort zurücksetzen"
#: pretix/presale/forms/customer.py
msgid ""
+3 -3
View File
@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-30 07:26+0000\n"
"PO-Revision-Date: 2026-10-13 14:40+0000\n"
"Last-Translator: Martin Gross <gross@rami.io>\n"
"PO-Revision-Date: 2026-07-06 02:00+0000\n"
"Last-Translator: Benedikt Bormann <mail@bbormann.de>\n"
"Language-Team: German <https://translate.pretix.eu/projects/pretix/pretix-js/"
"de/>\n"
"Language: de\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 2026.10\n"
"X-Generator: Weblate 2026.6.1\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js
msgid "Marked as paid"
@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: 1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-30 07:26+0000\n"
"PO-Revision-Date: 2026-10-13 14:40+0000\n"
"Last-Translator: Martin Gross <gross@rami.io>\n"
"PO-Revision-Date: 2026-09-30 08:09+0000\n"
"Last-Translator: Raphael Michel <michel@rami.io>\n"
"Language-Team: German (informal) <https://translate.pretix.eu/projects/"
"pretix/pretix/de_Informal/>\n"
"Language: de_Informal\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 2026.10\n"
"X-Generator: Weblate 2026.9.1\n"
#: pretix/_base_settings.py
msgid "English"
+26 -22
View File
@@ -8,16 +8,16 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-30 07:26+0000\n"
"PO-Revision-Date: 2026-10-23 13:02+0000\n"
"Last-Translator: Martin Gross <gross@rami.io>\n"
"Language-Team: Basque <https://translate.pretix.eu/projects/pretix/pretix/"
"eu/>\n"
"PO-Revision-Date: 2026-09-04 14:29+0000\n"
"Last-Translator: Albizuri <oier@puntu.eus>\n"
"Language-Team: Basque <https://translate.pretix.eu/projects/pretix/pretix/eu/"
">\n"
"Language: eu\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 2026.10.1\n"
"X-Generator: Weblate 2026.9\n"
#: pretix/_base_settings.py
msgid "English"
@@ -36,9 +36,8 @@ msgid "Arabic"
msgstr "Arabiera"
#: pretix/_base_settings.py
#, fuzzy
msgid "Basque"
msgstr "Euskera"
msgstr ""
#: pretix/_base_settings.py
msgid "Catalan"
@@ -1172,9 +1171,10 @@ msgid "Check-in datetime on list {}"
msgstr "Izen-emate zerrendak"
#: pretix/base/datasync/sourcefields.py
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid "Question {val}"
msgid "Question: {name}"
msgstr "Galdera {name}"
msgstr "Galdera {val}"
#: pretix/base/datasync/sourcefields.py pretix/base/settings.py
msgid "Given name"
@@ -1295,7 +1295,7 @@ msgstr ""
#: pretix/control/navigation.py
#: pretix/control/templates/pretixcontrol/organizers/customers.html
msgid "Customers"
msgstr "Bezeroak"
msgstr ""
#: pretix/base/exporters/customers.py pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/organizers/customer.html
@@ -3096,7 +3096,7 @@ msgstr "Helbide elektronikoa"
#: pretix/base/forms/auth.py pretix/control/forms/orders.py
#: pretix/control/templates/pretixcontrol/shredder/download.html
msgid "Confirmation code"
msgstr "Baieztatze kodea"
msgstr ""
#: pretix/base/forms/questions.py
#, fuzzy
@@ -3162,7 +3162,7 @@ msgstr ""
#: pretix/base/forms/questions.py
msgid "Street"
msgstr "Kalea"
msgstr ""
#: pretix/base/forms/questions.py
msgid "State"
@@ -3430,9 +3430,11 @@ msgid "Exchange System (SdI)"
msgstr ""
#: pretix/base/invoicing/national.py
#, fuzzy
#| msgid "Gift card code"
msgctxt "italian_invoice"
msgid "Fiscal code"
msgstr "Kode fiskala"
msgstr "Opari-txartelaren kodea"
#: pretix/base/invoicing/national.py
msgctxt "italian_invoice"
@@ -3759,8 +3761,10 @@ msgid "The relevant plugin is currently not active."
msgstr "Produktu hau ez dago eskuragarri."
#: pretix/base/logentrytypes.py
#, fuzzy
#| msgid "Order deleted"
msgid "(deleted)"
msgstr "(Ezabatutako eskaera)"
msgstr "Ezabatutako eskaera"
#: pretix/base/logentrytypes.py
#, python-brace-format
@@ -6230,13 +6234,13 @@ msgstr "Amaiera"
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mail.html
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mails.html
msgid "queued"
msgstr "zerrendan"
msgstr ""
#: pretix/base/models/mail.py
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mail.html
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mails.html
msgid "being sent"
msgstr "bidaltzen"
msgstr ""
#: pretix/base/models/mail.py
#, fuzzy
@@ -6260,7 +6264,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mail.html
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mails.html
msgid "sent"
msgstr "bidalita"
msgstr ""
#: pretix/base/models/mail.py
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mail.html
@@ -6638,7 +6642,7 @@ msgstr "Egiaztatzeak huts egin du"
#: pretix/base/models/orders.py pretix/control/views/event.py
#: pretix/control/views/organizer.py
msgid "Other"
msgstr "Beste bat"
msgstr ""
#: pretix/base/models/organizer.py
msgid ""
@@ -6795,7 +6799,7 @@ msgstr "Ordainketa itzuli"
#, fuzzy
#| msgid "Tax rate"
msgid "Tax free"
msgstr "Zergarik ez"
msgstr "Zerga-tasa"
#: pretix/base/models/tax.py
msgctxt "tax_code"
@@ -14803,7 +14807,7 @@ msgstr ""
#: pretix/control/forms/event.py
msgid "European Union"
msgstr "Europar Batasuna"
msgstr ""
#: pretix/control/forms/event.py
msgid "Any customer"
@@ -18745,7 +18749,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/auth/login.html
#: pretix/control/templates/pretixcontrol/auth/register.html
msgid "Register"
msgstr "Berretsi"
msgstr ""
#: pretix/control/templates/pretixcontrol/auth/login.html
msgid ""
@@ -21605,7 +21609,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/fragment_quota_box_paid.html
#, python-format
msgid "Currently available: %(num)s"
msgstr "Eskuragarri gaur egun: %(num)s"
msgstr ""
#: pretix/control/templates/pretixcontrol/global_license.html
msgid ""
+11 -11
View File
@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-30 07:26+0000\n"
"PO-Revision-Date: 2026-10-23 13:02+0000\n"
"Last-Translator: Martin Gross <gross@rami.io>\n"
"PO-Revision-Date: 2026-07-29 11:04+0000\n"
"Last-Translator: Albizuri <oier@puntu.eus>\n"
"Language-Team: Basque <https://translate.pretix.eu/projects/pretix/pretix-js/"
"eu/>\n"
"Language: eu\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 2026.10.1\n"
"X-Generator: Weblate 2026.7.1\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js
msgid "Marked as paid"
@@ -870,7 +870,7 @@ msgstr ""
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Register"
msgstr "Erregistratu"
msgstr ""
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
@@ -917,7 +917,7 @@ msgstr ""
#, javascript-format
msgctxt "widget"
msgid "currently available: %s"
msgstr "Eskuragarri gaur egun: %s"
msgstr ""
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
@@ -1054,32 +1054,32 @@ msgstr ""
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Choose a different date"
msgstr "Beste data bat aukera"
msgstr ""
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Back"
msgstr "Atzera"
msgstr ""
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Next month"
msgstr "Hurrengo hilabetea"
msgstr ""
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Previous month"
msgstr "Aurreko hilabetea"
msgstr ""
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Next week"
msgstr "Hurrengo astea"
msgstr ""
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Previous week"
msgstr "Aurreko astea"
msgstr ""
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
File diff suppressed because it is too large. Load diff
+3 -3
View File
@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-30 07:26+0000\n"
"PO-Revision-Date: 2026-10-13 14:40+0000\n"
"Last-Translator: Martin Gross <gross@rami.io>\n"
"PO-Revision-Date: 2025-10-28 17:00+0000\n"
"Last-Translator: Sven Muhlen <sven.muhlen@bnl.etat.lu>\n"
"Language-Team: Luxembourgish <https://translate.pretix.eu/projects/pretix/"
"pretix/lb/>\n"
"Language: lb\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 2026.10\n"
"X-Generator: Weblate 5.14\n"
#: pretix/_base_settings.py
msgid "English"
+38 -22
View File
@@ -7,16 +7,16 @@ msgstr ""
"Project-Id-Version: 1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-30 07:26+0000\n"
"PO-Revision-Date: 2026-10-19 02:00+0000\n"
"Last-Translator: Christiaan de Die le Clercq <contact@techwolf12.nl>\n"
"Language-Team: Dutch <https://translate.pretix.eu/projects/pretix/pretix/nl/>"
"\n"
"PO-Revision-Date: 2026-05-05 13:26+0000\n"
"Last-Translator: Ruud Hendrickx <ruud@leckxicon.eu>\n"
"Language-Team: Dutch <https://translate.pretix.eu/projects/pretix/pretix/nl/"
">\n"
"Language: nl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 2026.10.1\n"
"X-Generator: Weblate 5.17.1\n"
#: pretix/_base_settings.py
msgid "English"
@@ -92,7 +92,7 @@ msgstr "Hebreeuws"
#: pretix/_base_settings.py
msgid "Hungarian"
msgstr "Hongaars"
msgstr ""
#: pretix/_base_settings.py
msgid "Indonesian"
@@ -152,7 +152,7 @@ msgstr "Spaans (Latijns-Amerika)"
#: pretix/_base_settings.py
msgid "Thai"
msgstr "Thais"
msgstr ""
#: pretix/_base_settings.py
msgid "Turkish"
@@ -412,7 +412,7 @@ msgstr ""
#: pretix/api/serializers/organizer.py pretix/control/views/organizer.py
#, python-format
msgid "You've been invited to join %(organizer)s"
msgstr "Je bent uitgenodigd voor %(organizer)s"
msgstr ""
#: pretix/api/serializers/organizer.py pretix/control/views/organizer.py
msgid "This user already has been invited for this team."
@@ -432,12 +432,16 @@ msgid "Medium connected to other event"
msgstr "Het medium is verbonden met een ander evenement"
#: pretix/api/views/checkin.py
#, fuzzy
#| msgid "You cannot change this order."
msgid "You cannot exchange a medium for a medium."
msgstr "Je kunt geen medium inwisselen voor een medium."
msgstr "U kunt deze bestelling niet wijzigen."
#: pretix/api/views/checkin.py
#, fuzzy
#| msgid "You cannot change this order."
msgid "You cannot simulate a medium exchange."
msgstr "Je kunt een wisseling van medium niet simuleren."
msgstr "U kunt deze bestelling niet wijzigen."
#: pretix/api/views/oauth.py pretix/control/logdisplay.py
#, python-brace-format
@@ -595,17 +599,16 @@ msgstr ""
"objecten zoals varianten of bundels."
#: pretix/api/webhooks.py
#, fuzzy
#| msgid "Quota handling"
msgid "Quota changed"
msgstr "Quotum gewijzigd"
msgstr "Quotabeheer"
#: pretix/api/webhooks.py
msgid ""
"This includes related events like creation, deletion, opening or closing of "
"quotas. No webhook is sent for changes to the resulting availability."
msgstr ""
"Dit omvat gerelateerde gebeurtenissen zoals het aanmaken, verwijderen, "
"openen of sluiten van quota. Er wordt geen webhook verzonden voor "
"wijzigingen in de resulterende beschikbaarheid."
#: pretix/api/webhooks.py
msgid "Shop taken live"
@@ -1392,8 +1395,10 @@ msgid "Membership type"
msgstr "Lidmaatschapstype"
#: pretix/base/exporters/customers.py
#, fuzzy
#| msgid "Purchase time"
msgid "Purchase ticket"
msgstr "Ticket kopen"
msgstr "Aankooptijd"
#: pretix/base/exporters/customers.py pretix/base/exporters/orderlist.py
#: pretix/base/exporters/waitinglist.py pretix/base/forms/questions.py
@@ -1410,8 +1415,10 @@ msgid "Start date"
msgstr "Startdatum"
#: pretix/base/exporters/customers.py
#, fuzzy
#| msgid "Start time from"
msgid "Start time"
msgstr "Starttijd"
msgstr "Starttijd vanaf"
#: pretix/base/exporters/customers.py pretix/base/exporters/orderlist.py
#: pretix/base/exporters/waitinglist.py pretix/base/models/memberships.py
@@ -1424,8 +1431,10 @@ msgid "End date"
msgstr "Einddatum"
#: pretix/base/exporters/customers.py
#, fuzzy
#| msgid "End: %(time)s"
msgid "End time"
msgstr "Eindtijd"
msgstr "Einde: %(time)s"
#: pretix/base/exporters/dekodi.py pretix/base/exporters/invoices.py
msgctxt "export_category"
@@ -1785,12 +1794,16 @@ msgid "Transmission type"
msgstr "Verzendingstype"
#: pretix/base/exporters/invoices.py
#, fuzzy
#| msgid "Transmission type"
msgid "Transmission status"
msgstr "Verzendstatus"
msgstr "Verzendingstype"
#: pretix/base/exporters/invoices.py
#, fuzzy
#| msgid "Transmission type"
msgid "Transmission date"
msgstr "Verzendingsdatum"
msgstr "Verzendingstype"
#: pretix/base/exporters/invoices.py
msgid "Cancellation"
@@ -3028,12 +3041,11 @@ msgid ""
"The field \"%(label)s\" may not contain special characters such as "
"\"%(chars)s\"."
msgstr ""
"Het veld \"%(label)s\" mag geen speciale tekens zoals \"%(chars)s\" bevatten."
#: pretix/base/forms/questions.py
#, python-format
msgid "The field \"%(label)s\" may not contain an URL (%(url)s)."
msgstr "Het veld \"%(label)s\" mag geen URL (%(url)s) bevatten."
msgstr ""
#: pretix/base/forms/questions.py
msgctxt "phonenumber"
@@ -4095,8 +4107,10 @@ msgid "Users"
msgstr "Gebruikers"
#: pretix/base/models/auth.py
#, fuzzy
#| msgid "Changes to your account at {organizer}"
msgid "Changes to your account"
msgstr "Wijzigingen in uw account"
msgstr "Wijzigingen in uw account bij {organizer}"
#: pretix/base/models/auth.py
#, fuzzy, python-brace-format
@@ -4122,6 +4136,8 @@ msgstr ""
"naar {new_email}, gebruikt u de volgende code:"
#: pretix/base/models/auth.py
#, fuzzy
#| msgid "Enter confirmation code"
msgid "Your confirmation code"
msgstr "Voer bevestigingscode in"
-3
View File
@@ -633,9 +633,6 @@ class ImportView(ListView):
class OrganizerBanktransferView:
def dispatch(self, request, *args, **kwargs):
# Users can use the bank transfer views if they have sufficient permission for at least one event.
# Yes, this allows them to cauase changes in events they don't have access to. This is an accepted
# risk because every other way, the bank transfer feature becomes basically unusable.
has_any_event_perm = request.user.get_events_with_permission(
"event.orders:write", request=request
).filter(organizer=request.organizer).exists()
@@ -97,7 +97,7 @@ var pretixpaypal = {
let sdk_url = 'https://www.paypal.com/sdk/js'
+ '?client-id=' + pretixpaypal.client_id
+ '&components=buttons,funding-eligibility,messages'
+ '&components=buttons,funding-eligibility'
+ '&currency=' + pretixpaypal.currency
if (pretixpaypal.locale) {
@@ -195,12 +195,6 @@ var pretixpaypal = {
label: 'pay',
tagline: false
},
message: {
amount: undefined,
align: 'center',
color: 'black',
position: 'bottom'
},
createOrder: function (data, actions) {
if (pretixpaypal.order_id) {
return pretixpaypal.order_id
@@ -291,18 +285,6 @@ var pretixpaypal = {
if (button.isEligible()) {
eligibles.push(gettext(pretixpaypal.apm_map[fundingSource] || fundingSource))
if (fundingSource === 'paylater') {
pretixpaypal.paypal.Messages({
pageType: 'payment',
style: {
layout: 'text',
logo: {
type: 'none',
}
}
}).render('.pp-message');
}
}
})
@@ -14,7 +14,6 @@
After you clicked continue, we will be able to select how you want to pay and to fill in your payment
details. You will then be redirected back here to review and confirm your order.
{% endblocktrans %}
<div class="pp-message"></div>
{% endif %}
</p>
@@ -172,9 +172,6 @@ var pretixstripe = {
})
pretixstripe.affirm.mount('#stripe-affirm')
pretixstripe.affirm.on('ready', function () {
$('.stripe-container').closest('form').find('.checkout-button-row .btn-primary').prop('disabled', false)
})
}
if ($('#stripe-klarna').length) {
try {
@@ -186,9 +183,6 @@ var pretixstripe = {
})
pretixstripe.klarna.mount('#stripe-klarna')
pretixstripe.klarna.on('ready', function () {
$('.stripe-container').closest('form').find('.checkout-button-row .btn-primary').prop('disabled', false)
})
} catch (e) {
console.error(e)
$('#stripe-klarna').html('<div class=\'alert alert-danger\'>Technical error, please contact support: ' + e + '</div>')
+1 -2
View File
@@ -506,8 +506,7 @@ REST_FRAMEWORK = {
'pretix.testutils.api.UploadRenderer',
],
'EXCEPTION_HANDLER': 'pretix.api.exception.custom_exception_handler',
'UNICODE_JSON': False,
'LIST_SERIALIZER_ERRORS_AS_DICT': False
'UNICODE_JSON': False
}
@@ -20,7 +20,7 @@ function pgettext (context, msgid) {
return msgid
}
function interpolate (fmt, obj, named) {
function interpolate (fmt, object, named) {
if (named) {
return fmt.replace(/%\(\w+\)s/g, function (match) { return String(obj[match.slice(2, -2)]) })
} else {
-1
View File
@@ -57,7 +57,6 @@ filterwarnings =
ignore:teardown:pytest.PytestWarning
ignore:avoid running initialization queries:RuntimeWarning
ignore:.*The 'strip_cdata' option of HTMLParser.*:DeprecationWarning:
ignore:The list-based error format for `ListSerializer`:rest_framework.deprecation.RemovedInDRF320Warning
[coverage:run]
-93
View File
@@ -1070,99 +1070,6 @@ def test_event_update_live_free_product(token_client, organizer, event, free_ite
assert resp.status_code == 200
@pytest.mark.django_db
def test_event_update_live_required_meta_data_missing(token_client, organizer, event, free_quota):
organizer.meta_properties.create(name="required_prop", required=True)
resp = token_client.patch(
'/api/v1/organizers/{}/events/{}/'.format(organizer.slug, event.slug),
{
"live": True
},
format='json'
)
assert resp.status_code == 400
assert list(resp.data.keys()) == ['live']
assert len(resp.data['live']) == 1
assert '<a' not in resp.data['live'][0]
assert 'required_prop' in resp.data['live'][0]
event.refresh_from_db()
assert not event.live
@pytest.mark.django_db
def test_event_update_live_required_meta_data_set_in_same_request(token_client, organizer, event, free_quota):
organizer.meta_properties.create(name="required_prop", required=True)
resp = token_client.patch(
'/api/v1/organizers/{}/events/{}/'.format(organizer.slug, event.slug),
{
"live": True,
"meta_data": {
"type": "Conference",
"required_prop": "set",
}
},
format='json'
)
assert resp.status_code == 200
assert resp.data['live'] is True
event.refresh_from_db()
assert event.live
with scopes_disabled():
assert event.meta_values.filter(property__name="required_prop", value="set").exists()
@pytest.mark.django_db
def test_live_event_update_removing_required_meta_data(token_client, organizer, event, free_quota):
prop = organizer.meta_properties.create(name="required_prop", required=True)
with scopes_disabled():
event.meta_values.create(property=prop, value="set")
event.live = True
event.save()
resp = token_client.patch(
'/api/v1/organizers/{}/events/{}/'.format(organizer.slug, event.slug),
{
"meta_data": {
"type": "Conference",
}
},
format='json'
)
assert resp.status_code == 400
assert list(resp.data.keys()) == ['live']
assert 'required_prop' in resp.data['live'][0]
event.refresh_from_db()
assert event.live
with scopes_disabled():
assert event.meta_values.filter(property__name="required_prop", value="set").exists()
@pytest.mark.django_db
def test_live_event_update_removing_required_meta_data_while_going_offline(token_client, organizer, event, free_quota):
prop = organizer.meta_properties.create(name="required_prop", required=True)
with scopes_disabled():
event.meta_values.create(property=prop, value="set")
event.live = True
event.save()
resp = token_client.patch(
'/api/v1/organizers/{}/events/{}/'.format(organizer.slug, event.slug),
{
"live": False,
"meta_data": {
"type": "Conference",
}
},
format='json'
)
assert resp.status_code == 200
event.refresh_from_db()
assert not event.live
with scopes_disabled():
assert not event.meta_values.filter(property__name="required_prop").exists()
@pytest.mark.django_db
def test_event_update_plugins(token_client, organizer, event, free_item, free_quota):
resp = token_client.patch(
+1
View File
@@ -1000,6 +1000,7 @@ def test_item_create_with_bundle(token_client, organizer, event, item, category,
"bundles": [
{
"bundled_item": i.pk,
"bundled_variation": None,
"count": 2,
"designated_price": "3.00",
}
-4
View File
@@ -642,8 +642,6 @@ def assert_mail_connection(res, should_connect, use_ssl):
True, False
])
def test_private_smtp_ip(res, use_ssl, settings):
settings.EMAIL_HOST_USER = ''
settings.EMAIL_HOST_PASSWORD = ''
settings.EMAIL_CUSTOM_SMTP_BACKEND = 'pretix.base.email.CheckPrivateNetworkSmtpBackend'
settings.MAIL_CUSTOM_SMTP_ALLOW_PRIVATE_NETWORKS = False
with assert_mail_connection(res=res, should_connect=False, use_ssl=use_ssl), pytest.raises(match="Request to .* blocked"):
@@ -667,8 +665,6 @@ def test_private_smtp_ip(res, use_ssl, settings):
True, False
])
def test_public_smtp_ip(use_ssl, allow_private, settings):
settings.EMAIL_HOST_USER = ''
settings.EMAIL_HOST_PASSWORD = ''
settings.EMAIL_CUSTOM_SMTP_BACKEND = 'pretix.base.email.CheckPrivateNetworkSmtpBackend'
settings.MAIL_CUSTOM_SMTP_ALLOW_PRIVATE_NETWORKS = allow_private
+1 -51
View File
@@ -73,14 +73,6 @@ def _validate_sample_lines(sample_lines, rounding_mode):
assert sum(line.price for line in sample_lines) == Decimal("500.00")
assert sum(line.tax_value for line in sample_lines) == Decimal("79.83")
assert sum(line.price - line.tax_value for line in sample_lines) == Decimal("420.17")
elif rounding_mode == "sum_by_gross":
for line in sample_lines:
assert line.price == Decimal("100.00")
# net price may vary
assert line.tax_rate == Decimal("19.00")
assert sum(line.price for line in sample_lines) == Decimal("500.00")
assert sum(line.tax_value for line in sample_lines) == Decimal("79.83")
assert sum(line.price - line.tax_value for line in sample_lines) == Decimal("420.17")
@pytest.mark.django_db
@@ -93,14 +85,9 @@ def test_simple_case_by_net(sample_lines):
_validate_sample_lines(sample_lines, "sum_by_net")
@pytest.mark.django_db
def test_simple_case_net_by_gross(sample_lines):
_validate_sample_lines(sample_lines, "sum_by_net_keep_gross")
@pytest.mark.django_db
def test_simple_case_by_gross(sample_lines):
_validate_sample_lines(sample_lines, "sum_by_gross")
_validate_sample_lines(sample_lines, "sum_by_net_keep_gross")
@pytest.mark.django_db
@@ -109,7 +96,6 @@ def test_simple_case_switch_rounding(sample_lines):
_validate_sample_lines(sample_lines, "sum_by_net_keep_gross")
_validate_sample_lines(sample_lines, "line")
_validate_sample_lines(sample_lines, "sum_by_net")
_validate_sample_lines(sample_lines, "sum_by_gross")
@pytest.mark.django_db
@@ -148,24 +134,6 @@ def test_revert_net_keep_gross_rounding_to_single_line(sample_lines):
assert l.tax_rate == Decimal("19.00")
@pytest.mark.django_db
def test_revert_gross_rounding_to_single_line(sample_lines):
l = OrderPosition(
price=Decimal("100.00"),
price_includes_rounding_correction=Decimal("0.00"),
tax_value=Decimal("15.96"),
tax_value_includes_rounding_correction=Decimal("-0.01"),
tax_rate=Decimal("19.00"),
tax_code="S",
)
apply_rounding("sum_by_gross", None, "EUR", [l])
assert l.price == Decimal("100.00")
assert l.price_includes_rounding_correction == Decimal("0.00")
assert l.tax_value == Decimal("15.97")
assert l.tax_value_includes_rounding_correction == Decimal("0.00")
assert l.tax_rate == Decimal("19.00")
@pytest.mark.django_db
@pytest.mark.parametrize("rounding_mode", [
"sum_by_net",
@@ -184,24 +152,6 @@ def test_rounding_of_impossible_gross_price(rounding_mode):
assert l.tax_rate == Decimal("7.00")
@pytest.mark.django_db
@pytest.mark.parametrize("rounding_mode", [
"sum_by_gross",
"line",
])
def test_rounding_of_impossible_gross_price_possible_when_not_rounding_by_net(rounding_mode):
l = OrderPosition(
price=Decimal("23.00"),
)
l._calculate_tax(tax_rule=TaxRule(rate=Decimal("7.00")), invoice_address=InvoiceAddress())
apply_rounding(rounding_mode, None, "EUR", [l])
assert l.price == Decimal("23.00")
assert l.price_includes_rounding_correction == Decimal("0.00")
assert l.tax_value == Decimal("1.50")
assert l.tax_value_includes_rounding_correction == Decimal("0.00")
assert l.tax_rate == Decimal("7.00")
@pytest.mark.django_db
def test_round_down():
lines = [OrderPosition(