src/Entity/Purse/Purse.php line 58

Open in your IDE?
  1. <?php
  2. namespace App\Entity\Purse;
  3. use ApiPlatform\Core\Annotation\ApiFilter;
  4. use App\Controller\Api\PurseAvailableByUser;
  5. use App\Controller\Api\PurseExpiringByUser;
  6. use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
  7. use App\Entity\User\User;
  8. use App\Repository\Purse\PurseRepository;
  9. use Doctrine\Common\Annotations\Annotation\IgnoreAnnotation;
  10. use Doctrine\Common\Collections\ArrayCollection;
  11. use Doctrine\Common\Collections\Collection;
  12. use Doctrine\ORM\Mapping as ORM;
  13. use Gedmo\Timestampable\Traits\TimestampableEntity;
  14. use ApiPlatform\Core\Annotation\ApiResource;
  15. use ApiPlatform\Core\Annotation\ApiProperty;
  16. use Symfony\Component\Serializer\Annotation\Groups;
  17. use Ramsey\Uuid\Doctrine\UuidGenerator;
  18. /**
  19.  * @ApiResource(
  20.  *      attributes={
  21.  *          "normalization_context"={"groups"={"Purse:io","Purse:output"}},
  22.  *          "denormalization_context"={"groups"={"Purse:io","Purse:input"}}
  23.  *      },
  24.  *     collectionOperations={
  25.  *          "get"={
  26.  *              "method"="GET",
  27.  *              "access_control"="is_granted('ROLE_USER')",
  28.  *          },
  29.  *     },
  30.  *     itemOperations={
  31.  *          "get"={
  32.  *              "method"="GET",
  33.  *              "access_control"="is_granted('ROLE_USER')",
  34.  *          },
  35.  *          "purse-available"={
  36.  *              "method"="GET",
  37.  *              "path"="/purse-available/user",
  38.  *              "access_control"="is_granted('ROLE_USER')",
  39.  *              "controller"=PurseAvailableByUser::class,
  40.  *              "defaults"={"_api_receive"=false},
  41.  *          },
  42.  *          "purse-expiring"={
  43.  *              "method"="GET",
  44.  *              "path"="/purse-expiring/user",
  45.  *              "access_control"="is_granted('ROLE_USER')",
  46.  *              "controller"=PurseExpiringByUser::class,
  47.  *              "defaults"={"_api_receive"=false},
  48.  *          },
  49.  *      }
  50.  * )
  51.  *
  52.  * @ApiFilter(SearchFilter::class, properties={"items.status": "exact"})
  53.  * @ORM\Entity(repositoryClass=PurseRepository::class)
  54.  */
  55. class Purse
  56. {
  57.     /**
  58.      * Hook timestampable behavior
  59.      * updates createdAt, updatedAt fields
  60.      */
  61.     use TimestampableEntity;
  62.     // ###> Purse Config ###
  63.     const DEFAULT_CONFIG_PURSE_DURATION_IN_DAYS 365;
  64.     const DEFAULT_CONFIG_PURSE_MAX_ITEM 30;
  65.     // ###< Purse Config ###
  66.     const STATUS_AVAILABLE "available";
  67.     const STATUS_DONE "done";
  68.     const STATUS_EXPIRED "expired";
  69.     const STATUS_EXPIRING "expiring";
  70.     /**
  71.      * @var string
  72.      * @ORM\Id
  73.      * @ORM\Column(type="uuid", unique=true)
  74.      * @ORM\GeneratedValue(strategy="CUSTOM")
  75.      * @ORM\CustomIdGenerator(class=UuidGenerator::class)
  76.      * @ApiProperty(identifier=true)
  77.      * @Groups({"Purse:o"})
  78.      */
  79.     private $id;
  80.     /**
  81.      * @ORM\ManyToOne(targetEntity=User::class, inversedBy="purses")
  82.      * @ORM\JoinColumn(nullable=false)
  83.      */
  84.     private $user;
  85.     /**
  86.      * @ORM\Column(type="datetime")
  87.      * @Groups({"Purse:output"})
  88.      */
  89.     private $dueAt;
  90.     /**
  91.      * @ORM\Column(type="integer")
  92.      * @Groups({"Purse:output"})
  93.      */
  94.     private $maxItem;
  95.     /**
  96.      * @ORM\Column(type="float")
  97.      * @Groups({"Purse:output"})
  98.      */
  99.     private $amount 0;
  100.     /**
  101.      * @ORM\Column(type="string", length=30)
  102.      * @Groups({"Purse:output"})
  103.      */
  104.     private $status self::STATUS_AVAILABLE;
  105.     /**
  106.      * @ORM\OneToMany(targetEntity=Item::class, mappedBy="purse", orphanRemoval=true)
  107.      * @ORM\OrderBy({"createdAt" = "ASC", "percentApplied" = "ASC"})
  108.      * @Groups({"Purse:output"})
  109.      */
  110.     private $items;
  111.     public function __construct()
  112.     {
  113.         $this->maxItem $_ENV['CONFIG_PURSE_MAX_ITEM'] ?? self::DEFAULT_CONFIG_PURSE_MAX_ITEM;
  114.         $this->items = new ArrayCollection();
  115.     }
  116.     /**
  117.      * @return string
  118.      */
  119.     public function getId(): string
  120.     {
  121.         return $this->id;
  122.     }
  123.     public function getUser(): ?User
  124.     {
  125.         return $this->user;
  126.     }
  127.     public function setUser(?User $user): self
  128.     {
  129.         $this->user $user;
  130.         return $this;
  131.     }
  132.     public function getDueAt(): ?\DateTimeInterface
  133.     {
  134.         return $this->dueAt;
  135.     }
  136.     public function setDueAt(\DateTimeInterface $dueAt): self
  137.     {
  138.         $this->dueAt $dueAt;
  139.         return $this;
  140.     }
  141.     public function getMaxItem(): ?int
  142.     {
  143.         return $this->maxItem;
  144.     }
  145.     public function setMaxItem(int $maxItem): self
  146.     {
  147.         $this->maxItem $maxItem;
  148.         return $this;
  149.     }
  150.     public function getAmount(): ?float
  151.     {
  152.         if( $this->amount <= ) {
  153.             return 0;
  154.         }
  155.         return $this->amount;
  156.     }
  157.     public function getAvailableAmount(): ?float
  158.     {
  159.         $availableAmount 0;
  160.         foreach( $this->items as $item ) {
  161.             if( $item instanceof Item && in_array($item->getStatus(), [Item::STATUS_NEWItem::STATUS_AVAILABLE]) ) {
  162.                 $availableAmount += $item->getAmount();
  163.             }
  164.         }
  165.         return $availableAmount;
  166.     }
  167.     public function setAmount(float $amount): self
  168.     {
  169.         $this->amount $amount;
  170.         return $this;
  171.     }
  172.     public function getStatus(): ?string
  173.     {
  174.         return $this->status;
  175.     }
  176.     public function setStatus(string $status): self
  177.     {
  178.         $this->status $status;
  179.         return $this;
  180.     }
  181.     /**
  182.      * @param array $statusFilter default []
  183.      * @return Collection|Item[]
  184.      */
  185.     public function getItems(array $statusFilter = []): Collection
  186.     {
  187.         if( !$statusFilter) {
  188.             return $this->items;
  189.         }
  190.         return $this->items->filter(function(Item $item) use ($statusFilter) {
  191.             return in_array($item->getStatus(), $statusFilter);
  192.         });
  193.     }
  194.     public function addItem(Item $item): self
  195.     {
  196.         if ($this->maxItem !== -&& $this->items->count() >= $this->maxItem) {
  197.             return $this;
  198.         }
  199.         if (!$this->items->contains($item)) {
  200.             $this->items[] = $item;
  201.             $item->setPurse($this);
  202.             // increase purse amount
  203.             $this->amount += $item->getAmount();
  204.         }
  205.         return $this;
  206.     }
  207.     public function removeItem(Item $item): self
  208.     {
  209.         if ($this->items->removeElement($item)) {
  210.             // set the owning side to null (unless already changed)
  211.             if ($item->getPurse() === $this) {
  212.                 $item->setPurse(null);
  213.             }
  214.             // decrease purse amount
  215.             $this->amount -= $item->getAmount();
  216.         }
  217.         return $this;
  218.     }
  219.     public function setItemToExpired(Item $item)
  220.     {
  221.         $today = new \DateTime();
  222.         foreach ($this->items as $i) {
  223.             if( !$i instanceof Item || $i->getId() !== $item->getId()) {
  224.                 continue;
  225.             }
  226.             $dueDate = ($item->getDueDate())->modify('+6month');
  227.             if (in_array($item->getStatus(), [Item::STATUS_AVAILABLEItem::STATUS_EXPIRINGItem::STATUS_REFUND_SENT])) {
  228.                 if ($dueDate >= $today && $item->getStatus() !== Item::STATUS_REFUND_SENT) {
  229.                     $item->setStatus(Item::STATUS_EXPIRING);
  230.                 } else {
  231.                     $item->setStatus(Item::STATUS_EXPIRED);
  232.                 }
  233.             }
  234.         }
  235.     }
  236.     public function decreaseAmount($i 1) {
  237.         $this->amount -= $i;
  238.     }
  239. }