Bläddra i källkod

residence area

Vincent GUFFON 3 år sedan
förälder
incheckning
1038e4926f

+ 47 - 0
src/Doctrine/Billing/CurrentResidenceAreaExtension.php

@@ -0,0 +1,47 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Doctrine\Billing;
+
+use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\QueryCollectionExtensionInterface;
+use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\QueryItemExtensionInterface;
+use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface;
+use App\Entity\Access\Access;
+use App\Entity\Billing\ResidenceArea;
+use Doctrine\ORM\QueryBuilder;
+use Symfony\Component\Security\Core\Security;
+
+/**
+ * Class CurrentResidenceAreaExtension : Filtre de sécurité par défaut pour une resource ResidenceArea
+ * @package App\Doctrine\Core
+ */
+final class CurrentResidenceAreaExtension implements QueryCollectionExtensionInterface, QueryItemExtensionInterface
+{
+    public function __construct(private Security $security)
+    { }
+
+    public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null): void
+    {
+        $this->addWhere($queryBuilder, $resourceClass, $operationName);
+    }
+
+    public function applyToItem(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, array $identifiers, string $operationName = null, array $context = []): void
+    {
+        $this->addWhere($queryBuilder, $resourceClass, $operationName);
+    }
+
+    private function addWhere(QueryBuilder $queryBuilder, string $resourceClass, string $operationName): void
+    {
+        if (ResidenceArea::class !== $resourceClass) {
+            return;
+        }
+
+        /** @var Access $currentUser */
+        $currentUser = $this->security->getUser();
+        $rootAlias = $queryBuilder->getRootAliases()[0];
+        $queryBuilder
+            ->andWhere(sprintf('%s.billingSetting = :billingSetting', $rootAlias))
+            ->setParameter('billingSetting', $currentUser->getOrganization()->getBillingSetting())
+        ;
+    }
+}

+ 39 - 0
src/Entity/Billing/BillingSetting.php

@@ -4,9 +4,13 @@ declare(strict_types=1);
 namespace App\Entity\Billing;
 
 use ApiPlatform\Core\Annotation\ApiResource;
+use ApiPlatform\Core\Annotation\ApiSubresource;
 use App\Entity\Organization\Organization;
 use App\Repository\Billing\BillingSettingRepository;
+use Doctrine\Common\Collections\ArrayCollection;
+use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
+use JetBrains\PhpStorm\Pure;
 
 #[ApiResource(
     collectionOperations: [],
@@ -24,9 +28,17 @@ class BillingSetting
     #[ORM\JoinColumn(nullable: false)]
     private Organization $organization;
 
+    #[ORM\OneToMany( mappedBy: 'billingSetting', targetEntity: ResidenceArea::class, cascade: ['persist'], orphanRemoval: true)]
+    private Collection $residenceAreas;
+
     #[ORM\Column(options: ['default' => false])]
     private bool $applyVat = false;
 
+    #[Pure] public function __construct()
+    {
+        $this->residenceAreas = new ArrayCollection();
+    }
+
     public function getId(): ?int
     {
         return $this->id;
@@ -56,4 +68,31 @@ class BillingSetting
 
         return $this;
     }
+
+    public function getResidenceAreas(): Collection
+    {
+        return $this->residenceAreas;
+    }
+
+    public function addResidenceArea(ResidenceArea $residenceArea): self
+    {
+        if (!$this->residenceAreas->contains($residenceArea)) {
+            $this->residenceAreas[] = $residenceArea;
+            $residenceArea->setBillingSetting($this);
+        }
+
+        return $this;
+    }
+
+    public function removeResidenceArea(ResidenceArea $residenceArea): self
+    {
+        if ($this->residenceAreas->removeElement($residenceArea)) {
+            // set the owning side to null (unless already changed)
+            if ($residenceArea->getBillingSetting() === $this) {
+                $residenceArea->setBillingSetting(null);
+            }
+        }
+
+        return $this;
+    }
 }

+ 66 - 0
src/Entity/Billing/ResidenceArea.php

@@ -0,0 +1,66 @@
+<?php
+
+namespace App\Entity\Billing;
+
+use ApiPlatform\Core\Annotation\ApiResource;
+use App\Annotation\BillingSettingDefaultValue;
+use App\Repository\Billing\ResidenceAreaRepository;
+use Doctrine\ORM\Mapping as ORM;
+
+/**
+ * Zone de résidence d'un Access, telle que définie par l'Organization
+ */
+#[ApiResource(
+    collectionOperations: [
+        "get" => ["security" => "is_granted('ROLE_ORGANIZATION_VIEW')"],
+        "post"
+    ],
+    itemOperations: [
+        "get" => ["security" => "is_granted('ROLE_ORGANIZATION_VIEW') and object.getBillingSetting().getOrganization().getId() == user.getOrganization().getId()"],
+        "put" => ["security" => "object.getBillingSetting().getOrganization().getId() == user.getOrganization().getId()"],
+        "delete" => ["security" => "object.getBillingSetting().getOrganization().getId() == user.getOrganization().getId()"],
+    ],
+    attributes: ["security" => "is_granted('ROLE_ORGANIZATION')"]
+)]
+#[BillingSettingDefaultValue(fieldName: "billingSetting")]
+#[ORM\Entity(repositoryClass: ResidenceAreaRepository::class)]
+class ResidenceArea
+{
+    #[ORM\Id]
+    #[ORM\Column]
+    #[ORM\GeneratedValue]
+    private ?int $id = null;
+
+    #[ORM\ManyToOne(inversedBy: 'residenceAreas')]
+    private BillingSetting $billingSetting;
+
+    #[ORM\Column(length: 255)]
+    private string $label;
+
+    public function getId(): ?int
+    {
+        return $this->id;
+    }
+
+    public function getLabel(): string
+    {
+        return $this->label;
+    }
+
+    public function setLabel(string $label){
+        $this->label = $label;
+        return $this;
+    }
+
+    public function getBillingSetting(): BillingSetting
+    {
+        return $this->billingSetting;
+    }
+
+    public function setBillingSetting(BillingSetting $billingSetting): self
+    {
+        $this->billingSetting = $billingSetting;
+
+        return $this;
+    }
+}

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

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

+ 16 - 0
src/Service/Utils/EntityUtils.php

@@ -3,6 +3,7 @@ declare(strict_types=1);
 
 namespace App\Service\Utils;
 
+use App\Annotation\BillingSettingDefaultValue;
 use App\Annotation\OrganizationDefaultValue;
 use App\Entity\Access\Access;
 
@@ -15,6 +16,7 @@ class EntityUtils
     public function defaultValueSettersByAccess($entity, Access $access)
     {
         $this->organizationDefaultValue($entity, $access);
+        $this->billingSettingDefaultValueDefaultValue($entity, $access);
     }
 
     /**
@@ -30,4 +32,18 @@ class EntityUtils
             $entity->{sprintf('set%s', ucfirst($fieldName))}(...[$access->getOrganization()]);
         }
     }
+
+    /**
+     * @param $entity
+     * @throws \ReflectionException
+     */
+    private function billingSettingDefaultValueDefaultValue($entity, Access $access)
+    {
+        $reflection = new \ReflectionClass($entity::class);
+        $billingSettingDefaultValueDefault = $reflection->getAttributes(BillingSettingDefaultValue::class)[0] ?? null;
+        $fieldName = $billingSettingDefaultValueDefault?->getArguments()['fieldName'] ?? null;
+        if($fieldName){
+            $entity->{sprintf('set%s', ucfirst($fieldName))}(...[$access->getOrganization()->getBillingSetting()]);
+        }
+    }
 }