浏览代码

Merge branch 'release/0.0.2'

Vincent GUFFON 4 年之前
父节点
当前提交
dca0e37919
共有 41 个文件被更改,包括 1597 次插入512 次删除
  1. 1 1
      composer.json
  2. 164 167
      composer.lock
  3. 6 36
      config/opentalent/modulesbyconditions.yaml
  4. 6 0
      config/opentalent/products.yaml
  5. 1 2
      config/packages/security.yaml
  6. 1 14
      config/packages/security/billing.yaml
  7. 4 0
      config/services/services.yaml
  8. 19 26
      src/ApiResources/Profile/AccessProfile.php
  9. 59 24
      src/ApiResources/Profile/OrganizationProfile.php
  10. 1 1
      src/DataPersister/Common/OpentalentDataPersister.php
  11. 22 9
      src/DataProvider/Access/AccessProfileDataProvider.php
  12. 1 2
      src/DataProvider/Common/OpentalentCollectionDataProvider.php
  13. 1 1
      src/DataProvider/Common/OpentalentItemDataProvider.php
  14. 1 1
      src/Doctrine/Access/AccessExtension.php
  15. 17 0
      src/Entity/Access/Access.php
  16. 18 0
      src/Entity/Organization/Organization.php
  17. 543 0
      src/Entity/Organization/Parameters.php
  18. 25 0
      src/Enum/Core/TimeZoneEnum.php
  19. 16 0
      src/Enum/Education/PeriodicityEnum.php
  20. 14 0
      src/Enum/Organization/BulletinOutputEnum.php
  21. 16 0
      src/Enum/Organization/BulletinPeriodEnum.php
  22. 15 0
      src/Enum/Organization/OrganizationIdsEnum.php
  23. 16 0
      src/Enum/Organization/SendToBulletinEnum.php
  24. 6 6
      src/Enum/Organization/SettingsProductEnum.php
  25. 1 1
      src/Repository/Access/AccessRepository.php
  26. 90 24
      src/Repository/Network/NetworkOrganizationRepository.php
  27. 2 43
      src/Repository/Organization/OrganizationRepository.php
  28. 50 0
      src/Repository/Organization/ParametersRepository.php
  29. 2 3
      src/Security/ModuleVoter.php
  30. 37 72
      src/Service/Cotisation/Utils.php
  31. 62 0
      src/Service/Network/Tree.php
  32. 1 1
      src/Service/Network/Utils.php
  33. 43 2
      src/Service/Organization/Utils.php
  34. 11 17
      src/Service/Security/Module.php
  35. 4 3
      src/Service/Utils/Reflection.php
  36. 0 12
      symfony.lock
  37. 174 31
      tests/Service/Cotisation/UtilsTest.php
  38. 81 0
      tests/Service/Network/TreeTest.php
  39. 3 7
      tests/Service/Network/UtilsTest.php
  40. 62 5
      tests/Service/Organization/UtilsTest.php
  41. 1 1
      tests/Service/Security/ModuleTest.php

+ 1 - 1
composer.json

@@ -11,7 +11,7 @@
         "php": ">=7.2.5",
         "ext-ctype": "*",
         "ext-iconv": "*",
-        "api-platform/core": "^2.5",
+        "api-platform/core": "^2.6",
         "blackfire/php-sdk": "^1.23",
         "composer/package-versions-deprecated": "^1.11",
         "doctrine/annotations": "^1.0",

文件差异内容过多而无法显示
+ 164 - 167
composer.lock


+ 6 - 36
config/opentalent/modulesbyconditions.yaml

@@ -20,7 +20,7 @@ opentalent:
             conditions:
                 service:
                     name: opentalent.cotisation.utils
-                    function: isLastParentAndManagerCMFAndCMF
+                    function: isManagerAndLastParentAndCMF
         CotisationTransmissionState:
             roles:
                 - ROLE_COTISATION
@@ -40,40 +40,26 @@ opentalent:
                 - ROLE_COTISATION
             conditions:
                 service:
-                    name: opentalent.cotisation.utils
-                    function: isCMFAdministration
-
+                    name: opentalent.organization.utils
+                    function: isOrganizationIsCMF
         Admin2IOS:
             roles:
                 - ROLE_ADMIN2IOS
             conditions:
                 service:
-                    name: opentalent.admin2IOS.utils
-                    function: isAdmin2IOS
+                    name: opentalent.organization.utils
+                    function: isOrganizationIs2ios
         StatisticFederation:
-            roles:
-                - ROLE_STATISTIC
             conditions:
                 service:
                     name: opentalent.cotisation.utils
                     function: isManagerAndNotLastParentAndCMF
         StatisticStructure:
-            roles:
-                - ROLE_STATISTIC
             conditions:
                 service:
                     name: opentalent.cotisation.utils
                     function: isManagerAndCMF
-        Statistic:
-            roles:
-                - ROLE_STATISTIC
-            conditions:
-                service:
-                    name: opentalent.cotisation.utils
-                    function: isStructure
         Network:
-            roles:
-                - ROLE_NETWORK
             conditions:
                 service:
                     name: opentalent.network.utils
@@ -82,20 +68,4 @@ opentalent:
             conditions:
                 service:
                     name: opentalent.network.utils
-                    function: isCMF
-        Pes:
-            conditions:
-                service:
-                    name: opentalent.export.module.utils
-                    function: isOrganizationWithPes
-
-        BergerLevrault:
-            conditions:
-                service:
-                    name: opentalent.export.module.utils
-                    function: isOrganizationWithBergerLevrault
-        Jvs:
-            conditions:
-                service:
-                    name: opentalent.export.module.utils
-                    function: isOrganizationWithJvs
+                    function: isCMF

+ 6 - 0
config/opentalent/products.yaml

@@ -276,6 +276,11 @@ opentalent:
           roles:
             - ROLE_WEBSITE
 
+      Statistic:
+        entities: ~
+        roles:
+          - ROLE_STATISTIC
+
       ViewAudit:
           entities:
             - ViewAudit
@@ -309,6 +314,7 @@ opentalent:
           - ViewAudit
           - Messages
           - Tagg
+          - Statistic
 
       artist_premium:
         extend: artist

+ 1 - 2
config/packages/security.yaml

@@ -8,7 +8,6 @@ security:
         BASE_ROLE_ADMINISTRATION_CORE : &BASE_ROLE_ADMINISTRATION_CORE
             - ROLE_MEMBER_CORE
             - ROLE_ORGANIZATION_EDIT
-            - ROLE_ORGANIZATION_VIEW
 
         ROLE_ADMIN:
             - ROLE_CORE-CRUD
@@ -24,7 +23,7 @@ security:
             - ROLE_NETWORK
             - ROLE_COTISATION
             - ROLE_ONLINEREGISTRATION_ADMINISTRATION
-            - ROLE_STATISTIQUE
+            - ROLE_STATISTIC
             - ROLE_ADMIN_CORE
 
         ROLE_ADMIN_CORE: *BASE_ROLE_ADMINISTRATION_CORE

+ 1 - 14
config/packages/security/billing.yaml

@@ -18,17 +18,4 @@ security:
 
         ROLE_BILLINGS-SEIZURE_REFERENCE:
           - ROLE_ACCESS_REFERENCE
-          - ROLE_EDUCATION-CURRICULUM_REFERENCE
-
-        ROLE_PES-ADMINISTRATION:
-          - ROLE_PES
-          - ROLE_SEPA-DEBIT-MANDATE_EXPORT
-
-        ROLE_BERGERLEVRAULT-ADMINISTRATION:
-          - ROLE_BERGERLEVRAULT
-          - ROLE_SEPA-DEBIT-MANDATE_EXPORT
-
-
-        ROLE_JVS-ADMINISTRATION:
-          - ROLE_JVS
-          - ROLE_SEPA-DEBIT-MANDATE_EXPORT
+          - ROLE_EDUCATION-CURRICULUM_REFERENCE

+ 4 - 0
config/services/services.yaml

@@ -6,4 +6,8 @@ services:
   opentalent.network.utils:
     class: App\Service\Network\Utils
     public: true
+    autowire: true
+  opentalent.organization.utils:
+    class: App\Service\Organization\Utils
+    public: true
     autowire: true

+ 19 - 26
src/ApiResources/Profile/AccessProfile.php

@@ -24,28 +24,12 @@ class AccessProfile
     /**
      * @ApiProperty(identifier=true)
      */
-    public $id;
-
-    /**
-     * @var string
-     */
-    private $name;
-
-    /**
-     * @var string
-     */
-    private $givenName;
-
-    /**
-     * @var array
-     */
-    private $roles = [];
-
-
-    /**
-     * @var OrganizationProfile
-     */
-    private $organization;
+    public int $id;
+    private bool $isAdminAccess;
+    private string $name;
+    private string $givenName;
+    private array $roles = [];
+    private OrganizationProfile $organization;
 
     public function __construct()
     {
@@ -63,6 +47,18 @@ class AccessProfile
         return $this;
     }
 
