Browse Source

Merge branch 'develop' of git@gitlab.2iopenservice.com:vincent/api.git
into develop

Conflicts:
composer.lock

Olivier Massot 4 years ago
parent
commit
461e1a4e15
100 changed files with 2130 additions and 2355 deletions
  1. 3 3
      composer.json
  2. 270 131
      composer.lock
  3. 10 4
      config/opentalent/products.yaml
  4. 2 2
      config/packages/doctrine.yaml
  5. 8 7
      config/services.yaml
  6. 15 18
      src/ApiResources/Enum/Enum.php
  7. 87 75
      src/ApiResources/Profile/AccessProfile.php
  8. 44 45
      src/ApiResources/Profile/OrganizationProfile.php
  9. 27 30
      src/ApiResources/Utils/GpsCoordinate.php
  10. 15 16
      src/ApiResources/Utils/Siret.php
  11. 19 0
      src/DQL/DateConditions.php
  12. 3 9
      src/DataProvider/Access/AccessProfileDataProvider.php
  13. 9 17
      src/DataProvider/Enum/EnumDataProvider.php
  14. 3 9
      src/DataProvider/Utils/GpsCoordinateSearchingDataProvider.php
  15. 5 9
      src/DataProvider/Utils/SiretDataProvider.php
  16. 2 8
      src/Doctrine/Access/AccessExtension.php
  17. 1 1
      src/Doctrine/Access/Extensions/AdminExtension.php
  18. 2 1
      src/Doctrine/Access/Extensions/StudentsExtension.php
  19. 3 8
      src/Doctrine/Access/HandleAccessExtension.php
  20. 2 6
      src/Doctrine/Access/PersonalizedListExtension.php
  21. 235 222
      src/Entity/Access/Access.php
  22. 71 0
      src/Entity/Access/FunctionType.php
  23. 52 42
      src/Entity/Access/OrganizationFunction.php
  24. 50 55
      src/Entity/Access/PersonalizedList.php
  25. 30 0
      src/Entity/Billing/AbstractBillingIntangible.php
  26. 30 0
      src/Entity/Billing/AbstractBillingPayer.php
  27. 31 0
      src/Entity/Billing/AccessIntangible.php
  28. 49 0
      src/Entity/Billing/AccessPayer.php
  29. 35 60
      src/Entity/Core/AddressPostal.php
  30. 50 79
      src/Entity/Core/BankAccount.php
  31. 60 83
      src/Entity/Core/ContactPoint.php
  32. 10 15
      src/Entity/Core/Country.php
  33. 24 44
      src/Entity/Core/File.php
  34. 15 24
      src/Entity/Network/Network.php
  35. 20 30
      src/Entity/Network/NetworkOrganization.php
  36. 169 275
      src/Entity/Organization/Organization.php
  37. 20 30
      src/Entity/Organization/OrganizationAddressPostal.php
  38. 27 40
      src/Entity/Organization/OrganizationLicence.php
  39. 117 181
      src/Entity/Organization/Parameters.php
  40. 25 39
      src/Entity/Organization/Settings.php
  41. 32 75
      src/Entity/Person/Person.php
  42. 12 50
      src/Entity/Person/PersonActivity.php
  43. 8 39
      src/Entity/Traits/ActivityPeriodTrait.php
  44. 11 40
      src/Entity/Traits/ActivityYearTrait.php
  45. 23 0
      src/Enum/Access/DeparturesCauseEnum.php
  46. 103 0
      src/Enum/Access/FunctionEnum.php
  47. 24 0
      src/Enum/Access/RoleEnum.php
  48. 18 0
      src/Enum/Access/TypeFunctionEnum.php
  49. 2 5
      src/Enum/Core/ContactPointTypeEnum.php
  50. 2 2
      src/Enum/Core/TimeZoneEnum.php
  51. 1 0
      src/Enum/Education/PeriodicityEnum.php
  52. 1 0
      src/Enum/Network/LeadingCauseEnum.php
  53. 1 0
      src/Enum/Network/NetworkEnum.php
  54. 2 0
      src/Enum/Organization/AddressPostalOrganizationTypeEnum.php
  55. 1 0
      src/Enum/Organization/BulletinOutputEnum.php
  56. 1 0
      src/Enum/Organization/BulletinPeriodEnum.php
  57. 1 0
      src/Enum/Organization/CategoryEnum.php
  58. 1 0
      src/Enum/Organization/LegalEnum.php
  59. 1 0
      src/Enum/Organization/OpcaEnum.php
  60. 1 0
      src/Enum/Organization/OrganizationIdsEnum.php
  61. 1 0
      src/Enum/Organization/PrincipalTypeEnum.php
  62. 1 0
      src/Enum/Organization/SchoolCategoryEnum.php
  63. 1 0
      src/Enum/Organization/SendToBulletinEnum.php
  64. 1 0
      src/Enum/Organization/SettingsProductEnum.php
  65. 1 0
      src/Enum/Organization/TypeEstablishmentDetailEnum.php
  66. 1 0
      src/Enum/Organization/TypeEstablishmentEnum.php
  67. 23 7
      src/Repository/Access/AccessRepository.php
  68. 22 0
      src/Repository/Access/FunctionTypeRepository.php
  69. 0 29
      src/Repository/Access/OrganizationFunctionRepository.php
  70. 16 0
      src/Repository/Billing/AccessIntangibleRepository.php
  71. 16 0
      src/Repository/Billing/AccessPayerRepository.php
  72. 1 29
      src/Repository/Core/AddressPostalRepository.php
  73. 1 29
      src/Repository/Core/BankAccountRepository.php
  74. 1 28
      src/Repository/Core/ContactPointRepository.php
  75. 1 29
      src/Repository/Core/CountryRepository.php
  76. 1 0
      src/Repository/Core/FileRepository.php
  77. 0 29
      src/Repository/Network/NetworkRepository.php
  78. 1 29
      src/Repository/Organization/OrganizationAddressPostalRepository.php
  79. 1 29
      src/Repository/Organization/OrganizationLicenceRepository.php
  80. 1 29
      src/Repository/Organization/ParametersRepository.php
  81. 0 29
      src/Repository/Organization/SettingsRepository.php
  82. 0 29
      src/Repository/Person/PersonActivityRepository.php
  83. 0 29
      src/Repository/Person/PersonRepository.php
  84. 3 7
      src/Security/Voter/BankAccountVoter.php
  85. 3 7
      src/Security/Voter/ContactPointVoter.php
  86. 3 12
      src/Security/Voter/ModuleVoter.php
  87. 11 11
      src/Security/Voter/SwitchUserVoter.php
  88. 5 13
      src/Serializer/AccessContextBuilder.php
  89. 0 57
      src/Serializer/OpentalentNormalizer.php
  90. 13 19
      src/Service/Access/AccessProfileCreator.php
  91. 22 0
      src/Service/Access/HandleOptionalsRoles.php
  92. 30 0
      src/Service/Access/OptionalsRoles/CriteriaNotationOptionalRole.php
  93. 12 0
      src/Service/Access/OptionalsRolesInterface.php
  94. 28 3
      src/Service/Access/Utils.php
  95. 4 12
      src/Service/Cotisation/Utils.php
  96. 2 6
      src/Service/Network/Tree.php
  97. 0 4
      src/Service/Network/Utils.php
  98. 6 9
      src/Service/Organization/OrganizationProfileCreator.php
  99. 0 4
      src/Service/Organization/Utils.php
  100. 1 8
      src/Service/Security/Module.php

+ 3 - 3
composer.json

@@ -14,10 +14,10 @@
         "api-platform/core": "^2.6",
         "blackfire/php-sdk": "^1.23",
         "composer/package-versions-deprecated": "^1.11",
-        "doctrine/annotations": "^1.0",
+
         "doctrine/doctrine-bundle": "^2.1",
         "doctrine/doctrine-migrations-bundle": "^3.0",
-        "doctrine/orm": "^2.7",
+        "doctrine/orm": "^2.9",
         "egulias/email-validator": "^3.0",
         "jbouzekri/phumbor-bundle": "^2.1",
         "lexik/jwt-authentication-bundle": "^2.8",
@@ -40,7 +40,7 @@
         "symfony/twig-bundle": "^5.3",
         "symfony/validator": "5.3.*",
         "symfony/yaml": "5.3.*",
-        "vincent/foselastica": "1.1",
+        "vincent/foselastica": "1.2",
         "webonyx/graphql-php": "^14.3"
     },
     "require-dev": {

File diff suppressed because it is too large
+ 270 - 131
composer.lock


+ 10 - 4
config/opentalent/products.yaml

@@ -103,6 +103,10 @@ opentalent:
         roles:
           - ROLE_MAILS
 
+      TemplateMessages:
+        entities:
+          - TemplateSystem
+
       Tagg:
         entities:
           - Tagg
@@ -206,6 +210,11 @@ opentalent:
           actions:
             - EvaluateStudents
 
+      AdvancedEducationNotation:
+        entities:
+          - EducationNotationConfig
+          - EducationNotationCriteriaConfig
+
       BillingAdministration:
           entities:
             - Intangible
@@ -281,10 +290,6 @@ opentalent:
         roles:
           - ROLE_STATISTIC
 
-      ViewAudit:
-          entities:
-            - ViewAudit
-
       NetworkOrganization:
           entities:
             - NetworkOrganization
@@ -333,6 +338,7 @@ opentalent:
           - Attendances
           - UsersSchool
           - BillingAdministration
+          - TemplateMessages
 
       school_premium:
         extend: school

+ 2 - 2
config/packages/doctrine.yaml

@@ -11,7 +11,7 @@ doctrine:
         mappings:
             App:
                 is_bundle: false
-                type: annotation
+                type: attribute
                 dir: '%kernel.project_dir%/src/Entity'
                 prefix: 'App\Entity'
-                alias: App
+                alias: App

+ 8 - 7
config/services.yaml

@@ -10,10 +10,6 @@ services:
         bind:
             $opentalentConfig: '%kernel.project_dir%%env(OPENTALENT_CONFIG)%'
 
-    _instanceof:
-        App\Doctrine\Access\AccessExtensionInterface:
-            tags: ['app.extensions.access']
-
     # makes classes in src/ available to be used as services
     # this creates a service per class whose id is the fully-qualified class name
     App\:
@@ -35,14 +31,19 @@ services:
 
     #########################################
     ##  TAG Services ##
+    _instanceof:
+        App\Doctrine\Access\AccessExtensionInterface:
+            tags: ['app.extensions.access']
+        App\Service\Access\OptionalsRolesInterface:
+            tags: ['app.optionalsroles']
+
     App\Doctrine\Access\HandleAccessExtension:
         - !tagged_iterator app.extensions.access
+    App\Service\Access\HandleOptionalsRoles:
+        - !tagged_iterator app.optionalsroles
 
     #########################################
     ##  SERIALIZER Decorates ##
-    App\Serializer\OpentalentNormalizer:
-        decorates: 'api_platform.jsonld.normalizer.item'
-
     App\Serializer\AccessContextBuilder:
         decorates: 'api_platform.serializer.context_builder'
         arguments: [ '@App\Serializer\AccessContextBuilder.inner' ]

+ 15 - 18
src/ApiResources/Enum/Enum.php

@@ -8,34 +8,31 @@ use ApiPlatform\Core\Annotation\ApiResource;
 
 /**
  * Classe resource qui contient les champs disponibles lors d'un appel à enum.
- *
- * @ApiResource(
- *     collectionOperations={},
- *     itemOperations={
- *          "get"={
- *             "method"="GET",
- *             "path"="/enum/{name}"
- *          }
- *     }
- * )
  */
+#[ApiResource(
+    collectionOperations: [],
+    itemOperations: [
+        'get' => [
+            'method' => 'GET',
+            'path' => '/enum/{name}'
+        ]
+    ]
+)]
 class Enum
 {
-    /**
-     * @ApiProperty(identifier=true)
-     */
-    private $name;
-    private $items = [];
+    #[ApiProperty(identifier: true)]
+    private string $name;
+    private array $items = [];
 
     public function __construct()
     {
     }
-    public function getName(): ?string
+    public function getName(): string
     {
         return $this->name;
     }
 
-    public function setName(?string $name): self
+    public function setName(string $name): self
     {
         $this->name = $name;
 
@@ -49,7 +46,7 @@ class Enum
         return $this;
     }
 
-    public function getItems(): ?array
+    public function getItems(): array
     {
         return $this->items;
     }

+ 87 - 75
src/ApiResources/Profile/AccessProfile.php

@@ -5,81 +5,75 @@ namespace App\ApiResources\Profile;
 
 use ApiPlatform\Core\Annotation\ApiProperty;
 use ApiPlatform\Core\Annotation\ApiResource;
+use JetBrains\PhpStorm\Pure;
 use Symfony\Component\Serializer\Annotation\Groups;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
 
 /**
  * Classe resource qui contient les champs disponibles lors d'un appel à my_profile.
- *
- * @ApiResource(
- *     itemOperations={
- *          "get"={
- *             "normalization_context"={"groups"={"access_profile_read"}},
- *             "method"="GET",
- *             "path"="/my_profile/{id}",
- *             "defaults"={"id"=0}
- *          }
- *     }
- * )
  */
+#[ApiResource(
+    itemOperations: [
+        'get' => [
+            'normalization_context' => [
+                'groups' => ['access_profile_read']
+            ],
+            'method' => 'GET',
+            'path' => '/my_profile/{id}',
+            'defaults' => ['id' => 0]
+        ]
+    ]
+)]
 class AccessProfile
 {
-    /**
-     * @ApiProperty(identifier=true)
-     * @Groups({"access_profile_read"})
-     */
-    public $id;
-    /**
-     * @Groups({"access_profile_read"})
-     */
-    private $isAdminAccess;
-    /**
-     * @Groups({"access_profile_read"})
-     */
-    private $name;
-    /**
-     * @Groups({"access_profile_read"})
-     */
-    private $givenName;
-    /**
-     * @Groups({"access_profile_read"})
-     */
-    private $gender;
-    /**
-     * @Groups({"access_profile_read"})
-     */
-    private $avatarId;
-    /**
-     * @Groups({"access_profile_read"})
-     */
-    private $roles = [];
-    /**
-     * @Groups({"access_profile_read"})
-     */
-    private $activityYear;
-    /**
-     * @Groups({"access_profile_read"})
-     */
-    private $historical=[];
-    /**
-     * @Groups({"access_profile_read"})
-     */
-    private $organization;
-    /**
-     * @Groups({"access_profile_read"})
-     */
-    private $multiAccesses;
-    /**
-     * @Groups({"access_profile_read"})
-     */
-    private $familyAccesses;
-    /**
-     * @Groups({"access_profile_read"})
-     */
-    private $originalAccess;
-
-    public function __construct()
+    #[ApiProperty(identifier: true)]
+    #[Groups('access_profile_read')]
+    public ?int $id = null;
+
+    #[Groups('access_profile_read')]
+    private bool $isAdminAccess = false;
+
+    #[Groups('access_profile_read')]
+    private ?string $name = null;
+
+    #[Groups('access_profile_read')]
+    private ?string $givenName = null;
+
+    #[Groups('access_profile_read')]
+    private ?string $gender = null;
+
+    #[Groups('access_profile_read')]
+    private ?int $avatarId = null;
+
+    #[Groups('access_profile_read')]
+    private ?array $roles = [];
+
+    #[Groups('access_profile_read')]
+    private ?int $activityYear = null;
+
+    #[Groups('access_profile_read')]
+    private ?array $historical=[];
+
+    #[Groups('access_profile_read')]
+    private bool $isGuardian = false;
+
+    #[Groups('access_profile_read')]
+    private bool $isPayor = false;
+
+    #[Groups('access_profile_read')]
+    private ?OrganizationProfile $organization = null;
+
+    #[Groups('access_profile_read')]
+    private Collection $multiAccesses;
+
+    #[Groups('access_profile_read')]
+    private Collection $familyAccesses;
+
+    #[Groups('access_profile_read')]
+    private ?AccessProfile $originalAccess = null;
+
+    #[Pure] public function __construct()
     {
         $this->multiAccesses = new ArrayCollection();
         $this->familyAccesses = new ArrayCollection();
@@ -97,7 +91,7 @@ class AccessProfile
         return $this;
     }
 
-    public function getIsAdminAccess(): ?bool
+    public function getIsAdminAccess(): bool
     {
         return $this->isAdminAccess;
     }
@@ -180,9 +174,30 @@ class AccessProfile
         return $this;
     }
 
-    /**
-     * @return Collection|OrganizationProfile[]
-     */
+    public function getIsGuardian(): bool
+    {
+        return $this->isGuardian;
+    }
+
+    public function setIsGuardian(bool $isGuardian): self
+    {
+        $this->isGuardian = $isGuardian;
+
+        return $this;
+    }
+
+    public function getIsPayor(): bool
+    {
+        return $this->isPayor;
+    }
+
+    public function setIsPayor(bool $isPayor): self
+    {
+        $this->isPayor = $isPayor;
+
+        return $this;
+    }
+
     public function getMultiAccesses(): Collection
     {
         return $this->multiAccesses;
@@ -202,9 +217,6 @@ class AccessProfile
         return $this;
     }
 
-    /**
-     * @return Collection|OrganizationProfile[]
-     */
     public function getFamilyAccesses(): Collection
     {
         return $this->familyAccesses;
@@ -235,12 +247,12 @@ class AccessProfile
         return $this;
     }
 
-    public function getActivityYear(): int
+    public function getActivityYear(): ?int
     {
         return $this->activityYear;
     }
 
