<?php
namespace App\Entity\Channel;
use App\Entity\Common\Contact;
use App\Entity\Crm\Opportunity\Opportunity;
use App\Entity\Crm\Target\TargetableInterface;
use App\Enum\Serialization\ContactSerializationGroups;
use App\Enum\Serialization\ReverseSyncSerializationGroups;
use App\Enum\TargetTypeEnum;
use App\Repository\Channel\ChannelContactRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Drosalys\Bundle\ApiBundle\Serializer\Attributes\IdGroups;
use Nellapp\Bundle\SDKBundle\Archivable\Entity\ArchivableTrait;
use Nellapp\Bundle\SDKBundle\Channel\Entity\ChannelContact\ChannelContactInterface;
use Nellapp\Bundle\SDKBundle\Channel\Entity\ChannelContact\ChannelContactMethodTrait;
use Nellapp\Bundle\SDKBundle\ReverseSync\Entity\ReverseSyncableInterface;
use Doctrine\ORM\Mapping as ORM;
use Nellapp\Bundle\SDKBundle\Planning\Entity\PlanningResourceInterface;
use Nellapp\Bundle\SDKBundle\Planning\Entity\PlanningResourceTrait;
use Nellapp\Bundle\SDKBundle\ReverseSync\EntityKeys;
use Nellapp\Bundle\SDKBundle\Serializer\SerialRelation\Attribute\SerialRelation;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Serializer\Annotation as Serial;
use Symfony\Component\Validator\Constraints as Assert;
#[ORM\Entity(repositoryClass: ChannelContactRepository::class),
ORM\Table(name: 'channel_contacts'),
ORM\UniqueConstraint(fields: ['channel', 'contact']),
UniqueEntity(fields: ['channel', 'contact'], message: 'channel_contact.UniqueEntity', errorPath: 'contact')]
class ChannelContact implements
ChannelContactInterface,
ReverseSyncableInterface,
TargetableInterface,
\Stringable,
PlanningResourceInterface
{
use ArchivableTrait;
use ChannelContactMethodTrait;
use PlanningResourceTrait;
#[ORM\Id,
ORM\GeneratedValue(strategy: 'NONE'),
ORM\Column(type: 'string', length: 36)]
#[Serial\Groups([
ReverseSyncSerializationGroups::REVERSE_SYNC,
ContactSerializationGroups::COLLECTION,
ContactSerializationGroups::DETAIL,
])]
private ?string $id = null;
#[ORM\ManyToOne(targetEntity: Channel::class)]
#[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
#[IdGroups([ReverseSyncSerializationGroups::REVERSE_SYNC])]
private ?Channel $channel = null;
#[ORM\ManyToOne(targetEntity: Contact::class, cascade: ['persist'])]
#[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
#[IdGroups([ReverseSyncSerializationGroups::REVERSE_SYNC])]
#[Serial\Groups([
ContactSerializationGroups::COLLECTION,
ContactSerializationGroups::DETAIL,
ContactSerializationGroups::CREATE,
])]
#[
Assert\NotNull,
Assert\Valid(),
]
private ?Contact $contact = null;
#[ORM\OneToMany(mappedBy: 'channelContact', targetEntity: CompanyContact::class)]
private Collection $companyContacts;
#[ORM\OneToMany(mappedBy: 'targetContact', targetEntity: Opportunity::class)]
private Collection $opportunities;
public function __construct()
{
$this->initChannelContactMethod();
$this->companyContacts = new ArrayCollection();
$this->opportunities = new ArrayCollection();
}
public static function getReverseSyncKey(): string
{
return EntityKeys::CHANNEL_CONTACT;
}
public function getDisplayName(): string
{
return $this->getContact() ?? '';
}
#[Serial\Groups([
ContactSerializationGroups::COLLECTION,
ContactSerializationGroups::DETAIL,
])]
public function getFullAddress(): ?string
{
return $this->getContact()?->getFullAddress() ?? '';
}
#[SerialRelation(targetEntity: Company::class, multiple: true, groups: [
ContactSerializationGroups::COLLECTION,
ContactSerializationGroups::DETAIL,
])]
public function getCompanies(): Collection
{
return $this->getCompanyContacts()->map(fn(CompanyContact $companyContact) => $companyContact->getCompany());
}
public function getOpportunityTargetType(): string
{
return TargetTypeEnum::CONTACT;
}
/**
* @return Collection<int, Opportunity>
*/
public function getOpportunities(): Collection
{
return $this->opportunities;
}
public function addOpportunity(Opportunity $opportunity): static
{
if (!$this->opportunities->contains($opportunity)) {
$this->opportunities->add($opportunity);
$opportunity->setTargetContact($this);
}
return $this;
}
public function removeOpportunity(Opportunity $opportunity): static
{
if ($this->opportunities->removeElement($opportunity)) {
if ($opportunity->getTargetContact() === $this) {
$opportunity->setTargetContact(null);
}
}
return $this;
}
public function __toString(): string
{
return $this->getDisplayName();
}
}