<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiFilter;
use App\Entity\Reference\ReferenceContactType;
use App\Repository\ContactRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\OrderFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Serializer\Annotation\SerializedName;
use Symfony\Component\Validator\Constraints as Assert;
use App\Filter\ContactFilter;
use App\Filter\RecommenderFilter;
/**
* @ApiResource(
* security= "is_granted('ROLE_AGENT') or is_granted('ROLE_MANAGER')",
* normalizationContext={"groups"={"contact:read"}, "swagger_definition_name"="Read"},
* denormalizationContext={"groups"={"contact:write"}, "swagger_definition_name"="Write","skip_null_values" = true},
* itemOperations={
* "get"={"security"="is_granted('ROLE_AGENT') or is_granted('ROLE_MANAGER')"},
* "put" = {
* "denormalization_context"={"groups"={"contact:put"}},
* "access_control"="is_granted('ROLE_AGENT') or is_granted('ROLE_MANAGER')",
* },
*
* },
* collectionOperations={
* "get"={"security"="is_granted('ROLE_AGENT') or is_granted('ROLE_MANAGER')"},
* "post"={"security"="is_granted('ROLE_AGENT') or is_granted('ROLE_MANAGER')"}
*
* },
* attributes={
* "pagination_items_per_page"=10,
* "formats"={"jsonld", "json", "html", "jsonhal", "csv"={"text/csv"} },
* "order"={"id":"DESC"}
* }
* )
* @ApiFilter(OrderFilter::class, properties={"id","firstName","lastName","contactTypeReference.name","createdAt"} ,
* arguments= {"orderParameterName" : "order"})
* @ApiFilter(SearchFilter::class, properties={
* "contactTypeReference.id": "exact",
* "contactTypeReference.code": "exact",
* "createdAt[before]": "exact",
* })
* @ApiFilter(RecommenderFilter::class, properties={"recommender"})
* @ApiFilter(ContactFilter::class, properties={"collaborator.id" : "exact"})
* @ORM\Entity(repositoryClass=ContactRepository::class)
* @UniqueEntity(
* fields={"cin" },
* entityClass=Contact::class,
* message="AbstractPeople with cin {{ value }} is already used."
* )
* @UniqueEntity(
* fields={"email"},
* entityClass=Contact::class,
* message="AbstractPeople with email {{ value }} is already used."
* )
* @UniqueEntity(
* fields={"mainPhone"},
* entityClass=Contact::class,
* message="AbstractPeople with main phone {{ value }} is already used."
* )
* @ORM\HasLifecycleCallbacks()
*/
class Contact extends AbstractPeople implements Loggable
{
public const CONTACT_TYPE_BUYER = 'buyer';
public const CONTACT_TYPE_SELLER = 'seller';
public const ALL_CONTACT_TYPE = [self::CONTACT_TYPE_SELLER, self::CONTACT_TYPE_BUYER];
/**
* @ORM\ManyToOne(targetEntity=Agent::class, inversedBy="contacts")
* @ORM\JoinColumn(nullable=false)
* @Groups({
* "contact:read","property:read",
* "siege:write","siege:put"
* })
*/
private ?Agent $collaborator;
/**
* @ORM\ManyToOne(targetEntity=ReferenceContactType::class, inversedBy="contacts")
* @ORM\JoinColumn(nullable=false)
* @Assert\NotBlank
* @Groups({
* "contact:read","contact:write","contact:put",
* "property:read",
* "transaction:read",
* "mandate:read",
* "business-indication:item:read",
* "property-visit:read",
* })
*/
private ?ReferenceContactType $contactTypeReference;
/**
* @ORM\OneToMany(targetEntity=Property::class, mappedBy="contact")
*/
private $properties;
/**
* @ORM\OneToMany(targetEntity=Transaction::class, mappedBy="contact")
*/
private $transactions;
/**
* @ORM\OneToMany(targetEntity=PropertyVisitVoucher::class, mappedBy="contact")
* @Groups({
* "contact:write","contact:put",
* "mandate:read",
* })
*/
private $propertyVisitVouchers;
/**
* @ORM\ManyToOne(targetEntity=Agent::class)
* @Groups({
* "contact:read","contact:write","siege:put","contact:put",
* "property:read"
* })
*/
private ?Agent $recommender;
/**
* @ORM\Column(type="boolean", nullable=true, options={"default"=false})
* @Groups({
* "contact:read","siege:write","siege:put",
* "property:read",
* "business-indication:item:read",
* "business-indication:collection:read"
* })
*/
private ?bool $isBusinessIndication = false;
/**
* @ORM\Column(type="boolean", nullable=true)
* @Groups({
* "contact:read","contact:write","contact:put",
* "mandate:read",
* })
*/
private ?bool $isPreoccupation = false;
/**
* @ORM\OneToOne(targetEntity=ProxyContact::class, cascade={"persist", "remove"})
* @Assert\Valid
* @Groups({
* "contact:read","contact:write","contact:put",
* "mandate:read"
* })
*/
private ?ProxyContact $proxyContact;
public function __construct()
{
$this->properties = new ArrayCollection();
$this->transactions = new ArrayCollection();
$this->propertyVisitVouchers = new ArrayCollection();
}
/**
* @SerializedName("countPropertyVisit")
* @Groups({
* "contact:read",
* })
*/
public function getCountTotalPropertyVisit(): int
{
return $this->propertyVisitVouchers->filter(
fn (PropertyVisitVoucher $visit) => $visit->getCreatedBy() === $this->getCollaborator()->getId()
)->count();
}
/**
* @SerializedName("countBusinessIndication")
* @Groups({
* "contact:read"
* })
*/
public function getCountTotalBusinessIndication(): int
{
return count(
$this->transactions->filter(
fn (AbstractTransaction $transaction) => $transaction instanceof BusinessIndication
)
);
}
public function getCollaborator(): ?Agent
{
return $this->collaborator;
}
public function setCollaborator(?Agent $collaborator): self
{
$this->collaborator = $collaborator;
return $this;
}
public function getContactTypeReference(): ?ReferenceContactType
{
return $this->contactTypeReference;
}
public function setContactTypeReference(?ReferenceContactType $contactTypeReference): self
{
$this->contactTypeReference = $contactTypeReference;
return $this;
}
/**
* @return Collection|Property[]
*/
public function getProperties(): Collection
{
return $this->properties;
}
public function addProperty(Property $property): self
{
if (!$this->properties->contains($property)) {
$this->properties[] = $property;
$property->setContact($this);
}
return $this;
}
public function removeProperty(Property $property): self
{
// set the owning side to null (unless already changed)
if ($this->properties->removeElement($property) && $property->getContact() === $this) {
$property->setContact(null);
}
return $this;
}
/**
* @return Collection<int, Transaction>
*/
public function getTransactions(): Collection
{
return $this->transactions;
}
public function addTransaction(Transaction $transaction): self
{
if (!$this->transactions->contains($transaction)) {
$this->transactions[] = $transaction;
$transaction->setContact($this);
}
return $this;
}
public function removeTransaction(Transaction $transaction): self
{
if ($this->transactions->removeElement($transaction)) {
// set the owning side to null (unless already changed)
if ($transaction->getContact() === $this) {
$transaction->setContact(null);
}
}
return $this;
}
/**
* @return Collection<int, PropertyVisitVoucher>
*/
public function getPropertyVisitVouchers(): Collection
{
return $this->propertyVisitVouchers;
}
public function addPropertyVisitVoucher(PropertyVisitVoucher $propertyVisitVoucher): self
{
if (!$this->propertyVisitVouchers->contains($propertyVisitVoucher)) {
$this->propertyVisitVouchers[] = $propertyVisitVoucher;
$propertyVisitVoucher->setContact($this);
}
return $this;
}
public function removePropertyVisitVoucher(PropertyVisitVoucher $propertyVisitVoucher): self
{
// set the owning side to null (unless already changed)
if (
$this->propertyVisitVouchers->removeElement($propertyVisitVoucher)
&& $propertyVisitVoucher->getContact() === $this
) {
$propertyVisitVoucher->setContact(null);
}
return $this;
}
public function getRecommender(): ?Agent
{
return $this->recommender;
}
public function setRecommender(?Agent $recommender): self
{
$this->recommender = $recommender;
return $this;
}
/**
* @return bool|null
*/
public function getIsBusinessIndication(): ?bool
{
return $this->isBusinessIndication;
}
/**
* @param bool $isBusinessIndication
*
* @return $this
*/
public function setIsBusinessIndication(bool $isBusinessIndication): self
{
$this->isBusinessIndication = $isBusinessIndication;
return $this;
}
public function getIsPreoccupation(): ?bool
{
return $this->isPreoccupation;
}
public function setIsPreoccupation(?bool $isPreoccupation): self
{
$this->isPreoccupation = $isPreoccupation;
return $this;
}
public function getProxyContact(): ?ProxyContact
{
return $this->proxyContact;
}
public function setProxyContact(?ProxyContact $proxyContact): self
{
$this->proxyContact = $proxyContact;
return $this;
}
/**
* @return array
*/
public function getFields(): array
{
return [
'gender' => 'gender' ,
'address' => 'address' ,
'email' => 'email' ,
'mainPhone' => 'mainPhone' ,
'birthDay' => 'birthDay' ,
'cin' => 'cin' ,
'rc' => 'rc' ,
'commonCompanyIdentifier' => 'commonCompanyIdentifier' ,
'companyName' => 'companyName' ,
'contactTypeReference' => 'contactTypeReference' ,
'recommender' => 'recommender'
];
}
}