-    public function setActivityYear(int $activityYear): self
+    public function setActivityYear(?int $activityYear): self
     {
         $this->activityYear = $activityYear;
 

+ 44 - 45
src/ApiResources/Profile/OrganizationProfile.php

@@ -9,53 +9,41 @@ use ApiPlatform\Core\Annotation\ApiResource;
 
 /**
  * Classe resource qui contient les champs relatifs aux organizations présentent dans la requete my_profile.
- * @package App\ApiResources\Profile
- *
- *  @ApiResource()
  */
+
+#[ApiResource]
 class OrganizationProfile
 {
-    /**
-     * @ApiProperty(identifier=true)
-     * @Groups({"access_profile_read"})
-     */
-    public $id;
-    /**
-     * @Groups({"access_profile_read"})
-     */
-    private $name;
-    /**
-     * @Groups({"access_profile_read"})
-     */
-    private $product;
-    /**
-     * @Groups({"access_profile_read"})
-     */
-    private $subDomain;
-    /**
-     * @Groups({"access_profile_read"})
-     */
-    private $networks = [];
-    /**
-     * @Groups({"access_profile_read"})
-     */
-    private $website;
-    /**
-     * @Groups({"access_profile_read"})
-     */
-    private $modules = [];
-    /**
-     * @Groups({"access_profile_read"})
-     */
-    private $hasChildren = false;
-    /**
-     * @Groups({"access_profile_read"})
-     */
-    private $parents = [];
-
-    public function __construct()
-    {
-    }
+    #[ApiProperty(identifier: true)]
+    #[Groups('access_profile_read')]
+    public ?int $id = null;
+
+    #[Groups('access_profile_read')]
+    private ?string $name = null;
+
+    #[Groups('access_profile_read')]
+    private ?string $product = null;
+
+    #[Groups('access_profile_read')]
+    private ?string $subDomain = null;
+
+    #[Groups('access_profile_read')]
+    private array $networks = [];
+
+    #[Groups('access_profile_read')]
+    private ?string $website = null;
+
+    #[Groups('access_profile_read')]
+    private ?array $modules = [];
+
+    #[Groups('access_profile_read')]
+    private bool $hasChildren = false;
+
+    #[Groups('access_profile_read')]
+    private ?array $parents = [];
+
+    #[Groups('access_profile_read')]
+    private bool $showAdherentList = false;
 
     public function getId(): ?int
     {
@@ -154,7 +142,6 @@ class OrganizationProfile
         return $this;
     }
 
-
     public function getParents(): array
     {
         return $this->parents;
@@ -165,4 +152,16 @@ class OrganizationProfile
         $this->parents[] = $parent;
         return $this;
     }
+
+    public function getShowAdherentList(): bool
+    {
+        return $this->showAdherentList;
+    }
+
+    public function setShowAdherentList(bool $showAdherentList): self
+    {
+        $this->showAdherentList = $showAdherentList;
+
+        return $this;
+    }
 }

+ 27 - 30
src/ApiResources/Utils/GpsCoordinate.php

@@ -8,39 +8,36 @@ use ApiPlatform\Core\Annotation\ApiResource;
 
 /**
  * Classe resource qui contient les champs de recherche des coordonnées GPS d'une adresse
- *
- * @ApiResource(
- *     compositeIdentifier=false,
- *     collectionOperations={
- *          "get"={
- *             "method"="GET",
- *             "path"="/gps-coordinate-searching"
- *          }
- *     },
- *     itemOperations={
- *         "get"={
- *             "method"="GET",
- *             "path"="/gps-coordinate-reverse/{latitude}/{longitude}"
- *          }
- *     }
- * )
  */
+#[ApiResource(
+    collectionOperations: [
+        'get' => [
+            'method' => 'GET',
+            'path' => '/gps-coordinate-searching'
+        ]
+    ],
+    itemOperations: [
+        'get' => [
+            'method' => 'GET',
+            'path' => '/gps-coordinate-reverse/{latitude}/{longitude}'
+        ]
+    ],
+    compositeIdentifier: false
+)]
 class GpsCoordinate
 {
-    /**
-     * @ApiProperty(identifier=true)
-     */
-    private $latitude;
-    /**
-     * @ApiProperty(identifier=true)
-     */
-    private $longitude;
-    private $streetAddress;
-    private $streetAddressSecond;
-    private $streetAddressThird;
-    private $cp;
-    private $city;
-    private $country;
+    #[ApiProperty(identifier: true)]
+    private float $latitude;
+
+    #[ApiProperty(identifier: true)]
+    private float $longitude;
+
+    private ?string $streetAddress = null;
+    private ?string $streetAddressSecond = null;
+    private ?string $streetAddressThird = null;
+    private ?string $cp = null;
+    private ?string $city = null;
+    private ?string $country = null;
 
     public function __construct()
     {

+ 15 - 16
src/ApiResources/Utils/Siret.php

@@ -8,24 +8,23 @@ use ApiPlatform\Core\Annotation\ApiResource;
 
 /**
  * Classe resource qui contient les champs de vérification d'un siret
- *
- * @ApiResource(
- *     collectionOperations={},
- *     itemOperations={
- *          "get"={
- *             "method"="GET",
- *             "path"="/siret-checking/{number}"
- *          }
- *     }
- * )
  */
+
+#[ApiResource(
+    collectionOperations: [],
+    itemOperations: [
+        'get' => [
+            'method' => 'GET',
+            'path' => '/siret-checking/{number}'
+        ]
+    ]
+)]
 class Siret
 {
-    /**
-     * @ApiProperty(identifier=true)
-     */
-    private $number;
-    private $isCorrect;
+    #[ApiProperty(identifier: true)]
+    private ?string $number = null;
+
+    private bool $isCorrect = false;
 
     public function __construct()
     {
@@ -47,7 +46,7 @@ class Siret
         return $this;
     }
 
-    public function getIsCorrect(): ?bool
+    public function getIsCorrect(): bool
     {
         return $this->isCorrect;
     }

+ 19 - 0
src/DQL/DateConditions.php

@@ -0,0 +1,19 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DQL;
+
+use Doctrine\ORM\QueryBuilder;
+
+class DateConditions{
+    public static function addDateInPeriodCondition(QueryBuilder $qb, string $table, string $date): QueryBuilder{
+        return $qb
+                ->andWhere(sprintf('%s.startDate <= :date AND (%s.endDate >= :date  OR  %s.endDate IS NULL)',
+                    $table,
+                    $table,
+                    $table
+                ))
+                ->setParameter('date', $date)
+            ;
+    }
+}

+ 3 - 9
src/DataProvider/Access/AccessProfileDataProvider.php

@@ -19,17 +19,11 @@ use Symfony\Component\Security\Core\Security;
  */
 final class AccessProfileDataProvider implements ItemDataProviderInterface, RestrictedDataProviderInterface
 {
-    private Security $security;
-    private AccessProfileCreator $accessProfileCreator;
-
     public function __construct(
-        Security $security,
-        AccessProfileCreator $accessProfileCreator
+        private Security $security,
+        private AccessProfileCreator $accessProfileCreator
     )
-    {
-        $this->security = $security;
-        $this->accessProfileCreator = $accessProfileCreator;
-    }
+    { }
 
     public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
     {

+ 9 - 17
src/DataProvider/Enum/EnumDataProvider.php

@@ -16,33 +16,25 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  */
 final class EnumDataProvider implements ItemDataProviderInterface, RestrictedDataProviderInterface
 {
-    private Parser $parser;
-    private Reflection $reflection;
-    private string $opentalentConfig;
-
     public function __construct(
-        Parser $parser,
-        string $opentalentConfig,
-        Reflection $reflection
+        private Parser $parser,
+        private string $opentalentConfig,
+        private Reflection $reflection
     )
-    {
-        $this->parser = $parser;
-        $this->opentalentConfig = $opentalentConfig;
-        $this->reflection = $reflection;
-    }
+    { }
 
     public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
     {
         return Enum::class === $resourceClass;
     }
 
-    public function getItem(string $resourceClass, $name, string $operationName = null, array $context = []): ?Enum
+    public function getItem(string $resourceClass, $id, string $operationName = null, array $context = []): ?Enum
     {
         $enums = $this->parser->yamlParser($this->opentalentConfig, 'enum.yaml');
-        $enumClass = $enums['opentalent'][$name];
+        $enumClass = $enums['opentalent'][$id];
 
         if(!$enumClass)
-            throw new NotFoundHttpException(sprintf('Enum %s does\'nt exist', $name));
+            throw new NotFoundHttpException(sprintf('Enum %s does\'nt exist', $id));
 
         try{
             $items = $this->reflection->dynamicInvokeClassWithArgsAndMethod(
@@ -50,11 +42,11 @@ final class EnumDataProvider implements ItemDataProviderInterface, RestrictedDat
                 'toArray'
             );
         }catch (\Exception $exception){
-            throw new NotFoundHttpException(sprintf('Enum %s does\'nt exist', $name));
+            throw new NotFoundHttpException(sprintf('Enum %s does\'nt exist', $id));
         }
 
         $enumResponse = new Enum();
-        $enumResponse->setName($name);
+        $enumResponse->setName($id);
         $enumResponse->setItems($items);
         return $enumResponse;
     }

+ 3 - 9
src/DataProvider/Utils/GpsCoordinateSearchingDataProvider.php

@@ -18,17 +18,11 @@ use Symfony\Component\HttpFoundation\RequestStack;
  */
 final class GpsCoordinateSearchingDataProvider implements ItemDataProviderInterface, CollectionDataProviderInterface, RestrictedDataProviderInterface
 {
-    private GpsCoordinateUtils $gpsCoordinateUtils;
-    private RequestStack $requestStack;
-
     public function __construct(
-        GpsCoordinateUtils $gpsCoordinateUtils,
-        RequestStack $requestStack
+        private GpsCoordinateUtils $gpsCoordinateUtils,
+        private RequestStack $requestStack
     )
-    {
-        $this->gpsCoordinateUtils = $gpsCoordinateUtils;
-        $this->requestStack = $requestStack;
-    }
+    { }
 
     public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
     {

+ 5 - 9
src/DataProvider/Utils/SiretDataProvider.php

@@ -14,25 +14,21 @@ use App\Service\Utils\Siret as SiretUtils;
  */
 final class SiretDataProvider implements ItemDataProviderInterface, RestrictedDataProviderInterface
 {
-    private SiretUtils $siretUtils;
-
     public function __construct(
-        SiretUtils $siretUtils
+        private SiretUtils $siretUtils
     )
-    {
-        $this->siretUtils = $siretUtils;
-    }
+    { }
 
     public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
     {
         return Siret::class === $resourceClass;
     }
 
-    public function getItem(string $resourceClass, $number, string $operationName = null, array $context = []): ?Siret
+    public function getItem(string $resourceClass, $id, string $operationName = null, array $context = []): ?Siret
     {
         $siretResponse = new Siret();
-        $siretResponse->setNumber($number);
-        $siretResponse->setIsCorrect($this->siretUtils->isSiretIsCorrect($number));
+        $siretResponse->setNumber($id);
+        $siretResponse->setIsCorrect($this->siretUtils->isSiretIsCorrect($id));
         return $siretResponse;
     }
 }

+ 2 - 8
src/Doctrine/Access/AccessExtension.php

@@ -16,14 +16,8 @@ use Symfony\Component\Security\Core\Security;
  */
 final class AccessExtension implements QueryCollectionExtensionInterface, QueryItemExtensionInterface
 {
-    private Security $security;
-    private HandleAccessExtension $handleAccessExtension;
-
-    public function __construct(Security $security, HandleAccessExtension $handleAccessExtension)
-    {
-        $this->security = $security;
-        $this->handleAccessExtension = $handleAccessExtension;
-    }
+    public function __construct(private Security $security, private HandleAccessExtension $handleAccessExtension)
+    { }
 
     public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null): void
     {

+ 1 - 1
src/Doctrine/Access/Extensions/AdminExtension.php

@@ -7,7 +7,7 @@ use App\Doctrine\Access\AccessExtensionInterface;
 use Doctrine\ORM\QueryBuilder;
 
 class AdminExtension implements AccessExtensionInterface {
-    public function support(string $name)
+    public function support(string $name): bool
     {
         return $name === 'cget_admin';
     }

+ 2 - 1
src/Doctrine/Access/Extensions/StudentsExtension.php

@@ -7,7 +7,8 @@ use App\Doctrine\Access\AccessExtensionInterface;
 use Doctrine\ORM\QueryBuilder;
 
 class StudentsExtension implements AccessExtensionInterface {
-    public function support(string $name)
+
+    public function support(string $name): bool
     {
         return $name === 'cget_students';
     }

+ 3 - 8
src/Doctrine/Access/HandleAccessExtension.php

@@ -6,17 +6,12 @@ namespace App\Doctrine\Access;
 use Doctrine\ORM\QueryBuilder;
 
 class HandleAccessExtension{
-    /** @var iterable<AccessExtensionInterface>  */
-    private iterable $extension;
-
-    public function __construct(iterable $extensions)
-    {
-        $this->extension = $extensions;
-    }
+    public function __construct(private iterable $extensions)
+    { }
 
     public function addWhere(QueryBuilder $queryBuilder, $operationName){
         /** @var AccessExtensionInterface $extension */
-        foreach ($this->extension as $extension){
+        foreach ($this->extensions as $extension){
             if($extension->support($operationName))
                 return $extension->addWhere($queryBuilder);
         }

+ 2 - 6
src/Doctrine/Access/PersonalizedListExtension.php

@@ -16,12 +16,8 @@ use Symfony\Component\Security\Core\Security;
  */
 final class PersonalizedListExtension implements QueryCollectionExtensionInterface, QueryItemExtensionInterface
 {
-    private Security $security;
-
-    public function __construct(Security $security)
-    {
-        $this->security = $security;
-    }
+    public function __construct(private Security $security)
+    { }
 
     public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null): void
     {

+ 235 - 222
src/Entity/Access/Access.php

@@ -5,129 +5,111 @@ namespace App\Entity\Access;
 
 use ApiPlatform\Core\Annotation\ApiResource;
 use ApiPlatform\Core\Annotation\ApiSubresource;
+use App\Entity\Billing\AccessIntangible;
+use App\Entity\Billing\AccessPayer;
 use App\Entity\Organization\Organization;
 use App\Entity\Organization\OrganizationLicence;
-use App\Entity\Access\PersonalizedList;
 use App\Repository\Access\AccessRepository;
 use App\Entity\Person\Person;
 use App\Entity\Person\PersonActivity;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
+use JetBrains\PhpStorm\Pure;
 use Symfony\Component\Security\Core\User\UserInterface;
 use Symfony\Component\Serializer\Annotation\Groups;
 
 /**
  * Fais le lien entre une Person et une Organization
- * @ApiResource(
- *     collectionOperations={
- *         "cget_students"={
- *             "method"="GET",
- *             "path"="/students",
- *             "security"="is_granted('ROLE_USERS_VIEW')"
- *          },
- *          "cget_admin"={
- *              "method"="GET",
- *              "path"="/admin"
- *          },
- *          "get"
- *     },
- *     itemOperations={
- *         "get"={"security"="(is_granted('ROLE_USERS_VIEW') and object.getOrganization().getId() == user.getOrganization().getId()) or (object.getId() == user.getId())"},
- *         "put"={"security"="is_granted('ROLE_USERS') or (object.getId() == user.getId())"},
- *         "delete"
- *     }
- * )
- * @ORM\Entity(repositoryClass=AccessRepository::class)
  */
+#[ApiResource(
+    collectionOperations:[
+        'cget_students'=> [
+            'method' => 'GET',
+            'path' => '/students',
+            'security' => 'is_granted("ROLE_USERS_VIEW")'
+        ],
+        'cget_admin'=> [
+            'method' => 'GET',
+            'path' => '/admin'
+        ],
+        'get'
+    ],
+    itemOperations: [
+        'get' => [
+            'security' => '(is_granted("ROLE_USERS_VIEW") and object.getOrganization().getId() == user.getOrganization().getId()) or (object.getId() == user.getId())'
+        ],
+        'put' => [
+            'security' => 'is_granted("ROLE_USERS") or (object.getId() == user.getId())'
+        ],
+        'delete'
+    ]
+)]
+#[ORM\Entity(repositoryClass: AccessRepository::class)]
 class Access implements UserInterface
 {
-    /**
-     * @ORM\Id
-     * @ORM\GeneratedValue
-     * @ORM\Column(type="integer")
-     */
-    private $id;
-
-    /**
-     * @ORM\Column(type="boolean", options={"default" : false})
-     */
-    private $adminAccess = false;
-
-    /**
-     * @ORM\Column(type="integer", nullable=true)
-     */
-    private $activityYear;
-
-    /**
-     * @ORM\ManyToOne(targetEntity=Person::class, cascade={"persist"})
-     * @ORM\JoinColumn(nullable=false)
-     */
-    private $person;
-
-    /**
-     * @ORM\ManyToOne(targetEntity=Organization::class)
-     * @ORM\JoinColumn(nullable=false)
-     */
-    public $organization;
-
-    /**
-     * @ORM\Column(type="json_array", length=4294967295, nullable=true)
-     */
-    private $roles = [];
-
-    /**
-     * @Groups({"my_access:input"})
-     * @ORM\Column(type="json_array", length=4294967295, nullable=true)
-     */
-    private $setting;
-
-    /**
-     * @Groups({"my_access:input"})
-     */
-    private $historical;
-
-    /**
-     * @var ArrayCollection<PersonActivity>
-     * @ORM\OneToMany(targetEntity=PersonActivity::class, mappedBy="access", orphanRemoval=true, cascade={"persist"})
-     * @ApiSubresource()
-     */
-    private $personActivity;
-
-    /**
-     * @var ArrayCollection<OrganizationFunction>
-     * @ORM\OneToMany(targetEntity=OrganizationFunction::class, mappedBy="access", orphanRemoval=true, cascade={"persist"})
-     * @ApiSubresource()
-     */
-    private $organizationFunction;
-
-    /**
-     * @var ArrayCollection<OrganizationLicence>
-     * @ORM\OneToMany(targetEntity=OrganizationLicence::class, mappedBy="licensee", orphanRemoval=true)
-     */
-    private $organizationLicences;
-    /**
-     * @var ArrayCollection<PersonalizedList>
-     * @ORM\OneToMany(targetEntity=PersonalizedList::class, mappedBy="access", orphanRemoval=true)
-     */
-    private $personalizedLists;
-
-    /**
-     * @var ArrayCollection<Access>
-     * @ORM\ManyToMany(targetEntity=Access::class, mappedBy="children", cascade={"persist"})
-     */
-    private $guardians;
-    /**
-     * @var ArrayCollection<Access>
-     * @ORM\ManyToMany(targetEntity=Access::class, inversedBy="guardians", cascade={"persist"})
-     * @ORM\JoinTable(name="children_guardians",
-     *      joinColumns={@ORM\JoinColumn(name="guardians_id", referencedColumnName="id")},
-     *      inverseJoinColumns={@ORM\JoinColumn(name="children_id", referencedColumnName="id")}
-     *     )
-     */
-    private $children;
-
-    public function __construct()
+    #[ORM\Id]
+    #[ORM\Column]
+    #[ORM\GeneratedValue]
+    private ?int $id = null;
+
+    #[ORM\Column(options: ['default' => false])]
+    private bool $adminAccess = false;
+
+    #[ORM\Column(nullable: true)]
+    private ?int $activityYear = null;
+
+    #[ORM\ManyToOne(cascade: ['persist'])]
+    #[ORM\JoinColumn(nullable: false)]
+    private Person $person;
+
+    #[ORM\ManyToOne]
+    #[ORM\JoinColumn(nullable: false)]
+    private Organization $organization;
+
+    #[ORM\Column(type: 'json', length: 4294967295, nullable: true)]
+    private ?array $roles = [];
+
+    #[Groups(['my_access:input'])]
+    #[ORM\Column(type: 'json', length: 4294967295, nullable: true)]
+    private ?array $setting = [];
+
+    #[Groups(['my_access:input'])]
+    private array $historical  = [];
+
+    #[ORM\OneToMany(mappedBy: 'access', targetEntity: PersonActivity::class, cascade: ['persist'], orphanRemoval: true)]
+    #[ApiSubresource]
+    private Collection $personActivity;
+
+    #[ORM\OneToMany(mappedBy: 'access', targetEntity: OrganizationFunction::class, cascade: ['persist'], orphanRemoval: true)]
+    #[ApiSubresource]
+    private Collection $organizationFunction;
+
+    #[ORM\OneToMany(mappedBy: 'licensee', targetEntity: OrganizationLicence::class, cascade: ['persist'], orphanRemoval: true)]
+    private Collection $organizationLicences;
+
+    #[ORM\OneToMany(mappedBy: 'access', targetEntity: PersonalizedList::class, cascade: ['persist'], orphanRemoval: true)]
+    private Collection $personalizedLists;
+
+    #[ORM\ManyToMany(targetEntity: Access::class, mappedBy: 'children', cascade: ['persist'])]
+    private Collection $guardians;
+
+    #[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'], orphanRemoval: true)]
+    private Collection $billingPayers;
+
+    #[ORM\OneToMany(mappedBy: 'accessReceiver', targetEntity: AccessPayer::class, cascade: ['persist'], orphanRemoval: true)]
+    private Collection $billingReceivers;
+
+    #[ORM\OneToMany(mappedBy: 'access', targetEntity: AccessIntangible::class, cascade: ['persist'], orphanRemoval: true)]
+    private Collection $accessIntangibles;
+
+    #[Pure] public function __construct()
     {
         $this->personActivity = new ArrayCollection();
         $this->organizationFunction = new ArrayCollection();
@@ -135,6 +117,9 @@ class Access implements UserInterface
         $this->personalizedLists = new ArrayCollection();
         $this->guardians = new ArrayCollection();
         $this->children = new ArrayCollection();
+        $this->billingPayers = new ArrayCollection();
+        $this->billingReceivers = new ArrayCollection();
+        $this->accessIntangibles = new ArrayCollection();
     }
 
     public function getId(): ?int
@@ -154,45 +139,68 @@ class Access implements UserInterface
         return $this;
     }
 
+    public function getPerson(): ?Person
+    {
+        return $this->person;
+    }
+
+    public function setPerson(?Person $person): self
+    {
+        $this->person = $person;
+
+        return $this;
+    }
+
+    public function getOrganization(): ?Organization
+    {
+        return $this->organization;
+    }
+
+    public function setOrganization(?Organization $organization): self
+    {
+        $this->organization = $organization;
+
+        return $this;
+    }
+
     public function getActivityYear(): ?int
     {
         return $this->activityYear;
     }
 
-    public function setActivityYear(int $activityYear): self
+    public function setActivityYear(?int $activityYear): self
     {
         $this->activityYear = $activityYear;
 
         return $this;
     }
 
-    public function getPerson(): ?Person
+    public function getHistorical(): array
     {
-        return $this->person;
+        return array_key_exists('historical', $this->setting) && $this->setting['historical'] ? $this->setting['historical'] : ['present' => true];
     }
 
-    public function setPerson(?Person $person): self
+    public function setHistorical(array $historical): self
     {
-        $this->person = $person;
+        if(!$historical['past'] && !$historical['present'] && !$historical['future'])
+            $historical['present'] = true;
 
+        $this->setting['historical'] = $historical;
         return $this;
     }
 
-    public function getOrganization(): ?Organization
+    public function setRoles(?array $roles): self
     {
-        return $this->organization;
+        $this->roles = $roles;
+        return $this;
     }
 
-    public function setOrganization(?Organization $organization): self
+    public function getRoles(): ?array
     {
-        $this->organization = $organization;
-
-        return $this;
+        $roles = $this->roles;
+        return array_unique($roles);
     }
 
-    /**
-     * @return Collection|PersonActivity[]
-     */
     public function getPersonActivity(): Collection
     {
         return $this->personActivity;
@@ -220,9 +228,6 @@ class Access implements UserInterface
         return $this;
     }
 
-    /**
-     * @return Collection|OrganizationFunction[]
-     */
     public function getOrganizationFunction(): Collection
     {
         return $this->organizationFunction;
@@ -250,95 +255,6 @@ class Access implements UserInterface
         return $this;
     }
 
-    /**
-     * A visual identifier that represents this user.
-     *
-     * @see string
-     */
-    public function getUserIdentifier(): string
-    {
-        return $this->getPerson()->getUsername();
-    }
-
-    /**
-     * @inheritDoc
-     */
-    public function setRoles(array $roles): self
-    {
-        $this->roles = $roles;
-        return $this;
-    }
-
-    /**
-     * @inheritDoc
-     */
-    public function getRoles(): array
-    {
-        $roles = $this->roles;
-        return array_unique($roles);
-    }
-
-    public function setSetting(array $setting): self
-    {
-        $this->setting = $setting;
-        return $this;
-    }
-
-
-    public function getSetting(): array
-    {
-        return $this->setting;
-    }
-
-    public function getHistorical(): array
-    {
-        return $this->setting['historical'] ?? [];
-    }
-
-    public function setHistorical(array $historical): self
-    {
-        if(!$historical['past'] && !$historical['present'] && !$historical['future'])
-            $historical['present'] = true;
-
-        $this->setting['historical'] = $historical;
-        return $this;
-    }
-
-    /**
-     * @inheritDoc
-     */
-    public function getPassword()
-    {
-        // TODO: Implement getPassword() method.
-    }
-
-    /**
-     * @inheritDoc
-     */
-    public function getSalt()
-    {
-        // TODO: Implement getSalt() method.
-    }
-
-    /**
-     * @inheritDoc
-     */
-    public function getUsername()
-    {
-        // TODO: Implement getUsername() method.
-    }
-
-    /**
-     * @inheritDoc
-     */
-    public function eraseCredentials()
-    {
-        // TODO: Implement eraseCredentials() method.
-    }
-
-    /**
-     * @return Collection|OrganizationLicence[]
-     */
     public function getOrganizationLicences(): Collection
     {
         return $this->organizationLicences;
@@ -366,9 +282,6 @@ class Access implements UserInterface
         return $this;
     }
 
-    /**
-     * @return Collection|PersonalizedList[]
-     */
     public function getPersonalizedLists(): Collection
     {
         return $this->personalizedLists;
@@ -396,9 +309,6 @@ class Access implements UserInterface
         return $this;
     }
 
-    /**
-     * @return Collection|Access[]
-     */
     public function getChildren(): Collection
     {
         return $this->children;
@@ -421,9 +331,6 @@ class Access implements UserInterface
         return $this;
     }
 
-    /**
-     * @return Collection|Access[]
-     */
     public function getGuardians(): Collection
     {
         return $this->guardians;
@@ -445,4 +352,110 @@ class Access implements UserInterface
         }
         return $this;
     }
+
+    public function getBillingPayers(): Collection
+    {
+        return $this->billingPayers;
+    }
+
+    public function addBillingPayer(AccessPayer $billingPayer): self
+    {
+        if (!$this->billingPayers->contains($billingPayer)) {
+            $this->billingPayers[] = $billingPayer;
+            $billingPayer->setAccessPayer($this);
+        }
+
+        return $this;
+    }
+
+    public function removeBillingPayer(AccessPayer $billingPayer): self
+    {
+        if ($this->billingPayers->removeElement($billingPayer)) {
+            // set the owning side to null (unless already changed)
+            if ($billingPayer->getAccessPayer() === $this) {
+                $billingPayer->setAccessPayer(null);
+            }
+        }
+
+        return $this;
+    }
+
+    public function getBillingReceivers(): Collection
+    {
+        return $this->billingReceivers;
+    }
+
+    public function addBillingReceiver(AccessPayer $billingReceiver): self
+    {
+        if (!$this->billingReceivers->contains($billingReceiver)) {
+            $this->billingReceivers[] = $billingReceiver;
+            $billingReceiver->setAccessReceiver($this);
+        }
+
+        return $this;
+    }
+
+    public function removeBillingReceiver(AccessPayer $billingPayer): self
+    {
+        if ($this->billingReceivers->removeElement($billingPayer)) {
+            // set the owning side to null (unless already changed)
+            if ($billingPayer->getAccessReceiver() === $this) {
+                $billingPayer->setAccessReceiver(null);
+            }
+        }
+
+        return $this;
+    }
+
+    public function getAccessIntangibles(): Collection
+    {
+        return $this->accessIntangibles;
+    }
+
+    public function addAccessIntangible(AccessIntangible $accessIntangibles): self
+    {
+        if (!$this->accessIntangibles->contains($accessIntangibles)) {
+            $this->accessIntangibles[] = $accessIntangibles;
+            $accessIntangibles->setAccess($this);
+        }
+
+        return $this;
+    }
+
+    public function removeAccessIntangible(AccessIntangible $accessIntangibles): self
+    {
+        if ($this->accessIntangibles->removeElement($accessIntangibles)) {
+            // set the owning side to null (unless already changed)
+            if ($accessIntangibles->getAccess() === $this) {
+                $accessIntangibles->setAccess(null);
+            }
+        }
+
+        return $this;
+    }
+
+    #[Pure] public function getUserIdentifier(): string
+    {
+        return $this->person->getUsername();
+    }
+
+    public function getPassword()
+    {
+        // TODO: Implement getPassword() method.
+    }
+
+    public function getSalt()
+    {
+        // TODO: Implement getSalt() method.
+    }
+
+    public function getUsername()
+    {
+        // TODO: Implement getUsername() method.
+    }
+
+    public function eraseCredentials()
+    {
+        // TODO: Implement eraseCredentials() method.
+    }
 }

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

@@ -0,0 +1,71 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Entity\Access;
+
+use App\Repository\Access\FunctionTypeRepository;
+use Doctrine\ORM\Mapping as ORM;
+use Symfony\Component\Validator\Constraints as Assert;
+
+/**
+ * Enum des fonctions que peuvent occuper un Access au sein d'une Organization
+ *
+ */
+#[ORM\Entity(repositoryClass: FunctionTypeRepository::class)]
+class FunctionType
+{
+    #[ORM\Id]
+    #[ORM\GeneratedValue]
+    #[ORM\Column]
+    private ?int $id = null;
+
+    #[ORM\Column]
+    #[Assert\Choice(callback: ['\App\Enum\Access\TypeFunctionEnum', 'toArray'], message: 'invalid-function-type')]
+    private string $functionType;
+
+    #[ORM\Column]
+    #[Assert\Choice(callback: ['\App\Enum\Access\FunctionEnum', 'toArray'], message: 'invalid-function')]
+    private string $mission;
+
+    #[ORM\Column]
+    #[Assert\Choice(callback: ['\App\Enum\Access\RoleEnum', 'toArray'], message: 'invalid-role')]
+    private string $roleByDefault;
+
+    public function getId(): ?int
+    {
+        return $this->id;
+    }
+
+    public function getFunctionType(): string
+    {
+        return $this->functionType;
+    }
+
+    public function setFunctionType(string $functionType): self
+    {
+        $this->functionType = $functionType;
+        return $this;
+    }
+
+    public function getMission(): string
+    {
+        return $this->mission;
+    }
+
+    public function setMission(string $mission): self
+    {
+        $this->mission = $mission;
+        return $this;
+    }
+
+    public function getRoleByDefault(): string
+    {
+        return $this->roleByDefault;
+    }
+
+    public function setRoleByDefault(string $roleByDefault): self
+    {
+        $this->roleByDefault = $roleByDefault;
+        return $this;
+    }
+}

+ 52 - 42
src/Entity/Access/OrganizationFunction.php

@@ -4,43 +4,41 @@ declare(strict_types=1);
 namespace App\Entity\Access;
 
 use ApiPlatform\Core\Annotation\ApiResource;
+use App\Entity\Traits\ActivityPeriodTrait;
 use App\Repository\Access\OrganizationFunctionRepository;
 use Doctrine\ORM\Mapping as ORM;
+use Symfony\Component\Validator\Constraints as Assert;
 
 /**
  * Fonction d'un Access dans une Organization sur une période donnée
- *
- * @ApiResource()
- * @ORM\Entity(repositoryClass=OrganizationFunctionRepository::class)
  */
+#[ApiResource]
+#[ORM\Entity(repositoryClass: OrganizationFunctionRepository::class)]
 class OrganizationFunction
 {
-    /**
-     * @ORM\Id
-     * @ORM\GeneratedValue
-     * @ORM\Column(type="integer")
-     */
-    private $id;
-
-    /**
-     * @ORM\ManyToOne(targetEntity=Access::class, inversedBy="personActivity")
-     */
-    private $access;
-
-    /**
-     * @ORM\Column(type="date")
-     */
-    private $startDate;
-
-    /**
-     * @ORM\Column(type="date", nullable=true)
-     */
-    private $endDate;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $functionComplement;
+    use ActivityPeriodTrait;
+
+    #[ORM\Id]
+    #[ORM\GeneratedValue]
+    #[ORM\Column]
+    private ?int $id = null;
+
+    #[ORM\ManyToOne(inversedBy: 'organizationFunction')]
+    private ?Access $access = null;
+
+    #[ORM\ManyToOne]
+    #[ORM\JoinColumn(nullable: false)]
+    private FunctionType $functionType;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $functionComplement = null;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    #[Assert\Choice(callback: ['\App\Enum\Access\DeparturesCauseEnum', 'toArray'], message: 'invalid-departure-cause')]
+    private ?string $departureCause = null;
+
+    #[ORM\Column(options: ['default' => true])]
+    private bool $isMemberSection = true;
 
     public function getId(): ?int
     {
@@ -59,39 +57,51 @@ class OrganizationFunction
         return $this;
     }
 
-    public function getStartDate(): ?\DateTimeInterface
+    public function setFunctionType(FunctionType $functionType): self
     {
-        return $this->startDate;
+        $this->functionType = $functionType;
+
+        return $this;
     }
 
-    public function setStartDate(\DateTimeInterface $startDate): self
+    public function getFunctionType(): FunctionType
     {
-        $this->startDate = $startDate;
+        return $this->functionType;
+    }
 
-        return $this;
+    public function getFunctionComplement(): ?string
+    {
+        return $this->functionComplement;
     }
 
-    public function getEndDate(): ?\DateTimeInterface
+    public function setFunctionComplement(?string $functionComplement): self
     {
-        return $this->endDate;
+        $this->functionComplement = $functionComplement;
+
+        return $this;
     }
 
-    public function setEndDate(?\DateTimeInterface $endDate): self
+    public function setDepartureCause(?string $departureCause): self
     {
-        $this->endDate = $endDate;
+        $this->departureCause = $departureCause;
 
         return $this;
     }
 
-    public function getFunctionComplement(): ?string
+    public function getDepartureCause():?string
     {
-        return $this->functionComplement;
+        return $this->departureCause;
     }
 
-    public function setFunctionComplement(?string $functionComplement): self
+    public function setIsMemberSection(bool $isMemberSection): self
     {
-        $this->functionComplement = $functionComplement;
+        $this->isMemberSection = $isMemberSection;
 
         return $this;
     }
+
+    public function getIsMemberSection(): bool
+    {
+        return $this->isMemberSection;
+    }
 }

+ 50 - 55
src/Entity/Access/PersonalizedList.php

@@ -7,67 +7,62 @@ namespace App\Entity\Access;
 use ApiPlatform\Core\Annotation\ApiResource;
 use App\Repository\Access\PersonalizedListRepository;
 use Doctrine\ORM\Mapping as ORM;
+use JetBrains\PhpStorm\Pure;
 use Symfony\Component\Serializer\Annotation\Groups;
 
 /**
  * Liste personnalisées
- *
- * @ApiResource(
- *     attributes={"pagination_enabled"=false},
- *     collectionOperations={
- *         "get"={"normalization_context"={"groups"={"lists:output"}}}
- *     },
- *     itemOperations={
- *         "get"={"security"="object.getAccess().getId() == user.getId()"}
- *     }
- * )
- * @ORM\Entity(repositoryClass=PersonalizedListRepository::class)
  */
+#[ApiResource(
+    collectionOperations: [
+        'get' => [
+            'normalization_context' => [
+                'groups' => ['lists:output']
+            ]
+        ]
+    ],
+    itemOperations: [
+        'get' => [
+            'security' => 'object.getAccess().getId() == user.getId()'
+        ]
+    ],
+    attributes: [
+        'pagination_enabled' => false
+    ]
+)]
+#[ORM\Entity(repositoryClass: PersonalizedListRepository::class)]
 class PersonalizedList
 {
-    /**
-     * @ORM\Id
-     * @ORM\GeneratedValue
-     * @ORM\Column(type="integer")
-     * @Groups({"lists:output"})
-     */
-    private $id;
-    /**
-     * @ORM\ManyToOne(targetEntity="Access", inversedBy="personalizedLists")
-     * @ORM\JoinColumn(nullable=false)
-     */
-    private $access;
-
-    /**
-     * @ORM\Column(type="string", length=200, nullable=true)
-     * @Groups({"lists:output"})
-     */
-    private $label;
-
-    /**
-     * @ORM\Column(type="json_array", length=4294967295, nullable=true)
-     */
-    private $filters;
-
-    /**
-     * @ORM\Column(type="string", length=150)
-     * @Groups({"lists:output"})
-     */
-    private $entity;
-
-
-    /**
-     * @ORM\Column(type="json_array", nullable=true)
-     */
-    private $columns;
-
-    /**
-     * @ORM\Column(type="string", length=150, nullable=true)
-     * @Groups({"lists:output"})
-     */
-    private $menuKey;
-
-    public function __construct()
+    #[ORM\Id]
+    #[ORM\Column]
+    #[ORM\GeneratedValue]
+    #[Groups(['lists:output'])]
+    private ?int $id = null;
+
+    #[ORM\ManyToOne(inversedBy: 'personalizedLists')]
+    #[ORM\JoinColumn(nullable: false)]
+    private ?Access $access = null;
+
+
+    #[ORM\Column(length: 200, nullable: true)]
+    #[Groups(['lists:output'])]
+    private ?string $label = null;
+
+    #[ORM\Column(length: 4294967295, nullable: true)]
+    private ?array $filters = null;
+
+    #[ORM\Column(length: 150)]
+    #[Groups(['lists:output'])]
+    private string $entity;
+
+    #[ORM\Column(length: 4294967295, nullable: true)]
+    private array $columns;
+
+    #[ORM\Column(length: 150, nullable: true)]
+    #[Groups(['lists:output'])]
+    private string $menuKey;
+
+    #[Pure] public function __construct()
     {
     }
 
@@ -109,7 +104,7 @@ class PersonalizedList
         return $this;
     }
 
-    public function getAccess(): Access
+    public function getAccess(): ?Access
     {
         return $this->access;
     }

+ 30 - 0
src/Entity/Billing/AbstractBillingIntangible.php

@@ -0,0 +1,30 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Entity\Billing;
+
+use Doctrine\ORM\Mapping as ORM;
+
+/**
+ * Enregistrement d'un produit à facturer par une Organization, un Access ou un EducationalProject
+ * Classe de base de @see AccessIntangible, EducationalProjectIntangible
+ */
+
+#[ORM\Entity]
+#[ORM\Table(name: 'BillingIntangible')]
+#[ORM\InheritanceType('SINGLE_TABLE')]
+#[ORM\DiscriminatorColumn(name: 'discr', type: 'string')]
+#[ORM\DiscriminatorMap([
+    'access' => 'AccessIntangible'
+])]
+abstract class AbstractBillingIntangible{
+    #[ORM\Id]
+    #[ORM\Column]
+    #[ORM\GeneratedValue]
+    private ?int $id = null;
+
+    public function getId(): ?int
+    {
+        return $this->id;
+    }
+}

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

@@ -0,0 +1,30 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Entity\Billing;
+
+use Doctrine\ORM\Mapping as ORM;
+
+/**
+ * Fais le lien entre l'Access qui règle la facture et l'Access ou
+ * l'EducationalProject concerné par la facture
+ * Classe de base de @see  AccessPayer, EducationalProjectPayer
+ */
+#[ORM\Entity]
+#[ORM\Table(name: 'BillingPayer')]
+#[ORM\InheritanceType('SINGLE_TABLE')]
+#[ORM\DiscriminatorColumn(name: 'discr', type: 'string')]
+#[ORM\DiscriminatorMap([
+    'access' => 'AccessPayer'
+])]
+abstract class AbstractBillingPayer{
+    #[ORM\Id]
+    #[ORM\Column]
+    #[ORM\GeneratedValue]
+    private ?int $id = null;
+
+    public function getId(): ?int
+    {
+        return $this->id;
+    }
+}

+ 31 - 0
src/Entity/Billing/AccessIntangible.php

@@ -0,0 +1,31 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Entity\Billing;
+
+use ApiPlatform\Core\Annotation\ApiResource;
+use App\Entity\Access\Access;
+use Doctrine\ORM\Mapping as ORM;
+
+/**
+ * Enregistrement d'un produit à facturer par un Access
+ */
+#[ApiResource]
+#[ORM\Entity(repositoryClass: AccessIntangible::class)]
+class AccessIntangible extends AbstractBillingIntangible
+{
+    #[ORM\ManyToOne(inversedBy: 'accessIntangibles')]
+    private ?Access $access = null;
+
+    public function setAccess(?Access $access): self
+    {
+        $this->access = $access;
+
+        return $this;
+    }
+
+    public function getAccess(): ?Access
+    {
+        return $this->access;
+    }
+}

+ 49 - 0
src/Entity/Billing/AccessPayer.php

@@ -0,0 +1,49 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Entity\Billing;
+
+use ApiPlatform\Core\Annotation\ApiResource;
+use App\Repository\Billing\AccessPayerRepository;
+use App\Entity\Access\Access;
+use Doctrine\ORM\Mapping as ORM;
+
+/**
+ * Fais le lien entre l'Access qui règle la facture et l'Access concerné
+ *
+ */
+#[ApiResource]
+#[ORM\Entity(repositoryClass: AccessPayerRepository::class)]
+class AccessPayer extends AbstractBillingPayer
+{
+    #[ORM\ManyToOne(inversedBy: 'billingPayers')]
+    private ?Access $accessPayer = null;
+
+    #[ORM\ManyToOne(inversedBy: 'billingReceivers')]
+    private ?Access $accessReceiver = null;
+
+    public function setAccessPayer(?Access $accessPayer): self
+    {
+        $this->accessPayer = $accessPayer;
+
+        return $this;
+    }
+
+    public function getAccessPayer():?Access
+    {
+        return $this->accessPayer;
+    }
+
+    public function setAccessReceiver(?Access $accessReceiver): self
+    {
+        $this->accessReceiver = $accessReceiver;
+
+        return $this;
+    }
+
+    public function getAccessReceiver():?Access
+    {
+        return $this->accessReceiver;
+    }
+}

+ 35 - 60
src/Entity/Core/AddressPostal.php

@@ -3,72 +3,47 @@ declare(strict_types=1);
 
 namespace App\Entity\Core;
 
-use ApiPlatform\Core\Annotation\ApiResource;
 use App\Entity\Organization\OrganizationAddressPostal;
 use App\Repository\Core\AddressPostalRepository;
 use Doctrine\ORM\Mapping as ORM;
 
-/**
- * @ORM\Entity(repositoryClass=AddressPostalRepository::class)
- */
+#[ORM\Entity(repositoryClass: AddressPostalRepository::class)]
 class AddressPostal
 {
-    /**
-     * @ORM\Id
-     * @ORM\GeneratedValue
-     * @ORM\Column(type="integer")
-     */
-    private $id;
-
-    /**
-     * @ORM\ManyToOne(targetEntity=Country::class)
-     */
-    private $addressCountry;
-
-    /**
-     * @ORM\Column(type="string", length=100, nullable=true)
-     */
-    private $addressCity;
-
-    /**
-     * @ORM\Column(type="string", length=100, nullable=true)
-     */
-    private $addressOwner;
-
-    /**
-     * @ORM\Column(type="string", length=20, nullable=true)
-     */
-    private $postalCode;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $streetAddress;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $streetAddressSecond;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $streetAddressThird;
-
-    /**
-     * @ORM\Column(type="float", nullable=true)
-     */
-    private $latitude;
-
-    /**
-     * @ORM\Column(type="float", nullable=true)
-     */
-    private $longitude;
-
-    /**
-     * @ORM\OneToOne(targetEntity=OrganizationAddressPostal::class, mappedBy="addressPostal", cascade={"persist", "remove"})
-     */
-    private $organizationAddressPostal;
+    #[ORM\Id]
+    #[ORM\Column]
+    #[ORM\GeneratedValue]
+    private ?int $id = null;
+
+    #[ORM\ManyToOne]
+    private Country $addressCountry;
+
+    #[ORM\Column(length: 100, nullable: true)]
+    private ?string $addressCity = null;
+
+    #[ORM\Column(length: 100, nullable: true)]
+    private ?string $addressOwner = null;
+
+    #[ORM\Column(length: 20, nullable: true)]
+    private ?string $postalCode = null;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $streetAddress = null;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $streetAddressSecond = null;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $streetAddressThird = null;
+
+    #[ORM\Column(nullable: true)]
+    private ?float $latitude = null;
+
+    #[ORM\Column(nullable: true)]
+    private ?float $longitude = null;
+
+    #[ORM\OneToOne(mappedBy: 'addressPostal', cascade: ['persist', 'remove'])]
+    private OrganizationAddressPostal $organizationAddressPostal;
 
     public function getId(): ?int
     {

+ 50 - 79
src/Entity/Core/BankAccount.php

@@ -9,103 +9,77 @@ use App\Repository\Core\BankAccountRepository;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
+use JetBrains\PhpStorm\Pure;
 use Symfony\Component\Validator\Constraints as Assert;
 
 /**
  * Données bancaire d'une Person ou d'une Organization
- *
- * @ApiResource(
- *     itemOperations={
- *           "get"={"security"="is_granted('BANK_ACCOUNT_READ', object)"},
- *           "put"={"security"="is_granted('BANK_ACCOUNT_EDIT', object)"},
- *     }
- * )
- * @ORM\Entity(repositoryClass=BankAccountRepository::class)
  */
+#[ApiResource(
+    itemOperations: [
+        'get' => [
+            'security' => 'is_granted("BANK_ACCOUNT_READ", object)'
+        ],
+        'put' => [
+            'security' => 'is_granted("BANK_ACCOUNT_EDIT", object)'
+        ]
+    ]
+)]
+#[ORM\Entity(repositoryClass: BankAccountRepository::class)]
 class BankAccount
 {
-    /**
-     * @ORM\Id
-     * @ORM\GeneratedValue
-     * @ORM\Column(type="integer")
-     */
-    private $id;
+    #[ORM\Id]
+    #[ORM\Column]
+    #[ORM\GeneratedValue]
+    private ?int $id = null;
 
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $bankName;
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $bankName = null;
 
-    /**
-     * @ORM\Column(type="string", length=11, nullable=true)
-     * @Assert\Bic(
-     *    message="invalid_bic"
-     * )
-     */
-    private $bic;
+    #[ORM\Column(length: 11, nullable: true)]
+    #[Assert\Bic(message: 'invalid_bic')]
+    private ?string $bic = null;
 
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $bicInvalid;
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $bicInvalid = null;
 
-    /**
-     * @ORM\Column(type="string", length=34, nullable=true)
-     * @Assert\Iban(
-     *    message="invalid_iban"
-     * )
-     */
-    private $iban;
+    #[ORM\Column(length: 34, nullable: true)]
+    #[Assert\Iban(message: 'invalid_iban')]
+    private ?string $iban = null;
 
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $ibanInvalid;
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $ibanInvalid = null;
 
-    /**
-     * @ORM\Column(type="boolean", options={"default" : false})
-     */
-    private $holderIdDifferent = false;
+    #[ORM\Column(options: ['default'=>false])]
+    private bool $holderIdDifferent = false;
 
     /**
      * 0 => jamais facturé, 1 => facturé 1 fois, 2 => facturé plusieurs fois
-     * @ORM\Column(type="integer", options={"default" : 0})
      */
-    private $countInvoiced;
+    #[ORM\Column(options: ['default'=>0])]
+    private int $countInvoiced;
 
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $holder;
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $holder = null;
 
-    /**
-     * @ORM\Column(type="boolean", options={"default" : false})
-     * @Assert\NotNull
-     */
-    private $principal = false;
+    #[ORM\Column(options: ['default'=>false])]
+    #[Assert\NotNull]
+    private bool $principal = false;
 
-    /**
-     * @ORM\Column(type="text", nullable=true)
-     */
-    private $debitAddress;
+    #[ORM\Column(type: 'text', nullable: true)]
+    private ?string $debitAddress = null;
 
-    /**
-     * @ORM\Column(type="string", length=35, nullable=true, unique=true)
-     */
-    private $rum;
+    #[ORM\Column(length: 35, unique: true, nullable: true)]
+    private ?string $rum = null;
 
-    /**
-     * @ORM\Column(type="date", nullable=true)
-     */
-    private $signatureDateSamplingMandate;
+    #[ORM\Column(type: 'date', nullable: true)]
+    private \DateTimeInterface $signatureDateSamplingMandate;
 
-    /**
-     * @ORM\ManyToMany(targetEntity=Organization::class, inversedBy="bankAccounts")
-     * @ORM\JoinTable(name="organization_bankaccount")
-     */
-    private $organization;
+    #[ORM\ManyToMany(targetEntity: Organization::class, inversedBy: 'bankAccounts')]
+    #[ORM\JoinTable(name: 'organization_bankaccount')]
+    private Collection $organization;
 
-    public function __construct()
+    #[Pure] public function __construct()
     {
         $this->organization = new ArrayCollection();
     }
@@ -175,7 +149,7 @@ class BankAccount
         return $this;
     }
 
-    public function getHolderIdDifferent(): ?bool
+    public function getHolderIdDifferent(): bool
     {
         return $this->holderIdDifferent;
     }
@@ -187,7 +161,7 @@ class BankAccount
         return $this;
     }
 
