<?php
declare(strict_types=1);
namespace App\Domain\Entity;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Post;
use ApiPlatform\Metadata\Put;
use App\Application\ApiResources\State\Provider\ListPromoCodeProvider;
use App\Application\ApiResources\State\Provider\PartnerPromoCodeStatsProvider;
use App\Application\ApiResources\State\Provider\PromoCodeExportProvider;
use App\Application\Controller\Api\PromoCode\ImportAction;
use App\Application\Controller\Api\PromoCode\UseAction;
use App\Application\Dto\PromoCode\PromoCodeOutput;
use App\Domain\Entity\Behavior\Identifiable;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Gedmo\SoftDeleteable\Traits\SoftDeleteable;
use Gedmo\Timestampable\Traits\Timestampable;
/**
* Class PromoCode
*
* @package App\Domain\Entity
*/
#[ApiResource(
operations: [
new Delete(security: "is_granted('ROLE_ADMIN')"),
new GetCollection(
uriTemplate: '/promo_codes',
security: "is_granted('ROLE_ADMIN')",
filters: [
'promo_code.query_filter',
'promo_code.search_filter',
'soft_delete_filter',
],
output: PromoCodeOutput::class,
provider: ListPromoCodeProvider::class
),
new GetCollection(
uriTemplate: '/promo_codes/by_partner',
security: "is_granted('ROLE_ADMIN')",
filters: ['promo_code.query_filter'],
output: PromoCodeOutput::class,
provider: PartnerPromoCodeStatsProvider::class,
),
new GetCollection(
uriTemplate: '/promo_codes/by_partner/export',
formats: ['csv' => ['text/csv']],
paginationEnabled: false,
normalizationContext: ['groups' => ['promo_code_export'], 'csv_delimiter' => ';'],
security: "is_granted('ROLE_ADMIN')",
filters: ['promo_code.query_filter'],
output: PromoCodeOutput::class,
name: 'promo_code_export_by_partner',
provider: PartnerPromoCodeStatsProvider::class,
),
new GetCollection(uriTemplate: '/promo_codes/use', controller: UseAction::class, name: "use_promo_code"),
new GetCollection(
uriTemplate: '/promo_codes/export',
formats: ['csv' => ['text/csv']],
paginationEnabled: false,
normalizationContext: ['groups' => ['promo_code_export'], 'csv_delimiter' => ';'],
security: "is_granted('ROLE_ADMIN')",
filters: ['promo_code.query_filter', 'promo_code.exists_filter', 'soft_delete_filter'],
name: 'promo_code_export',
provider: PromoCodeExportProvider::class
),
new Get(security: "is_granted('ROLE_ADMIN')"),
new Post(
uriTemplate: '/promo_codes/import',
controller: ImportAction::class,
security: "is_granted('ROLE_ADMIN')",
deserialize: false,
serialize: false,
),
new Post(security: "is_granted('ROLE_ADMIN')"),
new Put(security: "is_granted('ROLE_ADMIN')"),
],
normalizationContext: ['groups' => ['promo_code_read']],
denormalizationContext: ['groups' => ['promo_code_write']],
)]
class PromoCode
{
use Identifiable;
use Timestampable;
use SoftDeleteable;
private Collection $personPromoCodes;
/**
* @param string $code
* @param int $maxUsage
* @param string|null $duration
* @param int|null $percent
* @param Partner|null $partner
*/
public function __construct(
public string $code,
public int $maxUsage,
public ?string $duration = null,
public ?int $percent = null,
public ?Partner $partner = null,
public ?bool $singleUsePerUser = false,
public ?\DateTime $startDate = null,
public ?\DateTime $endDate = null,
) {
$this->personPromoCodes = new ArrayCollection();
}
public function getUsageCount(): int
{
return $this->personPromoCodes->count();
}
public function getUsageLeft(): int
{
return $this->maxUsage - $this->personPromoCodes->count();
}
/**
* @return Collection
*/
public function getPersonPromoCodes(): Collection
{
return $this->personPromoCodes;
}
/**
* @param Collection $personPromoCodes
*/
public function setPersonPromoCodes(Collection $personPromoCodes): void
{
$this->personPromoCodes = $personPromoCodes;
}
public function addPersonPromoCode(PersonPromoCode $personPromoCodes): void
{
if ($this->personPromoCodes->contains($personPromoCodes)) {
return;
}
$this->personPromoCodes->add($personPromoCodes);
}
public function removePersonPromoCode(PersonPromoCode $personPromoCodes): void
{
if (!$this->personPromoCodes->contains($personPromoCodes)) {
return;
}
$this->personPromoCodes->removeElement($personPromoCodes);
}
}