src/V4/Model/Quote/Quote.php line 357

Open in your IDE?
  1. <?php
  2. namespace App\V4\Model\Quote;
  3. use ApiPlatform\Core\Annotation\ApiFilter;
  4. use ApiPlatform\Core\Annotation\ApiProperty;
  5. use ApiPlatform\Core\Annotation\ApiResource;
  6. use App\Model\CustomerFile\CustomerFile;
  7. use App\Model\IriNormalizableInterface;
  8. use App\Model\NormalizeAsIRITrait;
  9. use App\Model\ProspectRefreshNeededTrait;
  10. use App\Model\SpecificFieldAwareTrait;
  11. use App\Model\SpecificFieldsAwareInterface;
  12. use App\Model\Traits\BlamableTrait;
  13. use App\Model\Traits\ImportableObjectTrait;
  14. use App\Model\Traits\TimestampableTrait;
  15. use App\V4\Entity\ActionableEntityInterface;
  16. use App\V4\Model\ChildrenAwareInterface;
  17. use App\V4\Model\CustomerFileAwareInterface;
  18. use App\V4\Model\Prospect\Prospect;
  19. use App\V4\Model\QuoteLine\QuoteLine;
  20. use App\V4\Model\QuoteReason\QuoteReason;
  21. use App\V4\Model\QuoteSpecificField\QuoteSpecificField;
  22. use App\V4\Model\QuoteState\QuoteState;
  23. use App\V4\Model\QuoteTaskExternalRef\QuoteTaskExternalRef;
  24. use App\V4\Model\SpecificField\SpecificField;
  25. use DateTime;
  26. use Doctrine\Common\Collections\ArrayCollection;
  27. use Doctrine\Common\Collections\Collection;
  28. use Symfony\Component\Serializer\Annotation\Groups;
  29. use Symfony\Component\Serializer\Annotation\MaxDepth;
  30. use Symfony\Component\Validator\Constraints as Assert;
  31. /**
  32.  * @ApiResource(
  33.  *     shortName="V4/Quote",
  34.  *     attributes={
  35.  *         "api_allow_update": true
  36.  *     },
  37.  *     collectionOperations={
  38.  *         "get": {
  39.  *             "normalization_context": {
  40.  *                  "groups": {"quote:list"}
  41.  *             },
  42.  *             "security": "is_granted(constant('App\\V4\\Voters\\QuoteVoter::QUOTE_SHOW_LIST'), 'App\V4\Voters\QuoteVoter')"
  43.  *         },
  44.  *         "post_quote": {
  45.  *             "method": "POST",
  46.  *             "deserialize": false,
  47.  *             "write": false,
  48.  *             "controller": "App\V4\Controller\Quote\QuoteDataPersisterAction",
  49.  *             "path": "/V4/quotes",
  50.  *             "input_formats": {
  51.  *                 "multipart": {"multipart/form-data"}
  52.  *             },
  53.  *             "normalization_context": {
  54.  *                  "groups": {"quote:read", "isProspectRefreshNeeded"}
  55.  *             },
  56.  *             "denormalization_context": {
  57.  *                  "groups": {}
  58.  *             }
  59.  *         },
  60.  *         "get_form": {
  61.  *             "method": "GET",
  62.  *             "path": "/V4/quotes/form",
  63.  *             "controller": App\V4\Controller\Quote\GetQuoteFormAction::class
  64.  *         },
  65.  *         "get_search": {
  66.  *             "method": "GET",
  67.  *             "path": "/V4/quotes/search/form",
  68.  *             "controller": App\V4\Controller\Quote\GetQuoteSearchFormAction::class,
  69.  *         },
  70.  *         "post_search": {
  71.  *             "method": "POST",
  72.  *             "deserialize": false,
  73.  *             "path": "/V4/quotes/search/form",
  74.  *             "normalization_context": {
  75.  *                  "groups": {"quote:list"}
  76.  *             },
  77.  *             "controller": App\V4\Controller\Quote\PostQuoteSearchFormAction::class,
  78.  *         },
  79.  *         "post_export_request": {
  80.  *             "method": "POST",
  81.  *             "path": "/v4/export/quote",
  82.  *             "controller": App\V4\Action\Export\EntityExportRequestAction::class,
  83.  *             "swagger_context": {
  84.  *                 "summary": "Demande de création d'export de devis",
  85.  *                 "description": "Demande de création d'export de devis où 'ids' sont les ids des devis et 'fields' les champs souhaités",
  86.  *                 "parameters": {
  87.  *                     {
  88.  *                         "in": "body",
  89.  *                         "name": "body",
  90.  *                         "schema": {
  91.  *                             "type": "object",
  92.  *                             "properties": {
  93.  *                                 "ids": {
  94.  *                                     "type": "array",
  95.  *                                     "items": {"type": "string"}
  96.  *                                 },
  97.  *                                 "fields": {
  98.  *                                      "type": "array",
  99.  *                                      "items": {"type": "string"}
  100.  *                                 }
  101.  *                             }
  102.  *                         }
  103.  *                     }
  104.  *                 },
  105.  *                 "responses": {
  106.  *                     "201": {
  107.  *                         "description": "Création de l'export avec succès",
  108.  *                         "schema": {
  109.  *                             "type": "object",
  110.  *                             "properties": {
  111.  *                                 "message": {"type": "string", "example": "export_request_created"},
  112.  *                             }
  113.  *                         }
  114.  *                     },
  115.  *                     "400": {
  116.  *                         "description": "Utilisateur non trouvé ou champs 'fields' ou 'ids' manquant dans le body request",
  117.  *                         "schema": {
  118.  *                             "type": "object",
  119.  *                             "properties": {
  120.  *                                 "message": {"type": "string", "example": "user_not_found or missing_fields_or_ids"},
  121.  *                             }
  122.  *                         }
  123.  *                     },
  124.  *                     "422": {
  125.  *                         "description": "Les champs 'fields' ou 'ids' du body request sont vides ou l'entité demandée est invalide",
  126.  *                         "schema": {
  127.  *                             "type": "object",
  128.  *                             "properties": {
  129.  *                                 "message": {"type": "string", "example": "empty_fields_or_ids or entity_not_valid"},
  130.  *                             }
  131.  *                         }
  132.  *                     },
  133.  *                 },
  134.  *             }
  135.  *         },
  136.  *         "post_export_download": {
  137.  *             "method": "POST",
  138.  *             "path": "/v4/export/download/quote/{id}",
  139.  *             "controller": App\V4\Action\Export\EntityExportDownloadAction::class,
  140.  *             "swagger_context": {
  141.  *                 "summary": "Demande de téléchargement d'un export devis",
  142.  *                 "description": "Demande de téléchargement d'un export devis ou 'id' est le nom du fichier d'export",
  143.  *                 "requestBody": {},
  144.  *                 "parameters": {
  145.  *                     {
  146.  *                         "in": "path",
  147.  *                         "name": "id",
  148.  *                         "type": "string",
  149.  *                         "required": "true"
  150.  *                     }
  151.  *                 },
  152.  *                 "responses": {
  153.  *                     "200": {
  154.  *                         "description": "Téléchargement de l'export réalisé avec succès"
  155.  *                     },
  156.  *                     "401": {
  157.  *                         "description": "Utilisateur non trouvé ou non connecté",
  158.  *                         "schema": {
  159.  *                             "type": "object",
  160.  *                             "properties": {
  161.  *                                 "message": {"type": "string", "example": "need_authenticated"},
  162.  *                             }
  163.  *                         }
  164.  *                     },
  165.  *                     "404": {
  166.  *                         "description": "Fichier introuvable",
  167.  *                         "schema": {
  168.  *                             "type": "object",
  169.  *                             "properties": {
  170.  *                                 "message": {"type": "string", "example": "export_not_found"},
  171.  *                             }
  172.  *                         }
  173.  *                     },
  174.  *                 },
  175.  *             }
  176.  *         },
  177.  *         "get_expected_signed_at_form": {
  178.  *             "method": "GET",
  179.  *             "path": "/V4/quotes/expected-signed-at/form",
  180.  *             "controller": App\V4\Controller\Quote\GetQuoteExpectedSignedAtFormAction::class,
  181.  *             "swagger_context": {
  182.  *                 "summary": "Retourne le formulaire de date de signature",
  183.  *                 "description": "Retourne le formulaire de date de signature dans le cadre d'une action rapide visant à basculer un devis en statut gagné",
  184.  *                 "parameters": {},
  185.  *             },
  186.  *         },
  187.  *     },
  188.  *     itemOperations={
  189.  *        "get": {
  190.  *             "path": "/V4/quotes/{id}",
  191.  *         },
  192.  *         "get_form": {
  193.  *             "method": "GET",
  194.  *             "path": "/V4/quotes/{id}/form",
  195.  *             "controller": App\V4\Controller\Quote\GetQuoteFormAction::class
  196.  *         },
  197.  *         "get_reason_form": {
  198.  *             "method": "GET",
  199.  *             "path": "/V4/quotes/{id}/reason/form",
  200.  *             "controller": App\V4\Controller\Quote\GetQuoteReasonFormAction::class
  201.  *         },
  202.  *         "post_reason": {
  203.  *             "method": "POST",
  204.  *             "path": "/V4/quotes/{id}/reason",
  205.  *             "controller": App\V4\Controller\Quote\PostQuoteReasonAction::class
  206.  *         },
  207.  *         "put_quote": {
  208.  *             "method": "POST",
  209.  *             "deserialize": false,
  210.  *             "write": false,
  211.  *             "controller": "App\V4\Controller\Quote\QuoteDataPersisterAction",
  212.  *             "path": "/V4/quotes/{id}",
  213.  *             "input_formats": {
  214.  *                 "multipart": {"multipart/form-data"}
  215.  *             },
  216.  *             "normalization_context": {
  217.  *                  "groups": {"quote:read", "isProspectRefreshNeeded"}
  218.  *             },
  219.  *             "denormalization_context": {
  220.  *                  "groups": {}
  221.  *             }
  222.  *         },
  223.  *         "regenerate_quote": {
  224.  *             "method": "POST",
  225.  *             "path": "/V4/quotes/{id}/regenerate",
  226.  *             "controller": "App\V4\Action\Quote\RegenerateQuoteAction",
  227.  *             "swagger_context": {
  228.  *                  "summary": "Demande de réactualisation de l'offre",
  229.  *                  "description": "Demande de réactualisation de l'offre du devis 'id'",
  230.  *                  "parameters": {
  231.  *                      {
  232.  *                          "in": "path",
  233.  *                          "name": "id",
  234.  *                          "type": "string",
  235.  *                          "required": "true"
  236.  *                      },
  237.  *                      {
  238.  *                          "in": "body",
  239.  *                          "name": "body",
  240.  *                          "schema": {
  241.  *                              "type": "object",
  242.  *                              "properties": {
  243.  *                                  "updatePrice": {"type": "boolean"},
  244.  *                                  "template": {"type": "string", "example": "id_du_template"},
  245.  *                              },
  246.  *                          },
  247.  *                      },
  248.  *                  },
  249.  *              },
  250.  *         },
  251.  *          "regenerate_quote_get": {
  252.  *               "method": "GET",
  253.  *               "path": "/V4/quotes/{id}/regenerate",
  254.  *               "controller": "App\V4\Action\Quote\GetRegenerateQuoteFormAction",
  255.  *               "swagger_context": {
  256.  *                   "summary": "Demande de récupération du formulaire de réactualisation de l'offre",
  257.  *                   "description": "Demande de récupération du formulaire de réactualisation de l'offre du devis 'id'",
  258.  *                   "responses": {
  259.  *                       "200": {
  260.  *                           "description": "Envoi du formulaire de réactualisation de l'offre",
  261.  *                       },
  262.  *                       "404": {
  263.  *                           "description": "Devis introuvable",
  264.  *                       },
  265.  *                   },
  266.  *               },
  267.  *          },
  268.  *         "split_chidren": {
  269.  *             "method": "POST",
  270.  *             "deserialize": false,
  271.  *             "path": "/quotes/{id}/split-children",
  272.  *             "controller": App\V4\Controller\Quote\SplitChildrenAction::class,
  273.  *         },
  274.  *         "get_tasks": {
  275.  *             "method": "GET",
  276.  *             "path": "/v4/quotes/{id}/related-tasks",
  277.  *             "normalization_context": {
  278.  *                  "groups": {"task:list"}
  279.  *             },
  280.  *             "controller": App\V4\Action\Quote\GetRelatedTasksByQuoteAction::class,
  281.  *             "read": false,
  282.  *             "swagger_context": {
  283.  *                 "summary": "Récupert les actions liées au devis",
  284.  *             },
  285.  *         },
  286.  *         "delete_quote": {
  287.  *             "method": "DELETE",
  288.  *             "deserialize": false,
  289.  *             "write": false,
  290.  *             "controller": "App\V4\Controller\Quote\QuoteDataPersisterAction",
  291.  *             "path": "/V4/quotes/{id}"
  292.  *         },
  293.  *         "duplicate_quote": {
  294.  *             "method": "GET",
  295.  *             "path": "/V4/quotes/{quoteId}/form/duplicate",
  296.  *             "controller": "App\V4\Action\Quote\DuplicateQuoteAction::class",
  297.  *             "swagger_context": {
  298.  *                 "summary": "Demande de duplication d'un devis",
  299.  *                 "description": "Demande de création d'un nouveau formulaire devis ayant pour valeur une copie du devis 'quoteId'",
  300.  *                 "parameters": {
  301.  *                     {
  302.  *                         "in": "path",
  303.  *                         "name": "quoteId",
  304.  *                         "type": "string",
  305.  *                         "required": "true"
  306.  *                     }
  307.  *                 },
  308.  *                 "responses": {
  309.  *                     "200": {
  310.  *                         "description": "Création d'un formulaire basé sur le devis à duppliquer réalisé avec succès"
  311.  *                     },
  312.  *                     "500": {
  313.  *                         "description": "Le devis ne peut pas être divisé car il est enfant ou parent d'un autre devis"
  314.  *                     },
  315.  *                     "404": {
  316.  *                         "description": "Devis introuvable"
  317.  *                     },
  318.  *                 },
  319.  *             },
  320.  *         },
  321.  *         "post_expected_signed_at_form": {
  322.  *             "method": "POST",
  323.  *             "path": "/V4/quotes/{id}/expected-signed-at",
  324.  *             "controller": App\V4\Controller\Quote\PostQuoteExpectedSignedAtFormAction::class,
  325.  *             "swagger_context": {
  326.  *                 "summary": "Envoie date de signature pour passage d'un devis en statut Gagné",
  327.  *                 "description": "Demande de soumission du formulaire de date de signature dans le cadre d'une action rapide visant à basculer un devis en statut gagné",
  328.  *                 "parameters": {
  329.  *                     {
  330.  *                         "in": "path",
  331.  *                         "name": "id",
  332.  *                         "type": "string",
  333.  *                         "required": "true"
  334.  *                     },
  335.  *                     {
  336.  *                         "in": "body",
  337.  *                         "name": "body",
  338.  *                         "schema": {
  339.  *                             "type": "object",
  340.  *                             "properties": {
  341.  *                                 "status": {"type": "string", "example": "id_statut_gagne"},
  342.  *                                 "expectedSignedAt": {"type": "string", "example": "2024-03-22T17:50"},
  343.  *                             },
  344.  *                         },
  345.  *                     },
  346.  *                 },
  347.  *             },
  348.  *         },
  349.  *     }
  350.  * )
  351.  *
  352.  * @ApiFilter(App\Filters\PagingFilter::class)
  353.  */
  354. class Quote implements IriNormalizableInterfaceSpecificFieldsAwareInterfaceChildrenAwareInterfaceActionableEntityInterfaceCustomerFileAwareInterface
  355. {
  356.     public const SPECIFIC_FIELD_CLASS_NAME QuoteSpecificField::class;
  357.     public const DEFAULT_POTENTIAL_VALUE 50;
  358.     use TimestampableTrait;
  359.     use BlamableTrait;
  360.     use ImportableObjectTrait;
  361.     use NormalizeAsIRITrait;
  362.     use ProspectRefreshNeededTrait;
  363.     use SpecificFieldAwareTrait;
  364.     /**
  365.      * @var string|null
  366.      *
  367.      * @ApiProperty(identifier=true)
  368.      *
  369.      * @Groups({"quote:list", "quote:read"})
  370.      */
  371.     private $id;
  372.     /**
  373.      * @var string|null
  374.      *
  375.      * @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
  376.      */
  377.     private $externalId;
  378.     /**
  379.      * @var string|null
  380.      */
  381.     private $customerId;
  382.     /**
  383.      * @var ArrayCollection|QuoteLine[]
  384.      *
  385.      * @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
  386.      */
  387.     private $quoteLines;
  388.     /**
  389.      * @var string|null
  390.      *
  391.      * @Assert\NotBlank()
  392.      * @Assert\Length(max=255)
  393.      *
  394.      * @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
  395.      */
  396.     private $name;
  397.     /**
  398.      * @var Prospect|null
  399.      *
  400.      * @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
  401.      * @MaxDepth(1)
  402.      */
  403.     private $prospect;
  404.     /**
  405.      * @var string|null
  406.      *
  407.      * @Assert\NotBlank()
  408.      *
  409.      * @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
  410.      */
  411.     private $prospectId;
  412.     /**
  413.      * @var string|null
  414.      *
  415.      * @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
  416.      */
  417.     private $managedBy;
  418.     /**
  419.      * @var string|null
  420.      *
  421.      * @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
  422.      */
  423.     private $contactId;
  424.     /**
  425.      * @var string|null
  426.      *
  427.      * @Assert\Length(max=4294967295)
  428.      *
  429.      * @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
  430.      */
  431.     private $terms;
  432.     /**
  433.      * @var DateTime|null
  434.      *
  435.      * @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
  436.      */
  437.     private $warrantlyAt;
  438.     /**
  439.      * @var string|null
  440.      *
  441.      * @Assert\Length(max=100)
  442.      *
  443.      * @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
  444.      */
  445.     private $contractNumber;
  446.     /**
  447.      * @var bool|null
  448.      *
  449.      * @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
  450.      */
  451.     private $isMaintenance;
  452.     /**
  453.      * @var string|null
  454.      *
  455.      * @Assert\Length(max=4294967295)
  456.      *
  457.      * @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
  458.      */
  459.     private $comment;
  460.     /**
  461.      * @var DateTime|null
  462.      *
  463.      * @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
  464.      */
  465.     private $issuedAt;
  466.     /**
  467.      * @var float|null
  468.      *
  469.      * @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
  470.      */
  471.     private $potential;
  472.     /**
  473.      * @var string|null
  474.      *
  475.      * @Assert\Length(max=255)
  476.      *
  477.      * @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
  478.      */
  479.     private $quoteNumber;
  480.     /**
  481.      * @var QuoteState|null
  482.      *
  483.      * @Assert\NotBlank()
  484.      *
  485.      * @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
  486.      */
  487.     private $status;
  488.     /**
  489.      * @var string|null
  490.      *
  491.      * @Assert\Length(max=4294967295)
  492.      *
  493.      * @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
  494.      */
  495.     private $description;
  496.     /**
  497.      * @var DateTime|null
  498.      *
  499.      * @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
  500.      */
  501.     private $expectedSignedAt;
  502.     /**
  503.      * @var DateTime|null
  504.      *
  505.      * @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
  506.      */
  507.     private $expiredAt;
  508.     /**
  509.      * @var string|null
  510.      *
  511.      * @Assert\LessThan(99999999)
  512.      *
  513.      * @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
  514.      */
  515.     private $totalExcludingVat;
  516.     /**
  517.      * @var string|null
  518.      *
  519.      * @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
  520.      */
  521.     private $weightedTotal;
  522.     /**
  523.      * @var bool|null
  524.      *
  525.      * @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
  526.      */
  527.     private $isSalesForecast true;
  528.     /**
  529.      * @var CustomerFile[]|Collection
  530.      *
  531.      * @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
  532.      */
  533.     private $customerFiles = [];
  534.     /**
  535.      * @var string|null
  536.      *
  537.      * @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
  538.      */
  539.     private $sectionName;
  540.     /**
  541.      * @var SpecificField[]|Collection
  542.      *
  543.      * @Groups({"quote:list", "quote:read", "quote:write", "quote:update"})
  544.      */
  545.     private $specificFields;
  546.     /**
  547.      * @var Quote|null
  548.      *
  549.      * @Groups({"quote:list", "quote:read", "quote:write"})
  550.      */
  551.     private $parent;
  552.     /**
  553.      * @var Quote[]|Collection
  554.      *
  555.      * @Groups({"quote:list", "quote:read"})
  556.      */
  557.     private $children;
  558.     /**
  559.      * @var QuoteTaskExternalRef[]|Collection
  560.      *
  561.      * @Groups({"quote:read", "quote:write", "quote:update"})
  562.      */
  563.     private $tasks;
  564.     /**
  565.      * @var string|null
  566.      *
  567.      * @Groups({"quote:list"})
  568.      */
  569.     private $prospectFullName;
  570.     /**
  571.      * @var string|null
  572.      *
  573.      * @Groups({"quote:list"})
  574.      */
  575.     private $contactIdRealName;
  576.     /**
  577.      * @var string|null
  578.      */
  579.     private $managedByRealName;
  580.     /**
  581.      * @var QuoteReason|null
  582.      * @MaxDepth(1)
  583.      * @Groups({"list", "write_post_quote", "quote:read", "quote:write", "quote:update"})
  584.      */
  585.     private $reason;
  586.     /**
  587.      * @var string|null
  588.      *
  589.      * @Assert\Length(max=4294967295)
  590.      * @Groups({"list", "write_post_quote", "quote:read", "quote:write", "quote:update"})
  591.      */
  592.     private $reasonComment;
  593.     public function __construct()
  594.     {
  595.         $this->specificFields = new ArrayCollection();
  596.         $this->quoteLines = new ArrayCollection();
  597.         $this->children = new ArrayCollection();
  598.         $this->tasks = new ArrayCollection();
  599.     }
  600.     /**
  601.      * @return float
  602.      */
  603.     public function getTotalIncludingVat(): float
  604.     {
  605.         $total 0;
  606.         foreach ($this->quoteLines as $quoteLine) {
  607.             $total += (float) $quoteLine->getTotal();
  608.         }
  609.         return $total;
  610.     }
  611.     /**
  612.      * @return array The total vat amount by percentage
  613.      */
  614.     public function getTotalVatByPercentage(): array
  615.     {
  616.         $totalVatByPercentage = [];
  617.         foreach ($this->quoteLines as $quoteLine) {
  618.             $vatPercentage $quoteLine->getVatRate();
  619.             if (!isset($totalVatByPercentage[$vatPercentage])) {
  620.                 $totalVatByPercentage[$vatPercentage] = 0;
  621.             }
  622.             $totalVatByPercentage[$vatPercentage] += $quoteLine->getVatAmount();
  623.         }
  624.         return $totalVatByPercentage;
  625.     }
  626.     /**
  627.      * @return float
  628.      */
  629.     public function getTotalDiscount(): float
  630.     {
  631.         $total 0;
  632.         foreach ($this->quoteLines as $quoteLine) {
  633.             $total += (float) $quoteLine->getDiscountAmount();
  634.         }
  635.         return $total;
  636.     }
  637.     /**
  638.      * @return float
  639.      */
  640.     public function getTotalExcludingVatBeforeDiscount(): float
  641.     {
  642.         $total 0;
  643.         foreach ($this->quoteLines as $quoteLine) {
  644.             $total += (float) $quoteLine->getTotalExclDiscountAndVat();
  645.         }
  646.         return $total;
  647.     }
  648.     /**
  649.      * @return bool
  650.      *
  651.      * @Assert\Callback()
  652.      */
  653.     public function validateReason(): bool
  654.     {
  655.         if (!$this->reason || !$this->status) {
  656.             return true;
  657.         }
  658.         if ($this->reason->getQuoteState() !== $this->status) {
  659.             return false;
  660.         }
  661.         return true;
  662.     }
  663.     /**
  664.      * @param string $name
  665.      *
  666.      * @return string
  667.      */
  668.     public function getSectionTotal(string $name): string
  669.     {
  670.         $sum 0;
  671.         foreach ($this->getQuoteLines() as $quoteLine) {
  672.             if ($name !== $quoteLine->getSectionName()) {
  673.                 continue;
  674.             }
  675.             $sum += floatval($quoteLine->getTotal());
  676.         }
  677.         return $sum;
  678.     }
  679.     /**
  680.      * @param string $sectionName
  681.      *
  682.      * @return QuoteLine[]
  683.      */
  684.     public function getQuoteLinesForSection(string $sectionName): array
  685.     {
  686.         $quoteLines = [];
  687.         foreach ($this->getQuoteLines() as $quoteLine) {
  688.             if ($sectionName === $quoteLine->getSectionName()) {
  689.                 $quoteLines[] = $quoteLine;
  690.             }
  691.         }
  692.         return $quoteLines;
  693.     }
  694.     /**
  695.      * {@inheritdoc}
  696.      */
  697.     public function isSplit(): bool
  698.     {
  699.         return $this->isParent() || $this->isChild();
  700.     }
  701.     /**
  702.      * @return void
  703.      */
  704.     public function getSplitType(): ?string
  705.     {
  706.         if ($this->isParent()) {
  707.             return 'parent';
  708.         }
  709.         if ($this->isChild()) {
  710.             return 'child';
  711.         }
  712.         return null;
  713.     }
  714.     /**
  715.      * {@inheritdoc}
  716.      */
  717.     public function isParent(): bool
  718.     {
  719.         return !$this->getChildren()->isEmpty();
  720.     }
  721.     /**
  722.      * {@inheritdoc}
  723.      */
  724.     public function isChild(): bool
  725.     {
  726.         return $this->getParent() instanceof Quote;
  727.     }
  728.     /**
  729.      * @return Quote[]|Collection
  730.      */
  731.     public function getSiblings(): Collection
  732.     {
  733.         if (!$this->isChild()) {
  734.             return new ArrayCollection();
  735.         }
  736.         $siblings = [];
  737.         foreach ($this->getParent()->getChildren() as $child) {
  738.             if ($child->getId() !== $this->getId()) {
  739.                 $siblings[] = $child;
  740.             }
  741.         }
  742.         return new ArrayCollection($siblings);
  743.     }
  744.     /**
  745.      * @return bool
  746.      */
  747.     public function isLate(): bool
  748.     {
  749.         return $this->getStatus() && $this->getStatus()->getInProgress() && $this->getExpectedSignedAt() < new DateTime();
  750.     }
  751.     /**
  752.      * @return bool
  753.      */
  754.     public function isWon(): bool
  755.     {
  756.         return $this->getStatus() instanceof QuoteState && $this->getStatus()->getIsWon();
  757.     }
  758.     /**
  759.      * @return string[]
  760.      */
  761.     public function getAllSectionNames(): array
  762.     {
  763.         $sectionsNames = [];
  764.         foreach ($this->getQuoteLines() as $quoteLine) {
  765.             if (!empty($quoteLine->getSectionName()) && !in_array($quoteLine->getSectionName(), $sectionsNamestrue)) {
  766.                 $sectionsNames[] = $quoteLine->getSectionName();
  767.             }
  768.         }
  769.         return $sectionsNames;
  770.     }
  771.     public function getCurrentPdfVersion(): int
  772.     {
  773.         if (empty($this->getCustomerFiles())) {
  774.             return 1;
  775.         }
  776.         $version 0;
  777.         foreach ($this->getCustomerFiles() as $customerFile) {
  778.             if ($version $customerFile->getVersionNumber()) {
  779.                 $version $customerFile->getVersionNumber();
  780.             }
  781.         }
  782.         return $version 1;
  783.     }
  784.     public function getTemplateId(): ?string
  785.     {
  786.         $customerFiles array_filter($this->getCustomerFiles(), static function ($cf) {
  787.             return $cf->isQuotePdf();
  788.         });
  789.         usort($customerFiles, static function (CustomerFile $aCustomerFile $b) {
  790.             return $a->getUpdatedAt() < $b->getUpdatedAt();
  791.         });
  792.         if (empty($customerFiles)) {
  793.             return null;
  794.         }
  795.         return $customerFiles[0]->getTemplateId();
  796.     }
  797.     /**
  798.      * @return string
  799.      */
  800.     public function getId(): ?string
  801.     {
  802.         return $this->id;
  803.     }
  804.     /**
  805.      * @param string|null $id
  806.      *
  807.      * @return Quote
  808.      */
  809.     public function setId(?string $id): Quote
  810.     {
  811.         $this->id $id;
  812.         return $this;
  813.     }
  814.     /**
  815.      * @return string|null
  816.      */
  817.     public function getExternalId(): ?string
  818.     {
  819.         return $this->externalId;
  820.     }
  821.     /**
  822.      * @param string|null $externalId
  823.      *
  824.      * @return Quote
  825.      */
  826.     public function setExternalId(?string $externalId): self
  827.     {
  828.         $this->externalId $externalId;
  829.         return $this;
  830.     }
  831.     /**
  832.      * @return Collection|QuoteLine[]
  833.      */
  834.     public function getQuoteLines(): Collection
  835.     {
  836.         return $this->quoteLines;
  837.     }
  838.     /**
  839.      * @param QuoteLine $quoteLine
  840.      *
  841.      * @return self
  842.      */
  843.     public function addQuoteLine(QuoteLine $quoteLine): self
  844.     {
  845.         if (!$this->quoteLines->contains($quoteLine)) {
  846.             $quoteLine->setQuote($this);
  847.             $this->quoteLines->add($quoteLine);
  848.         }
  849.         return $this;
  850.     }
  851.     /**
  852.      * @param Collection|QuoteLine[] $quoteLines
  853.      *
  854.      * @return self
  855.      */
  856.     public function setQuoteLines(Collection $quoteLines): self
  857.     {
  858.         $this->quoteLines $quoteLines;
  859.         return $this;
  860.     }
  861.     /**
  862.      * @param QuoteLine $quoteLine
  863.      *
  864.      * @return self
  865.      */
  866.     public function removeQuoteLine(QuoteLine $quoteLine): self
  867.     {
  868.         if ($this->quoteLines->contains($quoteLine)) {
  869.             $this->quoteLines->removeElement($quoteLine);
  870.         }
  871.         return $this;
  872.     }
  873.     /**
  874.      * @return string|null
  875.      */
  876.     public function getName(): ?string
  877.     {
  878.         return $this->name;
  879.     }
  880.     /**
  881.      * @param string|null $name
  882.      *
  883.      * @return Quote
  884.      */
  885.     public function setName(?string $name): Quote
  886.     {
  887.         $this->name $name;
  888.         return $this;
  889.     }
  890.     /**
  891.      * @return string|null
  892.      */
  893.     public function getCustomerId(): ?string
  894.     {
  895.         return $this->customerId;
  896.     }
  897.     /**
  898.      * @param string|null $customerId
  899.      *
  900.      * @return Quote
  901.      */
  902.     public function setCustomerId(?string $customerId): Quote
  903.     {
  904.         $this->customerId $customerId;
  905.         return $this;
  906.     }
  907.     /**
  908.      * @return string|null
  909.      */
  910.     public function getManagedBy(): ?string
  911.     {
  912.         return $this->managedBy;
  913.     }
  914.     /**
  915.      * @param string|null $managedBy
  916.      *
  917.      * @return Quote
  918.      */
  919.     public function setManagedBy(?string $managedBy): Quote
  920.     {
  921.         $this->managedBy $managedBy;
  922.         return $this;
  923.     }
  924.     /**
  925.      * @return DateTime|null
  926.      */
  927.     public function getIssuedAt(): ?DateTime
  928.     {
  929.         return $this->issuedAt;
  930.     }
  931.     /**
  932.      * @param DateTime|null $issuedAt
  933.      *
  934.      * @return Quote
  935.      */
  936.     public function setIssuedAt(?DateTime $issuedAt): Quote
  937.     {
  938.         $this->issuedAt $issuedAt;
  939.         return $this;
  940.     }
  941.     /**
  942.      * @return float|null
  943.      */
  944.     public function getPotential(): ?float
  945.     {
  946.         return $this->potential;
  947.     }
  948.     /**
  949.      * @param float|null $potential
  950.      *
  951.      * @return Quote
  952.      */
  953.     public function setPotential(?float $potential): Quote
  954.     {
  955.         $this->potential $potential;
  956.         return $this;
  957.     }
  958.     /**
  959.      * @return QuoteState|null
  960.      */
  961.     public function getStatus(): ?QuoteState
  962.     {
  963.         return $this->status;
  964.     }
  965.     /**
  966.      * @param QuoteState|null $status
  967.      *
  968.      * @return Quote
  969.      */
  970.     public function setStatus(?QuoteState $status): Quote
  971.     {
  972.         $this->status $status;
  973.         return $this;
  974.     }
  975.     /**
  976.      * @return DateTime|null
  977.      */
  978.     public function getExpectedSignedAt(): ?DateTime
  979.     {
  980.         return $this->expectedSignedAt;
  981.     }
  982.     /**
  983.      * @param DateTime|null $expectedSignedAt
  984.      *
  985.      * @return Quote
  986.      */
  987.     public function setExpectedSignedAt(?DateTime $expectedSignedAt): Quote
  988.     {
  989.         $this->expectedSignedAt $expectedSignedAt;
  990.         return $this;
  991.     }
  992.     /**
  993.      * @return string|null
  994.      */
  995.     public function getTotalExcludingVat(): ?string
  996.     {
  997.         return $this->totalExcludingVat;
  998.     }
  999.     /**
  1000.      * @param string|null $totalExcludingVat
  1001.      *
  1002.      * @return Quote
  1003.      */
  1004.     public function setTotalExcludingVat(?string $totalExcludingVat): Quote
  1005.     {
  1006.         $this->totalExcludingVat $totalExcludingVat;
  1007.         return $this;
  1008.     }
  1009.     /**
  1010.      * @return bool|null
  1011.      */
  1012.     public function getIsSalesForecast(): ?bool
  1013.     {
  1014.         return $this->isSalesForecast;
  1015.     }
  1016.     /**
  1017.      * @param bool|null $isSalesForecast
  1018.      *
  1019.      * @return Quote
  1020.      */
  1021.     public function setIsSalesForecast(?bool $isSalesForecast): Quote
  1022.     {
  1023.         $this->isSalesForecast $isSalesForecast;
  1024.         return $this;
  1025.     }
  1026.     /**
  1027.      * @return Prospect|null
  1028.      */
  1029.     public function getProspect(): ?Prospect
  1030.     {
  1031.         return $this->prospect;
  1032.     }
  1033.     /**
  1034.      * @param Prospect|null $prospect
  1035.      *
  1036.      * @return Quote
  1037.      */
  1038.     public function setProspect(?Prospect $prospect): Quote
  1039.     {
  1040.         $this->prospect $prospect;
  1041.         return $this;
  1042.     }
  1043.     /**
  1044.      * @return string|null
  1045.      */
  1046.     public function getProspectId(): ?string
  1047.     {
  1048.         return $this->prospectId;
  1049.     }
  1050.     /**
  1051.      * @param string|null $prospectId
  1052.      *
  1053.      * @return Quote
  1054.      */
  1055.     public function setProspectId(?string $prospectId): self
  1056.     {
  1057.         $this->prospectId $prospectId;
  1058.         return $this;
  1059.     }
  1060.     /**
  1061.      * @return string|null
  1062.      */
  1063.     public function getQuoteNumber(): ?string
  1064.     {
  1065.         return $this->quoteNumber;
  1066.     }
  1067.     /**
  1068.      * @param string|null $quoteNumber
  1069.      *
  1070.      * @return Quote
  1071.      */
  1072.     public function setQuoteNumber(?string $quoteNumber): Quote
  1073.     {
  1074.         $this->quoteNumber $quoteNumber;
  1075.         return $this;
  1076.     }
  1077.     /**
  1078.      * @return DateTime|null
  1079.      */
  1080.     public function getExpiredAt(): ?DateTime
  1081.     {
  1082.         return $this->expiredAt;
  1083.     }
  1084.     /**
  1085.      * @param DateTime|null $expiredAt
  1086.      *
  1087.      * @return Quote
  1088.      */
  1089.     public function setExpiredAt(?DateTime $expiredAt): Quote
  1090.     {
  1091.         $this->expiredAt $expiredAt;
  1092.         return $this;
  1093.     }
  1094.     /**
  1095.      * @return string|null
  1096.      */
  1097.     public function getDescription(): ?string
  1098.     {
  1099.         return $this->description;
  1100.     }
  1101.     /**
  1102.      * @param string|null $description
  1103.      *
  1104.      * @return Quote
  1105.      */
  1106.     public function setDescription(?string $description): Quote
  1107.     {
  1108.         $this->description $description;
  1109.         return $this;
  1110.     }
  1111.     /**
  1112.      * @return string|null
  1113.      */
  1114.     public function getContactId(): ?string
  1115.     {
  1116.         return $this->contactId;
  1117.     }
  1118.     /**
  1119.      * @param string|null $contactId
  1120.      *
  1121.      * @return Quote
  1122.      */
  1123.     public function setContactId(?string $contactId): Quote
  1124.     {
  1125.         $this->contactId $contactId;
  1126.         return $this;
  1127.     }
  1128.     /**
  1129.      * @return string|null
  1130.      */
  1131.     public function getTerms(): ?string
  1132.     {
  1133.         return $this->terms;
  1134.     }
  1135.     /**
  1136.      * @param string|null $terms
  1137.      *
  1138.      * @return Quote
  1139.      */
  1140.     public function setTerms(?string $terms): Quote
  1141.     {
  1142.         $this->terms $terms;
  1143.         return $this;
  1144.     }
  1145.     /**
  1146.      * @return DateTime|null
  1147.      */
  1148.     public function getWarrantlyAt(): ?DateTime
  1149.     {
  1150.         return $this->warrantlyAt;
  1151.     }
  1152.     /**
  1153.      * @param DateTime|null $warrantlyAt
  1154.      *
  1155.      * @return Quote
  1156.      */
  1157.     public function setWarrantlyAt(?DateTime $warrantlyAt): Quote
  1158.     {
  1159.         $this->warrantlyAt $warrantlyAt;
  1160.         return $this;
  1161.     }
  1162.     /**
  1163.      * @return string|null
  1164.      */
  1165.     public function getContractNumber(): ?string
  1166.     {
  1167.         return $this->contractNumber;
  1168.     }
  1169.     /**
  1170.      * @param string|null $contractNumber
  1171.      *
  1172.      * @return Quote
  1173.      */
  1174.     public function setContractNumber(?string $contractNumber): Quote
  1175.     {
  1176.         $this->contractNumber $contractNumber;
  1177.         return $this;
  1178.     }
  1179.     /**
  1180.      * @return bool|null
  1181.      */
  1182.     public function getIsMaintenance(): ?bool
  1183.     {
  1184.         return $this->isMaintenance;
  1185.     }
  1186.     /**
  1187.      * @param bool|null $isMaintenance
  1188.      *
  1189.      * @return Quote
  1190.      */
  1191.     public function setIsMaintenance(?bool $isMaintenance): Quote
  1192.     {
  1193.         $this->isMaintenance $isMaintenance;
  1194.         return $this;
  1195.     }
  1196.     /**
  1197.      * @return string|null
  1198.      */
  1199.     public function getComment(): ?string
  1200.     {
  1201.         return $this->comment;
  1202.     }
  1203.     /**
  1204.      * @param string|null $comment
  1205.      *
  1206.      * @return Quote
  1207.      */
  1208.     public function setComment(?string $comment): Quote
  1209.     {
  1210.         $this->comment $comment;
  1211.         return $this;
  1212.     }
  1213.     /**
  1214.      * @Groups({"list", "write_post_quote"})
  1215.      *
  1216.      * @return string|null
  1217.      */
  1218.     public function getCreatedBy(): ?string
  1219.     {
  1220.         return $this->createdBy;
  1221.     }
  1222.     /**
  1223.      * @param string|null $createdBy
  1224.      *
  1225.      * @return Quote
  1226.      */
  1227.     public function setCreatedBy(?string $createdBy): Quote
  1228.     {
  1229.         $this->createdBy $createdBy;
  1230.         return $this;
  1231.     }
  1232.     /**
  1233.      * @Groups({"list", "write_post_quote"})
  1234.      *
  1235.      * @return string|null
  1236.      */
  1237.     public function getUpdatedBy(): ?string
  1238.     {
  1239.         return $this->updatedBy;
  1240.     }
  1241.     /**
  1242.      * @param string|null $updatedBy
  1243.      *
  1244.      * @return Quote
  1245.      */
  1246.     public function setUpdatedBy(?string $updatedBy): Quote
  1247.     {
  1248.         $this->updatedBy $updatedBy;
  1249.         return $this;
  1250.     }
  1251.     /**
  1252.      * @Groups({"list", "write_post_quote"})
  1253.      *
  1254.      * @return DateTime|null
  1255.      */
  1256.     public function getCreatedAt(): ?DateTime
  1257.     {
  1258.         return $this->createdAt;
  1259.     }
  1260.     /**
  1261.      * @param DateTime|null $createdAt
  1262.      *
  1263.      * @return Quote
  1264.      */
  1265.     public function setCreatedAt(?DateTime $createdAt): Quote
  1266.     {
  1267.         $this->createdAt $createdAt;
  1268.         return $this;
  1269.     }
  1270.     /**
  1271.      * @Groups({"list", "write_post_quote"})
  1272.      *
  1273.      * @return DateTime|null
  1274.      */
  1275.     public function getUpdatedAt(): ?DateTime
  1276.     {
  1277.         return $this->updatedAt;
  1278.     }
  1279.     /**
  1280.      * @param DateTime|null $updatedAt
  1281.      *
  1282.      * @return Quote
  1283.      */
  1284.     public function setUpdatedAt(?DateTime $updatedAt): Quote
  1285.     {
  1286.         $this->updatedAt $updatedAt;
  1287.         return $this;
  1288.     }
  1289.     /**
  1290.      * @return CustomerFile[]
  1291.      */
  1292.     public function getCustomerFiles()
  1293.     {
  1294.         return $this->customerFiles ?: [];
  1295.     }
  1296.     /**
  1297.      * @param CustomerFile $customerFile
  1298.      *
  1299.      * @return Quote
  1300.      */
  1301.     public function addCustomerFile(CustomerFile $customerFile): self
  1302.     {
  1303.         $this->customerFiles[] = $customerFile;
  1304.         return $this;
  1305.     }
  1306.     /**
  1307.      * @param CustomerFile $customerFile
  1308.      *
  1309.      * @return Quote
  1310.      */
  1311.     public function removeCustomerFile(CustomerFile $customerFile): self
  1312.     {
  1313.         $index array_search($customerFile$this->customerFilestrue);
  1314.         if (false !== $index) {
  1315.             unset($this->customerFiles[$index]);
  1316.         }
  1317.         return $this;
  1318.     }
  1319.     /**
  1320.      * @param CustomerFile[] $customerFiles
  1321.      *
  1322.      * @return Quote
  1323.      */
  1324.     public function setCustomerFiles(array $customerFiles): self
  1325.     {
  1326.         $this->customerFiles $customerFiles;
  1327.         return $this;
  1328.     }
  1329.     /**
  1330.      * {@inheritdoc}
  1331.      */
  1332.     public function getSpecificFields(): Collection
  1333.     {
  1334.         return $this->specificFields;
  1335.     }
  1336.     /**
  1337.      * {@inheritdoc}
  1338.      */
  1339.     public function getSpecificFieldByFieldId(string $id): ?SpecificField
  1340.     {
  1341.         foreach ($this->specificFields as $specificField) {
  1342.             if ($specificField->getFieldId() === $id) {
  1343.                 return $specificField;
  1344.             }
  1345.         }
  1346.         return null;
  1347.     }
  1348.     /**
  1349.      * @see ImportableObjectTrait::class
  1350.      *
  1351.      * @param QuoteSpecificField $specificField
  1352.      *
  1353.      * @return $this
  1354.      */
  1355.     public function addQuoteSpecificField(QuoteSpecificField $specificField): self
  1356.     {
  1357.         return $this->addSpecificField($specificField);
  1358.     }
  1359.     /**
  1360.      * {@inheritdoc}
  1361.      */
  1362.     public function addSpecificField($specificField): SpecificFieldsAwareInterface
  1363.     {
  1364.         $this->specificFields[] = $specificField;
  1365.         return $this;
  1366.     }
  1367.     /**
  1368.      * {@inheritdoc}
  1369.      */
  1370.     public function setSpecificFields(Collection $specificFields): self
  1371.     {
  1372.         $this->specificFields $specificFields;
  1373.         return $this;
  1374.     }
  1375.     /**
  1376.      * @return string|null
  1377.      */
  1378.     public function getWeightedTotal(): ?string
  1379.     {
  1380.         return $this->weightedTotal;
  1381.     }
  1382.     /**
  1383.      * @param string|null $weightedTotal
  1384.      *
  1385.      * @return Quote
  1386.      */
  1387.     public function setWeightedTotal(?string $weightedTotal): Quote
  1388.     {
  1389.         $this->weightedTotal $weightedTotal;
  1390.         return $this;
  1391.     }
  1392.     /**
  1393.      * @return string|null
  1394.      */
  1395.     public function getSectionName(): ?string
  1396.     {
  1397.         return $this->sectionName;
  1398.     }
  1399.     /**
  1400.      * @param string|null $sectionName
  1401.      *
  1402.      * @return Quote
  1403.      */
  1404.     public function setSectionName(?string $sectionName): Quote
  1405.     {
  1406.         $this->sectionName $sectionName;
  1407.         return $this;
  1408.     }
  1409.     /**
  1410.      * @return Quote|null
  1411.      */
  1412.     public function getParent(): ?self
  1413.     {
  1414.         return $this->parent;
  1415.     }
  1416.     /**
  1417.      * @param Quote|null $parent
  1418.      *
  1419.      * @return self
  1420.      */
  1421.     public function setParent(?self $parent): self
  1422.     {
  1423.         $this->parent $parent;
  1424.         return $this;
  1425.     }
  1426.     /**
  1427.      * {@inheritdoc}
  1428.      */
  1429.     public function getChildren(): Collection
  1430.     {
  1431.         return $this->children;
  1432.     }
  1433.     /**
  1434.      * @param Quote[]|Collection $children
  1435.      *
  1436.      * @return self
  1437.      */
  1438.     public function setChildren($children): self
  1439.     {
  1440.         //@todo : trouver le moyen de serializer le self pour récupérer devis1->parent->children qui contient devis1 (iri renvoyé actuellement donc ignoré)
  1441.         if ($children instanceof Collection) {
  1442.             $this->children $children;
  1443.         }
  1444.         return $this;
  1445.     }
  1446.     /**
  1447.      * @deprecated Use addChild() instead.
  1448.      *     This is stupid, but the ImportableObjectTrait checks for adders using add.ucfirst($type) where $type is the class name.
  1449.      *
  1450.      * @param Quote $child
  1451.      *
  1452.      * @return $this
  1453.      */
  1454.     public function addQuote(Quote $child): self
  1455.     {
  1456.         return $this->addChild($child);
  1457.     }
  1458.     /**
  1459.      * @param Quote $child
  1460.      *
  1461.      * @return $this
  1462.      */
  1463.     public function addChild(Quote $child): self
  1464.     {
  1465.         if (!$this->children->contains($child)) {
  1466.             $this->children[] = $child;
  1467.             $child->setParent($this);
  1468.         }
  1469.         return $this;
  1470.     }
  1471.     /**
  1472.      * @param Quote $child
  1473.      *
  1474.      * @return $this
  1475.      */
  1476.     public function removeChildren(Quote $child): self
  1477.     {
  1478.         if ($this->children->contains($child)) {
  1479.             $this->children->removeElement($child);
  1480.             $child->setParent(null);
  1481.         }
  1482.         return $this;
  1483.     }
  1484.     /**
  1485.      * @param string $taskId
  1486.      *
  1487.      * @return bool
  1488.      */
  1489.     public function hasTask(string $taskId): bool
  1490.     {
  1491.         foreach ($this->tasks as $task) {
  1492.             if ($taskId === $task->getExternalValue()) {
  1493.                 return true;
  1494.             }
  1495.         }
  1496.         return false;
  1497.     }
  1498.     /**
  1499.      * @return QuoteTaskExternalRef[]|Collection
  1500.      */
  1501.     public function getTasks(): Collection
  1502.     {
  1503.         return $this->tasks;
  1504.     }
  1505.     /**
  1506.      * @param QuoteTaskExternalRef[]|Collection $tasks
  1507.      *
  1508.      * @return self
  1509.      */
  1510.     public function setTasks(Collection $tasks): self
  1511.     {
  1512.         $this->tasks $tasks;
  1513.         return $this;
  1514.     }
  1515.     /**
  1516.      * @param QuoteTaskExternalRef $task
  1517.      *
  1518.      * @return self
  1519.      */
  1520.     public function addTask(QuoteTaskExternalRef $task): self
  1521.     {
  1522.         if (!$this->tasks->contains($task)) {
  1523.             $this->tasks->add($task);
  1524.         }
  1525.         return $this;
  1526.     }
  1527.     /**
  1528.      * Redondance avec addTask dû au ImportableObjectTrait.
  1529.      *
  1530.      * @param QuoteTaskExternalRef $task
  1531.      *
  1532.      * @return self
  1533.      */
  1534.     public function addQuoteTaskExternalRef(QuoteTaskExternalRef $task): self
  1535.     {
  1536.         return $this->addTask($task);
  1537.     }
  1538.     /**
  1539.      * @param QuoteTaskExternalRef $task
  1540.      *
  1541.      * @return self
  1542.      */
  1543.     public function removeTask(QuoteTaskExternalRef $task): self
  1544.     {
  1545.         if ($this->tasks->contains($task)) {
  1546.             $this->tasks->remove($task);
  1547.         }
  1548.         return $this;
  1549.     }
  1550.     /**
  1551.      * @return QuoteReason|null
  1552.      */
  1553.     public function getReason(): ?QuoteReason
  1554.     {
  1555.         return $this->reason;
  1556.     }
  1557.     /**
  1558.      * @param QuoteReason|null $reason
  1559.      *
  1560.      * @return Quote
  1561.      */
  1562.     public function setReason(?QuoteReason $reason): Quote
  1563.     {
  1564.         $this->reason $reason;
  1565.         return $this;
  1566.     }
  1567.     /**
  1568.      * @return string|null
  1569.      */
  1570.     public function getReasonComment(): ?string
  1571.     {
  1572.         return $this->reasonComment;
  1573.     }
  1574.     /**
  1575.      * @param string|null $reasonComment
  1576.      *
  1577.      * @return Quote
  1578.      */
  1579.     public function setReasonComment(?string $reasonComment): Quote
  1580.     {
  1581.         $this->reasonComment $reasonComment;
  1582.         return $this;
  1583.     }
  1584.     /**
  1585.      * @return string|null
  1586.      */
  1587.     public function getProspectFullName(): ?string
  1588.     {
  1589.         return $this->prospectFullName;
  1590.     }
  1591.     /**
  1592.      * @param string|null $prospectFullName
  1593.      *
  1594.      * @return Quote
  1595.      */
  1596.     public function setProspectFullName(?string $prospectFullName): self
  1597.     {
  1598.         $this->prospectFullName $prospectFullName;
  1599.         return $this;
  1600.     }
  1601.     /**
  1602.      * @return string|null
  1603.      */
  1604.     public function getContactIdRealName(): ?string
  1605.     {
  1606.         return $this->contactIdRealName;
  1607.     }
  1608.     /**
  1609.      * @param string|null $contactIdRealName
  1610.      *
  1611.      * @return Quote
  1612.      */
  1613.     public function setContactIdRealName(?string $contactIdRealName): self
  1614.     {
  1615.         $this->contactIdRealName $contactIdRealName;
  1616.         return $this;
  1617.     }
  1618.     /**
  1619.      * @return string
  1620.      */
  1621.     public function getManagedByRealName(): ?string
  1622.     {
  1623.         return $this->managedByRealName;
  1624.     }
  1625.     /**
  1626.      * @param string $managedByRealName
  1627.      *
  1628.      * @return Quote
  1629.      */
  1630.     public function setManagedByRealName(?string $managedByRealName): Quote
  1631.     {
  1632.         $this->managedByRealName $managedByRealName;
  1633.         return $this;
  1634.     }
  1635.     /**
  1636.      * @param string|null $taskId
  1637.      *
  1638.      * @return void
  1639.      */
  1640.     public function removeQuoteTaskExternalRefByExternalValue(?string $taskId)
  1641.     {
  1642.         foreach ($this->tasks as $task) {
  1643.             if ($taskId === $task->getExternalValue()) {
  1644.                 $this->removeTask($task);
  1645.             }
  1646.         }
  1647.     }
  1648. }