+    public function getIsAdminAccess(): ?bool
+    {
+        return $this->isAdminAccess;
+    }
+
+    public function setIsAdminAccess(bool $isAdminAccess): self
+    {
+        $this->isAdminAccess = $isAdminAccess;
+
+        return $this;
+    }
+
     public function getOrganization(): ?OrganizationProfile
     {
         return $this->organization;
@@ -99,10 +95,7 @@ class AccessProfile
         return $this;
     }
 
-    /**
-     * @inheritDoc
-     */
-    public function getRoles()
+    public function getRoles(): array
     {
         $roles = $this->roles;
 

+ 59 - 24
src/ApiResources/Profile/OrganizationProfile.php

@@ -3,35 +3,40 @@ declare(strict_types=1);
 
 namespace App\ApiResources\Profile;
 
+use ApiPlatform\Core\Annotation\ApiProperty;
+
 /**
  * Classe resource qui contient les champs relatifs aux organizations présentent dans la requete my_profile.
  * @package App\ApiResources\Profile
  */
 class OrganizationProfile
 {
-
-    /**
-     * @var string
-     */
-    private $name;
-
     /**
-     * @var string
+     * @ApiProperty(identifier=true)
      */
-    private $product;
+    public int $id;
+    private string $name;
+    private string $product;
+    private string $subDomain;
+    private string $website;
+    private array $modules = [];
+    private bool $hasChildren = false;
+    private array $parents = [];
 
-    /**
-     * @var array
-     */
-    private $modules = [];
+    public function __construct()
+    {
+    }
 
-    /**
-     * @var bool
-     */
-    private $hasChildren;
+    public function getId(): ?int
+    {
+        return $this->id;
+    }
 
-    public function __construct()
+    public function setId(?int $id): self
     {
+        $this->id = $id;
+
+        return $this;
     }
 
     public function getName(): ?string
@@ -58,10 +63,31 @@ class OrganizationProfile
         return $this;
     }
 
-    /**
-     * @inheritDoc
-     */
-    public function getModules()
+    public function getSubDomain(): ?string
+    {
+        return $this->subDomain;
+    }
+
+    public function setSubDomain(?string $subDomain): self
+    {
+        $this->subDomain = $subDomain;
+
+        return $this;
+    }
+
+    public function getWebsite(): ?string
+    {
+        return $this->website;
+    }
+
+    public function setWebsite(?string $website): self
+    {
+        $this->website = $website;
+
+        return $this;
+    }
+
+    public function getModules(): array
     {
         $modules = $this->modules;
         return array_unique($modules);
@@ -74,9 +100,6 @@ class OrganizationProfile
         return $this;
     }
 
-    /**
-     * @inheritDoc
-     */
     public function getHasChildren(): bool
     {
         return $this->hasChildren;
@@ -88,4 +111,16 @@ class OrganizationProfile
 
         return $this;
     }
+
+
+    public function getParents(): array
+    {
+        return $this->parents;
+    }
+
+    public function addParent(OrganizationProfile $parent): self
+    {
+        $this->parents[] = $parent;
+        return $this;
+    }
 }

+ 1 - 1
src/DataPersister/Common/OpentalentDataPersister.php

