ThirdParty::class])] class ThirdParty implements TrackCreationInterface, TrackUpdateInterface, \Stringable { final public const KIND_CHILD = 'child'; final public const KIND_COMPANY = 'company'; final public const KIND_CONTACT = 'contact'; /** * [fr] Sigle. */ #[Assert\Length(min: 2)] #[Groups(['read', 'write', 'docgen:read', 'docgen:read:3party:parent'])] #[ORM\Column(name: 'acronym', type: \Doctrine\DBAL\Types\Types::STRING, length: 64, nullable: true)] private ?string $acronym = ''; /** * Soft-delete flag. */ #[ORM\Column(name: 'active', type: \Doctrine\DBAL\Types\Types::BOOLEAN, options: ['defaut' => true])] private bool $active = true; #[Groups(['read', 'write', 'docgen:read', 'docgen:read:3party:parent'])] #[ORM\ManyToOne(targetEntity: Address::class, cascade: ['persist', 'remove'])] #[ORM\JoinColumn(nullable: true, onDelete: 'SET NULL')] #[Context(normalizationContext: ['groups' => 'docgen:read'], groups: ['docgen:read:3party:parent'])] private ?Address $address = null; /** * 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: \Doctrine\DBAL\Types\Types::TEXT, options: ['default' => ''])] private ?string $canonicalized = ''; /** * @var Collection */ #[Groups(['docgen:read', 'docgen:read:3party:parent'])] #[ORM\ManyToMany(targetEntity: ThirdPartyCategory::class)] #[ORM\JoinTable(name: 'chill_3party.thirdparty_category', joinColumns: [new ORM\JoinColumn(name: 'thirdparty_id', referencedColumnName: 'id')], inverseJoinColumns: [new ORM\JoinColumn(name: 'category_id', referencedColumnName: 'id')])] #[Context(normalizationContext: ['groups' => 'docgen:read'], groups: ['docgen:read:3party:parent'])] private Collection $categories; /** * @var Collection
*/ #[ORM\ManyToMany(targetEntity: Center::class)] #[ORM\JoinTable(name: 'chill_3party.party_center')] private Collection $centers; /** * Contact Persons: One Institutional ThirdParty has Many Contact Persons. * * @var Collection */ #[Assert\Valid(traverse: true)] #[ORM\OneToMany(targetEntity: ThirdParty::class, mappedBy: 'parent', cascade: ['persist'], orphanRemoval: true)] private Collection $children; #[Context(normalizationContext: ['groups' => 'docgen:read'], groups: ['docgen:read:3party:parent'])] #[Groups(['read', 'write', 'docgen:read', 'docgen:read:3party:parent'])] #[ORM\ManyToOne(targetEntity: Civility::class)] // ORM\JoinColumn(name="civility", referencedColumnName="id", nullable=true) private ?Civility $civility = null; #[Groups(['read', 'write'])] #[ORM\Column(name: 'comment', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)] private ?string $comment = null; #[Groups(['read', 'docgen:read', 'docgen:read:3party:parent'])] #[ORM\Column(name: 'contact_data_anonymous', type: \Doctrine\DBAL\Types\Types::BOOLEAN, options: ['default' => false])] private bool $contactDataAnonymous = false; #[ORM\Column(name: 'created_at', type: \Doctrine\DBAL\Types\Types::DATETIME_IMMUTABLE, nullable: false)] private \DateTimeImmutable $createdAt; #[ORM\ManyToOne(targetEntity: User::class)] #[ORM\JoinColumn(name: 'created_by', referencedColumnName: 'id')] private ?User $createdBy = null; #[Assert\Email] #[Groups(['read', 'write', 'docgen:read', 'docgen:read:3party:parent'])] #[ORM\Column(name: 'email', type: \Doctrine\DBAL\Types\Types::STRING, length: 255, nullable: true)] private ?string $email = null; #[Groups(['read', 'write', 'docgen:read', 'docgen:read:3party:parent'])] #[ORM\Column(name: 'firstname', type: \Doctrine\DBAL\Types\Types::TEXT, options: ['default' => ''])] private ?string $firstname = ''; #[Groups(['read', 'docgen:read', 'docgen:read:3party:parent'])] #[ORM\Column(name: 'id', type: \Doctrine\DBAL\Types\Types::INTEGER)] #[ORM\Id] #[ORM\GeneratedValue(strategy: 'AUTO')] private ?int $id = null; #[Groups(['write', 'docgen:read', 'docgen:read:3party:parent'])] #[ORM\Column(name: 'kind', type: \Doctrine\DBAL\Types\Types::STRING, length: 20, options: ['default' => ''])] private string $kind = ''; #[Assert\Length(min: 2)] #[Assert\NotNull] #[Assert\NotBlank] #[Groups(['read', 'write', 'docgen:read', 'docgen:read:3party:parent'])] #[ORM\Column(name: 'name', type: \Doctrine\DBAL\Types\Types::STRING, length: 255)] private string $name = ''; /** * [fr] Raison sociale. */ #[Assert\Length(min: 3)] #[Groups(['read', 'write', 'docgen:read', 'docgen:read:3party:parent'])] #[ORM\Column(name: 'name_company', type: \Doctrine\DBAL\Types\Types::STRING, length: 255, nullable: true)] private ?string $nameCompany = ''; /** * Institutional ThirdParty: Many Contact Persons have One Institutional ThirdParty. */ #[Groups(['read', 'write', 'docgen:read'])] #[ORM\ManyToOne(targetEntity: ThirdParty::class, inversedBy: 'children')] #[ORM\JoinColumn(name: 'parent_id', referencedColumnName: 'id')] #[Context(normalizationContext: ['groups' => 'docgen:read:3party:parent'], groups: ['docgen:read'])] private ?ThirdParty $parent = null; /** * [fr] Qualité. */ #[Groups(['read', 'write', 'docgen:read', 'docgen:read:3party:parent'])] #[ORM\Column(name: 'profession', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: false)] #[Context(normalizationContext: ['groups' => 'docgen:read'], groups: ['docgen:read:3party:parent'])] private string $profession = ''; #[Groups(['read', 'write', 'docgen:read', 'docgen:read:3party:parent'])] #[ORM\Column(name: 'telephone', type: 'phone_number', nullable: true)] #[PhonenumberConstraint(type: 'any')] private ?PhoneNumber $telephone = null; #[ORM\Column(name: 'types', type: \Doctrine\DBAL\Types\Types::JSON, nullable: true)] private ?array $thirdPartyTypes = []; #[ORM\Column(name: 'updated_at', type: \Doctrine\DBAL\Types\Types::DATETIME_IMMUTABLE, nullable: true)] private ?\DateTimeImmutable $updatedAt = null; #[ORM\ManyToOne(targetEntity: User::class)] #[ORM\JoinColumn(name: 'updated_by', referencedColumnName: 'id')] private ?User $updatedBy = null; /** * ThirdParty constructor. */ public function __construct() { $this->centers = new ArrayCollection(); $this->categories = new ArrayCollection(); $this->children = new ArrayCollection(); } public function __toString(): string { return $this->getName(); } /** * Add a child and set the child as active. * * Method used in conjonction with getActiveChildren in form. * * @internal use the method addChild * * @return $this */ public function addActiveChild(ThirdParty $child): self { $child->setActive(true); return $this->addChild($child); } /** * @return $this */ public function addCategory(ThirdPartyCategory $category): self { if (!$this->categories->contains($category)) { $this->categories[] = $category; } foreach ($this->children as $child) { $child->addCategory($category); } return $this; } public function addCenter(Center $center) { if (false === $this->centers->contains($center)) { $this->centers->add($center); } } /** * @return $this */ public function addChild(ThirdParty $child): self { $this->children[] = $child; $child->setParent($this)->setKind(ThirdParty::KIND_CHILD); return $this; } public function addThirdPartyTypes(?string $type): self { if (null === $type) { return $this; } if (!\in_array($type, $this->thirdPartyTypes ?? [], true)) { $this->thirdPartyTypes[] = $type; } foreach ($this->children as $child) { $child->addThirdPartyTypes($type); } return $this; } public function addTypesAndCategories($typeAndCategory): self { if ($typeAndCategory instanceof ThirdPartyCategory) { $this->addCategory($typeAndCategory); return $this; } if (\is_string($typeAndCategory)) { $this->addThirdPartyTypes($typeAndCategory); return $this; } throw new \UnexpectedValueException(sprintf('typeAndCategory should be a string or a %s', ThirdPartyCategory::class)); } public function getAcronym(): ?string { return $this->acronym; } public function getActive(): bool { return $this->active; } /** * Get the children where active = true. */ public function getActiveChildren(): ReadableCollection { return $this->children->filter(static fn (ThirdParty $tp) => $tp->getActive()); } public function getAddress(): ?Address { if ($this->isChild()) { return $this->getParent()->getAddress(); } return $this->address; } public function getCategories(): Collection { return $this->categories; } public function getCenters(): Collection { return $this->centers; } public function getChildren(): Collection { return $this->children; } public function getCivility(): ?Civility { return $this->civility; } /** * Get comment. */ public function getComment(): ?string { return $this->comment; } public function getCreatedAt(): \DateTimeImmutable { return $this->createdAt; } /** * Get email. */ public function getEmail(): ?string { return $this->email; } public function getFirstname(): string { return $this->firstname; } public function getId(): ?int { return $this->id; } public function getKind(): ?string { return $this->kind; } public function getName(): string { return $this->name; } public function getNameCompany(): ?string { return $this->nameCompany; } public function getParent(): ?ThirdParty { return $this->parent; } public function getProfession(): string { return $this->profession; } /** * Get telephone. */ public function getTelephone(): ?PhoneNumber { return $this->telephone; } /** * Get type. */ public function getThirdPartyTypes(): ?array { return $this->thirdPartyTypes ?? []; } public function getTypesAndCategories(): array { return \array_merge( $this->getCategories()->toArray(), $this->getThirdPartyTypes() ?? [] ); } /** * @return \DateTime|null */ public function getUpdatedAt(): ?\DateTimeImmutable { return $this->updatedAt; } public function getUpdatedBy(): ?User { return $this->updatedBy; } #[Groups(['read', 'docgen:read', 'docgen:read:3party:parent'])] public function isChild(): bool { return null !== $this->parent; } public function isContactDataAnonymous(): bool { return $this->contactDataAnonymous; } /** * Mechanism to differentiate children and parents. */ public function isLeaf(): bool { return 0 !== $this->children->count(); } public function isParent(): bool { return !$this->isChild(); } /** * mark the child as unactive, but keep the child existing in the * database. To effectively remove the child, use removeChild instead. * * @return $this */ public function removeActiveChild(ThirdParty $child): self { $child->setActive(false); return $this; } /** * @return $this */ public function removeCategory(ThirdPartyCategory $category): self { $this->categories->removeElement($category); foreach ($this->children as $child) { $child->removeCategory($category); } return $this; } public function removeCenter(Center $center) { if ($this->centers->contains($center)) { $this->centers->removeElement($center); } } /** * Remove the child from the database. * * If you want to keep the child into the database * but desactivate it, use removeActiveChildren instead. * * @return $this */ public function removeChild(ThirdParty $child): self { $this->children->removeElement($child); return $this; } public function removeThirdPartyTypes(?string $type): self { if (null === $type) { return $this; } if (\in_array($type, $this->thirdPartyTypes ?? [], true)) { $this->thirdPartyTypes = \array_filter($this->thirdPartyTypes, fn ($e) => !\in_array($e, $this->thirdPartyTypes, true)); } foreach ($this->children as $child) { $child->removeThirdPartyTypes($type); } return $this; } public function removeTypesAndCategories($typeAndCategory): self { if ($typeAndCategory instanceof ThirdPartyCategory) { $this->removeCategory($typeAndCategory); return $this; } if (\is_string($typeAndCategory)) { $this->removeThirdPartyTypes($typeAndCategory); return $this; } throw new \UnexpectedValueException(sprintf('typeAndCategory should be a string or a %s', ThirdPartyCategory::class)); } public function setAcronym(?string $acronym = null): ThirdParty { $this->acronym = (string) $acronym; return $this; } /** * @return $this */ public function setActive(bool $active) { $this->active = $active; foreach ($this->children as $child) { $child->setActive($active); } return $this; } /** * @return $this */ public function setAddress(?Address $address = null) { $this->address = $address; return $this; } /** * @return $this */ public function setCenters(Collection $centers) { $this->centers = $centers; return $this; } public function setCivility(?Civility $civility): ThirdParty { $this->civility = $civility; return $this; } /** * Set comment. * * @return ThirdParty */ public function setComment(?string $comment = null) { $this->comment = $comment; return $this; } public function setContactDataAnonymous(bool $contactDataAnonymous): ThirdParty { $this->contactDataAnonymous = $contactDataAnonymous; return $this; } /** * @param \DateTimeImmutable $createdAt * * @return $this */ public function setCreatedAt(\DateTimeInterface $createdAt): ThirdParty { $this->createdAt = $createdAt; return $this; } public function setCreatedBy(User $user): TrackCreationInterface { $this->createdBy = $user; return $this; } /** * Set email. * * @return ThirdParty */ public function setEmail(?string $email = null) { $this->email = trim((string) $email); return $this; } public function setFirstname(?string $firstname): self { $this->firstname = trim((string) $firstname); return $this; } public function setKind(?string $kind): ThirdParty { $this->kind = (string) $kind; return $this; } public function setName(?string $name): self { $this->name = (string) $name; return $this; } public function setNameCompany(?string $nameCompany): ThirdParty { $this->nameCompany = (string) $nameCompany; return $this; } public function setParent(?ThirdParty $parent): ThirdParty { $this->parent = $parent; return $this; } public function setProfession(?string $profession): self { $this->profession = (string) $profession; return $this; } /** * Set telephone. */ public function setTelephone(?PhoneNumber $telephone = null): self { $this->telephone = $telephone; return $this; } /** * Set type. * * @return ThirdParty */ public function setThirdPartyTypes(?array $type = []) { // remove all keys from the input data $this->thirdPartyTypes = \array_values($type); foreach ($this->children as $child) { $child->setThirdPartyTypes($type); } return $this; } public function setTypesAndCategories(array $typesAndCategories): self { $types = \array_filter($typesAndCategories, static fn ($item) => !$item instanceof ThirdPartyCategory); $this->setThirdPartyTypes($types); // handle categories foreach ($typesAndCategories as $t) { $this->addTypesAndCategories($t); } $categories = \array_filter($typesAndCategories, static fn ($item) => $item instanceof ThirdPartyCategory); $categoriesHashes = \array_map(static fn (ThirdPartyCategory $c) => \spl_object_hash($c), $categories); foreach ($categories as $c) { $this->addCategory($c); } foreach ($this->getCategories() as $t) { if (!\in_array(\spl_object_hash($t), $categoriesHashes, true)) { $this->removeCategory($t); } } return $this; } /** * @param \DateTimeImmutable $updatedAt * * @return $this */ public function setUpdatedAt(\DateTimeInterface $updatedAt): ThirdParty { $this->updatedAt = $updatedAt; return $this; } /** * @return $this */ public function setUpdatedBy(User $updatedBy): ThirdParty { $this->updatedBy = $updatedBy; return $this; } }