<?php
namespace Evo\Infrastructure\MappingORM;
use ApiPlatform\Core\Annotation\ApiFilter;
use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Core\Serializer\Filter\PropertyFilter;
use App\Enum\LegalRepresentativeQualityTypeEnum;
use App\Enum\PersonTypeEnum;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Serializer\Annotation\MaxDepth;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ApiResource(
* denormalizationContext={"groups"={"legal_representative"}},
* normalizationContext={"groups"={"legal_representative"}, "enable_max_depth"=true},
* itemOperations={"get", "put", "delete"},
* collectionOperations={"get", "post", "findByUser"={
* "method"="get",
* "route_name"="app_legalrepresentative_byuser"
* }}
* )
* @ORM\Entity(repositoryClass="App\Repository\LegalRepresentativeRepository")
* @ApiFilter(SearchFilter::class, properties={"person": "exact","person.familyName": "partial", "person.givenName": "partial" ,"organizations": "exact"})
* @ApiFilter(PropertyFilter::class)
*/
class LegalRepresentative
{
/**
* @Groups({
* "legal_representative",
* "read_organization",
* "read_person",
* "associate",
* "pappers_activity"
* })
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private ?int $id = null;
/**
* @Assert\Choice(callback={"App\Enum\LegalRepresentativeQualityTypeEnum", "getChoices"})
* @Groups({"legal_representative", "write_organization", "read_organization", "read_search", "associate", "pappers_activity"})
* @ORM\Column(type="string", length=150, nullable=true)
*/
private ?string $quality = null;
/**
* @Groups({"legal_representative", "write_organization", "read_organization", "read_search", "associate"})
* @ORM\Column(type="string", length=255, nullable=true)
* @Assert\Email
*/
private ?string $email = null;
/**
* @Groups({"legal_representative", "write_organization", "read_organization", "read_search", "associate"})
* @ORM\Column(type="string", length=255, nullable=true)
*/
private ?string $phoneNumber = null;
/*
* SAS, SASU : Président obligatoire + Directeurs généraux en option
* SCI SARL EURL : un gérant à minima (pas de président) + possibilité de cogérant
*/
/**
* @Groups({"legal_representative", "write_organization", "read_organization", "associate"})
* @MaxDepth(1)
* @ORM\ManyToMany(targetEntity="Evo\Infrastructure\MappingORM\Organization", mappedBy="legalRepresentatives")
*
* @deprecated Renommer "organization" car un RL n'est désormais lié qu'à une seule société
*/
private ?Collection $organizations;
/**
* @Groups({"legal_representative", "write_organization", "read_organization", "associate"})
* @ORM\Column(type="float", nullable=true)
*
* @deprecated
*/
private ?float $shareCapital = null;
/**
* @Groups({"legal_representative", "write_organization", "read_organization", "associate"})
* @MaxDepth(1)
* @ORM\OneToOne(targetEntity="Evo\Infrastructure\MappingORM\Associate", mappedBy="legalRepresentative", cascade={"persist"})
*/
private ?Associate $associate = null;
/**
* @Groups({"legal_representative", "write_organization", "read_organization", "read_search", "associate"})
* @ORM\ManyToOne(targetEntity="Evo\Infrastructure\MappingORM\LegalRepresentative", inversedBy="children", cascade={"persist"})
*/
private $parent;
/**
* @Groups({"legal_representative", "write_organization", "read_organization", "pappers_activity"})
* @ORM\OneToMany(targetEntity="Evo\Infrastructure\MappingORM\LegalRepresentative", mappedBy="parent")
*/
private ?Collection $children;
/**
* @Groups({"legal_representative", "write_organization", "read_organization", "read_search", "read_export_organization", "associate", "admin_orga_list", "pappers_activity"})
* @ORM\ManyToOne(targetEntity="Evo\Infrastructure\MappingORM\Person", inversedBy="legalRepresentatives", cascade={"persist"})
*/
private ?Person $person = null;
/**
* @Groups({"legal_representative", "write_organization", "read_organization", "associate"})
* @ORM\Column(type="string", length=150, nullable=true)
*/
private ?string $contributionType = null;
/**
* @Groups({"legal_representative", "write_organization", "read_organization", "associate"})
* @ORM\Column(type="float", nullable=true)
*/
private ?float $contributionAmount = null;
private $ratio;
/**
* @Groups({"legal_representative", "write_organization", "read_organization", "associate"})
* @ORM\Column(type="boolean", nullable=true)
*/
private $isAssociate;
/**
* @ORM\OneToMany(targetEntity=ActivityLog::class, mappedBy="legalRepresentative")
*/
private Collection $activityLogs;
public function __construct()
{
$this->organizations = new ArrayCollection();
$this->children = new ArrayCollection();
$this->quality = LegalRepresentativeQualityTypeEnum::MANAGER;
$this->activityLogs = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
/**
* @return Organization[]|Collection
*
* @deprecated Renommer "organization" car un RL n'est désormais lié qu'à une seule société
*/
public function getOrganizations()
{
return $this->organizations;
}
public function addOrganization(Organization $organization): self
{
if (!$this->organizations->contains($organization)) {
$this->organizations[] = $organization;
$organization->addLegalRepresentative($this);
}
return $this;
}
public function removeOrganization(Organization $organization): self
{
if ($this->organizations->contains($organization)) {
$this->organizations->removeElement($organization);
$organization->removeLegalRepresentative($this);
}
return $this;
}
public function getShareCapital(): ?float
{
return $this->shareCapital;
}
public function setShareCapital(?float $shareCapital): self
{
$this->shareCapital = $shareCapital;
return $this;
}
public function getAssociate(): ?Associate
{
return $this->associate;
}
public function setAssociate(?Associate $associate): self
{
$this->associate = $associate;
// set (or unset) the owning side of the relation if necessary
$newLegalRepresentative = null === $associate ? null : $this;
if ($associate && $newLegalRepresentative !== $associate->getLegalRepresentative()) {
$associate->setLegalRepresentative($newLegalRepresentative);
}
return $this;
}
public function addChildren(self $children): self
{
if (!$this->children->contains($children)) {
$this->children[] = $children;
$children->setParent($this);
}
return $this;
}
public function removeChildren(self $children): self
{
if ($this->children->contains($children)) {
$this->children->removeElement($children);
if ($children->getParent() === $this) {
$children->setParent(null);
}
}
return $this;
}
public function getParent(): ?self
{
return $this->parent;
}
public function setParent(?self $parent): self
{
$this->parent = $parent;
return $this;
}
public function getPhysicalRepresentative()
{
if ($this->getChildren()->toArray()) {
/** @var LegalRepresentative $representedBy */
foreach ($this->children as $representedBy) {
if (null !== $representedBy->getPerson()) {
if (PersonTypeEnum::PHYSICAL == $representedBy->getPerson()->getType()) {
return $representedBy;
}
return $representedBy->getPhysicalRepresentative();
}
}
}
return null;
}
/**
* @return Collection|self[]
*/
public function getChildren(): Collection
{
return $this->children;
}
public function getDocuments(): Collection
{
$documentsPerson = [];
$documentsParent = [];
if (null !== $this->getPerson()) {
$documentsPerson = $this->getPerson()->getDocuments()->toArray();
}
if (null !== $this->getParent()) {
$documentsParent = $this->getParent()->getDocuments()->toArray();
}
return new ArrayCollection(array_merge_recursive($documentsPerson, $documentsParent));
}
public function __toString()
{
$isAssociate = $this->getIsAssociate() && LegalRepresentativeQualityTypeEnum::ASSOCIE_SEUL !== $this->getQuality() ? ' - Associé' : ' ';
if (null !== $this->getPerson()) {
if (PersonTypeEnum::PHYSICAL == $this->getPerson()->getType()) {
return $this->getPerson()->getFamilyName().' '.$this->getPerson()->getGivenName().' ( '.$this->getQuality().$isAssociate.' )';
}
return $this->getPerson()->getLegalName().' ('.$this->getPerson()->getGivenName().', '.$this->getQuality().$isAssociate.' )';
}
return $this->getQuality();
}
public function getQuality(): ?string
{
return $this->quality;
}
public function setQuality(?string $quality): self
{
$this->quality = $quality;
return $this;
}
public function getEmail(): ?string
{
return $this->email;
}
public function getEmailFallbackUser(): ?string
{
if (null === $this->email || '' === $this->email) {
$organizations = $this->getOrganizations();
/** @var Organization $organization */
foreach ($organizations as $organization) {
$users = $organization->getUsers();
foreach ($users as $user) {
if ($user->getPhoneNumber() === $this->getPhoneNumber()) {
return $user->getEmail();
}
}
}
}
return $this->email;
}
public function setEmail(?string $email): self
{
$this->email = $email;
return $this;
}
public function getPhoneNumber(): ?string
{
return $this->phoneNumber;
}
public function setPhoneNumber(?string $phoneNumber): self
{
$this->phoneNumber = $phoneNumber;
return $this;
}
public function getPerson(): ?Person
{
return $this->person;
}
public function setPerson(?Person $person): self
{
$this->person = $person;
return $this;
}
public function getContributionType(): ?string
{
return $this->contributionType;
}
public function setContributionType(?string $contributionType): self
{
$this->contributionType = $contributionType;
return $this;
}
public function getContributionAmount(): ?float
{
return $this->contributionAmount;
}
public function setContributionAmount(?float $contributionAmount): self
{
$this->contributionAmount = $contributionAmount;
return $this;
}
public function getRatio(): ?string
{
return $this->ratio;
}
public function setRatio($ratio): self
{
$this->ratio = $ratio;
return $this;
}
public function getIsAssociate(): ?bool
{
return $this->isAssociate;
}
public function setIsAssociate(?bool $isAssociate): self
{
$this->isAssociate = $isAssociate;
return $this;
}
public function getActivityLogs(): Collection
{
return $this->activityLogs;
}
public function addActivityLog(ActivityLog $activityLog): self
{
if (!$this->activityLogs->contains($activityLog)) {
$this->activityLogs[] = $activityLog;
$activityLog->setLegalRepresentative($this);
}
return $this;
}
public function removeActivityLog(ActivityLog $activityLog): self
{
// set the owning side to null (unless already changed)
if ($this->activityLogs->removeElement($activityLog) && $activityLog->getLegalRepresentative() === $this) {
$activityLog->setLegalRepresentative(null);
}
return $this;
}
public static function createFixture(array $data): self
{
$self = new self();
$self->quality = $data['quality'];
$self->email = $data['email'];
$self->phoneNumber = $data['phoneNumber'];
$self->isAssociate = $data['isAssociate'];
$self->person = Person::createFixture($data['person']);
return $self;
}
// get top parent
public function getTopParent(): ?self
{
if (null !== $this->getParent()) {
return $this->getParent()->getTopParent();
}
return $this;
}
public function isAssociateOnly(): bool
{
return LegalRepresentativeQualityTypeEnum::ASSOCIE_SEUL === $this->getQuality();
}
}