-    public function getCountInvoiced(): ?int
+    public function getCountInvoiced(): int
     {
         return $this->countInvoiced;
     }
@@ -211,7 +185,7 @@ class BankAccount
         return $this;
     }
 
-    public function getPrincipal(): ?bool
+    public function getPrincipal(): bool
     {
         return $this->principal;
     }
@@ -235,9 +209,6 @@ class BankAccount
         return $this;
     }
 
-    /**
-     * @return Collection|Organization[]
-     */
     public function getOrganization(): Collection
     {
         return $this->organization;

+ 60 - 83
src/Entity/Core/ContactPoint.php

@@ -6,6 +6,7 @@ namespace App\Entity\Core;
 use ApiPlatform\Core\Annotation\ApiResource;
 use App\Entity\Organization\Organization;
 use App\Entity\Person\Person;
+use JetBrains\PhpStorm\Pure;
 use libphonenumber\PhoneNumber;
 use App\Repository\Core\ContactPointRepository;
 use Doctrine\Common\Collections\ArrayCollection;
@@ -15,85 +16,67 @@ use Symfony\Component\Validator\Constraints as Assert;
 
 /**
  * Données de contact d'une Person ou d'une Organization ou d'un lieu
- * @ApiResource(
- *     itemOperations={
- *           "get"={"security"="is_granted('CONTACT_POINT_READ', object)"},
- *           "put"={"security"="is_granted('CONTACT_POINT_EDIT', object)"},
- *           "delete"={"security"="is_granted('CONTACT_POINT_DELETE', object)"},
- *     }
- * )
- * @ORM\Entity(repositoryClass=ContactPointRepository::class)
  */
+#[ApiResource(
+    itemOperations: [
+        'get' => [
+            'security' => 'is_granted("CONTACT_POINT_READ", object)'
+        ],
+        'put' => [
+            'security' => 'is_granted("CONTACT_POINT_EDIT", object)'
+        ],
+        'delete' => [
+            'security' => 'is_granted("CONTACT_POINT_DELETE", object)'
+        ]
+    ]
+)]
+#[ORM\Entity(repositoryClass: ContactPointRepository::class)]
 class ContactPoint
 {
-    /**
-     * @ORM\Id
-     * @ORM\GeneratedValue
-     * @ORM\Column(type="integer")
-     */
-    private $id;
-
-    /**
-     * @ORM\Column(type="string", length=255)
-     * @Assert\Choice(callback={"\App\Enum\Core\ContactPointTypeEnum", "toArray"}, message="invalid-choice")
-     */
-    private $contactType;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     * @Assert\Email(mode="strict", message="invalid-email-format")
-     * @Assert\Regex(pattern="/^[a-zA-Z0-9._%-]{1,64}@[a-zA-Z0-9.-]{2,249}\.[a-zA-Z]{2,6}$/", message="email-error")
-     */
-    private $email;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $emailInvalid;
-
-    /**
-     * @ORM\Column(type="phone_number", nullable=true)
-     */
-    private $faxNumber;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $faxNumberInvalid;
-
-    /**
-     * @ORM\Column(type="phone_number", nullable=true)
-     */
-    private $telphone;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $telphoneInvalid;
-
-    /**
-     * @ORM\Column(type="phone_number", nullable=true)
-     */
-    private $mobilPhone;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $mobilPhoneInvalid;
-
-    /**
-     * @ORM\ManyToMany(targetEntity=Organization::class, inversedBy="contactPoints")
-     * @ORM\JoinTable(name="organization_contactpoint")
-     */
-    private $organization;
-
-    /**
-     * @ORM\ManyToMany(targetEntity=Person::class, inversedBy="contactPoints")
-     * @ORM\JoinTable(name="person_contactpoint")
-     */
-    private $person;
-
-    public function __construct()
+    #[ORM\Id]
+    #[ORM\Column]
+    #[ORM\GeneratedValue]
+    private ?int $id = null;
+
+    #[ORM\Column(length: 255)]
+    #[Assert\Choice(callback: ['\App\Enum\Core\ContactPointTypeEnum', 'toArray'], message: 'invalid-contact-type')]
+    private string $contactType;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    #[Assert\Email(message: 'invalid-email-format', mode: 'strict')]
+    #[Assert\Regex(pattern: '/^[a-zA-Z0-9._%-]{1,64}@[a-zA-Z0-9.-]{2,249}\.[a-zA-Z]{2,6}$/', message: 'email-error')]
+    private ?string $email = null;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $emailInvalid = null;
+
+    #[ORM\Column(type: 'phone_number', nullable: true)]
+    private ?PhoneNumber $faxNumber = null;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $faxNumberInvalid = null;
+
+    #[ORM\Column(type: 'phone_number', nullable: true)]
+    private ?PhoneNumber $telphone = null;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $telphoneInvalid = null;
+
+    #[ORM\Column(type: 'phone_number', nullable: true)]
+    private ?PhoneNumber $mobilPhone = null;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $mobilPhoneInvalid = null;
+
+    #[ORM\ManyToMany(targetEntity: Organization::class, inversedBy: 'contactPoints')]
+    #[ORM\JoinTable(name: 'organization_contactpoint')]
+    private Collection $organization;
+
+    #[ORM\ManyToMany(targetEntity: Person::class ,inversedBy: 'contactPoints')]
+    #[ORM\JoinTable(name: 'person_contactpoint')]
+    private Collection $person;
+
+    #[Pure] public function __construct()
     {
         $this->organization = new ArrayCollection();
         $this->person = new ArrayCollection();
@@ -104,7 +87,7 @@ class ContactPoint
         return $this->id;
     }
 
-    public function getContactType(): ?string
+    public function getContactType(): string
     {
         return $this->contactType;
     }
@@ -224,9 +207,6 @@ class ContactPoint
         return $this;
     }
 
