<?php
declare(strict_types=1);
namespace App\Point\Doctrine\Entity;
use ApiPlatform\Core\Annotation\ApiProperty;
use ApiPlatform\Core\Annotation\ApiResource;
use App\Point\Doctrine\Repository\AccountRepository;
use App\Program\Doctrine\Entity\Profile;
use DateTimeImmutable;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\JoinColumn;
use Doctrine\ORM\Mapping\ManyToOne;
use Doctrine\ORM\Mapping\OneToMany;
use Doctrine\ORM\Mapping\Table;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\NotNull;
#[ApiResource(
collectionOperations: ['post', 'get'],
itemOperations: [
'put' => ['security' => 'is_granted("item", object)'],
'get' => ['security' => 'is_granted("item", object)'],
],
normalizationContext: ['groups' => ['read']]
)]
#[Entity(repositoryClass: AccountRepository::class)]
#[Table(name: '`point_account`')]
class Account
{
#[Id]
#[Column(type: 'integer')]
#[GeneratedValue]
#[Groups('read')]
private ?int $id = null;
#[Column]
#[NotBlank]
#[Groups('read')]
private string $name;
#[ManyToOne(targetEntity: Profile::class, inversedBy: 'accounts')]
#[JoinColumn(onDelete: 'SET NULL')]
#[NotNull]
#[Groups('read')]
#[ApiProperty(readableLink: false, writableLink: false)]
private ?Profile $profile = null;
#[Column(type: 'datetime_immutable')]
#[Groups('read')]
private DateTimeImmutable $createdAt;
/**
* @var Collection<int, Wallet>
*/
#[OneToMany(mappedBy: 'account', targetEntity: Wallet::class)]
private Collection $wallets;
/**
* @var Collection<int, Transaction>
*/
#[OneToMany(mappedBy: 'account', targetEntity: Transaction::class)]
private Collection $transactions;
public function __construct()
{
$this->createdAt = new DateTimeImmutable();
$this->wallets = new ArrayCollection();
$this->transactions = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): string
{
return $this->name;
}
public function setName(string $name): void
{
$this->name = $name;
}
public function getProfile(): ?Profile
{
return $this->profile;
}
public function setProfile(?Profile $profile): void
{
$this->profile = $profile;
}
public function getCreatedAt(): DateTimeImmutable
{
return $this->createdAt;
}
/**
* @return Collection<int, Wallet>
*/
public function getWallets(): Collection
{
return $this->wallets;
}
/**
* @return Collection<int, Transaction>
*/
public function getTransactions(): Collection
{
return $this->transactions;
}
/**
* @return Collection<int, Wallet>
*/
public function getRemainingWallets(): Collection
{
return $this->wallets->filter(static fn (Wallet $wallet) => !$wallet->isExpired() && $wallet->getBalance() > 0);
}
#[Groups('read')]
public function getBalance(): int
{
return intval(
array_sum(
$this->getRemainingWallets()->map(static fn (Wallet $wallet) => $wallet->getBalance())->toArray()
)
);
}
}