<?php
namespace App\Entity\Channel;
use App\Entity\Channel\Certificate\CursusStartCertificate;
use App\Entity\Channel\ProfessionalId\ProfessionalId;
use App\Entity\Common\Address;
use App\Entity\Sync\SyncableInterface;
use App\Enum\Channel\FileOrganizationTagEnum;
use App\Repository\Channel\OrganizationRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Drosalys\Bundle\ApiBundle\Serializer\Attributes\IdGroups;
use Nellapp\Bundle\SDKBundle\Channel\Entity\Organization\OrganizationInterface;
use Nellapp\Bundle\SDKBundle\Channel\Entity\Organization\OrganizationMethodTrait;
use Nellapp\Bundle\SDKBundle\Entity\Common\Address\AddressInterface;
use Nellapp\Bundle\SDKBundle\Sync\EntityKeys;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Serializer\Annotation as Serial;
#[
ORM\Entity(repositoryClass: OrganizationRepository::class),
ORM\Table('channel_organizations')
]
class Organization implements \Stringable, OrganizationInterface, SyncableInterface
{
use OrganizationMethodTrait;
#[ORM\Id, ORM\GeneratedValue, ORM\Column(type: 'integer')]
#[Serial\Groups(['Manager', 'Sync'])]
private ?int $id = null;
#[ORM\ManyToOne(targetEntity: Channel::class, inversedBy: 'organizations')]
#[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
#[IdGroups(['Sync'])]
private ?Channel $channel = null;
#[ORM\Column(type: 'string', length: 63)]
#[Assert\NotBlank(
message: 'channel.organization.name.NotBlank',
)]
#[Assert\Length(
min: 2,
max: 63,
minMessage: 'channel.organization.name.Length.min',
maxMessage: 'channel.organization.name.Length.max',
)]
#[Serial\Groups(['Manager', 'Sync'])]
private ?string $name = null;
#[ORM\Column(type: 'string', length: 128, nullable: true)]
#[Serial\Groups(['Manager'])]
private ?string $legalOfficer = null;
#[ORM\Embedded(class: Address::class)]
#[Assert\Valid]
#[Serial\Groups(['Sync'])]
private ?AddressInterface $address = null;
#[ORM\Column(type: 'string', length: 180, nullable: true)]
#[Assert\Email(message: 'channel.organization.email.Email', mode: 'strict')]
#[Serial\Groups(['Manager'])]
private ?string $contactEmail = null;
#[ORM\Column(type: 'string', length: 20, nullable: true)]
#[Serial\Groups(['Manager'])]
private ?string $phoneNumber = null;
#[ORM\OneToMany(mappedBy: 'organization', targetEntity: FileOrganization::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
private ?Collection $files;
#[ORM\OneToOne(targetEntity: ProfessionalId::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
#[IdGroups(['Sync'])]
private ?ProfessionalId $professionalId = null;
#[ORM\Column(type: 'integer', nullable: false)]
private ?int $organizationOrder = null;
#[ORM\OneToOne(mappedBy: 'organization', targetEntity: CursusStartCertificate::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
private ?CursusStartCertificate $certificate = null;
public function __construct()
{
$this->files = new ArrayCollection();
$this->address = new Address();
}
public static function getSyncKey(): string
{
return EntityKeys::CHANNEL_ORGANIZATION;
}
public function getSyncDisplayLabel(): string
{
return $this->getName() ?? 'Structure';
}
#[Serial\Groups(['Sync'])]
public function getLogoPath(): ?string
{
return $this->getLogoFile()?->getPath();
}
public function getId(): ?int
{
return $this->id;
}
public function getLegalOfficer(): ?string
{
return $this->legalOfficer;
}
public function setLegalOfficer(?string $legalOfficer): Organization
{
$this->legalOfficer = $legalOfficer;
return $this;
}
public function getContactEmail(): ?string
{
return $this->contactEmail;
}
public function setContactEmail(?string $contactEmail): Organization
{
$this->contactEmail = $contactEmail;
return $this;
}
public function getPhoneNumber(): ?string
{
return $this->phoneNumber;
}
public function setPhoneNumber(?string $phoneNumber): Organization
{
$this->phoneNumber = $phoneNumber;
return $this;
}
public function getFiles(): ?Collection
{
return $this->files;
}
public function addFile(FileOrganization $file): Organization
{
if (!$this->files->contains($file)) {
$file->setOrganization($this);
$this->files[] = $file;
}
return $this;
}
public function removeFile(FileOrganization $file): Organization
{
if ($this->files->contains($file)) {
$this->files->removeElement($file);
}
return $this;
}
public function getFileByTag(string $tag): ?FileOrganization
{
foreach ($this->getFiles() as $file) {
if ($file->getTag() === $tag) {
return $file;
}
}
return null;
}
public function setFileByTag(FileOrganization $file): void
{
// Remove existing file with same tag if exists
if ($existingFile = $this->getFileByTag($file->getTag())) {
$this->removeFile($existingFile);
}
$this->addFile($file);
}
public function getLogoFile(): ?FileOrganization
{
return $this->getFileByTag(FileOrganizationTagEnum::LOGO);
}
public function getSignatureFile(): ?FileOrganization
{
return $this->getFileByTag(FileOrganizationTagEnum::SIGNATURE);
}
public function getOrganizationOrder(): ?int
{
return $this->organizationOrder;
}
public function setOrganizationOrder(?int $organizationOrder): Organization
{
$this->organizationOrder = $organizationOrder;
return $this;
}
public function __toString(): string
{
return $this->getName();
}
public function getCertificate(): ?CursusStartCertificate
{
return $this->certificate;
}
public function setCertificate(?CursusStartCertificate $certificate): Organization
{
$this->certificate = $certificate;
return $this;
}
public function getProfessionalId(): ?ProfessionalId
{
return $this->professionalId;
}
public function setProfessionalId(?ProfessionalId $professionalId): static
{
$this->professionalId = $professionalId;
return $this;
}
}