<?php
namespace App\V4\Model\Quote;
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\ProspectRefreshNeededTrait;
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\ChildrenAwareInterface;
use App\V4\Model\Prospect\Prospect;
use App\V4\Model\QuoteLine\QuoteLine;
use App\V4\Model\QuoteReason\QuoteReason;
use App\V4\Model\QuoteSpecificField\QuoteSpecificField;
use App\V4\Model\QuoteState\QuoteState;
use App\V4\Model\QuoteTaskExternalRef\QuoteTaskExternalRef;
use App\V4\Model\SpecificField\SpecificField;
use DateTime;
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;
/**
* @ApiResource(
* shortName="V4/Quote",
* attributes={
* "api_allow_update": true
* },
* collectionOperations={
* "get": {
* "normalization_context": {
* "groups": {"quote:list"}
* },
* "security": "is_granted(constant('App\\V4\\Voters\\QuoteVoter::QUOTE_SHOW_LIST'), 'App\V4\Voters\QuoteVoter')"
* },
* "post_quote": {
* "method": "POST",
* "deserialize": false,
* "write": false,
* "controller": "App\V4\Controller\Quote\QuoteDataPersisterAction",
* "path": "/V4/quotes",
* "input_formats": {
* "multipart": {"multipart/form-data"}
* },
* "normalization_context": {
* "groups": {"quote:read", "isProspectRefreshNeeded"}
* },
* "denormalization_context": {
* "groups": {}
* }
* },
* "get_form": {
* "method": "GET",
* "path": "/V4/quotes/form",
* "controller": App\V4\Controller\Quote\GetQuoteFormAction::class
* },
* "get_search": {
* "method": "GET",
* "path": "/V4/quotes/search/form",
* "controller": App\V4\Controller\Quote\GetQuoteSearchFormAction::class,
* },
* "post_search": {
* "method": "POST",
* "deserialize": false,
* "path": "/V4/quotes/search/form",
* "normalization_context": {
* "groups": {"quote:list"}
* },
* "controller": App\V4\Controller\Quote\PostQuoteSearchFormAction::class,
* },
* "post_export_request": {
* "method": "POST",
* "path": "/v4/export/quote",
* "controller": App\V4\Action\Export\EntityExportRequestAction::class,
* "swagger_context": {
* "summary": "Demande de création d'export de devis",
* "description": "Demande de création d'export de devis où 'ids' sont les ids des devis 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/quote/{id}",
* "controller": App\V4\Action\Export\EntityExportDownloadAction::class,
* "swagger_context": {
* "summary": "Demande de téléchargement d'un export devis",
* "description": "Demande de téléchargement d'un export devis 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"},
* }
* }
* },
* },
* }
* },
* "get_expected_signed_at_form": {
* "method": "GET",
* "path": "/V4/quotes/expected-signed-at/form",
* "controller": App\V4\Controller\Quote\GetQuoteExpectedSignedAtFormAction::class,
* "swagger_context": {
* "summary": "Retourne le formulaire de date de signature",
* "description": "Retourne le formulaire de date de signature dans le cadre d'une action rapide visant à basculer un devis en statut gagné",
* "parameters": {},
* },
* },
* },
* itemOperations={
* "get": {
* "path": "/V4/quotes/{id}",
* },
* "get_form": {
* "method": "GET",
* "path": "/V4/quotes/{id}/form",
* "controller": App\V4\Controller\Quote\GetQuoteFormAction::class
* },
* "get_reason_form": {
* "method": "GET",
* "path": "/V4/quotes/{id}/reason/form",
* "controller": App\V4\Controller\Quote\GetQuoteReasonFormAction::class
* },
* "post_reason": {
* "method": "POST",
* "path": "/V4/quotes/{id}/reason",
* "controller": App\V4\Controller\Quote\PostQuoteReasonAction::class
* },
* "put_quote": {
* "method": "POST",
* "deserialize": false,
* "write": false,
* "controller": "App\V4\Controller\Quote\QuoteDataPersisterAction",
* "path": "/V4/quotes/{id}",
* "input_formats": {
* "multipart": {"multipart/form-data"}
* },
* "normalization_context": {
* "groups": {"quote:read", "isProspectRefreshNeeded"}
* },
* "denormalization_context": {
* "groups": {}
* }
* },
* "regenerate_quote": {
* "method": "POST",
* "path": "/V4/quotes/{id}/regenerate",
* "controller": "App\V4\Action\Quote\RegenerateQuoteAction",
* "swagger_context": {
* "summary": "Demande de réactualisation de l'offre",
* "description": "Demande de réactualisation de l'offre du devis 'id'",
* "parameters": {
* {
* "in": "path",
* "name": "id",
* "type": "string",
* "required": "true"
* },
* {
* "in": "body",
* "name": "body",
* "schema": {
* "type": "object",
* "properties": {
* "updatePrice": {"type": "boolean"},
* "template": {"type": "string", "example": "id_du_template"},
* },
* },
* },
* },
* },
* },
* "regenerate_quote_get": {
* "method": "GET",
* "path": "/V4/quotes/{id}/regenerate",
* "controller": "App\V4\Action\Quote\GetRegenerateQuoteFormAction",
* "swagger_context": {
* "summary": "Demande de récupération du formulaire de réactualisation de l'offre",
* "description": "Demande de récupération du formulaire de réactualisation de l'offre du devis 'id'",
* "responses": {
* "200": {
* "description": "Envoi du formulaire de réactualisation de l'offre",
* },
* "404": {
* "description": "Devis introuvable",
* },
* },
* },
* },
* "split_chidren": {
* "method": "POST",
* "deserialize": false,
* "path": "/quotes/{id}/split-children",
* "controller": App\V4\Controller\Quote\SplitChildrenAction::class,
* },
* "get_tasks": {
* "method": "GET",
* "path": "/v4/quotes/{id}/related-tasks",
* "normalization_context": {
* "groups": {"task:list"}
* },
* "controller": App\V4\Action\Quote\GetRelatedTasksByQuoteAction::class,
* "read": false,
* "swagger_context": {
* "summary": "Récupert les actions liées au devis",
* },
* },
* "delete_quote": {
* "method": "DELETE",
* "deserialize": false,
* "write": false,
* "controller": "App\V4\Controller\Quote\QuoteDataPersisterAction",
* "path": "/V4/quotes/{id}"
* },
* "duplicate_quote": {
* "method": "GET",
* "path": "/V4/quotes/{quoteId}/form/duplicate",
* "controller": "App\V4\Action\Quote\DuplicateQuoteAction::class",
* "swagger_context": {
* "summary": "Demande de duplication d'un devis",
* "description": "Demande de création d'un nouveau formulaire devis ayant pour valeur une copie du devis 'quoteId'",
* "parameters": {
* {
* "in": "path",
* "name": "quoteId",
* "type": "string",
* "required": "true"
* }
* },
* "responses": {
* "200": {
* "description": "Création d'un formulaire basé sur le devis à duppliquer réalisé avec succès"
* },
* "500": {
* "description": "Le devis ne peut pas être divisé car il est enfant ou parent d'un autre devis"
* },
* "404": {
* "description": "Devis introuvable"
* },
* },
* },
* },
* "post_expected_signed_at_form": {
* "method": "POST",
* "path": "/V4/quotes/{id}/expected-signed-at",
* "controller": App\V4\Controller\Quote\PostQuoteExpectedSignedAtFormAction::class,
* "swagger_context": {
* "summary": "Envoie date de signature pour passage d'un devis en statut Gagné",
* "description": "Demande de soumission du formulaire de date de signature dans le cadre d'une action rapide visant à basculer un devis en statut gagné",
* "parameters": {
* {
* "in": "path",
* "name": "id",
* "type": "string",
* "required": "true"
* },
* {
* "in": "body",
* "name": "body",
* "schema": {
* "type": "object",
* "properties": {
* "status": {"type": "string", "example": "id_statut_gagne"},
* "expectedSignedAt": {"type": "string", "example": "2024-03-22T17:50"},
* },
* },
* },
* },
* },
* },
* }
* )
*
* @ApiFilter(App\Filters\PagingFilter::class)
*/
class Quote implements IriNormalizableInterface, SpecificFieldsAwareInterface, ChildrenAwareInterface, ActionableEntityInterface
{
public const SPECIFIC_FIELD_CLASS_NAME = QuoteSpecificField::class;
public const DEFAULT_POTENTIAL_VALUE = 50;
use TimestampableTrait;
use BlamableTrait;
use ImportableObjectTrait;
use NormalizeAsIRITrait;
use ProspectRefreshNeededTrait;
/**
* @var string|null
*
* @ApiProperty(identifier=true)
*
* @Groups({"quote:list", "quote:read"})
*/
private $id;
/**
* @var string|null
*
* @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
*/
private $externalId;
/**
* @var string|null
*/
private $customerId;
/**
* @var ArrayCollection|QuoteLine[]
*
* @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
*/
private $quoteLines;
/**
* @var string|null
*
* @Assert\NotBlank()
* @Assert\Length(max=255)
*
* @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
*/
private $name;
/**
* @var Prospect|null
*
* @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
* @MaxDepth(1)
*/
private $prospect;
/**
* @var string|null
*
* @Assert\NotBlank()
*
* @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
*/
private $prospectId;
/**
* @var string|null
*
* @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
*/
private $managedBy;
/**
* @var string|null
*
* @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
*/
private $contactId;
/**
* @var string|null
*
* @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
*/
private $terms;
/**
* @var DateTime|null
*
* @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
*/
private $warrantlyAt;
/**
* @var string|null
*
* @Assert\Length(max=100)
*
* @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
*/
private $contractNumber;
/**
* @var bool|null
*
* @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
*/
private $isMaintenance;
/**
* @var string|null
*
* @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
*/
private $comment;
/**
* @var DateTime|null
*
* @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
*/
private $issuedAt;
/**
* @var float|null
*
* @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
*/
private $potential;
/**
* @var string|null
*
* @Assert\Length(max=255)
*
* @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
*/
private $quoteNumber;
/**
* @var QuoteState|null
*
* @Assert\NotBlank()
*
* @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
*/
private $status;
/**
* @var string|null
*
* @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
*/
private $description;
/**
* @var DateTime|null
*
* @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
*/
private $expectedSignedAt;
/**
* @var DateTime|null
*
* @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
*/
private $expiredAt;
/**
* @var string|null
*
* @Assert\LessThan(99999999)
*
* @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
*/
private $totalExcludingVat;
/**
* @var string|null
*
* @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
*/
private $weightedTotal;
/**
* @var bool|null
*
* @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
*/
private $isSalesForecast = true;
/**
* @var CustomerFile[]|Collection
*
* @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
*/
private $customerFiles = [];
/**
* @var string|null
*
* @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
*/
private $sectionName;
/**
* @var SpecificField[]|Collection
*
* @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
*/
private $specificFields;
/**
* @var Quote|null
*
* @Groups({"quote:list", "quote:read", "quote:write"})
*/
private $parent;
/**
* @var Quote[]|Collection
*
* @Groups({"quote:list", "quote:read"})
*/
private $children;
/**
* @var QuoteTaskExternalRef[]|Collection
*
* @Groups({"quote:read", "quote:write", "quote:update"})
*/
private $tasks;
/**
* @var string|null
*
* @Groups({"quote:list"})
*/
private $prospectFullName;
/**
* @var string|null
*
* @Groups({"quote:list"})
*/
private $contactIdRealName;
/**
* @var string|null
*/
private $managedByRealName;
/**
* @var QuoteReason|null
* @MaxDepth(1)
* @Groups({"list", "write_post_quote", "quote:read", "quote:write", "quote:update"})
*/
private $reason;
/**
* @var string|null
* @Groups({"list", "write_post_quote", "quote:read", "quote:write", "quote:update"})
*/
private $reasonComment;
public function __construct()
{
$this->specificFields = new ArrayCollection();
$this->quoteLines = new ArrayCollection();
$this->children = new ArrayCollection();
$this->tasks = new ArrayCollection();
}
/**
* @return float
*/
public function getTotalIncludingVat(): float
{
$total = 0;
foreach ($this->quoteLines as $quoteLine) {
$total += (float) $quoteLine->getTotal();
}
return $total;
}
/**
* @return array The total vat amount by percentage
*/
public function getTotalVatByPercentage(): array
{
$totalVatByPercentage = [];
foreach ($this->quoteLines as $quoteLine) {
$vatPercentage = $quoteLine->getVatRate();
if (!isset($totalVatByPercentage[$vatPercentage])) {
$totalVatByPercentage[$vatPercentage] = 0;
}
$totalVatByPercentage[$vatPercentage] += $quoteLine->getVatAmount();
}
return $totalVatByPercentage;
}
/**
* @return float
*/
public function getTotalDiscount(): float
{
$total = 0;
foreach ($this->quoteLines as $quoteLine) {
$total += (float) $quoteLine->getDiscountAmount();
}
return $total;
}
/**
* @return float
*/
public function getTotalExcludingVatBeforeDiscount(): float
{
$total = 0;
foreach ($this->quoteLines as $quoteLine) {
$total += (float) $quoteLine->getTotalExclDiscountAndVat();
}
return $total;
}
/**
* @return bool
*
* @Assert\Callback()
*/
public function validateReason(): bool
{
if (!$this->reason || !$this->status) {
return true;
}
if ($this->reason->getQuoteState() !== $this->status) {
return false;
}
return true;
}
/**
* @param string $name
*
* @return string
*/
public function getSectionTotal(string $name): string
{
$sum = 0;
foreach ($this->getQuoteLines() as $quoteLine) {
if ($name !== $quoteLine->getSectionName()) {
continue;
}
$sum += floatval($quoteLine->getTotal());
}
return $sum;
}
/**
* @param string $sectionName
*
* @return QuoteLine[]
*/
public function getQuoteLinesForSection(string $sectionName): array
{
$quoteLines = [];
foreach ($this->getQuoteLines() as $quoteLine) {
if ($sectionName === $quoteLine->getSectionName()) {
$quoteLines[] = $quoteLine;
}
}
return $quoteLines;
}
/**
* {@inheritdoc}
*/
public function isSplit(): bool
{
return $this->isParent() || $this->isChild();
}
/**
* @return void
*/
public function getSplitType(): ?string
{
if ($this->isParent()) {
return 'parent';
}
if ($this->isChild()) {
return 'child';
}
return null;
}
/**
* {@inheritdoc}
*/
public function isParent(): bool
{
return !$this->getChildren()->isEmpty();
}
/**
* {@inheritdoc}
*/
public function isChild(): bool
{
return $this->getParent() instanceof Quote;
}
/**
* @return Quote[]|Collection
*/
public function getSiblings(): Collection
{
if (!$this->isChild()) {
return new ArrayCollection();
}
$siblings = [];
foreach ($this->getParent()->getChildren() as $child) {
if ($child->getId() !== $this->getId()) {
$siblings[] = $child;
}
}
return new ArrayCollection($siblings);
}
/**
* @return bool
*/
public function isLate(): bool
{
return $this->getStatus() && $this->getStatus()->getInProgress() && $this->getExpectedSignedAt() < new DateTime();
}
/**
* @return bool
*/
public function isWon(): bool
{
return $this->getStatus() instanceof QuoteState && $this->getStatus()->getIsWon();
}
/**
* @return string[]
*/
public function getAllSectionNames(): array
{
$sectionsNames = [];
foreach ($this->getQuoteLines() as $quoteLine) {
if (!empty($quoteLine->getSectionName()) && !in_array($quoteLine->getSectionName(), $sectionsNames, true)) {
$sectionsNames[] = $quoteLine->getSectionName();
}
}
return $sectionsNames;
}
public function getCurrentPdfVersion(): int
{
if (empty($this->getCustomerFiles())) {
return 1;
}
$version = 0;
foreach ($this->getCustomerFiles() as $customerFile) {
if ($version < $customerFile->getVersionNumber()) {
$version = $customerFile->getVersionNumber();
}
}
return $version + 1;
}
public function getTemplateId(): ?string
{
$customerFiles = array_filter($this->getCustomerFiles(), static function ($cf) {
return $cf->isQuotePdf();
});
usort($customerFiles, static function (CustomerFile $a, CustomerFile $b) {
return $a->getUpdatedAt() < $b->getUpdatedAt();
});
if (empty($customerFiles)) {
return null;
}
return $customerFiles[0]->getTemplateId();
}
/**
* @return string
*/
public function getId(): ?string
{
return $this->id;
}
/**
* @param string|null $id
*
* @return Quote
*/
public function setId(?string $id): Quote
{
$this->id = $id;
return $this;
}
/**
* @return string|null
*/
public function getExternalId(): ?string
{
return $this->externalId;
}
/**
* @param string|null $externalId
*
* @return Quote
*/
public function setExternalId(?string $externalId): self
{
$this->externalId = $externalId;
return $this;
}
/**
* @return Collection|QuoteLine[]
*/
public function getQuoteLines(): Collection
{
return $this->quoteLines;
}
/**
* @param QuoteLine $quoteLine
*
* @return self
*/
public function addQuoteLine(QuoteLine $quoteLine): self
{
if (!$this->quoteLines->contains($quoteLine)) {
$quoteLine->setQuote($this);
$this->quoteLines->add($quoteLine);
}
return $this;
}
/**
* @param Collection|QuoteLine[] $quoteLines
*
* @return self
*/
public function setQuoteLines(Collection $quoteLines): self
{
$this->quoteLines = $quoteLines;
return $this;
}
/**
* @param QuoteLine $quoteLine
*
* @return self
*/
public function removeQuoteLine(QuoteLine $quoteLine): self
{
if ($this->quoteLines->contains($quoteLine)) {
$this->quoteLines->removeElement($quoteLine);
}
return $this;
}
/**
* @return string|null
*/
public function getName(): ?string
{
return $this->name;
}
/**
* @param string|null $name
*
* @return Quote
*/
public function setName(?string $name): Quote
{
$this->name = $name;
return $this;
}
/**
* @return string|null
*/
public function getCustomerId(): ?string
{
return $this->customerId;
}
/**
* @param string|null $customerId
*
* @return Quote
*/
public function setCustomerId(?string $customerId): Quote
{
$this->customerId = $customerId;
return $this;
}
/**
* @return string|null
*/
public function getManagedBy(): ?string
{
return $this->managedBy;
}
/**
* @param string|null $managedBy
*
* @return Quote
*/
public function setManagedBy(?string $managedBy): Quote
{
$this->managedBy = $managedBy;
return $this;
}
/**
* @return DateTime|null
*/
public function getIssuedAt(): ?DateTime
{
return $this->issuedAt;
}
/**
* @param DateTime|null $issuedAt
*
* @return Quote
*/
public function setIssuedAt(?DateTime $issuedAt): Quote
{
$this->issuedAt = $issuedAt;
return $this;
}
/**
* @return float|null
*/
public function getPotential(): ?float
{
return $this->potential;
}
/**
* @param float|null $potential
*
* @return Quote
*/
public function setPotential(?float $potential): Quote
{
$this->potential = $potential;
return $this;
}
/**
* @return QuoteState|null
*/
public function getStatus(): ?QuoteState
{
return $this->status;
}
/**
* @param QuoteState|null $status
*
* @return Quote
*/
public function setStatus(?QuoteState $status): Quote
{
$this->status = $status;
return $this;
}
/**
* @return DateTime|null
*/
public function getExpectedSignedAt(): ?DateTime
{
return $this->expectedSignedAt;
}
/**
* @param DateTime|null $expectedSignedAt
*
* @return Quote
*/
public function setExpectedSignedAt(?DateTime $expectedSignedAt): Quote
{
$this->expectedSignedAt = $expectedSignedAt;
return $this;
}
/**
* @return string|null
*/
public function getTotalExcludingVat(): ?string
{
return $this->totalExcludingVat;
}
/**
* @param string|null $totalExcludingVat
*
* @return Quote
*/
public function setTotalExcludingVat(?string $totalExcludingVat): Quote
{
$this->totalExcludingVat = $totalExcludingVat;
return $this;
}
/**
* @return bool|null
*/
public function getIsSalesForecast(): ?bool
{
return $this->isSalesForecast;
}
/**
* @param bool|null $isSalesForecast
*
* @return Quote
*/
public function setIsSalesForecast(?bool $isSalesForecast): Quote
{
$this->isSalesForecast = $isSalesForecast;
return $this;
}
/**
* @return Prospect|null
*/
public function getProspect(): ?Prospect
{
return $this->prospect;
}
/**
* @param Prospect|null $prospect
*
* @return Quote
*/
public function setProspect(?Prospect $prospect): Quote
{
$this->prospect = $prospect;
return $this;
}
/**
* @return string|null
*/
public function getProspectId(): ?string
{
return $this->prospectId;
}
/**
* @param string|null $prospectId
*
* @return Quote
*/
public function setProspectId(?string $prospectId): self
{
$this->prospectId = $prospectId;
return $this;
}
/**
* @return string|null
*/
public function getQuoteNumber(): ?string
{
return $this->quoteNumber;
}
/**
* @param string|null $quoteNumber
*
* @return Quote
*/
public function setQuoteNumber(?string $quoteNumber): Quote
{
$this->quoteNumber = $quoteNumber;
return $this;
}
/**
* @return DateTime|null
*/
public function getExpiredAt(): ?DateTime
{
return $this->expiredAt;
}
/**
* @param DateTime|null $expiredAt
*
* @return Quote
*/
public function setExpiredAt(?DateTime $expiredAt): Quote
{
$this->expiredAt = $expiredAt;
return $this;
}
/**
* @return string|null
*/
public function getDescription(): ?string
{
return $this->description;
}
/**
* @param string|null $description
*
* @return Quote
*/
public function setDescription(?string $description): Quote
{
$this->description = $description;
return $this;
}
/**
* @return string|null
*/
public function getContactId(): ?string
{
return $this->contactId;
}
/**
* @param string|null $contactId
*
* @return Quote
*/
public function setContactId(?string $contactId): Quote
{
$this->contactId = $contactId;
return $this;
}
/**
* @return string|null
*/
public function getTerms(): ?string
{
return $this->terms;
}
/**
* @param string|null $terms
*
* @return Quote
*/
public function setTerms(?string $terms): Quote
{
$this->terms = $terms;
return $this;
}
/**
* @return DateTime|null
*/
public function getWarrantlyAt(): ?DateTime
{
return $this->warrantlyAt;
}
/**
* @param DateTime|null $warrantlyAt
*
* @return Quote
*/
public function setWarrantlyAt(?DateTime $warrantlyAt): Quote
{
$this->warrantlyAt = $warrantlyAt;
return $this;
}
/**
* @return string|null
*/
public function getContractNumber(): ?string
{
return $this->contractNumber;
}
/**
* @param string|null $contractNumber
*
* @return Quote
*/
public function setContractNumber(?string $contractNumber): Quote
{
$this->contractNumber = $contractNumber;
return $this;
}
/**
* @return bool|null
*/
public function getIsMaintenance(): ?bool
{
return $this->isMaintenance;
}
/**
* @param bool|null $isMaintenance
*
* @return Quote
*/
public function setIsMaintenance(?bool $isMaintenance): Quote
{
$this->isMaintenance = $isMaintenance;
return $this;
}
/**
* @return string|null
*/
public function getComment(): ?string
{
return $this->comment;
}
/**
* @param string|null $comment
*
* @return Quote
*/
public function setComment(?string $comment): Quote
{
$this->comment = $comment;
return $this;
}
/**
* @Groups({"list", "write_post_quote"})
*
* @return string|null
*/
public function getCreatedBy(): ?string
{
return $this->createdBy;
}
/**
* @param string|null $createdBy
*
* @return Quote
*/
public function setCreatedBy(?string $createdBy): Quote
{
$this->createdBy = $createdBy;
return $this;
}
/**
* @Groups({"list", "write_post_quote"})
*
* @return string|null
*/
public function getUpdatedBy(): ?string
{
return $this->updatedBy;
}
/**
* @param string|null $updatedBy
*
* @return Quote
*/
public function setUpdatedBy(?string $updatedBy): Quote
{
$this->updatedBy = $updatedBy;
return $this;
}
/**
* @Groups({"list", "write_post_quote"})
*
* @return DateTime|null
*/
public function getCreatedAt(): ?DateTime
{
return $this->createdAt;
}
/**
* @param DateTime|null $createdAt
*
* @return Quote
*/
public function setCreatedAt(?DateTime $createdAt): Quote
{
$this->createdAt = $createdAt;
return $this;
}
/**
* @Groups({"list", "write_post_quote"})
*
* @return DateTime|null
*/
public function getUpdatedAt(): ?DateTime
{
return $this->updatedAt;
}
/**
* @param DateTime|null $updatedAt
*
* @return Quote
*/
public function setUpdatedAt(?DateTime $updatedAt): Quote
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* @return CustomerFile[]
*/
public function getCustomerFiles()
{
return $this->customerFiles ?: [];
}
/**
* @param CustomerFile $customerFile
*
* @return Quote
*/
public function addCustomerFile(CustomerFile $customerFile): self
{
$this->customerFiles[] = $customerFile;
return $this;
}
/**
* @param CustomerFile $customerFile
*
* @return Quote
*/
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 Quote
*/
public function setCustomerFiles(array $customerFiles): self
{
$this->customerFiles = $customerFiles;
return $this;
}
/**
* {@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 QuoteSpecificField $specificField
*
* @return $this
*/
public function addQuoteSpecificField(QuoteSpecificField $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 getWeightedTotal(): ?string
{
return $this->weightedTotal;
}
/**
* @param string|null $weightedTotal
*
* @return Quote
*/
public function setWeightedTotal(?string $weightedTotal): Quote
{
$this->weightedTotal = $weightedTotal;
return $this;
}
/**
* @return string|null
*/
public function getSectionName(): ?string
{
return $this->sectionName;
}
/**
* @param string|null $sectionName
*
* @return Quote
*/
public function setSectionName(?string $sectionName): Quote
{
$this->sectionName = $sectionName;
return $this;
}
/**
* @return Quote|null
*/
public function getParent(): ?self
{
return $this->parent;
}
/**
* @param Quote|null $parent
*
* @return self
*/
public function setParent(?self $parent): self
{
$this->parent = $parent;
return $this;
}
/**
* {@inheritdoc}
*/
public function getChildren(): Collection
{
return $this->children;
}
/**
* @param Quote[]|Collection $children
*
* @return self
*/
public function setChildren($children): self
{
//@todo : trouver le moyen de serializer le self pour récupérer devis1->parent->children qui contient devis1 (iri renvoyé actuellement donc ignoré)
if ($children instanceof Collection) {
$this->children = $children;
}
return $this;
}
/**
* @deprecated Use addChild() instead.
* This is stupid, but the ImportableObjectTrait checks for adders using add.ucfirst($type) where $type is the class name.
*
* @param Quote $child
*
* @return $this
*/
public function addQuote(Quote $child): self
{
return $this->addChild($child);
}
/**
* @param Quote $child
*
* @return $this
*/
public function addChild(Quote $child): self
{
if (!$this->children->contains($child)) {
$this->children[] = $child;
$child->setParent($this);
}
return $this;
}
/**
* @param Quote $child
*
* @return $this
*/
public function removeChildren(Quote $child): self
{
if ($this->children->contains($child)) {
$this->children->removeElement($child);
$child->setParent(null);
}
return $this;
}
/**
* @param string $taskId
*
* @return bool
*/
public function hasTask(string $taskId): bool
{
foreach ($this->tasks as $task) {
if ($taskId === $task->getExternalValue()) {
return true;
}
}
return false;
}
/**
* @return QuoteTaskExternalRef[]|Collection
*/
public function getTasks(): Collection
{
return $this->tasks;
}
/**
* @param QuoteTaskExternalRef[]|Collection $tasks
*
* @return self
*/
public function setTasks(Collection $tasks): self
{
$this->tasks = $tasks;
return $this;
}
/**
* @param QuoteTaskExternalRef $task
*
* @return self
*/
public function addTask(QuoteTaskExternalRef $task): self
{
if (!$this->tasks->contains($task)) {
$this->tasks->add($task);
}
return $this;
}
/**
* Redondance avec addTask dû au ImportableObjectTrait.
*
* @param QuoteTaskExternalRef $task
*
* @return self
*/
public function addQuoteTaskExternalRef(QuoteTaskExternalRef $task): self
{
return $this->addTask($task);
}
/**
* @param QuoteTaskExternalRef $task
*
* @return self
*/
public function removeTask(QuoteTaskExternalRef $task): self
{
if ($this->tasks->contains($task)) {
$this->tasks->remove($task);
}
return $this;
}
/**
* @return QuoteReason|null
*/
public function getReason(): ?QuoteReason
{
return $this->reason;
}
/**
* @param QuoteReason|null $reason
*
* @return Quote
*/
public function setReason(?QuoteReason $reason): Quote
{
$this->reason = $reason;
return $this;
}
/**
* @return string|null
*/
public function getReasonComment(): ?string
{
return $this->reasonComment;
}
/**
* @param string|null $reasonComment
*
* @return Quote
*/
public function setReasonComment(?string $reasonComment): Quote
{
$this->reasonComment = $reasonComment;
return $this;
}
/**
* @return string|null
*/
public function getProspectFullName(): ?string
{
return $this->prospectFullName;
}
/**
* @param string|null $prospectFullName
*
* @return Quote
*/
public function setProspectFullName(?string $prospectFullName): self
{
$this->prospectFullName = $prospectFullName;
return $this;
}
/**
* @return string|null
*/
public function getContactIdRealName(): ?string
{
return $this->contactIdRealName;
}
/**
* @param string|null $contactIdRealName
*
* @return Quote
*/
public function setContactIdRealName(?string $contactIdRealName): self
{
$this->contactIdRealName = $contactIdRealName;
return $this;
}
/**
* @return string
*/
public function getManagedByRealName(): ?string
{
return $this->managedByRealName;
}
/**
* @param string $managedByRealName
*
* @return Quote
*/
public function setManagedByRealName(?string $managedByRealName): Quote
{
$this->managedByRealName = $managedByRealName;
return $this;
}
/**
* @param string|null $taskId
*
* @return void
*/
public function removeQuoteTaskExternalRefByExternalValue(?string $taskId)
{
foreach ($this->tasks as $task) {
if ($taskId === $task->getExternalValue()) {
$this->removeTask($task);
}
}
}
}