<?php
namespace App\Entity\Channel;
use App\Entity\ChannelUserData\AdminChannelUserData;
use App\Entity\ChannelUserData\Cursus\Internship;
use App\Entity\Common\Address;
use App\Entity\Common\Contact;
use App\Entity\Sync\SyncableInterface;
use App\Enum\FrenchProfessionalLegalFormEnum;
use App\Repository\Channel\CompanyRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Drosalys\Bundle\ApiBundle\Serializer\Attributes\IdGroups;
use DrosalysWeb\ObjectExtensions\Blame\Model\BlameInterface;
use DrosalysWeb\ObjectExtensions\Blame\Model\BlameTrait;
use DrosalysWeb\ObjectExtensions\Timestamp\Model\TimestampInterface;
use DrosalysWeb\ObjectExtensions\Timestamp\Model\TimestampTrait;
use Nellapp\Bundle\SDKBundle\Channel\Entity\Company\CompanyInterface;
use Nellapp\Bundle\SDKBundle\Channel\Entity\Company\CompanyMethodTrait;
use Nellapp\Bundle\SDKBundle\Entity\Common\Address\AddressInterface;
use Nellapp\Bundle\SDKBundle\Enum\Company\IndustryEnum;
use Nellapp\Bundle\SDKBundle\Sync\EntityKeys;
use Symfony\Component\Serializer\Annotation as Serial;
use Symfony\Component\Validator\Constraints as Assert;
#[
ORM\Entity(repositoryClass: CompanyRepository::class),
ORM\Table(name: 'channel_company'),
]
class Company implements TimestampInterface, BlameInterface, CompanyInterface, SyncableInterface
{
use TimestampTrait;
use BlameTrait;
use CompanyMethodTrait;
#[
ORM\Id,
ORM\GeneratedValue(strategy: 'NONE'),
ORM\Column(type: 'string', length: 36)
]
#[Serial\Groups(['Manager', 'Sync'])]
private ?string $id = null;
#[ORM\Column(type: 'string')]
#[
Assert\NotBlank,
Assert\Length(
min: 2,
max: 255,
),
]
#[Serial\Groups(['Manager', 'Sync'])]
private ?string $name = null;
#[ORM\Column(type: 'string', length: 14, nullable: true)]
#[
Assert\Length(
min: 9,
max: 14,
minMessage: 'channel.professional_id.french.siret.Length.min',
maxMessage: 'channel.professional_id.french.siret.Length.max',
),
Assert\Luhn(
message: 'channel.professional_id.french.siret.luhn'
),
]
#[Serial\Groups(['Sync'])]
private ?string $siret = null;
#[ORM\Column(type: 'string', length: 20, nullable: true)]
#[Assert\Choice(callback: [FrenchProfessionalLegalFormEnum::class, 'getChoices'])]
#[Serial\Groups(['Sync'])]
private ?string $legalForm = null;
#[ORM\Column(type: 'string', nullable: true)]
#[
Assert\Choice(callback: [IndustryEnum::class, 'getChoices']),
]
#[Serial\Groups(['Sync'])]
private ?string $industry = null;
#[ORM\Column(type: 'string', nullable: true)]
#[
Assert\NotBlank(message: 'user.entity.email.NotBlank'),
Assert\Email(message: 'user.entity.email.Email', mode: 'strict'),
Assert\Length(
min: 6,
max: 64,
minMessage: 'user.entity.email.Length.min',
maxMessage: 'user.entity.email.Length.max',
)
]
#[Serial\Groups(['Sync'])]
private ?string $email = null;
#[ORM\Column(type: 'string', nullable: true)]
#[
Assert\Length(exactly: 10, exactMessage: 'adviser.entity.phone.Length.message')
]
#[Serial\Groups(['Sync'])]
private ?string $phoneNumber = null;
#[ORM\Column(type: 'string', nullable: true)]
#[
Assert\Length(max: 255)
]
private ?string $website = null;
#[ORM\Column(type: 'integer', nullable: true)]
#[Assert\GreaterThanOrEqual(value: 0)]
#[Serial\Groups(['Sync'])]
private ?int $countEmployees = null;
#[ORM\Embedded(class: Address::class)]
#[Assert\Valid()]
#[Serial\Groups(['Sync'])]
private ?AddressInterface $address = null;
#[ORM\ManyToOne(targetEntity: Channel::class)]
#[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
#[IdGroups(['Sync'])]
private ?Channel $channel = null;
#[ORM\OneToMany(mappedBy: 'company', targetEntity: Internship::class)]
private Collection $internships;
#[ORM\OneToMany(mappedBy: 'company', targetEntity: CompanyChannelUserData::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
private Collection $companyChannelUserDatas;
#[ORM\OneToMany(mappedBy: 'company', targetEntity: CompanyContact::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
#[IdGroups(['Sync'])]
private Collection $companyContacts;
public function __construct()
{
$this->initCompanyMethod();
$this->internships = new ArrayCollection();
$this->companyChannelUserDatas = new ArrayCollection();
}
public static function getSyncKey(): string
{
return EntityKeys::CHANNEL_COMPANY;
}
public function getSyncDisplayLabel(): string
{
return $this->__toString();
}
public function __toString(): string
{
return $this->getNameWithCity() ?? '';
}
public function getNameWithAddress(): ?string
{
return $this->getName() . ', ' . $this->getAddress();
}
#[Serial\Groups(['Manager'])]
public function getNameWithCity(): ?string
{
return $this->getName() . ' (' . $this->getAddress()?->getPostCode() . ' - ' . $this->getAddress()?->getCity() . ')';
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(?string $email): static
{
$this->email = $email;
return $this;
}
public function getAddress(): ?AddressInterface
{
return $this->address ?? $this->address = new Address();
}
/**
* @return Collection<int, Internship>
*/
public function getInternships(): Collection
{
return $this->internships;
}
public function addInternship(Internship $internship): static
{
if (!$this->getInternships()->contains($internship)) {
$this->internships->add($internship);
}
return $this;
}
public function removeInternship(Internship $internship): static
{
if ($this->getInternships()->contains($internship)) {
$this->internships->removeElement($internship);
}
return $this;
}
public function getCompanyChannelUserDataFor(AdminChannelUserData $adminChannelUserData): ?CompanyChannelUserData
{
foreach ($this->getCompanyChannelUserDatas() as $companyChannelUserData) {
if ($companyChannelUserData->getChannelUserData() === $adminChannelUserData) {
return $companyChannelUserData;
}
}
return null;
}
/**
* @return Collection<int, CompanyChannelUserData>
*/
public function getCompanyChannelUserDatas(): Collection
{
return $this->companyChannelUserDatas;
}
public function addChannelUserData(AdminChannelUserData $adminChannelUserData, ?string $job = null): self
{
if (!$companyChannelUserData = $this->getCompanyChannelUserDataFor($adminChannelUserData)) {
$companyChannelUserData = new CompanyChannelUserData();
$companyChannelUserData->setCompany($this);
$companyChannelUserData->setChannelUserData($adminChannelUserData);
$this->companyChannelUserDatas->add($companyChannelUserData);
$adminChannelUserData->addCompany($this);
}
$companyChannelUserData->setJob($job);
return $this;
}
public function removeChannelUserData(AdminChannelUserData $adminChannelUserData): self
{
if (!$companyChannelUserData = $this->getCompanyChannelUserDataFor($adminChannelUserData)) {
return $this;
}
if ($this->companyChannelUserDatas->contains($companyChannelUserData)) {
$this->companyChannelUserDatas->removeElement($companyChannelUserData);
$adminChannelUserData->removeCompany($this);
}
return $this;
}
public function getCompanyChannelContactFor(ChannelContact $channelContact): ?CompanyContact
{
foreach ($this->getCompanyContacts() as $companyContact) {
if ($companyContact->getChannelContact() === $channelContact) {
return $companyContact;
}
}
return null;
}
public function getCompanyChannelContactForContact(Contact $contact): ?CompanyContact
{
foreach ($this->getCompanyContacts() as $companyContact) {
if ($companyContact->getChannelContact()?->getContact() === $contact) {
return $companyContact;
}
}
return null;
}
public function addChannelContact(ChannelContact $channelContact, ?string $behavior = null): self
{
if (!$companyContact = $this->getCompanyChannelContactFor($channelContact)) {
$companyContact = new CompanyContact();
$companyContact->setCompany($this);
$companyContact->setChannelContact($channelContact);
$this->addCompanyContact($companyContact);
}
if ($behavior) {
$companyContact->addBehavior($behavior);
}
return $this;
}
public function getContacts(): Collection
{
return $this->getCompanyContacts()
->map(function (CompanyContact $companyContact) {
return $companyContact->getChannelContact()->getContact();
});
}
public function getLegalForm(): ?string
{
return $this->legalForm;
}
public function setLegalForm(?string $legalForm): Company
{
$this->legalForm = $legalForm;
return $this;
}
public function getIndustry(): ?string
{
return $this->industry;
}
public function setIndustry(?string $industry): Company
{
$this->industry = $industry;
return $this;
}
public function getCountEmployees(): ?int
{
return $this->countEmployees;
}
public function setCountEmployees(?int $countEmployees): Company
{
$this->countEmployees = $countEmployees;
return $this;
}
public function getWebsite(): ?string
{
return $this->website;
}
public function setWebsite(?string $website): Company
{
$this->website = $website;
return $this;
}
}