-    /**
-     * @return Collection|Organization[]
-     */
     public function getOrganization(): Collection
     {
         return $this->organization;
@@ -248,9 +228,6 @@ class ContactPoint
         return $this;
     }
 
-    /**
-     * @return Collection|Person[]
-     */
     public function getPerson(): Collection
     {
         return $this->person;

+ 10 - 15
src/Entity/Core/Country.php

@@ -1,33 +1,28 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Entity\Core;
 
 use App\Repository\Core\CountryRepository;
 use Doctrine\ORM\Mapping as ORM;
 
-/**
- * @ORM\Entity(repositoryClass=CountryRepository::class)
- */
+#[ORM\Entity(repositoryClass: CountryRepository::class)]
 class Country
 {
-    /**
-     * @ORM\Id
-     * @ORM\GeneratedValue
-     * @ORM\Column(type="integer")
-     */
-    private $id;
-
-    /**
-     * @ORM\Column(type="string", length=255)
-     */
-    private $name;
+    #[ORM\Id]
+    #[ORM\Column]
+    #[ORM\GeneratedValue]
+    private ?int $id = null;
+
+    #[ORM\Column(length: 255)]
+    private string $name;
 
     public function getId(): ?int
     {
         return $this->id;
     }
 
-    public function getName(): ?string
+    public function getName(): string
     {
         return $this->name;
     }

+ 24 - 44
src/Entity/Core/File.php

@@ -8,49 +8,32 @@ use App\Repository\Core\FileRepository;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
+use JetBrains\PhpStorm\Pure;
 
-/**
- * @ORM\Entity(repositoryClass=FileRepository::class)
- */
+#[ORM\Entity(repositoryClass: FileRepository::class)]
 class File
 {
-    /**
-     * @ORM\Id
-     * @ORM\GeneratedValue
-     * @ORM\Column(type="integer")
-     */
-    private $id;
-
-    /**
-     * @ORM\Column(type="string", length=255)
-     *
-     */
-    private $slug;
-    /**
-     * @var string
-     *
-     * @ORM\Column(type="string", length=255)
-     *
-     */
-    private $path;
-    /**
-     * @var string
-     *
-     * @ORM\Column(type="string", length=255)
-     */
-    private $name;
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $mimeType;
-
-    /**
-     * @var ArrayCollection<Person>
-     * @ORM\OneToMany(targetEntity=Person::class, mappedBy="image", orphanRemoval=true)
-     */
-    private $personImages;
-
-    public function __construct()
+    #[ORM\Id]
+    #[ORM\Column]
+    #[ORM\GeneratedValue]
+    private ?int $id = null;
+
+    #[ORM\Column(length: 255)]
+    private string $slug;
+
+    #[ORM\Column(length: 255)]
+    private string $path;
+
+    #[ORM\Column(length: 255)]
+    private string $name;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $mimeType = null;
+
+    #[ORM\OneToMany(mappedBy: 'image', targetEntity: Person::class, orphanRemoval: true)]
+    private Collection $personImages;
+
+    #[Pure] public function __construct()
     {
         $this->personImages = new ArrayCollection();
     }
@@ -99,15 +82,12 @@ class File
         return $this->mimeType;
     }
 
-    public function setMimeType(string $mimeType): self
+    public function setMimeType(?string $mimeType): self
     {
         $this->mimeType = $mimeType;
         return $this;
     }
 
-    /**
-     * @return Collection|Person[]
-     */
     public function getPersonImages(): Collection
     {
         return $this->personImages;

+ 15 - 24
src/Entity/Network/Network.php

@@ -8,32 +8,23 @@ use Doctrine\ORM\Mapping as ORM;
 
 /**
  * Enum des différents réseaux auxquels peut appartenir une Organization
- *
- * @ORM\Entity(repositoryClass=NetworkRepository::class)
  */
+#[ORM\Entity(repositoryClass: NetworkRepository::class)]
 class Network
 {
-    /**
-     * @ORM\Id
-     * @ORM\GeneratedValue
-     * @ORM\Column(type="integer")
-     */
-    private $id;
-
-    /**
-     * @ORM\Column(type="string", length=255)
-     */
-    private $name;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $logo;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $url;
+    #[ORM\Id]
+    #[ORM\Column]
+    #[ORM\GeneratedValue]
+    private ?int $id = null;
+
+    #[ORM\Column(length: 255)]
+    private string $name;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $logo = null;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $url = null;
 
     public function setId($id): self
     {
@@ -46,7 +37,7 @@ class Network
         return $this->id;
     }
 
-    public function getName(): ?string
+    public function getName(): string
     {
         return $this->name;
     }

+ 20 - 30
src/Entity/Network/NetworkOrganization.php

@@ -11,41 +11,31 @@ use Doctrine\ORM\Mapping as ORM;
 
 /**
  * Fait le lien entre une Organization et un Network
- * @ApiResource()
- * @ORM\Entity(repositoryClass=NetworkOrganizationRepository::class)
  */
+#[ApiResource]
+#[ORM\Entity(repositoryClass: NetworkOrganizationRepository::class)]
 class NetworkOrganization
 {
     use ActivityPeriodTrait;
 
-    /**
-     * @ORM\Id
-     * @ORM\GeneratedValue
-     * @ORM\Column(type="integer")
-     */
-    private $id;
-
-    /**
-     * @ORM\ManyToOne(targetEntity=Network::class)
-     * @ORM\JoinColumn(nullable=false)
-     */
-    private $network;
-
-    /**
-     * @ORM\ManyToOne(targetEntity=Organization::class, inversedBy="networkOrganizations")
-     * @ORM\JoinColumn(nullable=false)
-     */
-    private $organization;
-
-    /**
-     * @ORM\ManyToOne(targetEntity=Organization::class, inversedBy="networkOrganizationChildren")
-     */
-    private $parent;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $leadingCause;
+    #[ORM\Id]
+    #[ORM\Column]
+    #[ORM\GeneratedValue]
+    private ?int $id = null;
+
+    #[ORM\ManyToOne]
+    #[ORM\JoinColumn(nullable: true)]
+    private Network $network;
+
+    #[ORM\ManyToOne(inversedBy: 'networkOrganizations')]
+    #[ORM\JoinColumn(nullable: true)]
+    private Organization $organization;
+
+    #[ORM\ManyToOne(inversedBy: 'networkOrganizationChildren')]
+    private Organization $parent;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $leadingCause = null;
 
     public function getId(): ?int
     {

+ 169 - 275
src/Entity/Organization/Organization.php

@@ -12,265 +12,177 @@ use App\Repository\Organization\OrganizationRepository;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
+use JetBrains\PhpStorm\Pure;
 use Symfony\Component\Validator\Constraints as Assert;
 
 /**
  * Structure, organisation
- *
- * @ApiResource(
- *     itemOperations={
- *         "get"={"security"="(is_granted('ROLE_ORGANIZATION_VIEW') or is_granted('ROLE_ORGANIZATION')) and object.getId() == user.organization.getId() "},
- *         "put"={"security"="is_granted('ROLE_ORGANIZATION') and object.getId() == user.organization.getId() "}
- *     }
- * )
- * @ORM\Entity(repositoryClass=OrganizationRepository::class)
  */
+#[ApiResource(
+    itemOperations: [
+        'get' => [
+            'security' => '(is_granted("ROLE_ORGANIZATION_VIEW") or is_granted("ROLE_ORGANIZATION")) and object.getId() == user.getOrganization().getId()'
+        ],
+        'put' => [
+            'security' => 'is_granted("ROLE_ORGANIZATION") and object.getId() == user.getOrganization()s.getId()'
+        ]
+    ]
+)]
+#[ORM\Entity(repositoryClass: OrganizationRepository::class)]
 class Organization
 {
-    /**
-     * @ORM\Id
-     * @ORM\GeneratedValue
-     * @ORM\Column(type="integer")
-     */
-    private $id;
-
-    /**
-     * @ORM\Column(type="string", length=128)
-     */
-    private $name;
-
-    /**
-     * @ORM\Column(type="string", length=128)
-     */
-    private $identifier;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     * @Assert\Choice(callback={"\App\Enum\Organization\LegalEnum", "toArray"})
-     */
-    private $legalStatus;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     * @Assert\Choice(callback={"\App\Enum\Organization\PrincipalTypeEnum", "toArray"})
-     */
-    private $principalType;
-
-    /**
-     * @ORM\OneToOne(targetEntity=Settings::class, mappedBy="organization", cascade={"persist", "remove"})
-     */
-    private $settings;
-
-    /**
-     * @ORM\OneToMany(targetEntity=NetworkOrganization::class, mappedBy="organization", orphanRemoval=true)
-     */
-    private $networkOrganizations;
-
-    /**
-     * @ORM\OneToMany(targetEntity=NetworkOrganization::class, mappedBy="parent")
-     */
-    private $networkOrganizationChildren;
-
-    /**
-     * @ORM\OneToOne(targetEntity=Parameters::class, cascade={"persist", "remove"})
-     * @ORM\JoinColumn(nullable=false)
-     */
-    private $parameters;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $description;
-
-    /**
-     * @ORM\Column(type="date", nullable=true)
-     */
-    private $creationDate;
-
-    /**
-     * @ORM\Column(type="date", nullable=true)
-     */
-    private $declarationDate;
-
-    /**
-     * @ORM\Column(type="string", length=14, nullable=true)
-     */
-    private $siretNumber;
-
-    /**
-     * @ORM\Column(type="string", length=10, nullable=true)
-     */
-    private $waldecNumber;
-
-    /**
-     * @ORM\Column(type="string", length=5, nullable=true)
-     */
-    private $apeNumber;
-
-    /**
-     * @ORM\Column(type="string", length=50, nullable=true)
-     */
-    private $tvaNumber;
-
-    /**
-     * @ORM\Column(type="string", length=40, nullable=true)
-     */
-    private $otherType;
-
-    /**
-     * @ORM\Column(type="string", length=80, nullable=true)
-     */
-    private $acronym;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $facebook;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $twitter;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $instagram;
-
-    /**
-     * @ORM\Column(type="string", length=35, nullable=true)
-     */
-    private $collectiveAgreement;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     * @Assert\Choice(callback={"\App\Enum\Organization\OpcaEnum", "toArray"})
-     */
-    private $opca;
-
-    /**
-     * @ORM\Column(type="string", length=35, nullable=true)
-     */
-    private $icomNumber;
-
-    /**
-     * @ORM\Column(type="string", length=35, nullable=true)
-     */
-    private $urssafNumber;
-
-    /**
-     * @ORM\Column(type="string", length=20, nullable=true)
-     */
-    private $youngApproval;
-
-    /**
-     * @ORM\Column(type="string", length=20, nullable=true)
-     */
-    private $trainingApproval;
-
-    /**
-     * @ORM\Column(type="string", length=50, nullable=true)
-     */
-    private $otherApproval;
-
-    /**
-     * @ORM\Column(type="string", length=35, nullable=true)
-     */
-    private $prefectureName;
-
-    /**
-     * @ORM\Column(type="string", length=20, nullable=true)
-     */
-    private $prefectureNumber;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     * @Assert\Choice(callback={"\App\Enum\Organization\CategoryEnum", "toArray"})
-     */
-    private $category;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     * @Assert\Choice(callback={"\App\Enum\Organization\SchoolCategoryEnum", "toArray"})
-     */
-    private $schoolCategory;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     * @Assert\Choice(callback={"\App\Enum\Organization\TypeEstablishmentEnum", "toArray"})
-     */
-    private $typeEstablishment;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     * @Assert\Choice(callback={"\App\Enum\Organization\TypeEstablishmentDetailEnum", "toArray"})
-     */
-    private $typeEstablishmentDetail;
-
-    /**
-     * @ORM\Column(type="float", nullable=true)
-     */
-    private $budget;
-
-    /**
-     * @ORM\Column(type="boolean", nullable=true)
-     */
-    private $isPedagogicIsPrincipalActivity;
-
-    /**
-     * @ORM\Column(type="float", nullable=true)
-     */
-    private $pedagogicBudget;
-
-    /**
-     * @ORM\Column(type="boolean", nullable=true)
-     */
-    private $isPerformanceContractor;
-
-    /**
-     * @ORM\Column(type="string", length=20, nullable=true)
-     */
-    private $ffecApproval;
-
-    /**
-     * @ORM\Column(type="boolean")
-     */
-    private $portailVisibility;
-
-    /**
-     * @ORM\Column(type="integer", nullable=true)
-     */
-    private $cmsId;
-
-    /**
-     * @ORM\Column(type="text", nullable=true)
-     */
-    private $otherPractice;
-
-    /**
-     * @ORM\ManyToMany(targetEntity=ContactPoint::class, mappedBy="organization")
-     * @ApiSubresource()
-     */
-    private $contactPoints;
-
-    /**
-     * @ORM\ManyToMany(targetEntity=BankAccount::class, mappedBy="organization")
-     * @ApiSubresource()
-     */
-    private $bankAccounts;
-
-    /**
-     * @ORM\OneToMany(targetEntity=OrganizationAddressPostal::class, mappedBy="organization", orphanRemoval=true)
-     * @ApiSubresource()
-     */
-    private $organizationAddressPostals;
-
-    /**
-     * @ORM\OneToMany(targetEntity=OrganizationLicence::class, mappedBy="organization", orphanRemoval=true)
-     */
-    private $organizationLicences;
-
-    public function __construct()
+    #[ORM\Id]
+    #[ORM\Column]
+    #[ORM\GeneratedValue]
+    private ?int $id = null;
+
+    #[ORM\Column(length: 128)]
+    public string $name;
+
+    #[ORM\Column(length: 128)]
+    private string $identifier;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    #[Assert\Choice(callback: ['\App\Enum\Organization\LegalEnum', 'toArray'], message: 'invalid-legal-status')]
+    private ?string $legalStatus = null;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    #[Assert\Choice(callback: ['\App\Enum\Organization\PrincipalTypeEnum', 'toArray'], message: 'invalid-principal-type')]
+    private ?string $principalType = null;
+
+    #[ORM\OneToOne(mappedBy: 'organization', cascade: ['persist', 'remove'])]
+    private Settings $settings;
+
+    #[ORM\OneToMany(mappedBy: 'organization', targetEntity: NetworkOrganization::class, orphanRemoval: true)]
+    private Collection $networkOrganizations;
+
+    #[ORM\OneToMany(mappedBy: 'parent', targetEntity: NetworkOrganization::class, orphanRemoval: true)]
+    private Collection $networkOrganizationChildren;
+
+    #[ORM\OneToOne(cascade: ['persist', 'remove'])]
+    #[ORM\JoinColumn(nullable: false)]
+    private Parameters $parameters;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $description = null;
+
+    #[ORM\Column(type: 'date', nullable: true)]
+    private ?\DateTimeInterface $creationDate = null;
+
+    #[ORM\Column(type: 'date', nullable: true)]
+    private ?\DateTimeInterface $declarationDate = null;
+
+    #[ORM\Column(length: 14, nullable: true)]
+    private ?string $siretNumber = null;
+
+    #[ORM\Column(length: 10, nullable: true)]
+    private ?string $waldecNumber = null;
+
+    #[ORM\Column(length: 5, nullable: true)]
+    private ?string $apeNumber = null;
+
+    #[ORM\Column(length: 50, nullable: true)]
+    private ?string $tvaNumber = null;
+
+    #[ORM\Column(length: 40, nullable: true)]
+    private ?string $otherType = null;
+
+    #[ORM\Column(length: 80, nullable: true)]
+    private ?string $acronym = null;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $facebook = null;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $twitter = null;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $instagram = null;
+
+    #[ORM\Column(length: 35, nullable: true)]
+    private ?string $collectiveAgreement = null;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    #[Assert\Choice(callback: ['\App\Enum\Organization\OpcaEnum', 'toArray'], message: 'invalid-opca')]
+    private ?string $opca = null;
+
+    #[ORM\Column(length: 35, nullable: true)]
+    private ?string $icomNumber = null;
+
+    #[ORM\Column(length: 35, nullable: true)]
+    private ?string $urssafNumber = null;
+
+    #[ORM\Column(length: 20, nullable: true)]
+    private ?string $youngApproval = null;
+
+    #[ORM\Column(length: 20, nullable: true)]
+    private ?string $trainingApproval = null;
+
+    #[ORM\Column(length: 50, nullable: true)]
+    private ?string $otherApproval = null;
+
+    #[ORM\Column(length: 35, nullable: true)]
+    private ?string $prefectureName = null;
+
+    #[ORM\Column(length: 20, nullable: true)]
+    private ?string $prefectureNumber = null;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    #[Assert\Choice(callback: ['\App\Enum\Organization\CategoryEnum', 'toArray'], message: 'invalid-category')]
+    private ?string $category = null;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    #[Assert\Choice(callback: ['\App\Enum\Organization\SchoolCategoryEnum', 'toArray'], message: 'invalid-school-category')]
+    private ?string $schoolCategory = null;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    #[Assert\Choice(callback: ['\App\Enum\Organization\TypeEstablishmentEnum', 'toArray'], message: 'invalid-type-establishment')]
+    private ?string $typeEstablishment = null;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    #[Assert\Choice(callback: ['\App\Enum\Organization\TypeEstablishmentDetailEnum', 'toArray'], message: 'invalid-type-establishment-detail')]
+    private ?string $typeEstablishmentDetail = null;
+
+    #[ORM\Column(nullable: true)]
+    private ?float $budget = null;
+
+    #[ORM\Column(nullable: true)]
+    private ?bool $isPedagogicIsPrincipalActivity = null;
+
+    #[ORM\Column(nullable: true)]
+    private ?float $pedagogicBudget = null;
+
+    #[ORM\Column(nullable: true)]
+    private ?bool $isPerformanceContractor = null;
+
+    #[ORM\Column(length:20, nullable: true)]
+    private ?string $ffecApproval = null;
+
+    #[ORM\Column]
+    private bool $portailVisibility;
+
+    #[ORM\Column(nullable: true)]
+    private ?int $cmsId = null;
+
+    #[ORM\Column(nullable: true)]
+    private ?string $otherPractice = null;
+
+    #[ORM\ManyToMany(targetEntity: ContactPoint::class, mappedBy: 'organization')]
+    #[ApiSubresource]
+    private Collection $contactPoints;
+
+    #[ORM\ManyToMany(targetEntity: BankAccount::class, mappedBy: 'organization')]
+    #[ApiSubresource]
+    private Collection $bankAccounts;
+
+    #[ORM\OneToMany( mappedBy: 'organization', targetEntity: OrganizationAddressPostal::class, orphanRemoval: true)]
+    #[ApiSubresource]
+    private Collection $organizationAddressPostals;
+
+    #[ORM\OneToMany(mappedBy: 'organization', targetEntity: OrganizationLicence::class, orphanRemoval: true)]
+    private Collection $organizationLicences;
+
+    #[Pure] public function __construct()
     {
         $this->networkOrganizations = new ArrayCollection();
         $this->networkOrganizationChildren = new ArrayCollection();
@@ -285,7 +197,7 @@ class Organization
         return $this->id;
     }
 
-    public function getName(): ?string
+    public function getName(): string
     {
         return $this->name;
     }
@@ -297,7 +209,7 @@ class Organization
         return $this;
     }
 
-    public function getIdentifier(): ?string
+    public function getIdentifier(): string
     {
         return $this->identifier;
     }
@@ -333,7 +245,7 @@ class Organization
         return $this;
     }
 
-    public function getSettings(): ?Settings
+    public function getSettings(): Settings
     {
         return $this->settings;
     }
@@ -350,9 +262,6 @@ class Organization
         return $this;
     }
 
-    /**
-     * @return Collection|NetworkOrganization[]
-     */
     public function getNetworkOrganizations(): Collection
     {
         return $this->networkOrganizations;
@@ -380,9 +289,6 @@ class Organization
         return $this;
     }
 
-    /**
-     * @return Collection|NetworkOrganization[]
-     */
     public function getNetworkOrganizationChildren(): Collection
     {
         return $this->networkOrganizationChildren;
@@ -410,7 +316,7 @@ class Organization
         return $this;
     }
 
-    public function getParameters(): ?Parameters
+    public function getParameters(): Parameters
     {
         return $this->parameters;
     }
@@ -782,7 +688,7 @@ class Organization
         return $this;
     }
 
-    public function getPortailVisibility(): ?bool
+    public function getPortailVisibility(): bool
     {
         return $this->portailVisibility;
     }
@@ -818,9 +724,6 @@ class Organization
         return $this;
     }
 
