<?php
namespace App\V4\Model\Prospect;
use ApiPlatform\Core\Annotation\ApiFilter;
use ApiPlatform\Core\Annotation\ApiProperty;
use ApiPlatform\Core\Annotation\ApiResource;
use App\Model\CustomerFile\CustomerFile;
use App\Model\IriNormalizableInterface;
use App\Model\NormalizeAsIRITrait;
use App\Model\ProspectSubscription\ProspectSubscription;
use App\Model\SpecificFieldsAwareInterface;
use App\Model\Traits\BlamableTrait;
use App\Model\Traits\ImportableObjectTrait;
use App\Model\Traits\TimestampableTrait;
use App\V4\Entity\ActionableEntityInterface;
use App\V4\Model\Address\Address;
use App\V4\Model\Company\Company;
use App\V4\Model\Contact\Contact;
use App\V4\Model\Origin\Origin;
use App\V4\Model\Params\Params;
use App\V4\Model\Potential\Potential;
use App\V4\Model\ProspectSpecificField\ProspectSpecificField;
use App\V4\Model\ProspectType\ProspectType;
use App\V4\Model\Quote\Quote;
use App\V4\Model\SpecificField\SpecificField;
use App\V4\Model\Task\Task;
use App\V4\Model\TVA\TVA;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Serializer\Annotation\MaxDepth;
use Symfony\Component\Validator\Constraints as Assert;
//Ici le formulaire d'édition est en POST, car il nécessite du form-data qui ne fonctionne pas avec PATCH ou PUT
/**
* @ApiResource(
* attributes={
* "api_allow_update": true
* },
* collectionOperations={
* "get": {
* "normalization_context": {
* "groups": {"prospect:list"}
* },
* "security": "is_granted(constant('App\\V4\\Voters\\ProspectVoter::PROSPECT_SHOW_LIST'), 'App\V4\Voters\ProspectVoter')"
* },
* "post_individual": {
* "method": "POST",
* "deserialize": false,
* "write": false,
* "controller": "App\V4\Controller\Prospect\ProspectDataPersisterAction",
* "path": "/V4/prospects/individual",
* "input_formats": {
* "multipart": {"multipart/form-data"}
* },
* "normalization_context": {
* "groups": {"prospect:read"}
* },
* "denormalization_context": {
* "groups": {}
* }
* },
* "post_company": {
* "method": "POST",
* "deserialize": false,
* "write": false,
* "controller": "App\V4\Controller\Prospect\ProspectDataPersisterAction",
* "path": "/V4/prospects/business",
* "input_formats": {
* "multipart": {"multipart/form-data"}
* },
* "normalization_context": {
* "groups": {"prospect:read"}
* },
* "denormalization_context": {
* "groups": {}
* }
* },
* "get_search": {
* "method": "GET",
* "path": "/V4/prospects/search/form",
* "controller": App\V4\Controller\Prospect\GetProspectSearchFormAction::class,
* },
* "post_search": {
* "method": "POST",
* "deserialize": false,
* "path": "/V4/prospects/search/form",
* "normalization_context": {
* "groups": {"prospect:list"}
* },
* "controller": App\V4\Controller\Prospect\PostProspectSearchFormAction::class,
* },
* "get_contacts": {
* "method": "GET",
* "path": "/V4/prospects/{id}/contacts",
* "normalization_context": {
* "groups": {"contact:list"}
* },
* "controller": App\V4\Controller\Contact\GetContactsByProspectAction::class
* },
* "get_tasks": {
* "method": "GET",
* "path": "/V4/prospects/{id}/tasks",
* "normalization_context": {
* "groups": {"task:list"}
* },
* "controller": App\V4\Controller\Task\GetTasksByProspectAction::class
* },
* "get_resume_tasks": {
* "method": "GET",
* "path": "/V4/prospects/{id}/tasks_resume",
* "controller": App\V4\Controller\Task\GetResumeTasksByProspectAction::class
* },
* "get_quotes": {
* "method": "GET",
* "path": "/V4/prospects/{id}/quotes",
* "normalization_context": {
* "groups": {"quote:list"}
* },
* "controller": App\V4\Controller\Quote\GetQuotesByProspectAction::class
* },
* "get_names": {
* "method": "GET",
* "path": "/V4/prospects/get_names",
* "controller": App\V4\Controller\Prospect\GetProspectsNamesAction::class
* },
* "get_customer_code": {
* "method": "GET",
* "path": "/V4/prospects/customer-code/{customerCode}",
* "controller": App\V4\Action\Prospect\GetProspectByCustomerCodeAction::class
* },
* "post_export_request": {
* "method": "POST",
* "path": "/v4/export/prospect",
* "controller": App\V4\Action\Export\EntityExportRequestAction::class,
* "swagger_context": {
* "summary": "Demande de création d'export de prospects",
* "description": "Demande de création d'export de prospects où 'ids' sont les ids des prospects et 'fields' les champs souhaités",
* "parameters": {
* {
* "in": "body",
* "name": "body",
* "schema": {
* "type": "object",
* "properties": {
* "ids": {
* "type": "array",
* "items": {"type": "string"}
* },
* "fields": {
* "type": "array",
* "items": {"type": "string"}
* }
* }
* }
* }
* },
* "responses": {
* "201": {
* "description": "Création de l'export avec succès",
* "schema": {
* "type": "object",
* "properties": {
* "message": {"type": "string", "example": "export_request_created"},
* }
* }
* },
* "400": {
* "description": "Utilisateur non trouvé ou champs 'fields' ou 'ids' manquant dans le body request",
* "schema": {
* "type": "object",
* "properties": {
* "message": {"type": "string", "example": "user_not_found or missing_fields_or_ids"},
* }
* }
* },
* "422": {
* "description": "Les champs 'fields' ou 'ids' du body request sont vides ou l'entité demandée est invalide",
* "schema": {
* "type": "object",
* "properties": {
* "message": {"type": "string", "example": "empty_fields_or_ids or entity_not_valid"},
* }
* }
* },
* },
* }
* },
* "post_export_download": {
* "method": "POST",
* "path": "/v4/export/download/prospect/{id}",
* "controller": App\V4\Action\Export\EntityExportDownloadAction::class,
* "swagger_context": {
* "summary": "Demande de téléchargement d'un export prospects",
* "description": "Demande de téléchargement d'un export prospects ou 'id' est le nom du fichier d'export",
* "requestBody": {},
* "parameters": {
* {
* "in": "path",
* "name": "id",
* "type": "string",
* "required": "true"
* }
* },
* "responses": {
* "200": {
* "description": "Téléchargement de l'export réalisé avec succès"
* },
* "401": {
* "description": "Utilisateur non trouvé ou non connecté",
* "schema": {
* "type": "object",
* "properties": {
* "message": {"type": "string", "example": "need_authenticated"},
* }
* }
* },
* "404": {
* "description": "Fichier introuvable",
* "schema": {
* "type": "object",
* "properties": {
* "message": {"type": "string", "example": "export_not_found"},
* }
* }
* },
* },
* }
* }
* },
* itemOperations={
* "get_form": {
* "method": "GET",
* "path": "/V4/prospects/{id}/form",
* "controller": App\V4\Controller\Prospect\GetProspectFormAction::class
* },
* "put_prospect": {
* "method": "POST",
* "deserialize": false,
* "write": false,
* "controller": "App\V4\Controller\Prospect\ProspectDataPersisterAction",
* "path": "/V4/prospects/{id}",
* "input_formats": {
* "multipart": {"multipart/form-data"}
* },
* "normalization_context": {
* "groups": {"prospect:read"}
* },
* "denormalization_context": {
* "groups": {}
* }
* },
* "delete_prospect": {
* "method": "DELETE",
* "deserialize": false,
* "write": false,
* "controller": "App\V4\Controller\Prospect\ProspectDataPersisterAction",
* "path": "/V4/prospects/{id}"
* }
* }
* )
*
* @ApiFilter(App\Filters\PagingFilter::class)
*/
class Prospect implements IriNormalizableInterface, SpecificFieldsAwareInterface, ActionableEntityInterface
{
public const SPECIFIC_FIELD_CLASS_NAME = ProspectSpecificField::class;
const GROUP_TYPE_INDIVIDUAL = 'individual';
const GROUP_TYPE_BUSINESS = 'business';
const ID_BEGIN_IS_UNKNOWN = 'unknown_';
use TimestampableTrait;
use BlamableTrait;
use ImportableObjectTrait;
use NormalizeAsIRITrait;
/**
* @ApiProperty(identifier=true)
*
* @var string
*
* @Groups({
* "prospect:list", "prospect:read",
* "contact:list", "contact:read", "contact:write", "contact:update",
* "task:list", "task:read", "task:write", "task:update",
* "quote:list", "quote:read", "quote:write", "quote:update"
* })
*/
private $id;
/**
* @var Potential|null
*
* @Groups({"prospect:list", "prospect:read", "prospect:write", "prospect:update"})
*/
private $potential;
/**
* @var string|null
*
* @Groups({"prospect:list", "prospect:read", "prospect:write", "prospect:update"})
*/
private $externalId;
/**
* @var string|null
*/
private $customerId;
/**
* @var string|null
*
* @Groups({"prospect:list", "prospect:read", "prospect:write", "prospect:update"})
*/
private $customerCode;
/**
* @var ProspectType|null
*
* @Groups({
* "prospect:list", "prospect:read", "prospect:write", "prospect:update",
* "quote:list", "quote:read"
* })
*/
private $prospectType;
/**
* @var TVA|null
*
* @Groups({"prospect:list", "prospect:read", "prospect:write", "prospect:update"})
*/
private $tva;
/**
* @var Origin|null
*
* @Groups({"prospect:list", "prospect:read", "prospect:write", "prospect:update"})
*/
private $origin;
/**
* @var string|null
*
* @Groups({"prospect:list", "prospect:read", "prospect:write", "prospect:update"})
*/
private $description;
/**
* @var string|null
*
* @Groups({"prospect:list", "prospect:read", "prospect:write", "prospect:update"})
*/
private $groupName;
/**
* @var string|null
*
* @Groups({"prospect:list", "prospect:read", "prospect:write", "prospect:update"})
*/
private $memo;
/**
* @var Contact|null
*
* @Assert\Type(type="App\V4\Model\Contact\Contact")
* @Assert\NotNull(
* message="Ce champs ne peut pas être vide"
* )
*
* @Groups({"prospect:list", "prospect:read", "prospect:write", "prospect:update"})
*/
private $contact;
/**
* @var Contact[]|Collection
*
* @Groups({"prospect:list", "prospect:read", "prospect:write", "prospect:update"})
*/
private $contacts;
/**
* @var Company|null
*
* @Groups({"prospect:list", "prospect:read", "prospect:write", "prospect:update"})
*/
private $company;
/**
* @todo refacto doit devenir une entity UserInfo
*
* @var string|null
*
* @Groups({"prospect:list", "prospect:read", "prospect:write", "prospect:update"})
*/
private $managedBy;
/**
* @var Task[]|Collection
*
* @Groups({"prospect:list", "prospect:read"})
*/
private $tasks;
/**
* @var Quote[]|Collection
*
* @Groups({"prospect:list", "prospect:read"})
*/
private $quotes;
/**
* @var ProspectSpecificField[]|Collection
*
* @MaxDepth(2)
*
* @Groups({"prospect:list", "prospect:read", "prospect:write", "prospect:update"})
*/
private $specificFields;
/**
* @var CustomerFile[]|Collection
*
* @Groups({"prospect:read", "prospect:write", "prospect:update"})
*/
private $customerFiles;
/**
* @todo refacto ce devrait etre section tout court
*
* @var string|null
*
* @Groups({"prospect:read", "prospect:write", "prospect:update"})
* @MaxDepth(1)
*/
private $sectionName;
/**
* Champ destiné au formulaire de recherche.
*
* @var string|null
*
* @Groups({
* "prospect:list", "prospect:read", "prospect:write", "prospect:update",
* "quote:list", "quote:read"
* })
*/
private $fullName;
/**
* @var Collection|ProspectSubscription[]
*
* @Groups({"prospect:read"})
*/
private $prospectSubscriptions;
/**
* @var string
*/
private $managedByRealName;
public function __construct()
{
$this->contacts = new ArrayCollection();
$this->tasks = new ArrayCollection();
$this->quotes = new ArrayCollection();
$this->specificFields = new ArrayCollection();
$this->prospectSubscriptions = new ArrayCollection();
}
/**
* @return bool
*/
public function isUnknown(): bool
{
return str_starts_with($this->id, self::ID_BEGIN_IS_UNKNOWN);
}
/**
* @return bool|null
*/
public function isCLient(): ?bool
{
return $this->getProspectType() instanceof Params ? $this->getProspectType()->getIsClient() : false;
}
/**
* @return ?string
*
* @Groups({"prospect:list", "prospect:read"})
*/
public function getFullname(): ?string
{
if (null !== $this->fullName) {
return $this->fullName;
}
if ($this->company instanceof Company) {
return $this->company->getName();
}
if ($this->contact instanceof Contact) {
return $this->contact->getName();
}
return null;
}
/**
* @return Address|null
*
* @Groups({"prospect:list", "prospect:read"})
*/
public function getMainAddress(): ?Address
{
return $this->contact ? $this->contact->getMainAddress() : null;
}
/**
* @return Address|null
*
* @Groups({"prospect:list", "prospect:read"})
*/
public function getDeliveryAddress(): ?Address
{
return $this->contact ? $this->contact->getDeliveryAddress() : null;
}
/**
* @param string|null $fullname
*
* @return Prospect
*
* @Groups({"prospect:list", "prospect:read"})
*/
public function setFullname(?string $fullname): Prospect
{
$this->fullName = $fullname;
return $this;
}
/**
* @return string
*
* @Groups({
* "prospect:list"
* })
*/
public function getType(): string
{
return $this->company ? self::GROUP_TYPE_BUSINESS : self::GROUP_TYPE_INDIVIDUAL;
}
/**
* @return bool
*/
public function isBusiness(): bool
{
return self::GROUP_TYPE_BUSINESS === $this->getType();
}
/**
* @return string|null
*/
public function getId(): ?string
{
return $this->id;
}
/**
* @param string|null $id
*
* @return $this
*/
public function setId(?string $id): self
{
$this->id = $id;
return $this;
}
/**
* @return Params|null
*/
public function getPotential(): ?Params
{
return $this->potential;
}
/**
* @param Params|null $potential
*
* @return $this
*/
public function setPotential(?Params $potential): self
{
$this->potential = $potential;
return $this;
}
/**
* @return string|null
*/
public function getExternalId(): ?string
{
return $this->externalId;
}
/**
* @param string|null $externalId
*
* @return $this
*/
public function setExternalId(?string $externalId): self
{
$this->externalId = $externalId;
return $this;
}
/**
* @return string|null
*/
public function getCustomerId(): ?string
{
return $this->customerId;
}
/**
* @param string|null $customerId
*
* @return $this
*/
public function setCustomerId(?string $customerId): self
{
$this->customerId = $customerId;
return $this;
}
/**
* @return Contact|null
*/
public function getContact(): ?Contact
{
return $this->contact;
}
/**
* @param Contact|null $contact
*
* @return $this
*/
public function setContact($contact): self
{
$this->contact = $contact;
return $this;
}
/**
* @return Contact[]|Collection
*/
public function getContacts(): Collection
{
return $this->contacts;
}
/**
* @param Contact $contact
*
* @return $this
*/
public function addContact(Contact $contact): self
{
if (!$this->contacts->contains($contact)) {
$this->contacts->add($contact);
if ($this->contact) {
$this->contact->setProspect($this);
}
}
return $this;
}
/**
* @param Contact $contact
*
* @return $this
*/
public function removeContact(Contact $contact): self
{
if ($this->contacts->contains($contact)) {
$this->contacts->removeElement($contact);
if ($contact->getProspect() === $this) {
$contact->setProspect(null);
}
}
return $this;
}
/**
* @return Company|null
*
* @Groups({"list", "read", "list_contact"})
*/
public function getCompany(): ?Company
{
return $this->company;
}
/**
* @param Company|null $company
*
* @return $this
*/
public function setCompany(?Company $company): self
{
$this->company = $company;
return $this;
}
/**
* @return Task[]|Collection
*/
public function getTasks()
{
return $this->tasks;
}
/**
* @param Task $task
*
* @return $this
*/
public function addTask(Task $task): self
{
if (!$this->tasks->contains($task)) {
$this->tasks->add($task);
$task->setProspect($this);
}
return $this;
}
/**
* @param Task $task
*
* @return $this
*/
public function removeTask(Task $task): self
{
if ($this->tasks->contains($task)) {
$this->tasks->removeElement($task);
if ($task->getProspect() === $this) {
$task->setProspect(null);
}
}
return $this;
}
/**
* @return Quote[]|Collection
*/
public function getQuotes(): ?Collection
{
return $this->quotes;
}
/**
* {@inheritdoc}
*/
public function getSpecificFields(): Collection
{
return $this->specificFields;
}
/**
* {@inheritdoc}
*/
public function getSpecificFieldByFieldId(string $id): ?SpecificField
{
foreach ($this->specificFields as $specificField) {
if ($specificField->getFieldId() === $id) {
return $specificField;
}
}
return null;
}
/**
* @see ImportableObjectTrait::class
*
* @param ProspectSpecificField $specificField
*
* @return $this
*/
public function addProspectSpecificField(ProspectSpecificField $specificField): self
{
return $this->addSpecificField($specificField);
}
/**
* {@inheritdoc}
*/
public function addSpecificField($specificField): SpecificFieldsAwareInterface
{
$this->specificFields[] = $specificField;
return $this;
}
/**
* {@inheritdoc}
*/
public function setSpecificFields(Collection $specificFields): self
{
$this->specificFields = $specificFields;
return $this;
}
/**
* @return string|null
*/
public function getManagedBy(): ?string
{
return $this->managedBy;
}
/**
* @todo refacto doit devenir une entity UserInfo
*
* @param string|null $managedBy
*
* @return Prospect
*/
public function setManagedBy(?string $managedBy): Prospect
{
$this->managedBy = $managedBy;
return $this;
}
/**
* @return string|null
*/
public function getCustomerCode(): ?string
{
return $this->customerCode;
}
/**
* @param string|null $customerCode
*
* @return Prospect
*/
public function setCustomerCode(?string $customerCode): Prospect
{
$this->customerCode = $customerCode;
return $this;
}
/**
* @return Params|null
*/
public function getProspectType(): ?Params
{
return $this->prospectType;
}
/**
* @param Params|null $prospectType
*
* @return Prospect
*/
public function setProspectType(?Params $prospectType): Prospect
{
$this->prospectType = $prospectType;
return $this;
}
/**
* @return Params|null
*/
public function getOrigin(): ?Params
{
return $this->origin;
}
/**
* @param Params|null $origin
*
* @return Prospect
*/
public function setOrigin(?Params $origin): Prospect
{
$this->origin = $origin;
return $this;
}
/**
* @return string|null
*/
public function getDescription(): ?string
{
return $this->description;
}
/**
* @param string|null $description
*
* @return Prospect
*/
public function setDescription(?string $description): Prospect
{
$this->description = $description;
return $this;
}
/**
* @return string|null
*/
public function getMemo(): ?string
{
return $this->memo;
}
/**
* @param string|null $memo
*
* @return Prospect
*/
public function setMemo(?string $memo): Prospect
{
$this->memo = $memo;
return $this;
}
/**
* @return Params|null
*/
public function getTva(): ?Params
{
return $this->tva;
}
/**
* @param Params|null $tva
*
* @return Prospect
*/
public function setTva(?Params $tva): Prospect
{
$this->tva = $tva;
return $this;
}
/**
* @return string|null
*/
public function getGroupName(): ?string
{
return $this->groupName;
}
/**
* @param string|null $groupName
*
* @return Prospect
*/
public function setGroupName(?string $groupName): Prospect
{
$this->groupName = $groupName;
return $this;
}
/**
* @return CustomerFile[]
*/
public function getCustomerFiles()
{
return $this->customerFiles;
}
/**
* @param CustomerFile $customerFile
*
* @return Prospect
*/
public function addCustomerFile(CustomerFile $customerFile): self
{
$this->customerFiles[] = $customerFile;
return $this;
}
/**
* @param CustomerFile $customerFile
*
* @return Prospect
*/
public function removeCustomerFile(CustomerFile $customerFile): self
{
$index = array_search($customerFile, $this->customerFiles, true);
if (false !== $index) {
unset($this->customerFiles[$index]);
}
return $this;
}
/**
* @param CustomerFile[] $customerFiles
*
* @return Prospect
*/
public function setCustomerFiles(array $customerFiles): self
{
$this->customerFiles = $customerFiles;
return $this;
}
/**
* Set the deliveryAddress.
*
* @return Prospect
*/
public function setDeliveryAddressFromContact(): Prospect
{
if (!$this->getContact() instanceof Contact) {
return $this;
}
foreach ($this->getContact()->getAddresses() as $address) {
if (Address::TYPE_DELIVERY_ADDRESS === $address->getTypeAddress()) {
$this->getContact()->setDeliveryAddress($address);
}
}
return $this;
}
/**
* @return string|null
*/
public function getSectionName(): ?string
{
return $this->sectionName;
}
/**
* @param string|null $sectionName
*
* @return Prospect
*/
public function setSectionName(?string $sectionName): Prospect
{
$this->sectionName = $sectionName;
return $this;
}
/**
* @return ProspectSubscription[]|Collection
*/
public function getProspectSubscriptions()
{
return $this->prospectSubscriptions;
}
/**
* @param ProspectSubscription[]|Collection $prospectSubscriptions
*
* @return self
*/
public function setProspectSubscriptions(array $prospectSubscriptions): self
{
$this->prospectSubscriptions = $prospectSubscriptions;
return $this;
}
/**
* @param ProspectSubscription $prospectSubscription
*
* @return self
*/
public function addProspectSubscription(ProspectSubscription $prospectSubscription): self
{
if (!$this->prospectSubscriptions->contains($prospectSubscription)) {
$this->prospectSubscriptions[] = $prospectSubscription;
}
return $this;
}
/**
* @param ProspectSubscription $prospectSubscription
*
* @return self
*/
public function removeProspectSubscription(ProspectSubscription $prospectSubscription): self
{
if ($this->prospectSubscriptions->contains($prospectSubscription)) {
$this->prospectSubscriptions->removeElement($prospectSubscription);
}
return $this;
}
/**
* @return string
*/
public function getManagedByRealName()
{
return $this->managedByRealName;
}
/**
* @param string $managedByRealName
*
* @return $this
*/
public function setManagedByRealName(string $managedByRealName): self
{
$this->managedByRealName = $managedByRealName;
return $this;
}
}