<?php
declare(strict_types=1);
namespace App\Point\Doctrine\Entity;
use ApiPlatform\Core\Annotation\ApiFilter;
use ApiPlatform\Core\Annotation\ApiProperty;
use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
use App\Order\Doctrine\Entity\Detail;
use App\Order\Doctrine\Entity\Order;
use App\Point\Doctrine\Repository\TransactionRepository;
use DateTimeImmutable;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\DiscriminatorColumn;
use Doctrine\ORM\Mapping\DiscriminatorMap;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\InheritanceType;
use Doctrine\ORM\Mapping\JoinColumn;
use Doctrine\ORM\Mapping\ManyToOne;
use Doctrine\ORM\Mapping\OneToOne;
use Doctrine\ORM\Mapping\PrePersist;
use Doctrine\ORM\Mapping\Table;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints\GreaterThan;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\NotNull;
#[ApiResource(
collectionOperations: ['get'],
itemOperations: ['get' => ['security' => 'is_granted("item", object)']],
normalizationContext: ['groups' => ['read']]
)]
#[ApiFilter(SearchFilter::class, properties: ['account' => 'exact'])]
#[Entity(repositoryClass: TransactionRepository::class)]
#[Table(name: '`point_transaction`')]
#[InheritanceType('SINGLE_TABLE')]
#[DiscriminatorColumn(name: 'discr', type: 'string')]
#[DiscriminatorMap([
'debit' => Debit::class,
'credit' => Credit::class,
'purchase' => Purchase::class,
])]
abstract class Transaction
{
#[Id]
#[Column(type: 'integer')]
#[GeneratedValue]
#[Groups('read')]
protected ?int $id = null;
#[Column(type: 'datetime_immutable')]
#[Groups(['read', 'write'])]
protected DateTimeImmutable $createdAt;
#[ManyToOne(targetEntity: Account::class, inversedBy: 'transactions')]
#[JoinColumn(nullable: false, onDelete: 'CASCADE')]
#[NotNull]
#[Groups(['read', 'write'])]
#[ApiProperty(readableLink: false)]
protected Account $account;
#[ManyToOne(targetEntity: Wallet::class, inversedBy: 'transactions')]
#[JoinColumn(onDelete: 'SET NULL')]
#[Groups('read')]
#[ApiProperty(readableLink: false)]
protected ?Wallet $wallet = null;
#[Column(type: 'integer')]
#[NotBlank]
#[GreaterThan(0)]
#[Groups(['read', 'write'])]
protected int $points = 0;
#[ManyToOne(targetEntity: Operation::class)]
#[JoinColumn(nullable: false)]
#[Groups('read')]
#[ApiProperty(readableLink: false)]
protected Operation $operation;
#[OneToOne(targetEntity: Order::class)]
private ?Order $order = null;
#[OneToOne(targetEntity: Detail::class)]
private ?Detail $detail = null;
public function __construct()
{
$this->createdAt = new DateTimeImmutable();
}
public function getId(): ?int
{
return $this->id;
}
#[Groups('read')]
public function getReference(): string
{
return sprintf('%08d', $this->id);
}
public function getCreatedAt(): DateTimeImmutable
{
return $this->createdAt;
}
public function setCreatedAt(DateTimeImmutable $createdAt): void
{
$this->createdAt = $createdAt;
}
public function getAccount(): Account
{
return $this->account;
}
public function setAccount(Account $account): void
{
$this->account = $account;
}
public function getWallet(): ?Wallet
{
return $this->wallet;
}
public function setWallet(?Wallet $wallet): void
{
$this->wallet = $wallet;
}
public function getPoints(): int
{
return $this->points;
}
public function setPoints(int $points): void
{
$this->points = $points;
}
public function getOperation(): Operation
{
return $this->operation;
}
public function setOperation(Operation $operation): void
{
$this->operation = $operation;
}
#[Groups(['read'])]
#[ApiProperty(readableLink: false)]
public function getTransfer(): ?Transfer
{
return null;
}
public function getOrder(): ?Order
{
return $this->order;
}
public function setOrder(?Order $order): void
{
$this->order = $order;
}
public function getDetail(): ?Detail
{
return $this->detail;
}
public function setDetail(?Detail $detail): void
{
$this->detail = $detail;
}
}