src/Model/Product/Product.php line 212

Open in your IDE?
  1. <?php
  2. namespace App\Model\Product;
  3. use ApiPlatform\Core\Annotation\ApiFilter;
  4. use ApiPlatform\Core\Annotation\ApiProperty;
  5. use ApiPlatform\Core\Annotation\ApiResource;
  6. use App\Model\Category\Category;
  7. use App\Model\CustomerFile\CustomerFile;
  8. use App\Model\IriNormalizableInterface;
  9. use App\Model\NormalizeAsIRITrait;
  10. use App\Model\Params\Params;
  11. use App\Model\ProductSpecificField\ProductSpecificField;
  12. use App\Model\SpecificField\SpecificField;
  13. use App\Model\SpecificFieldAwareTrait;
  14. use App\Model\SpecificFieldsAwareInterface;
  15. use App\Model\Traits\ImportableObjectTrait;
  16. use App\Model\Traits\TimestampableTrait;
  17. use App\Model\Unit\Unit;
  18. use App\Model\Vat\Vat;
  19. use App\Model\Warranty\Warranty;
  20. use App\V4\Entity\ActionableEntityInterface;
  21. use App\V4\Model\CustomerFileAwareInterface;
  22. use App\V4\Model\ProductConfiguration\ProductConfiguration;
  23. use Doctrine\Common\Collections\ArrayCollection;
  24. use Doctrine\Common\Collections\Collection;
  25. use Symfony\Component\Serializer\Annotation\Groups;
  26. use Symfony\Component\Serializer\Annotation\MaxDepth;
  27. use Symfony\Component\Serializer\Annotation\SerializedName;
  28. use Symfony\Component\Validator\Constraints as Assert;
  29. //Ici le formulaire d'édition est en POST, car il nécessite du form-data qui ne fonctionne pas avec PATCH ou PUT
  30. /**
  31.  * @ApiResource(
  32.  *     attributes={
  33.  *         "api_allow_update": true
  34.  *     },
  35.  *     collectionOperations={
  36.  *         "get": {
  37.  *             "normalization_context": {
  38.  *                  "groups": {"product:list"}
  39.  *             },
  40.  *             "security": "is_granted(constant('App\\Voters\\ProductVoter::PRODUCT_SHOW_LIST'), 'App\Voters\ProductVoter')"
  41.  *         },
  42.  *         "post": {
  43.  *             "deserialize": false,
  44.  *             "write": false,
  45.  *             "controller": "App\Controller\Product\ProductDataPersisterAction",
  46.  *             "input_formats": {
  47.  *                 "multipart": {"multipart/form-data"}
  48.  *             },
  49.  *             "normalization_context": {
  50.  *                  "groups": {"product:read"}
  51.  *             },
  52.  *             "denormalization_context": {
  53.  *                  "groups": {}
  54.  *             }
  55.  *         },
  56.  *         "get_form": {
  57.  *             "method": "GET",
  58.  *             "path": "/products/form",
  59.  *             "controller": App\Controller\Product\GetProductFormAction::class
  60.  *         },
  61.  *         "get_search": {
  62.  *             "method": "GET",
  63.  *             "path": "/products/search/form",
  64.  *             "controller": App\Controller\Product\GetProductSearchFormAction::class,
  65.  *         },
  66.  *         "post_search": {
  67.  *             "method": "POST",
  68.  *             "deserialize": false,
  69.  *             "path": "/products/search/form",
  70.  *             "normalization_context": {
  71.  *                  "groups": {"product:list"}
  72.  *             },
  73.  *             "controller": App\Controller\Product\PostProductSearchFormAction::class,
  74.  *             "validate": false,
  75.  *         },
  76.  *         "post_export_request": {
  77.  *              "method": "POST",
  78.  *              "path": "/v4/export/product",
  79.  *              "controller": App\V4\Action\Export\EntityExportRequestAction::class,
  80.  *              "swagger_context": {
  81.  *                  "summary": "Demande de création d'export de produits",
  82.  *                  "description": "Demande de création d'export de produits où 'ids' sont les ids des produits et 'fields' les champs souhaités",
  83.  *                  "parameters": {
  84.  *                      {
  85.  *                          "in": "body",
  86.  *                          "name": "body",
  87.  *                          "schema": {
  88.  *                              "type": "object",
  89.  *                              "properties": {
  90.  *                                  "ids": {
  91.  *                                      "type": "array",
  92.  *                                      "items": {"type": "string"}
  93.  *                                  },
  94.  *                                  "fields": {
  95.  *                                       "type": "array",
  96.  *                                       "items": {"type": "string"}
  97.  *                                  }
  98.  *                              }
  99.  *                          }
  100.  *                      }
  101.  *                  },
  102.  *                  "responses": {
  103.  *                      "201": {
  104.  *                          "description": "Création de l'export avec succès",
  105.  *                          "schema": {
  106.  *                              "type": "object",
  107.  *                              "properties": {
  108.  *                                  "message": {"type": "string", "example": "export_request_created"},
  109.  *                              }
  110.  *                          }
  111.  *                      },
  112.  *                      "400": {
  113.  *                          "description": "Utilisateur non trouvé ou champs 'fields' ou 'ids' manquant dans le body request",
  114.  *                          "schema": {
  115.  *                              "type": "object",
  116.  *                              "properties": {
  117.  *                                  "message": {"type": "string", "example": "user_not_found or missing_fields_or_ids"},
  118.  *                              }
  119.  *                          }
  120.  *                      },
  121.  *                      "422": {
  122.  *                          "description": "Les champs 'fields' ou 'ids' du body request sont vides ou l'entité demandée est invalide",
  123.  *                          "schema": {
  124.  *                              "type": "object",
  125.  *                              "properties": {
  126.  *                                  "message": {"type": "string", "example": "empty_fields_or_ids or entity_not_valid"},
  127.  *                              }
  128.  *                          }
  129.  *                      },
  130.  *                  },
  131.  *              }
  132.  *          },
  133.  *          "post_export_download": {
  134.  *              "method": "POST",
  135.  *              "path": "/v4/export/download/product/{id}",
  136.  *              "controller": App\V4\Action\Export\EntityExportDownloadAction::class,
  137.  *              "swagger_context": {
  138.  *                  "summary": "Demande de téléchargement d'un export produits",
  139.  *                  "description": "Demande de téléchargement d'un export produits ou 'id' est le nom du fichier d'export",
  140.  *                  "requestBody": {},
  141.  *                  "parameters": {
  142.  *                      {
  143.  *                          "in": "path",
  144.  *                          "name": "id",
  145.  *                          "type": "string",
  146.  *                          "required": "true"
  147.  *                      }
  148.  *                  },
  149.  *                  "responses": {
  150.  *                      "200": {
  151.  *                          "description": "Téléchargement de l'export réalisé avec succès"
  152.  *                      },
  153.  *                      "401": {
  154.  *                          "description": "Utilisateur non trouvé ou non connecté",
  155.  *                          "schema": {
  156.  *                              "type": "object",
  157.  *                              "properties": {
  158.  *                                  "message": {"type": "string", "example": "need_authenticated"},
  159.  *                              }
  160.  *                          }
  161.  *                      },
  162.  *                      "404": {
  163.  *                          "description": "Fichier introuvable",
  164.  *                          "schema": {
  165.  *                              "type": "object",
  166.  *                              "properties": {
  167.  *                                  "message": {"type": "string", "example": "export_not_found"},
  168.  *                              }
  169.  *                          }
  170.  *                      },
  171.  *                  },
  172.  *              }
  173.  *          }
  174.  *     },
  175.  *     itemOperations={
  176.  *         "get": {
  177.  *             "normalization_context": {
  178.  *                  "groups": {"product:read"}
  179.  *             },
  180.  *             "security": "is_granted(constant('App\\Voters\\ProductVoter::PRODUCT_ADD_EDIT'), 'App\Voters\ProductVoter')"
  181.  *         },
  182.  *         "get_form": {
  183.  *             "method": "GET",
  184.  *             "path": "/products/{id}/form",
  185.  *             "controller": App\Controller\Product\GetProductFormAction::class
  186.  *         },
  187.  *         "put": {
  188.  *             "deserialize": false,
  189.  *             "write": false,
  190.  *             "method": "POST",
  191.  *             "controller": "App\Controller\Product\ProductDataPersisterAction",
  192.  *             "input_formats": {
  193.  *                 "multipart": {"multipart/form-data"}
  194.  *             },
  195.  *             "normalization_context": {
  196.  *                  "groups": {"product:read"}
  197.  *             },
  198.  *             "denormalization_context": {
  199.  *                  "groups": {}
  200.  *             }
  201.  *         },
  202.  *         "delete"
  203.  *     }
  204.  * )
  205.  *
  206.  * @ApiFilter(App\Filters\PagingFilter::class)
  207.  */
  208. class Product implements IriNormalizableInterfaceSpecificFieldsAwareInterfaceActionableEntityInterfaceCustomerFileAwareInterface
  209. {
  210.     public const SPECIFIC_FIELD_CLASS_NAME ProductSpecificField::class;
  211.     public const SUBSCRIPTION_UNIT_HOUR 'hours';
  212.     public const SUBSCRIPTION_UNIT_DAY 'days';
  213.     public const SUBSCRIPTION_UNIT_MONTH 'months';
  214.     public const SUBSCRIPTION_UNIT_YEAR 'years';
  215.     public const SUBSCRIPTION_UNITS = [
  216.         self::SUBSCRIPTION_UNIT_HOUR,
  217.         self::SUBSCRIPTION_UNIT_DAY,
  218.         self::SUBSCRIPTION_UNIT_MONTH,
  219.         self::SUBSCRIPTION_UNIT_YEAR,
  220.     ];
  221.     use TimestampableTrait;
  222.     use ImportableObjectTrait;
  223.     use NormalizeAsIRITrait;
  224.     use SpecificFieldAwareTrait;
  225.     /**
  226.      * @var string|null
  227.      *
  228.      * @ApiProperty(identifier=true)
  229.      * @Groups({"list", "product:list", "product:read"})
  230.      */
  231.     private $id;
  232.     /**
  233.      * @var string|null
  234.      *
  235.      * @Groups({"product:list", "product:read"})
  236.      */
  237.     private $externalId;
  238.     /**
  239.      * @var string|null
  240.      */
  241.     private $customerId;
  242.     /**
  243.      * @var Vat|null
  244.      *
  245.      * @Groups({"product:list", "product:read", "product:write", "product:update"})
  246.      */
  247.     private $vat;
  248.     /**
  249.      * @var Unit|null
  250.      *
  251.      * @Groups({"product:list", "product:read", "product:write", "product:update"})
  252.      */
  253.     private $unit;
  254.     /**
  255.      * @var Category[]|null
  256.      *
  257.      * @Groups({"list", "product:list", "product:read", "product:write", "product:update"})
  258.      * @MaxDepth(1)
  259.      */
  260.     private $categories;
  261.     /**
  262.      * @var Warranty|null
  263.      *
  264.      * @Groups({"product:list", "product:read", "product:write", "product:update"})
  265.      */
  266.     private $warranty;
  267.     /**
  268.      * @var SpecificField[]|Collection
  269.      *
  270.      * @Groups({"product:list", "product:read", "product:write", "product:update"})
  271.      */
  272.     private $specificFields;
  273.     /**
  274.      * @var string|null
  275.      *
  276.      * @Assert\Length(max="255")
  277.      * @Assert\NotBlank()
  278.      *
  279.      * @Groups({"list", "product:list", "product:read", "product:write", "product:update"})
  280.      */
  281.     private $name;
  282.     /**
  283.      * @var string|null
  284.      *
  285.      * @Assert\Length(max="255")
  286.      *
  287.      * @Groups({"list", "product:list", "product:read", "product:write", "product:update"})
  288.      */
  289.     private $shortDescription;
  290.     /**
  291.      * @var string|null
  292.      *
  293.      * @Assert\Length(max="255")
  294.      *
  295.      * @Groups({"list", "product:list", "product:read", "product:write", "product:update"})
  296.      */
  297.     private $reference;
  298.     /**
  299.      * @var string|null
  300.      *
  301.      * @Groups({"product:list", "product:read", "product:write", "product:update"})
  302.      */
  303.     private $priceExcludingVat;
  304.     /**
  305.      * @var string|null
  306.      *
  307.      * @Groups({"product:list", "product:read", "product:write", "product:update"})
  308.      */
  309.     private $sellingPriceExcludingVat;
  310.     /**
  311.      * @var string|null
  312.      *
  313.      * @Groups({"product:list", "product:read", "product:write", "product:update"})
  314.      */
  315.     private $imageId;
  316.     /**
  317.      * @var CustomerFile|null
  318.      *
  319.      * @Groups({"product:list", "product:read", "product:write", "product:update"})
  320.      */
  321.     private $imageFile;
  322.     /**
  323.      * @var string|null
  324.      *
  325.      * @Assert\Length(max="255")
  326.      *
  327.      * @Groups({"product:list", "product:read", "product:write", "product:update"})
  328.      */
  329.     private $serialNumber;
  330.     /**
  331.      * @var bool
  332.      *
  333.      * @Groups({"product:list", "product:read", "product:write", "product:update"})
  334.      */
  335.     private $isComponent false;
  336.     /**
  337.      * @var int|null
  338.      *
  339.      * @Assert\GreaterThan(0)
  340.      *
  341.      * @Groups({"product:list", "product:read", "product:write", "product:update"})
  342.      */
  343.     private $stockQty 1;
  344.     /**
  345.      * @var CustomerFile[]
  346.      *
  347.      * @Groups({"product:list", "product:read", "product:write", "product:update"})
  348.      */
  349.     private $customerFiles;
  350.     /**
  351.      * @var ProductConfiguration|null
  352.      *
  353.      * @Groups({"list", "product:list", "product:read", "product:write", "product:update"})
  354.      */
  355.     private $productConfiguration;
  356.     /**
  357.      * @var int|null
  358.      *
  359.      * @Groups({
  360.      *     "list",
  361.      *     "product:list", "product:read",
  362.      *     "product:write", "product:update",
  363.      * })
  364.      */
  365.     private $subscriptionValue;
  366.     /**
  367.      * @var string|null
  368.      *
  369.      * @Groups({
  370.      *     "list",
  371.      *     "product:list", "product:read",
  372.      *     "product:write", "product:update",
  373.      * })
  374.      */
  375.     private $subscriptionUnit;
  376.     /**
  377.      * @var string|null
  378.      *
  379.      * @Groups({
  380.      *     "list",
  381.      *     "product:list", "product:read",
  382.      *     "product:write", "product:update",
  383.      * })
  384.      */
  385.     private $quoteSection;
  386.     /**
  387.      * @var string|null
  388.      *
  389.      * @Groups({
  390.      *      "list",
  391.      *      "product:list", "product:read",
  392.      *      "product:write", "product:update",
  393.      *  })
  394.      */
  395.     private $description;
  396.     public function __construct()
  397.     {
  398.         $this->specificFields = new ArrayCollection();
  399.         $this->categories = new ArrayCollection();
  400.     }
  401.     /**
  402.      * @Assert\IsTrue(message="subscription_unit_empty_and_not_value");
  403.      **/
  404.     public function isCorrectSubscriptionValueAndUnit(): bool
  405.     {
  406.         if (!$this->isSubscriptionProduct()) {
  407.             return true;
  408.         }
  409.         return null !== $this->subscriptionValue && null !== $this->subscriptionUnit;
  410.     }
  411.     /**
  412.      * @return bool
  413.      */
  414.     public function isSubscriptionProduct(): bool
  415.     {
  416.         return null !== $this->subscriptionValue || null !== $this->subscriptionUnit;
  417.     }
  418.     /**
  419.      * @return string
  420.      */
  421.     public function getId(): ?string
  422.     {
  423.         return $this->id;
  424.     }
  425.     /**
  426.      * @param string|null $id
  427.      *
  428.      * @return self
  429.      */
  430.     public function setId(?string $id): self
  431.     {
  432.         $this->id $id;
  433.         return $this;
  434.     }
  435.     /**
  436.      * @return string|null
  437.      */
  438.     public function getExternalId(): ?string
  439.     {
  440.         return $this->externalId;
  441.     }
  442.     /**
  443.      * @param string|null $externalId
  444.      *
  445.      * @return self
  446.      */
  447.     public function setExternalId(?string $externalId): self
  448.     {
  449.         $this->externalId $externalId;
  450.         return $this;
  451.     }
  452.     /**
  453.      * @return string|null
  454.      */
  455.     public function getCustomerId(): ?string
  456.     {
  457.         return $this->customerId;
  458.     }
  459.     /**
  460.      * @param string $customerId
  461.      *
  462.      * @return self
  463.      */
  464.     public function setCustomerId(string $customerId): self
  465.     {
  466.         $this->customerId $customerId;
  467.         return $this;
  468.     }
  469.     /**
  470.      * @return Params|null
  471.      */
  472.     public function getVat(): ?Params
  473.     {
  474.         return $this->vat;
  475.     }
  476.     /**
  477.      * @param Params|null $vat
  478.      *
  479.      * @return self
  480.      */
  481.     public function setVat(?Params $vat): self
  482.     {
  483.         $this->vat $vat;
  484.         return $this;
  485.     }
  486.     /**
  487.      * @return Params|null
  488.      */
  489.     public function getUnit(): ?Params
  490.     {
  491.         return $this->unit;
  492.     }
  493.     /**
  494.      * @param Params|null $unit
  495.      *
  496.      * @return self
  497.      */
  498.     public function setUnit(?Params $unit): self
  499.     {
  500.         $this->unit $unit;
  501.         return $this;
  502.     }
  503.     /**
  504.      * @return Collection|Category[]
  505.      */
  506.     public function getCategories(): Collection
  507.     {
  508.         return $this->categories;
  509.     }
  510.     /**
  511.      * @param Collection|Category[] $categories
  512.      *
  513.      * @return $this
  514.      */
  515.     public function setCategories(Collection $categories): self
  516.     {
  517.         $this->categories $categories;
  518.         return $this;
  519.     }
  520.     /**
  521.      * @param Category $category
  522.      *
  523.      * @return $this
  524.      */
  525.     public function addCategory(Category $category): self
  526.     {
  527.         if (!$this->categories->contains($category)) {
  528.             $this->categories[] = $category;
  529.             $category->addProduct($this);
  530.         }
  531.         return $this;
  532.     }
  533.     /**
  534.      * @param Category $category
  535.      *
  536.      * @return $this
  537.      */
  538.     public function removeCategory(Category $category): self
  539.     {
  540.         if ($this->categories->contains($category)) {
  541.             $this->categories->removeElement($category);
  542.             $category->removeProduct($this);
  543.         }
  544.         return $this;
  545.     }
  546.     /**
  547.      * @return Params|null
  548.      */
  549.     public function getWarranty(): ?Params
  550.     {
  551.         return $this->warranty;
  552.     }
  553.     /**
  554.      * @param Params|null $warranty
  555.      *
  556.      * @return self
  557.      */
  558.     public function setWarranty(?Params $warranty): self
  559.     {
  560.         $this->warranty $warranty;
  561.         return $this;
  562.     }
  563.     /**
  564.      * {@inheritdoc}
  565.      */
  566.     public function getSpecificFields(): Collection
  567.     {
  568.         return $this->specificFields;
  569.     }
  570.     /**
  571.      * {@inheritdoc}
  572.      */
  573.     public function getSpecificFieldByFieldId(string $id): ?SpecificField
  574.     {
  575.         foreach ($this->specificFields as $specificField) {
  576.             if ($specificField->getFieldId() === $id) {
  577.                 return $specificField;
  578.             }
  579.         }
  580.         return null;
  581.     }
  582.     /**
  583.      * @param ProductSpecificField $specificField
  584.      *
  585.      * @return $this
  586.      *
  587.      * @see ImportableObjectTrait::class
  588.      */
  589.     public function addProductSpecificField(ProductSpecificField $specificField): self
  590.     {
  591.         return $this->addSpecificField($specificField);
  592.     }
  593.     /**
  594.      * {@inheritdoc}
  595.      */
  596.     public function addSpecificField($specificField): SpecificFieldsAwareInterface
  597.     {
  598.         $this->specificFields[] = $specificField;
  599.         return $this;
  600.     }
  601.     /**
  602.      * {@inheritdoc}
  603.      */
  604.     public function setSpecificFields(Collection $specificFields): self
  605.     {
  606.         $this->specificFields $specificFields;
  607.         return $this;
  608.     }
  609.     /**
  610.      * @return string|null
  611.      */
  612.     public function getName(): ?string
  613.     {
  614.         return $this->name;
  615.     }
  616.     /**
  617.      * @param string|null $name
  618.      *
  619.      * @return self
  620.      */
  621.     public function setName(?string $name): self
  622.     {
  623.         $this->name $name;
  624.         return $this;
  625.     }
  626.     /**
  627.      * @return string|null
  628.      */
  629.     public function getShortDescription(): ?string
  630.     {
  631.         return $this->shortDescription;
  632.     }
  633.     /**
  634.      * @param string|null $shortDescription
  635.      *
  636.      * @return Product
  637.      */
  638.     public function setShortDescription(?string $shortDescription): Product
  639.     {
  640.         $this->shortDescription $shortDescription;
  641.         return $this;
  642.     }
  643.     /**
  644.      * @return string|null
  645.      */
  646.     public function getReference(): ?string
  647.     {
  648.         return $this->reference;
  649.     }
  650.     /**
  651.      * @param string|null $reference
  652.      *
  653.      * @return self
  654.      */
  655.     public function setReference(?string $reference): self
  656.     {
  657.         $this->reference $reference;
  658.         return $this;
  659.     }
  660.     /**
  661.      * @return string|null
  662.      */
  663.     public function getPriceExcludingVat(): ?string
  664.     {
  665.         return $this->priceExcludingVat;
  666.     }
  667.     /**
  668.      * @param string|null $priceExcludingVat
  669.      *
  670.      * @return self
  671.      */
  672.     public function setPriceExcludingVat(?string $priceExcludingVat): self
  673.     {
  674.         $this->priceExcludingVat $priceExcludingVat;
  675.         return $this;
  676.     }
  677.     /**
  678.      * @return string|null
  679.      */
  680.     public function getSellingPriceExcludingVat(): ?string
  681.     {
  682.         return $this->sellingPriceExcludingVat;
  683.     }
  684.     /**
  685.      * @param string|null $sellingPriceExcludingVat
  686.      *
  687.      * @return self
  688.      */
  689.     public function setSellingPriceExcludingVat(?string $sellingPriceExcludingVat): self
  690.     {
  691.         $this->sellingPriceExcludingVat $sellingPriceExcludingVat;
  692.         return $this;
  693.     }
  694.     /**
  695.      * @return string|null
  696.      */
  697.     public function getImageId(): ?string
  698.     {
  699.         return $this->imageId;
  700.     }
  701.     /**
  702.      * @param string|null $imageId
  703.      *
  704.      * @return self
  705.      */
  706.     public function setImageId(?string $imageId): self
  707.     {
  708.         $this->imageId $imageId;
  709.         return $this;
  710.     }
  711.     /**
  712.      * @return CustomerFile|null
  713.      */
  714.     public function getImageFile(): ?CustomerFile
  715.     {
  716.         return $this->imageFile;
  717.     }
  718.     /**
  719.      * @param CustomerFile|null $imageFile
  720.      *
  721.      * @return Product
  722.      */
  723.     public function setImageFile(?CustomerFile $imageFile): self
  724.     {
  725.         $this->imageFile $imageFile;
  726.         return $this;
  727.     }
  728.     /**
  729.      * @TODO: PV-746: Find a better way
  730.      *
  731.      * @SerializedName("imageUrl")
  732.      * @Groups({"list", "product:list", "product:read"})
  733.      *
  734.      * @return string
  735.      */
  736.     public function getImageUrl(): ?string
  737.     {
  738.         if ($this->imageId) {
  739.             return '/api/logo/'.$this->imageId;
  740.         }
  741.         return null;
  742.     }
  743.     /**
  744.      * @return string|null
  745.      */
  746.     public function getSerialNumber(): ?string
  747.     {
  748.         return $this->serialNumber;
  749.     }
  750.     /**
  751.      * @param string|null $serialNumber
  752.      *
  753.      * @return self
  754.      */
  755.     public function setSerialNumber(?string $serialNumber): self
  756.     {
  757.         $this->serialNumber $serialNumber;
  758.         return $this;
  759.     }
  760.     /**
  761.      * @return bool
  762.      */
  763.     public function isComponent(): bool
  764.     {
  765.         return $this->isComponent;
  766.     }
  767.     /**
  768.      * @param bool $isComponent
  769.      *
  770.      * @return self
  771.      */
  772.     public function setIsComponent(bool $isComponent): self
  773.     {
  774.         $this->isComponent $isComponent;
  775.         return $this;
  776.     }
  777.     /**
  778.      * @return int|null
  779.      */
  780.     public function getStockQty(): ?int
  781.     {
  782.         return $this->stockQty;
  783.     }
  784.     /**
  785.      * @param int|null $stockQty
  786.      *
  787.      * @return self
  788.      */
  789.     public function setStockQty(?int $stockQty): self
  790.     {
  791.         $this->stockQty $stockQty;
  792.         return $this;
  793.     }
  794.     /**
  795.      * @return CustomerFile[]
  796.      */
  797.     public function getCustomerFiles()
  798.     {
  799.         return $this->customerFiles;
  800.     }
  801.     /**
  802.      * @param CustomerFile $customerFile
  803.      *
  804.      * @return $this
  805.      */
  806.     public function addCustomerFile(CustomerFile $customerFile): self
  807.     {
  808.         $this->customerFiles[] = $customerFile;
  809.         return $this;
  810.     }
  811.     /**
  812.      * @param CustomerFile $customerFile
  813.      *
  814.      * @return self
  815.      */
  816.     public function removeCustomerFile(CustomerFile $customerFile): self
  817.     {
  818.         $index array_search($customerFile$this->customerFilestrue);
  819.         if (false !== $index) {
  820.             unset($this->customerFiles[$index]);
  821.         }
  822.         return $this;
  823.     }
  824.     /**
  825.      * @param CustomerFile[] $customerFiles
  826.      *
  827.      * @return Product
  828.      */
  829.     public function setCustomerFiles(array $customerFiles): self
  830.     {
  831.         $this->customerFiles $customerFiles;
  832.         return $this;
  833.     }
  834.     /**
  835.      * @return ProductConfiguration|null
  836.      */
  837.     public function getProductConfiguration(): ?ProductConfiguration
  838.     {
  839.         return $this->productConfiguration;
  840.     }
  841.     /**
  842.      * @param ProductConfiguration|null $productConfiguration
  843.      *
  844.      * @return Product
  845.      */
  846.     public function setProductConfiguration(?ProductConfiguration $productConfiguration): self
  847.     {
  848.         $this->productConfiguration $productConfiguration;
  849.         return $this;
  850.     }
  851.     /**
  852.      * @return int|null
  853.      */
  854.     public function getSubscriptionValue(): ?int
  855.     {
  856.         return $this->subscriptionValue;
  857.     }
  858.     /**
  859.      * @param int|null $subscriptionValue
  860.      *
  861.      * @return self
  862.      */
  863.     public function setSubscriptionValue(?int $subscriptionValue): self
  864.     {
  865.         $this->subscriptionValue $subscriptionValue;
  866.         return $this;
  867.     }
  868.     /**
  869.      * @return string|null
  870.      */
  871.     public function getSubscriptionUnit(): ?string
  872.     {
  873.         return $this->subscriptionUnit;
  874.     }
  875.     /**
  876.      * @param string|null $subscriptionUnit
  877.      *
  878.      * @return self
  879.      */
  880.     public function setSubscriptionUnit(?string $subscriptionUnit): self
  881.     {
  882.         $this->subscriptionUnit $subscriptionUnit;
  883.         return $this;
  884.     }
  885.     /**
  886.      * @return string|null
  887.      */
  888.     public function getQuoteSection(): ?string
  889.     {
  890.         return $this->quoteSection;
  891.     }
  892.     /**
  893.      * @param string|null $quoteSection
  894.      *
  895.      * @return Product
  896.      */
  897.     public function setQuoteSection(?string $quoteSection): self
  898.     {
  899.         $this->quoteSection $quoteSection;
  900.         return $this;
  901.     }
  902.     /**
  903.      * @Groups({
  904.      *     "quote:read"
  905.      * })
  906.      *
  907.      * @return bool
  908.      */
  909.     public function isConfigurable(): bool
  910.     {
  911.         return $this->getProductConfiguration() instanceof ProductConfiguration;
  912.     }
  913.     /**
  914.      * @return string|null
  915.      */
  916.     public function getDescription(): ?string
  917.     {
  918.         return $this->description;
  919.     }
  920.     /**
  921.      * @param string|null $description
  922.      *
  923.      * @return $this
  924.      */
  925.     public function setDescription(?string $description): self
  926.     {
  927.         $this->description $description;
  928.         return $this;
  929.     }
  930. }