@@ -11,7 +11,7 @@ use ApiPlatform\Core\DataPersister\ContextAwareDataPersisterInterface;
  */
 final class OpentalentDataPersister implements ContextAwareDataPersisterInterface
 {
-    private $decorated;
+    private ContextAwareDataPersisterInterface $decorated;
 
     public function __construct(ContextAwareDataPersisterInterface $decorated)
     {

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

@@ -9,6 +9,8 @@ use App\ApiResources\Profile\AccessProfile;
 use App\ApiResources\Profile\OrganizationProfile;
 use App\Entity\Access\Access;
 use App\Entity\Organization\Organization;
+use App\Repository\Organization\OrganizationRepository;
+use App\Service\Network\Tree;
 use App\Service\Security\Module;
 use Symfony\Component\Security\Core\Role\Role;
 use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;
@@ -20,24 +22,22 @@ use Symfony\Component\Security\Core\Security;
  */
 final class AccessProfileDataProvider implements ItemDataProviderInterface, RestrictedDataProviderInterface
 {
-    /** @var Security  */
-    private $security;
-
-    /** @var RoleHierarchyInterface  */
-    private $roleHierarchy;
-
-    /** @var Module  */
-    private $module;
+    private Security $security;
+    private RoleHierarchyInterface $roleHierarchy;
+    private Module $module;
+    private Tree $tree;
 
     public function __construct(
         Security $security,
         RoleHierarchyInterface $roleHierarchy,
-        Module $module
+        Module $module,
+        Tree $tree
     )
     {
         $this->security = $security;
         $this->roleHierarchy = $roleHierarchy;
         $this->module = $module;
+        $this->tree = $tree;
     }
 
     public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
@@ -67,6 +67,7 @@ final class AccessProfileDataProvider implements ItemDataProviderInterface, Rest
     {
         $accessProfile = new AccessProfile();
         $accessProfile->setId($access->getId());
+        $accessProfile->setIsAdminAccess($access->getAdminAccess());
         $accessProfile->setName($access->getPerson()->getName());
         $accessProfile->setGivenName($access->getPerson()->getGivenName());
         return $accessProfile;
@@ -83,6 +84,18 @@ final class AccessProfileDataProvider implements ItemDataProviderInterface, Rest
         $organizationProfile->setModules($this->module->getOrganizationModules($organization));
         $organizationProfile->setProduct($organization->getSettings()->getProduct());
         $organizationProfile->setHasChildren($organization->getNetworkOrganizationChildren()->count() > 1);
+        $organizationProfile->setSubDomain($organization->getParameters()->getSubDomain());
+        $organizationProfile->setWebsite($organization->getParameters()->getWebsite());
+
+        /** @var Organization $parent */
+        foreach ($this->tree->findAllParentsAndSortByType($organization) as $parent){
+            $parentProfile = new OrganizationProfile();
+            $parentProfile->setId($parent->getId());
+            $parentProfile->setName($parent->getName());
+            $parentProfile->setSubDomain($parent->getParameters()->getSubDomain());
+            $parentProfile->setWebsite($parent->getParameters()->getWebsite());
+            $organizationProfile->addParent($parentProfile);
+        }
         return $organizationProfile;
     }
 }

+ 1 - 2
src/DataProvider/Common/OpentalentCollectionDataProvider.php

@@ -12,8 +12,7 @@ use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
  */
 final class OpentalentCollectionDataProvider implements ContextAwareCollectionDataProviderInterface, RestrictedDataProviderInterface
 {
-    /** @var ContextAwareCollectionDataProviderInterface  */
-    private $decorated;
+    private ContextAwareCollectionDataProviderInterface $decorated;
 
     public function __construct(
         ContextAwareCollectionDataProviderInterface $decorated

+ 1 - 1
src/DataProvider/Common/OpentalentItemDataProvider.php

@@ -12,7 +12,7 @@ use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
  */
 final class OpentalentItemDataProvider implements DenormalizedIdentifiersAwareItemDataProviderInterface, RestrictedDataProviderInterface
 {
-    private $decorated;
+    private DenormalizedIdentifiersAwareItemDataProviderInterface $decorated;
 
     public function __construct(DenormalizedIdentifiersAwareItemDataProviderInterface $decorated)
     {

+ 1 - 1
src/Doctrine/Access/AccessExtension.php

@@ -16,7 +16,7 @@ use Symfony\Component\Security\Core\Security;
  */
 final class AccessExtension implements QueryCollectionExtensionInterface, QueryItemExtensionInterface
 {
-    private $security;
+    private Security $security;
 
     public function __construct(Security $security)
     {

+ 17 - 0
src/Entity/Access/Access.php

@@ -38,6 +38,11 @@ class Access implements UserInterface
      */
     private $id;
 
+    /**
+     * @ORM\Column(type="boolean", options={"default" : false})
+     */
+    private $adminAccess = false;
+
     /**
      * @ORM\ManyToOne(targetEntity=Person::class, cascade={"persist"})
      * @ORM\JoinColumn(nullable=false)
@@ -72,6 +77,18 @@ class Access implements UserInterface
         return $this->id;
     }
 
+    public function getAdminAccess(): ?bool
+    {
+        return $this->adminAccess;
+    }
+
+    public function setAdminAccess(bool $adminAccess): self
+    {
+        $this->adminAccess = $adminAccess;
+
+        return $this;
+    }
+
     public function getPerson(): ?Person
     {
         return $this->person;

+ 18 - 0
src/Entity/Organization/Organization.php

@@ -69,6 +69,12 @@ class Organization
      */
     private $networkOrganizationChildren;
 
+    /**
+     * @ORM\OneToOne(targetEntity=Parameters::class, cascade={"persist", "remove"})
+     * @ORM\JoinColumn(nullable=false)
+     */
+    private $parameters;
+
     public function __construct()
     {
         $this->networkOrganizations = new ArrayCollection();
@@ -204,4 +210,16 @@ class Organization
 
         return $this;
     }
+
+    public function getParameters(): ?Parameters
+    {
+        return $this->parameters;
+    }
+
+    public function setParameters(Parameters $parameters): self
+    {
+        $this->parameters = $parameters;
+
+        return $this;
+    }
 }

+ 543 - 0
src/Entity/Organization/Parameters.php

@@ -0,0 +1,543 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Entity\Organization;
+
+use ApiPlatform\Core\Annotation\ApiResource;
+use App\Repository\Organization\ParametersRepository;
+use Doctrine\ORM\Mapping as ORM;
+use Symfony\Component\Validator\Constraints as Assert;
+
+/**
+ * @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;
+
+    public function getId(): ?int
+    {
+        return $this->id;
+    }
+
+    public function getFinancialDate(): ?\DateTimeInterface
+    {
+        return $this->financialDate;
+    }
+
+    public function setFinancialDate(?\DateTimeInterface $financialDate): self
+    {
+        $this->financialDate = $financialDate;
+
+        return $this;
+    }
+
+    public function getMusicalDate(): ?\DateTimeInterface
+    {
+        return $this->musicalDate;
+    }
+
+    public function setMusicalDate(?\DateTimeInterface $musicalDate): self
+    {
+        $this->musicalDate = $musicalDate;
+
+        return $this;
+    }
+
+    public function getStartCourseDate(): ?\DateTimeInterface
+    {
+        return $this->startCourseDate;
+    }
+
+    public function setStartCourseDate(?\DateTimeInterface $startCourseDate): self
+    {
+        $this->startCourseDate = $startCourseDate;
+
+        return $this;
+    }
+
+    public function getEndCourseDate(): ?\DateTimeInterface
+    {
+        return $this->endCourseDate;
+    }
+
+    public function setEndCourseDate(?\DateTimeInterface $endCourseDate): self
+    {
+        $this->endCourseDate = $endCourseDate;
+
+        return $this;
+    }
+
+    public function getTrackingValidation(): ?bool
+    {
+        return $this->trackingValidation;
+    }
+
+    public function setTrackingValidation(bool $trackingValidation): self
+    {
+        $this->trackingValidation = $trackingValidation;
+
+        return $this;
+    }
+
+    public function getEditCriteriaNotationByAdminOnly(): ?bool
+    {
+        return $this->editCriteriaNotationByAdminOnly;
+    }
+
+    public function setEditCriteriaNotationByAdminOnly(bool $editCriteriaNotationByAdminOnly): self
+    {
+        $this->editCriteriaNotationByAdminOnly = $editCriteriaNotationByAdminOnly;
+
+        return $this;
+    }
+
+    public function getSmsSenderName(): ?string
+    {
+        return $this->smsSenderName;
+    }
+
+    public function setSmsSenderName(?string $smsSenderName): self
+    {
+        $this->smsSenderName = $smsSenderName;
+
+        return $this;
+    }
+
+    public function getLogoDonorsMove(): ?bool
+    {
+        return $this->logoDonorsMove;
+    }
+
+    public function setLogoDonorsMove(bool $logoDonorsMove): self
+    {
+        $this->logoDonorsMove = $logoDonorsMove;
+
+        return $this;
+    }
+
+    public function getSubDomain(): ?string
+    {
+        return $this->subDomain;
+    }
+
+    public function setSubDomain(?string $subDomain): self
+    {
+        $this->subDomain = $subDomain;
+
+        return $this;
+    }
+
+    public function getWebsite(): ?string
+    {
+        return $this->website;
+    }
+
+    public function setWebsite(?string $website): self
+    {
+        $this->website = $website;
+
+        return $this;
+    }
+
+    public function getOtherWebsite(): ?string
+    {
+        return $this->otherWebsite;
+    }
+
+    public function setOtherWebsite(?string $otherWebsite): self
+    {
+        $this->otherWebsite = $otherWebsite;
+
+        return $this;
+    }
+
+    public function getDesactivateOpentalentSiteWeb(): ?bool
+    {
+        return $this->desactivateOpentalentSiteWeb;
+    }
+
+    public function setDesactivateOpentalentSiteWeb(bool $desactivateOpentalentSiteWeb): self
+    {
+        $this->desactivateOpentalentSiteWeb = $desactivateOpentalentSiteWeb;
+
+        return $this;
+    }
+
+    public function getBulletinPeriod(): ?string
+    {
+        return $this->bulletinPeriod;
+    }
+
+    public function setBulletinPeriod(?string $bulletinPeriod): self
+    {
+        $this->bulletinPeriod = $bulletinPeriod;
+
+        return $this;
+    }
+
+    public function getBulletinWithTeacher(): ?bool
+    {
+        return $this->bulletinWithTeacher;
+    }
+
+    public function setBulletinWithTeacher(bool $bulletinWithTeacher): self
+    {
+        $this->bulletinWithTeacher = $bulletinWithTeacher;
+
+        return $this;
+    }
+
+    public function getBulletinPrintAddress(): ?bool
+    {
+        return $this->bulletinPrintAddress;
+    }
+
+    public function setBulletinPrintAddress(bool $bulletinPrintAddress): self
+    {
+        $this->bulletinPrintAddress = $bulletinPrintAddress;
+
+        return $this;
+    }
+
+    public function getBulletinSignatureDirector(): ?bool
+    {
+        return $this->bulletinSignatureDirector;
+    }
+
+    public function setBulletinSignatureDirector(bool $bulletinSignatureDirector): self
+    {
+        $this->bulletinSignatureDirector = $bulletinSignatureDirector;
+
+        return $this;
+    }
+
+    public function getBulletinDisplayLevelAcquired(): ?bool
+    {
+        return $this->bulletinDisplayLevelAcquired;
+    }
+
+    public function setBulletinDisplayLevelAcquired(bool $bulletinDisplayLevelAcquired): self
+    {
+        $this->bulletinDisplayLevelAcquired = $bulletinDisplayLevelAcquired;
+
+        return $this;
+    }
+
+    public function getBulletinShowEducationWithoutEvaluation(): ?bool
+    {
+        return $this->bulletinShowEducationWithoutEvaluation;
+    }
+
+    public function setBulletinShowEducationWithoutEvaluation(bool $bulletinShowEducationWithoutEvaluation): self
+    {
+        $this->bulletinShowEducationWithoutEvaluation = $bulletinShowEducationWithoutEvaluation;
+
+        return $this;
+    }
+
+    public function getBulletinViewTestResults(): ?bool
+    {
+        return $this->bulletinViewTestResults;
+    }
+
+    public function setBulletinViewTestResults(bool $bulletinViewTestResults): self
+    {
+        $this->bulletinViewTestResults = $bulletinViewTestResults;
+
+        return $this;
+    }
+
+    public function getBulletinShowAbsences(): ?bool
+    {
+        return $this->bulletinShowAbsences;
+    }
+
+    public function setBulletinShowAbsences(bool $bulletinShowAbsences): self
+    {
+        $this->bulletinShowAbsences = $bulletinShowAbsences;
+
+        return $this;
+    }
+
+    public function getBulletinShowAverages(): ?bool
+    {
+        return $this->bulletinShowAverages;
+    }
+
+    public function setBulletinShowAverages(bool $bulletinShowAverages): self
+    {
+        $this->bulletinShowAverages = $bulletinShowAverages;
+
+        return $this;
+    }
+
+    public function getBulletinOutput(): ?string
+    {
+        return $this->bulletinOutput;
+    }
+
+    public function setBulletinOutput(?string $bulletinOutput): self
+    {
+        $this->bulletinOutput = $bulletinOutput;
+
+        return $this;
+    }
+
+    public function getUsernameSMS(): ?string
+    {
+        return $this->usernameSMS;
+    }
+
+    public function setUsernameSMS(?string $usernameSMS): self
+    {
+        $this->usernameSMS = $usernameSMS;
+
+        return $this;
+    }
+
+    public function getPasswordSMS(): ?string
+    {
+        return $this->passwordSMS;
+    }
+
+    public function setPasswordSMS(?string $passwordSMS): self
+    {
+        $this->passwordSMS = $passwordSMS;
+
+        return $this;
+    }
+
+    public function getBulletinEditWithoutEvaluation(): ?bool
+    {
+        return $this->bulletinEditWithoutEvaluation;
+    }
+
+    public function setBulletinEditWithoutEvaluation(bool $bulletinEditWithoutEvaluation): self
+    {
+        $this->bulletinEditWithoutEvaluation = $bulletinEditWithoutEvaluation;
+
+        return $this;
+    }
+
+    public function getBulletinReceiver(): ?string
+    {
+        return $this->bulletinReceiver;
+    }
+
+    public function setBulletinReceiver(?string $bulletinReceiver): self
+    {
+        $this->bulletinReceiver = $bulletinReceiver;
+
+        return $this;
+    }
+
+    public function getShowAdherentList(): ?bool
+    {
+        return $this->showAdherentList;
+    }
+
+    public function setShowAdherentList(bool $showAdherentList): self
+    {
+        $this->showAdherentList = $showAdherentList;
+
+        return $this;
+    }
+
+    public function getStudentsAreAdherents(): ?bool
+    {
+        return $this->studentsAreAdherents;
+    }
+
+    public function setStudentsAreAdherents(bool $studentsAreAdherents): self
+    {
+        $this->studentsAreAdherents = $studentsAreAdherents;
+
+        return $this;
+    }
+
+    public function getTimezone(): ?string
+    {
+        return $this->timezone;
+    }
+
+    public function setTimezone(string $timezone): self
+    {
+        $this->timezone = $timezone;
+
+        return $this;
+    }
+
+    public function getEducationPeriodicity(): ?string
+    {
+        return $this->educationPeriodicity;
+    }
+
+    public function setEducationPeriodicity(?string $educationPeriodicity): self
+    {
+        $this->educationPeriodicity = $educationPeriodicity;
+
+        return $this;
+    }
+}

+ 25 - 0
src/Enum/Core/TimeZoneEnum.php

@@ -0,0 +1,25 @@
+<?php
+
+namespace App\Enum\Core;
+
+use MyCLabs\Enum\Enum;
+
+/**
+ * TimeZone disponibles
+ * @package App\Enum\Core
+ */
+class TimeZoneEnum extends Enum
+{
+    /**
+     * Return a custom array instead the original array
+     * @return mixed
+     */
+    public static function toArrayCustom()
+    {
+        return [
+         'Indian/Reunion' => 'Indian/Reunion',
+         'Europe/Zurich' => 'Europe/Zurich',
+         'Europe/Paris' => 'Europe/Paris'
+        ];
+    }
+}

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

@@ -0,0 +1,16 @@
+<?php
+
+namespace App\Enum\Education;
+
+use MyCLabs\Enum\Enum;
+
+/**
+ * Période disponibles.
+ */
+class PeriodicityEnum extends Enum
+{
+    private const MONTHLY ='MONTHLY';
+    private const QUARTERLY ='QUARTERLY';
+    private const HALF = 'HALF';
+    private const ANNUAL = 'ANNUAL';
+}

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

@@ -0,0 +1,14 @@
+<?php
+
+namespace App\Enum\Organization;
+
+use MyCLabs\Enum\Enum;
+
+/**
+ * Sortie des bulletin
+ */
+class BulletinOutputEnum extends Enum
+{
+    private const PRINTING = 'PRINTING';
+    private const SEND_BY_EMAIL = 'SEND_BY_EMAIL';
+}

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

@@ -0,0 +1,16 @@
+<?php
+
+namespace App\Enum\Organization;
+
+use MyCLabs\Enum\Enum;
+
+/**
+ * Périodes des bulletin
+ */
+class BulletinPeriodEnum extends Enum
+{
+    private const YEAR = 'YEAR';
+    private const SEMESTER = 'SEMESTER';
+    private const TRIMESTER = 'TRIMESTER';
+    private const MONTH = 'MONTH';
+}

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

@@ -0,0 +1,15 @@
+<?php
+
+namespace App\Enum\Organization;
+
+use MyCLabs\Enum\Enum;
+
+/**
+ * Id de structure spécifiques
+ */
+class OrganizationIdsEnum extends Enum
+{
+    private const CMF     = 12097;
+    private const _2IOS   = 32366;
+    private const OPENTALENT_BASE   = 13;
+}

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

@@ -0,0 +1,16 @@
+<?php
+
+namespace App\Enum\Organization;
+
+use MyCLabs\Enum\Enum;
+
+/**
+ * Bulletin envoyés à...
+ */
+class SendToBulletinEnum extends Enum
+{
+    private const STUDENTS_AND_THEIR_GUARDIANS = 'STUDENTS_AND_THEIR_GUARDIANS';
+    private const STUDENTS = 'STUDENTS';
+    private const GUARDIANS = 'GUARDIANS';
+}
+

+ 6 - 6
src/Enum/Organization/SettingsProductEnum.php

@@ -9,10 +9,10 @@ use MyCLabs\Enum\Enum;
  */
 class SettingsProductEnum extends Enum
 {
-    const ARTIST = 'artist';
-    const ARTIST_PREMIUM = 'artist-premium';
-    const SCHOOL = 'school';
-    const SCHOOL_PREMIUM = 'school-premium';
-    const MANAGER = 'manager';
-    const MANAGER_PREMIUM = 'manager-premium';
+    private const ARTIST = 'artist';
+    private const ARTIST_PREMIUM = 'artist-premium';
+    private const SCHOOL = 'school';
+    private const SCHOOL_PREMIUM = 'school-premium';
+    private const MANAGER = 'manager';
+    private const MANAGER_PREMIUM = 'manager-premium';
 }

+ 1 - 1
src/Repository/Access/AccessRepository.php

@@ -19,7 +19,7 @@ final class AccessRepository extends ServiceEntityRepository implements UserLoad
 {
     const ACCESS_NAME_HEADER = 'X-AccessId';
 
-    private $requestStack;
+    private RequestStack $requestStack;
 
     public function __construct(ManagerRegistry $registry, RequestStack $requestStack)
     {

+ 90 - 24
src/Repository/Network/NetworkOrganizationRepository.php

@@ -4,7 +4,12 @@ declare(strict_types=1);
 namespace App\Repository\Network;
 
 use App\Entity\Network\NetworkOrganization;
+use App\Entity\Organization\Organization;
+use App\Enum\Organization\OrganizationIdsEnum;
+use App\Enum\Organization\PrincipalTypeEnum;
 use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
+use Doctrine\ORM\Query\ResultSetMapping;
+use Doctrine\ORM\Query\ResultSetMappingBuilder;
 use Doctrine\Persistence\ManagerRegistry;
 
 /**
@@ -13,39 +18,100 @@ use Doctrine\Persistence\ManagerRegistry;
  * @method NetworkOrganization[]    findAll()
  * @method NetworkOrganization[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
  */
-final class NetworkOrganizationRepository extends ServiceEntityRepository
+class NetworkOrganizationRepository extends ServiceEntityRepository
 {
     public function __construct(ManagerRegistry $registry)
     {
         parent::__construct($registry, NetworkOrganization::class);
     }
 
-    // /**
-    //  * @return NetworkOrganization[] Returns an array of NetworkOrganization objects
-    //  */
-    /*
-    public function findByExampleField($value)
+    /**
+     * Vérifie si l'organisation est un dernier parent : possède des enfants mais ces enfants ne possèdent pas d'enfant
+     * @param Organization $organization
+     * @return bool
+     */
+    public function isLastParent(Organization $organization): bool
     {
-        return $this->createQueryBuilder('n')
-            ->andWhere('n.exampleField = :val')
-            ->setParameter('val', $value)
-            ->orderBy('n.id', 'ASC')
-            ->setMaxResults(10)
-            ->getQuery()
-            ->getResult()
-        ;
+        $sql = sprintf("
+        SELECT 
+            IF( (SELECT o.id 
+                    FROM Organization as o 
+                    WHERE o.id=neto.organization_id
+                    AND o.principalType IN('%s','%s','%s','%s','%s','%s')) IS NOT NULL ,0,1) AS is_last_parent
+        FROM
+            NetworkOrganization as neto
+        WHERE
+            neto.parent_id = %d
+            and (neto.endDate is null or neto.endDate = \"0000-00-00\" or neto.endDate > CURDATE())
+        GROUP BY is_last_parent
+        ORDER BY is_last_parent DESC",
+            PrincipalTypeEnum::NATIONAL_FEDERATION(),
+            PrincipalTypeEnum::REGIONAL_FEDERATION(),
+            PrincipalTypeEnum::LOCAL_FEDERATION(),
+            PrincipalTypeEnum::GROUPMENT(),
+            PrincipalTypeEnum::DEPARTEMENTAL_FEDERATION(),
+            PrincipalTypeEnum::DELEGATION(),
+            $organization->getId()
+        );
+
+        $rsm = new ResultSetMapping();
+        $rsm->addScalarResult('is_last_parent', 'is_last_parent', 'integer');
+        $query = $this->getEntityManager()->createNativeQuery($sql, $rsm);
+        $result = $query->getResult(\Doctrine\ORM\Query::HYDRATE_ARRAY);
+
+        foreach ($result as $a_tmp) {
+            if ($a_tmp['is_last_parent']) {
+                return true;
+            }
+        }
+        return false;
     }
-    */
 
-    /*
-    public function findOneBySomeField($value): ?NetworkOrganization
+    /**
+     * Retrouve tous les parents de la structure passée en paramètres
+     *
+     * @param Organization $organization.
+     *
+     * @return array The organizations.
+     */
+    public function findAllParents(Organization $organization): ?array
     {
-        return $this->createQueryBuilder('n')
-            ->andWhere('n.exampleField = :val')
-            ->setParameter('val', $value)
-            ->getQuery()
-            ->getOneOrNullResult()
-        ;
+        $sql = sprintf("
+            SELECT *
+             FROM Organization o
+             JOIN
+               (
+                 SELECT
+                         GROUP_CONCAT(@target:=
+                             (
+                                 SELECT @source:=GROUP_CONCAT(parent_id)
+                                 FROM
+                                     NetworkOrganization
+                                 WHERE
+                                     FIND_IN_SET(organization_id, @source) AND parent_id NOT IN (%s, %s)
+                                    AND (endDate is null or endDate = \"0000-00-00\" or endDate > CURDATE()) 
+                             )
+                         ) AS parents
+                 FROM
+                     (SELECT
+                         @source:=%d,
+                         @target:=0
+                     ) vars,
+                     NetworkOrganization
+                 WHERE
+                     @source IS NOT NULL
+               ) tmp
+               WHERE FIND_IN_SET(o.id, parents)
+         ",
+            OrganizationIdsEnum::_2IOS(),
+            OrganizationIdsEnum::OPENTALENT_BASE(),
+            $organization->getId()
+        );
+
+        $rsm = new ResultSetMappingBuilder($this->getEntityManager());
+        $rsm->addRootEntityFromClassMetadata(Organization::class, 'o');
+        $query = $this->getEntityManager()->createNativeQuery($sql, $rsm);
+
+        return $query->getResult();
     }
-    */
 }

+ 2 - 43
src/Repository/Organization/OrganizationRepository.php

@@ -4,9 +4,11 @@ declare(strict_types=1);
 namespace App\Repository\Organization;
 
 use App\Entity\Organization\Organization;
+use App\Enum\Organization\OrganizationIdsEnum;
 use App\Enum\Organization\PrincipalTypeEnum;
 use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
 use Doctrine\ORM\Query\ResultSetMapping;
+use Doctrine\ORM\Query\ResultSetMappingBuilder;
 use Doctrine\Persistence\ManagerRegistry;
 
 /**
@@ -21,47 +23,4 @@ class OrganizationRepository extends ServiceEntityRepository
     {
         parent::__construct($registry, Organization::class);
     }
-
-    /**
-     * Vérifie si l'organisation est un dernier parent : possède des enfants mais ces enfants ne possèdent pas d'enfant
-     * @param Organization $organization
-     * @return bool
-     */
-    public function isLastParent(Organization $organization): bool {
-
-        $sql = sprintf("
-        SELECT 
-            IF( (SELECT o.id 
-                    FROM Organization as o 
-                    WHERE o.id=neto.organization_id
-                    AND o.principalType IN('%s','%s','%s','%s','%s','%s')) IS NOT NULL ,0,1) AS is_last_parent
-        FROM
-            NetworkOrganization as neto
-        WHERE
-            neto.parent_id = %d
-            and (neto.endDate is null or neto.endDate = \"0000-00-00\" or neto.endDate > CURDATE())
-        GROUP BY is_last_parent
-        ORDER BY is_last_parent DESC",
-            PrincipalTypeEnum::NATIONAL_FEDERATION(),
-            PrincipalTypeEnum::REGIONAL_FEDERATION(),
-            PrincipalTypeEnum::LOCAL_FEDERATION(),
-            PrincipalTypeEnum::GROUPMENT(),
-            PrincipalTypeEnum::DEPARTEMENTAL_FEDERATION(),
-            PrincipalTypeEnum::DELEGATION(),
-            $organization->getId()
-        );
-
-        $rsm = new ResultSetMapping();
-        $rsm->addScalarResult('is_last_parent', 'is_last_parent', 'integer');
-        $query = $this->getEntityManager()->createNativeQuery($sql, $rsm);
-        $result = $query->getResult(\Doctrine\ORM\Query::HYDRATE_ARRAY);
-
-        foreach ($result as $a_tmp) {
-            if ($a_tmp['is_last_parent']) {
-                return true;
-            }
-        }
-
-        return false;
-    }
 }

+ 50 - 0
src/Repository/Organization/ParametersRepository.php

@@ -0,0 +1,50 @@
+<?php
+
+namespace App\Repository\Organization;
+
+use App\Entity\Organization\Parameters;
+use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
+use Doctrine\Persistence\ManagerRegistry;
+
+/**
+ * @method Parameters|null find($id, $lockMode = null, $lockVersion = null)
+ * @method Parameters|null findOneBy(array $criteria, array $orderBy = null)
+ * @method Parameters[]    findAll()
+ * @method Parameters[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
+ */
+class ParametersRepository extends ServiceEntityRepository
+{
+    public function __construct(ManagerRegistry $registry)
+    {
+        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()
+        ;
+    }
+    */
+}

+ 2 - 3
src/Security/ModuleVoter.php

@@ -19,11 +19,10 @@ use ApiPlatform\Core\Util\RequestAttributesExtractor;
  */
 class ModuleVoter extends Voter
 {
-    private $resourceMetadataFactory;
-
     const HAVING_MODULE = 'IS_HAVING_MODULE';
 
-    private $module;
+    private ResourceMetadataFactoryInterface $resourceMetadataFactory;
+    private Module $module;
 
     public function __construct(Module $module, ResourceMetadataFactoryInterface $resourceMetadataFactory)
     {

+ 37 - 72
src/Service/Cotisation/Utils.php

@@ -4,31 +4,28 @@ declare(strict_types=1);
 namespace App\Service\Cotisation;
 
 use App\Entity\Organization\Organization;
-use App\Repository\Organization\OrganizationRepository;
+use App\Repository\Network\NetworkOrganizationRepository;
 use App\Service\Organization\Utils as OrganizationUtils;
 use App\Tests\Service\Cotisation\UtilsTest;
-use App\Service\Network\Utils as NetWorkUtils;
+use App\Service\Network\Utils as NetworkUtils;
 
 /**
  * Class Utils : Service rassemblant des fonctions d'interrogation pour gérer des conditions dans les Cotisations
  * @package App\Service\Cotisation
  */
 class Utils {
-    /** @var NetWorkUtils  */
-    private $networkUtils;
-    /** @var OrganizationRepository  */
-    private $organizationRepository;
-    /** @var OrganizationUtils  */
-    private $organizationUtils;
+    private NetworkUtils $networkUtils;
+    private NetworkOrganizationRepository $networkOrganizationRepository;
+    private OrganizationUtils $organizationUtils;
 
     function __construct(
-        NetWorkUtils $networkUtils,
+        NetworkUtils $networkUtils,
         OrganizationUtils $organizationUtils,
-        OrganizationRepository $organizationRepository
+        NetworkOrganizationRepository $networkOrganizationRepository
     ) {
         $this->networkUtils = $networkUtils;
         $this->organizationUtils = $organizationUtils;
-        $this->organizationRepository = $organizationRepository;
+        $this->networkOrganizationRepository = $networkOrganizationRepository;
     }
 
     /**
@@ -38,78 +35,46 @@ class Utils {
      * @see UtilsTest::testIsLastParentAndCMF()
      */
     public function isLastParentAndCMF(Organization $organization): bool {
-        return $this->organizationRepository->isLastParent($organization) && $this->networkUtils->isCMF($organization);
+        return $this->networkOrganizationRepository->isLastParent($organization) && $this->networkUtils->isCMF($organization);
     }
 
     /**
      * Test si l'organisation est une structure (non manager) ET appartient à la CMF
      * @param Organization $organization
      * @return bool
+     * @see UtilsTest::testIsStructureAndCMF()
      */
     public function isStructureAndCMF(Organization $organization):bool {
         return $this->organizationUtils->isStructure($organization) && $this->networkUtils->isCMF($organization);
     }
 
+    /**
+     * Test si la structure est un manager ET qu'elle appartient à la CMF
+     * @param Organization $organization
+     * @return bool
+     * @see UtilsTest::testIsManagerAndCMF()
+     */
+    public function isManagerAndCMF(Organization $organization): bool{
+        return $this->organizationUtils->isManager($organization) && $this->networkUtils->isCMF($organization);
+    }
 
-//
-//    /**
-//     * check if the organization is "lastParent" and product is manager and belong to CMF net
-//     * @param Organization $organization
-//     * @return type boolean TRUE if the organization is "lastParent" and product is manager and belong to CMF net
-//     */
-//    public function isLastParentAndManagerCMFAndCMF(Organization $organization) {
-//        $organizationRepository = $this->em->getRepository(Organization::class);
-//
-//        $isLastParent = $organizationRepository->isLastParent($organization->getId());
-//        $isCMFOrganization = ($organization->getId() == OrganizationEnum::CMF);
-//        $productName = $this->tipsUtils->getProductName(TipsProductEnum::OPENTALENT_MANAGER_STANDARD);
-//        $isManager = ($organization->getSettings()->getProduct() == $productName);
-//        $isCMF = $this->networkUtils->isOrganizationBelongToTheNetwork($organization, NetworkEnum::CMF());
-//
-//        return $isLastParent & $isCMFOrganization & $isManager & $isCMF;
-//    }
-//
-//    /**
-//     * check if the organization is OrganizationEnum::CMF
-//     *
-//     * @param Organization $organization
-//     * @return type boolean return TRUE if the organization is OrganizationEnum::CMF
-//     */
-//    public function isCMFAdministration(Organization $organization) {
-//        $organizationRepository = $this->em->getRepository(Organization::class);
-//
-//        $isCMFOrganization = ($organization->getId() == OrganizationEnum::CMF());
-//
-//        return $isCMFOrganization;
-//    }
-//
-//    /**
-//     * Check if the organization product is manager and belong to CMF net
-//     * @param Organization $organization
-//     * @return type boolean TRUE if the organization product is manager and belong to CMF net
-//     */
-//    public function isManagerAndCMF(Organization $organization) {
-//        $productName = $this->tipsUtils->getProductName(TipsProductEnum::OPENTALENT_MANAGER_STANDARD());
-//        $isManager = ($organization->getSettings()->getProduct() == $productName);
-//        $isCMF = $this->networkUtils->isOrganizationBelongToTheNetwork($organization, NetworkEnum::CMF());
-//
-//        return $isManager & $isCMF;
-//    }
-//
-//    /**
-//     * Check if the organization product is manager and is not "lastParent" and belong to CMF net
-//     * @param Organization $organization
-//     * @return type boolean TRUE if the organization product is manager and is not "lastParent" and belong to CMF net
-//     */
-//    public function isManagerAndNotLastParentAndCMF(Organization $organization) {
-//        $organizationRepository = $this->em->getRepository(Organization::class);
-//
-//        $productName = $this->tipsUtils->getProductName(TipsProductEnum::OPENTALENT_MANAGER_STANDARD());
-//        $isManager = ($organization->getSettings()->getProduct() == $productName);
-//        $isLastParent = $organizationRepository->isLastParent($organization->getId());
-//        $isCMF = $this->networkUtils->isOrganizationBelongToTheNetwork($organization, NetworkEnum::CMF());
-//        return $isManager & !$isLastParent & $isCMF;
-//    }
-//
+    /**
+     * Test si l'organisation est un manager ET un dernier parent ET appartient à la CMF
+     * @param Organization $organization
+     * @return bool
+     * @see UtilsTest::testIsManagerAndLastParentAndCMF()
+     */
+    public function isManagerAndLastParentAndCMF(Organization $organization): bool {
+        return $this->organizationUtils->isManager($organization) && $this->isLastParentAndCMF($organization);
+    }
 
+    /**
+     * Test si l'organisation est un manager ET n'est pas un dernier parent ET appartient à la CMF
+     * @param Organization $organization
+     * @return bool
+     * @see UtilsTest::testIsManagerAndNotLastParentAndCMF()
+     */
+    public function isManagerAndNotLastParentAndCMF(Organization $organization): bool {
+        return $this->organizationUtils->isManager($organization) && !$this->isLastParentAndCMF($organization);
+    }
 }

+ 62 - 0
src/Service/Network/Tree.php

@@ -0,0 +1,62 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Service\Network;
+
+
+use App\Entity\Organization\Organization;
+use App\Enum\Organization\PrincipalTypeEnum;
+use App\Repository\Network\NetworkOrganizationRepository;
+use App\Tests\Service\Network\TreeTest;
+
+/**
+ * Class Tree : service rassemblant des fonction pour répondre aux poblématique d'arbre du réseau
+ * @package App\Service\Network
+ */
+class Tree
+{
+    private NetworkOrganizationRepository $networkOrganizationRepository;
+
+    public function __construct(NetworkOrganizationRepository $networkOrganizationRepository)
+    {
+        $this->networkOrganizationRepository = $networkOrganizationRepository;
+    }
+
+    /**
+     * Retrouve tous les parents d'une structure et les tries selon leur type principal
+     * @param Organization $organization
+     * @return array
+     */
+    public function findAllParentsAndSortByType(Organization $organization): array {
+        return $this->sortByType($this->networkOrganizationRepository->findAllParents($organization));
+    }
+
+    /**
+     * Trie les organisations par rapport à leur type principal :
+     * DELEGATION, GROUPMENT,  LOCAL_FEDERATION, DEPARTEMENTAL_FEDERATION, REGIONAL_FEDERATION, NATIONAL_FEDERATION
+     * @param array $organizations
+     * @return array
+     * @see TreeTest::testSortByType()
+     */
+    public function sortByType(array $organizations): array {
+        $typeOrder = [
+            PrincipalTypeEnum::DELEGATION(),
+            PrincipalTypeEnum::GROUPMENT(),
+            PrincipalTypeEnum::LOCAL_FEDERATION(),
+            PrincipalTypeEnum::DEPARTEMENTAL_FEDERATION(),
+            PrincipalTypeEnum::REGIONAL_FEDERATION(),
+            PrincipalTypeEnum::NATIONAL_FEDERATION()
+        ];
+
+        usort($organizations, function(Organization $organization1, Organization $organization2) use($typeOrder){
+            $orderOrganization1 = array_keys($typeOrder, $organization1->getPrincipalType());
+            $orderOrganization2 = array_keys($typeOrder, $organization2->getPrincipalType());
+            if ($orderOrganization1 == $orderOrganization2) {
+                return 0;
+            }
+            return ($orderOrganization1 < $orderOrganization2) ? -1 : 1;
+        });
+
+        return $organizations;
+    }
+}

+ 1 - 1
src/Service/Network/Utils.php

@@ -21,7 +21,7 @@ class Utils
     /**
      * Test si l'organisation appartient au réseau de la CMF
      * @param Organization $organization
-     * @return bool TRUE if the organization belong to CMF net
+     * @return bool
      * @see UtilsTest::testIsCmf()
      */
     public function isCMF(Organization $organization): bool {

+ 43 - 2
src/Service/Organization/Utils.php

@@ -4,6 +4,7 @@ declare(strict_types=1);
 namespace App\Service\Organization;
 
 use App\Entity\Organization\Organization;
+use App\Enum\Organization\OrganizationIdsEnum;
 use App\Enum\Organization\SettingsProductEnum;
 use App\Test\Service\Organization\UtilsTest;
 
@@ -24,7 +25,47 @@ class Utils
      * @see UtilsTest::testIsStructureTest()
      */
     public function isStructure(Organization $organization): bool{
-        return $organization->getSettings()->getProduct() !== SettingsProductEnum::MANAGER()
-            && $organization->getSettings()->getProduct() !== SettingsProductEnum::MANAGER_PREMIUM();
+        return $organization->getSettings()->getProduct() != SettingsProductEnum::MANAGER()
+            && $organization->getSettings()->getProduct() != SettingsProductEnum::MANAGER_PREMIUM();
+    }
+
+    /**
+     * Test si l'organisation est considérée comme un manager == a un produit manager standard
+     * @param Organization $organization
+     * @return bool
+     * @see UtilsTest::testIsManagerTest()
+     */
+    public function isManager(Organization $organization): bool{
+        return $organization->getSettings()->getProduct() == SettingsProductEnum::MANAGER();
+    }
+
+    /**
+     * Test si l'organisation est la structure 2iOpenservice
+     * @param Organization $organization
+     * @return bool
+     * @see UtilsTest::testIsOrganizationIs2ios()
+     */
+    public function isOrganizationIs2ios(Organization $organization): bool{
+        return $this->isOrganizationIdIs($organization, OrganizationIdsEnum::_2IOS());
+    }
+
+    /**
+     * Test si l'organisation est la structure CMF
+     * @param Organization $organization
+     * @return bool
+     * @see UtilsTest::testIsOrganizationIsCMF()
+     */
+    public function isOrganizationIsCMF(Organization $organization): bool{
+        return $this->isOrganizationIdIs($organization, OrganizationIdsEnum::CMF());
+    }
+
+    /**
+     * Test si l'id de l'organisation est celui passé en paramètre (doit faire partit des OrganizationIdsEnum)
+     * @param Organization $organization
+     * @param OrganizationIdsEnum $organizationIdsEnum
+     * @return bool
+     */
+    private function isOrganizationIdIs(Organization $organization, OrganizationIdsEnum $organizationIdsEnum){
+        return $organization->getId() === $organizationIdsEnum->getValue();
     }
 }

+ 11 - 17
src/Service/Security/Module.php

@@ -19,14 +19,9 @@ class Module
 {
     const OPENTALENT_CONFIG = __DIR__.'/../../../config/opentalent';
 
-    /** @var array  */
-    private $moduleConfig;
-
-    /** @var array */
-    private $moduleByConditionsConfig;
-
-    /** @var Reflection  */
-    private $reflection;
+    private array $moduleConfig;
+    private array $moduleByConditionsConfig;
+    private Reflection $reflection;
 
     public function __construct(Reflection $reflection)
     {
@@ -36,16 +31,17 @@ class Module
     }
 
     /**
+     * @todo activer le cache après que la fin de la migration.
      * Récupère tous les modules de l'oganisation
      * @param Organization $organization
      * @return array
      */
     public function getOrganizationModules(Organization $organization): array {
-        $cacheDriver = new ApcuCache();
-        //If the modules are all ready available inside the APCu cache
-        if($cacheDriver->contains('organization_modules_' . $organization->getId())){
-            return $cacheDriver->fetch('organization_modules_' . $organization->getId());
-        }
+//        $cacheDriver = new ApcuCache();
+//        //If the modules are all ready available inside the APCu cache
+//        if($cacheDriver->contains('organization_modules_' . $organization->getId())){
+//            return $cacheDriver->fetch('organization_modules_' . $organization->getId());
+//        }
 
         $modulesBySettings = $this->getModuleBySettings($organization);
 
@@ -56,8 +52,8 @@ class Module
 
         $organizationModules = array_merge_recursive($modulesForProduct, $modulesBySettings, $modulesByConditions);
 
-        //Keep the modules inside the APCu cache
-        $cacheDriver->save('organization_modules_' . $organization->getId(), $organizationModules, '86400');
+//        //Keep the modules inside the APCu cache
+//        $cacheDriver->save('organization_modules_' . $organization->getId(), $organizationModules, '86400');
 
         return $organizationModules;
     }
@@ -88,7 +84,6 @@ class Module
      */
     public function getModulesByConditions(Organization $organization): array {
         $modulesByConditions = [];
-        return $modulesByConditions;
         $modules = $this->moduleByConditionsConfig['opentalent']['modulesbyconditions'];
         foreach ($modules as $moduleName => $module) {
             try{
@@ -102,7 +97,6 @@ class Module
                 }
             }catch (\Exception $exception){}
         }
-
         return $modulesByConditions;
     }
 

+ 4 - 3
src/Service/Utils/Reflection.php

@@ -11,8 +11,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
  */
 class Reflection
 {
-    /** @var ContainerInterface */
-    private $container;
+    private ContainerInterface $container;
 
     public function __construct(ContainerInterface $container)
     {
@@ -20,14 +19,16 @@ class Reflection
     }
 
     /**
+     * Appel une fonction avec ses paramètres d'une classe
      * @param string $serviceName
      * @param string $method
      * @param array $parameters
      * @return mixed
+     * @throws \ReflectionException
      */
     public function dynamicInvokeWithArgsServiceMethod(string $serviceName, string $method, array $parameters = []) {
         $function = $this->container->get($serviceName);
-        $reflection = \ReflectionClass(get_class($function));
+        $reflection = new \ReflectionClass(get_class($function));
         $method = $reflection->getMethod($method);
         return $method->invokeArgs($function, $parameters);
     }

+ 0 - 12
symfony.lock

@@ -203,9 +203,6 @@
     "symfony/asset": {
         "version": "v5.1.7"
     },
-    "symfony/browser-kit": {
-        "version": "v5.2.1"
-    },
     "symfony/cache": {
         "version": "v5.1.7"
     },
@@ -227,9 +224,6 @@
             "bin/console"
         ]
     },
-    "symfony/css-selector": {
-        "version": "v5.2.1"
-    },
     "symfony/dependency-injection": {
         "version": "v5.1.7"
     },
@@ -239,9 +233,6 @@
     "symfony/doctrine-bridge": {
         "version": "v5.1.7"
     },
-    "symfony/dom-crawler": {
-        "version": "v5.2.1"
-    },
     "symfony/dotenv": {
         "version": "v5.1.7"
     },
@@ -408,9 +399,6 @@
     "symfony/string": {
         "version": "v5.1.7"
     },
-    "symfony/test-pack": {
-        "version": "v1.0.7"
-    },
     "symfony/translation-contracts": {
         "version": "v2.3.0"
     },

+ 174 - 31
tests/Service/Cotisation/UtilsTest.php

@@ -3,7 +3,7 @@
 namespace App\Tests\Service\Cotisation;
 
 use App\Entity\Organization\Organization;
-use App\Repository\Organization\OrganizationRepository;
+use App\Repository\Network\NetworkOrganizationRepository;
 use App\Service\Cotisation\Utils;
 use App\Service\Organization\Utils as OrganizationUtils;
 use PHPUnit\Framework\TestCase;
@@ -11,8 +11,28 @@ use \App\Service\Network\Utils as NetworkUtils;
 
 class UtilsTest extends TestCase
 {
+    private NetworkOrganizationRepository $networkOrganizationRepositoryMock;
+    private NetworkUtils $networkUtilsMock;
+    private OrganizationUtils $organizationUtilsMock;
+
     public function setUp(): void
     {
+        $this->networkOrganizationRepositoryMock =
+            $this
+                ->getMockBuilder(NetworkOrganizationRepository::class)
+                ->disableOriginalConstructor()
+                ->getMock();
+
+        $this->networkUtilsMock =
+            $this
+                ->getMockBuilder(NetworkUtils::class)
+                ->disableOriginalConstructor()
+                ->getMock();
+
+        $this->organizationUtilsMock =
+            $this
+                ->getMockBuilder(OrganizationUtils::class)
+                ->getMock();
     }
 
     /**
@@ -25,31 +45,19 @@ class UtilsTest extends TestCase
             ->method('getId')
             ->willReturn(1);
 
-        $organizationRepositoryMock =
-            $this
-                ->getMockBuilder(OrganizationRepository::class)
-                ->disableOriginalConstructor()
-                ->getMock();
-        $organizationRepositoryMock
+        $this->networkOrganizationRepositoryMock
                 ->expects($this->once())
                 ->method('isLastParent')
                 ->with($organizationMock)
                 ->willReturn(true);
 
-        $networkUtilsMock =
-            $this
-                ->getMockBuilder(NetworkUtils::class)
-                ->disableOriginalConstructor()
-                ->getMock();
-        $networkUtilsMock
+        $this->networkUtilsMock
                 ->expects($this->once())
                 ->method('isCMF')
                 ->with($organizationMock)
                 ->willReturn(true);
 
-        $organizationUtilsMock = $this->getMockBuilder(OrganizationUtils::class)->getMock();
-
-        $utils = new Utils($networkUtilsMock, $organizationUtilsMock, $organizationRepositoryMock);
+        $utils = new Utils($this->networkUtilsMock, $this->organizationUtilsMock, $this->networkOrganizationRepositoryMock);
         $this->assertTrue($utils->isLastParentAndCMF($organizationMock));
     }
 
@@ -63,31 +71,166 @@ class UtilsTest extends TestCase
             ->method('getId')
             ->willReturn(1);
 
-        $organizationRepositoryMock =
-            $this
-                ->getMockBuilder(OrganizationRepository::class)
-                ->disableOriginalConstructor()
-                ->getMock();
-        $organizationRepositoryMock
+        $this->networkOrganizationRepositoryMock
             ->expects($this->once())
             ->method('isLastParent')
             ->with($organizationMock)
             ->willReturn(false);
 
-        $networkUtilsMock =
-            $this
-                ->getMockBuilder(NetworkUtils::class)
-                ->disableOriginalConstructor()
-                ->getMock();
-        $networkUtilsMock
+        $this->networkUtilsMock
             ->expects($this->never())
+            ->method('isCMF');
+
+        $utils = new Utils($this->networkUtilsMock, $this->organizationUtilsMock, $this->networkOrganizationRepositoryMock);
+        $this->assertFalse($utils->isLastParentAndCMF($organizationMock));
+    }
+
+    /**
+     * @see Utils::isStructureAndCMF()
+     */
+    public function testIsStructureAndCMF(): void
+    {
+        $organizationMock = $this->getMockBuilder(Organization::class)->getMock();
+
+        $this->organizationUtilsMock
+            ->expects($this->once())
+            ->method('isStructure')
+            ->with($organizationMock)
+            ->willReturn(true);
+
+        $this->networkUtilsMock
+            ->expects($this->once())
             ->method('isCMF')
             ->with($organizationMock)
             ->willReturn(true);
 
-        $organizationUtilsMock = $this->getMockBuilder(OrganizationUtils::class)->getMock();
+        $utils = new Utils($this->networkUtilsMock, $this->organizationUtilsMock, $this->networkOrganizationRepositoryMock);
+        $this->assertTrue($utils->isStructureAndCMF($organizationMock));
+    }
 
-        $utils = new Utils($networkUtilsMock, $organizationUtilsMock, $organizationRepositoryMock);
-        $this->assertFalse($utils->isLastParentAndCMF($organizationMock));
+    /**
+     * @see Utils::isStructureAndCMF()
+     */
+    public function testIsNotStructureAndCMF(): void
+    {
+        $organizationMock = $this->getMockBuilder(Organization::class)->getMock();
+
+        $this->organizationUtilsMock
+            ->expects($this->once())
+            ->method('isStructure')
+            ->with($organizationMock)
+            ->willReturn(false);
+
+        $this->networkUtilsMock
+            ->expects($this->never())
+            ->method('isCMF');
+
+        $utils = new Utils($this->networkUtilsMock, $this->organizationUtilsMock, $this->networkOrganizationRepositoryMock);
+        $this->assertFalse($utils->isStructureAndCMF($organizationMock));
+    }
+
+    /**
+     * @see Utils::isManagerAndCMF()
+     */
+    public function testIsManagerAndCMF(): void
+    {
+        $organizationMock = $this->getMockBuilder(Organization::class)->getMock();
+
+        $this->organizationUtilsMock
+            ->expects($this->once())
+            ->method('isManager')
+            ->with($organizationMock)
+            ->willReturn(true);
+
+        $this->networkUtilsMock
+            ->expects($this->once())
+            ->method('isCMF')
+            ->with($organizationMock)
+            ->willReturn(true);
+
+        $utils = new Utils($this->networkUtilsMock, $this->organizationUtilsMock, $this->networkOrganizationRepositoryMock);
+        $this->assertTrue($utils->isManagerAndCMF($organizationMock));
+    }
+
+    /**
+     * @see Utils::isManagerAndCMF()
+     */
+    public function testIsNotManagerAndCMF(): void
+    {
+        $organizationMock = $this->getMockBuilder(Organization::class)->getMock();
+
+        $this->organizationUtilsMock
+            ->expects($this->once())
+            ->method('isManager')
+            ->with($organizationMock)
+            ->willReturn(false);
+
+        $this->networkUtilsMock
+            ->expects($this->never())
+            ->method('isCMF');
+
+        $utils = new Utils($this->networkUtilsMock, $this->organizationUtilsMock, $this->networkOrganizationRepositoryMock);
+        $this->assertFalse($utils->isManagerAndCMF($organizationMock));
+    }
+
+    /**
+     * @see Utils::isManagerAndNotLastParentAndCMF()
+     */
+    public function testIsManagerAndNotLastParentAndCMF(): void
+    {
+        $organizationMock = $this->getMockBuilder(Organization::class)->getMock();
+        $organizationMock
+            ->method('getId')
+            ->willReturn(1);
+
+        $this->organizationUtilsMock
+            ->expects($this->once())
+            ->method('isManager')
+            ->with($organizationMock)
+            ->willReturn(true);
+
+        $this->networkOrganizationRepositoryMock
+            ->expects($this->once())
+            ->method('isLastParent')
+            ->with($organizationMock)
+            ->willReturn(false);
+
+        $this->networkUtilsMock
+            ->expects($this->never())
+            ->method('isCMF');
+
+        $utils = new Utils($this->networkUtilsMock, $this->organizationUtilsMock, $this->networkOrganizationRepositoryMock);
+        $this->assertTrue($utils->isManagerAndNotLastParentAndCMF($organizationMock));
+    }
+
+    /**
+     * @see Utils::isManagerAndLastParentAndCMF()
+     */
+    public function testIsManagerAndLastParentAndCMF(): void
+    {
+        $organizationMock = $this->getMockBuilder(Organization::class)->getMock();
+        $organizationMock
+            ->method('getId')
+            ->willReturn(1);
+
+        $this->organizationUtilsMock
+            ->expects($this->once())
+            ->method('isManager')
+            ->with($organizationMock)
+            ->willReturn(true);
+
+        $this->networkOrganizationRepositoryMock
+            ->expects($this->once())
+            ->method('isLastParent')
+            ->with($organizationMock)
+            ->willReturn(true);
+
+        $this->networkUtilsMock
+            ->expects($this->once())
+            ->method('isCMF')
+            ->willReturn(true);
+
+        $utils = new Utils($this->networkUtilsMock, $this->organizationUtilsMock, $this->networkOrganizationRepositoryMock);
+        $this->assertTrue($utils->isManagerAndLastParentAndCMF($organizationMock));
     }
 }

+ 81 - 0
tests/Service/Network/TreeTest.php

@@ -0,0 +1,81 @@
+<?php
+namespace App\Tests\Service\Network;
+
+use App\Entity\Organization\Organization;
+use App\Repository\Network\NetworkOrganizationRepository;
+use PHPUnit\Framework\TestCase;
+use App\Service\Network\Tree;
+
+class TreeTest extends TestCase
+{
+    private Tree $tree;
+    private NetworkOrganizationRepository $networkOrganizationRepositoryMock;
+
+    public function setUp():void
+    {
+        $this->networkOrganizationRepositoryMock =
+            $this
+                ->getMockBuilder(NetworkOrganizationRepository::class)
+                ->disableOriginalConstructor()
+                ->getMock();
+        $this->tree = new Tree($this->networkOrganizationRepositoryMock);
+    }
+
+    /**
+     * @see Tree::findAllParentsAndSortByType()
+     */
+    public function testFindAllParentsAndSortByType():void
+    {
+        $organizationMock = $this->getMockBuilder(Organization::class)->getMock();
+        $organizationMock
+            ->method('getId')
+            ->willReturn(1);
+        $this->networkOrganizationRepositoryMock
+            ->expects($this->once())
+            ->method('findAllParents')
+            ->with($organizationMock)
+            ->willReturn([$organizationMock]);
+
+        $treeMock = $this
+            ->getMockBuilder(Tree::class)
+            ->setConstructorArgs([$this->networkOrganizationRepositoryMock])
+            ->onlyMethods(['sortByType'])
+            ->getMock();
+        $treeMock
+            ->expects($this->once())
+            ->method('sortByType');
+        $treeMock->findAllParentsAndSortByType($organizationMock);
+    }
+
+    /**
+     * @see Tree::sortByType()
+     */
+    public function testSortByType():void
+    {
+        $organizationMock1 = $this->getMockBuilder(Organization::class)->getMock();
+        $organizationMock1->method('getId')->willReturn(2);
+        $organizationMock1->method('getPrincipalType')->willReturn('REGIONAL_FEDERATION');
+
+        $organizationMock2 = $this->getMockBuilder(Organization::class)->getMock();
+        $organizationMock2->method('getId')->willReturn(3);
+        $organizationMock2->method('getPrincipalType')->willReturn('NATIONAL_FEDERATION');
+
+        $organizationMock3 = $this->getMockBuilder(Organization::class)->getMock();
+        $organizationMock3->method('getId')->willReturn(4);
+        $organizationMock3->method('getPrincipalType')->willReturn('DEPARTEMENTAL_FEDERATION');
+
+        $organizations = [
+            $organizationMock2,
+            $organizationMock1,
+            $organizationMock3
+        ];
+
+        $result = $this->tree->sortByType($organizations);
+
+        $this->assertIsArray($result);
+        $this->assertContainsOnlyInstancesOf(Organization::class, $result);
+        $this->assertEquals(4, $result[0]->getId());
+        $this->assertEquals(2, $result[1]->getId());
+        $this->assertEquals(3, $result[2]->getId());
+    }
+}

+ 3 - 7
tests/Service/Network/UtilsTest.php

@@ -5,18 +5,14 @@ use App\Entity\Network\Network;
 use App\Entity\Network\NetworkOrganization;
 use App\Entity\Organization\Organization;
 use App\Enum\Network\NetworkEnum;
-use Doctrine\Common\Collections\ArrayCollection;
 use PHPUnit\Framework\TestCase;
 use App\Service\Network\Utils;
 
 class UtilsTest extends TestCase
 {
-    /** @var Utils */
-    private $utils;
-
-    private $organizationCmf;
-
-    private $organizationFfec;
+    private Utils $utils;
+    private Organization $organizationCmf;
+    private Organization $organizationFfec;
 
     public function setUp():void
     {

+ 62 - 5
tests/Service/Organization/UtilsTest.php

@@ -9,11 +9,9 @@ use PHPUnit\Framework\TestCase;
 
 class UtilsTest extends TestCase
 {
-    /** @var OrganizationUtils */
-    private $organizationUtils;
-
-    /** @var Organization */
-    private $organization;
+    private OrganizationUtils $organizationUtils;
+    private Organization $organization;
+    private Organization $federation;
 
     public function setUp():void
     {
@@ -22,6 +20,11 @@ class UtilsTest extends TestCase
         $this->organization = new Organization();
         $this->organization->setSettings($settings);
 
+        $settings = new Settings();
+        $settings->setProduct(SettingsProductEnum::MANAGER());
+        $this->federation = new Organization();
+        $this->federation->setSettings($settings);
+
         $this->organizationUtils = new OrganizationUtils();
     }
 
@@ -31,4 +34,58 @@ class UtilsTest extends TestCase
     public function testIsStructureTest(){
         $this->assertTrue($this->organizationUtils->isStructure($this->organization));
     }
+
+    /**
+     * @see OrganizationUtils::isStructure()
+     */
+    public function testIsNotStructureTest(){
+        $this->assertFalse($this->organizationUtils->isStructure($this->federation));
+    }
+
+    /**
+     * @see OrganizationUtils::isManager()
+     */
+    public function testIsManagerTest(){
+        $this->assertTrue($this->organizationUtils->isManager($this->federation));
+    }
+
+    /**
+     * @see OrganizationUtils::isManager()
+     */
+    public function testIsNotManagerTest(){
+        $this->assertFalse($this->organizationUtils->isManager($this->organization));
+    }
+
+    /**
+     * @see OrganizationUtils::isOrganizationIs2ios()
+     */
+    public function testIsOrganizationIs2ios(){
+        $organizationMock = $this->getMockBuilder(Organization::class)->getMock();
+        $organizationMock
+            ->method('getId')
+            ->willReturn(32366);
+        $this->assertTrue($this->organizationUtils->isOrganizationIs2ios($organizationMock));
+    }
+
+    /**
+     * @see OrganizationUtils::isOrganizationIs2ios()
+     */
+    public function testIsNotOrganizationIs2ios(){
+        $organizationMock = $this->getMockBuilder(Organization::class)->getMock();
+        $organizationMock
+            ->method('getId')
+            ->willReturn(1);
+        $this->assertFalse($this->organizationUtils->isOrganizationIs2ios($organizationMock));
+    }
+
+    /**
+     * @see OrganizationUtils::isOrganizationIsCMF()
+     */
+    public function testIsOrganizationIsCMF(){
+        $organizationMock = $this->getMockBuilder(Organization::class)->getMock();
+        $organizationMock
+            ->method('getId')
+            ->willReturn(12097);
+        $this->assertTrue($this->organizationUtils->isOrganizationIsCMF($organizationMock));
+    }
 }

+ 1 - 1
tests/Service/Security/ModuleTest.php

@@ -9,7 +9,7 @@ use App\Service\Security\Module;
 
 class ModuleTest extends TestCase
 {
-    private $reflectionMock;
+    private Reflection $reflectionMock;
 
     public function setUp():void
     {

部分文件因为文件数量过多而无法显示