, * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ namespace Chill\ThirdPartyBundle\Entity; use Chill\MainBundle\Doctrine\Model\TrackCreationInterface; use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface; use Chill\MainBundle\Entity\Civility; use Chill\MainBundle\Entity\User; use Doctrine\ORM\Mapping as ORM; use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\ArrayCollection; use Chill\MainBundle\Entity\Center; use Symfony\Component\Validator\Constraints as Assert; use Chill\MainBundle\Entity\Address; use Symfony\Component\Serializer\Annotation\DiscriminatorMap; use Symfony\Component\Serializer\Annotation\Groups; use Chill\MainBundle\Validation\Constraint\PhonenumberConstraint; /** * ThirdParty is a party recorded in the database. * * A party may be attached to multiple centers. Being attach to a center allow * all users with the right 'CHILL_3PARTY_3PARTY_SEE', 'CHILL_3PARTY_3 to see, select and edit parties for this * center. * * @ORM\Entity * @ORM\Table(name="chill_3party.third_party") * @DiscriminatorMap(typeProperty="type", mapping={ * "thirdparty"=ThirdParty::class * }) */ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface { /** * @var int * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ private ?int $id = null; const KIND_CONTACT = 'contact'; const KIND_COMPANY = 'company'; const KIND_CHILD = 'child'; /** * @ORM\Column(name="kind", type="string", length="20", options={"default":""}) */ private ?string $kind = ""; /** * @var string * @ORM\Column(name="name", type="string", length=255) * @Assert\Length(min="2") * @Groups({"read", "write"}) */ private ?string $name = ""; /** * [fr] Raison sociale * @var string * @ORM\Column(name="name_company", type="string", length=255, nullable=true) * @Assert\Length(min="3") * @Groups({"read", "write"}) */ private ?string $nameCompany = ""; /** * Canonicalized form composed of name, company name and acronym. * * This field is read-only, and is generated on database side. * * @ORM\Column(name="canonicalized", type="text", options={"default":""}) */ private ?string $canonicalized = ""; /** * [fr] Sigle * @var string * @ORM\Column(name="acronym", type="string", length=64, nullable=true) * @Assert\Length(min="2") * @Groups({"read", "write"}) */ private ?string $acronym = ""; /** * @var ThirdPartyCategory * @ORM\ManyToMany(targetEntity="Chill\ThirdPartyBundle\Entity\ThirdPartyCategory") * @ORM\JoinTable(name="chill_3party.thirdparty_category", * joinColumns={@ORM\JoinColumn(name="thirdparty_id", referencedColumnName="id")}, * inverseJoinColumns={@ORM\JoinColumn(name="category_id", referencedColumnName="id")}) */ private Collection $categories; /** * @var array|null * @ORM\Column(name="types", type="json", nullable=true) */ private $types; /** * Contact Persons: One Institutional ThirdParty has Many Contact Persons * @ORM\OneToMany(targetEntity="Chill\ThirdPartyBundle\Entity\ThirdParty", mappedBy="parent", * cascade={"persist"}, orphanRemoval=true) * @var ThirdParty[]|Collection * @Assert\Valid(traverse=true) */ private Collection $children; /** * Institutional ThirdParty: Many Contact Persons have One Institutional ThirdParty * @ORM\ManyToOne(targetEntity="Chill\ThirdPartyBundle\Entity\ThirdParty", inversedBy="children") * @ORM\JoinColumn(name="parent_id", referencedColumnName="id") * @Groups({"read"}) */ private ?ThirdParty $parent; /** * @var Civility * @ORM\ManyToOne(targetEntity=Civility::class) * ORM\JoinColumn(name="civility", referencedColumnName="id", nullable=true) */ private ?Civility $civility; /** * [fr] Qualité * @var ThirdPartyProfession * @ORM\ManyToOne(targetEntity="Chill\ThirdPartyBundle\Entity\ThirdPartyProfession") * ORM\JoinColumn(name="profession", referencedColumnName="id", nullable=true) */ private ?ThirdPartyProfession $profession; /** * @var string|null * @ORM\Column(name="telephone", type="string", length=64, nullable=true) * @Assert\Regex("/^([\+{1}])([0-9\s*]{4,20})$/", * message="Invalid phone number: it should begin with the international prefix starting with ""+"", hold only digits and be smaller than 20 characters. Ex: +33123456789" * ) * @PhonenumberConstraint(type="any") * @Groups({"read", "write"}) */ private ?string $telephone = null; /** * @var string|null * @ORM\Column(name="email", type="string", length=255, nullable=true) * @Assert\Email(checkMX=false) * @Groups({"read", "write"}) */ private ?string $email = null; /** * @var bool * @ORM\Column(name="contact_data_anonymous", type="boolean", options={"default":false}) */ private bool $contactDataAnonymous = false; /** * @var Address|null * @ORM\ManyToOne(targetEntity="\Chill\MainBundle\Entity\Address", * cascade={"persist", "remove"}) * @ORM\JoinColumn(nullable=true, onDelete="SET NULL") * @Groups({"read", "write"}) */ private ?Address $address = null; /** * Soft-delete flag * @ORM\Column(name="active", type="boolean", options={"defaut": true}) */ private bool $active = true; /** * @ORM\Column(name="comment", type="text", nullable=true) */ private ?string $comment = null; /** * @ORM\ManyToMany(targetEntity="\Chill\MainBundle\Entity\Center") * @ORM\JoinTable(name="chill_3party.party_center") */ private Collection $centers; /** * @ORM\Column(name="created_at", type="datetime_immutable", nullable=false) */ private \DateTimeImmutable $createdAt; /** * @ORM\Column(name="updated_at", type="datetime_immutable", nullable=true) */ private ?\DateTimeImmutable $updatedAt; /** * @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\User") * @ORM\JoinColumn(name="updated_by", referencedColumnName="id") */ private ?User $updatedBy; /** * @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\User") * @ORM\JoinColumn(name="created_by", referencedColumnName="id") */ private ?User $createdBy; /** * ThirdParty constructor. */ public function __construct() { $this->centers = new ArrayCollection(); $this->categories = new ArrayCollection(); $this->children = new ArrayCollection(); } /** * Get id. * * @return int */ public function getId() { return $this->id; } public function getKind(): ?string { return $this->kind; } public function setKind(?string $kind): ThirdParty { $this->kind = $kind; return $this; } /** * Set name. * * @param string $name * @return ThirdParty */ public function setName($name) { $this->name = $name; return $this; } /** * Get name. * * @return string */ public function getName() { return $this->name; } /** * Set telephone. * * @param string|null $telephone * @return ThirdParty */ public function setTelephone($telephone = null) { $this->telephone = $telephone; return $this; } /** * Get telephone. * * @return string|null */ public function getTelephone() { return $this->telephone; } /** * Set email. * * @param string|null $email * @return ThirdParty */ public function setEmail($email = null) { $this->email = $email; return $this; } /** * Get email. * * @return string|null */ public function getEmail() { return $this->email; } public function isContactDataAnonymous(): bool { return $this->contactDataAnonymous; } public function setContactDataAnonymous(bool $contactDataAnonymous): ThirdParty { $this->contactDataAnonymous = $contactDataAnonymous; return $this; } /** * Set comment. * * @param string|null $comment * @return ThirdParty */ public function setComment($comment = null) { $this->comment = $comment; return $this; } /** * Get comment. * * @return string|null */ public function getComment() { return $this->comment; } /** * Set type. * * @param array|null $type * @return ThirdParty */ public function setTypes(array $type = null) { // remove all keys from the input data $this->type = \array_values($type); foreach ($this->children as $child) { $child->setTypes($type); } return $this; } /** * Get type. * * @return array|null */ public function getTypes() { return $this->types; } /** * @return bool */ public function getActive(): bool { return $this->active; } /** * @return Collection */ public function getCenters(): Collection { return $this->centers; } /** * @param bool $active * @return $this */ public function setActive(bool $active) { $this->active = $active; foreach ($this->children as $child) { $child->setActive($active); } return $this; } /** * @param Center $center */ public function addCenter(Center $center) { if (FALSE === $this->centers->contains($center)) { $this->centers->add($center); } } /** * @param Center $center */ public function removeCenter(Center $center) { if ($this->centers->contains($center)) { $this->centers->removeElement($center); } } /** * @param Collection $centers * @return $this */ public function setCenters(Collection $centers) { foreach ($centers as $center) { $this->addCenter($center); } foreach ($this->centers as $center) { if (FALSE === $centers->contains($center)) { $this->removeCenter($center); } } return $this; } /** * @return Address|null */ public function getAddress(): ?Address { return $this->address; } /** * @param Address $address * @return $this */ public function setAddress(Address $address) { $this->address = $address; return $this; } /** * @return string */ public function __toString() { return $this->getName(); } /** * @return string|null */ public function getNameCompany(): ?string { return $this->nameCompany; } /** * @param string $nameCompany * @return ThirdParty */ public function setNameCompany(?string $nameCompany): ThirdParty { $this->nameCompany = (string) $nameCompany; return $this; } /** * @return string */ public function getAcronym(): ?string { return $this->acronym; } /** * @param string $acronym * @return $this */ public function setAcronym(string $acronym): ThirdParty { $this->acronym = $acronym; return $this; } /** * @return Collection */ public function getCategories(): Collection { return $this->categories; } /** * @param ThirdPartyCategory $category * @return $this */ public function addCategory(ThirdPartyCategory $category): self { if (!$this->categories->contains($category)) { $this->categories[] = $category; } foreach ($this->children as $child) { $child->addCategory($child); } return $this; } /** * @param ThirdPartyCategory $category * @return $this */ public function removeCategory(ThirdPartyCategory $category): self { $this->categories->removeElement($category); foreach ($this->children as $child) { $child->removeCategory($child); } return $this; } /** * Mechanism to differentiate children and parents */ public function isLeaf(): bool { return $this->children->count() !== 0; } /** * @Groups({"read"}) */ public function isChild():bool { return $this->parent !== null; } public function isParent():bool { return !$this->isChild(); } /** * @return Collection */ public function getChildren(): Collection { return $this->children; } /** * Get the children where active = true * * @return Collection */ public function getActiveChildren(): Collection { return $this->children->filter(fn (ThirdParty $tp) => $tp->getActive()); } /** * Add a child and set the child as active * * Method used in conjonction with getActiveChildren in form. * * @internal use the method addChild * @param ThirdParty $child * @return $this */ public function addActiveChild(ThirdParty $child): self { $child->setActive(true); return $this->addChild($child); } /** * mark the child as unactive, but keep the child existing in the * database. To effectively remove the child, use removeChild instead. * * @param ThirdParty $child * @return $this */ public function removeActiveChild(ThirdParty $child): self { $child->setActive(false); return $this; } /** * @param ThirdParty $child * @return $this */ public function addChild(ThirdParty $child): self { $this->children[] = $child; $child->setParent($this)->setKind(ThirdParty::KIND_CHILD);; return $this; } /** * Remove the child from the database. * * If you want to keep the child into the database * but desactivate it, use removeActiveChildren instead. * * @param ThirdParty $child * @return $this */ public function removeChild(ThirdParty $child): self { $this->children->removeElement($child); return $this; } /** * @return ThirdParty|null */ public function getParent(): ?ThirdParty { return $this->parent; } /** * @param ThirdParty|null $parent * @return $this */ public function setParent(?ThirdParty $parent): ThirdParty { $this->parent = $parent; return $this; } /** * @return Civility|null */ public function getCivility(): ?Civility { return $this->civility; } /** * @param Civility $civility * @return $this */ public function setCivility(Civility $civility): ThirdParty { $this->civility = $civility; return $this; } /** * @return ThirdPartyProfession */ public function getProfession(): ?ThirdPartyProfession { return $this->profession; } /** * @param ThirdPartyProfession $profession * @return $this */ public function setProfession(ThirdPartyProfession $profession): ThirdParty { $this->profession = $profession; return $this; } /** * @return \DateTimeImmutable */ public function getCreatedAt(): \DateTimeImmutable { return $this->createdAt; } /** * @param \DateTimeImmutable $createdAt * @return $this */ public function setCreatedAt(\DateTimeInterface $createdAt): ThirdParty { $this->createdAt = $createdAt; return $this; } /** * @return \DateTime|null */ public function getUpdatedAt(): ?\DateTimeImmutable { return $this->updatedAt; } /** * @param \DateTimeImmutable $updatedAt * @return $this */ public function setUpdatedAt(\DateTimeInterface $updatedAt): ThirdParty { $this->updatedAt = $updatedAt; return $this; } /** * @return User|null */ public function getUpdatedBy(): ?User { return $this->updatedBy; } /** * @param User $updatedBy * @return $this */ public function setUpdatedBy(User $updatedBy): ThirdParty { $this->updatedBy = $updatedBy; return $this; } public function setCreatedBy(User $user): TrackCreationInterface { $this->createdBy = $user; return $this; } }