-    /**
-     * @return Collection|ContactPoint[]
-     */
     public function getContactPoints(): Collection
     {
         return $this->contactPoints;
@@ -845,9 +748,6 @@ class Organization
         return $this;
     }
 
-    /**
-     * @return Collection|BankAccount[]
-     */
     public function getBankAccounts(): Collection
     {
         return $this->bankAccounts;
@@ -872,9 +772,6 @@ class Organization
         return $this;
     }
 
-    /**
-     * @return Collection|OrganizationAddressPostal[]
-     */
     public function getOrganizationAddressPostals(): Collection
     {
         return $this->organizationAddressPostals;
@@ -902,9 +799,6 @@ class Organization
         return $this;
     }
 
-    /**
-     * @return Collection|OrganizationLicence[]
-     */
     public function getOrganizationLicences(): Collection
     {
         return $this->organizationLicences;

+ 20 - 30
src/Entity/Organization/OrganizationAddressPostal.php

@@ -9,36 +9,26 @@ use App\Repository\Organization\OrganizationAddressPostalRepository;
 use Doctrine\ORM\Mapping as ORM;
 use Symfony\Component\Validator\Constraints as Assert;
 
-/**
- * @ApiResource()
- * @ORM\Entity(repositoryClass=OrganizationAddressPostalRepository::class)
- */
+#[ApiResource]
+#[ORM\Entity(repositoryClass: OrganizationAddressPostalRepository::class)]
 class OrganizationAddressPostal
 {
-    /**
-     * @ORM\Id
-     * @ORM\GeneratedValue
-     * @ORM\Column(type="integer")
-     */
-    private $id;
-
-    /**
-     * @ORM\ManyToOne(targetEntity=Organization::class, inversedBy="organizationAddressPostals")
-     * @ORM\JoinColumn(nullable=false)
-     */
-    private $organization;
-
-    /**
-     * @ORM\OneToOne(targetEntity=AddressPostal::class, inversedBy="organizationAddressPostal", cascade={"persist", "remove"})
-     * @ORM\JoinColumn(nullable=false)
-     */
-    private $addressPostal;
-
-    /**
-     * @ORM\Column(type="string", length=255)
-     * @Assert\Choice(callback={"AppBundle\Enum\Core\AddressPostalTypeEnum", "toArray"})
-     */
-    private $type;
+    #[ORM\Id]
+    #[ORM\Column]
+    #[ORM\GeneratedValue]
+    private ?int $id = null;
+
+    #[ORM\ManyToOne(inversedBy: 'organizationAddressPostals')]
+    #[ORM\JoinColumn(nullable: false)]
+    private ?Organization $organization = null;
+
+    #[ORM\OneToOne(inversedBy: 'organizationAddressPostal', cascade: ['persist', 'remove'])]
+    #[ORM\JoinColumn(nullable: false)]
+    private ?AddressPostal $addressPostal = null;
+
+    #[ORM\Column(length: 255)]
+    #[Assert\Choice(callback: ['\App\Enum\Core\AddressPostalTypeEnum', 'toArray'], message: 'invalid-address-postal-type')]
+    private string $type;
 
     public function getId(): ?int
     {
@@ -50,7 +40,7 @@ class OrganizationAddressPostal
         return $this->organization;
     }
 
-    public function setOrganization(?Organization $organization): self
+    public function setOrganization(Organization $organization): self
     {
         $this->organization = $organization;
 
@@ -69,7 +59,7 @@ class OrganizationAddressPostal
         return $this;
     }
 
-    public function getType(): ?string
+    public function getType(): string
     {
         return $this->type;
     }

+ 27 - 40
src/Entity/Organization/OrganizationLicence.php

@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Entity\Organization;
 
@@ -7,57 +8,43 @@ use App\Entity\Access\Access;
 use App\Repository\Organization\OrganizationLicenceRepository;
 use Doctrine\ORM\Mapping as ORM;
 
-/**
- * @ApiResource()
- * @ORM\Entity(repositoryClass=OrganizationLicenceRepository::class)
- */
+#[ApiResource]
+#[ORM\Entity(repositoryClass: OrganizationLicenceRepository::class)]
 class OrganizationLicence
 {
-    /**
-     * @ORM\Id
-     * @ORM\GeneratedValue
-     * @ORM\Column(type="integer")
-     */
-    private $id;
-
-    /**
-     * @ORM\ManyToOne(targetEntity=Organization::class, inversedBy="organizationLicences")
-     * @ORM\JoinColumn(nullable=false)
-     */
-    private $organization;
-
-    /**
-     * @ORM\ManyToOne(targetEntity=Access::class, inversedBy="organizationLicences")
-     * @ORM\JoinColumn(nullable=false)
-     */
-    private $licensee;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $licenceNumber;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $categorie;
-
-    /**
-     * @ORM\Column(type="date", nullable=true)
-     */
-    private $validityDate;
+    #[ORM\Id]
+    #[ORM\Column]
+    #[ORM\GeneratedValue]
+    private ?int $id = null;
+
+    #[ORM\ManyToOne(inversedBy: 'organizationLicences')]
+    #[ORM\JoinColumn(nullable: false)]
+    private Organization $organization;
+
+    #[ORM\ManyToOne(inversedBy: 'organizationLicences')]
+    #[ORM\JoinColumn(nullable: false)]
+    private ?Access $licensee = null;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $licenceNumber = null;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $categorie = null;
+
+    #[ORM\Column(type: 'date', nullable: true)]
+    private ?\DateTimeInterface $validityDate = null;
 
     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;
 
@@ -69,7 +56,7 @@ class OrganizationLicence
         return $this->licensee;
     }
 
-    public function setLicensee(?Access $licensee): self
+    public function setLicensee(Access $licensee): self
     {
         $this->licensee = $licensee;
 

+ 117 - 181
src/Entity/Organization/Parameters.php

@@ -8,173 +8,109 @@ use App\Repository\Organization\ParametersRepository;
 use Doctrine\ORM\Mapping as ORM;
 use Symfony\Component\Validator\Constraints as Assert;
 
-/**
- * @ApiResource()
- * @ORM\Entity(repositoryClass=ParametersRepository::class)
- */
+#[ApiResource]
+#[ORM\Entity(repositoryClass: ParametersRepository::class)]
 class Parameters
 {
-    /**
-     * @ORM\Id
-     * @ORM\GeneratedValue
-     * @ORM\Column(type="integer")
-     */
-    private $id;
-
-    /**
-     * @ORM\Column(type="date", nullable=true)
-     */
-    private $financialDate;
-
-    /**
-     * @ORM\Column(type="date", nullable=true)
-     */
-    private $musicalDate;
-
-    /**
-     * @ORM\Column(type="date", nullable=true)
-     */
-    private $startCourseDate;
-
-    /**
-     * @ORM\Column(type="date", nullable=true)
-     */
-    private $endCourseDate;
-
-    /**
-     * @ORM\Column(type="boolean", options={"default" : false})
-     */
-    private $trackingValidation = false;
-
-    /**
-     * @ORM\Column(type="boolean", options={"default" : true})
-     */
-    private $editCriteriaNotationByAdminOnly = true;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $smsSenderName;
-
-    /**
-     * @ORM\Column(type="boolean", options={"default" : false})
-     */
-    private $logoDonorsMove = false;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $subDomain;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $website;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $otherWebsite;
-
-    /**
-     * @ORM\Column(type="boolean", options={"default" : false})
-     */
-    private $desactivateOpentalentSiteWeb = false;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     * @Assert\Choice(callback={"\App\Enum\Organization\BulletinPeriodEnum", "toArray"})
-     */
-    private $bulletinPeriod;
-
-    /**
-     * @ORM\Column(type="boolean", options={"default" : false})
-     */
-    private $bulletinWithTeacher = false;
-
-    /**
-     * @ORM\Column(type="boolean", options={"default" : false})
-     */
-    private $bulletinPrintAddress = false;
-
-    /**
-     * @ORM\Column(type="boolean", options={"default" : true})
-     */
-    private $bulletinSignatureDirector = true;
-
-    /**
-     * @ORM\Column(type="boolean", options={"default" : true})
-     */
-    private $bulletinDisplayLevelAcquired = true;
-
-    /**
-     * @ORM\Column(type="boolean", options={"default" : false})
-     */
-    private $bulletinShowEducationWithoutEvaluation = false;
-
-    /**
-     * @ORM\Column(type="boolean", options={"default" : false})
-     */
-    private $bulletinViewTestResults = false;
-
-    /**
-     * @ORM\Column(type="boolean", options={"default" : false})
-     */
-    private $bulletinShowAbsences = false;
-
-    /**
-     * @ORM\Column(type="boolean", options={"default" : true})
-     */
-    private $bulletinShowAverages = true;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     * @Assert\Choice(callback={"\App\Enum\Organization\BulletinOutputEnum", "toArray"})
-     */
-    private $bulletinOutput;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $usernameSMS;
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $passwordSMS;
-
-    /**
-     * @ORM\Column(type="boolean", options={"default" : true})
-     */
-    private $bulletinEditWithoutEvaluation = true;
-
-    /**
-     * @ORM\Column(type="string", length=255, options={"default":"STUDENTS_AND_THEIR_GUARDIANS"})
-     * @Assert\Choice(callback={"\App\Enum\Organization\SendToBulletinEnum", "toArray"})
-     */
-    private $bulletinReceiver;
-
-    /**
-     * @ORM\Column(type="boolean", options={"default" : true})
-     */
-    private $showAdherentList = true;
-
-    /**
-     * @ORM\Column(type="boolean", options={"default" : false})
-     */
-    private $studentsAreAdherents = false;
-
-    /**
-     * @ORM\Column(type="string", length=255, options={"default" : "Europe/Paris"})
-     * @Assert\Choice(callback={"\App\Enum\Core\TimeZoneEnum", "toArrayCustom"})
-     */
-    private $timezone = "Europe/Paris";
-
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     * @Assert\Choice(callback={"\App\Enum\Education\PeriodicityEnum", "toArray"})
-     */
-    private $educationPeriodicity;
+    #[ORM\Id]
+    #[ORM\Column]
+    #[ORM\GeneratedValue]
+    private ?int $id = null;
+
+    #[ORM\Column(type: 'date', nullable: true)]
+    private ?\DateTimeInterface $financialDate = null;
+
+    #[ORM\Column(type: 'date', nullable: true)]
+    private ?\DateTimeInterface $musicalDate = null;
+
+    #[ORM\Column(type: 'date', nullable: true)]
+    private ?\DateTimeInterface $startCourseDate = null;
+
+    #[ORM\Column(type: 'date', nullable: true)]
+    private ?\DateTimeInterface $endCourseDate = null;
+
+    #[ORM\Column(options: ['default' => false])]
+    private bool $trackingValidation = false;
+
+    #[ORM\Column(options: ['default' => true])]
+    private bool $editCriteriaNotationByAdminOnly = true;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $smsSenderName = null;
+
+    #[ORM\Column(options: ['default' => false])]
+    private bool $logoDonorsMove = false;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $subDomain = null;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $website = null;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $otherWebsite = null;
+
+    #[ORM\Column(options: ['default' => false])]
+    private bool $desactivateOpentalentSiteWeb = false;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    #[Assert\Choice(callback: ['\App\Enum\Organization\OpcBulletinPeriodEnumaEnum', 'toArray'], message: 'invalid-bulletin-period')]
+    private ?string $bulletinPeriod = null;
+
+    #[ORM\Column(options: ['default' => false])]
+    private bool $bulletinWithTeacher = false;
+
+    #[ORM\Column(options: ['default' => false])]
+    private bool $bulletinPrintAddress = false;
+
+    #[ORM\Column(options: ['default' => true])]
+    private bool $bulletinSignatureDirector = true;
+
+    #[ORM\Column(options: ['default' => true])]
+    private bool $bulletinDisplayLevelAcquired = true;
+
+    #[ORM\Column(options: ['default' => false])]
+    private bool $bulletinShowEducationWithoutEvaluation = false;
+
+    #[ORM\Column(options: ['default' => false])]
+    private bool $bulletinViewTestResults = false;
+
+    #[ORM\Column(options: ['default' => false])]
+    private bool $bulletinShowAbsences = false;
+
+    #[ORM\Column(options: ['default' => true])]
+    private bool $bulletinShowAverages = true;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    #[Assert\Choice(callback: ['\App\Enum\Organization\BulletinOutputEnum', 'toArray'], message: 'invalid-bulletin-output')]
+    private ?string $bulletinOutput = null;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $usernameSMS = null;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $passwordSMS = null;
+
+    #[ORM\Column(options: ['default' => true])]
+    private bool $bulletinEditWithoutEvaluation = true;
+
+    #[ORM\Column(length: 255, nullable: true, options: ['default' => 'STUDENTS_AND_THEIR_GUARDIANS'])]
+    #[Assert\Choice(callback: ['\App\Enum\Organization\SendToBulletinEnum', 'toArray'], message: 'invalid-send-to-bulletin')]
+    private ?string $bulletinReceiver = null;
+
+    #[ORM\Column(options: ['default' => true])]
+    private bool $showAdherentList = true;
+
+    #[ORM\Column(options: ['default' => false])]
+    private bool $studentsAreAdherents = false;
+
+    #[ORM\Column(length: 255, options: ['default' => 'Europe/Paris'])]
+    #[Assert\Choice(callback: ['\App\Enum\Organization\TimeZoneEnum', 'toArray'], message: 'invalid-timezone')]
+    private ?string $timezone = "Europe/Paris";
+
+    #[ORM\Column(length: 255, nullable: true)]
+    #[Assert\Choice(callback: ['\App\Enum\Organization\PeriodicityEnum', 'toArray'], message: 'invalid-periodicity')]
+    private ?string $educationPeriodicity = null;
 
     public function getId(): ?int
     {
@@ -229,7 +165,7 @@ class Parameters
         return $this;
     }
 
-    public function getTrackingValidation(): ?bool
+    public function getTrackingValidation(): bool
     {
         return $this->trackingValidation;
     }
@@ -241,7 +177,7 @@ class Parameters
         return $this;
     }
 
-    public function getEditCriteriaNotationByAdminOnly(): ?bool
+    public function getEditCriteriaNotationByAdminOnly(): bool
     {
         return $this->editCriteriaNotationByAdminOnly;
     }
@@ -265,7 +201,7 @@ class Parameters
         return $this;
     }
 
-    public function getLogoDonorsMove(): ?bool
+    public function getLogoDonorsMove(): bool
     {
         return $this->logoDonorsMove;
     }
@@ -313,7 +249,7 @@ class Parameters
         return $this;
     }
 
-    public function getDesactivateOpentalentSiteWeb(): ?bool
+    public function getDesactivateOpentalentSiteWeb(): bool
     {
         return $this->desactivateOpentalentSiteWeb;
     }
@@ -337,7 +273,7 @@ class Parameters
         return $this;
     }
 
