wip: booking process
This commit is contained in:
Generated
+83
-168
@@ -142,99 +142,6 @@
|
||||
},
|
||||
"time": "2023-06-19T06:10:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/cache",
|
||||
"version": "2.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/cache.git",
|
||||
"reference": "1ca8f21980e770095a31456042471a57bc4c68fb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb",
|
||||
"reference": "1ca8f21980e770095a31456042471a57bc4c68fb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "~7.1 || ^8.0"
|
||||
},
|
||||
"conflict": {
|
||||
"doctrine/common": ">2.2,<2.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"cache/integration-tests": "dev-master",
|
||||
"doctrine/coding-standard": "^9",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
|
||||
"psr/cache": "^1.0 || ^2.0 || ^3.0",
|
||||
"symfony/cache": "^4.4 || ^5.4 || ^6",
|
||||
"symfony/var-exporter": "^4.4 || ^5.4 || ^6"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Guilherme Blanco",
|
||||
"email": "[email protected]"
|
||||
},
|
||||
{
|
||||
"name": "Roman Borschel",
|
||||
"email": "[email protected]"
|
||||
},
|
||||
{
|
||||
"name": "Benjamin Eberlei",
|
||||
"email": "[email protected]"
|
||||
},
|
||||
{
|
||||
"name": "Jonathan Wage",
|
||||
"email": "[email protected]"
|
||||
},
|
||||
{
|
||||
"name": "Johannes Schmitt",
|
||||
"email": "[email protected]"
|
||||
}
|
||||
],
|
||||
"description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.",
|
||||
"homepage": "https://www.doctrine-project.org/projects/cache.html",
|
||||
"keywords": [
|
||||
"abstraction",
|
||||
"apcu",
|
||||
"cache",
|
||||
"caching",
|
||||
"couchdb",
|
||||
"memcached",
|
||||
"php",
|
||||
"redis",
|
||||
"xcache"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/doctrine/cache/issues",
|
||||
"source": "https://github.com/doctrine/cache/tree/2.2.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.doctrine-project.org/sponsorship.html",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://www.patreon.com/phpdoctrine",
|
||||
"type": "patreon"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcache",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-05-20T20:07:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/collections",
|
||||
"version": "2.3.0",
|
||||
@@ -323,28 +230,31 @@
|
||||
},
|
||||
{
|
||||
"name": "doctrine/dbal",
|
||||
"version": "3.9.5",
|
||||
"version": "3.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/dbal.git",
|
||||
"reference": "4a4e2eed3134036ee36a147ee0dac037dfa17868"
|
||||
"reference": "1cf840d696373ea0d58ad0a8875c0fadcfc67214"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/dbal/zipball/4a4e2eed3134036ee36a147ee0dac037dfa17868",
|
||||
"reference": "4a4e2eed3134036ee36a147ee0dac037dfa17868",
|
||||
"url": "https://api.github.com/repos/doctrine/dbal/zipball/1cf840d696373ea0d58ad0a8875c0fadcfc67214",
|
||||
"reference": "1cf840d696373ea0d58ad0a8875c0fadcfc67214",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer-runtime-api": "^2",
|
||||
"doctrine/cache": "^1.11|^2.0",
|
||||
"doctrine/deprecations": "^0.5.3|^1",
|
||||
"doctrine/event-manager": "^1|^2",
|
||||
"php": "^7.4 || ^8.0",
|
||||
"psr/cache": "^1|^2|^3",
|
||||
"psr/log": "^1|^2|^3"
|
||||
},
|
||||
"conflict": {
|
||||
"doctrine/cache": "< 1.11"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/cache": "^1.11|^2.0",
|
||||
"doctrine/coding-standard": "13.0.0",
|
||||
"fig/log-test": "^1",
|
||||
"jetbrains/phpstorm-stubs": "2023.1",
|
||||
@@ -414,7 +324,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/doctrine/dbal/issues",
|
||||
"source": "https://github.com/doctrine/dbal/tree/3.9.5"
|
||||
"source": "https://github.com/doctrine/dbal/tree/3.10.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -430,7 +340,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-06-15T22:40:05+00:00"
|
||||
"time": "2025-07-10T21:11:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/deprecations",
|
||||
@@ -1121,16 +1031,16 @@
|
||||
},
|
||||
{
|
||||
"name": "doctrine/orm",
|
||||
"version": "3.4.3",
|
||||
"version": "3.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/orm.git",
|
||||
"reference": "ef607f26c2965fe460c55733cc7c031fb7e1f2fa"
|
||||
"reference": "6deec3655ba3e8f15280aac11e264225854d2369"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/orm/zipball/ef607f26c2965fe460c55733cc7c031fb7e1f2fa",
|
||||
"reference": "ef607f26c2965fe460c55733cc7c031fb7e1f2fa",
|
||||
"url": "https://api.github.com/repos/doctrine/orm/zipball/6deec3655ba3e8f15280aac11e264225854d2369",
|
||||
"reference": "6deec3655ba3e8f15280aac11e264225854d2369",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1205,9 +1115,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/doctrine/orm/issues",
|
||||
"source": "https://github.com/doctrine/orm/tree/3.4.3"
|
||||
"source": "https://github.com/doctrine/orm/tree/3.5.0"
|
||||
},
|
||||
"time": "2025-06-27T12:14:15+00:00"
|
||||
"time": "2025-07-01T17:40:53+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/persistence",
|
||||
@@ -3136,16 +3046,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpseclib/phpseclib",
|
||||
"version": "3.0.45",
|
||||
"version": "3.0.46",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpseclib/phpseclib.git",
|
||||
"reference": "bd81b90d5963c6b9d87de50357585375223f4dd8"
|
||||
"reference": "56483a7de62a6c2a6635e42e93b8a9e25d4f0ec6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/bd81b90d5963c6b9d87de50357585375223f4dd8",
|
||||
"reference": "bd81b90d5963c6b9d87de50357585375223f4dd8",
|
||||
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/56483a7de62a6c2a6635e42e93b8a9e25d4f0ec6",
|
||||
"reference": "56483a7de62a6c2a6635e42e93b8a9e25d4f0ec6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3226,7 +3136,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/phpseclib/phpseclib/issues",
|
||||
"source": "https://github.com/phpseclib/phpseclib/tree/3.0.45"
|
||||
"source": "https://github.com/phpseclib/phpseclib/tree/3.0.46"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -3242,20 +3152,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-06-22T22:54:43+00:00"
|
||||
"time": "2025-06-26T16:29:55+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpdoc-parser",
|
||||
"version": "2.1.0",
|
||||
"version": "2.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpdoc-parser.git",
|
||||
"reference": "9b30d6fd026b2c132b3985ce6b23bec09ab3aa68"
|
||||
"reference": "b9e61a61e39e02dd90944e9115241c7f7e76bfd8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/9b30d6fd026b2c132b3985ce6b23bec09ab3aa68",
|
||||
"reference": "9b30d6fd026b2c132b3985ce6b23bec09ab3aa68",
|
||||
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/b9e61a61e39e02dd90944e9115241c7f7e76bfd8",
|
||||
"reference": "b9e61a61e39e02dd90944e9115241c7f7e76bfd8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3287,9 +3197,9 @@
|
||||
"description": "PHPDoc parser with support for nullable, intersection and generic types",
|
||||
"support": {
|
||||
"issues": "https://github.com/phpstan/phpdoc-parser/issues",
|
||||
"source": "https://github.com/phpstan/phpdoc-parser/tree/2.1.0"
|
||||
"source": "https://github.com/phpstan/phpdoc-parser/tree/2.2.0"
|
||||
},
|
||||
"time": "2025-02-19T13:28:12+00:00"
|
||||
"time": "2025-07-13T07:04:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/cache",
|
||||
@@ -5285,16 +5195,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/flex",
|
||||
"version": "v2.7.1",
|
||||
"version": "v2.8.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/flex.git",
|
||||
"reference": "4ae50d368415a06820739e54d38a4a29d6df9155"
|
||||
"reference": "423c36e369361003dc31ef11c5f15fb589e52c01"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/flex/zipball/4ae50d368415a06820739e54d38a4a29d6df9155",
|
||||
"reference": "4ae50d368415a06820739e54d38a4a29d6df9155",
|
||||
"url": "https://api.github.com/repos/symfony/flex/zipball/423c36e369361003dc31ef11c5f15fb589e52c01",
|
||||
"reference": "423c36e369361003dc31ef11c5f15fb589e52c01",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5333,7 +5243,7 @@
|
||||
"description": "Composer plugin for Symfony",
|
||||
"support": {
|
||||
"issues": "https://github.com/symfony/flex/issues",
|
||||
"source": "https://github.com/symfony/flex/tree/v2.7.1"
|
||||
"source": "https://github.com/symfony/flex/tree/v2.8.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -5349,7 +5259,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-05-28T14:22:54+00:00"
|
||||
"time": "2025-07-05T07:45:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/form",
|
||||
@@ -10515,58 +10425,59 @@
|
||||
},
|
||||
{
|
||||
"name": "friendsofphp/php-cs-fixer",
|
||||
"version": "v3.75.0",
|
||||
"version": "v3.82.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
|
||||
"reference": "399a128ff2fdaf4281e4e79b755693286cdf325c"
|
||||
"reference": "684ed3ab41008a2a4848de8bde17eb168c596247"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/399a128ff2fdaf4281e4e79b755693286cdf325c",
|
||||
"reference": "399a128ff2fdaf4281e4e79b755693286cdf325c",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/684ed3ab41008a2a4848de8bde17eb168c596247",
|
||||
"reference": "684ed3ab41008a2a4848de8bde17eb168c596247",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"clue/ndjson-react": "^1.0",
|
||||
"composer/semver": "^3.4",
|
||||
"composer/xdebug-handler": "^3.0.3",
|
||||
"composer/xdebug-handler": "^3.0.5",
|
||||
"ext-filter": "*",
|
||||
"ext-hash": "*",
|
||||
"ext-json": "*",
|
||||
"ext-tokenizer": "*",
|
||||
"fidry/cpu-core-counter": "^1.2",
|
||||
"php": "^7.4 || ^8.0",
|
||||
"react/child-process": "^0.6.5",
|
||||
"react/child-process": "^0.6.6",
|
||||
"react/event-loop": "^1.0",
|
||||
"react/promise": "^2.0 || ^3.0",
|
||||
"react/promise": "^2.11 || ^3.0",
|
||||
"react/socket": "^1.0",
|
||||
"react/stream": "^1.0",
|
||||
"sebastian/diff": "^4.0 || ^5.1 || ^6.0 || ^7.0",
|
||||
"symfony/console": "^5.4 || ^6.4 || ^7.0",
|
||||
"symfony/event-dispatcher": "^5.4 || ^6.4 || ^7.0",
|
||||
"symfony/filesystem": "^5.4 || ^6.4 || ^7.0",
|
||||
"symfony/finder": "^5.4 || ^6.4 || ^7.0",
|
||||
"symfony/options-resolver": "^5.4 || ^6.4 || ^7.0",
|
||||
"symfony/polyfill-mbstring": "^1.31",
|
||||
"symfony/polyfill-php80": "^1.31",
|
||||
"symfony/polyfill-php81": "^1.31",
|
||||
"symfony/process": "^5.4 || ^6.4 || ^7.2",
|
||||
"symfony/stopwatch": "^5.4 || ^6.4 || ^7.0"
|
||||
"sebastian/diff": "^4.0.6 || ^5.1.1 || ^6.0.2 || ^7.0",
|
||||
"symfony/console": "^5.4.45 || ^6.4.13 || ^7.0",
|
||||
"symfony/event-dispatcher": "^5.4.45 || ^6.4.13 || ^7.0",
|
||||
"symfony/filesystem": "^5.4.45 || ^6.4.13 || ^7.0",
|
||||
"symfony/finder": "^5.4.45 || ^6.4.17 || ^7.0",
|
||||
"symfony/options-resolver": "^5.4.45 || ^6.4.16 || ^7.0",
|
||||
"symfony/polyfill-mbstring": "^1.32",
|
||||
"symfony/polyfill-php80": "^1.32",
|
||||
"symfony/polyfill-php81": "^1.32",
|
||||
"symfony/process": "^5.4.47 || ^6.4.20 || ^7.2",
|
||||
"symfony/stopwatch": "^5.4.45 || ^6.4.19 || ^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"facile-it/paraunit": "^1.3.1 || ^2.6",
|
||||
"infection/infection": "^0.29.14",
|
||||
"justinrainbow/json-schema": "^5.3 || ^6.2",
|
||||
"keradus/cli-executor": "^2.1",
|
||||
"justinrainbow/json-schema": "^5.3 || ^6.4",
|
||||
"keradus/cli-executor": "^2.2",
|
||||
"mikey179/vfsstream": "^1.6.12",
|
||||
"php-coveralls/php-coveralls": "^2.7",
|
||||
"php-coveralls/php-coveralls": "^2.8",
|
||||
"php-cs-fixer/accessible-object": "^1.1",
|
||||
"php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6",
|
||||
"php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6",
|
||||
"phpunit/phpunit": "^9.6.22 || ^10.5.45 || ^11.5.12",
|
||||
"symfony/var-dumper": "^5.4.48 || ^6.4.18 || ^7.2.3",
|
||||
"symfony/yaml": "^5.4.45 || ^6.4.18 || ^7.2.3"
|
||||
"phpunit/phpunit": "^9.6.23 || ^10.5.47 || ^11.5.25",
|
||||
"symfony/polyfill-php84": "^1.32",
|
||||
"symfony/var-dumper": "^5.4.48 || ^6.4.23 || ^7.3.1",
|
||||
"symfony/yaml": "^5.4.45 || ^6.4.23 || ^7.3.1"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-dom": "For handling output formats in XML",
|
||||
@@ -10607,7 +10518,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.75.0"
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.82.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -10615,20 +10526,20 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-03-31T18:40:42+00:00"
|
||||
"time": "2025-07-08T21:13:15+00:00"
|
||||
},
|
||||
{
|
||||
"name": "myclabs/deep-copy",
|
||||
"version": "1.13.1",
|
||||
"version": "1.13.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/myclabs/DeepCopy.git",
|
||||
"reference": "1720ddd719e16cf0db4eb1c6eca108031636d46c"
|
||||
"reference": "faed855a7b5f4d4637717c2b3863e277116beb36"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/1720ddd719e16cf0db4eb1c6eca108031636d46c",
|
||||
"reference": "1720ddd719e16cf0db4eb1c6eca108031636d46c",
|
||||
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/faed855a7b5f4d4637717c2b3863e277116beb36",
|
||||
"reference": "faed855a7b5f4d4637717c2b3863e277116beb36",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -10667,7 +10578,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/myclabs/DeepCopy/issues",
|
||||
"source": "https://github.com/myclabs/DeepCopy/tree/1.13.1"
|
||||
"source": "https://github.com/myclabs/DeepCopy/tree/1.13.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -10675,7 +10586,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-04-29T12:36:36+00:00"
|
||||
"time": "2025-07-05T12:25:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
@@ -12981,16 +12892,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/maker-bundle",
|
||||
"version": "v1.63.0",
|
||||
"version": "v1.64.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/maker-bundle.git",
|
||||
"reference": "69478ab39bc303abfbe3293006a78b09a8512425"
|
||||
"reference": "c86da84640b0586e92aee2b276ee3638ef2f425a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/maker-bundle/zipball/69478ab39bc303abfbe3293006a78b09a8512425",
|
||||
"reference": "69478ab39bc303abfbe3293006a78b09a8512425",
|
||||
"url": "https://api.github.com/repos/symfony/maker-bundle/zipball/c86da84640b0586e92aee2b276ee3638ef2f425a",
|
||||
"reference": "c86da84640b0586e92aee2b276ee3638ef2f425a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -13018,6 +12929,7 @@
|
||||
"symfony/http-client": "^6.4|^7.0",
|
||||
"symfony/phpunit-bridge": "^6.4.1|^7.0",
|
||||
"symfony/security-core": "^6.4|^7.0",
|
||||
"symfony/security-http": "^6.4|^7.0",
|
||||
"symfony/yaml": "^6.4|^7.0",
|
||||
"twig/twig": "^3.0|^4.x-dev"
|
||||
},
|
||||
@@ -13053,7 +12965,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/symfony/maker-bundle/issues",
|
||||
"source": "https://github.com/symfony/maker-bundle/tree/v1.63.0"
|
||||
"source": "https://github.com/symfony/maker-bundle/tree/v1.64.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -13069,20 +12981,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-04-26T01:41:37+00:00"
|
||||
"time": "2025-06-23T16:12:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/phpunit-bridge",
|
||||
"version": "v7.3.0",
|
||||
"version": "v7.3.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/phpunit-bridge.git",
|
||||
"reference": "2eabda563921f21cbce1d1e3247b3c36568905e6"
|
||||
"reference": "71624984d8bcad6acf7a790d4e3ceafe04bc2485"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/2eabda563921f21cbce1d1e3247b3c36568905e6",
|
||||
"reference": "2eabda563921f21cbce1d1e3247b3c36568905e6",
|
||||
"url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/71624984d8bcad6acf7a790d4e3ceafe04bc2485",
|
||||
"reference": "71624984d8bcad6acf7a790d4e3ceafe04bc2485",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -13134,8 +13046,11 @@
|
||||
],
|
||||
"description": "Provides utilities for PHPUnit, especially user deprecation notices management",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"testing"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/phpunit-bridge/tree/v7.3.0"
|
||||
"source": "https://github.com/symfony/phpunit-bridge/tree/v7.3.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -13151,7 +13066,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-05-23T07:26:30+00:00"
|
||||
"time": "2025-06-04T10:09:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/web-profiler-bundle",
|
||||
|
||||
@@ -13,8 +13,8 @@ use App\BusProNet\Model\Notification;
|
||||
use App\BusProNet\Model\PersonalData;
|
||||
use App\BusProNet\Traits\ApiClientTrait;
|
||||
use App\BusProNet\XmlParser\ApiResponseParser;
|
||||
use App\Form\Model\BookingData;
|
||||
use App\Form\Model\RegistrationData;
|
||||
use App\Form\Model\BookingEditDto;
|
||||
use App\Form\Model\RegistrationDto;
|
||||
use League\Flysystem\FilesystemException;
|
||||
use League\Flysystem\FilesystemOperator;
|
||||
use Psr\Log\LoggerInterface;
|
||||
@@ -65,7 +65,7 @@ class ApiClient
|
||||
/**
|
||||
* @throws ApiClientException
|
||||
*/
|
||||
public function register(RegistrationData $registrationData): Notification
|
||||
public function register(RegistrationDto $registrationData): Notification
|
||||
{
|
||||
$data = [
|
||||
'user' => $this->config['bpn_username'],
|
||||
@@ -184,7 +184,7 @@ class ApiClient
|
||||
/**
|
||||
* @throws ApiClientException
|
||||
*/
|
||||
public function updateBooking(BookingData $formData, bool $debug = false): Notification|BookingUpdate
|
||||
public function updateBooking(BookingEditDto $formData, bool $debug = false): Notification|BookingUpdate
|
||||
{
|
||||
$payload = (new BookingDataProcessor())->createUpdateRequestPayload($formData);
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\BusProNet;
|
||||
|
||||
final class Constants
|
||||
{
|
||||
public const SOURCE_TRAVEL = 'travel';
|
||||
public const SOURCE_BOOKING = 'booking';
|
||||
|
||||
public const CATEGORY_ADDITIONAL = 'additional';
|
||||
public const CATEGORY_TRANSPORTATION = 'transportation';
|
||||
|
||||
public const TOKEN_COURSES = 'KUR';
|
||||
public const TOKEN_SKI_PASS = 'SPA';
|
||||
public const TOKEN_ADDITIONAL = 'SON';
|
||||
public const TOKEN_BOARD = 'VPF';
|
||||
public const TOKEN_RENTALS = ['VER', 'VE2', 'VE3', 'VE4', 'VE5', 'VE6', 'VE7', 'VE8'];
|
||||
|
||||
public const STATUS_AVAILABLE = 'Frei';
|
||||
public const STATUS_BLOCKED = 'Buchungsstop';
|
||||
public const STATUS_ON_REQUEST = 'Anfrage';
|
||||
}
|
||||
@@ -3,19 +3,26 @@
|
||||
namespace App\BusProNet\DataProcessor;
|
||||
|
||||
use App\BusProNet\Model\Communication;
|
||||
use App\Form\Model\BookingData;
|
||||
use App\Form\Model\BookingEditDto;
|
||||
|
||||
class BookingDataProcessor
|
||||
{
|
||||
public function createUpdateRequestPayload(?BookingData $formData): array
|
||||
public function createUpdateRequestPayload(?BookingEditDto $formData): array
|
||||
{
|
||||
$bookingData = $formData->booking;
|
||||
$travelData = $formData->travel;
|
||||
|
||||
// Reset mappings
|
||||
foreach ([...$bookingData->additionalServices, ...$bookingData->transportationServices, ...$bookingData->pickupsTo, ...$bookingData->pickupsFro] as $service) {
|
||||
$servicesToReset = [
|
||||
...$bookingData->additionalServices,
|
||||
...$bookingData->transportationServices,
|
||||
...$bookingData->pickupsTo,
|
||||
...$bookingData->pickupsFro,
|
||||
];
|
||||
foreach ($servicesToReset as $service) {
|
||||
$service->mapping = [];
|
||||
}
|
||||
|
||||
// Update mappings, add services and pickups
|
||||
foreach ($formData->participants as $participant) {
|
||||
// skip canceled participants
|
||||
|
||||
@@ -1,25 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
/**
|
||||
* Represents a physical address with street, postal code, city, and country information.
|
||||
*
|
||||
* This class handles address data for users and participants in the booking system.
|
||||
* It provides validation constraints for required fields and methods to convert
|
||||
* address data to API payload format.
|
||||
*/
|
||||
class Address
|
||||
{
|
||||
#[Assert\NotBlank(message: 'Bitte angeben', groups: ['personal_data'])]
|
||||
public ?string $street = '';
|
||||
public string $street = '';
|
||||
|
||||
#[Assert\NotBlank(message: 'Bitte angeben', groups: ['personal_data'])]
|
||||
public ?string $postCode = '';
|
||||
public string $postCode = '';
|
||||
|
||||
#[Assert\NotBlank(message: 'Bitte angeben', groups: ['personal_data'])]
|
||||
public ?string $city = '';
|
||||
public string $city = '';
|
||||
|
||||
public ?string $district = '';
|
||||
public string $district = '';
|
||||
|
||||
#[Assert\NotBlank(message: 'Bitte angeben', groups: ['personal_data'])]
|
||||
public ?string $country = '';
|
||||
public string $country = '';
|
||||
|
||||
/**
|
||||
* Converts the address to API payload format.
|
||||
*
|
||||
* Transforms the address object into an array structure suitable
|
||||
* for API communication with the BusProNet system.
|
||||
*
|
||||
* @return array<string, string> The payload array for API transmission
|
||||
*/
|
||||
public function toPayload(): array
|
||||
{
|
||||
return [
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
/**
|
||||
* Represents service availability with status and pricing information.
|
||||
*
|
||||
* This class handles availability data including service identification,
|
||||
* status, available quantity, and pricing. It implements JsonSerializable
|
||||
* for API response formatting.
|
||||
*/
|
||||
class Availability implements \JsonSerializable
|
||||
{
|
||||
public ?int $serviceId = null;
|
||||
@@ -9,6 +18,14 @@ class Availability implements \JsonSerializable
|
||||
public ?int $available = null;
|
||||
public ?float $price = null;
|
||||
|
||||
/**
|
||||
* Serializes the availability data to JSON format.
|
||||
*
|
||||
* Converts the availability object to an array structure suitable
|
||||
* for JSON serialization in API responses.
|
||||
*
|
||||
* @return array<string, mixed> The serialized availability data
|
||||
*/
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return [
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
/**
|
||||
* Represents a bank account with payment information.
|
||||
*
|
||||
* This class handles bank account data including IBAN, BIC, bank name,
|
||||
* and account holder information for payment processing.
|
||||
*/
|
||||
class BankAccount
|
||||
{
|
||||
public ?string $iban = null;
|
||||
|
||||
@@ -1,18 +1,38 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
/**
|
||||
* Represents base data with item collection and retrieval functionality.
|
||||
*
|
||||
* This class provides a container for generic data items with methods
|
||||
* to access the entire collection or individual items by key.
|
||||
*/
|
||||
class BaseData
|
||||
{
|
||||
public function __construct(private readonly array $items)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all items in the base data collection.
|
||||
*
|
||||
* @return array The complete items array
|
||||
*/
|
||||
public function getItems(): array
|
||||
{
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a specific item by its key.
|
||||
*
|
||||
* @param string $key The key to search for
|
||||
*
|
||||
* @return mixed The item value or null if not found
|
||||
*/
|
||||
public function getItemByKey(string $key): mixed
|
||||
{
|
||||
return $this->items[$key] ?? null;
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
/**
|
||||
* Represents a booking with participants, services, and pricing information.
|
||||
*
|
||||
* This class handles complete booking data including participant information,
|
||||
* selected services, transportation details, accommodation, and pricing calculations.
|
||||
* It provides methods to retrieve participant-specific data and calculate costs.
|
||||
*/
|
||||
class Booking
|
||||
{
|
||||
public ?int $id = null;
|
||||
@@ -12,7 +21,7 @@ class Booking
|
||||
public ?int $participantCount = null;
|
||||
public ?float $price = null;
|
||||
public ?\DateTimeImmutable $bookingDate = null;
|
||||
public ?string $travel = null;
|
||||
public ?string $travelName = null;
|
||||
public ?int $travelId = null;
|
||||
public ?string $travelCode = null;
|
||||
public ?\DateTimeImmutable $travelDate = null;
|
||||
@@ -37,6 +46,14 @@ class Booking
|
||||
public ?float $totalPrice = null;
|
||||
public ?string $travelInfoUrl = null;
|
||||
|
||||
/**
|
||||
* Calculates the remaining balance for the booking.
|
||||
*
|
||||
* Returns the difference between the total price and any payments made.
|
||||
* If no payment has been made, returns the full price.
|
||||
*
|
||||
* @return float The remaining balance amount
|
||||
*/
|
||||
public function getBalance(): float
|
||||
{
|
||||
if (null === $this->payment) {
|
||||
@@ -46,6 +63,16 @@ class Booking
|
||||
return $this->price - $this->payment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves additional services filtered by group.
|
||||
*
|
||||
* Filters the additional services array based on the provided group(s).
|
||||
* Supports both single group strings and arrays of groups.
|
||||
*
|
||||
* @param mixed $group The service group(s) to filter by
|
||||
*
|
||||
* @return array<Service> The filtered services array
|
||||
*/
|
||||
public function getAdditionalServicesByGroup(mixed $group): array
|
||||
{
|
||||
$group = (array) $group;
|
||||
@@ -55,6 +82,17 @@ class Booking
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves additional services for a specific participant by group.
|
||||
*
|
||||
* Filters additional services by group and participant index mapping.
|
||||
* Returns services that are assigned to the specified participant.
|
||||
*
|
||||
* @param int $participantIndex The participant index to filter by
|
||||
* @param mixed $group The service group(s) to filter by
|
||||
*
|
||||
* @return array<Service> The filtered services for the participant
|
||||
*/
|
||||
public function getAdditionalServicesForParticipantByGroup(int $participantIndex, mixed $group): array
|
||||
{
|
||||
$selectedServices = $this->getAdditionalServicesByGroup($group);
|
||||
@@ -64,6 +102,17 @@ class Booking
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves transportation service for a specific participant and direction.
|
||||
*
|
||||
* Finds the transportation service that matches the participant index
|
||||
* and travel direction (e.g., 'H' for outbound, 'R' for return).
|
||||
*
|
||||
* @param int $participantIndex The participant index to search for
|
||||
* @param string $direction The travel direction ('H' or 'R')
|
||||
*
|
||||
* @return Service|null The matching transportation service or null if not found
|
||||
*/
|
||||
public function getTransportationServiceForParticipantAndDirection(
|
||||
int $participantIndex,
|
||||
string $direction
|
||||
@@ -80,6 +129,16 @@ class Booking
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves pickup service for a specific participant.
|
||||
*
|
||||
* Finds the pickup service assigned to the specified participant
|
||||
* from the outbound pickup services.
|
||||
*
|
||||
* @param int $participantIndex The participant index to search for
|
||||
*
|
||||
* @return Pickup|null The matching pickup service or null if not found
|
||||
*/
|
||||
public function getPickupForParticipant(int $participantIndex): ?Pickup
|
||||
{
|
||||
foreach ($this->pickupsTo as $pickup) {
|
||||
@@ -91,6 +150,16 @@ class Booking
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves room assignment for a specific participant.
|
||||
*
|
||||
* Finds the room assigned to the specified participant
|
||||
* based on the room mapping configuration.
|
||||
*
|
||||
* @param int $participantIndex The participant index to search for
|
||||
*
|
||||
* @return Room|null The matching room or null if not found
|
||||
*/
|
||||
public function getRoomForParticipant(int $participantIndex): ?Room
|
||||
{
|
||||
foreach ($this->rooms as $room) {
|
||||
@@ -102,6 +171,16 @@ class Booking
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the total price for a specific participant.
|
||||
*
|
||||
* Sums up all services, surcharges, and room costs assigned to the participant.
|
||||
* Includes mandatory services that apply to all participants.
|
||||
*
|
||||
* @param int $participantIndex The participant index to calculate for
|
||||
*
|
||||
* @return float The total price for the participant
|
||||
*/
|
||||
public function getPriceForParticipant(int $participantIndex): float
|
||||
{
|
||||
$price = 0.0;
|
||||
@@ -126,6 +205,15 @@ class Booking
|
||||
return $price;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves surcharges for a specific participant.
|
||||
*
|
||||
* Filters surcharges based on participant index mapping.
|
||||
*
|
||||
* @param int $participantIndex The participant index to filter by
|
||||
*
|
||||
* @return array<Surcharge> The surcharges assigned to the participant
|
||||
*/
|
||||
public function getSurchargesForParticipant(int $participantIndex): array
|
||||
{
|
||||
return array_filter($this->surcharges, function (Surcharge $surcharge) use ($participantIndex) {
|
||||
@@ -133,6 +221,13 @@ class Booking
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the total price for all participants.
|
||||
*
|
||||
* Sums up the individual prices for all participants in the booking.
|
||||
*
|
||||
* @return float The calculated total price for all participants
|
||||
*/
|
||||
public function getCalculatedTotalPrice(): float
|
||||
{
|
||||
$totalPrice = 0.0;
|
||||
@@ -144,6 +239,14 @@ class Booking
|
||||
return $totalPrice;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the booking is editable.
|
||||
*
|
||||
* A booking is editable if the travel date is in the future and
|
||||
* the status is not cancelled ('S') or unknown ('U').
|
||||
*
|
||||
* @return bool True if the booking can be edited, false otherwise
|
||||
*/
|
||||
public function isEditable(): bool
|
||||
{
|
||||
return $this->travelDate > new \DateTimeImmutable() && false === in_array($this->status, ['S', 'U']);
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
/**
|
||||
* Represents a booking update response with validation and status information.
|
||||
*
|
||||
* This class handles booking update results including validation status,
|
||||
* success indication, and status messages for API response handling.
|
||||
*/
|
||||
class BookingUpdate
|
||||
{
|
||||
public bool $valid = false;
|
||||
|
||||
@@ -1,22 +1,39 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
/**
|
||||
* Represents communication information including email, phone, and newsletter preferences.
|
||||
*
|
||||
* This class handles contact information for users and participants in the booking system.
|
||||
* It provides validation constraints for required fields and methods to convert
|
||||
* communication data to API payload format.
|
||||
*/
|
||||
class Communication
|
||||
{
|
||||
public ?string $phone = '';
|
||||
public string $phone = '';
|
||||
|
||||
#[Assert\NotBlank(message: 'Bitte angeben', groups: ['personal_data'])]
|
||||
public ?string $mobile = '';
|
||||
public string $mobile = '';
|
||||
|
||||
#[Assert\NotBlank(message: 'Bitte angeben', groups: ['personal_data'])]
|
||||
#[Assert\Email(message: 'Bitte eine gültige Adresse angeben', mode: 'strict', groups: ['personal_data'])]
|
||||
public ?string $email = '';
|
||||
public string $email = '';
|
||||
|
||||
public bool $newsletter = false;
|
||||
|
||||
/**
|
||||
* Converts the communication data to API payload format.
|
||||
*
|
||||
* Transforms the communication object into an array structure suitable
|
||||
* for API communication with the BusProNet system.
|
||||
*
|
||||
* @return array<string, string> The payload array for API transmission
|
||||
*/
|
||||
public function toPayload(): array
|
||||
{
|
||||
return [
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
/**
|
||||
* Represents a country with identification and nationality information.
|
||||
*
|
||||
* This class handles country data including unique identification,
|
||||
* name, token, and associated nationality information.
|
||||
*/
|
||||
class Country
|
||||
{
|
||||
public ?int $id = null;
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
/**
|
||||
* Represents a CRM action with configuration and state information.
|
||||
*
|
||||
* This class handles CRM action data including identification, labeling,
|
||||
* mutability status, and selection state for user interface management.
|
||||
*/
|
||||
class CrmAction
|
||||
{
|
||||
public ?int $id = null;
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
/**
|
||||
* Represents CRM attributes with role and permission information.
|
||||
*
|
||||
* This class handles CRM system attributes including selection groups,
|
||||
* actions, user roles, and hotel assignments for access control.
|
||||
*/
|
||||
class CrmAttributes
|
||||
{
|
||||
public ?array $selectionGroups = null;
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
use Symfony\Component\Serializer\Attribute\Groups;
|
||||
|
||||
/**
|
||||
* Represents a CRM selection with configuration and state information.
|
||||
*
|
||||
* This class handles CRM selection data including identification, labeling,
|
||||
* mutability status, and selection state. It provides serialization groups
|
||||
* for API responses.
|
||||
*/
|
||||
class CrmSelection
|
||||
{
|
||||
#[Groups(['api:single'])]
|
||||
|
||||
@@ -1,16 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
use Symfony\Component\Serializer\Attribute\Groups;
|
||||
|
||||
/**
|
||||
* Represents a CRM selection group with included services mapping.
|
||||
*
|
||||
* This class handles CRM selection group data including identification,
|
||||
* labeling, and selections. It provides methods to filter mutable selections
|
||||
* and determine visibility, along with a static mapping for included services.
|
||||
*/
|
||||
class CrmSelectionGroup
|
||||
{
|
||||
/**
|
||||
* Maps BusPro IDs of CRM selection groups representing
|
||||
* included services.
|
||||
*
|
||||
* @var array|string[]
|
||||
* @var array<string, string>
|
||||
*/
|
||||
public static array $includedServicesMapping = [
|
||||
7 => 'Skipass',
|
||||
@@ -32,6 +41,14 @@ class CrmSelectionGroup
|
||||
#[Groups(['api:single'])]
|
||||
public ?array $selections = null;
|
||||
|
||||
/**
|
||||
* Retrieves only the mutable selections from the group.
|
||||
*
|
||||
* Filters the selections array to return only items that are marked
|
||||
* as mutable for user interface management.
|
||||
*
|
||||
* @return array<CrmSelection> The mutable selections array
|
||||
*/
|
||||
public function getMutableSelections(): array
|
||||
{
|
||||
return array_filter($this->selections, function (CrmSelection $selection) {
|
||||
@@ -39,6 +56,14 @@ class CrmSelectionGroup
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the selection group should be visible.
|
||||
*
|
||||
* A group is considered visible if it contains at least one
|
||||
* mutable selection for user interaction.
|
||||
*
|
||||
* @return bool True if the group has mutable selections, false otherwise
|
||||
*/
|
||||
#[Groups(['api:single'])]
|
||||
public function isVisible(): bool
|
||||
{
|
||||
|
||||
@@ -1,9 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
/**
|
||||
* Represents error codes and messages for the BusProNet API.
|
||||
*
|
||||
* This class provides a static mapping of error codes to their corresponding
|
||||
* German error messages for consistent error handling across the application.
|
||||
* Error codes range from 100-999 and cover various API scenarios.
|
||||
*/
|
||||
class Error
|
||||
{
|
||||
/**
|
||||
* @var array<int, string>
|
||||
*/
|
||||
private static array $errors = [
|
||||
100 => 'Anfrageknoten fehlt',
|
||||
101 => 'Satzknoten fehlt in Anfrageknoten',
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
/**
|
||||
* Represents a file with content and metadata information.
|
||||
*
|
||||
* This class handles file data including filename, content, and MIME type
|
||||
* for document storage and retrieval operations.
|
||||
*/
|
||||
class File
|
||||
{
|
||||
public function __construct(string $filename, string $content, string $mimeType)
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
use Symfony\Component\Serializer\Attribute\Groups;
|
||||
|
||||
/**
|
||||
* Represents a travel guide with contact information.
|
||||
*
|
||||
* This class handles guide data including name and contact details.
|
||||
* It provides serialization groups for API responses in travel contexts.
|
||||
*/
|
||||
class Guide
|
||||
{
|
||||
#[Groups(['api:single'])]
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
use Symfony\Component\Serializer\Attribute\Groups;
|
||||
|
||||
/**
|
||||
* Represents a hotel with location and contact information.
|
||||
*
|
||||
* This class handles hotel data including identification, location details,
|
||||
* and contact information. It provides serialization groups for API responses
|
||||
* in travel and booking contexts.
|
||||
*/
|
||||
class Hotel
|
||||
{
|
||||
#[Groups(['api:list', 'api:single'])]
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
/**
|
||||
* Represents mutable data configuration with category and timing information.
|
||||
*
|
||||
* This class handles mutable data settings including category identification,
|
||||
* mutability status, and timing constraints for booking modifications.
|
||||
*/
|
||||
class MutableData
|
||||
{
|
||||
public const CATEGORY_PARTICIPANT_COUNT = 'participant_count';
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
/**
|
||||
* Represents a notification with code and message information.
|
||||
*
|
||||
* This class handles notification data including error codes and messages
|
||||
* for API response handling. It provides methods to determine if the
|
||||
* notification represents an error condition.
|
||||
*/
|
||||
class Notification
|
||||
{
|
||||
public function __construct(int $code, string $message)
|
||||
@@ -13,6 +22,14 @@ class Notification
|
||||
public ?int $code;
|
||||
public ?string $message;
|
||||
|
||||
/**
|
||||
* Determines if the notification represents an error.
|
||||
*
|
||||
* Returns true if the notification code is not 650 (success code).
|
||||
* Code 650 is used for successful operations in the BusProNet API.
|
||||
*
|
||||
* @return bool True if the notification is an error, false otherwise
|
||||
*/
|
||||
public function isError(): bool
|
||||
{
|
||||
return 650 !== $this->code;
|
||||
|
||||
@@ -1,31 +1,43 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
/**
|
||||
* Represents personal data for a user including address and communication information.
|
||||
*
|
||||
* This class handles the storage and transformation of personal information
|
||||
* including name, address, communication details, and physical attributes.
|
||||
* It provides methods to convert data to API payload format and extract claims
|
||||
* for authentication purposes.
|
||||
*/
|
||||
class PersonalData
|
||||
{
|
||||
private const DEFAULT_AGE_YEARS = 18;
|
||||
|
||||
public ?int $addressId = null;
|
||||
public ?int $personId = null;
|
||||
public bool $mutable = false;
|
||||
public ?string $status = '';
|
||||
public ?string $status = null;
|
||||
|
||||
#[Assert\NotBlank(message: 'Bitte angeben', groups: ['Default', 'personal_data'])]
|
||||
public ?string $name = '';
|
||||
public string $name = '';
|
||||
|
||||
#[Assert\NotBlank(message: 'Bitte angeben', groups: ['Default', 'personal_data'])]
|
||||
public ?string $firstName = '';
|
||||
public string $firstName = '';
|
||||
|
||||
public ?string $salutation = '';
|
||||
public ?string $title = '';
|
||||
public ?string $gender = '';
|
||||
public ?string $nationality = '';
|
||||
public ?string $height = '';
|
||||
public ?string $shoeSize = '';
|
||||
public ?string $weight = '';
|
||||
public string $salutation = '';
|
||||
public string $title = '';
|
||||
public string $gender = '';
|
||||
public string $nationality = '';
|
||||
public string $height = '';
|
||||
public string $shoeSize = '';
|
||||
public string $weight = '';
|
||||
public ?\DateTimeImmutable $dateOfBirth = null;
|
||||
public ?string $remarks = '';
|
||||
public string $remarks = '';
|
||||
|
||||
#[Assert\Valid(groups: ['personal_data'])]
|
||||
public Address $address;
|
||||
@@ -39,11 +51,19 @@ class PersonalData
|
||||
$this->communication = new Communication();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the personal data to API payload format.
|
||||
*
|
||||
* Transforms the personal data object into an array structure suitable
|
||||
* for API communication with the BusProNet system.
|
||||
*
|
||||
* @return array<string, mixed> The payload array for API transmission
|
||||
*/
|
||||
public function toPayload(): array
|
||||
{
|
||||
// Ensure date of birth is populated
|
||||
if (null === $dob = $this->dateOfBirth) {
|
||||
$dob = new \DateTimeImmutable('18 years ago');
|
||||
$dob = new \DateTimeImmutable(self::DEFAULT_AGE_YEARS . ' years ago');
|
||||
}
|
||||
|
||||
return [
|
||||
@@ -56,8 +76,8 @@ class PersonalData
|
||||
'titel' => $this->title,
|
||||
'vorname' => $this->firstName,
|
||||
'name' => $this->name,
|
||||
'anschrift' => $this->address?->toPayload(),
|
||||
'kommunikation' => $this->communication?->toPayload(),
|
||||
'anschrift' => $this->address->toPayload(),
|
||||
'kommunikation' => $this->communication->toPayload(),
|
||||
'sonstiges1' => $this->height,
|
||||
'sonstiges2' => $this->weight,
|
||||
'sonstiges3' => $this->shoeSize,
|
||||
@@ -65,6 +85,14 @@ class PersonalData
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts user claims for authentication and profile information.
|
||||
*
|
||||
* Creates a structured array containing user profile information
|
||||
* suitable for JWT claims or user session data.
|
||||
*
|
||||
* @return array<string, mixed> The claims array with user profile data
|
||||
*/
|
||||
public function getClaims(): array
|
||||
{
|
||||
return [
|
||||
|
||||
@@ -1,11 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
use Symfony\Component\Serializer\Attribute\Context;
|
||||
use Symfony\Component\Serializer\Attribute\Groups;
|
||||
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
|
||||
|
||||
/**
|
||||
* Represents a pickup location with timing and pricing information.
|
||||
*
|
||||
* This class handles pickup point data including location details, scheduled times,
|
||||
* pricing, and participant mapping. It provides serialization groups for API
|
||||
* responses and booking management.
|
||||
*/
|
||||
class Pickup
|
||||
{
|
||||
#[Groups(['api:list'])]
|
||||
|
||||
@@ -1,11 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
use Symfony\Component\Serializer\Attribute\Context;
|
||||
use Symfony\Component\Serializer\Attribute\Groups;
|
||||
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
|
||||
|
||||
/**
|
||||
* Represents a room configuration with capacity, pricing, and availability information.
|
||||
*
|
||||
* This class handles room data including category, board options, capacity limits,
|
||||
* pricing structure, and participant mapping. It provides serialization groups
|
||||
* for different API contexts and booking management.
|
||||
*/
|
||||
class Room
|
||||
{
|
||||
#[Groups(['api:list', 'api:single'])]
|
||||
|
||||
@@ -1,29 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
use Symfony\Component\Serializer\Attribute\Context;
|
||||
use Symfony\Component\Serializer\Attribute\Groups;
|
||||
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
|
||||
|
||||
/**
|
||||
* Represents a service offering with pricing, availability, and configuration options.
|
||||
*
|
||||
* This class handles various types of services including transportation, additional
|
||||
* services, courses, and rentals. It provides constants for service categorization
|
||||
* and status management, along with serialization groups for API responses.
|
||||
*/
|
||||
class Service
|
||||
{
|
||||
public const SOURCE_TRAVEL = 'travel';
|
||||
public const SOURCE_BOOKING = 'booking';
|
||||
|
||||
public const CATEGORY_ADDITIONAL = 'additional';
|
||||
public const CATEGORY_TRANSPORTATION = 'transportation';
|
||||
|
||||
public const TOKEN_COURSES = 'KUR';
|
||||
public const TOKEN_SKI_PASS = 'SPA';
|
||||
public const TOKEN_ADDITIONAL = 'SON';
|
||||
public const TOKEN_BOARD = 'VPF';
|
||||
public const TOKEN_RENTALS = ['VER', 'VE2', 'VE3', 'VE4', 'VE5', 'VE6', 'VE7', 'VE8'];
|
||||
|
||||
public const STATUS_AVAILABLE = 'Frei';
|
||||
public const STATUS_BLOCKED = 'Buchungsstop';
|
||||
public const STATUS_ON_REQUEST = 'Anfrage';
|
||||
|
||||
#[Groups(['api:single', 'api:list'])]
|
||||
public ?int $id = null;
|
||||
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
/**
|
||||
* Represents a surcharge with pricing and participant mapping.
|
||||
*
|
||||
* This class handles surcharge data including label, pricing structure,
|
||||
* and participant mapping for booking calculations.
|
||||
*/
|
||||
class Surcharge
|
||||
{
|
||||
public ?string $label = null;
|
||||
|
||||
@@ -1,11 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
use Symfony\Component\Serializer\Attribute\Context;
|
||||
use Symfony\Component\Serializer\Attribute\Groups;
|
||||
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
|
||||
|
||||
/**
|
||||
* Represents a travel package with services, accommodation, and pricing information.
|
||||
*
|
||||
* This class handles travel data including dates, hotel information, available services,
|
||||
* transportation options, and participant configuration. It provides methods to filter
|
||||
* and retrieve services by various criteria and manage included services.
|
||||
*/
|
||||
class Travel
|
||||
{
|
||||
#[Groups(['api:list', 'api:single'])]
|
||||
@@ -76,6 +85,17 @@ class Travel
|
||||
#[Groups(['api:single'])]
|
||||
public ?Guide $guide = null;
|
||||
|
||||
/**
|
||||
* Retrieves additional services filtered by group and availability.
|
||||
*
|
||||
* Filters additional services based on the provided group(s) and optionally
|
||||
* by availability. Services are sorted alphabetically by label.
|
||||
*
|
||||
* @param mixed $group The service group(s) to filter by
|
||||
* @param bool $availableOnly Whether to include only available services
|
||||
*
|
||||
* @return array<Service> The filtered and sorted services array
|
||||
*/
|
||||
public function getAdditionalServicesByGroup(mixed $group, bool $availableOnly = true): array
|
||||
{
|
||||
$group = (array) $group;
|
||||
@@ -91,6 +111,17 @@ class Travel
|
||||
return $services;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves transportation services filtered by direction and availability.
|
||||
*
|
||||
* Filters transportation services based on travel direction and optionally
|
||||
* by availability. Services are sorted by subtype.
|
||||
*
|
||||
* @param string $direction The travel direction to filter by
|
||||
* @param bool $availableOnly Whether to include only available services
|
||||
*
|
||||
* @return array<Service> The filtered and sorted transportation services
|
||||
*/
|
||||
public function getTransportationServicesByDirection(string $direction, bool $availableOnly = true): array
|
||||
{
|
||||
$services = array_filter($this->transportationServices, function (Service $service) use ($direction, $availableOnly) {
|
||||
@@ -106,6 +137,14 @@ class Travel
|
||||
return $services;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves included services from selection groups.
|
||||
*
|
||||
* Maps selection group IDs to their corresponding services based on
|
||||
* the predefined included services mapping.
|
||||
*
|
||||
* @return array The included services from selection groups
|
||||
*/
|
||||
public function getIncludedServices(): array
|
||||
{
|
||||
$services = [];
|
||||
@@ -118,4 +157,27 @@ class Travel
|
||||
|
||||
return $services;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves rooms filtered by their IDs.
|
||||
*
|
||||
* Filters the rooms array to return only rooms whose IDs match
|
||||
* the provided array of IDs. Returns an empty array if no matching
|
||||
* rooms are found.
|
||||
*
|
||||
* @param array<int> $ids The array of room IDs to filter by
|
||||
*
|
||||
* @return array<Room> The filtered rooms array
|
||||
*/
|
||||
public function getRoomsByIds(array $ids): array
|
||||
{
|
||||
if (empty($ids)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return array_filter($this->rooms, function (Room $room) use ($ids) {
|
||||
return in_array($room->id, $ids, true);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\BusProNet\XmlLoader;
|
||||
|
||||
use App\BusProNet\Constants;
|
||||
use App\BusProNet\Model\BaseData;
|
||||
use App\BusProNet\Model\CrmSelection;
|
||||
use App\BusProNet\Model\CrmSelectionGroup;
|
||||
@@ -192,8 +193,8 @@ class TravelLoader extends AbstractLoader
|
||||
$serviceId = (int) $serviceNode->attr('idbuspro');
|
||||
|
||||
$service = new Service();
|
||||
$service->source = Service::SOURCE_TRAVEL;
|
||||
$service->category = Service::CATEGORY_ADDITIONAL;
|
||||
$service->source = Constants::SOURCE_TRAVEL;
|
||||
$service->category = Constants::CATEGORY_ADDITIONAL;
|
||||
$service->id = $serviceId;
|
||||
$service->subType = $serviceNode->attr('unterart');
|
||||
$service->mandatory = $this->stringToBool($serviceNode->attr('pflicht'));
|
||||
@@ -236,8 +237,8 @@ class TravelLoader extends AbstractLoader
|
||||
$serviceId = (int) $serviceNode->attr('idbuspro');
|
||||
|
||||
$service = new Service();
|
||||
$service->source = Service::SOURCE_TRAVEL;
|
||||
$service->category = Service::CATEGORY_TRANSPORTATION;
|
||||
$service->source = Constants::SOURCE_TRAVEL;
|
||||
$service->category = Constants::CATEGORY_TRANSPORTATION;
|
||||
$service->id = $serviceId;
|
||||
$service->subType = $serviceNode->attr('unterart');
|
||||
$service->dateFrom = $this->stringToDate($serviceNode->attr('termin'));
|
||||
@@ -311,12 +312,12 @@ class TravelLoader extends AbstractLoader
|
||||
$room->category = $roomNode->attr('kat');
|
||||
$room->boardId = (int) $roomNode->attr('idbuspro_vp');
|
||||
$room->label = $roomNode->attr('zimmertext');
|
||||
$room->minPax = (int) $roomNode->attr('MinPax');
|
||||
$room->maxPax = (int) $roomNode->attr('MaxPax');
|
||||
$room->minPax = (int) $roomNode->attr('minpax');
|
||||
$room->maxPax = (int) $roomNode->attr('maxpax');
|
||||
$room->nights = (int) $roomNode->attr('naechte');
|
||||
$room->price = $roomNode->attr('preis') ?
|
||||
$this->stringToFloat($roomNode->attr('preis')) : null;
|
||||
$room->status = $this->getStringOrNullValue($roomNode->filterXPath('//status'));
|
||||
$room->status = $roomNode->attr('status');
|
||||
$room->available = (int) $roomNode->attr('verfuegbar');
|
||||
|
||||
$rooms[$roomId] = $room;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\BusProNet\XmlParser;
|
||||
|
||||
use App\BusProNet\Constants;
|
||||
use App\BusProNet\Model\Address;
|
||||
use App\BusProNet\Model\BankAccount;
|
||||
use App\BusProNet\Model\Booking;
|
||||
@@ -38,7 +39,7 @@ class BookingParser extends AbstractParser
|
||||
|
||||
$travelData = $node->filterXPath('//reise');
|
||||
|
||||
$booking->travel = $travelData->attr('bezeichnung');
|
||||
$booking->travelName = $travelData->attr('bezeichnung');
|
||||
$booking->travelId = $this->getIntOrNullValue($node->filterXPath('//idreise'));
|
||||
$booking->travelCode = $travelData->attr('code');
|
||||
$booking->travelDate = $this->stringToDate($travelData->attr('termin'));
|
||||
@@ -72,14 +73,14 @@ class BookingParser extends AbstractParser
|
||||
if (0 < $transportationData->count()) {
|
||||
$booking->transportationServices = $this
|
||||
->servicesParser
|
||||
->parse($transportationData, Service::CATEGORY_TRANSPORTATION, Service::SOURCE_BOOKING);
|
||||
->parse($transportationData, Constants::CATEGORY_TRANSPORTATION, Constants::SOURCE_BOOKING);
|
||||
}
|
||||
|
||||
$additionalServicesData = $node->filterXPath('//zusatzleistungen/zusatzleistung');
|
||||
if (0 < $additionalServicesData->count()) {
|
||||
$booking->additionalServices = $this
|
||||
->servicesParser
|
||||
->parse($additionalServicesData, Service::CATEGORY_ADDITIONAL, Service::SOURCE_BOOKING);
|
||||
->parse($additionalServicesData, Constants::CATEGORY_ADDITIONAL, Constants::SOURCE_BOOKING);
|
||||
}
|
||||
|
||||
$roomsData = $node->filterXPath('//ferienzielunterbringungen/ferienzielunterbringung');
|
||||
|
||||
@@ -26,7 +26,7 @@ class BookingsParser extends AbstractParser
|
||||
$booking->participantCount = $this->getIntOrNullValue($node->filterXPath('//personen'));
|
||||
$booking->price = $this->getFloatOrNullValue($node->filterXPath('//preis'));
|
||||
$booking->bookingDate = $this->getDateTimeOrNullValue($node->filterXPath('//buchungsdatum'));
|
||||
$booking->travel = $this->getStringOrNullValue($node->filterXPath('//reise'));
|
||||
$booking->travelName = $this->getStringOrNullValue($node->filterXPath('//reise'));
|
||||
$booking->travelId = $this->getIntOrNullValue($node->filterXPath('//idreise'));
|
||||
$booking->travelDate = $this->getDateOrNullValue($node->filterXPath('//reisedatum'));
|
||||
$booking->hasDocuments = $this->getBoolValue($node->filterXPath('//reisedokument'));
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\BusProNet\XmlParser;
|
||||
|
||||
use App\BusProNet\Constants;
|
||||
use App\BusProNet\Model\Service;
|
||||
use Symfony\Component\DomCrawler\Crawler;
|
||||
|
||||
@@ -30,7 +31,7 @@ class ServicesParser extends AbstractParser
|
||||
}, $this->stringToArray($node->attr('einzelpreis', ''), '/')
|
||||
);
|
||||
$service->individualPrice = array_combine($mapping, $individualPrices);
|
||||
if (Service::CATEGORY_TRANSPORTATION === $category) {
|
||||
if (Constants::CATEGORY_TRANSPORTATION === $category) {
|
||||
$service->direction = $node->attr('richtung');
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller\Booking;
|
||||
|
||||
use App\BusProNet\XmlLoader\TravelLoader;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class CreateController extends AbstractController
|
||||
{
|
||||
public function __construct(private readonly TravelLoader $travelDataLoader)
|
||||
{}
|
||||
|
||||
#[Route('/bookings/create', name: 'app_booking_create', methods: ['POST'])]
|
||||
public function index(Request $request): Response
|
||||
{
|
||||
$travelId = $request->query->getInt('travel_id');
|
||||
$hotelId = $request->query->getInt('hotel_id');
|
||||
|
||||
$roomsIdsAndQuantities = $this->getRoomsIdsAndQuantities($request);
|
||||
|
||||
$travelData = $this->travelDataLoader->loadById($travelId, $hotelId);
|
||||
|
||||
if (null === $travelData) {
|
||||
throw $this->createNotFoundException('Travel data not found');
|
||||
}
|
||||
|
||||
$participantsCount = 0;
|
||||
|
||||
$rooms = $travelData->getRoomsByIds(array_keys($roomsIdsAndQuantities));
|
||||
|
||||
foreach ($rooms as $room) {
|
||||
$roomCount = $roomsIdsAndQuantities[$room->id] ?? 0;
|
||||
$participantsCount += $room->minPax * $roomCount;
|
||||
}
|
||||
|
||||
return $this->render('booking/create.html.twig', [
|
||||
'travelData' => $travelData,
|
||||
]);
|
||||
}
|
||||
|
||||
private function getRoomsIdsAndQuantities(Request $request): array
|
||||
{
|
||||
$rooms = $request->request->all('rooms');
|
||||
|
||||
return array_map('intval', array_filter($rooms, 'strlen'));
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ use App\BusProNet\XmlLoader\TravelLoader;
|
||||
use App\Controller\Traits\BookingDataTrait;
|
||||
use App\Entity\User;
|
||||
use App\Form\BookingType;
|
||||
use App\Form\Model\BookingData;
|
||||
use App\Form\Model\BookingEditDto;
|
||||
use App\Security\Crypt;
|
||||
use Psr\Cache\InvalidArgumentException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
@@ -90,7 +90,7 @@ class EditController extends AbstractController
|
||||
$this->pickupDataLoader->patchPickupsDetails($travelData);
|
||||
|
||||
// Create DTO for form
|
||||
$formData = BookingData::fromBooking($bookingData, $travelData);
|
||||
$formData = BookingEditDto::fromBooking($bookingData, $travelData);
|
||||
|
||||
$form = $this->createForm(BookingType::class, $formData, [
|
||||
'attr' => ['novalidate' => 'novalidate'],
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace App\Controller;
|
||||
|
||||
use App\BusProNet\ApiClient;
|
||||
use App\BusProNet\Exception\ApiClientException;
|
||||
use App\Form\Model\RegistrationData;
|
||||
use App\Form\Model\RegistrationDto;
|
||||
use App\Form\RegistrationType;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
@@ -25,7 +25,7 @@ class RegistrationController extends AbstractController
|
||||
#[IsGranted('PUBLIC_ACCESS')]
|
||||
public function index(Request $request): Response
|
||||
{
|
||||
$registrationData = new RegistrationData();
|
||||
$registrationData = new RegistrationDto();
|
||||
$form = $this->createForm(RegistrationType::class, $registrationData, [
|
||||
'action' => $this->generateUrl('app_registration'),
|
||||
]);
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use App\BusProNet\Constants;
|
||||
use App\BusProNet\Model\Service;
|
||||
use App\Form\Model\BookingData;
|
||||
use App\Form\Model\BookingEditDto;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
@@ -16,7 +17,7 @@ final class BookingType extends AbstractType
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
|
||||
/** @var BookingData $data */
|
||||
/** @var BookingEditDto $data */
|
||||
$data = $event->getData();
|
||||
$form = $event->getForm();
|
||||
|
||||
@@ -24,11 +25,11 @@ final class BookingType extends AbstractType
|
||||
$form->add('participants', CollectionType::class, [
|
||||
'entry_type' => ParticipantType::class,
|
||||
'entry_options' => [
|
||||
'selectable_courses' => $this->mergeSelectableServices($data, Service::TOKEN_COURSES),
|
||||
'selectable_ski_passes' => $this->mergeSelectableServices($data, Service::TOKEN_SKI_PASS),
|
||||
'selectable_services' => $this->mergeSelectableServices($data, Service::TOKEN_ADDITIONAL),
|
||||
'selectable_board' => $this->mergeSelectableServices($data, Service::TOKEN_BOARD),
|
||||
'selectable_rentals' => $this->mergeSelectableServices($data, Service::TOKEN_RENTALS),
|
||||
'selectable_courses' => $this->mergeSelectableServices($data, Constants::TOKEN_COURSES),
|
||||
'selectable_ski_passes' => $this->mergeSelectableServices($data, Constants::TOKEN_SKI_PASS),
|
||||
'selectable_services' => $this->mergeSelectableServices($data, Constants::TOKEN_ADDITIONAL),
|
||||
'selectable_board' => $this->mergeSelectableServices($data, Constants::TOKEN_BOARD),
|
||||
'selectable_rentals' => $this->mergeSelectableServices($data, Constants::TOKEN_RENTALS),
|
||||
'selectable_transportation_services_to' => $travelData
|
||||
->getTransportationServicesByDirection('HIN', false),
|
||||
'selectable_transportation_services_fro' => $travelData
|
||||
@@ -46,7 +47,7 @@ final class BookingType extends AbstractType
|
||||
});
|
||||
}
|
||||
|
||||
private function mergeSelectableServices(BookingData $data, mixed $subType): array
|
||||
private function mergeSelectableServices(BookingEditDto $data, mixed $subType): array
|
||||
{
|
||||
// combine selectable services from travel data with additional services
|
||||
// from booking data
|
||||
@@ -67,7 +68,7 @@ final class BookingType extends AbstractType
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'data_class' => BookingData::class,
|
||||
'data_class' => BookingEditDto::class,
|
||||
'anti_xss' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
namespace App\Form\Model;
|
||||
|
||||
use App\BusProNet\Constants;
|
||||
use App\BusProNet\Model\Booking;
|
||||
use App\BusProNet\Model\PersonalData;
|
||||
use App\BusProNet\Model\Service;
|
||||
use App\BusProNet\Model\Travel;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
class BookingData
|
||||
class BookingEditDto
|
||||
{
|
||||
public ?Booking $booking = null;
|
||||
public ?Travel $travel = null;
|
||||
@@ -25,19 +25,19 @@ class BookingData
|
||||
|
||||
foreach ($booking->participants as $index => $participant) {
|
||||
/** @var PersonalData $participant */
|
||||
$participantData = ParticipantData::fromPersonalData($participant);
|
||||
$participantData = ParticipantDto::fromPersonalData($participant);
|
||||
$participantData->index = $index;
|
||||
|
||||
$participantData->courses = $booking
|
||||
->getAdditionalServicesForParticipantByGroup($index, Service::TOKEN_COURSES);
|
||||
->getAdditionalServicesForParticipantByGroup($index, Constants::TOKEN_COURSES);
|
||||
$participantData->skiPass = $booking
|
||||
->getAdditionalServicesForParticipantByGroup($index, Service::TOKEN_SKI_PASS);
|
||||
->getAdditionalServicesForParticipantByGroup($index, Constants::TOKEN_SKI_PASS);
|
||||
$participantData->additionalServices = $booking
|
||||
->getAdditionalServicesForParticipantByGroup($index, Service::TOKEN_ADDITIONAL);
|
||||
->getAdditionalServicesForParticipantByGroup($index, Constants::TOKEN_ADDITIONAL);
|
||||
$participantData->board = $booking
|
||||
->getAdditionalServicesForParticipantByGroup($index, Service::TOKEN_BOARD);
|
||||
->getAdditionalServicesForParticipantByGroup($index, Constants::TOKEN_BOARD);
|
||||
$participantData->rentals = $booking
|
||||
->getAdditionalServicesForParticipantByGroup($index, Service::TOKEN_RENTALS);
|
||||
->getAdditionalServicesForParticipantByGroup($index, Constants::TOKEN_RENTALS);
|
||||
// Different keys for direction used in booking data (H <=> HIN, R <=> RUECK)!
|
||||
$participantData->transportationServiceTo = $booking
|
||||
->getTransportationServiceForParticipantAndDirection($index, 'H');
|
||||
@@ -9,7 +9,7 @@ use App\Validator\Constraints as AppAssert;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
#[AppAssert\Participant]
|
||||
class ParticipantData
|
||||
class ParticipantDto
|
||||
{
|
||||
public ?int $index = null;
|
||||
public ?int $addressId = null;
|
||||
@@ -4,7 +4,7 @@ namespace App\Form\Model;
|
||||
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
class RegistrationData
|
||||
class RegistrationDto
|
||||
{
|
||||
#[Assert\NotBlank(message: 'Bitte angeben')]
|
||||
public ?string $firstName = null;
|
||||
@@ -2,10 +2,11 @@
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use App\BusProNet\Constants;
|
||||
use App\BusProNet\Form\CountryType;
|
||||
use App\BusProNet\Model\Pickup;
|
||||
use App\BusProNet\Model\Service;
|
||||
use App\Form\Model\ParticipantData;
|
||||
use App\Form\Model\ParticipantDto;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\BirthdayType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
@@ -21,7 +22,7 @@ class ParticipantType extends AbstractType
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($options) {
|
||||
/** @var ParticipantData $participantData */
|
||||
/** @var ParticipantDto $participantData */
|
||||
$participantData = $event->getData();
|
||||
$participantIndex = $participantData->index;
|
||||
|
||||
@@ -166,12 +167,12 @@ class ParticipantType extends AbstractType
|
||||
}
|
||||
|
||||
// disable selection of services only available in booking data
|
||||
if (Service::SOURCE_BOOKING === $service->source) {
|
||||
if (Constants::SOURCE_BOOKING === $service->source) {
|
||||
$attributes['class'] = 'text-pink';
|
||||
}
|
||||
|
||||
// disable selection of services that are unavailable according to their status
|
||||
if (Service::STATUS_BLOCKED === $service->status) {
|
||||
if (Constants::STATUS_BLOCKED === $service->status) {
|
||||
$attributes['checked'] = false;
|
||||
$attributes['readonly'] = true;
|
||||
$attributes['tooltip'] = 'Diese Leistung ist derzeit leider nicht buchbar';
|
||||
@@ -191,8 +192,8 @@ class ParticipantType extends AbstractType
|
||||
// remove choices only available in booking data and
|
||||
// which are not mapped to the current participant
|
||||
if (
|
||||
Service::SOURCE_TRAVEL === $service->source
|
||||
|| Service::CATEGORY_ADDITIONAL !== $service->category
|
||||
Constants::SOURCE_TRAVEL === $service->source
|
||||
|| Constants::CATEGORY_ADDITIONAL !== $service->category
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
@@ -249,7 +250,7 @@ class ParticipantType extends AbstractType
|
||||
$attributes['readonly'] = true;
|
||||
$attributes['tooltip'] = 'Diese Leistung kann nicht mehr geändert werden';
|
||||
}
|
||||
if (Service::STATUS_BLOCKED === $service->status) {
|
||||
if (Constants::STATUS_BLOCKED === $service->status) {
|
||||
$attributes['checked'] = false;
|
||||
$attributes['readonly'] = true;
|
||||
$attributes['tooltip'] = 'Diese Leistung ist derzeit leider nicht buchbar';
|
||||
@@ -341,7 +342,7 @@ class ParticipantType extends AbstractType
|
||||
$participantIndex = $form->getData()->index;
|
||||
|
||||
return true === $service->mandatory
|
||||
|| (Service::SOURCE_BOOKING === $service->source && in_array($participantIndex, $service->mapping));
|
||||
|| (Constants::SOURCE_BOOKING === $service->source && in_array($participantIndex, $service->mapping));
|
||||
});
|
||||
|
||||
if (0 < count($mandatoryServices)) {
|
||||
@@ -364,7 +365,7 @@ class ParticipantType extends AbstractType
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'data_class' => ParticipantData::class,
|
||||
'data_class' => ParticipantDto::class,
|
||||
'selectable_courses' => [],
|
||||
'selectable_ski_passes' => [],
|
||||
'selectable_services' => [],
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use App\Form\Model\RegistrationData;
|
||||
use App\Form\Model\RegistrationDto;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\EmailType;
|
||||
@@ -39,7 +39,7 @@ class RegistrationType extends AbstractType
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'data_class' => RegistrationData::class,
|
||||
'data_class' => RegistrationDto::class,
|
||||
'anti_xss' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace App\Validator\Constraints;
|
||||
use App\BusProNet\ApiClient;
|
||||
use App\BusProNet\Model\BookingUpdate;
|
||||
use App\BusProNet\Model\Notification;
|
||||
use App\Form\Model\BookingData;
|
||||
use App\Form\Model\BookingEditDto;
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\ConstraintValidator;
|
||||
|
||||
@@ -17,7 +17,7 @@ class BookingValidator extends ConstraintValidator
|
||||
|
||||
public function validate(mixed $value, Constraint $constraint): void
|
||||
{
|
||||
/** @var BookingData $booking */
|
||||
/** @var BookingEditDto $booking */
|
||||
$bookingData = $value;
|
||||
|
||||
$result = $this->apiClient->updateBooking($bookingData);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Validator\Constraints;
|
||||
|
||||
use App\Form\Model\ParticipantData;
|
||||
use App\Form\Model\ParticipantDto;
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\ConstraintValidator;
|
||||
|
||||
@@ -10,7 +10,7 @@ class ParticipantValidator extends ConstraintValidator
|
||||
{
|
||||
public function validate(mixed $value, Constraint $constraint): void
|
||||
{
|
||||
/** @var ParticipantData $participant */
|
||||
/** @var ParticipantDto $participant */
|
||||
$participant = $value;
|
||||
|
||||
$this->assertBodyMeasurementsValid($participant);
|
||||
@@ -18,7 +18,7 @@ class ParticipantValidator extends ConstraintValidator
|
||||
$this->assertPickupSelected($participant);
|
||||
}
|
||||
|
||||
public function assertBodyMeasurementsValid(ParticipantData $participant): void
|
||||
public function assertBodyMeasurementsValid(ParticipantDto $participant): void
|
||||
{
|
||||
if (0 === count($participant->rentals)) {
|
||||
return;
|
||||
@@ -34,7 +34,7 @@ class ParticipantValidator extends ConstraintValidator
|
||||
}
|
||||
}
|
||||
|
||||
public function assertTransportationSelected(ParticipantData $participant): void
|
||||
public function assertTransportationSelected(ParticipantDto $participant): void
|
||||
{
|
||||
// no transportation services required for canceled participants
|
||||
if (true === $participant->isCanceled()) {
|
||||
@@ -51,7 +51,7 @@ class ParticipantValidator extends ConstraintValidator
|
||||
}
|
||||
}
|
||||
|
||||
public function assertPickupSelected(ParticipantData $participant): void
|
||||
public function assertPickupSelected(ParticipantDto $participant): void
|
||||
{
|
||||
if (
|
||||
null !== $participant->transportationServiceTo
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<h2 class="text-lg font-semibold">
|
||||
Reise
|
||||
</h2>
|
||||
{{ bookingData.travel }}
|
||||
{{ bookingData.travelName }}
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold">
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<tr class="odd:bg-zinc-50 hover:bg-zinc-100 odd:hover:bg-zinc-100">
|
||||
<td class="border-r border-zinc-200 px-2 py-1 md:p-2"
|
||||
data-label="Reise">
|
||||
{{ booking.travel }}
|
||||
{{ booking.travelName }}
|
||||
</td>
|
||||
<td class="border-r border-zinc-200 px-2 py-1 md:p-2"
|
||||
data-label="Buchungsdatum">
|
||||
|
||||
Reference in New Issue
Block a user