Olivier Massot vor 9 Monaten
Ursprung
Commit
089af4a7e2
100 geänderte Dateien mit 1160 neuen und 1313 gelöschten Zeilen
  1. 19 13
      .gitlab-ci.yml
  2. 62 67
      composer.json
  3. 9 1
      config/packages/api_platform.yaml
  4. 3 0
      config/packages/liip_imagine.yaml
  5. 3 6
      config/services.yaml
  6. 2 1
      phpstan.neon.dist
  7. 2 2
      src/ApiResources/Profile/AccessProfile.php
  8. 2 2
      src/ApiResources/Profile/OrganizationProfile.php
  9. 4 11
      src/Commands/Doctrine/SchemaUpdateCommand.php
  10. 10 4
      src/Doctrine/AbstractExtension.php
  11. 0 1
      src/Doctrine/ORM/AST/SphericalDistance.php
  12. 191 118
      src/Entity/Access/Access.php
  13. 4 2
      src/Entity/Access/AccessCommunication.php
  14. 6 3
      src/Entity/Access/AccessFamily.php
  15. 4 2
      src/Entity/Access/AccessNetworkSetting.php
  16. 4 2
      src/Entity/Access/AccessSocial.php
  17. 2 0
      src/Entity/Access/FunctionType.php
  18. 2 2
      src/Entity/Access/OrganizationFunction.php
  19. 3 1
      src/Entity/Access/OrganizationResponsability.php
  20. 4 4
      src/Entity/Access/PersonalizedList.php
  21. 1 1
      src/Entity/Access/Preferences.php
  22. 6 2
      src/Entity/AccessWish/AccessFamilyWish.php
  23. 4 2
      src/Entity/AccessWish/AccessTmp.php
  24. 19 15
      src/Entity/AccessWish/AccessWish.php
  25. 9 6
      src/Entity/AccessWish/DocumentWish.php
  26. 16 13
      src/Entity/AccessWish/EducationStudentWish.php
  27. 9 6
      src/Entity/Awin/Product.php
  28. 30 135
      src/Entity/Billing/AbstractBillAccounting.php
  29. 3 2
      src/Entity/Billing/AbstractBillingIntangible.php
  30. 8 0
      src/Entity/Billing/AbstractBillingPayer.php
  31. 11 8
      src/Entity/Billing/AccessBilling.php
  32. 6 4
      src/Entity/Billing/AccessFictionalIntangible.php
  33. 4 1
      src/Entity/Billing/AccessIntangible.php
  34. 1 4
      src/Entity/Billing/AccessPayer.php
  35. 4 3
      src/Entity/Billing/AdvancePayment.php
  36. 6 2
      src/Entity/Billing/Afi.php
  37. 7 3
      src/Entity/Billing/BergerLevrault.php
  38. 101 3
      src/Entity/Billing/Bill.php
  39. 2 2
      src/Entity/Billing/BillAccessDetail.php
  40. 5 3
      src/Entity/Billing/BillAccounting.php
  41. 4 3
      src/Entity/Billing/BillCredit.php
  42. 3 1
      src/Entity/Billing/BillDebitBalance.php
  43. 9 7
      src/Entity/Billing/BillLine.php
  44. 18 13
      src/Entity/Billing/BillPayment.php
  45. 4 1
      src/Entity/Billing/BillPeriod.php
  46. 9 3
      src/Entity/Billing/BillSchedule.php
  47. 3 0
      src/Entity/Billing/BillScheduleDate.php
  48. 3 1
      src/Entity/Billing/BillTotalDetail.php
  49. 9 6
      src/Entity/Billing/BillingExportSetting.php
  50. 7 6
      src/Entity/Billing/BillingIntangibleExcludeDate.php
  51. 11 6
      src/Entity/Billing/BillingSetting.php
  52. 7 5
      src/Entity/Billing/BillingSettingRent.php
  53. 8 5
      src/Entity/Billing/Ciril.php
  54. 8 4
      src/Entity/Billing/CirilCivil.php
  55. 8 13
      src/Entity/Billing/EducationalProjectIntangible.php
  56. 5 18
      src/Entity/Billing/EducationalProjectPayer.php
  57. 5 3
      src/Entity/Billing/FamilyQuotient.php
  58. 8 7
      src/Entity/Billing/FamilyQuotientBand.php
  59. 8 4
      src/Entity/Billing/FamilyQuotientBandDetail.php
  60. 7 2
      src/Entity/Billing/FamilyQuotientModel.php
  61. 8 5
      src/Entity/Billing/Jvs.php
  62. 8 4
      src/Entity/Billing/Odyssee.php
  63. 3 0
      src/Entity/Billing/PayboxPaymentReturn.php
  64. 3 1
      src/Entity/Billing/PayfipPaymentReturn.php
  65. 9 5
      src/Entity/Billing/Pes.php
  66. 6 4
      src/Entity/Billing/PesSetting.php
  67. 4 2
      src/Entity/Billing/ResidenceArea.php
  68. 8 5
      src/Entity/Billing/SddBank.php
  69. 11 8
      src/Entity/Billing/SddRegie.php
  70. 3 1
      src/Entity/Billing/SddTeneur.php
  71. 62 56
      src/Entity/Booking/AbstractBooking.php
  72. 15 1
      src/Entity/Booking/AbstractBookingRecur.php
  73. 6 5
      src/Entity/Booking/Attendance.php
  74. 8 8
      src/Entity/Booking/AttendanceBooking.php
  75. 2 1
      src/Entity/Booking/AttendanceBookingReason.php
  76. 10 8
      src/Entity/Booking/CalendarSynchro.php
  77. 20 121
      src/Entity/Booking/Course.php
  78. 5 18
      src/Entity/Booking/CourseRecur.php
  79. 28 73
      src/Entity/Booking/EducationalProject.php
  80. 5 0
      src/Entity/Booking/EducationalProjectAge.php
  81. 7 1
      src/Entity/Booking/EducationalProjectPublic.php
  82. 6 17
      src/Entity/Booking/EducationalProjectRecur.php
  83. 23 104
      src/Entity/Booking/Event.php
  84. 5 0
      src/Entity/Booking/EventGender.php
  85. 5 16
      src/Entity/Booking/EventRecur.php
  86. 8 2
      src/Entity/Booking/EventReport.php
  87. 3 3
      src/Entity/Booking/EventUser.php
  88. 44 39
      src/Entity/Booking/Examen.php
  89. 3 2
      src/Entity/Booking/ExamenConvocation.php
  90. 5 18
      src/Entity/Booking/ExamenRecur.php
  91. 4 21
      src/Entity/Booking/OrganizationHoliday.php
  92. 5 18
      src/Entity/Booking/OrganizationHolidayRecur.php
  93. 19 54
      src/Entity/Booking/PersonHoliday.php
  94. 5 18
      src/Entity/Booking/PersonHolidayRecur.php
  95. 8 4
      src/Entity/Booking/Work.php
  96. 5 3
      src/Entity/Booking/WorkByUser.php
  97. 16 51
      src/Entity/Core/AbstractControl.php
  98. 5 38
      src/Entity/Core/AbstractInformation.php
  99. 19 6
      src/Entity/Core/AbstractRepair.php
  100. 9 7
      src/Entity/Core/AddressPostal.php

+ 19 - 13
.gitlab-ci.yml

@@ -14,19 +14,6 @@ before_script:
   - bash tests/ci_docker_install.sh > /dev/null
   - php -v
 
-static_analysis:
-  script:
-    - php vendor/bin/phpstan analyse -c phpstan.neon.dist --error-format gitlab > phpstan.json  # Display code quality in MR
-    - php vendor/bin/phpstan analyse -c phpstan.neon.dist
-  artifacts:
-    when: always
-    reports:
-      codequality: phpstan.json
-
-code_style:
-  script:
-    - php vendor/bin/php-cs-fixer check --config=.php-cs-fixer.dist.php
-
 unit:
   stage: test
 
@@ -43,3 +30,22 @@ unit:
 
   coverage: '/^\s*Lines:\s*\d+.\d+\%/'
 
+#doctrine:
+#  script:
+#    - php bin/console d:s:v
+
+static_analysis:
+  script:
+    - php vendor/bin/phpstan analyse -c phpstan.neon.dist --error-format gitlab > phpstan.json  # Display code quality in MR
+    - php vendor/bin/phpstan analyse -c phpstan.neon.dist
+  artifacts:
+    when: always
+    reports:
+      codequality: phpstan.json
+
+code_style:
+  script:
+    - php vendor/bin/php-cs-fixer check --config=.php-cs-fixer.dist.php
+
+
+

+ 62 - 67
composer.json