-    public function getBulletinWithTeacher(): ?bool
+    public function getBulletinWithTeacher(): bool
     {
         return $this->bulletinWithTeacher;
     }
@@ -349,7 +285,7 @@ class Parameters
         return $this;
     }
 
-    public function getBulletinPrintAddress(): ?bool
+    public function getBulletinPrintAddress(): bool
     {
         return $this->bulletinPrintAddress;
     }
@@ -361,7 +297,7 @@ class Parameters
         return $this;
     }
 
-    public function getBulletinSignatureDirector(): ?bool
+    public function getBulletinSignatureDirector(): bool
     {
         return $this->bulletinSignatureDirector;
     }
@@ -373,7 +309,7 @@ class Parameters
         return $this;
     }
 
-    public function getBulletinDisplayLevelAcquired(): ?bool
+    public function getBulletinDisplayLevelAcquired(): bool
     {
         return $this->bulletinDisplayLevelAcquired;
     }
@@ -385,7 +321,7 @@ class Parameters
         return $this;
     }
 
-    public function getBulletinShowEducationWithoutEvaluation(): ?bool
+    public function getBulletinShowEducationWithoutEvaluation(): bool
     {
         return $this->bulletinShowEducationWithoutEvaluation;
     }
@@ -397,7 +333,7 @@ class Parameters
         return $this;
     }
 
-    public function getBulletinViewTestResults(): ?bool
+    public function getBulletinViewTestResults(): bool
     {
         return $this->bulletinViewTestResults;
     }
@@ -409,7 +345,7 @@ class Parameters
         return $this;
     }
 
-    public function getBulletinShowAbsences(): ?bool
+    public function getBulletinShowAbsences(): bool
     {
         return $this->bulletinShowAbsences;
     }
@@ -421,7 +357,7 @@ class Parameters
         return $this;
     }
 
-    public function getBulletinShowAverages(): ?bool
+    public function getBulletinShowAverages(): bool
     {
         return $this->bulletinShowAverages;
     }
@@ -469,7 +405,7 @@ class Parameters
         return $this;
     }
 
-    public function getBulletinEditWithoutEvaluation(): ?bool
+    public function getBulletinEditWithoutEvaluation(): bool
     {
         return $this->bulletinEditWithoutEvaluation;
     }
@@ -493,7 +429,7 @@ class Parameters
         return $this;
     }
 
-    public function getShowAdherentList(): ?bool
+    public function getShowAdherentList(): bool
     {
         return $this->showAdherentList;
     }
@@ -505,7 +441,7 @@ class Parameters
         return $this;
     }
 
-    public function getStudentsAreAdherents(): ?bool
+    public function getStudentsAreAdherents(): bool
     {
         return $this->studentsAreAdherents;
     }
@@ -517,7 +453,7 @@ class Parameters
         return $this;
     }
 
-    public function getTimezone(): ?string
+    public function getTimezone(): string
     {
         return $this->timezone;
     }

+ 25 - 39
src/Entity/Organization/Settings.php

@@ -4,52 +4,38 @@ declare(strict_types=1);
 namespace App\Entity\Organization;
 
 use ApiPlatform\Core\Annotation\ApiResource;
-use App\Enum\Organization\settingsProductEnum;
 use App\Repository\Organization\SettingsRepository;
 use Doctrine\ORM\Mapping as ORM;
 use Symfony\Component\Validator\Constraints as Assert;
 
 /**
  * Caractéristiques d'une Organization (produits, options...etc)
- *
- * @ApiResource()
- * @ORM\Entity(repositoryClass=SettingsRepository::class)
  */
+#[ApiResource]
+#[ORM\Entity(repositoryClass: SettingsRepository::class)]
 class Settings
 {
-    /**
-     * @ORM\Id
-     * @ORM\GeneratedValue
-     * @ORM\Column(type="integer")
-     */
-    private $id;
-
-    /**
-     * @ORM\OneToOne(targetEntity=Organization::class, inversedBy="settings", cascade={"persist", "remove"})
-     * @ORM\JoinColumn(nullable=false)
-     */
-    private $organization;
-
-    /**
-     * @ORM\Column(type="string", length=255)
-     * @Assert\Choice(callback={"\App\Enum\Organization\SettingsProductEnum", "toArray"})
-     */
-    private $product;
-
-    /**
-     * @ORM\Column(type="json", nullable=true)
-     */
-    private $modules = [];
-
-    /**
-     * @ORM\Column(type="json", nullable=true)
-     */
-    private $actions = [];
-
-    /**
-     * @ORM\Column(type="string", length=255, options={"default":"FRANCE"})
-     */
-    private $country;
+    #[ORM\Id]
+    #[ORM\Column]
+    #[ORM\GeneratedValue]
+    private ?int $id = null;
+
+    #[ORM\OneToOne(inversedBy: 'settings', cascade: ['persist', 'remove'])]
+    #[ORM\JoinColumn(nullable: false)]
+    private ?Organization $organization = null;
+
+    #[ORM\Column(length: 255)]
+    #[Assert\Choice(callback: ['\App\Enum\Organization\SettingsProductEnum', 'toArray'], message: 'invalid-product')]
+    private string $product;
+
+    #[ORM\Column(type: 'json', length: 4294967295, nullable: true)]
+    private ?array $modules = [];
+
+    #[ORM\Column(type: 'json', length: 4294967295, nullable: true)]
+    private ?array $actions = [];
+
+    #[ORM\Column(length: 255, options: ['default' => 'FRANCE'])]
+    private string $country;
 
     public function getId(): ?int
     {
@@ -68,7 +54,7 @@ class Settings
         return $this;
     }
 
-    public function getProduct(): ?string
+    public function getProduct(): string
     {
         return $this->product;
     }
@@ -104,7 +90,7 @@ class Settings
         return $this;
     }
 
-    public function getCountry(): ?string
+    public function getCountry(): string
     {
         return $this->country;
     }

+ 32 - 75
src/Entity/Person/Person.php

@@ -10,69 +10,48 @@ use App\Repository\Person\PersonRepository;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
+use JetBrains\PhpStorm\Pure;
 use Symfony\Component\Security\Core\User\UserInterface;
 use Symfony\Component\Validator\Constraints as Assert;
 
 /**
  * Personne physique ou morale
- *
- * @ORM\Entity(repositoryClass=PersonRepository::class)
- * @ApiResource()
  */
+#[ApiResource]
+#[ORM\Entity(repositoryClass: PersonRepository::class)]
 class Person implements UserInterface
 {
-    /**
-     * @ORM\Id
-     * @ORM\GeneratedValue
-     * @ORM\Column(type="integer")
-     */
-    private $id;
+    #[ORM\Id]
+    #[ORM\Column]
+    #[ORM\GeneratedValue]
+    private ?int $id = null;
 
-    /**
-     * @ORM\Column(type="string", length=180, unique=true)
-     */
-    private $username;
+    #[ORM\Column(length: 180, unique: true, nullable: true)]
+    private ?string $username = null;
 
-    /**
-     *
-     */
-    private $roles = [];
+    private array $roles = [];
 
-    /**
-     * @var string The hashed password
-     * @ORM\Column(type="string")
-     */
-    private $password;
+    #[ORM\Column(nullable: true)]
+    private ?string $password = null;
 
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $name;
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $name = null;
 
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $givenName;
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $givenName = null;
 
-    /**
-     * @ORM\ManyToMany(targetEntity=ContactPoint::class, mappedBy="person")
-     */
-    private $contactPoints;
+    #[ORM\ManyToMany(targetEntity: ContactPoint::class, mappedBy: 'person')]
+    private Collection $contactPoints;
 
-    /**
-     * @var string Gender of the person.
-     * @ORM\Column(type="string", nullable=true)
-     * @Assert\Choice(callback={"App\Enum\Person\GenderEnum", "toArray"})
-     */
-    private $gender;
+    #[ORM\Column(nullable: true)]
+    #[Assert\Choice(callback: ['\App\Enum\Person\GenderEnum', 'toArray'], message: 'invalid-gender')]
+    private ?string $gender = null;
 
-    /**
-     * @ORM\ManyToOne(targetEntity=File::class, inversedBy="personImages")
-     * @ORM\JoinColumn(referencedColumnName="id", nullable=true, onDelete="SET NULL")
-     */
-    private $image;
+    #[ORM\ManyToOne(inversedBy: 'personImages')]
+    #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
+    private ?File $image = null;
 
-    public function __construct()
+    #[Pure] public function __construct()
     {
         $this->contactPoints = new ArrayCollection();
     }
@@ -82,36 +61,23 @@ class Person implements UserInterface
         return $this->id;
     }
 
-    /**
-     * A visual identifier that represents this user.
-     *
-     * @see UserInterface
-     */
-    public function getUsername(): string
+    public function getUsername(): ?string
     {
         return (string) $this->username;
     }
 
-    /**
-     * A visual identifier that represents this user.
-     *
-     * @see string
-     */
-    public function getUserIdentifier(): string
+    public function getUserIdentifier(): ?string
     {
         return (string) $this->username;
     }
 
-    public function setUsername(string $username): self
+    public function setUsername(?string $username): self
     {
         $this->username = $username;
 
         return $this;
     }
 
-    /**
-     * @see UserInterface
-     */
     public function getRoles(): array
     {
         $roles = $this->roles;
@@ -128,32 +94,23 @@ class Person implements UserInterface
         return $this;
     }
 
-    /**
-     * @see UserInterface
-     */
-    public function getPassword(): string
+    public function getPassword(): ?string
     {
         return (string) $this->password;
     }
 
-    public function setPassword(string $password): self
+    public function setPassword(?string $password): self
     {
         $this->password = $password;
 
         return $this;
     }
 
-    /**
-     * @see UserInterface
-     */
     public function getSalt()
     {
         // not needed when using the "bcrypt" algorithm in security.yaml
     }
 
-    /**
-     * @see UserInterface
-     */
     public function eraseCredentials()
     {
         // If you store any temporary, sensitive data on the user, clear it here
@@ -184,7 +141,7 @@ class Person implements UserInterface
         return $this;
     }
 
-    public function setGender($gender): self
+    public function setGender(?string $gender): self
     {
         $this->gender = $gender;
         return $this;
@@ -222,7 +179,7 @@ class Person implements UserInterface
         return $this;
     }
 
-    public function setImage(File $image):self
+    public function setImage(?File $image):self
     {
         $this->image = $image;
         return $this;

+ 12 - 50
src/Entity/Person/PersonActivity.php

@@ -5,43 +5,29 @@ namespace App\Entity\Person;
 
 use ApiPlatform\Core\Annotation\ApiResource;
 use App\Entity\Access\Access;
+use App\Entity\Traits\ActivityPeriodTrait;
 use App\Repository\Person\PersonActivityRepository;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
  * Lien entre une Person et une Activity
- *
- * @ApiResource()
- * @ORM\Entity(repositoryClass=PersonActivityRepository::class)
  */
+#[ApiResource]
+#[ORM\Entity(repositoryClass: PersonActivityRepository::class)]
 class PersonActivity
 {
-    /**
-     * @ORM\Id
-     * @ORM\GeneratedValue
-     * @ORM\Column(type="integer")
-     */
-    private $id;
+    use ActivityPeriodTrait;
 
-    /**
-     * @ORM\Column(type="string", length=255, nullable=true)
-     */
-    private $complementSpeciality;
+    #[ORM\Id]
+    #[ORM\Column]
+    #[ORM\GeneratedValue]
+    private ?int $id = null;
 
-    /**
-     * @ORM\Column(type="date")
-     */
-    private $startDate;
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $complementSpeciality = null;
 
-    /**
-     * @ORM\Column(type="date", nullable=true)
-     */
-    private $endDate;
-
-    /**
-     * @ORM\ManyToOne(targetEntity=Access::class, inversedBy="personActivity")
-     */
-    private $access;
+    #[ORM\ManyToOne(inversedBy: 'personActivity')]
+    private ?Access $access = null;
 
     public function getId(): ?int
     {
@@ -60,30 +46,6 @@ class PersonActivity
         return $this;
     }
 
-    public function getStartDate(): ?\DateTimeInterface
-    {
-        return $this->startDate;
-    }
-
-    public function setStartDate(\DateTimeInterface $startDate): self
-    {
-        $this->startDate = $startDate;
-
-        return $this;
-    }
-
-    public function getEndDate(): ?\DateTimeInterface
-    {
-        return $this->endDate;
-    }
-
-    public function setEndDate(?\DateTimeInterface $endDate): self
-    {
-        $this->endDate = $endDate;
-
-        return $this;
-    }
-
     public function getAccess(): ?Access
     {
         return $this->access;

+ 8 - 39
src/Entity/Traits/ActivityPeriodTrait.php

@@ -8,58 +8,27 @@ use Symfony\Component\Validator\Constraints as Assert;
 
 trait ActivityPeriodTrait
 {
-    /**
-     * @var \DateTime
-     *
-     * @ORM\Column(type="date", nullable=true)
-     * @Assert\Date
-     */
-    private $startDate;
+    #[ORM\Column(type: 'date', nullable: true)]
+    private ?\DateTimeInterface $startDate = null;
 
-    /**
-     * @var \DateTime
-     *
-     * @ORM\Column(type="date", nullable=true)
-     * @Assert\Date
-     */
-    private $endDate;
+    #[ORM\Column(type: 'date', nullable: true)]
+    private ?\DateTimeInterface $endDate = null;
 
-    /**
-     * Gets start date
-     *
-     * @return \DateTime
-     */
     public function getStartDate(): ?string {
-        return $this->startDate ? $this->startDate->format('Y-m-d') : null;
+        return $this->startDate?->format('Y-m-d');
     }
 
-    /**
-     * @param \DateTime|null $startDate
-     * @return $this
-     * @throws \Exception
-     */
-    public function setStartDate(\DateTime $startDate = null): self {
+    public function setStartDate(?\DateTime $startDate = null): self {
         if($startDate == null) $startDate = new \DateTime();
         $this->startDate = $startDate;
         return $this;
     }
 
-    /**
-     * Gets end date
-     *
-     * @return \DateTime
-     */
     public function getEndDate(): ?string {
-        return $this->endDate ? $this->endDate->format('Y-m-d') : null;
+        return $this->endDate?->format('Y-m-d');
     }
 
-    /**
-     * Sets end date
-     *
-     * @param \DateTime $endDate
-     * @return $this
-     */
-    public function setEndDate(\DateTime $endDate = null) :self {
+    public function setEndDate(?\DateTime $endDate = null) :self {
         $this->endDate = $endDate;
         return $this;
     }

+ 11 - 40
src/Entity/Traits/ActivityYearTrait.php

@@ -7,57 +7,28 @@ use Doctrine\ORM\Mapping as ORM;
 
 trait ActivityYearTrait
 {
-    /**
-     * @var int
-     *
-     * @ORM\Column(type="integer", nullable=true)
-     */
-    private $startYear;
 
-    /**
-     * @var int
-     *
-     * @ORM\Column(type="integer", nullable=true)
-     */
-    private $endYear;
-    
-    /**
-     * Gets start year
-     * 
-     * @return int
-     */
-    public function getStartYear(): int {
+    #[ORM\Column(nullable: true)]
+    private ?int $startYear = null;
+
+    #[ORM\Column(nullable: true)]
+    private ?int $endYear = null;
+
+    public function getStartYear(): ?int {
         return $this->startYear;
     }
-    
-    /**
-     * Sets start year
-     * 
-     * @param int $startYear
-     * @return $this
-     */
-    public function setStartYear($startYear = null):self {
+
+    public function setStartYear(?int $startYear = null):self {
         if($startYear == null) $startYear = date('Y');
         $this->startYear = $startYear;
         return $this;
     }
 
-    /**
-     * Gets end year
-     *
-     * @return int
-     */
-    public function getEndYear():int {
+    public function getEndYear():?int {
         return $this->endYear;
     }
 
-    /**
-     * Sets end year
-     *
-     * @param int $endYear
-     * @return $this
-     */
-    public function setEndYear($endYear):self {
+    public function setEndYear(?int $endYear):self {
         $this->endYear = $endYear;
         return $this;
     }

+ 23 - 0
src/Enum/Access/DeparturesCauseEnum.php

@@ -0,0 +1,23 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Enum\Access;
+
+use MyCLabs\Enum\Enum;
+
+/**
+ * Due to departures.
+ */
+class DeparturesCauseEnum extends Enum
+{
+    private const LEFT_THE_STRUCTURE = 'LEFT_THE_STRUCTURE';
+    private const DEATH = 'DEATH';
+    private const REFERENCE = 'REFERENCE';
+    private const ABANDONMENT = 'ABANDONMENT';
+    private const SABBATICAL = 'SABBATICAL';
+    private const OTHER = 'OTHER';
+    private const MOVE = 'MOVE';
+    private const DISEASE = 'DISEASE';
+    private const RESIGNATION = 'RESIGNATION';
+    private const END_OF_TERM = 'END_OF_TERM';
+}

+ 103 - 0
src/Enum/Access/FunctionEnum.php

@@ -0,0 +1,103 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Enum\Access;
+
+use MyCLabs\Enum\Enum;
+
+/**
+ * Activities functions.
+ */
+class FunctionEnum extends Enum
+{
+    private const STUDENT = 'STUDENT';
+    private const TEACHER = 'TEACHER';
+    private const DIRECTOR = 'DIRECTOR';
+    private const DIRECTOR_ASSISTANT = 'DIRECTOR_ASSISTANT';
+    private const INITIATOR = 'INITIATOR';
+    private const MONITOR = 'MONITOR';
+
+    private const MUSIC_DIRECTOR_AND_HEAD = 'MUSIC_DIRECTOR_AND_HEAD';
+    private const MUSIC_DIRECTOR_AND_HEAD_ASSISTANT = 'MUSIC_DIRECTOR_AND_HEAD_ASSISTANT';
+    private const DESK_OFFICER = 'DESK_OFFICER';
+
+    private const ADMINISTRATIVE_OFFICER = 'ADMINISTRATIVE_OFFICER';
+    private const ADMINISTRATIVE_SECRETARY = 'ADMINISTRATIVE_SECRETARY';
+    private const ADMINISTRATIVE_DIRECTOR = 'ADMINISTRATIVE_DIRECTOR';
+    private const ADMINISTRATIVE_DIRECTOR_ASSISTANT = 'ADMINISTRATIVE_DIRECTOR_ASSISTANT';
+    private const ARCHIVIST = 'ARCHIVIST';
+    private const PRESENTER = 'PRESENTER';
+    private const ADMINISTRATIVE_STAFF = 'ADMINISTRATIVE_STAFF';
+    private const NETWORK_ANIMATOR = 'NETWORK_ANIMATOR';
+    private const CORRESPONDING = 'CORRESPONDING';
+    private const COORDINATOR = 'COORDINATOR';
+    private const TECHNICAL_STAFF = 'TECHNICAL_STAFF';
+    private const ACCOUNTANT = 'ACCOUNTANT';
+
+    private const ACTIVE_MEMBER_OF_THE_CA = 'ACTIVE_MEMBER_OF_THE_CA';
+    private const HONORARY_PRESIDENT = 'HONORARY_PRESIDENT';
+    private const PRESIDENT = 'PRESIDENT';
+    private const YOUTH_REPRESENTATIVE = 'YOUTH_REPRESENTATIVE';
+    private const SECRETARY = 'SECRETARY';
+    private const ASSISTANT_SECRETARY = 'ASSISTANT_SECRETARY';
+    private const TREASURER = 'TREASURER';
+    private const TREASURER_ASSISTANT = 'TREASURER_ASSISTANT';
+    private const VICE_PRESIDENT = 'VICE_PRESIDENT';
+    private const ADHERENT = 'ADHERENT';
+    private const NO_MEMBER = 'NO_MEMBER';
+    private const VICE_PRESIDENT_OF_HONOR = 'VICE_PRESIDENT_OF_HONOR';
+    private const HOUR_PRESIDENT = 'HOUR_PRESIDENT';
+    private const PRESIDENT_ASSISTANT = 'PRESIDENT_ASSISTANT';
+    private const ACTIVE_COOPTED_MEMBER_OF_THE_CA = 'ACTIVE_COOPTED_MEMBER_OF_THE_CA';
+    private const ACTIVE_SUBSTITUTE_MEMBER_OF_THE_CA = 'ACTIVE_SUBSTITUTE_MEMBER_OF_THE_CA';
+    private const MEMBER_OF_THE_BOARD = 'MEMBER_OF_THE_BOARD';
+    private const MEMBER_OF_BOARD_OF_HONOR = 'MEMBER_OF_BOARD_OF_HONOR';
+    private const HONORARY_MEMBER = 'HONORARY_MEMBER';
+    private const BENEFACTOR_MEMBER = 'BENEFACTOR_MEMBER';
+    private const HOUR_MEMBER = 'HOUR_MEMBER';
+
+    private const OTHER = 'OTHER';
+
+    public static function getOrganizationStaffAndBoardOfDirectorsMission(){
+        return [
+            self::ACTIVE_MEMBER_OF_THE_CA,
+            self::HONORARY_PRESIDENT,
+            self::PRESIDENT,
+            self::YOUTH_REPRESENTATIVE,
+            self::SECRETARY,
+            self::ASSISTANT_SECRETARY,
+            self::TREASURER,
+            self::TREASURER_ASSISTANT,
+            self::VICE_PRESIDENT,
+            self::VICE_PRESIDENT_OF_HONOR,
+            self::HOUR_PRESIDENT,
+            self::PRESIDENT_ASSISTANT,
+            self::ACTIVE_COOPTED_MEMBER_OF_THE_CA,
+            self::ACTIVE_SUBSTITUTE_MEMBER_OF_THE_CA,
+            self::MEMBER_OF_THE_BOARD,
+            self::MEMBER_OF_BOARD_OF_HONOR,
+            self::SECRETARY,
+            self::TREASURER,
+            self::DIRECTOR,
+            self::DIRECTOR_ASSISTANT,
+            self::ADMINISTRATIVE_DIRECTOR,
+            self::ADMINISTRATIVE_DIRECTOR_ASSISTANT,
+            self::MUSIC_DIRECTOR_AND_HEAD,
+            self::MUSIC_DIRECTOR_AND_HEAD_ASSISTANT,
+            self::DESK_OFFICER,
+            self::ADMINISTRATIVE_OFFICER,
+            self::ADMINISTRATIVE_SECRETARY,
+            self::ARCHIVIST,
+            self::PRESENTER,
+            self::ADMINISTRATIVE_STAFF,
+            self::NETWORK_ANIMATOR,
+            self::CORRESPONDING,
+            self::COORDINATOR,
+            self::TECHNICAL_STAFF,
+            self::ACCOUNTANT,
+            self::MUSIC_DIRECTOR_AND_HEAD
+        ];
+    }
+}
+
+

+ 24 - 0
src/Enum/Access/RoleEnum.php

@@ -0,0 +1,24 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Enum\Access;
+
+use MyCLabs\Enum\Enum;
+
+/**
+ * Role
+ */
+class RoleEnum extends Enum
+{
+    private const ROLE_ADMIN = 'ROLE_ADMIN';
+    private const ROLE_ADMINISTRATIF_MANAGER = 'ROLE_ADMINISTRATIF_MANAGER';
+    private const ROLE_PEDAGOGICS_MANAGER = 'ROLE_PEDAGOGICS_MANAGER';
+    private const ROLE_FINANCIAL_MANAGER = 'ROLE_FINANCIAL_MANAGER';
+    private const ROLE_CA = 'ROLE_CA';
+    private const ROLE_STUDENT = 'ROLE_STUDENT';
+    private const ROLE_TEACHER = 'ROLE_TEACHER';
+    private const ROLE_MEMBER = 'ROLE_MEMBER';
+    private const ROLE_OTHER = 'ROLE_OTHER';
+}
+
+

+ 18 - 0
src/Enum/Access/TypeFunctionEnum.php

@@ -0,0 +1,18 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Enum\Access;
+
+use MyCLabs\Enum\Enum;
+
+/**
+ * Type of function.
+ */
+class TypeFunctionEnum extends Enum
+{
+   private const ACTIVITIES_FUNCTION = 'ACTIVITIES_FUNCTION';
+   private const ADMINISTRATIVES_FUNCTION = 'ADMINISTRATIVES_FUNCTION';
+   private const PEDAGOGICS_FUNCTION = 'PEDAGOGICS_FUNCTION';
+   private const ASSOCIATIVES_FUNCTION = 'ASSOCIATIVES_FUNCTION';
+   private const OTHER_FUNCTION = 'OTHER_FUNCTION';
+}

+ 2 - 5
src/Enum/Core/ContactPointTypeEnum.php

@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Enum\Core;
 
@@ -15,11 +16,7 @@ class ContactPointTypeEnum extends Enum
     private const OTHER = 'OTHER';
     private const CONTACT = 'CONTACT';
 
-    /**
-     * @param bool $type
-     * @return array
-     */
-    public static function toArray($type = false)
+    public static function toArray(bool $type = false): array
     {
         if($type == 'person'){
             return ['PRINCIPAL'=>self::PRINCIPAL,'OTHER'=>self::OTHER];

+ 2 - 2
src/Enum/Core/TimeZoneEnum.php

@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Enum\Core;
 
@@ -12,9 +13,8 @@ class TimeZoneEnum extends Enum
 {
     /**
      * Return a custom array instead the original array
-     * @return mixed
      */
-    public static function toArray()
+    public static function toArray(): array
     {
         return [
          'Indian/Reunion' => 'Indian/Reunion',

+ 1 - 0
src/Enum/Education/PeriodicityEnum.php

@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Enum\Education;
 

+ 1 - 0
src/Enum/Network/LeadingCauseEnum.php

@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Enum\Network;
 

+ 1 - 0
src/Enum/Network/NetworkEnum.php

@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Enum\Network;
 

+ 2 - 0
src/Enum/Organization/AddressPostalOrganizationTypeEnum.php

@@ -1,4 +1,6 @@
 <?php
+declare(strict_types=1);
+
 namespace App\Enum\Organization;
 
 use MyCLabs\Enum\Enum;

+ 1 - 0
src/Enum/Organization/BulletinOutputEnum.php

@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Enum\Organization;
 

+ 1 - 0
src/Enum/Organization/BulletinPeriodEnum.php

@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Enum\Organization;
 

+ 1 - 0
src/Enum/Organization/CategoryEnum.php

@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Enum\Organization;
 

+ 1 - 0
src/Enum/Organization/LegalEnum.php

@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Enum\Organization;
 

+ 1 - 0
src/Enum/Organization/OpcaEnum.php

@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Enum\Organization;
 

+ 1 - 0
src/Enum/Organization/OrganizationIdsEnum.php

@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Enum\Organization;
 

+ 1 - 0
src/Enum/Organization/PrincipalTypeEnum.php

@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Enum\Organization;
 

+ 1 - 0
src/Enum/Organization/SchoolCategoryEnum.php

@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Enum\Organization;
 

+ 1 - 0
src/Enum/Organization/SendToBulletinEnum.php

@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Enum\Organization;
 

+ 1 - 0
src/Enum/Organization/SettingsProductEnum.php

@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Enum\Organization;
 

+ 1 - 0
src/Enum/Organization/TypeEstablishmentDetailEnum.php

@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Enum\Organization;
 

+ 1 - 0
src/Enum/Organization/TypeEstablishmentEnum.php

@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Enum\Organization;
 

+ 23 - 7
src/Repository/Access/AccessRepository.php

@@ -3,6 +3,7 @@ declare(strict_types=1);
 
 namespace App\Repository\Access;
 
+use App\DQL\DateConditions;
 use App\Entity\Access\Access;
 use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
 use Doctrine\Persistence\ManagerRegistry;
@@ -20,12 +21,9 @@ class AccessRepository extends ServiceEntityRepository implements UserLoaderInte
     const ACCESS_NAME_HEADER = 'X-AccessId';
     const HTTP_X_SWITCH_USER = 'X-Switch-User';
 
-    private RequestStack $requestStack;
-
-    public function __construct(ManagerRegistry $registry, RequestStack $requestStack)
+    public function __construct(ManagerRegistry $registry, private RequestStack $requestStack)
     {
         parent::__construct($registry, Access::class);
-        $this->requestStack = $requestStack;
     }
 
     /**
@@ -44,7 +42,8 @@ class AccessRepository extends ServiceEntityRepository implements UserLoaderInte
      * @throws \Doctrine\ORM\OptimisticLockException
      * @throws \Doctrine\ORM\TransactionRequiredException
      */
-    public function loadUserByIdentifier($identifier){
+    public function loadUserByIdentifier($identifier): mixed
+    {
         if($this->requestStack->getMainRequest()->headers->get(self::HTTP_X_SWITCH_USER) == $identifier)
             return $this->getEntityManager()->find(Access::class, $identifier);
 
@@ -58,7 +57,8 @@ class AccessRepository extends ServiceEntityRepository implements UserLoaderInte
      * @return mixed
      * @throws \Doctrine\ORM\NonUniqueResultException
      */
-    private function findAccessByUsernameAndAccessId(string $username, $id){
+    private function findAccessByUsernameAndAccessId(string $username, $id): mixed
+    {
         $entityManager = $this->getEntityManager();
         return $entityManager->createQuery(
             'SELECT a
@@ -76,7 +76,7 @@ class AccessRepository extends ServiceEntityRepository implements UserLoaderInte
      * @return mixed
      * @throws \Exception
      */
-    public function findAllValidAccesses(Access $acces)
+    public function findAllValidAccesses(Access $acces): array
     {
         $datetime = new \DateTime();
         $today = $datetime->format('Y-m-d');
@@ -92,4 +92,20 @@ class AccessRepository extends ServiceEntityRepository implements UserLoaderInte
             ->getResult()
       ;
     }
+
+    public function hasGotFunctionAtThisDate(Access $access, $function, \DateTime $date): bool
+    {
+        $qb = $this->createQueryBuilder('access');
+        $qb
+            ->innerJoin('access.organizationFunction', 'organization_function')
+            ->innerJoin('organization_function.functionType', 'function_type')
+            ->where('function_type.mission = :mission')
+            ->andWhere('access.id = :id')
+            ->setParameter('id', $access->getId())
+            ->setParameter('mission', $function)
+        ;
+        DateConditions::addDateInPeriodCondition($qb, 'organization_function', $date->format('Y-m-d'));
+
+        return count($qb->getQuery()->getResult()) > 0;
+    }
 }

+ 22 - 0
src/Repository/Access/FunctionTypeRepository.php

@@ -0,0 +1,22 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Repository\Access;
+
+use App\Entity\Access\OrganizationFunction;
+use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
+use Doctrine\Persistence\ManagerRegistry;
+
+/**
+ * @method OrganizationFunction|null find($id, $lockMode = null, $lockVersion = null)
+ * @method OrganizationFunction|null findOneBy(array $criteria, array $orderBy = null)
+ * @method OrganizationFunction[]    findAll()
+ * @method OrganizationFunction[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
+ */
+final class FunctionTypeRepository extends ServiceEntityRepository
+{
+    public function __construct(ManagerRegistry $registry)
+    {
+        parent::__construct($registry, OrganizationFunction::class);
+    }
+}

+ 0 - 29
src/Repository/Access/OrganizationFunctionRepository.php

@@ -19,33 +19,4 @@ final class OrganizationFunctionRepository extends ServiceEntityRepository
     {
         parent::__construct($registry, OrganizationFunction::class);
     }
-
-    // /**
-    //  * @return OrganizationFunction[] Returns an array of OrganizationFunction objects
-    //  */
-    /*
-    public function findByExampleField($value)
-    {
-        return $this->createQueryBuilder('o')
-            ->andWhere('o.exampleField = :val')
-            ->setParameter('val', $value)
-            ->orderBy('o.id', 'ASC')
-            ->setMaxResults(10)
-            ->getQuery()
-            ->getResult()
-        ;
-    }
-    */
-
-    /*
-    public function findOneBySomeField($value): ?OrganizationFunction
-    {
-        return $this->createQueryBuilder('o')
-            ->andWhere('o.exampleField = :val')
-            ->setParameter('val', $value)
-            ->getQuery()
-            ->getOneOrNullResult()
-        ;
-    }
-    */
 }

+ 16 - 0
src/Repository/Billing/AccessIntangibleRepository.php

@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Repository\Billing;
+
+use App\Entity\Billing\AccessIntangible;
+use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
+use Doctrine\Persistence\ManagerRegistry;
+
+final class AccessIntangibleRepository extends ServiceEntityRepository
+{
+    public function __construct(ManagerRegistry $registry)
+    {
+        parent::__construct($registry, AccessIntangible::class);
+    }
+}

+ 16 - 0
src/Repository/Billing/AccessPayerRepository.php

@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Repository\Billing;
+
+use App\Entity\Billing\AccessPayer;
+use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
+use Doctrine\Persistence\ManagerRegistry;
+
+final class AccessPayerRepository extends ServiceEntityRepository
+{
+    public function __construct(ManagerRegistry $registry)
+    {
+        parent::__construct($registry, AccessPayer::class);
+    }
+}

+ 1 - 29
src/Repository/Core/AddressPostalRepository.php

@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Repository\Core;
 
@@ -18,33 +19,4 @@ class AddressPostalRepository extends ServiceEntityRepository
     {
         parent::__construct($registry, AddressPostal::class);
     }
-
-    // /**
-    //  * @return AddressPostal[] Returns an array of AddressPostal objects
-    //  */
-    /*
-    public function findByExampleField($value)
-    {
-        return $this->createQueryBuilder('a')
-            ->andWhere('a.exampleField = :val')
-            ->setParameter('val', $value)
-            ->orderBy('a.id', 'ASC')
-            ->setMaxResults(10)
-            ->getQuery()
-            ->getResult()
-        ;
-    }
-    */
-
-    /*
-    public function findOneBySomeField($value): ?AddressPostal
-    {
-        return $this->createQueryBuilder('a')
-            ->andWhere('a.exampleField = :val')
-            ->setParameter('val', $value)
-            ->getQuery()
-            ->getOneOrNullResult()
-        ;
-    }
-    */
 }

+ 1 - 29
src/Repository/Core/BankAccountRepository.php

@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Repository\Core;
 
@@ -18,33 +19,4 @@ class BankAccountRepository extends ServiceEntityRepository
     {
         parent::__construct($registry, BankAccount::class);
     }
-
-    // /**
-    //  * @return BankAccount[] Returns an array of BankAccount objects
-    //  */
-    /*
-    public function findByExampleField($value)
-    {
-        return $this->createQueryBuilder('b')
-            ->andWhere('b.exampleField = :val')
-            ->setParameter('val', $value)
-            ->orderBy('b.id', 'ASC')
-            ->setMaxResults(10)
-            ->getQuery()
-            ->getResult()
-        ;
-    }
-    */
-
-    /*
-    public function findOneBySomeField($value): ?BankAccount
-    {
-        return $this->createQueryBuilder('b')
-            ->andWhere('b.exampleField = :val')
-            ->setParameter('val', $value)
-            ->getQuery()
-            ->getOneOrNullResult()
-        ;
-    }
-    */
 }

+ 1 - 28
src/Repository/Core/ContactPointRepository.php

@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Repository\Core;
 
@@ -19,32 +20,4 @@ class ContactPointRepository extends ServiceEntityRepository
         parent::__construct($registry, ContactPoint::class);
     }
 
-    // /**
-    //  * @return ContactPoint[] Returns an array of ContactPoint objects
-    //  */
-    /*
-    public function findByExampleField($value)
-    {
-        return $this->createQueryBuilder('c')
-            ->andWhere('c.exampleField = :val')
-            ->setParameter('val', $value)
-            ->orderBy('c.id', 'ASC')
-            ->setMaxResults(10)
-            ->getQuery()
-            ->getResult()
-        ;
-    }
-    */
-
-    /*
-    public function findOneBySomeField($value): ?ContactPoint
-    {
-        return $this->createQueryBuilder('c')
-            ->andWhere('c.exampleField = :val')
-            ->setParameter('val', $value)
-            ->getQuery()
-            ->getOneOrNullResult()
-        ;
-    }
-    */
 }

+ 1 - 29
src/Repository/Core/CountryRepository.php

@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Repository\Core;
 
@@ -18,33 +19,4 @@ class CountryRepository extends ServiceEntityRepository
     {
         parent::__construct($registry, Country::class);
     }
-
-    // /**
-    //  * @return Country[] Returns an array of Country objects
-    //  */
-    /*
-    public function findByExampleField($value)
-    {
-        return $this->createQueryBuilder('c')
-            ->andWhere('c.exampleField = :val')
-            ->setParameter('val', $value)
-            ->orderBy('c.id', 'ASC')
-            ->setMaxResults(10)
-            ->getQuery()
-            ->getResult()
-        ;
-    }
-    */
-
-    /*
-    public function findOneBySomeField($value): ?Country
-    {
-        return $this->createQueryBuilder('c')
-            ->andWhere('c.exampleField = :val')
-            ->setParameter('val', $value)
-            ->getQuery()
-            ->getOneOrNullResult()
-        ;
-    }
-    */
 }

+ 1 - 0
src/Repository/Core/FileRepository.php

@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Repository\Core;
 

+ 0 - 29
src/Repository/Network/NetworkRepository.php

@@ -19,33 +19,4 @@ final class NetworkRepository extends ServiceEntityRepository
     {
         parent::__construct($registry, Network::class);
     }
-
-    // /**
-    //  * @return Network[] Returns an array of Network objects
-    //  */
-    /*
-    public function findByExampleField($value)
-    {
-        return $this->createQueryBuilder('n')
-            ->andWhere('n.exampleField = :val')
-            ->setParameter('val', $value)
-            ->orderBy('n.id', 'ASC')
-            ->setMaxResults(10)
-            ->getQuery()
-            ->getResult()
-        ;
-    }
-    */
-
-    /*
-    public function findOneBySomeField($value): ?Network
-    {
-        return $this->createQueryBuilder('n')
-            ->andWhere('n.exampleField = :val')
-            ->setParameter('val', $value)
-            ->getQuery()
-            ->getOneOrNullResult()
-        ;
-    }
-    */
 }

+ 1 - 29
src/Repository/Organization/OrganizationAddressPostalRepository.php

@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Repository\Organization;
 
@@ -18,33 +19,4 @@ class OrganizationAddressPostalRepository extends ServiceEntityRepository
     {
         parent::__construct($registry, OrganizationAddressPostal::class);
     }
-
-    // /**
-    //  * @return OrganizationAddressPostal[] Returns an array of OrganizationAddressPostal objects
-    //  */
-    /*
-    public function findByExampleField($value)
-    {
-        return $this->createQueryBuilder('o')
-            ->andWhere('o.exampleField = :val')
-            ->setParameter('val', $value)
-            ->orderBy('o.id', 'ASC')
-            ->setMaxResults(10)
-            ->getQuery()
-            ->getResult()
-        ;
-    }
-    */
-
-    /*
-    public function findOneBySomeField($value): ?OrganizationAddressPostal
-    {
-        return $this->createQueryBuilder('o')
-            ->andWhere('o.exampleField = :val')
-            ->setParameter('val', $value)
-            ->getQuery()
-            ->getOneOrNullResult()
-        ;
-    }
-    */
 }

+ 1 - 29
src/Repository/Organization/OrganizationLicenceRepository.php

@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Repository\Organization;
 
@@ -18,33 +19,4 @@ class OrganizationLicenceRepository extends ServiceEntityRepository
     {
         parent::__construct($registry, OrganizationLicence::class);
     }
-
-    // /**
-    //  * @return OrganizationLicence[] Returns an array of OrganizationLicence objects
-    //  */
-    /*
-    public function findByExampleField($value)
-    {
-        return $this->createQueryBuilder('o')
-            ->andWhere('o.exampleField = :val')
-            ->setParameter('val', $value)
-            ->orderBy('o.id', 'ASC')
-            ->setMaxResults(10)
-            ->getQuery()
-            ->getResult()
-        ;
-    }
-    */
-
-    /*
-    public function findOneBySomeField($value): ?OrganizationLicence
-    {
-        return $this->createQueryBuilder('o')
-            ->andWhere('o.exampleField = :val')
-            ->setParameter('val', $value)
-            ->getQuery()
-            ->getOneOrNullResult()
-        ;
-    }
-    */
 }

+ 1 - 29
src/Repository/Organization/ParametersRepository.php

@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Repository\Organization;
 
@@ -18,33 +19,4 @@ class ParametersRepository extends ServiceEntityRepository
     {
         parent::__construct($registry, Parameters::class);
     }
-
-    // /**
-    //  * @return Parameters[] Returns an array of Parameters objects
-    //  */
-    /*
-    public function findByExampleField($value)
-    {
-        return $this->createQueryBuilder('p')
-            ->andWhere('p.exampleField = :val')
-            ->setParameter('val', $value)
-            ->orderBy('p.id', 'ASC')
-            ->setMaxResults(10)
-            ->getQuery()
-            ->getResult()
-        ;
-    }
-    */
-
-    /*
-    public function findOneBySomeField($value): ?Parameters
-    {
-        return $this->createQueryBuilder('p')
-            ->andWhere('p.exampleField = :val')
-            ->setParameter('val', $value)
-            ->getQuery()
-            ->getOneOrNullResult()
-        ;
-    }
-    */
 }

+ 0 - 29
src/Repository/Organization/SettingsRepository.php

@@ -19,33 +19,4 @@ final class SettingsRepository extends ServiceEntityRepository
     {
         parent::__construct($registry, Settings::class);
     }
-
-    // /**
-    //  * @return Settings[] Returns an array of Settings objects
-    //  */
-    /*
-    public function findByExampleField($value)
-    {
-        return $this->createQueryBuilder('s')
-            ->andWhere('s.exampleField = :val')
-            ->setParameter('val', $value)
-            ->orderBy('s.id', 'ASC')
-            ->setMaxResults(10)
-            ->getQuery()
-            ->getResult()
-        ;
-    }
-    */
-
-    /*
-    public function findOneBySomeField($value): ?Settings
-    {
-        return $this->createQueryBuilder('s')
-            ->andWhere('s.exampleField = :val')
-            ->setParameter('val', $value)
-            ->getQuery()
-            ->getOneOrNullResult()
-        ;
-    }
-    */
 }

+ 0 - 29
src/Repository/Person/PersonActivityRepository.php

@@ -19,33 +19,4 @@ final class PersonActivityRepository extends ServiceEntityRepository
     {
         parent::__construct($registry, PersonActivity::class);
     }
-
-    // /**
-    //  * @return PersonActivity[] Returns an array of PersonActivity objects
-    //  */
-    /*
-    public function findByExampleField($value)
-    {
-        return $this->createQueryBuilder('p')
-            ->andWhere('p.exampleField = :val')
-            ->setParameter('val', $value)
-            ->orderBy('p.id', 'ASC')
-            ->setMaxResults(10)
-            ->getQuery()
-            ->getResult()
-        ;
-    }
-    */
-
-    /*
-    public function findOneBySomeField($value): ?PersonActivity
-    {
-        return $this->createQueryBuilder('p')
-            ->andWhere('p.exampleField = :val')
-            ->setParameter('val', $value)
-            ->getQuery()
-            ->getOneOrNullResult()
-        ;
-    }
-    */
 }

+ 0 - 29
src/Repository/Person/PersonRepository.php

@@ -36,33 +36,4 @@ final class PersonRepository extends ServiceEntityRepository implements Password
         $this->_em->persist($user);
         $this->_em->flush();
     }
-
-    // /**
-    //  * @return Person[] Returns an array of Person objects
-    //  */
-    /*
-    public function findByExampleField($value)
-    {
-        return $this->createQueryBuilder('p')
-            ->andWhere('p.exampleField = :val')
-            ->setParameter('val', $value)
-            ->orderBy('p.id', 'ASC')
-            ->setMaxResults(10)
-            ->getQuery()
-            ->getResult()
-        ;
-    }
-    */
-
-    /*
-    public function findOneBySomeField($value): ?Person
-    {
-        return $this->createQueryBuilder('p')
-            ->andWhere('p.exampleField = :val')
-            ->setParameter('val', $value)
-            ->getQuery()
-            ->getOneOrNullResult()
-        ;
-    }
-    */
 }

+ 3 - 7
src/Security/Voter/BankAccountVoter.php

@@ -12,12 +12,8 @@ use Symfony\Component\Security\Core\User\UserInterface;
 
 class BankAccountVoter extends Voter
 {
-    private Security $security;
-
-    public function __construct(Security $security)
-    {
-        $this->security = $security;
-    }
+    public function __construct(private Security $security)
+    { }
 
     protected function supports($attribute, $subject): bool
     {
@@ -31,7 +27,7 @@ class BankAccountVoter extends Voter
      * @param TokenInterface $token
      * @return bool
      */
-    protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool
+    protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
     {
         /** @var Access $user */
         $user = $token->getUser();

+ 3 - 7
src/Security/Voter/ContactPointVoter.php

@@ -12,12 +12,8 @@ use Symfony\Component\Security\Core\User\UserInterface;
 
 class ContactPointVoter extends Voter
 {
-    private Security $security;
-
-    public function __construct(Security $security)
-    {
-        $this->security = $security;
-    }
+    public function __construct(private Security $security)
+    { }
 
     protected function supports($attribute, $subject): bool
     {
@@ -31,7 +27,7 @@ class ContactPointVoter extends Voter
      * @param TokenInterface $token
      * @return bool
      */
-    protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool
+    protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
     {
         /** @var Access $user */
         $user = $token->getUser();

+ 3 - 12
src/Security/Voter/ModuleVoter.php

@@ -21,18 +21,9 @@ class ModuleVoter extends Voter
 {
     const HAVING_MODULE = 'IS_HAVING_MODULE';
 
-    private ResourceMetadataFactoryInterface $resourceMetadataFactory;
-    private Module $module;
-
-    public function __construct(Module $module, ResourceMetadataFactoryInterface $resourceMetadataFactory)
-    {
-        $this->module = $module;
-        $this->resourceMetadataFactory = $resourceMetadataFactory;
-    }
-
-    /**
-     * @inheritDoc
-     */
+    public function __construct(private Module $module, private ResourceMetadataFactoryInterface $resourceMetadataFactory)
+    { }
+    
     protected function supports(string $attribute, $subject): bool
     {
         if (!in_array($attribute, [self::HAVING_MODULE])) {

+ 11 - 11
src/Security/Voter/SwitchUserVoter.php

@@ -11,14 +11,8 @@ use Symfony\Component\Security\Core\User\UserInterface;
 
 class SwitchUserVoter extends Voter
 {
-    private Security $security;
-    private SwitchUser $switchUser;
-
-    public function __construct(Security $security, SwitchUser $switchUser)
-    {
-        $this->security = $security;
-        $this->switchUser = $switchUser;
-    }
+    public function __construct(private Security $security, private SwitchUser $switchUser)
+    { }
 
     protected function supports($attribute, $subject): bool
     {
@@ -26,12 +20,18 @@ class SwitchUserVoter extends Voter
             && $subject instanceof UserInterface;
     }
 
-    protected function voteOnAttribute($attribute, $user_to_switch, TokenInterface $token): bool
+    /**
+     * @param string $attribute
+     * @param mixed $subject User to switch
+     * @param TokenInterface $token
+     * @return bool
+     */
+    protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
     {
         $user = $token->getUser();
 
         // if the user is anonymous or if the subject is not a user, do not grant access
-        if (!$user instanceof UserInterface || !$user_to_switch instanceof UserInterface) {
+        if (!$user instanceof UserInterface || !$subject instanceof UserInterface) {
             return false;
         }
 
@@ -40,7 +40,7 @@ class SwitchUserVoter extends Voter
             return true;
         }
 
-        if ($this->switchUser->isAllowedToSwitch($user, $user_to_switch)) {
+        if ($this->switchUser->isAllowedToSwitch($user, $subject)) {
             return true;
         }
 

+ 5 - 13
src/Serializer/AccessContextBuilder.php

@@ -14,20 +14,12 @@ use Symfony\Component\Security\Core\Security;
  */
 final class AccessContextBuilder implements SerializerContextBuilderInterface
 {
-    private SerializerContextBuilderInterface $decorated;
-    private AuthorizationCheckerInterface $authorizationChecker;
-    private Security $security;
-
     public function __construct(
-        SerializerContextBuilderInterface $decorated,
-        AuthorizationCheckerInterface $authorizationChecker,
-        Security $security
+        private SerializerContextBuilderInterface $decorated,
+        private AuthorizationCheckerInterface $authorizationChecker,
+        private Security $security
 )
-    {
-        $this->decorated = $decorated;
-        $this->authorizationChecker = $authorizationChecker;
-        $this->security = $security;
-    }
+    { }
 
 
     public function createFromRequest(Request $request, bool $normalization, ?array $extractedAttributes = null): array
@@ -35,7 +27,7 @@ final class AccessContextBuilder implements SerializerContextBuilderInterface
         $context = $this->decorated->createFromRequest($request, $normalization, $extractedAttributes);
         $resourceClass = $context['resource_class'] ?? null;
 
-        //On ajoute un nouveau groupe seulement si : la ressource est Access, on est en denoramlization, l'utilisateur n'a pas le ROLE_USERS
+        //On ajoute un nouveau groupe seulement si : la ressource est Access, on est en denormalization, l'utilisateur n'a pas le ROLE_USERS
         //et la denormalization est faite sur l'Access de l'utilisateur connecté
         if (
             $resourceClass === Access::class &&

+ 0 - 57
src/Serializer/OpentalentNormalizer.php

@@ -1,57 +0,0 @@
-<?php
-declare(strict_types=1);
-
-namespace App\Serializer;
-
-use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
-use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
-use Symfony\Component\Serializer\SerializerAwareInterface;
-use Symfony\Component\Serializer\SerializerInterface;
-
-/**
- * Class OpentalentNormalizer : class décoratrice du serializer de base.
- * @package App\Serializer
- */
-final class OpentalentNormalizer implements NormalizerInterface, DenormalizerInterface, SerializerAwareInterface
-{
-    private NormalizerInterface $decorated;
-
-    public function __construct(
-        NormalizerInterface $decorated
-    )
-    {
-        if (!$decorated instanceof DenormalizerInterface) {
-            throw new \InvalidArgumentException(sprintf('The decorated normalizer must implement the %s.', DenormalizerInterface::class));
-        }
-
-        $this->decorated = $decorated;
-    }
-
-    public function supportsNormalization($data, $format = null)
-    {
-        return $this->decorated->supportsNormalization($data, $format);
-    }
-
-    public function normalize($object, $format = null, array $context = [])
-    {
-        $data = $this->decorated->normalize($object, $format, $context);
-        return $data;
-    }
-
-    public function supportsDenormalization($data, $type, $format = null)
-    {
-        return $this->decorated->supportsDenormalization($data, $type, $format);
-    }
-
-    public function denormalize($data, $class, $format = null, array $context = [])
-    {
-        return $this->decorated->denormalize($data, $class, $format, $context);
-    }
-
-    public function setSerializer(SerializerInterface $serializer)
-    {
-        if($this->decorated instanceof SerializerAwareInterface) {
-            $this->decorated->setSerializer($serializer);
-        }
-    }
-}

+ 13 - 19
src/Service/Access/AccessProfileCreator.php

@@ -9,7 +9,6 @@ use App\Repository\Access\AccessRepository;
 use App\Service\Organization\OrganizationProfileCreator;
 use App\Test\Service\Access\AccessProfileCreatorTest;
 use Symfony\Component\Security\Core\Exception\AuthenticationException;
-use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;
 
 /**
  * Class AccessProfileCreator : Service contenant les manipulations associés à la ressource AccessProfile
@@ -17,23 +16,12 @@ use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;
  */
 class AccessProfileCreator
 {
-    private RoleHierarchyInterface $roleHierarchy;
-    private OrganizationProfileCreator $organizationProfileCreator;
-    private AccessRepository $accessRepository;
-    private Utils $accessUtils;
-
     public function __construct(
-        RoleHierarchyInterface $roleHierarchy,
-        OrganizationProfileCreator $organizationProfileCreator,
-        AccessRepository $accessRepository,
-        Utils $accessUtils
+        private OrganizationProfileCreator $organizationProfileCreator,
+        private AccessRepository $accessRepository,
+        private Utils $accessUtils
     )
-    {
-        $this->roleHierarchy = $roleHierarchy;
-        $this->organizationProfileCreator = $organizationProfileCreator;
-        $this->accessRepository = $accessRepository;
-        $this->accessUtils = $accessUtils;
-    }
+    { }
 
     /**
      * On récupère l'accessProfile complet correspondant à l'Access
@@ -81,9 +69,15 @@ class AccessProfileCreator
         $accessProfile = $this->createLightAccessProfile($access);
         return $accessProfile
             ->setIsAdminAccess($access->getAdminAccess())
-            ->setRoles($this->roleHierarchy->getReachableRoleNames($access->getRoles()))
+            ->setRoles($this->accessUtils->getAllRoles($access))
             ->setHistorical($access->getHistorical())
-            ->setOrganization($this->organizationProfileCreator->createCompleteOrganizationProfile($access->getOrganization()));
+            ->setOrganization($this->organizationProfileCreator->createCompleteOrganizationProfile($access->getOrganization()))
+            ->setIsGuardian(!$access->getChildren()->isEmpty())
+            ->setIsPayor(
+                !$access->getBillingPayers()->isEmpty() ||
+                ($access->getBillingReceivers()->isEmpty() && $access->getChildren()->isEmpty() && !$access->getAccessIntangibles()->isEmpty())
+            )
+            ;
     }
 
     /**
@@ -100,7 +94,7 @@ class AccessProfileCreator
             ->setGivenName($access->getPerson()->getGivenName())
             ->setGender($access->getPerson()->getGender())
             ->setActivityYear($access->getActivityYear())
-            ->setAvatarId($access->getPerson()->getImage() ? $access->getPerson()->getImage()->getId() : null)
+            ->setAvatarId($access->getPerson()->getImage()?->getId())
         ;
     }
 }

+ 22 - 0
src/Service/Access/HandleOptionalsRoles.php

@@ -0,0 +1,22 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Service\Access;
+
+use App\Entity\Access\Access;
+
+class HandleOptionalsRoles{
+
+    public function __construct(private iterable $optionalsRoles)
+    { }
+
+    public function getOptionalsRoles(Access $access):array {
+        $roles = [];
+        /** @var OptionalsRolesInterface $optionalsRoles */
+        foreach ($this->optionalsRoles as $optionalsRoles){
+            if($optionalsRoles->support($access))
+                $roles[] = $optionalsRoles->getRole();
+        }
+        return $roles;
+    }
+}

+ 30 - 0
src/Service/Access/OptionalsRoles/CriteriaNotationOptionalRole.php

@@ -0,0 +1,30 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Service\Access\OptionalsRoles;
+
+use App\Entity\Access\Access;
+use App\Repository\Access\AccessRepository;
+use App\Service\Access\OptionalsRolesInterface;
+use App\Service\Access\Utils;
+use App\Enum\Access\FunctionEnum;
+
+class CriteriaNotationOptionalRole implements OptionalsRolesInterface {
+    public function __construct(
+        private Utils $accessUtils,
+        private AccessRepository $accessRepository
+    )
+    {
+    }
+
+    public function support(Access $access): bool
+    {
+        $isActiveTeacher = $this->accessRepository->hasGotFunctionAtThisDate($access, FunctionEnum::TEACHER(), new \DateTime('now'));
+        return $isActiveTeacher && !$access->getOrganization()->getParameters()->getEditCriteriaNotationByAdminOnly();
+    }
+
+    public function getRole(): string
+    {
+        return 'ROLE_CRITERIANOTATION';
+    }
+}

+ 12 - 0
src/Service/Access/OptionalsRolesInterface.php

@@ -0,0 +1,12 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Service\Access;
+
+
+use App\Entity\Access\Access;
+
+interface OptionalsRolesInterface{
+    public function support(Access $access):bool;
+    public function getRole():string;
+}

+ 28 - 3
src/Service/Access/Utils.php

@@ -5,6 +5,7 @@ namespace App\Service\Access;
 
 use App\Entity\Access\Access;
 use App\Test\Service\Access\UtilsTest;
+use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;
 
 /**
  * Class Utils : service rassemblant des fonctions d'aides pour les questions se rapportant à l'access
@@ -12,9 +13,11 @@ use App\Test\Service\Access\UtilsTest;
  */
 class Utils
 {
-    public function __construct()
-    {
-    }
+    public function __construct(
+        private RoleHierarchyInterface $roleHierarchy,
+        private HandleOptionalsRoles $handleOptionalsRoles
+    )
+    {}
 
     /**
      * Filtre un tableau d'Access pour ne laisser que les Accesses ne correspondant pas à l'Access passé en second parametre
@@ -29,4 +32,26 @@ class Utils
             return $a->getId() !== $access->getId();
         });
     }
+
+    /**
+     * Recherche parmis les roles si l'Access possède celui passé en paramètre
+     * @param Access $access
+     * @param string $roleToHave
+     * @return bool
+     * @see UtilsTest::testHasRoles()
+     */
+    public function hasRoles(Access $access, string $roleToHave): bool{
+        return in_array($roleToHave, $this->getAllRoles($access));
+    }
+
+    /**
+     * Va récupérer les roles d'access + les roles optionnels possibles
+     * @param Access $access
+     * @return array
+     * @see UtilsTest::testGetAllRoles()
+     */
+    public function getAllRoles(Access $access): array {
+        $roles = $this->handleOptionalsRoles->getOptionalsRoles($access);
+        return $this->roleHierarchy->getReachableRoleNames(array_merge($access->getRoles(), $roles));
+    }
 }

+ 4 - 12
src/Service/Cotisation/Utils.php

@@ -14,19 +14,11 @@ use App\Service\Network\Utils as NetworkUtils;
  * @package App\Service\Cotisation
  */
 class Utils {
-    private NetworkUtils $networkUtils;
-    private NetworkOrganizationRepository $networkOrganizationRepository;
-    private OrganizationUtils $organizationUtils;
-
     function __construct(
-        NetworkUtils $networkUtils,
-        OrganizationUtils $organizationUtils,
-        NetworkOrganizationRepository $networkOrganizationRepository
-    ) {
-        $this->networkUtils = $networkUtils;
-        $this->organizationUtils = $organizationUtils;
-        $this->networkOrganizationRepository = $networkOrganizationRepository;
-    }
+        private NetworkUtils $networkUtils,
+        private OrganizationUtils $organizationUtils,
+        private NetworkOrganizationRepository $networkOrganizationRepository
+    ) { }
 
     /**
      * Test si l'organisation est un dernier parent ET appartient à la CMF.

+ 2 - 6
src/Service/Network/Tree.php

@@ -15,12 +15,8 @@ use App\Tests\Service\Network\TreeTest;
  */
 class Tree
 {
-    private NetworkOrganizationRepository $networkOrganizationRepository;
-
-    public function __construct(NetworkOrganizationRepository $networkOrganizationRepository)
-    {
-        $this->networkOrganizationRepository = $networkOrganizationRepository;
-    }
+    public function __construct(private NetworkOrganizationRepository $networkOrganizationRepository)
+    { }
 
     /**
      * Retrouve tous les parents d'une structure et les tries selon leur type principal

+ 0 - 4
src/Service/Network/Utils.php

@@ -14,10 +14,6 @@ use App\Tests\Service\Network\UtilsTest;
  */
 class Utils
 {
-    public function __construct()
-    {
-    }
-
     /**
      * Test si l'organisation appartient au réseau de la CMF
      * @param Organization $organization

+ 6 - 9
src/Service/Organization/OrganizationProfileCreator.php

@@ -5,6 +5,8 @@ namespace App\Service\Organization;
 
 use App\ApiResources\Profile\OrganizationProfile;
 use App\Entity\Organization\Organization;
+use App\Enum\Organization\PrincipalTypeEnum;
+use App\Enum\Organization\TypeEstablishmentDetailEnum;
 use App\Service\Network\Tree;
 use App\Service\Security\Module;
 use App\Test\Service\Organization\OrganizationProfileCreatorTest;
@@ -15,17 +17,11 @@ use App\Test\Service\Organization\OrganizationProfileCreatorTest;
  */
 class OrganizationProfileCreator
 {
-    private Module $module;
-    private Tree $tree;
-
     public function __construct(
-        Module $module,
-        Tree $tree
+        private Module $module,
+        private Tree $tree
     )
-    {
-        $this->module = $module;
-        $this->tree = $tree;
-    }
+    { }
 
     /**
      * Classe permettant de créer le profile d'une organisation à partir d'une entité Organization
@@ -38,6 +34,7 @@ class OrganizationProfileCreator
         $organizationProfile->setModules($this->module->getOrganizationModules($organization));
         $organizationProfile->setProduct($organization->getSettings()->getProduct());
         $organizationProfile->setHasChildren($organization->getNetworkOrganizationChildren()->count() > 1);
+        $organizationProfile->setShowAdherentList($organization->getParameters()->getShowAdherentList() && $organization->getPrincipalType() != PrincipalTypeEnum::ARTISTIC_EDUCATION_ONLY());
 
         foreach ($organization->getNetworkOrganizations() as $networkOrganization){
             $organizationProfile->addNetwork($networkOrganization->getNetwork()->getName());

+ 0 - 4
src/Service/Organization/Utils.php

@@ -14,10 +14,6 @@ use App\Test\Service\Organization\UtilsTest;
  */
 class Utils
 {
-    public function __construct()
-    {
-    }
-
     /**
      * Test si l'organisation est considérée comme une structure == n'a pas un produit manager
      * @param Organization $organization

+ 1 - 8
src/Service/Security/Module.php

@@ -19,16 +19,9 @@ class Module
 {
     private array $moduleConfig;
     private array $moduleByConditionsConfig;
-    private Reflection $reflection;
-    private Parser $parser;
-    private string $opentalentConfig;
 
-    public function __construct(Reflection $reflection, Parser $parser,  string $opentalentConfig)
+    public function __construct(private Reflection $reflection, private Parser $parser,  private string $opentalentConfig)
     {
-        $this->reflection = $reflection;
-        $this->parser = $parser;
-        $this->opentalentConfig = $opentalentConfig;
-
         $this->moduleConfig = $this->getModuleConfig();
         $this->moduleByConditionsConfig = $this->getModuleByConditionsConfig();
     }

Some files were not shown because too many files changed in this diff