@@ -2,10 +2,6 @@
   "type": "project",
   "license": "proprietary",
   "repositories": [
-    {
-      "type": "vcs",
-      "url": "ssh://git@gitlab.2iopenservice.com/vincent/foselastica.git"
-    },
     {
       "type": "vcs",
       "url": "ssh://git@gitlab.2iopenservice.com/opentalent/phpdocx-15.5.git"
@@ -15,92 +11,91 @@
     "php": ">=8.2",
     "ext-ctype": "*",
     "ext-iconv": "*",
-    "api-platform/core": "3.1.7",
+    "api-platform/core": "^4.0",
     "beberlei/doctrineextensions": "^1.3",
-    "blackfire/php-sdk": "^1.23",
     "composer/package-versions-deprecated": "^1.11",
-    "doctrine/dbal": "^2.6",
-    "doctrine/doctrine-bundle": "^2.1",
-    "doctrine/doctrine-migrations-bundle": "^3.0",
-    "doctrine/orm": "^2.17",
-    "dompdf/dompdf": "^3.0",
-    "egulias/email-validator": "^3.0",
+    "doctrine/dbal": "^3.9",
+    "doctrine/doctrine-bundle": "2.13",
+    "doctrine/doctrine-migrations-bundle": "^3.4",
+    "doctrine/orm": "^3.3",
+    "dompdf/dompdf": "^3.1",
+    "egulias/email-validator": "^4.0",
     "jbouzekri/phumbor-bundle": "^3.1.0",
-    "knplabs/knp-gaufrette-bundle": "^0.8.0",
-    "knplabs/knp-snappy-bundle": "^1.9",
-    "lcobucci/jwt": "^4.1",
-    "lexik/jwt-authentication-bundle": "^2.8",
-    "liip/imagine-bundle": "^2.12",
+    "knplabs/knp-gaufrette-bundle": "0.9.0",
+    "knplabs/knp-snappy-bundle": "^1.10",
+    "lcobucci/jwt": "^5.5",
+    "lexik/jwt-authentication-bundle": "^3.1",
+    "liip/imagine-bundle": "^2.13",
     "lorenzo/pinky": "^1.0",
-    "myclabs/php-enum": "^1.7",
-    "nelmio/cors-bundle": "^2.1",
+    "myclabs/php-enum": "^1.8",
+    "nelmio/cors-bundle": "^2.5",
     "nette/php-generator": "^4.1",
-    "odolbeau/phone-number-bundle": "^3.1",
+    "odolbeau/phone-number-bundle": "^4.1",
     "olinox14/path-php": "^0.1.8",
     "opentalent/phpdocx": "dev-master",
-    "phpdocumentor/reflection-docblock": "^5.2",
-    "phpstan/phpdoc-parser": "^1.0",
+    "phpdocumentor/reflection-docblock": "^5.6",
+    "phpstan/phpdoc-parser": "^1.16",
     "ramsey/uuid": "^4.2",
     "ramsey/uuid-doctrine": "^2.0",
-    "symfony/asset": "6.3.*",
-    "symfony/console": "6.3.*",
-    "symfony/doctrine-messenger": "6.3.*",
-    "symfony/dotenv": "6.3.*",
-    "symfony/error-handler": "6.3.*",
-    "symfony/expression-language": "6.3.*",
+    "symfony/asset": "7.2.*",
+    "symfony/console": "7.2.*",
+    "symfony/doctrine-messenger": "7.2.*",
+    "symfony/dotenv": "7.2.*",
+    "symfony/error-handler": "7.2.*",
+    "symfony/expression-language": "7.2.*",
     "symfony/flex": "^1.3.1",
-    "symfony/framework-bundle": "6.3.*",
-    "symfony/http-client": "6.3.*",
-    "symfony/intl": "6.3.*",
-    "symfony/lock": "6.3.*",
-    "symfony/mailer": "6.3.*",
+    "symfony/framework-bundle": "7.2.*",
+    "symfony/http-client": "7.2.*",
+    "symfony/intl": "7.2.*",
+    "symfony/lock": "7.2.*",
+    "symfony/mailer": "7.2.*",
     "symfony/mercure": "^0.6.1",
     "symfony/mercure-bundle": "^0.3.4",
-    "symfony/messenger": "6.3.*",
+    "symfony/messenger": "7.2.*",
     "symfony/monolog-bundle": "^3.7",
     "symfony/polyfill-intl-icu": "^1.21",
     "symfony/polyfill-intl-messageformatter": "^1.24",
-    "symfony/property-access": "6.3.*",
-    "symfony/property-info": "6.3.*",
-    "symfony/security-bundle": "6.3.*",
-    "symfony/serializer": "6.3.*",
-    "symfony/translation": "6.3.*",
-    "symfony/twig-bundle": "6.3.*",
-    "symfony/uid": "6.3.*",
-    "symfony/validator": "6.3.*",
-    "symfony/yaml": "6.3.*",
-    "twig/cssinliner-extra": "^3.4",
-    "twig/extra-bundle": "^3.4",
-    "twig/inky-extra": "^3.4",
-    "vincent/foselastica": "1.3.1",
-    "webonyx/graphql-php": "^14.3",
+    "symfony/property-access": "7.2.*",
+    "symfony/property-info": "7.2.*",
+    "symfony/security-bundle": "7.2.*",
+    "symfony/serializer": "7.2.*",
+    "symfony/translation": "7.2.*",
+    "symfony/twig-bundle": "7.2.*",
+    "symfony/uid": "7.2.*",
+    "symfony/validator": "7.2.*",
+    "symfony/yaml": "7.2.*",
+    "twig/cssinliner-extra": "^3.20",
+    "twig/extra-bundle": "^3.20",
+    "twig/inky-extra": "^3.20",
+    "webonyx/graphql-php": "^15.19",
     "xantios/mimey": "*"
   },
   "require-dev": {
-    "cyclonedx/cyclonedx-php-composer": "^3.4",
+    "cyclonedx/cyclonedx-php-composer": "^5.2",
     "dg/bypass-finals": "^1.4",
     "doctrine/doctrine-fixtures-bundle": "^3.4",
     "ergebnis/phpstan-rules": "^2.5",
-    "friendsofphp/php-cs-fixer": "^3.52.1",
-    "hautelook/alice-bundle": "^2.11",
-    "justinrainbow/json-schema": "^5.2",
-    "phpstan/extension-installer": "^1.4",
-    "phpstan/phpstan": "^1.10",
+    "friendsofphp/php-cs-fixer": "^3.69",
+    "hautelook/alice-bundle": "^2.14",
+    "justinrainbow/json-schema": "^6.1",
+    "phpstan/extension-installer": "^1.2",
+    "phpstan/phpstan": "^2.1",
     "phpstan/phpstan-deprecation-rules": "^1.2",
-    "phpstan/phpstan-doctrine": "^1.3",
-    "phpstan/phpstan-phpunit": "^1.3",
-    "phpstan/phpstan-symfony": "^1.3",
+    "phpstan/phpstan-doctrine": "^2.0",
+    "phpstan/phpstan-phpunit": "^2.0",
+    "phpstan/phpstan-symfony": "^2.0",
     "phpunit/phpunit": "^9.6",
-    "rector/rector": "^1.2",
-    "symfony/browser-kit": "6.3.*",
-    "symfony/css-selector": "6.3.*",
-    "symfony/debug-bundle": "6.3.*",
+    "rector/rector": "^2.0",
+    "symfony/browser-kit": "7.2.*",
+    "symfony/css-selector": "7.2.*",
+    "symfony/debug-bundle": "7.2.*",
     "symfony/maker-bundle": "^1.48",
-    "symfony/phpunit-bridge": "6.3.*",
-    "symfony/stopwatch": "6.3.*",
-    "symfony/web-profiler-bundle": "6.3.*",
-    "timeweb/phpstan-enum": "^3.1",
-    "zenstruck/foundry": "^1.31"
+    "symfony/phpunit-bridge": "7.2.*",
+    "symfony/stopwatch": "7.2.*",
+    "symfony/web-profiler-bundle": "7.2.*",
+    "theofidry/alice-data-fixtures": "1.7.2",
+    "timeweb/phpstan-enum": "^4.0",
+    "zenstruck/foundry": "2.3"
   },
   "config": {
     "optimize-autoloader": true,
@@ -157,7 +152,7 @@
   "extra": {
     "symfony": {
       "allow-contrib": false,
-      "require": "6.3.*"
+      "require": "7.2.*"
     },
     "phpstan": {
       "includes": [

+ 9 - 1
config/packages/api_platform.yaml

@@ -1,6 +1,6 @@
 api_platform:
     title: 'Opentalent API'
-    version: '3.1'
+    version: '2.5'
     enable_swagger_ui: false
     enable_re_doc: false
     mapping:
@@ -21,3 +21,11 @@ api_platform:
             ## property is true which means that from now on null values are omitted during serialization.
             ## we don't want this => surcharge default value to false
             skip_null_values: false
+    graphql:
+        graphql_playground: false
+    use_symfony_listeners: true
+    mercure:
+        enabled: true
+    messenger:
+        enabled: true
+    # To enable collecting denormalization errors

+ 3 - 0
config/packages/liip_imagine.yaml

@@ -19,6 +19,9 @@ liip_imagine:
 
     data_loader: stream.storage
 
+    twig:
+        mode: 'lazy'
+
     filter_sets:
         sm:
             filters:

+ 3 - 6
config/services.yaml

@@ -68,6 +68,9 @@ services:
     App\Tests\Fixture\:
         resource: '%kernel.project_dir%/tests/Fixture/*'
 
+    Doctrine\ORM\Tools\Console\EntityManagerProvider: '@doctrine.orm.command.entity_manager_provider'
+
+
     #########################################
     ##  TAG Services ##
     _instanceof:
@@ -119,12 +122,6 @@ services:
     #########################################
     ##  LISTENER ##
 
-    #########################################
-    ##  ELASTIC SERVICE ##
-    App\Service\Elasticsearch\EducationNotationUpdater:
-        arguments:
-            - '@fos_elastica.object_persister.search.educationNotation'
-
     #########################################
     ## AutoWiring du service container ##
     Symfony\Component\DependencyInjection\ContainerInterface: '@service_container'

+ 2 - 1
phpstan.neon.dist

@@ -9,7 +9,8 @@ parameters:
     # on ignore les erreurs qui imposent d'indiquer le type d'un iterable dans la phpDoc (cf: https://phpstan.org/blog/solving-phpstan-no-value-type-specified-in-iterable-type)
     ignoreErrors :
         - '#Attribute class JetBrains\\PhpStorm\\[a-zA-Z]+ does not exist.#'
-        - identifier: missingType.generics
+        - identifier: 'missingType.generics'
+        - '#Property .+::\$id \(int\|null\) is never assigned int so it can be removed from the property type\.$#'
 
     ergebnis:
         # TODO: simplify by using allRules: false (https://github.com/ergebnis/phpstan-rules?tab=readme-ov-file#enabling-rules-one-by-one)

+ 2 - 2
src/ApiResources/Profile/AccessProfile.php

@@ -56,14 +56,14 @@ class AccessProfile implements ApiResourcesInterface
 
     /** @var list<string> $roles */
     #[Groups('access_profile_read')]
-    private ?array $roles = [];
+    private array $roles = [];
 
     #[Groups('access_profile_read')]
     private ?int $activityYear = null;
 
     /** @var bool[] $historical */
     #[Groups('access_profile_read')]
-    private ?array $historical = [];
+    private array $historical = [];
 
     #[Groups('access_profile_read')]
     private bool $isGuardian = false;

+ 2 - 2
src/ApiResources/Profile/OrganizationProfile.php

@@ -48,14 +48,14 @@ class OrganizationProfile implements ApiResourcesInterface
 
     /** @var list<string> $modules */
     #[Groups('access_profile_read')]
-    private ?array $modules = [];
+    private array $modules = [];
 
     #[Groups('access_profile_read')]
     private bool $hasChildren = false;
 
     /** @var list<OrganizationProfile> */
     #[Groups('access_profile_read')]
-    private ?array $parents = [];
+    private array $parents = [];
 
     #[Groups('access_profile_read')]
     private bool $showAdherentList = false;

+ 4 - 11
src/Commands/Doctrine/SchemaUpdateCommand.php

@@ -6,9 +6,8 @@ declare(strict_types=1);
 
 namespace App\Commands\Doctrine;
 
-use App\Service\Utils\FileUtils;
-use App\Service\Utils\PathUtils;
-use Doctrine\Bundle\DoctrineBundle\Command\Proxy\UpdateSchemaDoctrineCommand;
+use App\Service\Utils\Path;
+use Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand;
 use Doctrine\ORM\Tools\SchemaTool;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Output\OutputInterface;
@@ -17,15 +16,9 @@ use Symfony\Component\Console\Style\SymfonyStyle;
 /**
  * Overrides the default doctrine:schema:update command.
  */
-class SchemaUpdateCommand extends UpdateSchemaDoctrineCommand
+class SchemaUpdateCommand extends UpdateCommand
 {
-    public function __construct(
-        private readonly FileUtils $fileUtils,
-    ) {
-        parent::__construct();
-    }
-
-    protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas, SymfonyStyle $ui): ?int
+    protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas, SymfonyStyle $ui): int
     {
         $output->writeln('-- Executing pre-update scripts');
 

+ 10 - 4
src/Doctrine/AbstractExtension.php

@@ -30,13 +30,19 @@ abstract class AbstractExtension implements QueryCollectionExtensionInterface, Q
     /**
      * Called by doctrine when getting an item.
      *
-     * @param list<int> $identifiers
-     * @param mixed[]   $context
+     * @param array<string, mixed> $identifiers
+     * @param mixed[]              $context
      *
      * @throws \Exception
      */
-    public function applyToItem(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, array $identifiers, ?Operation $operation = null, array $context = []): void
-    {
+    public function applyToItem(
+        QueryBuilder $queryBuilder,
+        QueryNameGeneratorInterface $queryNameGenerator,
+        string $resourceClass,
+        array $identifiers,
+        ?Operation $operation = null,
+        array $context = [],
+    ): void {
         $this->apply($queryBuilder, $resourceClass, $operation);
     }
 

+ 0 - 1
src/Doctrine/ORM/AST/SphericalDistance.php

@@ -7,7 +7,6 @@ namespace App\Doctrine\ORM\AST;
 use Doctrine\ORM\Query\AST\ASTException;
 use Doctrine\ORM\Query\AST\Functions\FunctionNode;
 use Doctrine\ORM\Query\AST\Node;
-use Doctrine\ORM\Query\Lexer;
 use Doctrine\ORM\Query\Parser;
 use Doctrine\ORM\Query\QueryException;
 use Doctrine\ORM\Query\SqlWalker;

+ 191 - 118
src/Entity/Access/Access.php

@@ -18,7 +18,6 @@ use App\Entity\Billing\Bill;
 use App\Entity\Billing\BillCredit;
 use App\Entity\Billing\BillLine;
 use App\Entity\Billing\EducationalProjectPayer;
-use App\Entity\Booking\AbstractBooking;
 use App\Entity\Booking\Attendance;
 use App\Entity\Booking\AttendanceBooking;
 use App\Entity\Booking\CalendarSynchro;
@@ -29,7 +28,6 @@ use App\Entity\Booking\EventUser;
 use App\Entity\Booking\ExamenConvocation;
 use App\Entity\Booking\PersonHoliday;
 use App\Entity\Booking\WorkByUser;
-use App\Entity\Core\AbstractControl;
 use App\Entity\Core\Notification;
 use App\Entity\Core\NotificationUser;
 use App\Entity\Core\Tagg;
@@ -38,6 +36,7 @@ use App\Entity\Education\EducationNotationConfig;
 use App\Entity\Education\EducationStudent;
 use App\Entity\Education\EducationTeacher;
 use App\Entity\Message\AbstractMessage;
+use App\Entity\Message\AbstractReport;
 use App\Entity\Message\Email;
 use App\Entity\Message\Mail;
 use App\Entity\Message\Sms;
@@ -52,11 +51,12 @@ use App\Entity\Person\PersonActivity;
 use App\Entity\Place\PlaceRepair;
 use App\Entity\Place\RoomRepair;
 use App\Entity\Product\Equipment;
+use App\Entity\Product\EquipmentControl;
 use App\Entity\Product\EquipmentLoan;
 use App\Entity\Product\EquipmentRepair;
 use App\Entity\Reward\AccessReward;
-use App\Entity\Traits\CreatedOnAndByTrait;
 use App\Entity\Token\Token;
+use App\Entity\Traits\CreatedOnAndByTrait;
 use App\Filter\ApiPlatform\Person\FullNameFilter;
 use App\Filter\ApiPlatform\Utils\InFilter;
 use App\Repository\Access\AccessRepository;
@@ -75,7 +75,7 @@ use Symfony\Component\Serializer\Annotation\Groups;
  * Security :
  *
  *     @see ~/config/api_platform/Access/access.yaml
- *     @see App\Doctrine\Access\CurrentAccessExtension
+ *     @see \App\Doctrine\Access\CurrentAccessExtension
  */
 #[ApiResource]
 // #[Auditable]
@@ -101,7 +101,7 @@ class Access implements UserInterface, PasswordAuthenticatedUserInterface
     #[Groups(['private'])]
     private bool $superAdminAccess = false;
 
-    #[ORM\Column(type: "smallint", nullable: true)]
+    #[ORM\Column(nullable: true)]
     #[Groups(['my_access:input'])]
     private ?int $activityYear = null;
 
@@ -127,79 +127,100 @@ class Access implements UserInterface, PasswordAuthenticatedUserInterface
     private ?array $setting = [];
 
     #[ORM\OneToOne(mappedBy: 'access', cascade: ['persist'], orphanRemoval: true)]
-    private AccessBilling $accessBilling;
+    private ?AccessBilling $accessBilling;
 
-    #[ORM\OneToMany(mappedBy: 'access', targetEntity: PersonActivity::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, PersonActivity> */
+    #[ORM\OneToMany(targetEntity: PersonActivity::class, mappedBy: 'access', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $personActivity;
 
-    #[ORM\OneToMany(mappedBy: 'access', targetEntity: OrganizationFunction::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, OrganizationFunction> */
+    #[ORM\OneToMany(targetEntity: OrganizationFunction::class, mappedBy: 'access', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $organizationFunction;
 
-    #[ORM\OneToMany(mappedBy: 'licensee', targetEntity: OrganizationLicence::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, OrganizationLicence> */
+    #[ORM\OneToMany(targetEntity: OrganizationLicence::class, mappedBy: 'licensee', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $organizationLicences;
 
-    #[ORM\OneToMany(mappedBy: 'access', targetEntity: PersonalizedList::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, PersonalizedList> */
+    #[ORM\OneToMany(targetEntity: PersonalizedList::class, mappedBy: 'access', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $personalizedLists;
 
-    #[ORM\OneToMany(mappedBy: 'recipientAccess', targetEntity: Notification::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, Notification> */
+    #[ORM\OneToMany(targetEntity: Notification::class, mappedBy: 'recipientAccess', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $notifications;
 
-    #[ORM\OneToMany(mappedBy: 'access', targetEntity: NotificationUser::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, NotificationUser> */
+    #[ORM\OneToMany(targetEntity: NotificationUser::class, mappedBy: 'access', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $notificationUsers;
 
+    /** @var Collection<int, Access> */
     #[ORM\ManyToMany(targetEntity: Access::class, mappedBy: 'children', cascade: ['persist'])]
     private Collection $guardians;
 
+    /** @var Collection<int, Access> */
     #[ORM\ManyToMany(targetEntity: Access::class, inversedBy: 'guardians', cascade: ['persist'])]
     #[ORM\JoinTable(name: 'children_guardians')]
     #[ORM\JoinColumn(name: 'guardians_id', referencedColumnName: 'id')]
     #[ORM\InverseJoinColumn(name: 'children_id', referencedColumnName: 'id')]
     private Collection $children;
 
-    #[ORM\OneToMany(mappedBy: 'accessPayer', targetEntity: AccessPayer::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, AccessPayer> */
+    #[ORM\OneToMany(targetEntity: AccessPayer::class, mappedBy: 'accessPayer', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $billingPayers;
 
-    #[ORM\OneToMany(mappedBy: 'accessReceiver', targetEntity: AccessPayer::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, AccessPayer> */
+    #[ORM\OneToMany(targetEntity: AccessPayer::class, mappedBy: 'accessReceiver', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $billingReceivers;
 
-    #[ORM\OneToMany(mappedBy: 'access', targetEntity: AccessIntangible::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, AccessIntangible> */
+    #[ORM\OneToMany(targetEntity: AccessIntangible::class, mappedBy: 'access', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $accessIntangibles;
 
     #[ORM\ManyToOne(inversedBy: 'publicationDirectors')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: false)]
-    private ?Parameters $publicationDirector;
+    private Parameters $publicationDirector;
 
     #[ORM\ManyToOne(inversedBy: 'teachers')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
     private ?EducationNotationConfig $educationNotationConfig;
 
-    #[ORM\OneToMany(mappedBy: 'company', targetEntity: CompanyPerson::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, CompanyPerson> */
+    #[ORM\OneToMany(targetEntity: CompanyPerson::class, mappedBy: 'company', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $companyPersonAccesses;
 
-    #[ORM\OneToMany(mappedBy: 'access', targetEntity: CompanyPerson::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, CompanyPerson> */
+    #[ORM\OneToMany(targetEntity: CompanyPerson::class, mappedBy: 'access', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $companyPersonCompany;
 
-    #[ORM\OneToMany(mappedBy: 'access', targetEntity: EducationStudent::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, EducationStudent> */
+    #[ORM\OneToMany(targetEntity: EducationStudent::class, mappedBy: 'access', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $educationStudent;
 
+    /** @var Collection<int, EducationStudent> */
     #[ORM\ManyToMany(targetEntity: EducationStudent::class, mappedBy: 'teachers', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $educationStudentByTeacher;
 
-    #[ORM\OneToMany(mappedBy: 'teacher', targetEntity: EducationTeacher::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, EducationTeacher> */
+    #[ORM\OneToMany(targetEntity: EducationTeacher::class, mappedBy: 'teacher', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $educationTeachers;
 
-    #[ORM\OneToMany(mappedBy: 'access', targetEntity: PersonHoliday::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, PersonHoliday> */
+    #[ORM\OneToMany(targetEntity: PersonHoliday::class, mappedBy: 'access', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $holidays;
 
+    /** @var Collection<int, Course> */
     #[ORM\ManyToMany(targetEntity: Course::class, mappedBy: 'students', cascade: ['persist'])]
     private Collection $courses;
 
+    /** @var Collection<int, Course> */
     #[ORM\ManyToMany(targetEntity: Course::class, mappedBy: 'organizer', cascade: ['persist'])]
     private Collection $practicalCourses;
 
+    /** @var Collection<int, Event> */
     #[ORM\ManyToMany(targetEntity: Event::class, mappedBy: 'organizer', cascade: ['persist'])]
     private Collection $eventOrganizers;
 
+    /** @var Collection<int, EducationalProject> */
     #[ORM\ManyToMany(targetEntity: EducationalProject::class, mappedBy: 'organizer', cascade: ['persist'])]
     private Collection $educationalProjectOrganizers;
 
@@ -213,141 +234,184 @@ class Access implements UserInterface, PasswordAuthenticatedUserInterface
     #[ORM\Column]
     private bool $ielEnabled = false;
 
-    #[ORM\OneToMany(mappedBy: 'educationalProjectPayer', targetEntity: EducationalProjectPayer::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, EducationalProjectPayer> */
+    #[ORM\OneToMany(targetEntity: EducationalProjectPayer::class, mappedBy: 'educationalProjectPayer', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $billingEducationalProjectPayers;
 
-    #[ORM\OneToMany(mappedBy: 'access', targetEntity: Bill::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, Bill> */
+    #[ORM\OneToMany(targetEntity: Bill::class, mappedBy: 'access', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $bills;
 
-    #[ORM\OneToMany(mappedBy: 'access', targetEntity: BillLine::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, BillLine> */
+    #[ORM\OneToMany(targetEntity: BillLine::class, mappedBy: 'access', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $billLines;
 
-    #[ORM\OneToMany(mappedBy: 'access', targetEntity: BillCredit::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, BillCredit> */
+    #[ORM\OneToMany(targetEntity: BillCredit::class, mappedBy: 'access', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $billCredits;
 
-    #[ORM\OneToMany(mappedBy: 'silentPartner', targetEntity: EducationalProject::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, EducationalProject> */
+    #[ORM\OneToMany(targetEntity: EducationalProject::class, mappedBy: 'silentPartner', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $silentPartners;
 
-    #[ORM\OneToMany(mappedBy: 'operationalPartner', targetEntity: EducationalProject::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, EducationalProject> */
+    #[ORM\OneToMany(targetEntity: EducationalProject::class, mappedBy: 'operationalPartner', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $operationalPartners;
 
-    #[ORM\OneToMany(mappedBy: 'guest', targetEntity: EventUser::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, EventUser> */
+    #[ORM\OneToMany(targetEntity: EventUser::class, mappedBy: 'guest', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $eventUsers;
 
-    #[ORM\OneToMany(mappedBy: 'student', targetEntity: ExamenConvocation::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, ExamenConvocation> */
+    #[ORM\OneToMany(targetEntity: ExamenConvocation::class, mappedBy: 'student', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $examenConvocations;
 
-    #[ORM\OneToMany(mappedBy: 'provider', targetEntity: EquipmentRepair::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, EquipmentRepair> */
+    #[ORM\OneToMany(targetEntity: EquipmentRepair::class, mappedBy: 'provider', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $equipmentRepairProviders;
 
-    #[ORM\OneToMany(mappedBy: 'access', targetEntity: Attendance::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, Attendance> */
+    #[ORM\OneToMany(targetEntity: Attendance::class, mappedBy: 'access', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $attendances;
 
-    #[ORM\OneToMany(mappedBy: 'access', targetEntity: AttendanceBooking::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, AttendanceBooking> */
+    #[ORM\OneToMany(targetEntity: AttendanceBooking::class, mappedBy: 'access', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $attendanceBookings;
 
-    #[ORM\OneToMany(mappedBy: 'replacement', targetEntity: Attendance::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, Attendance> */
+    #[ORM\OneToMany(targetEntity: Attendance::class, mappedBy: 'replacement', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $attendanceReplacements;
 
-    #[ORM\OneToMany(mappedBy: 'provider', targetEntity: RoomRepair::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, RoomRepair> */
+    #[ORM\OneToMany(targetEntity: RoomRepair::class, mappedBy: 'provider', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $roomRepairProviders;
 
-    #[ORM\OneToMany(mappedBy: 'provider', targetEntity: PlaceRepair::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, PlaceRepair> */
+    #[ORM\OneToMany(targetEntity: PlaceRepair::class, mappedBy: 'provider', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $placeRepairProviders;
 
-    #[ORM\OneToMany(mappedBy: 'author', targetEntity: Email::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, Email> */
+    #[ORM\OneToMany(targetEntity: Email::class, mappedBy: 'author', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $emails;
 
-    #[ORM\OneToMany(mappedBy: 'author', targetEntity: Mail::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, Mail> */
+    #[ORM\OneToMany(targetEntity: Mail::class, mappedBy: 'author', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $mails;
 
-    #[ORM\OneToMany(mappedBy: 'author', targetEntity: Sms::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, Sms> */
+    #[ORM\OneToMany(targetEntity: Sms::class, mappedBy: 'author', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $sms;
 
+    /** @var Collection<int, Jury> */
     #[ORM\ManyToMany(targetEntity: Jury::class, mappedBy: 'members', orphanRemoval: true)]
     private Collection $juryMembers;
 
-    #[ORM\OneToMany(mappedBy: 'contactPerson', targetEntity: Organization::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, Organization> */
+    #[ORM\OneToMany(targetEntity: Organization::class, mappedBy: 'contactPerson', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $organizationContacts;
 
-    #[ORM\OneToMany(mappedBy: 'member', targetEntity: CommissionMember::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, CommissionMember> */
+    #[ORM\OneToMany(targetEntity: CommissionMember::class, mappedBy: 'member', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $commissionMembers;
 
-    #[ORM\OneToMany(mappedBy: 'supplier', targetEntity: Equipment::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, Equipment> */
+    #[ORM\OneToMany(targetEntity: Equipment::class, mappedBy: 'supplier', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $equipmentSuppliers;
 
-    #[ORM\OneToMany(mappedBy: 'controlManager', targetEntity: Equipment::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, Equipment> */
+    #[ORM\OneToMany(targetEntity: Equipment::class, mappedBy: 'controlManager', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $equipmentControlManagers;
 
-    #[ORM\OneToMany(mappedBy: 'editor', targetEntity: Equipment::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, Equipment> */
+    #[ORM\OneToMany(targetEntity: Equipment::class, mappedBy: 'editor', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $equipmentEditors;
 
-    #[ORM\OneToMany(mappedBy: 'borrower', targetEntity: EquipmentLoan::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, EquipmentLoan> */
+    #[ORM\OneToMany(targetEntity: EquipmentLoan::class, mappedBy: 'borrower', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $equipmentLoans;
 
-    #[ORM\OneToMany(mappedBy: 'access', targetEntity: Equipment::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, Equipment> */
+    #[ORM\OneToMany(targetEntity: Equipment::class, mappedBy: 'access', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $equipments;
 
-    #[ORM\OneToMany(mappedBy: 'access', targetEntity: AccessFictionalIntangible::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, AccessFictionalIntangible> */
+    #[ORM\OneToMany(targetEntity: AccessFictionalIntangible::class, mappedBy: 'access', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $accessFictionalIntangibles;
 
-    #[ORM\OneToMany(mappedBy: 'access', targetEntity: Donor::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, Donor> */
+    #[ORM\OneToMany(targetEntity: Donor::class, mappedBy: 'access', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $donors;
 
-    #[ORM\OneToMany(mappedBy: 'access', targetEntity: AccessReward::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, AccessReward> */
+    #[ORM\OneToMany(targetEntity: AccessReward::class, mappedBy: 'access', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $accessRewards;
 
-    #[ORM\OneToMany(mappedBy: 'access', targetEntity: OrganizationResponsability::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, OrganizationResponsability> */
+    #[ORM\OneToMany(targetEntity: OrganizationResponsability::class, mappedBy: 'access', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $organizationResponsabilities;
 
-    #[ORM\OneToMany(mappedBy: 'accessOriginal', targetEntity: AccessWish::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, AccessWish> */
+    #[ORM\OneToMany(targetEntity: AccessWish::class, mappedBy: 'accessOriginal', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $accessWishes;
 
-    #[ORM\OneToMany(mappedBy: 'student', targetEntity: WorkByUser::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
+    /** @var Collection<int, WorkByUser> */
+    #[ORM\OneToMany(targetEntity: WorkByUser::class, mappedBy: 'student', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $workByUsers;
 
+    /** @var Collection<int, Tagg> */
     #[ORM\ManyToMany(targetEntity: Tagg::class, inversedBy: 'accesses', cascade: ['persist'])]
     #[ORM\JoinTable(name: 'tag_access')]
     #[ORM\JoinColumn(name: 'access_id', referencedColumnName: 'id')]
     #[ORM\InverseJoinColumn(name: 'tag_id', referencedColumnName: 'id')]
     private Collection $tags;
 
-    #[ORM\ManyToMany(mappedBy: 'organizer', targetEntity: AbstractBooking::class, cascade: ['persist'], orphanRemoval: false)]
-    private Collection $bookingOrganizers;
+    // TODO: revoir le mapping, on ne peut pas mapper à une mapped superclass comme abstract booking
+    //    #[ORM\ManyToMany(mappedBy: 'organizer', targetEntity: AbstractBooking::class, cascade: ['persist'], orphanRemoval: false)]
+    //    private Collection $bookingOrganizers;
 
-    #[ORM\OneToMany(mappedBy: 'access', targetEntity: AdvancePayment::class, cascade: [], orphanRemoval: true)]
+    /** @var Collection<int, AdvancePayment> */
+    #[ORM\OneToMany(targetEntity: AdvancePayment::class, mappedBy: 'access', cascade: [], orphanRemoval: true)]
     private Collection $advancePayments;
 
-    #[ORM\OneToMany(mappedBy: 'author', targetEntity: AbstractMessage::class, cascade: [], orphanRemoval: true)]
+    /** @var Collection<int, AbstractMessage> */
+    #[ORM\OneToMany(targetEntity: AbstractMessage::class, mappedBy: 'author', cascade: [], orphanRemoval: true)]
     private Collection $messages;
 
-    #[ORM\OneToMany(mappedBy: 'managerControl', targetEntity: Equipment::class, cascade: [], orphanRemoval: false)]
+    /** @var Collection<int, Equipment> */
+    #[ORM\OneToMany(targetEntity: Equipment::class, mappedBy: 'managerControl', cascade: [], orphanRemoval: false)]
     private Collection $equipmentManagerControls;
 
-    #[ORM\OneToMany(mappedBy: 'accompanist', targetEntity: AbstractControl::class, cascade: [], orphanRemoval: true)]
+    /** @var Collection<int, EquipmentControl> */
+    #[ORM\OneToMany(targetEntity: EquipmentControl::class, mappedBy: 'accompanist', cascade: [], orphanRemoval: true)]
     private Collection $accompanistControl;
 
-    #[ORM\OneToMany(mappedBy: 'access', targetEntity: AccessReward::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, AccessReward> */
+    #[ORM\OneToMany(targetEntity: AccessReward::class, mappedBy: 'access', cascade: ['persist'], orphanRemoval: true)]
     private Collection $rewards;
 
-    #[ORM\OneToOne(mappedBy: 'access', targetEntity: AccessSocial::class, cascade: ['persist'], orphanRemoval: true)]
-    private AccessSocial $accessSocial;
+    #[ORM\OneToOne(targetEntity: AccessSocial::class, mappedBy: 'access', cascade: ['persist'], orphanRemoval: true)]
+    private ?AccessSocial $accessSocial;
 
-    #[ORM\OneToOne(mappedBy: 'access', targetEntity: AccessNetworkSetting::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
-    private AccessNetworkSetting $accessNetworkSetting;
+    #[ORM\OneToOne(targetEntity: AccessNetworkSetting::class, mappedBy: 'access', cascade: ['persist', 'remove'], orphanRemoval: true)]
+    private ?AccessNetworkSetting $accessNetworkSetting;
 
-    #[ORM\OneToOne(mappedBy: 'access', targetEntity: AccessCommunication::class, cascade: ['persist'], orphanRemoval: true)]
-    private AccessCommunication $accessCommunication;
+    #[ORM\OneToOne(targetEntity: AccessCommunication::class, mappedBy: 'access', cascade: ['persist'], orphanRemoval: true)]
+    private ?AccessCommunication $accessCommunication;
 
-    #[ORM\OneToOne(mappedBy: 'access', targetEntity: CalendarSynchro::class, cascade: ['persist'], orphanRemoval: true)]
-    private CalendarSynchro $calendarSynchro;
+    #[ORM\OneToOne(targetEntity: CalendarSynchro::class, mappedBy: 'access', cascade: ['persist'], orphanRemoval: true)]
+    private ?CalendarSynchro $calendarSynchro;
 
-    #[ORM\OneToMany(mappedBy: 'access', targetEntity: Token::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, Token> */
+    #[ORM\OneToMany(targetEntity: Token::class, mappedBy: 'access', cascade: ['persist'], orphanRemoval: true)]
     private Collection $tokens;
 
     #[ORM\OneToOne(mappedBy: 'access', cascade: ['persist'], fetch: 'EAGER', orphanRemoval: true)]
     private ?Preferences $preferences;
 
+    /** @var Collection<int, AbstractReport> */
+    #[ORM\OneToMany(targetEntity: AbstractReport::class, mappedBy: 'access', cascade: ['persist'], orphanRemoval: true)]
+    private Collection $reports;
+
     #[Pure]
     public function __construct()
     {
@@ -1115,9 +1179,6 @@ class Access implements UserInterface, PasswordAuthenticatedUserInterface
         return $this;
     }
 
-    /**
-     * @return Collection<int, Course>
-     */
     public function getPracticalCourses(): Collection
     {
         return $this->practicalCourses;
@@ -1224,12 +1285,7 @@ class Access implements UserInterface, PasswordAuthenticatedUserInterface
 
     public function removeBill(Bill $bill): self
     {
-        if ($this->bills->removeElement($bill)) {
-            // set the owning side to null (unless already changed)
-            if ($bill->getAccess() === $this) {
-                $bill->setAccess(null);
-            }
-        }
+        $this->bills->removeElement($bill);
 
         return $this;
     }
@@ -1284,12 +1340,7 @@ class Access implements UserInterface, PasswordAuthenticatedUserInterface
 
     public function removeBillCredit(BillCredit $billCredit): self
     {
-        if ($this->billCredits->removeElement($billCredit)) {
-            // set the owning side to null (unless already changed)
-            if ($billCredit->getAccess() === $this) {
-                $billCredit->setAccess(null);
-            }
-        }
+        $this->billCredits->removeElement($billCredit);
 
         return $this;
     }
@@ -2199,29 +2250,29 @@ class Access implements UserInterface, PasswordAuthenticatedUserInterface
         return $this;
     }
 
-    public function getBookingOrganizers(): Collection
-    {
-        return $this->bookingOrganizers;
-    }
-
-    public function addBookingOrganizer(AbstractBooking $bookingOrganizer): self
-    {
-        if (!$this->bookingOrganizers->contains($bookingOrganizer)) {
-            $this->bookingOrganizers[] = $bookingOrganizer;
-            $bookingOrganizer->addOrganizer($this);
-        }
-
-        return $this;
-    }
-
-    public function removeBookingOrganizer(AbstractBooking $bookingOrganizer): self
-    {
-        if ($this->bookingOrganizers->removeElement($bookingOrganizer)) {
-            $bookingOrganizer->removeOrganizer($this);
-        }
-
-        return $this;
-    }
+    //    public function getBookingOrganizers(): Collection
+    //    {
+    //        return $this->bookingOrganizers;
+    //    }
+    //
+    //    public function addBookingOrganizer(AbstractBooking $bookingOrganizer): self
+    //    {
+    //        if (!$this->bookingOrganizers->contains($bookingOrganizer)) {
+    //            $this->bookingOrganizers[] = $bookingOrganizer;
+    //            $bookingOrganizer->addOrganizer($this);
+    //        }
+    //
+    //        return $this;
+    //    }
+    //
+    //    public function removeBookingOrganizer(AbstractBooking $bookingOrganizer): self
+    //    {
+    //        if ($this->bookingOrganizers->removeElement($bookingOrganizer)) {
+    //            $bookingOrganizer->removeOrganizer($this);
+    //        }
+    //
+    //        return $this;
+    //    }
 
     public function getAdvancePayments(): Collection
     {
@@ -2240,9 +2291,7 @@ class Access implements UserInterface, PasswordAuthenticatedUserInterface
 
     public function removeAdvancePayment(AdvancePayment $advancePayment): self
     {
-        if ($this->advancePayments->removeElement($advancePayment)) {
-            $advancePayment->setAccess(null);
-        }
+        $this->advancePayments->removeElement($advancePayment);
 
         return $this;
     }
@@ -2300,7 +2349,7 @@ class Access implements UserInterface, PasswordAuthenticatedUserInterface
         return $this->accompanistControl;
     }
 
-    public function addAccompanistControl(AbstractControl $accompanistControl): self
+    public function addAccompanistControl(EquipmentControl $accompanistControl): self
     {
         if (!$this->accompanistControl->contains($accompanistControl)) {
             $this->accompanistControl[] = $accompanistControl;
@@ -2310,7 +2359,7 @@ class Access implements UserInterface, PasswordAuthenticatedUserInterface
         return $this;
     }
 
-    public function removeAccompanistControl(AbstractControl $accompanistControl): self
+    public function removeAccompanistControl(EquipmentControl $accompanistControl): self
     {
         if ($this->accompanistControl->removeElement($accompanistControl)) {
             //            $accompanistControl->setAccompanist(null);  // TODO: actuellement, pas nullable: conserver?
@@ -2343,48 +2392,48 @@ class Access implements UserInterface, PasswordAuthenticatedUserInterface
         return $this;
     }
 
-    public function getAccessSocial(): AccessSocial
+    public function getAccessSocial(): ?AccessSocial
     {
         return $this->accessSocial;
     }
 
-    public function setAccessSocial(AccessSocial $accessSocial): self
+    public function setAccessSocial(?AccessSocial $accessSocial): self
     {
         $this->accessSocial = $accessSocial;
 
         return $this;
     }
 
-    public function getAccessNetworkSetting(): AccessNetworkSetting
+    public function getAccessNetworkSetting(): ?AccessNetworkSetting
     {
         return $this->accessNetworkSetting;
     }
 
-    public function setAccessNetworkSetting(AccessNetworkSetting $accessNetworkSetting): self
+    public function setAccessNetworkSetting(?AccessNetworkSetting $accessNetworkSetting): self
     {
         $this->accessNetworkSetting = $accessNetworkSetting;
 
         return $this;
     }
 
-    public function getAccessCommunication(): AccessCommunication
+    public function getAccessCommunication(): ?AccessCommunication
     {
         return $this->accessCommunication;
     }
 
-    public function setAccessCommunication(AccessCommunication $accessCommunication): self
+    public function setAccessCommunication(?AccessCommunication $accessCommunication): self
     {
         $this->accessCommunication = $accessCommunication;
 
         return $this;
     }
 
-    public function getCalendarSynchro(): CalendarSynchro
+    public function getCalendarSynchro(): ?CalendarSynchro
     {
         return $this->calendarSynchro;
     }
 
-    public function setCalendarSynchro(CalendarSynchro $calendarSynchro): self
+    public function setCalendarSynchro(?CalendarSynchro $calendarSynchro): self
     {
         $this->calendarSynchro = $calendarSynchro;
 
@@ -2429,4 +2478,28 @@ class Access implements UserInterface, PasswordAuthenticatedUserInterface
     {
         return $this->preferences;
     }
+
+    public function getReports(): Collection
+    {
+        return $this->reports;
+    }
+
+    public function addReport(AbstractReport $report): self
+    {
+        if (!$this->reports->contains($report)) {
+            $this->reports[] = $report;
+            $report->setAccess($this);
+        }
+
+        return $this;
+    }
+
+    public function removeReport(AbstractReport $report): self
+    {
+        if ($this->reports->removeElement($report)) {
+            $report->setAccess(null);
+        }
+
+        return $this;
+    }
 }

+ 4 - 2
src/Entity/Access/AccessCommunication.php

@@ -5,11 +5,13 @@ declare(strict_types=1);
 namespace App\Entity\Access;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * Paramètres d'abonnement à la com pour un Access.
  */
+#[ApiResource(operations: [])]
 // #[Auditable]
 #[ORM\Entity]
 class AccessCommunication
@@ -20,7 +22,7 @@ class AccessCommunication
     private ?int $id = null;
 
     #[ORM\OneToOne(inversedBy: 'accessCommunication', targetEntity: Access::class, cascade: ['persist'])]
-    protected Access $access;
+    protected ?Access $access;
 
     public function getId(): ?int
     {

+ 6 - 3
src/Entity/Access/AccessFamily.php

@@ -12,7 +12,8 @@ use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * Fais le lien entre les Access dont les titulaires sont membres d'une même famille
+ * (cf. table 'children_guardians' pour les responsables légaux).
  */
 #[ApiResource(operations: [])]
 // #[Auditable]
@@ -24,10 +25,12 @@ class AccessFamily
     #[ORM\GeneratedValue]
     private ?int $id = null;
 
-    #[ORM\OneToMany(mappedBy: 'accessFamily', targetEntity: Access::class)]
+    /** @var Collection<int, Access> */
+    #[ORM\OneToMany(targetEntity: Access::class, mappedBy: 'accessFamily')]
     private Collection $accesses;
 
-    #[ORM\OneToMany(mappedBy: 'accessFamily', targetEntity: AccessFictionalIntangible::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, AccessFictionalIntangible> */
+    #[ORM\OneToMany(targetEntity: AccessFictionalIntangible::class, mappedBy: 'accessFamily', cascade: ['persist'], orphanRemoval: true)]
     private Collection $accessFictionalIntangibles;
 
     public function __construct()

+ 4 - 2
src/Entity/Access/AccessNetworkSetting.php

@@ -5,12 +5,14 @@ declare(strict_types=1);
 namespace App\Entity\Access;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * TODO: documenter.
  */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 class AccessNetworkSetting
 {
@@ -20,7 +22,7 @@ class AccessNetworkSetting
     private ?int $id = null;
 
     #[ORM\OneToOne(inversedBy: 'accessNetworkSetting', targetEntity: Access::class, cascade: ['persist'])]
-    protected Access $access;
+    protected ?Access $access;
 
     public function getId(): ?int
     {

+ 4 - 2
src/Entity/Access/AccessSocial.php

@@ -5,12 +5,14 @@ declare(strict_types=1);
 namespace App\Entity\Access;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * Caractéristiques socio-professionnelles pour un Access.
  */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 class AccessSocial
 {
@@ -20,7 +22,7 @@ class AccessSocial
     private ?int $id = null;
 
     #[ORM\OneToOne(inversedBy: 'accessSocial', targetEntity: Access::class, cascade: ['persist'])]
-    protected Access $access;
+    protected ?Access $access;
 
     public function getId(): ?int
     {

+ 2 - 0
src/Entity/Access/FunctionType.php

@@ -4,6 +4,7 @@ declare(strict_types=1);
 
 namespace App\Entity\Access;
 
+use ApiPlatform\Metadata\ApiResource;
 use App\Enum\Access\FunctionEnum;
 use App\Enum\Access\RoleEnum;
 use App\Enum\Access\TypeFunctionEnum;
@@ -15,6 +16,7 @@ use Doctrine\ORM\Mapping as ORM;
  * Enum des fonctions que peuvent occuper un Access au sein d'une Organization.
  */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity(repositoryClass: FunctionTypeRepository::class)]
 class FunctionType
 {

+ 2 - 2
src/Entity/Access/OrganizationFunction.php

@@ -33,7 +33,7 @@ class OrganizationFunction
 
     #[ORM\ManyToOne(inversedBy: 'organizationFunction')]
     #[ORM\JoinColumn(nullable: false)]
-    private ?Access $access = null;
+    private Access $access;
 
     #[ORM\ManyToOne]
     #[ORM\JoinColumn(nullable: false)]
@@ -44,7 +44,7 @@ class OrganizationFunction
 
     #[ORM\ManyToOne]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    private Activity $activity;
+    private ?Activity $activity = null;
 
     #[ORM\Column(length: 255, nullable: true, enumType: DeparturesCauseEnum::class)]
     private ?DeparturesCauseEnum $departureCause = null;

+ 3 - 1
src/Entity/Access/OrganizationResponsability.php

@@ -5,12 +5,14 @@ declare(strict_types=1);
 namespace App\Entity\Access;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * Responsibilité d'un Access au sein d'une Organization.
  */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 class OrganizationResponsability
 {

+ 4 - 4
src/Entity/Access/PersonalizedList.php

@@ -13,7 +13,7 @@ use JetBrains\PhpStorm\Pure;
 use Symfony\Component\Serializer\Annotation\Groups;
 
 /**
- * Liste personnalisées.
+ * Listes personnalisées.
  *
  * Security :
  *
@@ -41,7 +41,7 @@ class PersonalizedList
 
     #[ORM\ManyToOne(inversedBy: 'personalizedLists')]
     #[ORM\JoinColumn(nullable: false)]
-    private ?Access $access = null;
+    private Access $access;
 
     #[ORM\Column(length: 200, nullable: true)]
     #[Groups(['lists:output'])]
@@ -61,7 +61,7 @@ class PersonalizedList
 
     #[ORM\Column(length: 150, nullable: true)]
     #[Groups(['lists:output'])]
-    private string $menuKey;
+    private ?string $menuKey = null;
 
     #[Pure]
     public function __construct()
@@ -125,7 +125,7 @@ class PersonalizedList
         return $this->access;
     }
 
-    public function setMenuKey(string $menuKey): self
+    public function setMenuKey(?string $menuKey): self
     {
         $this->menuKey = $menuKey;
 

+ 1 - 1
src/Entity/Access/Preferences.php

@@ -34,7 +34,7 @@ class Preferences
 
     #[ORM\OneToOne(inversedBy: 'preferences', fetch: 'EAGER')]
     #[ORM\JoinColumn(nullable: true)]
-    private Access $access;
+    private ?Access $access = null;
 
     #[ORM\Column(options: ['default' => true])]
     private bool $messageReport = true;

+ 6 - 2
src/Entity/AccessWish/AccessFamilyWish.php

@@ -5,6 +5,7 @@ declare(strict_types=1);
 namespace App\Entity\AccessWish;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
@@ -13,6 +14,7 @@ use Doctrine\ORM\Mapping as ORM;
  * Famille à laquelle est rattaché un AccessWish.
  */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 class AccessFamilyWish
 {
@@ -21,14 +23,15 @@ class AccessFamilyWish
     #[ORM\GeneratedValue]
     private ?int $id = null;
 
-    #[ORM\OneToMany(mappedBy: 'accessFamilyWish', targetEntity: AccessWish::class, cascade: ['remove'])]
+    /** @var Collection<int, AccessWish> */
+    #[ORM\OneToMany(targetEntity: AccessWish::class, mappedBy: 'accessFamilyWish', cascade: ['remove'])]
     private Collection $accessWishes;
 
     /**
      * Date de dernière mise à jour de l'entité.
      */
     #[ORM\Column(type: 'datetime', nullable: true)]
-    private \DateTimeInterface $updateDate;
+    private ?\DateTimeInterface $updateDate;
 
     #[ORM\Column]
     private bool $registrationCompleted = false;
@@ -36,6 +39,7 @@ class AccessFamilyWish
     #[ORM\Column]
     private bool $closeRegistration = false;
 
+    /** @var Collection<int, AccessWish> */
     #[ORM\OneToMany(mappedBy: 'accessFamilyWish', targetEntity: AccessWish::class, cascade: ['remove'], orphanRemoval: false)]
     protected Collection $accessWishesGuardians;
 

+ 4 - 2
src/Entity/AccessWish/AccessTmp.php

@@ -4,14 +4,16 @@ declare(strict_types=1);
 
 namespace App\Entity\AccessWish;
 
+use ApiPlatform\Metadata\ApiResource;
 use App\Entity\Organization\Organization;
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * TODO: documenter.
  */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 class AccessTmp
 {
@@ -21,7 +23,7 @@ class AccessTmp
     private ?int $id = null;
 
     #[ORM\ManyToOne]
-    private Organization $organization;
+    private ?Organization $organization = null;
 
     public function getId(): ?int
     {

+ 19 - 15
src/Entity/AccessWish/AccessWish.php

@@ -38,27 +38,31 @@ class AccessWish
 
     #[ORM\ManyToOne(cascade: ['persist'], inversedBy: 'accessWishes')]
     #[ORM\JoinColumn(onDelete: 'CASCADE')]
-    private Access $accessOriginal;
+    private ?Access $accessOriginal = null;
 
     #[ORM\ManyToOne(inversedBy: 'accessWishes')]
-    private AccessFamilyWish $accessFamilyWish;
+    private ?AccessFamilyWish $accessFamilyWish = null;
 
     #[ORM\ManyToOne]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: false, onDelete: 'SET NULL')]
     private File $image;
 
     #[ORM\ManyToOne]
-    private Country $addressCountry;
+    private ?Country $addressCountry = null;
 
-    #[ORM\OneToMany(mappedBy: 'accessWish', targetEntity: EducationStudentWish::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, EducationStudentWish> */
+    #[ORM\OneToMany(targetEntity: EducationStudentWish::class, mappedBy: 'accessWish', cascade: ['persist'], orphanRemoval: true)]
     private Collection $educationStudentWishes;
 
-    #[ORM\OneToMany(mappedBy: 'accessWishReregistrations', targetEntity: EducationStudentWish::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, EducationStudentWish> */
+    #[ORM\OneToMany(targetEntity: EducationStudentWish::class, mappedBy: 'accessWishReregistrations', cascade: ['persist'], orphanRemoval: true)]
     private Collection $educationStudentReregistrationsWishes;
 
-    #[ORM\OneToMany(mappedBy: 'accessWish', targetEntity: DocumentWish::class, cascade: ['persist'])]
+    /** @var Collection<int, DocumentWish> */
+    #[ORM\OneToMany(targetEntity: DocumentWish::class, mappedBy: 'accessWish', cascade: ['persist'])]
     private Collection $documentWishes;
 
+    /** @var Collection<int, Tagg> */
     #[ORM\ManyToMany(targetEntity: Tagg::class, inversedBy: 'accessWishes', cascade: ['persist'])]
     #[ORM\JoinTable(name: 'tag_accessWish')]
     #[ORM\JoinColumn(name: 'accessWish_id', referencedColumnName: 'id')]
@@ -70,21 +74,21 @@ class AccessWish
 
     #[ORM\ManyToOne(targetEntity: BillSchedule::class, cascade: ['persist'], inversedBy: 'accessWishes')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    protected BillSchedule $billSchedule;
+    protected ?BillSchedule $billSchedule;
 
-    #[ORM\OneToOne(mappedBy: 'accessWishRib', targetEntity: DocumentWish::class, cascade: ['persist'])]
-    protected DocumentWish $documentRib;
+    #[ORM\OneToOne(targetEntity: DocumentWish::class, mappedBy: 'accessWishRib', cascade: ['persist'])]
+    protected ?DocumentWish $documentRib;
 
-    #[ORM\OneToOne(mappedBy: 'accessWishSepa', targetEntity: DocumentWish::class, cascade: ['persist'])]
-    protected DocumentWish $documentSepa;
+    #[ORM\OneToOne(targetEntity: DocumentWish::class, mappedBy: 'accessWishSepa', cascade: ['persist'])]
+    protected ?DocumentWish $documentSepa;
 
     #[ORM\ManyToOne(targetEntity: EducationCurriculumPack::class, cascade: [])]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    protected EducationCurriculumPack $wishPack;
+    protected ?EducationCurriculumPack $wishPack;
 
     #[ORM\ManyToOne(targetEntity: Place::class, cascade: [])]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    protected Place $favoritePlace;
+    protected ?Place $favoritePlace;
 
     /**
      * Date de création dde l'entité.
@@ -92,7 +96,7 @@ class AccessWish
      * @var \DateTime
      */
     #[ORM\Column(type: 'datetime', nullable: true)]
-    private \DateTimeInterface $createDate;
+    private ?\DateTimeInterface $createDate = null;
 
     /**
      * Date de dernière mise à jour de l'entité.
@@ -100,7 +104,7 @@ class AccessWish
      * @var \DateTime
      */
     #[ORM\Column(type: 'datetime', nullable: true)]
-    private \DateTimeInterface $updateDate;
+    private ?\DateTimeInterface $updateDate = null;
 
     public function __construct()
     {

+ 9 - 6
src/Entity/AccessWish/DocumentWish.php

@@ -4,6 +4,7 @@ declare(strict_types=1);
 
 namespace App\Entity\AccessWish;
 
+use ApiPlatform\Metadata\ApiResource;
 use App\Entity\Core\File;
 use App\Entity\Person\Person;
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
@@ -12,9 +13,10 @@ use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * TODO: documenter.
  */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 class DocumentWish
 {
@@ -25,20 +27,21 @@ class DocumentWish
 
     #[ORM\ManyToOne(inversedBy: 'documentWishes')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    private AccessWish $accessWish;
+    private ?AccessWish $accessWish = null;
 
     #[ORM\ManyToOne(inversedBy: 'documentWishes')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    private Person $personOwner;
+    private ?Person $personOwner = null;
 
-    #[ORM\OneToMany(mappedBy: 'documentWish', targetEntity: File::class, orphanRemoval: true)]
+    /** @var Collection<int, File> */
+    #[ORM\OneToMany(targetEntity: File::class, mappedBy: 'documentWish', orphanRemoval: true)]
     private Collection $files;
 
     #[ORM\OneToOne(inversedBy: 'documentRib', targetEntity: AccessWish::class, cascade: [])]
-    protected AccessWish $accessWishRib;
+    protected ?AccessWish $accessWishRib;
 
     #[ORM\OneToOne(inversedBy: 'documentSepa', targetEntity: AccessWish::class, cascade: [])]
-    protected AccessWish $accessWishSepa;
+    protected ?AccessWish $accessWishSepa;
 
     public function __construct()
     {

+ 16 - 13
src/Entity/AccessWish/EducationStudentWish.php

@@ -4,6 +4,7 @@ declare(strict_types=1);
 
 namespace App\Entity\AccessWish;
 
+use ApiPlatform\Metadata\ApiResource;
 use App\Entity\Access\Access;
 use App\Entity\Booking\Course;
 use App\Entity\Education\Education;
@@ -19,9 +20,10 @@ use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * TODO: documenter.
  */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 class EducationStudentWish
 {
@@ -31,43 +33,44 @@ class EducationStudentWish
     private ?int $id = null;
 
     #[ORM\Column(length: 50, enumType: WishRegistrationEnum::class)]
-    private ?WishRegistrationEnum $wishRegistration = null;
+    private WishRegistrationEnum $wishRegistration;
 
     #[ORM\Column(length: 50, enumType: RegistrationStatusEnum::class)]
-    private ?RegistrationStatusEnum $registrationStatus = null;
+    private RegistrationStatusEnum $registrationStatus;
 
-    #[ORM\ManyToOne]
+    #[ORM\ManyToOne(targetEntity: Education::class, cascade: ['persist'], inversedBy: 'educationWishes')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    private Education $educationWish;
+    private ?Education $educationWish = null;
 
     #[ORM\ManyToOne(inversedBy: 'educationStudentWishes')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    private AccessWish $accessWish;
+    private ?AccessWish $accessWish = null;
 
     #[ORM\ManyToOne(inversedBy: 'educationStudentReregistrationsWishes')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    private AccessWish $accessWishReregistrations;
+    private ?AccessWish $accessWishReregistrations = null;
 
-    #[ORM\ManyToOne]
-    private EducationCurriculum $educationCurriculum;
+    #[ORM\ManyToOne(targetEntity: EducationCurriculum::class, cascade: ['persist'], inversedBy: 'educationStudentWish')]
+    private ?EducationCurriculum $educationCurriculum = null;
 
     #[ORM\ManyToOne]
-    private EducationStudent $educationStudent;
+    private ?EducationStudent $educationStudent = null;
 
     #[ORM\ManyToOne]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    private EducationTiming $educationTiming;
+    private ?EducationTiming $educationTiming = null;
 
+    /** @var Collection<int, Access> */
     #[ORM\ManyToMany(targetEntity: Access::class, cascade: [], orphanRemoval: false)]
     protected Collection $teachers;
 
     #[ORM\ManyToOne(targetEntity: EquipmentList::class, cascade: [])]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    protected EquipmentList $speciality;
+    protected ?EquipmentList $speciality;
 
     #[ORM\ManyToOne(targetEntity: Course::class, cascade: [], inversedBy: 'educationStudentWishes')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    protected Course $course;
+    protected ?Course $course;
 
     public function __construct()
     {

+ 9 - 6
src/Entity/Awin/Product.php

@@ -7,6 +7,9 @@ namespace App\Entity\Awin;
 use ApiPlatform\Metadata\ApiResource;
 use Doctrine\ORM\Mapping as ORM;
 
+/**
+ * Produit / Évènement pour le portail fourni par le partenaire Awin.
+ */
 #[ApiResource(operations: [])]
 #[ORM\Entity]
 #[ORM\Table(
@@ -95,16 +98,16 @@ class Product
     #[ORM\Column]
     protected mixed $priceMaxi;
 
-    #[ORM\Column(length: 255, options: ['nullable' => true])]
-    protected string $artists;
+    #[ORM\Column(length: 255, nullable: true)]
+    protected ?string $artists;
 
-    #[ORM\Column(length: 255, options: ['nullable' => true])]
-    protected string $uuid;
+    #[ORM\Column(length: 255, nullable: true)]
+    protected ?string $uuid;
 
-    #[ORM\Column(type: 'date', options: ['nullable' => true])]
+    #[ORM\Column(type: 'date', nullable: true)]
     protected ?\DateTimeInterface $createDate;
 
-    #[ORM\Column(type: 'date', options: ['nullable' => true])]
+    #[ORM\Column(type: 'date', nullable: true)]
     protected ?\DateTimeInterface $updateDate;
 
     public function getId(): int

+ 30 - 135
src/Entity/Billing/AbstractBillAccounting.php

@@ -20,52 +20,52 @@ use Doctrine\ORM\Mapping as ORM;
  * @todo : A la suite de la migration, il faut supprimer le nom de la table pour avoir une table BillAccounting, et supprimer l'attribut discr.
  */
 #[ORM\MappedSuperclass]
-abstract class AbstractBillAccounting
+#[ORM\Table(name: 'BillAccounting')]
+#[ORM\DiscriminatorColumn(name: 'discr', type: 'string')]
+#[ORM\DiscriminatorMap(
+    [
+        'billaccounting' => BillAccounting::class,
+        'bill' => Bill::class,
+        'billcredit' => BillCredit::class,
+        'advancepayment' => AdvancePayment::class,
+    ]
+)]
+class AbstractBillAccounting
 {
     #[ORM\Id]
     #[ORM\Column]
     #[ORM\GeneratedValue]
     protected ?int $id = null;
 
-    #[ORM\Column(length: 255, nullable: false)]
-    protected string $discr;
-
     #[ORM\ManyToOne(targetEntity: Organization::class)]
     #[ORM\JoinColumn(nullable: true)]
-    protected Organization $organization;
-
-    #[ORM\OneToMany(mappedBy: 'bill', targetEntity: BillLine::class, cascade: ['persist'], orphanRemoval: true)]
-    protected Collection $billLines;
-
-    #[ORM\OneToMany(mappedBy: 'bill', targetEntity: BillCredit::class, cascade: ['persist'], orphanRemoval: true)]
-    protected Collection $billCredits;
-
-    #[ORM\OneToMany(mappedBy: 'bill', targetEntity: BillPayment::class, cascade: ['persist'], orphanRemoval: true)]
-    protected Collection $billPayments;
+    protected ?Organization $organization;
 
     #[ORM\ManyToOne(inversedBy: 'billCredits')]
     #[ORM\JoinColumn(nullable: true)]
-    protected AbstractBillAccounting $bill;
+    protected ?Bill $bill;
 
-    #[ORM\OneToMany(mappedBy: 'bill', targetEntity: BillingIntangibleExcludeDate::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, BillingIntangibleExcludeDate> */
+    #[ORM\OneToMany(targetEntity: BillingIntangibleExcludeDate::class, mappedBy: 'bill', cascade: ['persist'], orphanRemoval: true)]
     protected Collection $billingIntangibleExcludeDates;
 
     #[ORM\ManyToOne(cascade: ['persist'], inversedBy: 'bills')]
     #[ORM\JoinColumn(nullable: true)]
-    protected Pes $pes;
+    protected ?Pes $pes;
 
     #[ORM\ManyToOne(cascade: ['persist'], inversedBy: 'bills')]
     #[ORM\JoinColumn(nullable: true)]
-    protected BergerLevrault $bergerLevrault;
+    protected ?BergerLevrault $bergerLevrault;
 
     #[ORM\ManyToOne(cascade: ['persist'], inversedBy: 'bills')]
     #[ORM\JoinColumn(nullable: true)]
-    protected Ciril $ciril;
+    protected ?Ciril $ciril;
 
     #[ORM\ManyToOne(cascade: ['persist'], inversedBy: 'bills')]
     #[ORM\JoinColumn(nullable: true)]
-    protected Jvs $jvs;
+    protected ?Jvs $jvs;
 
+    /** @var Collection<int, Tagg> */
     #[ORM\ManyToMany(targetEntity: Tagg::class, inversedBy: 'billAccountings', cascade: ['persist'])]
     #[ORM\JoinTable(name: 'tag_billAccounting')]
     #[ORM\JoinColumn(name: 'billAccounting_id', referencedColumnName: 'id')]
@@ -77,34 +77,31 @@ abstract class AbstractBillAccounting
     protected Access $access;
 
     #[ORM\OneToOne(targetEntity: BillAccessDetail::class, cascade: ['persist'])]
-    protected BillAccessDetail $accessDetail;
+    protected ?BillAccessDetail $accessDetail;
 
     #[ORM\OneToOne(targetEntity: BillPeriod::class, cascade: ['persist'])]
-    protected BillPeriod $billPeriod;
+    protected ?BillPeriod $billPeriod;
 
     #[ORM\OneToOne(targetEntity: BillTotalDetail::class, cascade: ['persist'])]
-    protected BillTotalDetail $totalDetail;
+    protected ?BillTotalDetail $totalDetail;
 
     #[ORM\OneToOne(targetEntity: File::class, cascade: ['persist'])]
-    protected File $file;
+    protected ?File $file;
 
-    #[ORM\ManyToOne(targetEntity: Odyssee::class, inversedBy: 'bills', cascade: ['persist'])]
+    #[ORM\ManyToOne(targetEntity: Odyssee::class, cascade: ['persist'], inversedBy: 'bills')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: false, onDelete: 'SET NULL')]
     protected Odyssee $odyssee; // TODO: sûr que c'est pas nullable?
 
-    #[ORM\ManyToOne(targetEntity: Afi::class, inversedBy: 'bills', cascade: ['persist'])]
+    #[ORM\ManyToOne(targetEntity: Afi::class, cascade: ['persist'], inversedBy: 'bills')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: false, onDelete: 'SET NULL')]
     protected Afi $afi;
 
-    #[ORM\ManyToOne(targetEntity: CirilCivil::class, inversedBy: 'bills', cascade: ['persist'])]
+    #[ORM\ManyToOne(targetEntity: CirilCivil::class, cascade: ['persist'], inversedBy: 'bills')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: false, onDelete: 'SET NULL')]
     protected CirilCivil $cirilCivil;
 
     public function __construct()
     {
-        $this->billLines = new ArrayCollection();
-        $this->billCredits = new ArrayCollection();
-        $this->billPayments = new ArrayCollection();
         $this->billingIntangibleExcludeDates = new ArrayCollection();
         $this->tags = new ArrayCollection();
     }
@@ -114,18 +111,6 @@ abstract class AbstractBillAccounting
         return $this->id;
     }
 
-    public function getDiscr(): ?string
-    {
-        return $this->discr;
-    }
-
-    public function setDiscr(string $discr): self
-    {
-        $this->discr = $discr;
-
-        return $this;
-    }
-
     public function getOrganization(): ?Organization
     {
         return $this->organization;
@@ -138,102 +123,12 @@ abstract class AbstractBillAccounting
         return $this;
     }
 
-    /**
-     * @return Collection<int, BillLine>
-     */
-    public function getBillLines(): Collection
-    {
-        return $this->billLines;
-    }
-
-    public function addBillLine(BillLine $billLine): self
-    {
-        if (!$this->billLines->contains($billLine)) {
-            $this->billLines[] = $billLine;
-            $billLine->setBill($this);
-        }
-
-        return $this;
-    }
-
-    public function removeBillLine(BillLine $billLine): self
-    {
-        if ($this->billLines->removeElement($billLine)) {
-            // set the owning side to null (unless already changed)
-            if ($billLine->getBill() === $this) {
-                $billLine->setBill(null);
-            }
-        }
-
-        return $this;
-    }
-
-    /**
-     * @return Collection<int, BillCredit>
-     */
-    public function getBillCredits(): Collection
-    {
-        return $this->billCredits;
-    }
-
-    public function addBillCredit(BillCredit $billCredit): self
-    {
-        if (!$this->billCredits->contains($billCredit)) {
-            $this->billCredits[] = $billCredit;
-            $billCredit->setBill($this);
-        }
-
-        return $this;
-    }
-
-    public function removeBillCredit(BillCredit $billCredit): self
-    {
-        if ($this->billCredits->removeElement($billCredit)) {
-            // set the owning side to null (unless already changed)
-            if ($billCredit->getBill() === $this) {
-                $billCredit->setBill(null);
-            }
-        }
-
-        return $this;
-    }
-
-    /**
-     * @return Collection<int, BillPayment>
-     */
-    public function getBillPayments(): Collection
-    {
-        return $this->billPayments;
-    }
-
-    public function addBillPayment(BillPayment $billPayment): self
-    {
-        if (!$this->billPayments->contains($billPayment)) {
-            $this->billPayments[] = $billPayment;
-            $billPayment->setBill($this);
-        }
-
-        return $this;
-    }
-
-    public function removeBillPayment(BillPayment $billPayment): self
-    {
-        if ($this->billPayments->removeElement($billPayment)) {
-            // set the owning side to null (unless already changed)
-            if ($billPayment->getBill() === $this) {
-                $billPayment->setBill(null);
-            }
-        }
-
-        return $this;
-    }
-
-    public function getBill(): ?self
+    public function getBill(): ?Bill
     {
         return $this->bill;
     }
 
-    public function setBill(?self $bill): self
+    public function setBill(?Bill $bill): self
     {
         $this->bill = $bill;
 
@@ -351,7 +246,7 @@ abstract class AbstractBillAccounting
         return $this->access;
     }
 
-    public function setAccess(?Access $access): self
+    public function setAccess(Access $access): self
     {
         $this->access = $access;
 

+ 3 - 2
src/Entity/Billing/AbstractBillingIntangible.php

@@ -19,8 +19,8 @@ use Doctrine\ORM\Mapping as ORM;
 #[ORM\InheritanceType('SINGLE_TABLE')]
 #[ORM\DiscriminatorColumn(name: 'discr', type: 'string')]
 #[ORM\DiscriminatorMap([
-    'access' => 'AccessIntangible',
-    'educationalproject' => 'EducationalProjectIntangible',
+    'access' => AccessIntangible::class,
+    'educationalproject' => EducationalProjectIntangible::class,
 ])]
 abstract class AbstractBillingIntangible
 {
@@ -33,6 +33,7 @@ abstract class AbstractBillingIntangible
     #[ORM\JoinColumn(nullable: false)]
     protected Intangible $intangible;
 
+    /** @var Collection<int, Tagg> */
     #[ORM\ManyToMany(targetEntity: Tagg::class, inversedBy: 'billingIntangibles', cascade: ['persist'])]
     #[ORM\JoinTable(name: 'tag_billingIntangible')]
     #[ORM\JoinColumn(name: 'billingIntangible_id', referencedColumnName: 'id')]

+ 8 - 0
src/Entity/Billing/AbstractBillingPayer.php

@@ -12,6 +12,14 @@ use Doctrine\ORM\Mapping as ORM;
  * Classe de base de @see  AccessPayer, EducationalProjectPayer.
  */
 #[ORM\MappedSuperclass]
+#[ORM\Table(name: 'BillingPayer')]
+#[ORM\DiscriminatorColumn(name: 'discr', type: 'string')]
+#[ORM\DiscriminatorMap(
+    [
+        'access' => AccessPayer::class,
+        'educationalproject' => EducationalProjectPayer::class,
+    ]
+)]
 abstract class AbstractBillingPayer
 {
     #[ORM\Id]

+ 11 - 8
src/Entity/Billing/AccessBilling.php

@@ -12,7 +12,7 @@ use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * Paramètres de facturation pour un Access.
  */
 #[ApiResource(operations: [])]
 // #[Auditable]
@@ -26,28 +26,31 @@ class AccessBilling
 
     #[ORM\OneToOne(inversedBy: 'accessBilling', cascade: ['persist'], fetch: 'EAGER')]
     #[ORM\JoinColumn(nullable: true, onDelete: 'CASCADE')]
-    private Access $access;
+    private ?Access $access = null;
 
     #[ORM\ManyToOne(cascade: ['persist'], inversedBy: 'accessBilling')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    private FamilyQuotient $familyQuotient;
+    private ?FamilyQuotient $familyQuotient = null;
 
     #[ORM\ManyToOne(cascade: ['persist'], inversedBy: 'accessBilling')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    private ResidenceArea $residenceArea;
+    private ?ResidenceArea $residenceArea = null;
 
-    #[ORM\OneToMany(mappedBy: 'accessBilling', targetEntity: BillPayment::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, BillPayment> */
+    #[ORM\OneToMany(targetEntity: BillPayment::class, mappedBy: 'accessBilling', cascade: ['persist'], orphanRemoval: true)]
     private Collection $billDetachedPayments;
 
-    #[ORM\OneToMany(mappedBy: 'accessBilling', targetEntity: BillDebitBalance::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, BillDebitBalance> */
+    #[ORM\OneToMany(targetEntity: BillDebitBalance::class, mappedBy: 'accessBilling', cascade: ['persist'], orphanRemoval: true)]
     private Collection $billDebitBalances;
 
-    #[ORM\OneToMany(mappedBy: 'accessBillingAccountBalanceReimbursement', targetEntity: BillPayment::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, BillPayment> */
+    #[ORM\OneToMany(targetEntity: BillPayment::class, mappedBy: 'accessBillingAccountBalanceReimbursement', cascade: ['persist'], orphanRemoval: true)]
     private Collection $accountBalanceReimbursements;
 
     #[ORM\ManyToOne(targetEntity: BillSchedule::class, cascade: ['persist'], inversedBy: 'accessBilling')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    protected BillSchedule $billSchedule;
+    protected ?BillSchedule $billSchedule;
 
     public function __construct()
     {

+ 6 - 4
src/Entity/Billing/AccessFictionalIntangible.php

@@ -14,7 +14,8 @@ use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * Correspond à une ligne de facturation pour un Access
+ * (@see FictionalIntangible).
  */
 #[ApiResource(operations: [])]
 // #[Auditable]
@@ -27,16 +28,17 @@ class AccessFictionalIntangible
     private ?int $id = null;
 
     #[ORM\ManyToOne(cascade: ['persist'], inversedBy: 'accessFictionalIntangibles')]
-    private Access $access;
+    private ?Access $access = null;
 
     #[ORM\ManyToOne(cascade: ['persist'], inversedBy: 'accessFictionalIntangibles')]
-    private AccessFamily $accessFamily;
+    private ?AccessFamily $accessFamily = null;
 
     #[ORM\ManyToOne]
     #[ORM\JoinColumn(nullable: false)]
     private FictionalIntangible $fictionalIntangible;
 
-    #[ORM\OneToMany(mappedBy: 'accessFictionalIntangible', targetEntity: BillingIntangibleExcludeDate::class, cascade: ['persist'], orphanRemoval: true, )]
+    /** @var Collection<int, BillingIntangibleExcludeDate> */
+    #[ORM\OneToMany(targetEntity: BillingIntangibleExcludeDate::class, mappedBy: 'accessFictionalIntangible', cascade: ['persist'], orphanRemoval: true, )]
     private Collection $billingIntangibleExcludeDates;
 
     public function __construct()

+ 4 - 1
src/Entity/Billing/AccessIntangible.php

@@ -18,17 +18,20 @@ use Doctrine\ORM\Mapping as ORM;
 #[ApiResource(operations: [])]
 // #[Auditable]
 #[ORM\Entity(repositoryClass: AccessIntangibleRepository::class)]
+#[ORM\Table(name: 'BillingIntangible')]
 class AccessIntangible extends AbstractBillingIntangible
 {
     #[ORM\ManyToOne(inversedBy: 'accessIntangibles')]
     private ?Access $access = null;
 
-    #[ORM\OneToMany(mappedBy: 'accessIntangible', targetEntity: BillingIntangibleExcludeDate::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, BillingIntangibleExcludeDate> */
+    #[ORM\OneToMany(targetEntity: BillingIntangibleExcludeDate::class, mappedBy: 'accessIntangible', cascade: ['persist'], orphanRemoval: true)]
     private Collection $billingIntangibleExcludeDates;
 
     public function __construct()
     {
         $this->billingIntangibleExcludeDates = new ArrayCollection();
+        parent::__construct();
     }
 
     public function setAccess(?Access $access): self

+ 1 - 4
src/Entity/Billing/AccessPayer.php

@@ -16,14 +16,11 @@ use Doctrine\ORM\Mapping as ORM;
  * Fais le lien entre l'Access qui règle la facture et l'Access concerné
  */
 #[ApiResource(operations: [])]
-// #[Auditable]
 #[ORM\Table(name: 'BillingPayer')]
+// #[Auditable]
 #[ORM\Entity(repositoryClass: AccessPayerRepository::class)]
 class AccessPayer extends AbstractBillingPayer
 {
-    #[ORM\Column(length: 255, nullable: false)]
-    private string $discr = 'access';
-
     #[ORM\ManyToOne(inversedBy: 'billingPayers')]
     private ?Access $accessPayer = null;
 

+ 4 - 3
src/Entity/Billing/AdvancePayment.php

@@ -7,12 +7,13 @@ namespace App\Entity\Billing;
 use ApiPlatform\Metadata\ApiResource;
 use Doctrine\ORM\Mapping as ORM;
 
+/**
+ * TODO: documenter.
+ */
 #[ApiResource(operations: [])]
 // #[Auditable]
-#[ORM\Table(name: 'BillAccounting')]
 #[ORM\Entity]
+#[ORM\Table(name: 'BillAccounting')]
 class AdvancePayment extends AbstractBillAccounting
 {
-    #[ORM\Column(length: 255, nullable: false)]
-    protected string $discr = 'advancepayment';
 }

+ 6 - 2
src/Entity/Billing/Afi.php

@@ -9,6 +9,9 @@ use App\Entity\Core\File;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
+/**
+ * TODO: documenter.
+ */
 #[ApiResource(operations: [])]
 #[ORM\Entity]
 class Afi
@@ -18,11 +21,12 @@ class Afi
     #[ORM\GeneratedValue]
     private int $id;
 
-    #[ORM\OneToMany(mappedBy: 'afi', targetEntity: Bill::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, Bill> */
+    #[ORM\OneToMany(targetEntity: Bill::class, mappedBy: 'afi', cascade: ['persist'], orphanRemoval: true)]
     protected Collection $bills;
 
     #[ORM\OneToOne(targetEntity: File::class, cascade: ['persist'])]
-    protected File $file;
+    protected ?File $file;
 
     public function getId(): int
     {

+ 7 - 3
src/Entity/Billing/BergerLevrault.php

@@ -5,16 +5,19 @@ declare(strict_types=1);
 namespace App\Entity\Billing;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use App\Entity\Core\File;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * Fais le lien entre les factures (Bill) concernées par l'export et l'objet File généré
+ * NB: BergerLevrault est un format de données demandé par le Trésor Public pour l'export des données comptables.
  */
 // #[Auditable]
 #[ORM\Entity]
+#[ApiResource(operations: [])]
 class BergerLevrault
 {
     #[ORM\Id]
@@ -22,11 +25,12 @@ class BergerLevrault
     #[ORM\GeneratedValue]
     private ?int $id = null;
 
-    #[ORM\OneToMany(mappedBy: 'bergerLevrault', targetEntity: Bill::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, Bill> */
+    #[ORM\OneToMany(targetEntity: Bill::class, mappedBy: 'bergerLevrault', cascade: ['persist'], orphanRemoval: true)]
     private Collection $bills;
 
     #[ORM\OneToOne(targetEntity: File::class, cascade: ['persist'])]
-    protected File $file;
+    protected ?File $file;
 
     public function __construct()
     {

+ 101 - 3
src/Entity/Billing/Bill.php

@@ -5,14 +5,112 @@ declare(strict_types=1);
 namespace App\Entity\Billing;
 
 use ApiPlatform\Metadata\ApiResource;
+use Doctrine\Common\Collections\ArrayCollection;
+use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
+/**
+ * Facture.
+ */
 #[ApiResource(operations: [])]
 // #[Auditable]
-#[ORM\Table(name: 'BillAccounting')]
 #[ORM\Entity]
+#[ORM\Table(name: 'BillAccounting')]
 class Bill extends AbstractBillAccounting
 {
-    #[ORM\Column(length: 255, nullable: false)]
-    protected string $discr = 'bill';
+    /** @var Collection<int, BillLine> */
+    #[ORM\OneToMany(targetEntity: BillLine::class, mappedBy: 'bill', cascade: ['persist'], orphanRemoval: true)]
+    protected Collection $billLines;
+
+    /** @var Collection<int, BillCredit> */
+    #[ORM\OneToMany(targetEntity: BillCredit::class, mappedBy: 'bill', cascade: ['persist'], orphanRemoval: true)]
+    protected Collection $billCredits;
+
+    /** @var Collection<int, BillPayment> */
+    #[ORM\OneToMany(targetEntity: BillPayment::class, mappedBy: 'bill', cascade: ['persist'], orphanRemoval: true)]
+    protected Collection $billPayments;
+
+    public function __construct()
+    {
+        $this->billLines = new ArrayCollection();
+        $this->billCredits = new ArrayCollection();
+        $this->billPayments = new ArrayCollection();
+        parent::__construct();
+    }
+
+    public function getBillLines(): Collection
+    {
+        return $this->billLines;
+    }
+
+    public function addBillLine(BillLine $billLine): self
+    {
+        if (!$this->billLines->contains($billLine)) {
+            $this->billLines[] = $billLine;
+            $billLine->setBill($this);
+        }
+
+        return $this;
+    }
+
+    public function removeBillLine(BillLine $billLine): self
+    {
+        $this->billLines->removeElement($billLine);
+
+        return $this;
+    }
+
+    public function getBillCredits(): Collection
+    {
+        return $this->billCredits;
+    }
+
+    public function addBillCredit(BillCredit $billCredit): self
+    {
+        if (!$this->billCredits->contains($billCredit)) {
+            $this->billCredits[] = $billCredit;
+            $billCredit->setBill($this);
+        }
+
+        return $this;
+    }
+
+    public function removeBillCredit(BillCredit $billCredit): self
+    {
+        if ($this->billCredits->removeElement($billCredit)) {
+            // set the owning side to null (unless already changed)
+            if ($billCredit->getBill() === $this) {
+                $billCredit->setBill(null);
+            }
+        }
+
+        return $this;
+    }
+
+    public function getBillPayments(): Collection
+    {
+        return $this->billPayments;
+    }
+
+    public function addBillPayment(BillPayment $billPayment): self
+    {
+        if (!$this->billPayments->contains($billPayment)) {
+            $this->billPayments[] = $billPayment;
+            $billPayment->setBill($this);
+        }
+
+        return $this;
+    }
+
+    public function removeBillPayment(BillPayment $billPayment): self
+    {
+        if ($this->billPayments->removeElement($billPayment)) {
+            // set the owning side to null (unless already changed)
+            if ($billPayment->getBill() === $this) {
+                $billPayment->setBill(null);
+            }
+        }
+
+        return $this;
+    }
 }

+ 2 - 2
src/Entity/Billing/BillAccessDetail.php

@@ -9,11 +9,11 @@ use ApiPlatform\Metadata\ApiResource;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * Paramètres d'un Access pour une facture (Bill).
  */
 // #[Auditable]
-#[ApiResource(operations: [])]
 #[ORM\Entity]
+#[ApiResource(operations: [])]
 class BillAccessDetail
 {
     #[ORM\Id]

+ 5 - 3
src/Entity/Billing/BillAccounting.php

@@ -7,12 +7,14 @@ namespace App\Entity\Billing;
 use ApiPlatform\Metadata\ApiResource;
 use Doctrine\ORM\Mapping as ORM;
 
+/**
+ * Facture ou avoir (@see Bill, BillCredit).
+ */
 #[ApiResource(operations: [])]
-#[ORM\Table(name: 'BillAccounting')]
 // #[Auditable]
 #[ORM\Entity]
+#[ORM\Table(name: 'BillAccounting')]
+#[ORM\InheritanceType('SINGLE_TABLE')]
 class BillAccounting extends AbstractBillAccounting
 {
-    #[ORM\Column(length: 255, nullable: false)]
-    protected string $discr = 'billaccounting';
 }

+ 4 - 3
src/Entity/Billing/BillCredit.php

@@ -7,12 +7,13 @@ namespace App\Entity\Billing;
 use ApiPlatform\Metadata\ApiResource;
 use Doctrine\ORM\Mapping as ORM;
 
+/**
+ * Avoir.
+ */
 #[ApiResource(operations: [])]
 // #[Auditable]
-#[ORM\Table(name: 'BillAccounting')]
 #[ORM\Entity]
+#[ORM\Table(name: 'BillAccounting')]
 class BillCredit extends AbstractBillAccounting
 {
-    #[ORM\Column(length: 255, nullable: false)]
-    protected string $discr = 'billcredit';
 }

+ 3 - 1
src/Entity/Billing/BillDebitBalance.php

@@ -5,12 +5,14 @@ declare(strict_types=1);
 namespace App\Entity\Billing;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * Trop-perçu conservé pour être reversé à la Bill suivante.
  */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 class BillDebitBalance
 {

+ 9 - 7
src/Entity/Billing/BillLine.php

@@ -12,7 +12,9 @@ use App\Entity\Product\EquipmentLoan;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * Une ligne de facturation.
+ *
+ * @see BillAccounting
  */
 #[ApiResource(operations: [])]
 // #[Auditable]
@@ -26,28 +28,28 @@ class BillLine
 
     #[ORM\ManyToOne(inversedBy: 'billLines')]
     #[ORM\JoinColumn(nullable: false)]
-    private AbstractBillAccounting $bill;
+    private Bill $bill;
 
     #[ORM\ManyToOne(inversedBy: 'billLines')]
-    private Access $access;
+    private ?Access $access = null;
 
     #[ORM\ManyToOne(inversedBy: 'billLines')]
-    private EducationalProject $educationalProject;
+    private ?EducationalProject $educationalProject = null;
 
     #[ORM\ManyToOne(inversedBy: 'billLines')]
-    private EquipmentLoan $equipmentLoan;
+    private ?EquipmentLoan $equipmentLoan = null;
 
     public function getId(): ?int
     {
         return $this->id;
     }
 
-    public function getBill(): ?AbstractBillAccounting
+    public function getBill(): Bill
     {
         return $this->bill;
     }
 
-    public function setBill(?AbstractBillAccounting $bill): self
+    public function setBill(Bill $bill): self
     {
         $this->bill = $bill;
 

+ 18 - 13
src/Entity/Billing/BillPayment.php

@@ -4,6 +4,7 @@ declare(strict_types=1);
 
 namespace App\Entity\Billing;
 
+use ApiPlatform\Metadata\ApiResource;
 use App\Entity\Core\Tagg;
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
 use Doctrine\Common\Collections\ArrayCollection;
@@ -11,9 +12,11 @@ use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * Données de paiement d'une facture BillAccounting
+ * NB: il peut y avoir plusieurs lignes pour une facture en cas de paiement en plusieurs fois.
  */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 class BillPayment
 {
@@ -24,20 +27,22 @@ class BillPayment
 
     #[ORM\ManyToOne(cascade: ['persist'], inversedBy: 'billPayments')]
     #[ORM\JoinColumn(nullable: true)]
-    private AbstractBillAccounting $bill;
+    private ?Bill $bill = null;
 
     #[ORM\ManyToOne(cascade: ['persist'], inversedBy: 'billDetachedPayments')]
     #[ORM\JoinColumn(nullable: true)]
-    private AccessBilling $accessBilling;
+    private ?AccessBilling $accessBilling = null;
 
-    #[ORM\OneToMany(mappedBy: 'billPayment', targetEntity: BillDebitBalance::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, BillDebitBalance> */
+    #[ORM\OneToMany(targetEntity: BillDebitBalance::class, mappedBy: 'billPayment', cascade: ['persist'], orphanRemoval: true)]
     #[ORM\JoinColumn(nullable: true)]
     private Collection $billDebitBalances;
 
     #[ORM\ManyToOne(cascade: ['persist'], inversedBy: 'accountBalanceReimbursements')]
     #[ORM\JoinColumn(nullable: true)]
-    private AccessBilling $accessBillingAccountBalanceReimbursement;
+    private ?AccessBilling $accessBillingAccountBalanceReimbursement = null;
 
+    /** @var Collection<int, Tagg> */
     #[ORM\ManyToMany(targetEntity: Tagg::class, inversedBy: 'payments', cascade: ['persist'])]
     #[ORM\JoinTable(name: 'tag_billPayment')]
     #[ORM\JoinColumn(name: 'billPayment_id', referencedColumnName: 'id')]
@@ -46,11 +51,11 @@ class BillPayment
 
     #[ORM\ManyToOne(targetEntity: SddBank::class, cascade: ['persist'], inversedBy: 'billPayments')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    protected SddBank $sddBank;
+    protected ?SddBank $sddBank;
 
     #[ORM\ManyToOne(targetEntity: SddRegie::class, cascade: ['persist'], inversedBy: 'billPayments')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    protected SddRegie $sddRegie;
+    protected ?SddRegie $sddRegie;
 
     public function __construct()
     {
@@ -63,12 +68,12 @@ class BillPayment
         return $this->id;
     }
 
-    public function getBill(): ?AbstractBillAccounting
+    public function getBill(): ?Bill
     {
         return $this->bill;
     }
 
-    public function setBill(?AbstractBillAccounting $bill): self
+    public function setBill(?Bill $bill): self
     {
         $this->bill = $bill;
 
@@ -153,24 +158,24 @@ class BillPayment
         return $this;
     }
 
-    public function getSddBank(): SddBank
+    public function getSddBank(): ?SddBank
     {
         return $this->sddBank;
     }
 
-    public function setSddBank(SddBank $sddBank): self
+    public function setSddBank(?SddBank $sddBank): self
     {
         $this->sddBank = $sddBank;
 
         return $this;
     }
 
-    public function getSddRegie(): SddRegie
+    public function getSddRegie(): ?SddRegie
     {
         return $this->sddRegie;
     }
 
-    public function setSddRegie(SddRegie $sddRegie): self
+    public function setSddRegie(?SddRegie $sddRegie): self
     {
         $this->sddRegie = $sddRegie;
 

+ 4 - 1
src/Entity/Billing/BillPeriod.php

@@ -5,12 +5,15 @@ declare(strict_types=1);
 namespace App\Entity\Billing;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * Période associée à une facture
+ * (Ex: Deuxième trimestre 2020).
  */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 class BillPeriod
 {

+ 9 - 3
src/Entity/Billing/BillSchedule.php

@@ -10,6 +10,9 @@ use App\Entity\Organization\Organization;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
+/**
+ * TODO: documenter.
+ */
 #[ApiResource(operations: [])]
 #[ORM\Entity]
 class BillSchedule
@@ -23,13 +26,16 @@ class BillSchedule
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: false, onDelete: 'SET NULL')]
     protected Organization $organization;
 
-    #[ORM\OneToMany(mappedBy: 'billSchedule', targetEntity: BillScheduleDate::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, BillScheduleDate> */
+    #[ORM\OneToMany(targetEntity: BillScheduleDate::class, mappedBy: 'billSchedule', cascade: ['persist'], orphanRemoval: true)]
     protected Collection $scheduleDates;
 
-    #[ORM\OneToMany(mappedBy: 'billSchedule', targetEntity: AccessBilling::class, cascade: [], orphanRemoval: false)] // TODO: à revoir
+    /** @var Collection<int, AccessBilling> */
+    #[ORM\OneToMany(targetEntity: AccessBilling::class, mappedBy: 'billSchedule', cascade: [], orphanRemoval: false)] // TODO: à revoir
     protected Collection $accessBilling;
 
-    #[ORM\OneToMany(mappedBy: 'billSchedule', targetEntity: AccessWish::class, cascade: [], orphanRemoval: false)] // TODO: à revoir
+    /** @var Collection<int, AccessWish> */
+    #[ORM\OneToMany(targetEntity: AccessWish::class, mappedBy: 'billSchedule', cascade: [], orphanRemoval: false)] // TODO: à revoir
     protected Collection $accessWishes;
 
     public function getId(): int

+ 3 - 0
src/Entity/Billing/BillScheduleDate.php

@@ -7,6 +7,9 @@ namespace App\Entity\Billing;
 use ApiPlatform\Metadata\ApiResource;
 use Doctrine\ORM\Mapping as ORM;
 
+/**
+ * TODO: documenter.
+ */
 #[ApiResource(operations: [])]
 #[ORM\Entity]
 class BillScheduleDate

+ 3 - 1
src/Entity/Billing/BillTotalDetail.php

@@ -5,12 +5,14 @@ declare(strict_types=1);
 namespace App\Entity\Billing;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * Totaux des lignes BillLine d'une facture BillAccounting, avec calcul de TVA.
  */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 class BillTotalDetail
 {

+ 9 - 6
src/Entity/Billing/BillingExportSetting.php

@@ -5,6 +5,7 @@ declare(strict_types=1);
 namespace App\Entity\Billing;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use App\Entity\Access\Access;
 use App\Entity\Organization\Organization;
 use Doctrine\Common\Collections\ArrayCollection;
@@ -12,9 +13,10 @@ use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * Paramètres généraux des exports de factures (Bill).
  */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 class BillingExportSetting
 {
@@ -25,11 +27,12 @@ class BillingExportSetting
 
     #[ORM\ManyToOne]
     #[ORM\JoinColumn(nullable: true)]
-    private SddTeneur $teneur;
+    private ?SddTeneur $teneur = null;
 
-    #[ORM\OneToOne(inversedBy: 'billingExportSetting', targetEntity: Organization::class, cascade: [])]
-    protected Organization $organization;
+    #[ORM\OneToOne(targetEntity: Organization::class, inversedBy: 'billingExportSetting', cascade: [])]
+    protected ?Organization $organization;
 
+    /** @var Collection<int, Access> */
     #[ORM\ManyToMany(targetEntity: Access::class, cascade: [], orphanRemoval: false)]
     protected Collection $stageManagers;
 
@@ -55,12 +58,12 @@ class BillingExportSetting
         return $this;
     }
 
-    public function getOrganization(): Organization
+    public function getOrganization(): ?Organization
     {
         return $this->organization;
     }
 
-    public function setOrganization(Organization $organization): self
+    public function setOrganization(?Organization $organization): self
     {
         $this->organization = $organization;
 

+ 7 - 6
src/Entity/Billing/BillingIntangibleExcludeDate.php

@@ -10,7 +10,8 @@ use App\Entity\Product\EquipmentLoan;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * Indique les produits (BillingIntangible) déjà facturés
+ * TODO: confirmer la doc?
  */
 #[ApiResource(operations: [])]
 // #[Auditable]
@@ -23,19 +24,19 @@ class BillingIntangibleExcludeDate
     private ?int $id = null;
 
     #[ORM\ManyToOne(cascade: ['persist'], inversedBy: 'billingIntangibleExcludeDates')]
-    private AccessIntangible $accessIntangible;
+    private ?AccessIntangible $accessIntangible = null;
 
     #[ORM\ManyToOne(cascade: ['persist'], inversedBy: 'billingIntangibleExcludeDates')]
-    private AccessFictionalIntangible $accessFictionalIntangible;
+    private ?AccessFictionalIntangible $accessFictionalIntangible = null;
 
     #[ORM\ManyToOne(cascade: ['persist'], inversedBy: 'billingIntangibleExcludeDates')]
-    private EducationalProjectIntangible $educationalProjectIntangible;
+    private ?EducationalProjectIntangible $educationalProjectIntangible = null;
 
     #[ORM\ManyToOne(cascade: ['persist'], inversedBy: 'billingIntangibleExcludeDates')]
-    private EquipmentLoan $equipmentLoan;
+    private ?EquipmentLoan $equipmentLoan = null;
 
     #[ORM\ManyToOne(cascade: ['persist'], inversedBy: 'billingIntangibleExcludeDates')]
-    private Bill $bill;
+    private ?Bill $bill = null;
 
     public function getId(): ?int
     {

+ 11 - 6
src/Entity/Billing/BillingSetting.php

@@ -13,6 +13,9 @@ use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 use JetBrains\PhpStorm\Pure;
 
+/**
+ * Paramètres globaux d'une Organization concernant la facturation.
+ */
 #[ApiResource(operations: [])]
 // #[Auditable]
 #[ORM\Entity(repositoryClass: BillingSettingRepository::class)]
@@ -27,17 +30,19 @@ class BillingSetting
     #[ORM\JoinColumn(nullable: false)]
     private Organization $organization;
 
-    #[ORM\OneToMany(mappedBy: 'billingSetting', targetEntity: ResidenceArea::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, ResidenceArea> */
+    #[ORM\OneToMany(targetEntity: ResidenceArea::class, mappedBy: 'billingSetting', cascade: ['persist'], orphanRemoval: true)]
     private Collection $residenceAreas;
 
     #[ORM\Column(options: ['default' => false])]
     private bool $applyVat = false;
 
-    #[ORM\OneToMany(mappedBy: 'billingSetting', targetEntity: FamilyQuotient::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, FamilyQuotient> */
+    #[ORM\OneToMany(targetEntity: FamilyQuotient::class, mappedBy: 'billingSetting', cascade: ['persist'], orphanRemoval: true)]
     private Collection $familyQuotients;
 
-    #[ORM\OneToOne(mappedBy: 'billingSetting', targetEntity: BillingSettingRent::class, cascade: ['persist'])]
-    protected BillingSettingRent $billingSettingRent;
+    #[ORM\OneToOne(targetEntity: BillingSettingRent::class, mappedBy: 'billingSetting', cascade: ['persist'])]
+    protected ?BillingSettingRent $billingSettingRent;
 
     #[Pure]
     public function __construct()
@@ -132,12 +137,12 @@ class BillingSetting
         return $this;
     }
 
-    public function getBillingSettingRent(): BillingSettingRent
+    public function getBillingSettingRent(): ?BillingSettingRent
     {
         return $this->billingSettingRent;
     }
 
-    public function setBillingSettingRent(BillingSettingRent $billingSettingRent): self
+    public function setBillingSettingRent(?BillingSettingRent $billingSettingRent): self
     {
         $this->billingSettingRent = $billingSettingRent;
 

+ 7 - 5
src/Entity/Billing/BillingSettingRent.php

@@ -5,12 +5,14 @@ declare(strict_types=1);
 namespace App\Entity\Billing;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * Paramètres globaux d'une Organization concernant la facturation liée à la location.
  */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 class BillingSettingRent
 {
@@ -19,15 +21,15 @@ class BillingSettingRent
     #[ORM\GeneratedValue]
     private ?int $id = null;
 
-    #[ORM\OneToOne(inversedBy: 'billingSettingRent', targetEntity: BillingSetting::class, cascade: [])]
-    protected BillingSetting $billingSetting;
+    #[ORM\OneToOne(targetEntity: BillingSetting::class, inversedBy: 'billingSettingRent', cascade: [])]
+    protected ?BillingSetting $billingSetting;
 
-    public function getBillingSetting(): BillingSetting
+    public function getBillingSetting(): ?BillingSetting
     {
         return $this->billingSetting;
     }
 
-    public function setBillingSetting(BillingSetting $billingSetting): self
+    public function setBillingSetting(?BillingSetting $billingSetting): self
     {
         $this->billingSetting = $billingSetting;
 

+ 8 - 5
src/Entity/Billing/Ciril.php

@@ -5,15 +5,17 @@ declare(strict_types=1);
 namespace App\Entity\Billing;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use App\Entity\Core\File;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * TODO: documenter.
  */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 class Ciril
 {
@@ -22,11 +24,12 @@ class Ciril
     #[ORM\GeneratedValue]
     private ?int $id = null;
 
-    #[ORM\OneToMany(mappedBy: 'ciril', targetEntity: Bill::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, Bill> */
+    #[ORM\OneToMany(targetEntity: Bill::class, mappedBy: 'ciril', cascade: ['persist'], orphanRemoval: true)]
     private Collection $bills;
 
     #[ORM\OneToOne(targetEntity: File::class, cascade: ['persist'])]
-    protected File $file;
+    protected ?File $file;
 
     public function __construct()
     {
@@ -68,12 +71,12 @@ class Ciril
         return $this;
     }
 
-    public function getFile(): File
+    public function getFile(): ?File
     {
         return $this->file;
     }
 
-    public function setFile(File $file): self
+    public function setFile(?File $file): self
     {
         $this->file = $file;
 

+ 8 - 4
src/Entity/Billing/CirilCivil.php

@@ -9,6 +9,9 @@ use App\Entity\Core\File;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
+/**
+ * TODO: documenter.
+ */
 #[ApiResource(operations: [])]
 #[ORM\Entity]
 class CirilCivil
@@ -18,11 +21,12 @@ class CirilCivil
     #[ORM\GeneratedValue]
     private int $id;
 
-    #[ORM\OneToMany(mappedBy: 'cirilCivil', targetEntity: Bill::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, Bill> */
+    #[ORM\OneToMany(targetEntity: Bill::class, mappedBy: 'cirilCivil', cascade: ['persist'], orphanRemoval: true)]
     protected Collection $bills;
 
     #[ORM\OneToOne(targetEntity: File::class, cascade: ['persist'])]
-    protected File $file;
+    protected ?File $file;
 
     public function getId(): int
     {
@@ -58,12 +62,12 @@ class CirilCivil
         return $this;
     }
 
-    public function getFile(): File
+    public function getFile(): ?File
     {
         return $this->file;
     }
 
-    public function setFile(File $file): self
+    public function setFile(?File $file): self
     {
         $this->file = $file;
 

+ 8 - 13
src/Entity/Billing/EducationalProjectIntangible.php

@@ -4,6 +4,7 @@ declare(strict_types=1);
 
 namespace App\Entity\Billing;
 
+use ApiPlatform\Metadata\ApiResource;
 use App\Entity\Booking\EducationalProject;
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
 use Doctrine\Common\Collections\ArrayCollection;
@@ -11,31 +12,25 @@ use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * Fais le lien entre l'Access qui règle la facture et l'EducationalProject concerné.
  */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
+#[ORM\Table(name: 'BillingIntangible')]
 class EducationalProjectIntangible extends AbstractBillingIntangible
 {
-    #[ORM\Id]
-    #[ORM\Column]
-    #[ORM\GeneratedValue]
-    protected ?int $id = null;
-
     #[ORM\ManyToOne(inversedBy: 'educationalProjectIntangibles')]
-    private EducationalProject $educationalProject;
+    private ?EducationalProject $educationalProject = null;
 
-    #[ORM\OneToMany(mappedBy: 'educationalProjectIntangible', targetEntity: BillingIntangibleExcludeDate::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, BillingIntangibleExcludeDate> */
+    #[ORM\OneToMany(targetEntity: BillingIntangibleExcludeDate::class, mappedBy: 'educationalProjectIntangible', cascade: ['persist'], orphanRemoval: true)]
     private Collection $billingIntangibleExcludeDates;
 
     public function __construct()
     {
         $this->billingIntangibleExcludeDates = new ArrayCollection();
-    }
-
-    public function getId(): ?int
-    {
-        return $this->id;
+        parent::__construct();
     }
 
     public function getEducationalProject(): ?EducationalProject

+ 5 - 18
src/Entity/Billing/EducationalProjectPayer.php

@@ -13,32 +13,19 @@ use Doctrine\ORM\Mapping as ORM;
 /**
  * @todo : A la suite de la migration, il faut supprimer le nom de la table pour avoir une table EducationalProjectPayer, et supprimer l'attribut discr.
  *
- * Classe ... qui ...
+ * Fais le lien entre l'Access qui règle la facture et l'EducationalProject concerné
  */
 #[ApiResource(operations: [])]
 // #[Auditable]
-#[ORM\Table(name: 'BillingPayer')]
 #[ORM\Entity]
-class EducationalProjectPayer
+#[ORM\Table(name: 'BillingPayer')]
+class EducationalProjectPayer extends AbstractBillingPayer
 {
-    #[ORM\Column(length: 255, nullable: false)]
-    private string $discr = 'educationalproject';
-
-    #[ORM\Id]
-    #[ORM\Column]
-    #[ORM\GeneratedValue]
-    private ?int $id = null;
-
     #[ORM\ManyToOne(cascade: ['persist'], inversedBy: 'billingEducationalProjectPayers')]
-    private Access $educationalProjectPayer;
+    private ?Access $educationalProjectPayer = null;
 
     #[ORM\ManyToOne(cascade: ['persist'], inversedBy: 'billingReceivers')]
-    private EducationalProject $educationalProjectReceiver;
-
-    public function getId(): ?int
-    {
-        return $this->id;
-    }
+    private ?EducationalProject $educationalProjectReceiver = null;
 
     public function getEducationalProjectPayer(): ?Access
     {

+ 5 - 3
src/Entity/Billing/FamilyQuotient.php

@@ -12,7 +12,7 @@ use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * Définition d'une tranche de quotient familial.
  */
 #[ApiResource(operations: [])]
 // #[Auditable]
@@ -28,10 +28,12 @@ class FamilyQuotient
     #[ORM\JoinColumn(nullable: false)]
     private BillingSetting $billingSetting;
 
-    #[ORM\OneToMany(mappedBy: 'familyQuotient', targetEntity: AccessBilling::class)]
+    /** @var Collection<int, AccessBilling> */
+    #[ORM\OneToMany(targetEntity: AccessBilling::class, mappedBy: 'familyQuotient')]
     private Collection $accessBilling;
 
-    #[ORM\OneToMany(mappedBy: 'familyQuotient', targetEntity: IntangibleDiscountDetail::class)]
+    /** @var Collection<int, IntangibleDiscountDetail> */
+    #[ORM\OneToMany(targetEntity: IntangibleDiscountDetail::class, mappedBy: 'familyQuotient')]
     private Collection $intangibleDiscountDetails;
 
     public function __construct()

+ 8 - 7
src/Entity/Billing/FamilyQuotientBand.php

@@ -9,6 +9,9 @@ use App\Entity\Product\IntangibleDiscountDetail;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
+/**
+ * TODO: documenter.
+ */
 #[ApiResource(operations: [])]
 #[ORM\Entity]
 class FamilyQuotientBand
@@ -22,15 +25,13 @@ class FamilyQuotientBand
     #[ORM\JoinColumn(nullable: false)]
     protected mixed $familyQuotientModel;
 
-    #[ORM\OneToMany(
-        mappedBy: 'familyQuotientBand',
-        targetEntity: FamilyQuotientBandDetail::class,
-        cascade: ['persist'],
-        orphanRemoval: true,
-    )]
+    /** @var Collection<int, FamilyQuotientBandDetail> */
+    //    #[ORM\Column(type: 'string')] // TODO: pourquoi c'est là ça?
+    #[ORM\OneToMany(targetEntity: FamilyQuotientBandDetail::class, mappedBy: 'familyQuotientBand', cascade: ['persist'], orphanRemoval: true)]
     protected Collection $familyQuotientBandDetails;
 
-    #[ORM\OneToMany(mappedBy: 'familyQuotientBand', targetEntity: IntangibleDiscountDetail::class, cascade: [], orphanRemoval: true)]
+    /** @var Collection<int, IntangibleDiscountDetail> */
+    #[ORM\OneToMany(targetEntity: IntangibleDiscountDetail::class, mappedBy: 'familyQuotientBand', cascade: [], orphanRemoval: true)]
     protected Collection $intangibleDiscountDetails;
 
     public function getId(): int

+ 8 - 4
src/Entity/Billing/FamilyQuotientBandDetail.php

@@ -9,6 +9,9 @@ use App\Entity\Product\IntangibleDiscountDetail;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
+/**
+ * TODO: documenter.
+ */
 #[ApiResource(operations: [])]
 #[ORM\Entity]
 class FamilyQuotientBandDetail
@@ -24,9 +27,10 @@ class FamilyQuotientBandDetail
 
     #[ORM\ManyToOne(targetEntity: ResidenceArea::class, cascade: [], inversedBy: 'intangibleDiscountDetails')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    protected ResidenceArea $residenceArea;
+    protected ?ResidenceArea $residenceArea;
 
-    #[ORM\OneToMany(mappedBy: 'familyQuotientBandDetail', targetEntity: IntangibleDiscountDetail::class, cascade: [], orphanRemoval: true)]
+    /** @var Collection<int, IntangibleDiscountDetail> */
+    #[ORM\OneToMany(targetEntity: IntangibleDiscountDetail::class, mappedBy: 'familyQuotientBandDetail', cascade: [], orphanRemoval: true)]
     protected Collection $intangibleDiscountDetails;
 
     public function getId(): int
@@ -53,12 +57,12 @@ class FamilyQuotientBandDetail
         return $this;
     }
 
-    public function getResidenceArea(): ResidenceArea
+    public function getResidenceArea(): ?ResidenceArea
     {
         return $this->residenceArea;
     }
 
-    public function setResidenceArea(ResidenceArea $residenceArea): self
+    public function setResidenceArea(?ResidenceArea $residenceArea): self
     {
         $this->residenceArea = $residenceArea;
 

+ 7 - 2
src/Entity/Billing/FamilyQuotientModel.php

@@ -10,6 +10,9 @@ use App\Entity\Product\IntangiblePriceAndDiscount;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
+/**
+ * TODO: documenter.
+ */
 #[ApiResource(operations: [])]
 #[ORM\Entity]
 class FamilyQuotientModel
@@ -23,10 +26,12 @@ class FamilyQuotientModel
     #[ORM\JoinColumn(nullable: false)]
     protected Organization $organization;
 
-    #[ORM\OneToMany(mappedBy: 'familyQuotientModel', targetEntity: FamilyQuotientBand::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, FamilyQuotientBand> */
+    #[ORM\OneToMany(targetEntity: FamilyQuotientBand::class, mappedBy: 'familyQuotientModel', cascade: ['persist'], orphanRemoval: true)]
     protected Collection $familyQuotientBands;
 
-    #[ORM\OneToMany(mappedBy: 'familyQuotientModel', targetEntity: IntangiblePriceAndDiscount::class, cascade: [], orphanRemoval: false)]
+    /** @var Collection<int, IntangiblePriceAndDiscount> */
+    #[ORM\OneToMany(targetEntity: IntangiblePriceAndDiscount::class, mappedBy: 'familyQuotientModel', cascade: [], orphanRemoval: false)]
     protected Collection $intangiblePriceAndDiscounts;
 
     public function getId(): int

+ 8 - 5
src/Entity/Billing/Jvs.php

@@ -5,15 +5,17 @@ declare(strict_types=1);
 namespace App\Entity\Billing;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use App\Entity\Core\File;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * TODO: documenter.
  */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 class Jvs
 {
@@ -22,11 +24,12 @@ class Jvs
     #[ORM\GeneratedValue]
     private ?int $id = null;
 
-    #[ORM\OneToMany(mappedBy: 'jvs', targetEntity: Bill::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, Bill> */
+    #[ORM\OneToMany(targetEntity: Bill::class, mappedBy: 'jvs', cascade: ['persist'], orphanRemoval: true)]
     private Collection $bills;
 
     #[ORM\OneToOne(targetEntity: File::class, cascade: ['persist'])]
-    protected File $file;
+    protected ?File $file;
 
     public function __construct()
     {
@@ -68,12 +71,12 @@ class Jvs
         return $this;
     }
 
-    public function getFile(): File
+    public function getFile(): ?File
     {
         return $this->file;
     }
 
-    public function setFile(File $file): self
+    public function setFile(?File $file): self
     {
         $this->file = $file;
 

+ 8 - 4
src/Entity/Billing/Odyssee.php

@@ -9,6 +9,9 @@ use App\Entity\Core\File;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
+/**
+ * TODO: documenter.
+ */
 #[ApiResource(operations: [])]
 #[ORM\Entity]
 class Odyssee
@@ -18,11 +21,12 @@ class Odyssee
     #[ORM\GeneratedValue]
     private int $id;
 
-    #[ORM\OneToMany(mappedBy: 'odyssee', targetEntity: Bill::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, Bill> */
+    #[ORM\OneToMany(targetEntity: Bill::class, mappedBy: 'odyssee', cascade: ['persist'], orphanRemoval: true)]
     protected Collection $bills;
 
     #[ORM\OneToOne(targetEntity: File::class, cascade: ['persist'])]
-    protected File $file;
+    protected ?File $file;
 
     public function getId(): int
     {
@@ -60,12 +64,12 @@ class Odyssee
         return $this;
     }
 
-    public function getFile(): File
+    public function getFile(): ?File
     {
         return $this->file;
     }
 
-    public function setFile(File $file): self
+    public function setFile(?File $file): self
     {
         $this->file = $file;
 

+ 3 - 0
src/Entity/Billing/PayboxPaymentReturn.php

@@ -7,6 +7,9 @@ namespace App\Entity\Billing;
 use ApiPlatform\Metadata\ApiResource;
 use Doctrine\ORM\Mapping as ORM;
 
+/**
+ * TODO: documenter.
+ */
 #[ApiResource(operations: [])]
 #[ORM\Entity]
 class PayboxPaymentReturn

+ 3 - 1
src/Entity/Billing/PayfipPaymentReturn.php

@@ -5,12 +5,14 @@ declare(strict_types=1);
 namespace App\Entity\Billing;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * TODO: documenter.
  */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 class PayfipPaymentReturn
 {

+ 9 - 5
src/Entity/Billing/Pes.php

@@ -5,15 +5,18 @@ declare(strict_types=1);
 namespace App\Entity\Billing;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use App\Entity\Core\File;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * Paramètres généraux d'un export PES
+ * NB: PES est un format de données demandé par le Trésor Public pour l'export des données comptables.
  */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 class Pes
 {
@@ -22,11 +25,12 @@ class Pes
     #[ORM\GeneratedValue]
     private ?int $id = null;
 
-    #[ORM\OneToMany(mappedBy: 'pes', targetEntity: Bill::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, Bill> */
+    #[ORM\OneToMany(targetEntity: Bill::class, mappedBy: 'pes', cascade: ['persist'], orphanRemoval: true)]
     private Collection $bills;
 
     #[ORM\OneToOne(targetEntity: File::class, cascade: ['persist'])]
-    protected File $file;
+    protected ?File $file;
 
     public function __construct()
     {
@@ -68,12 +72,12 @@ class Pes
         return $this;
     }
 
-    public function getFile(): File
+    public function getFile(): ?File
     {
         return $this->file;
     }
 
-    public function setFile(File $file): self
+    public function setFile(?File $file): self
     {
         $this->file = $file;
 

+ 6 - 4
src/Entity/Billing/PesSetting.php

@@ -5,13 +5,15 @@ declare(strict_types=1);
 namespace App\Entity\Billing;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use App\Entity\Organization\Organization;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * TODO: (Plus utilisée, à confirmer).
  */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 class PesSetting
 {
@@ -21,19 +23,19 @@ class PesSetting
     private ?int $id = null;
 
     #[ORM\OneToOne(targetEntity: Organization::class, inversedBy: 'pesSetting', cascade: [])]
-    protected Organization $organization;
+    protected ?Organization $organization;
 
     public function getId(): ?int
     {
         return $this->id;
     }
 
-    public function getOrganization(): Organization
+    public function getOrganization(): ?Organization
     {
         return $this->organization;
     }
 
-    public function setOrganization(Organization $organization): self
+    public function setOrganization(?Organization $organization): self
     {
         $this->organization = $organization;
 

+ 4 - 2
src/Entity/Billing/ResidenceArea.php

@@ -58,10 +58,12 @@ class ResidenceArea
     #[ORM\JoinColumn(nullable: false)]
     private BillingSetting $billingSetting;
 
-    #[ORM\OneToMany(mappedBy: 'residenceArea', targetEntity: AccessBilling::class)]
+    /** @var Collection<int, AccessBilling> */
+    #[ORM\OneToMany(targetEntity: AccessBilling::class, mappedBy: 'residenceArea')]
     private Collection $accessBilling;
 
-    #[ORM\OneToMany(mappedBy: 'residenceArea', targetEntity: IntangibleDiscountDetail::class)]
+    /** @var Collection<int, IntangibleDiscountDetail> */
+    #[ORM\OneToMany(targetEntity: IntangibleDiscountDetail::class, mappedBy: 'residenceArea')]
     private Collection $intangibleDiscountDetails;
 
     #[ORM\Column(length: 255)]

+ 8 - 5
src/Entity/Billing/SddBank.php

@@ -5,15 +5,17 @@ declare(strict_types=1);
 namespace App\Entity\Billing;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use App\Entity\Core\File;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * TODO: documenter.
  */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 class SddBank
 {
@@ -22,11 +24,12 @@ class SddBank
     #[ORM\GeneratedValue]
     private ?int $id = null;
 
-    #[ORM\OneToMany(mappedBy: 'sddBank', targetEntity: BillPayment::class, cascade: [], orphanRemoval: false)]
+    /** @var Collection<int, BillPayment> */
+    #[ORM\OneToMany(targetEntity: BillPayment::class, mappedBy: 'sddBank', cascade: [], orphanRemoval: false)]
     protected Collection $billPayments;
 
     #[ORM\OneToOne(targetEntity: File::class, cascade: ['persist'])]
-    protected File $file;
+    protected ?File $file;
 
     public function __construct()
     {
@@ -62,12 +65,12 @@ class SddBank
         return $this;
     }
 
-    public function getFile(): File
+    public function getFile(): ?File
     {
         return $this->file;
     }
 
-    public function setFile(File $file): self
+    public function setFile(?File $file): self
     {
         $this->file = $file;
 

+ 11 - 8
src/Entity/Billing/SddRegie.php

@@ -5,16 +5,18 @@ declare(strict_types=1);
 namespace App\Entity\Billing;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use App\Entity\Core\File;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * TODO: documenter
  * // TODO: possible factoriser avec SddBank?
  */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 class SddRegie
 {
@@ -23,14 +25,15 @@ class SddRegie
     #[ORM\GeneratedValue]
     private ?int $id = null;
 
-    #[ORM\OneToMany(mappedBy: 'sddRegie', targetEntity: BillPayment::class, cascade: [], orphanRemoval: false)]
+    /** @var Collection<int, BillPayment> */
+    #[ORM\OneToMany(mappedBy: 'sddRegime', targetEntity: BillPayment::class, cascade: [], orphanRemoval: false)]
     protected Collection $billPayments;
 
     #[ORM\OneToOne(targetEntity: File::class, cascade: ['persist'])]
-    protected File $file;
+    protected ?File $file;
 
     #[ORM\OneToOne(targetEntity: File::class, cascade: ['persist'])]
-    protected File $bordereau;
+    protected ?File $bordereau;
 
     public function __construct()
     {
@@ -66,24 +69,24 @@ class SddRegie
         return $this;
     }
 
-    public function getFile(): File
+    public function getFile(): ?File
     {
         return $this->file;
     }
 
-    public function setFile(File $file): self
+    public function setFile(?File $file): self
     {
         $this->file = $file;
 
         return $this;
     }
 
-    public function getBordereau(): File
+    public function getBordereau(): ?File
     {
         return $this->bordereau;
     }
 
-    public function setBordereau(File $bordereau): self
+    public function setBordereau(?File $bordereau): self
     {
         $this->bordereau = $bordereau;
 

+ 3 - 1
src/Entity/Billing/SddTeneur.php

@@ -5,12 +5,14 @@ declare(strict_types=1);
 namespace App\Entity\Billing;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * TODO: documenter.
  */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 class SddTeneur
 {

+ 62 - 56
src/Entity/Booking/AbstractBooking.php

@@ -10,7 +10,6 @@ use App\Entity\Access\Access;
 use App\Entity\Core\Tagg;
 use App\Entity\Product\Equipment;
 use App\Entity\Traits\ActivityYearTrait;
-use App\Enum\Booking\VisibilityEnum;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
@@ -23,6 +22,18 @@ use Doctrine\ORM\Mapping as ORM;
 #[ActivityYearConstraintAware(startYearFieldName: 'startYear', endYearFieldName: 'endYear')]
 #[OrganizationDefaultValue(fieldName: 'organization')]
 #[ORM\MappedSuperclass]
+#[ORM\Table(name: 'Booking')]
+#[ORM\DiscriminatorColumn(name: 'discr', type: 'string')]
+#[ORM\DiscriminatorMap(
+    [
+        'educationalproject' => EducationalProject::class,
+        'course' => Course::class,
+        'event' => Event::class,
+        'examen' => Examen::class,
+        'organizationholiday' => OrganizationHoliday::class,
+        'personholiday' => PersonHoliday::class,
+    ]
+)]
 abstract class AbstractBooking
 {
     use ActivityYearTrait;
@@ -32,31 +43,37 @@ abstract class AbstractBooking
     #[ORM\GeneratedValue]
     protected ?int $id = null;
 
-    #[ORM\Column(length: 255, nullable: false)]
-    protected string $discr;
-
     #[ORM\Column]
     protected string $name;
 
+    /** @var Collection<int, Access> */
+    #[ORM\ManyToMany(targetEntity: Access::class, inversedBy: 'educationalProjectOrganizers')]
+    #[ORM\JoinTable(name: 'booking_organizer')]
+    #[ORM\JoinColumn(name: 'booking_id', referencedColumnName: 'id')]
+    #[ORM\InverseJoinColumn(name: 'organizer_id', referencedColumnName: 'id')]
+    protected Collection $organizer;
+
     #[ORM\Column(type: 'datetime', nullable: true)]
     protected ?\DateTimeInterface $datetimeStart = null;
 
     #[ORM\Column(type: 'datetime', nullable: true)]
     protected ?\DateTimeInterface $datetimeEnd = null;
 
-    #[ORM\Column(length: 50, nullable: false, enumType: VisibilityEnum::class)]
-    protected VisibilityEnum $visibility;
+    /** @var Collection<int, Equipment> */
+    #[ORM\ManyToMany(targetEntity: Equipment::class, cascade: [], orphanRemoval: false)]
+    #[ORM\JoinTable(name: 'booking_equipment')]
+    #[ORM\JoinColumn(name: 'booking_id')]
+    #[ORM\InverseJoinColumn(name: 'equipment_id')]
+    protected Collection $equipments;
 
     #[ORM\Column(unique: true)]
     protected string $uuid;
 
-    #[ORM\ManyToMany(targetEntity: Access::class, inversedBy: 'practicalCourses', cascade: [], orphanRemoval: false)]
-    protected Collection $organizer;
-
-    #[ORM\ManyToMany(targetEntity: Equipment::class, cascade: [], orphanRemoval: false)]
-    protected Collection $equipments;
-
+    /** @var Collection<int, Tagg> */
     #[ORM\ManyToMany(targetEntity: Tagg::class, inversedBy: 'bookings', cascade: ['persist'], orphanRemoval: false)]
+    #[ORM\JoinTable(name: 'tag_booking')]
+    #[ORM\JoinColumn(name: 'booking_id')]
+    #[ORM\InverseJoinColumn(name: 'tag_id')]
     protected Collection $tags;
 
     public function __construct()
@@ -83,73 +100,49 @@ abstract class AbstractBooking
         return $this;
     }
 
-    public function setDatetimeStart(?\DateTimeInterface $datetimeStart = null): self
-    {
-        $this->datetimeStart = $datetimeStart;
-
-        return $this;
-    }
-
-    public function getDatetimeStart(): ?\DateTimeInterface
+    public function getOrganizer(): Collection
     {
-        return $this->datetimeStart;
+        return $this->organizer;
     }
 
-    public function setDatetimeEnd(?\DateTimeInterface $datetimeEnd = null): self
+    public function addOrganizer(Access $organizer): self
     {
-        $this->datetimeEnd = $datetimeEnd;
+        if (!$this->organizer->contains($organizer)) {
+            $this->organizer[] = $organizer;
+        }
 
         return $this;
     }
 
-    public function getDatetimeEnd(): ?\DateTimeInterface
-    {
-        return $this->datetimeEnd;
-    }
-
-    public function getVisibility(): ?VisibilityEnum
-    {
-        return $this->visibility;
-    }
-
-    public function setVisibility(?VisibilityEnum $visibility): self
+    public function removeOrganizer(Access $organizer): self
     {
-        $this->visibility = $visibility;
+        $this->organizer->removeElement($organizer);
 
         return $this;
     }
 
-    public function getUuid(): string
-    {
-        return $this->uuid;
-    }
-
-    public function setUuid(string $uuid): self
+    public function setDatetimeStart(?\DateTimeInterface $datetimeStart = null): self
     {
-        $this->uuid = $uuid;
+        $this->datetimeStart = $datetimeStart;
 
         return $this;
     }
 
-    public function getOrganizer(): Collection
+    public function getDatetimeStart(): ?\DateTimeInterface
     {
-        return $this->organizer;
+        return $this->datetimeStart;
     }
 
-    public function addOrganizer(Access $organizer): self
+    public function setDatetimeEnd(?\DateTimeInterface $datetimeEnd = null): self
     {
-        if (!$this->organizer->contains($organizer)) {
-            $this->organizer[] = $organizer;
-        }
+        $this->datetimeEnd = $datetimeEnd;
 
         return $this;
     }
 
-    public function removeOrganizer(Access $organizer): self
+    public function getDatetimeEnd(): ?\DateTimeInterface
     {
-        $this->organizer->removeElement($organizer);
-
-        return $this;
+        return $this->datetimeEnd;
     }
 
     public function getEquipments(): Collection
@@ -159,9 +152,7 @@ abstract class AbstractBooking
 
     public function addEquipment(Equipment $equipment): self
     {
-        if (!$this->equipments->contains($equipment)) {
-            $this->equipments[] = $equipment;
-        }
+        $this->equipments[] = $equipment;
 
         return $this;
     }
@@ -173,6 +164,18 @@ abstract class AbstractBooking
         return $this;
     }
 
+    public function getUuid(): string
+    {
+        return $this->uuid;
+    }
+
+    public function setUuid(string $uuid): self
+    {
+        $this->uuid = $uuid;
+
+        return $this;
+    }
+
     public function getTags(): Collection
     {
         return $this->tags;
@@ -182,6 +185,7 @@ abstract class AbstractBooking
     {
         if (!$this->tags->contains($tag)) {
             $this->tags[] = $tag;
+            $tag->addBooking($this);
         }
 
         return $this;
@@ -189,7 +193,9 @@ abstract class AbstractBooking
 
     public function removeTag(Tagg $tag): self
     {
-        $this->tags->removeElement($tag);
+        if ($this->tags->removeElement($tag)) {
+            $tag->removeBooking($this);
+        }
 
         return $this;
     }

+ 15 - 1
src/Entity/Booking/AbstractBookingRecur.php

@@ -7,9 +7,23 @@ namespace App\Entity\Booking;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * Données de récurrence d'un évènement, classe de base des récurrences d'évènements.
+ *
+ * @see EventRecur, CourseRecur, EducationalProjectRecur, ExamenRecur, OrganizationHolidayRecur, PersonHolidayRecur
  */
 #[ORM\MappedSuperclass]
+#[ORM\Table(name: 'BookingRecur')]
+#[ORM\DiscriminatorColumn(name: 'discr', type: 'string')]
+#[ORM\DiscriminatorMap(
+    [
+        'educationalproject' => EducationalProjectRecur::class,
+        'course' => CourseRecur::class,
+        'event' => EventRecur::class,
+        'examen' => ExamenRecur::class,
+        'organizationholiday' => OrganizationHolidayRecur::class,
+        'personholiday' => PersonHolidayRecur::class,
+    ]
+)]
 abstract class AbstractBookingRecur
 {
     #[ORM\Id]

+ 6 - 5
src/Entity/Booking/Attendance.php

@@ -13,7 +13,7 @@ use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * Représente une période d'absence pour un Access dans une Organization.
  */
 #[ApiResource(operations: [])]
 // #[Auditable]
@@ -26,15 +26,16 @@ class Attendance
     private ?int $id = null;
 
     #[ORM\ManyToOne(inversedBy: 'attendances')]
-    private Organization $organization;
+    private ?Organization $organization = null;
 
     #[ORM\ManyToOne(inversedBy: 'attendances')]
-    private Access $access;
+    private ?Access $access = null;
 
     #[ORM\ManyToOne(inversedBy: 'attendanceReplacements')]
-    private Access $replacement;
+    private ?Access $replacement = null;
 
-    #[ORM\OneToMany(mappedBy: 'attendance', targetEntity: AttendanceBooking::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, AttendanceBooking> */
+    #[ORM\OneToMany(targetEntity: AttendanceBooking::class, mappedBy: 'attendance', cascade: ['persist'], orphanRemoval: true)]
     #[ORM\JoinColumn(nullable: false)]
     private Collection $attendanceBooking;
 

+ 8 - 8
src/Entity/Booking/AttendanceBooking.php

@@ -10,7 +10,7 @@ use App\Entity\Access\Access;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * Représente l'absence d'un Access à un type de Booking et à une date précise.
  */
 #[ApiResource(operations: [])]
 // #[Auditable]
@@ -23,26 +23,26 @@ class AttendanceBooking
     private ?int $id = null;
 
     #[ORM\ManyToOne(inversedBy: 'attendanceBookings')]
-    private Access $access;
+    private ?Access $access = null;
 
     #[ORM\ManyToOne(inversedBy: 'attendanceBooking')]
-    private Attendance $attendance;
+    private ?Attendance $attendance = null;
 
     #[ORM\ManyToOne(inversedBy: 'attendanceBooking')]
-    private Course $course;
+    private ?Course $course = null;
 
     #[ORM\ManyToOne(inversedBy: 'attendanceBooking')]
-    private EducationalProject $educationalProject;
+    private ?EducationalProject $educationalProject = null;
 
     #[ORM\ManyToOne(inversedBy: 'attendanceBooking')]
-    private Event $event;
+    private ?Event $event = null;
 
     #[ORM\ManyToOne(inversedBy: 'attendanceBooking')]
-    private Examen $examen;
+    private ?Examen $examen = null;
 
     #[ORM\ManyToOne(inversedBy: 'attendanceBookings')]
     #[ORM\JoinColumn(nullable: true)]
-    private ?AttendanceBookingReason $reason;
+    private ?AttendanceBookingReason $reason = null;
 
     public function getId(): ?int
     {

+ 2 - 1
src/Entity/Booking/AttendanceBookingReason.php

@@ -59,7 +59,8 @@ class AttendanceBookingReason
     #[ORM\Column(length: 255, nullable: false)]
     private string $reason;
 
-    #[ORM\OneToMany(mappedBy: 'reason', targetEntity: AttendanceBooking::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, AttendanceBooking> */
+    #[ORM\OneToMany(targetEntity: AttendanceBooking::class, mappedBy: 'reason', cascade: ['persist'], orphanRemoval: true)]
     private Collection $attendanceBookings;
 
     public function __construct()

+ 10 - 8
src/Entity/Booking/CalendarSynchro.php

@@ -5,14 +5,16 @@ declare(strict_types=1);
 namespace App\Entity\Booking;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use App\Entity\Access\Access;
 use App\Entity\Core\File;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * TODO: documenter.
  */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 class CalendarSynchro
 {
@@ -21,35 +23,35 @@ class CalendarSynchro
     #[ORM\GeneratedValue]
     private ?int $id = null;
 
-    #[ORM\OneToOne(inversedBy: 'calendarSynchro', targetEntity: Access::class, cascade: ['persist'])]
-    protected Access $access;
+    #[ORM\OneToOne(targetEntity: Access::class, inversedBy: 'calendarSynchro', cascade: ['persist'])]
+    protected ?Access $access;
 
     #[ORM\OneToOne(inversedBy: 'calendarSynchro', targetEntity: File::class, cascade: ['persist'])]
-    protected File $file;
+    protected ?File $file;
 
     public function getId(): ?int
     {
         return $this->id;
     }
 
-    public function getAccess(): Access
+    public function getAccess(): ?Access
     {
         return $this->access;
     }
 
-    public function setAccess(Access $access): self
+    public function setAccess(?Access $access): self
     {
         $this->access = $access;
 
         return $this;
     }
 
-    public function getFile(): File
+    public function getFile(): ?File
     {
         return $this->file;
     }
 
-    public function setFile(File $file): self
+    public function setFile(?File $file): self
     {
         $this->file = $file;
 

+ 20 - 121
src/Entity/Booking/Course.php

@@ -7,13 +7,11 @@ namespace App\Entity\Booking;
 use ApiPlatform\Metadata\ApiResource;
 use App\Entity\Access\Access;
 use App\Entity\AccessWish\EducationStudentWish;
-use App\Entity\Core\Tagg;
 use App\Entity\Education\Education;
 use App\Entity\Education\EducationCurriculum;
 use App\Entity\Organization\Organization;
-use App\Entity\Place\AbstractPlace;
+use App\Entity\Place\Place;
 use App\Entity\Place\Room;
-use App\Entity\Product\Equipment;
 use App\Repository\Booking\CourseRepository;
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
 use Doctrine\Common\Collections\ArrayCollection;
@@ -36,31 +34,24 @@ use Doctrine\ORM\Mapping as ORM;
 #[ORM\Table(name: 'Booking')]
 class Course extends AbstractBooking
 {
-    #[ORM\Column(length: 255, nullable: false)]
-    protected string $discr = 'course';
-
-    #[ORM\OneToMany(mappedBy: 'event', targetEntity: CourseRecur::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, CourseRecur> */
+    #[ORM\OneToMany(targetEntity: CourseRecur::class, mappedBy: 'event', cascade: ['persist'], orphanRemoval: true)]
     protected Collection $eventRecur;
 
-    #[ORM\OneToMany(mappedBy: 'parent', targetEntity: Course::class, orphanRemoval: true)]
+    /** @var Collection<int, Course> */
+    #[ORM\OneToMany(targetEntity: Course::class, mappedBy: 'parent', orphanRemoval: true)]
     protected Collection $timeline;
 
     #[ORM\ManyToOne(inversedBy: 'timeline')]
-    protected Course $parent;
+    protected ?Course $parent;
 
     #[ORM\ManyToOne(inversedBy: 'courses')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    protected AbstractPlace $place;
+    protected ?Place $place = null;
 
     #[ORM\ManyToOne(inversedBy: 'courses')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    protected Room $room;
-
-    #[ORM\ManyToMany(targetEntity: Access::class, inversedBy: 'practicalCourses')]
-    #[ORM\JoinTable(name: 'booking_organizer')]
-    #[ORM\JoinColumn(name: 'booking_id', referencedColumnName: 'id')]
-    #[ORM\InverseJoinColumn(name: 'organizer_id', referencedColumnName: 'id')]
-    protected Collection $organizer;
+    protected ?Room $room = null;
 
     #[ORM\ManyToOne(inversedBy: 'courses')]
     #[ORM\JoinColumn(nullable: false)]
@@ -68,37 +59,30 @@ class Course extends AbstractBooking
 
     #[ORM\ManyToOne(inversedBy: 'courses')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    protected Education $education;
+    protected ?Education $education = null;
 
-    #[ORM\ManyToMany(targetEntity: EducationCurriculum::class)]
+    /** @var Collection<int, EducationCurriculum> */
+    #[ORM\ManyToMany(targetEntity: EducationCurriculum::class, inversedBy: 'courses', cascade: ['persist'])]
     protected Collection $educationCurriculum;
 
+    /** @var Collection<int, Access> */
     #[ORM\ManyToMany(targetEntity: Access::class, inversedBy: 'courses')]
     #[ORM\JoinTable(name: 'course_student')]
     #[ORM\JoinColumn(name: 'course_id', referencedColumnName: 'id')]
     #[ORM\InverseJoinColumn(name: 'student_id', referencedColumnName: 'id')]
     protected Collection $students;
 
-    #[ORM\OneToMany(mappedBy: 'course', targetEntity: Work::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, Work> */
+    #[ORM\OneToMany(targetEntity: Work::class, mappedBy: 'course', cascade: ['persist'], orphanRemoval: true)]
     protected Collection $work;
 
-    #[ORM\ManyToMany(targetEntity: Equipment::class)]
-    #[ORM\JoinTable(name: 'booking_equipment')]
-    #[ORM\JoinColumn(name: 'booking_id', referencedColumnName: 'id')]
-    #[ORM\InverseJoinColumn(name: 'equipment_id', referencedColumnName: 'id')]
-    protected Collection $equipments;
-
-    #[ORM\OneToMany(mappedBy: 'course', targetEntity: AttendanceBooking::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, AttendanceBooking> */
+    #[ORM\OneToMany(targetEntity: AttendanceBooking::class, mappedBy: 'course', cascade: ['persist'], orphanRemoval: true)]
     #[ORM\JoinColumn(nullable: false)]
     protected Collection $attendanceBooking;
 
-    #[ORM\ManyToMany(targetEntity: Tagg::class, inversedBy: 'courses', cascade: ['persist'])]
-    #[ORM\JoinTable(name: 'tag_booking')]
-    #[ORM\JoinColumn(name: 'booking_id', referencedColumnName: 'id')]
-    #[ORM\InverseJoinColumn(name: 'tag_id', referencedColumnName: 'id')]
-    protected Collection $tags;
-
-    #[ORM\OneToMany(mappedBy: 'course', targetEntity: EducationStudentWish::class, cascade: [], orphanRemoval: false)]
+    /** @var Collection<int, EducationStudentWish> */
+    #[ORM\OneToMany(targetEntity: EducationStudentWish::class, mappedBy: 'course', cascade: [], orphanRemoval: false)]
     protected Collection $educationStudentWishes;
 
     public function __construct()
@@ -111,23 +95,10 @@ class Course extends AbstractBooking
         $this->work = new ArrayCollection();
         $this->equipments = new ArrayCollection();
         $this->attendanceBooking = new ArrayCollection();
-        $this->tags = new ArrayCollection();
         $this->educationStudentWishes = new ArrayCollection();
         parent::__construct();
     }
 
-    public function getDiscr(): ?string
-    {
-        return $this->discr;
-    }
-
-    public function setDiscr(string $discr): self
-    {
-        $this->discr = $discr;
-
-        return $this;
-    }
-
     /**
      * @return Collection<int, CourseRecur>
      */
@@ -200,12 +171,12 @@ class Course extends AbstractBooking
         return $this;
     }
 
-    public function getPlace(): ?AbstractPlace
+    public function getPlace(): ?Place
     {
         return $this->place;
     }
 
-    public function setPlace(?AbstractPlace $place): self
+    public function setPlace(?Place $place): self
     {
         $this->place = $place;
 
@@ -224,30 +195,6 @@ class Course extends AbstractBooking
         return $this;
     }
 
-    /**
-     * @return Collection<int, Access>
-     */
-    public function getOrganizer(): Collection
-    {
-        return $this->organizer;
-    }
-
-    public function addOrganizer(Access $organizer): self
-    {
-        if (!$this->organizer->contains($organizer)) {
-            $this->organizer[] = $organizer;
-        }
-
-        return $this;
-    }
-
-    public function removeOrganizer(Access $organizer): self
-    {
-        $this->organizer->removeElement($organizer);
-
-        return $this;
-    }
-
     public function getOrganization(): ?Organization
     {
         return $this->organization;
@@ -350,30 +297,6 @@ class Course extends AbstractBooking
         return $this;
     }
 
-    /**
-     * @return Collection<int, Equipment>
-     */
-    public function getEquipments(): Collection
-    {
-        return $this->equipments;
-    }
-
-    public function addEquipment(Equipment $equipment): self
-    {
-        if (!$this->equipments->contains($equipment)) {
-            $this->equipments[] = $equipment;
-        }
-
-        return $this;
-    }
-
-    public function removeEquipment(Equipment $equipment): self
-    {
-        $this->equipments->removeElement($equipment);
-
-        return $this;
-    }
-
     /**
      * @return Collection<int, AttendanceBooking>
      */
@@ -404,30 +327,6 @@ class Course extends AbstractBooking
         return $this;
     }
 
-    /**
-     * @return Collection<int, Tagg>
-     */
-    public function getTags(): Collection
-    {
-        return $this->tags;
-    }
-
-    public function addTag(Tagg $tag): self
-    {
-        if (!$this->tags->contains($tag)) {
-            $this->tags[] = $tag;
-        }
-
-        return $this;
-    }
-
-    public function removeTag(Tagg $tag): self
-    {
-        $this->tags->removeElement($tag);
-
-        return $this;
-    }
-
     public function getEducationStudentWishes(): Collection
     {
         return $this->educationStudentWishes;

+ 5 - 18
src/Entity/Booking/CourseRecur.php

@@ -5,35 +5,22 @@ declare(strict_types=1);
 namespace App\Entity\Booking;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
  * @todo : A la suite de la migration, il faut supprimer le nom de la table pour avoir une table CourseRecur, et supprimer l'attribut discr.
  *
- * Classe ... qui ...
+ * Cours récurrent
  */
 // #[Auditable]
-#[ORM\Table(name: 'BookingRecur')]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
+#[ORM\Table(name: 'BookingRecur')]
 class CourseRecur extends AbstractBookingRecur
 {
-    #[ORM\Column(length: 255, nullable: false)]
-    protected string $discr = 'course';
-
     #[ORM\ManyToOne(inversedBy: 'eventRecur')]
-    private Course $event;
-
-    public function getDiscr(): ?string
-    {
-        return $this->discr;
-    }
-
-    public function setDiscr(string $discr): self
-    {
-        $this->discr = $discr;
-
-        return $this;
-    }
+    private ?Course $event = null;
 
     public function getEvent(): ?Course
     {

+ 28 - 73
src/Entity/Booking/EducationalProject.php

@@ -10,9 +10,8 @@ use App\Entity\Billing\BillLine;
 use App\Entity\Billing\EducationalProjectIntangible;
 use App\Entity\Billing\EducationalProjectPayer;
 use App\Entity\Core\File;
-use App\Entity\Core\Tagg;
 use App\Entity\Organization\Organization;
-use App\Entity\Place\AbstractPlace;
+use App\Entity\Place\Place;
 use App\Entity\Place\Room;
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
 use Doctrine\Common\Collections\ArrayCollection;
@@ -22,25 +21,24 @@ use Doctrine\ORM\Mapping as ORM;
 /**
  * @todo : A la suite de la migration, il faut supprimer le nom de la table pour avoir une table EducationalProject, et supprimer l'attribut discr.
  * @todo : migration table tag_booking
- * Classe ... qui ...
+ * Prestation pédagogique
  */
 #[ApiResource(operations: [])]
 // #[Auditable]
-#[ORM\Table(name: 'Booking')]
 #[ORM\Entity]
+#[ORM\Table(name: 'Booking')]
 class EducationalProject extends AbstractBooking
 {
-    #[ORM\Column(length: 255, nullable: false)]
-    protected string $discr = 'educationalproject';
-
-    #[ORM\OneToMany(mappedBy: 'event', targetEntity: EducationalProjectRecur::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, EducationalProjectRecur> */
+    #[ORM\OneToMany(targetEntity: EducationalProjectRecur::class, mappedBy: 'event', cascade: ['persist'], orphanRemoval: true)]
     protected Collection $eventRecur;
 
-    #[ORM\OneToMany(mappedBy: 'parent', targetEntity: EducationalProject::class, orphanRemoval: true)]
+    /** @var Collection<int, EducationalProject> */
+    #[ORM\OneToMany(targetEntity: EducationalProject::class, mappedBy: 'parent', orphanRemoval: true)]
     protected Collection $timeline;
 
     #[ORM\ManyToOne(inversedBy: 'timeline')]
-    protected EducationalProject $parent;
+    protected ?EducationalProject $parent = null;
 
     #[ORM\ManyToOne(inversedBy: 'educationalProjects')]
     #[ORM\JoinColumn(nullable: false)]
@@ -48,58 +46,52 @@ class EducationalProject extends AbstractBooking
 
     #[ORM\ManyToOne(inversedBy: 'silentPartners')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    protected Access $silentPartner;
+    protected ?Access $silentPartner = null;
 
     #[ORM\ManyToOne(inversedBy: 'educationalProjects')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    protected EducationalProjectPublic $public;
+    protected ?EducationalProjectPublic $public = null;
 
     #[ORM\ManyToOne(inversedBy: 'operationalPartners')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    protected Access $operationalPartner;
+    protected ?Access $operationalPartner = null;
 
+    /** @var Collection<int, Access> */
     #[ORM\ManyToMany(targetEntity: Access::class)]
     #[ORM\JoinTable(name: 'educationalproject_financier')]
     protected Collection $financiers;
 
+    /** @var Collection<int, File> */
     #[ORM\ManyToMany(targetEntity: File::class)]
     protected Collection $files;
 
-    #[ORM\OneToMany(mappedBy: 'educationalProject', targetEntity: EducationalProjectIntangible::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, EducationalProjectIntangible> */
+    #[ORM\OneToMany(targetEntity: EducationalProjectIntangible::class, mappedBy: 'educationalProject', cascade: ['persist'], orphanRemoval: true)]
     protected Collection $educationalProjectIntangibles;
 
-    #[ORM\OneToMany(mappedBy: 'educationalProjectReceiver', targetEntity: EducationalProjectPayer::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, EducationalProjectPayer> */
+    #[ORM\OneToMany(targetEntity: EducationalProjectPayer::class, mappedBy: 'educationalProjectReceiver', cascade: ['persist'], orphanRemoval: true)]
     protected Collection $billingReceivers;
 
-    #[ORM\OneToMany(mappedBy: 'educationalProject', targetEntity: BillLine::class, orphanRemoval: true)]
+    /** @var Collection<int, BillLine> */
+    #[ORM\OneToMany(targetEntity: BillLine::class, mappedBy: 'educationalProject', orphanRemoval: true)]
     protected Collection $billLines;
 
-    #[ORM\OneToMany(mappedBy: 'educationalProject', targetEntity: AttendanceBooking::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, AttendanceBooking> */
+    #[ORM\OneToMany(targetEntity: AttendanceBooking::class, mappedBy: 'educationalProject', cascade: ['persist'], orphanRemoval: true)]
     #[ORM\JoinColumn(nullable: false)]
     protected Collection $attendanceBooking;
 
     #[ORM\ManyToOne(inversedBy: 'educationalProjects')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    protected AbstractPlace $place;
+    protected ?Place $place = null;
 
     #[ORM\ManyToOne(inversedBy: 'educationalProjects')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    protected Room $room;
-
-    #[ORM\ManyToMany(targetEntity: Access::class, inversedBy: 'educationalProjectOrganizers')]
-    #[ORM\JoinTable(name: 'booking_organizer')]
-    #[ORM\JoinColumn(name: 'booking_id', referencedColumnName: 'id')]
-    #[ORM\InverseJoinColumn(name: 'organizer_id', referencedColumnName: 'id')]
-    protected Collection $organizer;
-
-    #[ORM\ManyToMany(targetEntity: Tagg::class, inversedBy: 'educationalProjects', cascade: ['persist'])]
-    #[ORM\JoinTable(name: 'tag_booking')]
-    #[ORM\JoinColumn(name: 'booking_id', referencedColumnName: 'id')]
-    #[ORM\InverseJoinColumn(name: 'tag_id', referencedColumnName: 'id')]
-    protected Collection $tags;
+    protected ?Room $room = null;
 
     #[ORM\OneToOne(targetEntity: EducationalProjectAge::class, cascade: ['persist'])]
-    protected EducationalProjectAge $ageDistribution;
+    protected ?EducationalProjectAge $ageDistribution;
 
     public function __construct()
     {
@@ -112,23 +104,10 @@ class EducationalProject extends AbstractBooking
         $this->billLines = new ArrayCollection();
         $this->attendanceBooking = new ArrayCollection();
         $this->organizer = new ArrayCollection();
-        $this->tags = new ArrayCollection();
         $this->equipments = new ArrayCollection();
         parent::__construct();
     }
 
-    public function getDiscr(): ?string
-    {
-        return $this->discr;
-    }
-
-    public function setDiscr(string $discr): self
-    {
-        $this->discr = $discr;
-
-        return $this;
-    }
-
     /**
      * @return Collection<int, EducationalProjectRecur>
      */
@@ -417,12 +396,12 @@ class EducationalProject extends AbstractBooking
         return $this;
     }
 
-    public function getPlace(): ?AbstractPlace
+    public function getPlace(): ?Place
     {
         return $this->place;
     }
 
-    public function setPlace(?AbstractPlace $place): self
+    public function setPlace(?Place $place): self
     {
         $this->place = $place;
 
@@ -465,36 +444,12 @@ class EducationalProject extends AbstractBooking
         return $this;
     }
 
-    /**
-     * @return Collection<int, Tagg>
-     */
-    public function getTags(): Collection
-    {
-        return $this->tags;
-    }
-
-    public function addTag(Tagg $tag): self
-    {
-        if (!$this->tags->contains($tag)) {
-            $this->tags[] = $tag;
-        }
-
-        return $this;
-    }
-
-    public function removeTag(Tagg $tag): self
-    {
-        $this->tags->removeElement($tag);
-
-        return $this;
-    }
-
-    public function getAgeDistribution(): EducationalProjectAge
+    public function getAgeDistribution(): ?EducationalProjectAge
     {
         return $this->ageDistribution;
     }
 
-    public function setAgeDistribution(EducationalProjectAge $ageDistribution): self
+    public function setAgeDistribution(?EducationalProjectAge $ageDistribution): self
     {
         $this->ageDistribution = $ageDistribution;
 

+ 5 - 0
src/Entity/Booking/EducationalProjectAge.php

@@ -5,10 +5,15 @@ declare(strict_types=1);
 namespace App\Entity\Booking;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use Doctrine\ORM\Mapping as ORM;
 use Symfony\Component\Serializer\Annotation\Groups;
 
+/**
+ * Répartition des âges dans une prestation pédagogique EducationnalProject.
+ */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 class EducationalProjectAge
 {

+ 7 - 1
src/Entity/Booking/EducationalProjectPublic.php

@@ -5,11 +5,16 @@ declare(strict_types=1);
 namespace App\Entity\Booking;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
+/**
+ * Type de public d'une prestation pédagogique EducationnalProject.
+ */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 class EducationalProjectPublic
 {
@@ -18,7 +23,8 @@ class EducationalProjectPublic
     #[ORM\GeneratedValue]
     private ?int $id = null;
 
-    #[ORM\OneToMany(mappedBy: 'public', targetEntity: EducationalProject::class, )]
+    /** @var Collection<int, EducationalProject> */
+    #[ORM\OneToMany(targetEntity: EducationalProject::class, mappedBy: 'public', )]
     private Collection $educationalProjects;
 
     public function __construct()

+ 6 - 17
src/Entity/Booking/EducationalProjectRecur.php

@@ -5,33 +5,22 @@ declare(strict_types=1);
 namespace App\Entity\Booking;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
+ * TODO: documenter.
+ *
  * @todo : A la suite de la migration, il faut supprimer le nom de la table pour avoir une table EducationalProjectRecur, et supprimer l'attribut discr.
  */
 // #[Auditable]
-#[ORM\Table(name: 'BookingRecur')]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
+#[ORM\Table(name: 'BookingRecur')]
 class EducationalProjectRecur extends AbstractBookingRecur
 {
-    #[ORM\Column(length: 255, nullable: false)]
-    protected string $discr = 'educationalproject';
-
     #[ORM\ManyToOne(inversedBy: 'eventRecur')]
-    private EducationalProject $event;
-
-    public function getDiscr(): ?string
-    {
-        return $this->discr;
-    }
-
-    public function setDiscr(string $discr): self
-    {
-        $this->discr = $discr;
-
-        return $this;
-    }
+    private ?EducationalProject $event = null;
 
     public function getEvent(): ?EducationalProject
     {

+ 23 - 104
src/Entity/Booking/Event.php

@@ -5,12 +5,10 @@ declare(strict_types=1);
 namespace App\Entity\Booking;
 
 use ApiPlatform\Metadata\ApiResource;
-use App\Entity\Access\Access;
 use App\Entity\Core\Categories;
 use App\Entity\Core\File;
-use App\Entity\Core\Tagg;
 use App\Entity\Organization\Organization;
-use App\Entity\Place\AbstractPlace;
+use App\Entity\Place\Place;
 use App\Entity\Place\PlaceSystem;
 use App\Entity\Place\Room;
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
@@ -22,6 +20,8 @@ use Symfony\Component\Validator\Constraints as Assert;
 /**
  * @todo : A la suite de la migration, il faut supprimer le nom de la table pour avoir une table Event, et supprimer l'attribut discr.
  * @todo : migration table tag_booking
+ *
+ * Évènement, rencontre
  */
 #[ApiResource(operations: [])]
 // #[Auditable]
@@ -29,48 +29,51 @@ use Symfony\Component\Validator\Constraints as Assert;
 #[ORM\Table(name: 'Booking')]
 class Event extends AbstractBooking
 {
-    #[ORM\Column(length: 255, nullable: false)]
-    protected string $discr = 'event';
-
     #[ORM\ManyToOne(inversedBy: 'events')]
     #[ORM\JoinColumn(nullable: false)]
     protected Organization $organization;
 
     #[ORM\ManyToOne(inversedBy: 'events')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    protected AbstractPlace $place;
+    protected ?Place $place;
 
     #[ORM\ManyToOne(inversedBy: 'events')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    protected Room $room;
+    protected ?Room $room = null;
 
-    #[ORM\OneToMany(mappedBy: 'event', targetEntity: EventRecur::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, EventRecur> */
+    #[ORM\OneToMany(targetEntity: EventRecur::class, mappedBy: 'event', cascade: ['persist'], orphanRemoval: true)]
     protected Collection $eventRecur;
 
-    #[ORM\OneToMany(mappedBy: 'parent', targetEntity: Event::class, orphanRemoval: true)]
+    /** @var Collection<int, Event> */
+    #[ORM\OneToMany(targetEntity: Event::class, mappedBy: 'parent', orphanRemoval: true)]
     protected Collection $timeline;
 
     #[ORM\ManyToOne(inversedBy: 'timeline')]
-    protected Event $parent;
+    protected ?Event $parent;
 
     #[Assert\Valid]
     #[ORM\ManyToOne(cascade: ['persist'], inversedBy: 'events')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    protected File $image;
+    protected ?File $image;
 
     #[ORM\ManyToOne]
-    protected EventGender $gender;
+    protected ?EventGender $gender;
 
+    /** @var Collection<int, EventUser> */
     #[Assert\Valid]
-    #[ORM\OneToMany(mappedBy: 'event', targetEntity: EventUser::class, cascade: ['persist'], orphanRemoval: true)]
+    #[ORM\OneToMany(targetEntity: EventUser::class, mappedBy: 'event', cascade: ['persist'], orphanRemoval: true)]
     protected Collection $eventUser;
 
+    /** @var Collection<int, Categories> */
     #[ORM\ManyToMany(targetEntity: Categories::class, cascade: ['persist'])]
     protected Collection $categories;
 
-    #[ORM\OneToMany(mappedBy: 'event', targetEntity: EventReport::class, orphanRemoval: true)]
+    /** @var Collection<int, EventReport> */
+    #[ORM\OneToMany(targetEntity: EventReport::class, mappedBy: 'event', orphanRemoval: true)]
     protected Collection $eventReports;
 
+    /** @var Collection<int, File> */
     #[ORM\ManyToMany(targetEntity: File::class, cascade: ['persist'], orphanRemoval: true)]
     #[ORM\JoinTable(name: 'event_files')]
     #[ORM\JoinColumn(name: 'event_id', referencedColumnName: 'id', onDelete: 'cascade')]
@@ -79,24 +82,13 @@ class Event extends AbstractBooking
 
     #[ORM\ManyToOne]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    protected PlaceSystem $placeSystem;
+    protected ?PlaceSystem $placeSystem;
 
-    #[ORM\OneToMany(mappedBy: 'event', targetEntity: AttendanceBooking::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, AttendanceBooking> */
+    #[ORM\OneToMany(targetEntity: AttendanceBooking::class, mappedBy: 'event', cascade: ['persist'], orphanRemoval: true)]
     #[ORM\JoinColumn(nullable: false)]
     protected Collection $attendanceBooking;
 
-    #[ORM\ManyToMany(targetEntity: Access::class, inversedBy: 'eventOrganizers')]
-    #[ORM\JoinTable(name: 'booking_organizer')]
-    #[ORM\JoinColumn(name: 'booking_id', referencedColumnName: 'id')]
-    #[ORM\InverseJoinColumn(name: 'organizer_id', referencedColumnName: 'id')]
-    protected Collection $organizer;
-
-    #[ORM\ManyToMany(targetEntity: Tagg::class, inversedBy: 'events', cascade: ['persist'])]
-    #[ORM\JoinTable(name: 'tag_booking')]
-    #[ORM\JoinColumn(name: 'booking_id', referencedColumnName: 'id')]
-    #[ORM\InverseJoinColumn(name: 'tag_id', referencedColumnName: 'id')]
-    protected Collection $tags;
-
     public function __construct()
     {
         $this->eventRecur = new ArrayCollection();
@@ -107,23 +99,10 @@ class Event extends AbstractBooking
         $this->files = new ArrayCollection();
         $this->attendanceBooking = new ArrayCollection();
         $this->organizer = new ArrayCollection();
-        $this->tags = new ArrayCollection();
         $this->equipments = new ArrayCollection();
         parent::__construct();
     }
 
-    public function getDiscr(): ?string
-    {
-        return $this->discr;
-    }
-
-    public function setDiscr(string $discr): self
-    {
-        $this->discr = $discr;
-
-        return $this;
-    }
-
     public function getOrganization(): ?Organization
     {
         return $this->organization;
@@ -136,12 +115,12 @@ class Event extends AbstractBooking
         return $this;
     }
 
-    public function getPlace(): ?AbstractPlace
+    public function getPlace(): ?Place
     {
         return $this->place;
     }
 
-    public function setPlace(?AbstractPlace $place): self
+    public function setPlace(?Place $place): self
     {
         $this->place = $place;
 
@@ -405,64 +384,4 @@ class Event extends AbstractBooking
 
         return $this;
     }
-
-    /**
-     * @return Collection<int, Access>
-     */
-    public function getOrganizer(): Collection
-    {
-        return $this->organizer;
-    }
-
-    public function addOrganizer(Access $organizer): self
-    {
-        if (!$this->organizer->contains($organizer)) {
-            $this->organizer[] = $organizer;
-        }
-
-        return $this;
-    }
-
-    public function removeOrganizer(Access $organizer): self
-    {
-        $this->organizer->removeElement($organizer);
-
-        return $this;
-    }
-
-    /**
-     * @return Collection<int, Tagg>
-     */
-    public function getTags(): Collection
-    {
-        return $this->tags;
-    }
-
-    public function addTag(Tagg $tag): self
-    {
-        if (!$this->tags->contains($tag)) {
-            $this->tags[] = $tag;
-        }
-
-        return $this;
-    }
-
-    public function removeTag(Tagg $tag): self
-    {
-        $this->tags->removeElement($tag);
-
-        return $this;
-    }
-
-    public function getEquipments(): Collection
-    {
-        return $this->equipments;
-    }
-
-    public function setEquipments(Collection $equipments): self
-    {
-        $this->equipments = $equipments;
-
-        return $this;
-    }
 }

+ 5 - 0
src/Entity/Booking/EventGender.php

@@ -5,9 +5,14 @@ declare(strict_types=1);
 namespace App\Entity\Booking;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use Doctrine\ORM\Mapping as ORM;
 
+/**
+ * Enum des genres d'évènements.
+ */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 class EventGender
 {

+ 5 - 16
src/Entity/Booking/EventRecur.php

@@ -5,33 +5,22 @@ declare(strict_types=1);
 namespace App\Entity\Booking;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
  * @todo : A la suite de la migration, il faut supprimer le nom de la table pour avoir une table EventRecur, et supprimer l'attribut discr.
+ *
+ * Évènement récurrent
  */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 #[ORM\Table(name: 'BookingRecur')]
 class EventRecur extends AbstractBookingRecur
 {
-    #[ORM\Column(length: 255, nullable: false)]
-    protected string $discr = 'event';
-
     #[ORM\ManyToOne(inversedBy: 'eventRecur')]
-    private Event $event;
-
-    public function getDiscr(): ?string
-    {
-        return $this->discr;
-    }
-
-    public function setDiscr(string $discr): self
-    {
-        $this->discr = $discr;
-
-        return $this;
-    }
+    private ?Event $event = null;
 
     public function getEvent(): ?Event
     {

+ 8 - 2
src/Entity/Booking/EventReport.php

@@ -4,13 +4,18 @@ declare(strict_types=1);
 
 namespace App\Entity\Booking;
 
+use ApiPlatform\Metadata\ApiResource;
 use App\Entity\Core\File;
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
+/**
+ * Compte-rendu d'un évènement Event.
+ */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 class EventReport
 {
@@ -20,9 +25,10 @@ class EventReport
     private ?int $id = null;
 
     #[ORM\ManyToOne(inversedBy: 'eventReports')]
-    private Event $event;
+    private ?Event $event = null;
 
-    #[ORM\OneToMany(mappedBy: 'eventReport', targetEntity: File::class, orphanRemoval: true)]
+    /** @var Collection<int, File> */
+    #[ORM\OneToMany(targetEntity: File::class, mappedBy: 'eventReport', orphanRemoval: true)]
     private Collection $files;
 
     public function __construct()

+ 3 - 3
src/Entity/Booking/EventUser.php

@@ -10,7 +10,7 @@ use App\Entity\Access\Access;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * Participation d'un Access à un Event.
  */
 #[ApiResource(operations: [])]
 // #[Auditable]
@@ -23,10 +23,10 @@ class EventUser
     private ?int $id = null;
 
     #[ORM\ManyToOne(inversedBy: 'eventUser')]
-    private Event $event;
+    private ?Event $event = null;
 
     #[ORM\ManyToOne(inversedBy: 'eventUsers')]
-    private Access $guest;
+    private ?Access $guest = null;
 
     public function getId(): ?int
     {

+ 44 - 39
src/Entity/Booking/Examen.php

@@ -10,9 +10,10 @@ use App\Entity\Education\Education;
 use App\Entity\Education\EducationCurriculum;
 use App\Entity\Organization\Jury;
 use App\Entity\Organization\Organization;
-use App\Entity\Place\AbstractPlace;
+use App\Entity\Place\Place;
 use App\Entity\Place\Room;
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use App\Entity\Product\Equipment;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
@@ -20,7 +21,7 @@ use Doctrine\ORM\Mapping as ORM;
 /**
  * @todo : A la suite de la migration, il faut supprimer le nom de la table pour avoir une table Examen, et supprimer l'attribut discr.
  * @todo : migration table tag_booking
- * Classe ... qui ...
+ * Examen
  */
 #[ApiResource(operations: [])]
 // #[Auditable]
@@ -28,79 +29,59 @@ use Doctrine\ORM\Mapping as ORM;
 #[ORM\Table(name: 'Booking')]
 class Examen extends AbstractBooking
 {
-    #[ORM\Column(length: 255, nullable: false)]
-    protected string $discr = 'examen';
-
     #[ORM\ManyToOne(inversedBy: 'examens')]
     #[ORM\JoinColumn(nullable: false)]
     protected Organization $organization;
 
-    #[ORM\OneToMany(mappedBy: 'event', targetEntity: ExamenRecur::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, ExamenRecur> */
+    #[ORM\OneToMany(targetEntity: ExamenRecur::class, mappedBy: 'event', cascade: ['persist'], orphanRemoval: true)]
     protected Collection $eventRecur;
 
-    #[ORM\OneToMany(mappedBy: 'parent', targetEntity: Examen::class, orphanRemoval: true)]
+    /** @var Collection<int, Examen> */
+    #[ORM\OneToMany(targetEntity: Examen::class, mappedBy: 'parent', orphanRemoval: true)]
     protected Collection $timeline;
 
     #[ORM\ManyToOne(inversedBy: 'timeline')]
-    protected Examen $parent;
+    protected ?Examen $parent;
 
     #[ORM\ManyToOne(cascade: ['persist'], inversedBy: 'examens')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    protected Jury $jury;
+    protected ?Jury $jury;
 
     #[ORM\ManyToOne(inversedBy: 'examens')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    protected Education $education;
+    protected ?Education $education;
 
-    #[ORM\ManyToMany(targetEntity: EducationCurriculum::class)]
+    /** @var Collection<int, EducationCurriculum> */
+    #[ORM\ManyToMany(targetEntity: EducationCurriculum::class, inversedBy: 'examens', cascade: ['persist'])]
     protected Collection $educationCurriculum;
 
-    #[ORM\OneToMany(mappedBy: 'examen', targetEntity: ExamenConvocation::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, ExamenConvocation> */
+    #[ORM\OneToMany(targetEntity: ExamenConvocation::class, mappedBy: 'examen', cascade: ['persist'], orphanRemoval: true)]
     protected Collection $convocation;
 
-    #[ORM\OneToMany(mappedBy: 'examen', targetEntity: AttendanceBooking::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, AttendanceBooking> */
+    #[ORM\OneToMany(targetEntity: AttendanceBooking::class, mappedBy: 'examen', cascade: ['persist'], orphanRemoval: true)]
     #[ORM\JoinColumn(nullable: false)]
     protected Collection $attendanceBooking;
 
     #[ORM\ManyToOne(inversedBy: 'examens')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    protected AbstractPlace $place;
+    protected ?Place $place;
 
     #[ORM\ManyToOne(inversedBy: 'examens')]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
-    protected Room $room;
-
-    #[ORM\ManyToMany(targetEntity: Tagg::class, inversedBy: 'examens', cascade: ['persist'])]
-    #[ORM\JoinTable(name: 'tag_booking')]
-    #[ORM\JoinColumn(name: 'booking_id', referencedColumnName: 'id')]
-    #[ORM\InverseJoinColumn(name: 'tag_id', referencedColumnName: 'id')]
-    protected Collection $tags;
+    protected ?Room $room = null;
 
     public function __construct()
     {
-        $this->eventRecur = new ArrayCollection();
         $this->timeline = new ArrayCollection();
         $this->educationCurriculum = new ArrayCollection();
         $this->convocation = new ArrayCollection();
         $this->attendanceBooking = new ArrayCollection();
-        $this->tags = new ArrayCollection();
-        $this->organizer = new ArrayCollection();
-        $this->equipments = new ArrayCollection();
         parent::__construct();
     }
 
-    public function getDiscr(): ?string
-    {
-        return $this->discr;
-    }
-
-    public function setDiscr(string $discr): self
-    {
-        $this->discr = $discr;
-
-        return $this;
-    }
-
     public function getOrganization(): ?Organization
     {
         return $this->organization;
@@ -293,12 +274,12 @@ class Examen extends AbstractBooking
         return $this;
     }
 
-    public function getPlace(): ?AbstractPlace
+    public function getPlace(): ?Place
     {
         return $this->place;
     }
 
-    public function setPlace(?AbstractPlace $place): self
+    public function setPlace(?Place $place): self
     {
         $this->place = $place;
 
@@ -317,6 +298,30 @@ class Examen extends AbstractBooking
         return $this;
     }
 
+    public function getEquipments(): Collection
+    {
+        return $this->equipments;
+    }
+
+    public function addEquipment(Equipment $equipment): self
+    {
+        if (!$this->equipments->contains($equipment)) {
+            $this->equipments[] = $equipment;
+            //            $equipment->addXXX($this);
+        }
+
+        return $this;
+    }
+
+    public function removeEquipment(Equipment $equipment): self
+    {
+        if ($this->equipments->removeElement($equipment)) {
+            //            $equipment->removeXXXX($this);
+        }
+
+        return $this;
+    }
+
     /**
      * @return Collection<int, Tagg>
      */

+ 3 - 2
src/Entity/Booking/ExamenConvocation.php

@@ -13,7 +13,7 @@ use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * Convocation d'un Access (élève) à un Examen.
  */
 // #[Auditable]
 #[ApiResource(operations: [])]
@@ -27,12 +27,13 @@ class ExamenConvocation
     private ?int $id = null;
 
     #[ORM\ManyToOne(inversedBy: 'convocation')]
-    private Examen $examen;
+    private ?Examen $examen = null;
 
     #[ORM\ManyToOne(inversedBy: 'examenConvocations')]
     #[ORM\JoinColumn(nullable: false)]
     private Access $student;
 
+    /** @var Collection<int, Equipment> */
     #[ORM\ManyToMany(targetEntity: Equipment::class)]
     #[ORM\JoinColumn(name: 'examenconvocation_id', referencedColumnName: 'id')]
     #[ORM\InverseJoinColumn(name: 'equipment_id', referencedColumnName: 'id')]

+ 5 - 18
src/Entity/Booking/ExamenRecur.php

@@ -5,35 +5,22 @@ declare(strict_types=1);
 namespace App\Entity\Booking;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
  * @todo : A la suite de la migration, il faut supprimer le nom de la table pour avoir une table ExamenRecur, et supprimer l'attribut discr.
  *
- * Classe ... qui ...
+ * Examen récurrent
  */
 // #[Auditable]
-#[ORM\Table(name: 'BookingRecur')]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
+#[ORM\Table(name: 'BookingRecur')]
 class ExamenRecur extends AbstractBookingRecur
 {
-    #[ORM\Column(length: 255, nullable: false)]
-    protected string $discr = 'examen';
-
     #[ORM\ManyToOne(inversedBy: 'eventRecur')]
-    private Examen $event;
-
-    public function getDiscr(): ?string
-    {
-        return $this->discr;
-    }
-
-    public function setDiscr(string $discr): self
-    {
-        $this->discr = $discr;
-
-        return $this;
-    }
+    private ?Examen $event = null;
 
     public function getEvent(): ?Examen
     {

+ 4 - 21
src/Entity/Booking/OrganizationHoliday.php

@@ -14,7 +14,7 @@ use Doctrine\ORM\Mapping as ORM;
 /**
  * @todo : A la suite de la migration, il faut supprimer le nom de la table pour avoir une table OrganizationHoliday, et supprimer l'attribut discr.
  *
- * Classe ... qui ...
+ * Périodes de vacances d'une Organization
  */
 #[ApiResource(operations: [])]
 // #[Auditable]
@@ -22,11 +22,9 @@ use Doctrine\ORM\Mapping as ORM;
 #[ORM\Table(name: 'Booking')]
 class OrganizationHoliday extends AbstractBooking
 {
-    #[ORM\Column(length: 255, nullable: false)]
-    protected string $discr = 'organizationholiday';
-
-    #[ORM\OneToMany(mappedBy: 'event', targetEntity: OrganizationHolidayRecur::class, cascade: ['persist'], orphanRemoval: true)]
-    private Collection $eventRecur;
+    /** @var Collection<int, OrganizationHolidayRecur> */
+    #[ORM\OneToMany(targetEntity: OrganizationHolidayRecur::class, mappedBy: 'event', cascade: ['persist'], orphanRemoval: true)]
+    protected Collection $eventRecur;
 
     #[ORM\ManyToOne(inversedBy: 'holidays')]
     #[ORM\JoinColumn(nullable: false)]
@@ -35,24 +33,9 @@ class OrganizationHoliday extends AbstractBooking
     public function __construct()
     {
         $this->eventRecur = new ArrayCollection();
-        $this->organizer = new ArrayCollection();
-        $this->equipments = new ArrayCollection();
-        $this->tags = new ArrayCollection();
         parent::__construct();
     }
 
-    public function getDiscr(): ?string
-    {
-        return $this->discr;
-    }
-
-    public function setDiscr(string $discr): self
-    {
-        $this->discr = $discr;
-
-        return $this;
-    }
-
     /**
      * @return Collection<int, OrganizationHolidayRecur>
      */

+ 5 - 18
src/Entity/Booking/OrganizationHolidayRecur.php

@@ -5,33 +5,20 @@ declare(strict_types=1);
 namespace App\Entity\Booking;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * Périodes de vacances récurrentes d'une Organization.
  */
 // #[Auditable]
-#[ORM\Table(name: 'BookingRecur')]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
+#[ORM\Table(name: 'BookingRecur')]
 class OrganizationHolidayRecur extends AbstractBookingRecur
 {
-    #[ORM\Column(length: 255, nullable: false)]
-    protected string $discr = 'organizationholiday';
-
     #[ORM\ManyToOne(inversedBy: 'eventRecur')]
-    private OrganizationHoliday $event;
-
-    public function getDiscr(): ?string
-    {
-        return $this->discr;
-    }
-
-    public function setDiscr(string $discr): self
-    {
-        $this->discr = $discr;
-
-        return $this;
-    }
+    private ?OrganizationHoliday $event = null;
 
     public function getEvent(): ?OrganizationHoliday
     {

+ 19 - 54
src/Entity/Booking/PersonHoliday.php

@@ -8,14 +8,13 @@ use ApiPlatform\Metadata\ApiResource;
 use App\Entity\Access\Access;
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
 use App\Entity\Organization\Organization;
-use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
  * @todo : A la suite de la migration, il faut supprimer le nom de la table pour avoir une table PersonHoliday, et supprimer l'attribut discr.
  *
- * Classe ... qui ...
+ * Périodes de vacances d'un Access
  */
 #[ApiResource(operations: [])]
 // #[Auditable]
@@ -23,90 +22,56 @@ use Doctrine\ORM\Mapping as ORM;
 #[ORM\Table(name: 'Booking')]
 class PersonHoliday extends AbstractBooking
 {
-    #[ORM\Column(length: 255, nullable: false)]
-    protected string $discr = 'personholiday';
-
-    #[ORM\OneToMany(mappedBy: 'event', targetEntity: PersonHolidayRecur::class, cascade: ['persist'], orphanRemoval: true)]
-    protected Collection $eventRecur;
-
     #[ORM\ManyToOne(inversedBy: 'holidays')]
-    private Access $access;
+    private ?Access $access = null;
 
     #[ORM\ManyToOne(targetEntity: Organization::class, cascade: [])]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: false, onDelete: 'SET NULL')]
     protected Organization $organization;
 
-    public function __construct()
-    {
-        $this->eventRecur = new ArrayCollection();
-        $this->organizer = new ArrayCollection();
-        $this->equipments = new ArrayCollection();
-        $this->tags = new ArrayCollection();
-        parent::__construct();
-    }
+    /** @var Collection<int, PersonHolidayRecur> */
+    #[ORM\OneToMany(targetEntity: PersonHolidayRecur::class, mappedBy: 'event', cascade: ['persist'], orphanRemoval: true)]
+    protected Collection $eventRecur;
 
-    public function getDiscr(): ?string
+    public function getAccess(): ?Access
     {
-        return $this->discr;
+        return $this->access;
     }
 
-    public function setDiscr(string $discr): self
+    public function setAccess(?Access $access): self
     {
-        $this->discr = $discr;
+        $this->access = $access;
 
         return $this;
     }
 
-    /**
-     * @return Collection<int, PersonHolidayRecur>
-     */
-    public function getEventRecur(): Collection
-    {
-        return $this->eventRecur;
-    }
-
-    public function addEventRecur(PersonHolidayRecur $eventRecur): self
+    public function getOrganization(): Organization
     {
-        if (!$this->eventRecur->contains($eventRecur)) {
-            $this->eventRecur[] = $eventRecur;
-            $eventRecur->setEvent($this);
-        }
-
-        return $this;
+        return $this->organization;
     }
 
-    public function removeEventRecur(PersonHolidayRecur $eventRecur): self
+    public function setOrganization(Organization $organization): self
     {
-        if ($this->eventRecur->removeElement($eventRecur)) {
-            // set the owning side to null (unless already changed)
-            if ($eventRecur->getEvent() === $this) {
-                $eventRecur->setEvent(null);
-            }
-        }
+        $this->organization = $organization;
 
         return $this;
     }
 
-    public function getAccess(): ?Access
+    public function getOrganizer(): Collection
     {
-        return $this->access;
+        return $this->organizer;
     }
 
-    public function setAccess(?Access $access): self
+    public function addOrganizer(Access $organizer): self
     {
-        $this->access = $access;
+        $this->organizer[] = $organizer;
 
         return $this;
     }
 
-    public function getOrganization(): Organization
+    public function removeOrganizer(Access $organizer): self
     {
-        return $this->organization;
-    }
-
-    public function setOrganization(Organization $organization): self
-    {
-        $this->organization = $organization;
+        $this->organizer->removeElement($organizer);
 
         return $this;
     }

+ 5 - 18
src/Entity/Booking/PersonHolidayRecur.php

@@ -5,35 +5,22 @@ declare(strict_types=1);
 namespace App\Entity\Booking;
 
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use ApiPlatform\Metadata\ApiResource;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
  * @todo : A la suite de la migration, il faut supprimer le nom de la table pour avoir une table PersonHolidayRecur, et supprimer l'attribut discr.
  *
- * Classe ... qui ...
+ * Périodes de vacances récurrentes d'un Access
  */
 // #[Auditable]
-#[ORM\Table(name: 'BookingRecur')]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
+#[ORM\Table(name: 'BookingRecur')]
 class PersonHolidayRecur extends AbstractBookingRecur
 {
-    #[ORM\Column(length: 255, nullable: false)]
-    protected string $discr = 'personholiday';
-
     #[ORM\ManyToOne(inversedBy: 'eventRecur')]
-    private PersonHoliday $event;
-
-    public function getDiscr(): ?string
-    {
-        return $this->discr;
-    }
-
-    public function setDiscr(string $discr): self
-    {
-        $this->discr = $discr;
-
-        return $this;
-    }
+    private ?PersonHoliday $event = null;
 
     public function getEvent(): ?PersonHoliday
     {

+ 8 - 4
src/Entity/Booking/Work.php

@@ -4,6 +4,7 @@ declare(strict_types=1);
 
 namespace App\Entity\Booking;
 
+use ApiPlatform\Metadata\ApiResource;
 use App\Entity\Core\File;
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
 use Doctrine\Common\Collections\ArrayCollection;
@@ -11,9 +12,10 @@ use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * TODO: documenter.
  */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 class Work
 {
@@ -23,12 +25,14 @@ class Work
     private ?int $id = null;
 
     #[ORM\ManyToOne(inversedBy: 'work')]
-    private Course $course;
+    private ?Course $course = null;
 
-    #[ORM\OneToMany(mappedBy: 'work', targetEntity: WorkByUser::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, WorkByUser> */
+    #[ORM\OneToMany(targetEntity: WorkByUser::class, mappedBy: 'work', cascade: ['persist'], orphanRemoval: true)]
     private Collection $workByUsers;
 
-    #[ORM\OneToMany(mappedBy: 'work', targetEntity: File::class, orphanRemoval: true)]
+    /** @var Collection<int, File> */
+    #[ORM\OneToMany(targetEntity: File::class, mappedBy: 'work', orphanRemoval: true)]
     private Collection $files;
 
     public function __construct()

+ 5 - 3
src/Entity/Booking/WorkByUser.php

@@ -4,14 +4,16 @@ declare(strict_types=1);
 
 namespace App\Entity\Booking;
 
+use ApiPlatform\Metadata\ApiResource;
 use App\Entity\Access\Access;
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
- * Classe ... qui ...
+ * TODO: documenter.
  */
 // #[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 class WorkByUser
 {
@@ -21,10 +23,10 @@ class WorkByUser
     private ?int $id = null;
 
     #[ORM\ManyToOne(inversedBy: 'workByUsers')]
-    private Work $work;
+    private ?Work $work = null;
 
     #[ORM\ManyToOne(inversedBy: 'workByUsers')]
-    private Access $student;
+    private ?Access $student = null;
 
     public function getId(): ?int
     {

+ 16 - 51
src/Entity/Core/AbstractControl.php

@@ -4,12 +4,25 @@ declare(strict_types=1);
 
 namespace App\Entity\Core;
 
-use App\Entity\Access\Access;
-use Doctrine\Common\Collections\ArrayCollection;
-use Doctrine\Common\Collections\Collection;
+use App\Entity\Place\PlaceControl;
+use App\Entity\Place\RoomControl;
+use App\Entity\Product\EquipmentControl;
 use Doctrine\ORM\Mapping as ORM;
 
+/**
+ * Contrôle du bon état des Place, Room et Equipment, effectué ou planifié
+ * Classe de base de @see PlaceControl, RoomControl, EquipmentControl.
+ */
 #[ORM\MappedSuperclass]
+#[ORM\Table(name: 'Control')]
+#[ORM\DiscriminatorColumn(name: 'discr', type: 'string')]
+#[ORM\DiscriminatorMap(
+    [
+        'equipment' => EquipmentControl::class,
+        'place' => PlaceControl::class,
+        'room' => RoomControl::class,
+    ]
+)]
 abstract class AbstractControl
 {
     #[ORM\Id]
@@ -17,56 +30,8 @@ abstract class AbstractControl
     #[ORM\GeneratedValue]
     protected ?int $id = null;
 
-    #[ORM\ManyToOne(inversedBy: 'accompanistControl')]
-    #[ORM\JoinColumn(nullable: true)]
-    protected Access $accompanist;
-
-    #[ORM\ManyToMany(targetEntity: Tagg::class, inversedBy: 'controls', cascade: ['persist'], orphanRemoval: false)]
-    protected Collection $tags;
-
-    public function __construct()
-    {
-        $this->tags = new ArrayCollection();
-    }
-
     public function getId(): ?int
     {
         return $this->id;
     }
-
-    public function getAccompanist(): Access
-    {
-        return $this->accompanist;
-    }
-
-    public function setAccompanist(Access $accompanist): self
-    {
-        $this->accompanist = $accompanist;
-
-        return $this;
-    }
-
-    public function getTags(): Collection
-    {
-        return $this->tags;
-    }
-
-    public function addTag(Tagg $tag): self
-    {
-        if (!$this->tags->contains($tag)) {
-            $this->tags[] = $tag;
-            $tag->addControl($this);
-        }
-
-        return $this;
-    }
-
-    public function removeTag(Tagg $tag): self
-    {
-        if ($this->tags->removeElement($tag)) {
-            $tag->addControl($this);
-        }
-
-        return $this;
-    }
 }

+ 5 - 38
src/Entity/Core/AbstractInformation.php

@@ -5,8 +5,6 @@ declare(strict_types=1);
 namespace App\Entity\Core;
 
 use ApiPlatform\Metadata\ApiResource;
-use App\Entity\Access\Access;
-use App\Entity\Organization\Organization;
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
 use App\Enum\Core\NotificationTypeEnum;
 use Doctrine\Common\Collections\ArrayCollection;
@@ -19,7 +17,7 @@ use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
 /**
  * @todo : A la suite de la migration, il faut supprimer le nom de la table pour avoir une table Notification, et supprimer l'attribut discr.
  *
- * Classe Notification. qui permet de gérer les notifications aux utilisateurs.
+ * Classe Notification qui permet de gérer les notifications aux utilisateurs.
  */
 #[ApiResource(operations: [])]
 // #[Auditable]
@@ -28,8 +26,8 @@ use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
 #[ORM\InheritanceType('SINGLE_TABLE')]
 #[ORM\DiscriminatorColumn(name: 'discr', type: 'string')]
 #[ORM\DiscriminatorMap([
-    'notification' => 'Notification',
-    'tips' => 'Tips',
+    'notification' => Notification::class,
+    'tips' => Tips::class,
 ])]
 class AbstractInformation
 {
@@ -38,14 +36,6 @@ class AbstractInformation
     #[ORM\GeneratedValue]
     protected ?int $id = null;
 
-    #[ORM\ManyToOne(inversedBy: 'notifications')]
-    #[ORM\JoinColumn(nullable: false)]
-    protected ?Access $recipientAccess;
-
-    #[ORM\ManyToOne(inversedBy: 'notifications')]
-    #[ORM\JoinColumn(nullable: false)]
-    protected ?Organization $recipientOrganization;
-
     #[ORM\Column(length: 40, nullable: true)]
     protected ?string $name = null;
 
@@ -68,7 +58,8 @@ class AbstractInformation
     #[Context(normalizationContext: [DateTimeNormalizer::FORMAT_KEY => 'Y-m-d'])]
     protected ?\DateTimeInterface $availabilityDate = null;
 
-    #[ORM\OneToMany(mappedBy: 'notification', targetEntity: NotificationUser::class, cascade: ['persist'], orphanRemoval: true)]
+    /** @var Collection<int, NotificationUser> */
+    #[ORM\OneToMany(targetEntity: NotificationUser::class, mappedBy: 'notification', cascade: ['persist'], orphanRemoval: true)]
     protected Collection $notificationUsers;
 
     #[Pure]
@@ -94,30 +85,6 @@ class AbstractInformation
         return $this->name;
     }
 
-    public function setRecipientAccess(?Access $recipientAccess): self
-    {
-        $this->recipientAccess = $recipientAccess;
-
-        return $this;
-    }
-
-    public function getRecipientAccess(): ?Access
-    {
-        return $this->recipientAccess;
-    }
-
-    public function getRecipientOrganization(): ?Organization
-    {
-        return $this->recipientOrganization;
-    }
-
-    public function setRecipientOrganization(?Organization $recipientOrganization): self
-    {
-        $this->recipientOrganization = $recipientOrganization;
-
-        return $this;
-    }
-
     public function getCreateDate(): ?\DateTimeInterface
     {
         return $this->createDate;

+ 19 - 6
src/Entity/Core/AbstractRepair.php

@@ -4,11 +4,25 @@ declare(strict_types=1);
 
 namespace App\Entity\Core;
 
-use Doctrine\Common\Collections\ArrayCollection;
+use App\Entity\Place\PlaceRepair;
+use App\Entity\Place\RoomRepair;
+use App\Entity\Product\EquipmentRepair;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
+/**
+ * Classe de base de @see PlaceRepair, RoomRepair, EquipmentRepair.
+ */
 #[ORM\MappedSuperclass]
+#[ORM\Table(name: 'Repair')]
+#[ORM\DiscriminatorColumn(name: 'discr', type: 'string')]
+#[ORM\DiscriminatorMap(
+    [
+        'room' => RoomRepair::class,
+        'place' => PlaceRepair::class,
+        'equipment' => EquipmentRepair::class,
+    ]
+)]
 abstract class AbstractRepair
 {
     #[ORM\Id]
@@ -16,14 +30,13 @@ abstract class AbstractRepair
     #[ORM\GeneratedValue]
     protected ?int $id = null;
 
+    /** @var Collection<int, Tagg> */
     #[ORM\ManyToMany(targetEntity: Tagg::class, inversedBy: 'repairs', cascade: ['persist'], orphanRemoval: false)]
+    #[ORM\JoinTable(name: 'tag_repair')]
+    #[ORM\JoinColumn(name: 'repair_id')]
+    #[ORM\InverseJoinColumn(name: 'tag_id')]
     protected Collection $tags;
 
-    public function __construct()
-    {
-        $this->tags = new ArrayCollection();
-    }
-
     public function getId(): ?int
     {
         return $this->id;

+ 9 - 7
src/Entity/Core/AddressPostal.php

@@ -7,8 +7,8 @@ namespace App\Entity\Core;
 use ApiPlatform\Metadata\ApiResource;
 use App\Entity\Organization\OrganizationAddressPostal;
 use App\Entity\Person\PersonAddressPostal;
-use App\Entity\Place\AbstractPlace;
 // use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use App\Entity\Place\Place;
 use App\Entity\Traits\CreatedOnAndByTrait;
 use App\Repository\Core\AddressPostalRepository;
 use Doctrine\Common\Collections\ArrayCollection;
@@ -73,14 +73,16 @@ class AddressPostal
     private ?float $longitude = null;
 
     #[ORM\OneToOne(mappedBy: 'addressPostal')]
-    private OrganizationAddressPostal $organizationAddressPostal;
+    private ?OrganizationAddressPostal $organizationAddressPostal = null;
 
     #[ORM\OneToOne(mappedBy: 'addressPostal')]
-    private PersonAddressPostal $personAddressPostal;
+    private ?PersonAddressPostal $personAddressPostal = null;
 
-    #[ORM\OneToMany(mappedBy: 'addressPostal', targetEntity: AbstractPlace::class)]
+    /** @var Collection<int, Place> */
+    #[ORM\OneToMany(mappedBy: 'addressPostal', targetEntity: Place::class)]
     private Collection $places;
 
+    /** @var Collection<int, OrganizationAddressPostal> */
     #[ORM\OneToMany(mappedBy: 'addressPostal', targetEntity: OrganizationAddressPostal::class, cascade: [], orphanRemoval: false)]
     protected Collection $organizationAddressPostals;
 
@@ -228,14 +230,14 @@ class AddressPostal
     }
 
     /**
-     * @return Collection<int, AbstractPlace>
+     * @return Collection<int, Place>
      */
     public function getPlaces(): Collection
     {
         return $this->places;
     }
 
-    public function addPlace(AbstractPlace $place): self
+    public function addPlace(Place $place): self
     {
         if (!$this->places->contains($place)) {
             $this->places[] = $place;
@@ -245,7 +247,7 @@ class AddressPostal
         return $this;
     }
 
-    public function removePlace(AbstractPlace $place): self
+    public function removePlace(Place $place): self
     {
         if ($this->places->removeElement($place)) {
             // set the owning side to null (unless already changed)

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.