src/Entity/Garages/Garage.php line 64

Open in your IDE?
  1. <?php
  2. namespace App\Entity\Garages;
  3. use ApiPlatform\Core\Annotation\ApiFilter;
  4. use ApiPlatform\Core\Annotation\ApiProperty;
  5. use ApiPlatform\Core\Annotation\ApiResource;
  6. use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\BooleanFilter;
  7. use App\Annotation\SiteAware;
  8. use App\Entity\AbstractBase;
  9. use App\Entity\Address;
  10. use App\Entity\Interfaces\CodeInterface;
  11. use App\Entity\Interfaces\ImageInterface;
  12. use App\Entity\Interfaces\PublishedInterface;
  13. use App\Entity\Interfaces\SiteInterface;
  14. use App\Entity\Interfaces\SlugInterface;
  15. use App\Entity\MiniAbstractBase;
  16. use App\Entity\Promotions\LocalPromotion;
  17. use App\Entity\Province;
  18. use App\Entity\PurchaseTracking\GaragePurchase;
  19. use App\Entity\Traits\HasImageTrait;
  20. use App\Entity\Traits\NameTrait;
  21. use App\Entity\Traits\PhoneTrait;
  22. use App\Entity\Traits\PublishedTrait;
  23. use App\Entity\Traits\SiteTrait;
  24. use App\Entity\Traits\SlugTrait;
  25. use App\Entity\User;
  26. use App\Enum\SiteEnum;
  27. use App\Repository\Garages\GarageRepository;
  28. use Doctrine\Common\Collections\ArrayCollection;
  29. use Doctrine\Common\Collections\Collection;
  30. use Doctrine\ORM\Mapping as ORM;
  31. use Gedmo\Mapping\Annotation as Gedmo;
  32. use Symfony\Component\HttpFoundation\File\File;
  33. use Symfony\Component\Security\Core\User\UserInterface;
  34. use Symfony\Component\Serializer\Annotation\Groups;
  35. use Symfony\Component\Validator\Constraints as Assert;
  36. use Symfony\Component\Validator\Constraints\Callback;
  37. use Symfony\Component\Validator\Context\ExecutionContextInterface;
  38. use Symfony\Component\Validator\Mapping\ClassMetadata;
  39. use Vich\UploaderBundle\Mapping\Annotation as Vich;
  40. /**
  41.  * @ApiResource(
  42.  *     shortName="garage",
  43.  *     normalizationContext={"groups"={"api:read", "garage:read"}, "swagger_definition_name"="Read"},
  44.  *     denormalizationContext={"groups"={"garage:write"}, "swagger_definition_name"="Write"},
  45.  *     collectionOperations={"get"},
  46.  *     itemOperations={"get", "put"}
  47.  * )
  48.  *
  49.  * @ApiFilter(BooleanFilter::class, properties={"published"})
  50.  *
  51.  * @ORM\Table(name="vulco_garage", indexes={@ORM\Index(name="garage_site_idx", columns={"site"})}, uniqueConstraints={@ORM\UniqueConstraint(name="garage_site_slug_idx", columns={"site", "slug"})})
  52.  *
  53.  * @ORM\Entity(repositoryClass=GarageRepository::class)
  54.  *
  55.  * @Gedmo\SoftDeleteable(fieldName="removedAt", timeAware=false)
  56.  *
  57.  * @SiteAware(siteFieldName="site")
  58.  *
  59.  * @Vich\Uploadable
  60.  */
  61. class Garage extends AbstractBase implements CodeInterfaceImageInterfacePublishedInterfaceSiteInterfaceSlugInterface
  62. {
  63.     use HasImageTrait;
  64.     use NameTrait;
  65.     use PhoneTrait;
  66.     use PublishedTrait;
  67.     use SiteTrait;
  68.     use SlugTrait;
  69.     public const DEFAULT_POINTS_LIMIT 4800.0;
  70.     /**
  71.      * @ApiProperty(identifier=false)
  72.      *
  73.      * @ORM\Id
  74.      *
  75.      * @ORM\GeneratedValue
  76.      *
  77.      * @ORM\Column(type="integer")
  78.      *
  79.      * @Groups({"api:read"})
  80.      */
  81.     protected int $id;
  82.     /**
  83.      * @Vich\UploadableField(mapping="garage_image", fileNameProperty="imageName")
  84.      */
  85.     private ?File $image null;
  86.     /**
  87.      * @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="garages")
  88.      *
  89.      * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
  90.      */
  91.     private ?User $owner null;
  92.     /**
  93.      * @ORM\OneToOne(targetEntity="App\Entity\Address", cascade={"persist"}, orphanRemoval=true, fetch="EAGER")
  94.      *
  95.      * @ORM\JoinColumn(name="address_id", referencedColumnName="id")
  96.      */
  97.     private Address $address;
  98.     /**
  99.      * @ORM\OneToOne(targetEntity="App\Entity\Garages\GarageSchedules", cascade={"persist"}, orphanRemoval=true, fetch="EAGER")
  100.      *
  101.      * @ORM\JoinColumn(name="schedules_id", referencedColumnName="id")
  102.      */
  103.     private GarageSchedules $schedules;
  104.     /**
  105.      * @ORM\ManyToMany(targetEntity="App\Entity\Garages\GarageService")
  106.      *
  107.      * @ORM\JoinTable(name="vulco_garage_to_service_relation",
  108.      *     joinColumns={@ORM\JoinColumn(name="garage_id", referencedColumnName="id")},
  109.      *     inverseJoinColumns={@ORM\JoinColumn(name="garage_service_id", referencedColumnName="id")}
  110.      * )
  111.      */
  112.     private ?Collection $services;
  113.     /**
  114.      * @ORM\ManyToMany(targetEntity="App\Entity\Garages\GarageFacility")
  115.      *
  116.      * @ORM\JoinTable(name="vulco_garage_to_facility_relation",
  117.      *     joinColumns={@ORM\JoinColumn(name="garage_id", referencedColumnName="id")},
  118.      *     inverseJoinColumns={@ORM\JoinColumn(name="garage_facility_id", referencedColumnName="id")}
  119.      * )
  120.      */
  121.     private ?Collection $facilities;
  122.     /**
  123.      * @ORM\OneToMany(targetEntity="App\Entity\Promotions\LocalPromotion", mappedBy="garage", cascade={"persist", "remove"}, orphanRemoval=true)
  124.      */
  125.     private ?Collection $localPromotions;
  126.     /**
  127.      * @ORM\ManyToMany(targetEntity="App\Entity\Garages\GarageVehicleType")
  128.      *
  129.      * @ORM\JoinTable(name="vulco_garage_vechicle_type_relation",
  130.      *     joinColumns={@ORM\JoinColumn(name="garage_id", referencedColumnName="id")},
  131.      *     inverseJoinColumns={@ORM\JoinColumn(name="vehicle_type_id", referencedColumnName="id")}
  132.      * )
  133.      */
  134.     private ?Collection $typeVehicles;
  135.     /**
  136.      * @ORM\ManyToMany(targetEntity="App\Entity\Address", cascade={"persist", "remove"}, orphanRemoval=true)
  137.      *
  138.      * @ORM\JoinTable(name="vulco_garage_additional_addresses",
  139.      *     joinColumns={@ORM\JoinColumn(name="garage_id", referencedColumnName="id")},
  140.      *     inverseJoinColumns={@ORM\JoinColumn(name="address_id", referencedColumnName="id")}
  141.      * )
  142.      */
  143.     private ?Collection $additionalAddresses;
  144.     /**
  145.      * @ORM\OneToMany(targetEntity="App\Entity\PurchaseTracking\GaragePurchase", mappedBy="garage", orphanRemoval=true)
  146.      */
  147.     private ?Collection $purchases;
  148.     /**
  149.      * @ORM\OneToOne(targetEntity="App\Entity\Garages\GarageAboutUs", orphanRemoval=true, fetch="EAGER", cascade={"persist"})
  150.      *
  151.      * @ORM\JoinColumn(name="garage_about_us_id", referencedColumnName="id")
  152.      */
  153.     private ?GarageAboutUs $aboutUs;
  154.     /**
  155.      * @ORM\OneToOne(targetEntity="App\Entity\Garages\GarageOwner", mappedBy="garage")
  156.      */
  157.     private ?GarageOwner $garageOwner null;
  158.     /**
  159.      * @ORM\Column(type="string", length=255, nullable=false)
  160.      *
  161.      * @Groups({"garage:read"})
  162.      */
  163.     private string $name;
  164.     /**
  165.      * @ApiProperty(identifier=true)
  166.      *
  167.      * @ORM\Column(type="string", length=255, nullable=false, unique=true)
  168.      *
  169.      * @Groups({"garage:read"})
  170.      */
  171.     private string $code;
  172.     /**
  173.      * @ORM\Column(type="string", length=255, nullable=false)
  174.      */
  175.     private string $cif;
  176.     /**
  177.      * @ORM\Column(type="string", length=255, nullable=false)
  178.      *
  179.      * @Gedmo\Slug(fields={"name"}, unique=true)
  180.      */
  181.     private string $slug;
  182.     /**
  183.      * @ORM\Column(type="string", length=255)
  184.      */
  185.     private string $companyName;
  186.     /**
  187.      * @ORM\Column(type="string", length=255, nullable=true)
  188.      */
  189.     private ?string $mobile null;
  190.     /**
  191.      * @ORM\Column(type="string", length=255, nullable=true)
  192.      */
  193.     private ?string $mobileAssociated null;
  194.     /**
  195.      * España (prefijo 34 => 11 caracteres) o Portugal (prefijo 351 => 12 caracteres).
  196.      *
  197.      * @Assert\Regex(pattern="/^\d{11}$|^\d{12}$/")
  198.      *
  199.      * @ORM\Column(type="string", length=255, nullable=true)
  200.      */
  201.     private ?string $whatsapp null;
  202.     /**
  203.      * Móvil con whatsapp para recibir comunicaciones comerciales
  204.      * España (prefijo 34 => 11 caracteres) o Portugal (prefijo 351 => 12 caracteres).
  205.      *
  206.      * @ORM\Column(type="string", length=255, nullable=true, unique=true)
  207.      *
  208.      * @Assert\Regex(pattern="/^\d{11}$|^\d{12}$/")
  209.  *
  210.      */
  211.     private ?string $whatsappCampaigns null;
  212.     /**
  213.      * @ORM\Column(type="string", length=255, nullable=true)
  214.      */
  215.     private ?string $whatsappCampaignsName null;
  216.     /**
  217.      * @ORM\Column(type="string", length=255, nullable=true)
  218.      */
  219.     private ?string $website null;
  220.     /**
  221.      * @ORM\Column(type="string", length=255, nullable=true)
  222.      */
  223.     private ?string $fax null;
  224.     /**
  225.      * @ORM\Column(type="boolean", nullable=true)
  226.      */
  227.     private ?bool $sms null;
  228.     /**
  229.      * @ORM\Column(type="string", length=255, nullable=false)
  230.      *
  231.      * @Assert\Email()
  232.      *
  233.      * @Groups({"garage:read"})
  234.      */
  235.     private string $email;
  236.     /**
  237.      * @ORM\Column(type="text", length=10000, nullable=true)
  238.      */
  239.     private ?string $budgetEmail null;
  240.     /**
  241.      * @ORM\Column(type="text", length=10000, nullable=true)
  242.      */
  243.     private ?string $garageAppointmentNotificationEmails null;
  244.     /**
  245.      * @ORM\Column(type="string", length=255, nullable=true)
  246.      */
  247.     private ?string $timetableMorning null;
  248.     /**
  249.      * @ORM\Column(type="string", length=255, nullable=true)
  250.      */
  251.     private ?string $timetableAfternoon null;
  252.     /**
  253.      * @ORM\Column(type="string", length=255, nullable=true)
  254.      */
  255.     private ?string $timetableSaturday null;
  256.     /**
  257.      * @ORM\Column(type="boolean", nullable=false)
  258.      */
  259.     private bool $worksWithCollective;
  260.     /**
  261.      * @ORM\Column(type="string", length=255, nullable=true)
  262.      */
  263.     private ?string $otherServices null;
  264.     /**
  265.      * @ORM\Column(type="string", length=255, nullable=true)
  266.      */
  267.     private ?string $imageName null;
  268.     /**
  269.      * @ORM\Column(type="string", length=255, nullable=true)
  270.      */
  271.     private ?string $internObservations null;
  272.     /**
  273.      * @ORM\Column(type="boolean", nullable=false, options={"default": 0})
  274.      */
  275.     private bool $maintenancePlansEnabled false;
  276.     /**
  277.      * @ORM\Column(type="array", nullable=true)
  278.      */
  279.     private ?array $maintenancePlans null;
  280.     /**
  281.      * @ORM\Column(type="string", length=255, nullable=true)
  282.      */
  283.     private ?string $garageECImageName null;
  284.     /**
  285.      * @ORM\Column(type="text", length=10000, nullable=true)
  286.      */
  287.     private ?string $garageECImageUrl null;
  288.     /**
  289.      * @ORM\Column(type="text", length=10000, nullable=true)
  290.      */
  291.     private ?string $eCommerceWarningMessage null;
  292.     /**
  293.      * @ORM\Column(type="string", length=255, nullable=true)
  294.      */
  295.     private ?string $legalInformation null;
  296.     /**
  297.      * @ORM\Column(type="string", length=255, nullable=true)
  298.      */
  299.     private ?string $legalInformationCa null;
  300.     /**
  301.      * @ORM\Column(type="text", length=10000, nullable=true)
  302.      */
  303.     private ?string $featuredBox null;
  304.     /**
  305.      * @ORM\Column(type="text", length=10000, nullable=true)
  306.      */
  307.     private ?string $featuredBoxCa null;
  308.     /**
  309.      * @ORM\Column(type="text", length=10000, nullable=true)
  310.      */
  311.     private ?string $facebookUrl null;
  312.     /**
  313.      * @ORM\Column(type="text", length=10000, nullable=true)
  314.      */
  315.     private ?string $twitterUrl null;
  316.     /**
  317.      * @ORM\Column(type="text", length=10000, nullable=true)
  318.      */
  319.     private ?string $instagramUrl null;
  320.     /**
  321.      * @ORM\Column(type="boolean", nullable=false, options={"default": 0})
  322.      */
  323.     private bool $eCommerceWebsite false;
  324.     /**
  325.      * @ORM\Column(type="boolean", nullable=false, options={"default": 0})
  326.      */
  327.     private bool $catalanLanguage false;
  328.     /**
  329.      * @ORM\Column(type="float", nullable=false, options={"default": 4800})
  330.      */
  331.     private float $pointsLimit self::DEFAULT_POINTS_LIMIT;
  332.     /**
  333.      * @ORM\Column(type="string", length=255, nullable=true)
  334.      */
  335.     private ?string $ERP null;
  336.     /**
  337.      * @ORM\Column(type="string", length=255, nullable=true)
  338.      */
  339.     private ?string $gerente null;
  340.     /**
  341.      * @ORM\Column(type="boolean", nullable=false, options={"default": 1})
  342.      */
  343.     private bool $allowBudgetRequest true;
  344.     /**
  345.      * @ORM\Column(type="boolean", nullable=false, options={"default": 1})
  346.      */
  347.     private bool $allowGarageAppointment true;
  348.     /**
  349.      * @ORM\Column(type="boolean", nullable=false, options={"default": 0})
  350.      * The garage has GRIPS software
  351.      */
  352.     private bool $grips false;
  353.     /**
  354.      * @ORM\Column(type="boolean", nullable=false, options={"default": 0})
  355.      * El taller está adherido a la tarifa de Vulco interna para camiones y aparecerá en el mapa del site para camiones
  356.      */
  357.     private bool $vulcoTruckRate false;
  358.     /**
  359.      * @ORM\OneToMany(targetEntity="App\Entity\User", mappedBy="employeeGarage")
  360.      */
  361.     private ?Collection $employees;
  362.     public function __construct()
  363.     {
  364.         $this->services = new ArrayCollection();
  365.         $this->localPromotions = new ArrayCollection();
  366.         $this->facilities = new ArrayCollection();
  367.         $this->typeVehicles = new ArrayCollection();
  368.         $this->additionalAddresses = new ArrayCollection();
  369.         $this->purchases = new ArrayCollection();
  370.         $this->schedules = new GarageSchedules();
  371.         $this->aboutUs = new GarageAboutUs();
  372.         $this->employees = new ArrayCollection();
  373.     }
  374.     public function __clone() {
  375.         if ($this->id) {
  376.             if (!is_null($this->owner)) {
  377.                 $this->owner = clone $this->owner;
  378.             }
  379.             if (!is_null($this->address)) {
  380.                 $this->address = clone $this->address;
  381.             }
  382.             if (!is_null($this->schedules)) {
  383.                 $this->schedules = clone $this->schedules;
  384.             }
  385.             if (!is_null($this->services)) {
  386.                 $this->services = clone $this->services;
  387.             }
  388.             if (!is_null($this->facilities)) {
  389.                 $this->facilities = clone $this->facilities;
  390.             }
  391.             if (!is_null($this->localPromotions)) {
  392.                 $this->localPromotions = clone $this->localPromotions;
  393.             }
  394.             if (!is_null($this->typeVehicles)) {
  395.                 $this->typeVehicles = clone $this->typeVehicles;
  396.             }
  397.             if (!is_null($this->additionalAddresses)) {
  398.                 $additionalAddresses $this->getAdditionalAddresses();
  399.                 $this->additionalAddresses = new ArrayCollection();
  400.                 if (count($additionalAddresses) > 0) {
  401.                     foreach ($additionalAddresses as $address) {
  402.                         $addressClone = clone $address;
  403.                         $this->additionalAddresses->add($addressClone);
  404.                     }
  405.                 }
  406.             }
  407.             if (!is_null($this->purchases)) {
  408.                 $this->purchases = clone $this->purchases;
  409.             }
  410.             if (!is_null($this->aboutUs)) {
  411.                 $this->aboutUs = clone $this->aboutUs;
  412.             }
  413.             if (!is_null($this->garageOwner)) {
  414.                 $this->garageOwner = clone $this->garageOwner;
  415.             }
  416.         }
  417.     }
  418.     public static function loadValidatorMetadata(ClassMetadata $metadata): void
  419.     {
  420.         $metadata->addConstraint(new Callback('validate'));
  421.     }
  422.     public function validate(ExecutionContextInterface $context): void
  423.     {
  424.         $areBudgetEmailsValid $this->internalEmailsValidationCheck($this->getBudgetEmail());
  425.         $areGarageAppointmentNotificationEmailsValid $this->internalEmailsValidationCheck($this->getGarageAppointmentNotificationEmails());
  426.         if (!$areBudgetEmailsValid) {
  427.             $context->buildViolation(SiteEnum::SITE_STR_ES === $this->getSite() ? 'ERROR! Alguna dirección de correo electrónico introducida no es correcta o no están separados por coma.' 'ERRO! Quaisquer endereços de e-mail inseridos não estão corretos ou não estão separados por vírgulas.')
  428.                 ->atPath('budgetEmail')
  429.                 ->addViolation()
  430.             ;
  431.         }
  432.         if (!$areGarageAppointmentNotificationEmailsValid) {
  433.             $context->buildViolation(SiteEnum::SITE_STR_ES === $this->getSite() ? 'ERROR! Alguna dirección de correo electrónico introducida no es correcta o no están separados por coma.' 'ERRO! Quaisquer endereços de e-mail inseridos não estão corretos ou não estão separados por vírgulas.')
  434.                 ->atPath('garageAppointmentNotificationEmails')
  435.                 ->addViolation()
  436.             ;
  437.         }
  438.     }
  439.     private function internalEmailsValidationCheck(?string $internalEmailsString): bool
  440.     {
  441.         $areIneternalEmailsValid true;
  442.         if ($internalEmailsString) {
  443.             $trimmedString trim($internalEmailsString);
  444.             $emailsArray explode(','$trimmedString);
  445.             foreach ($emailsArray as $email) {
  446.                 if (false === filter_var($emailFILTER_VALIDATE_EMAIL)) {
  447.                     $areIneternalEmailsValid false;
  448.                     break;
  449.                 }
  450.             }
  451.         }
  452.         return $areIneternalEmailsValid;
  453.     }
  454.     public function getOwner(): ?User
  455.     {
  456.         return $this->owner;
  457.     }
  458.     public function setOwner(?User $owner): self
  459.     {
  460.         $this->owner $owner;
  461.         return $this;
  462.     }
  463.     public function getAddress(): Address
  464.     {
  465.         return $this->address;
  466.     }
  467.     public function setAddress(Address $address): self
  468.     {
  469.         $this->address $address;
  470.         return $this;
  471.     }
  472.     public function getSchedules(): GarageSchedules
  473.     {
  474.         return $this->schedules;
  475.     }
  476.     public function setSchedules(GarageSchedules $schedules): self
  477.     {
  478.         $this->schedules $schedules;
  479.         return $this;
  480.     }
  481.     public function hasService(GarageService $service): bool
  482.     {
  483.         $result false;
  484.         /** @var GarageService $item */
  485.         foreach ($this->getServices() as $item) {
  486.             if ($service->getId() === $item->getId()) {
  487.                 $result true;
  488.                 break;
  489.             }
  490.         }
  491.         return $result;
  492.     }
  493.     public function getServices(): ?Collection
  494.     {
  495.         return $this->services;
  496.     }
  497.     public function setServices(?Collection $services): self
  498.     {
  499.         $this->services $services;
  500.         return $this;
  501.     }
  502.     public function addService(GarageService $service): self
  503.     {
  504.         if (!$this->services->contains($service)) {
  505.             $this->services->add($service);
  506.         }
  507.         return $this;
  508.     }
  509.     public function removeService(GarageService $service): self
  510.     {
  511.         if ($this->services->contains($service)) {
  512.             $this->services->removeElement($service);
  513.         }
  514.         return $this;
  515.     }
  516.     public function hasFacility(GarageFacility $facility): bool
  517.     {
  518.         $result false;
  519.         /** @var GarageFacility $item */
  520.         foreach ($this->getFacilities() as $item) {
  521.             if ($facility->getId() === $item->getId()) {
  522.                 $result true;
  523.                 break;
  524.             }
  525.         }
  526.         return $result;
  527.     }
  528.     public function getFacilities(): ?Collection
  529.     {
  530.         return $this->facilities;
  531.     }
  532.     public function setFacilities(?Collection $facilities): self
  533.     {
  534.         $this->facilities $facilities;
  535.         return $this;
  536.     }
  537.     public function addFacility(GarageFacility $facility): self
  538.     {
  539.         if (!$this->facilities->contains($facility)) {
  540.             $this->facilities->add($facility);
  541.         }
  542.         return $this;
  543.     }
  544.     public function removeFacility(GarageFacility $facility): self
  545.     {
  546.         if ($this->facilities->contains($facility)) {
  547.             $this->facilities->removeElement($facility);
  548.         }
  549.         return $this;
  550.     }
  551.     public function getLocalPromotions(): ?Collection
  552.     {
  553.         return $this->localPromotions;
  554.     }
  555.     public function setLocalPromotions(?Collection $localPromotions): self
  556.     {
  557.         $this->localPromotions $localPromotions;
  558.         return $this;
  559.     }
  560.     public function addLocalPromotion(LocalPromotion $localPromotion): self
  561.     {
  562.         if (!$this->localPromotions->contains($localPromotion)) {
  563.             $this->localPromotions->add($localPromotion);
  564.         }
  565.         return $this;
  566.     }
  567.     public function removeLocalPromotion(LocalPromotion $localPromotion): self
  568.     {
  569.         if ($this->localPromotions->contains($localPromotion)) {
  570.             $this->localPromotions->removeElement($localPromotion);
  571.         }
  572.         return $this;
  573.     }
  574.     public function hasTypeVehicle(GarageVehicleType $typeVehicle): bool
  575.     {
  576.         $result false;
  577.         /** @var GarageVehicleType $item */
  578.         foreach ($this->getTypeVehicles() as $item) {
  579.             if ($typeVehicle->getId() === $item->getId()) {
  580.                 $result true;
  581.                 break;
  582.             }
  583.         }
  584.         return $result;
  585.     }
  586.     public function getTypeVehicles(): ?Collection
  587.     {
  588.         return $this->typeVehicles;
  589.     }
  590.     public function setTypeVehicles(?Collection $typeVehicles): self
  591.     {
  592.         $this->typeVehicles $typeVehicles;
  593.         return $this;
  594.     }
  595.     public function addTypeVehicle(GarageVehicleType $typeVehicle): self
  596.     {
  597.         if (!$this->typeVehicles->contains($typeVehicle)) {
  598.             $this->typeVehicles->add($typeVehicle);
  599.         }
  600.         return $this;
  601.     }
  602.     public function removeTypeVehicle(GarageVehicleType $typeVehicle): self
  603.     {
  604.         if ($this->typeVehicles->contains($typeVehicle)) {
  605.             $this->typeVehicles->removeElement($typeVehicle);
  606.         }
  607.         return $this;
  608.     }
  609.     public function getAdditionalAddresses(): ?Collection
  610.     {
  611.         return $this->additionalAddresses;
  612.     }
  613.     public function setAdditionalAddresses(?Collection $additionalAddresses): self
  614.     {
  615.         $this->additionalAddresses $additionalAddresses;
  616.         return $this;
  617.     }
  618.     public function addAdditionalAddresses(Address $additionalAddress): self
  619.     {
  620.         if (!$this->additionalAddresses->contains($additionalAddress)) {
  621.             $this->additionalAddresses->add($additionalAddress);
  622.         }
  623.         return $this;
  624.     }
  625.     public function removeAdditionalAddresses(Address $additionalAddress): self
  626.     {
  627.         if ($this->additionalAddresses->contains($additionalAddress)) {
  628.             $this->additionalAddresses->removeElement($additionalAddress);
  629.         }
  630.         return $this;
  631.     }
  632.     public function getPurchases(): ?Collection
  633.     {
  634.         return $this->purchases;
  635.     }
  636.     public function setPurchases(?Collection $purchases): self
  637.     {
  638.         $this->purchases $purchases;
  639.         return $this;
  640.     }
  641.     public function getAboutUs(): ?GarageAboutUs
  642.     {
  643.         return $this->aboutUs;
  644.     }
  645.     public function setAboutUs(?GarageAboutUs $aboutUs): self
  646.     {
  647.         $this->aboutUs $aboutUs;
  648.         return $this;
  649.     }
  650.     public function getGarageOwner(): ?GarageOwner
  651.     {
  652.         return $this->garageOwner;
  653.     }
  654.     public function setGarageOwner(GarageOwner $garageOwner): self
  655.     {
  656.         $this->garageOwner $garageOwner;
  657.         return $this;
  658.     }
  659.     public function getRelatedAddresses(): array
  660.     {
  661.         $result = [];
  662.         $result[] = $this->getAddress();
  663.         /** @var Address $additionalAddress */
  664.         foreach ($this->getAdditionalAddresses() as $additionalAddress) {
  665.             $result[] = $additionalAddress;
  666.         }
  667.         return $result;
  668.     }
  669.     public function isOwner(UserInterface $user): bool
  670.     {
  671.         if ($this->getOwner() && ($user->getId() === $this->getOwner()->getId())) {
  672.             return true;
  673.         }
  674.         return false;
  675.     }
  676.     public function isCoordinator(UserInterface $user): bool
  677.     {
  678.         return $user->getWorkProvinces() && $user->getWorkProvinces()->contains($this->getAddress()->getProvince());
  679.     }
  680.     public function province(): ?Province
  681.     {
  682.         return $this->address->getProvince() ?: null;
  683.     }
  684.     public function provinceName(): ?string
  685.     {
  686.         return $this->province() ? $this->province()->getName() : null;
  687.     }
  688.     public function getCode(): string
  689.     {
  690.         return $this->code;
  691.     }
  692.     public function setCode(string $code): self
  693.     {
  694.         $this->code $code;
  695.         return $this;
  696.     }
  697.     public function getCif(): string
  698.     {
  699.         return $this->cif;
  700.     }
  701.     public function setCif(string $cif): self
  702.     {
  703.         $this->cif $cif;
  704.         return $this;
  705.     }
  706.     public function getCompanyName(): string
  707.     {
  708.         return $this->companyName;
  709.     }
  710.     public function setCompanyName(string $companyName): self
  711.     {
  712.         $this->companyName $companyName;
  713.         return $this;
  714.     }
  715.     public function getMobile(): ?string
  716.     {
  717.         return $this->mobile;
  718.     }
  719.     public function setMobile(?string $mobile): self
  720.     {
  721.         $this->mobile $mobile;
  722.         return $this;
  723.     }
  724.     public function getMobileAssociated(): ?string
  725.     {
  726.         return $this->mobileAssociated;
  727.     }
  728.     public function setMobileAssociated(?string $mobileAssociated): self
  729.     {
  730.         $this->mobileAssociated $mobileAssociated;
  731.         return $this;
  732.     }
  733.     public function getWhatsapp(): ?string
  734.     {
  735.         return $this->whatsapp;
  736.     }
  737.     public function setWhatsapp(?string $whatsapp): self
  738.     {
  739.         $this->whatsapp $whatsapp;
  740.         return $this;
  741.     }
  742.     public function getWhatsappCampaigns(): ?string
  743.     {
  744.         return $this->whatsappCampaigns;
  745.     }
  746.     public function setWhatsappCampaigns(?string $whatsappCampaigns): self
  747.     {
  748.         $this->whatsappCampaigns $whatsappCampaigns;
  749.         return $this;
  750.     }
  751.     public function getWhatsappCampaignsName(): ?string
  752.     {
  753.         return $this->whatsappCampaignsName;
  754.     }
  755.     public function setWhatsappCampaignsName(?string $whatsappCampaignsName): self
  756.     {
  757.         $this->whatsappCampaignsName $whatsappCampaignsName;
  758.         return $this;
  759.     }
  760.     public function getWebsite(): ?string
  761.     {
  762.         return $this->website;
  763.     }
  764.     public function setWebsite(?string $website): self
  765.     {
  766.         $this->website $website;
  767.         return $this;
  768.     }
  769.     public function getFax(): ?string
  770.     {
  771.         return $this->fax;
  772.     }
  773.     public function setFax(?string $fax): self
  774.     {
  775.         $this->fax $fax;
  776.         return $this;
  777.     }
  778.     public function getSms(): ?bool
  779.     {
  780.         return $this->sms;
  781.     }
  782.     public function setSms(?bool $sms): self
  783.     {
  784.         $this->sms $sms;
  785.         return $this;
  786.     }
  787.     public function getEmail(): string
  788.     {
  789.         return $this->email;
  790.     }
  791.     public function setEmail(string $email): self
  792.     {
  793.         $this->email $email;
  794.         return $this;
  795.     }
  796.     public function getBudgetEmail(): ?string
  797.     {
  798.         return $this->budgetEmail;
  799.     }
  800.     public function setBudgetEmail(?string $budgetEmail): self
  801.     {
  802.         $this->budgetEmail $budgetEmail;
  803.         return $this;
  804.     }
  805.     public function getGarageAppointmentNotificationEmails(): ?string
  806.     {
  807.         return $this->garageAppointmentNotificationEmails;
  808.     }
  809.     public function getGarageAppointmentNotificationEmailsExplodedArrayOrDefaultEmailInstead()
  810.     {
  811.         $result $this->getEmail();
  812.         if ($this->getGarageAppointmentNotificationEmails()) {
  813.             $result explode(','$this->getGarageAppointmentNotificationEmails());
  814.         }
  815.         return $result;
  816.     }
  817.     public function setGarageAppointmentNotificationEmails(?string $garageAppointmentNotificationEmails): self
  818.     {
  819.         $this->garageAppointmentNotificationEmails $garageAppointmentNotificationEmails;
  820.         return $this;
  821.     }
  822.     public function getTimetableMorning(): ?string
  823.     {
  824.         return $this->timetableMorning;
  825.     }
  826.     public function setTimetableMorning(?string $timetableMorning): self
  827.     {
  828.         $this->timetableMorning $timetableMorning;
  829.         return $this;
  830.     }
  831.     public function getTimetableAfternoon(): ?string
  832.     {
  833.         return $this->timetableAfternoon;
  834.     }
  835.     public function setTimetableAfternoon(?string $timetableAfternoon): self
  836.     {
  837.         $this->timetableAfternoon $timetableAfternoon;
  838.         return $this;
  839.     }
  840.     public function getTimetableSaturday(): ?string
  841.     {
  842.         return $this->timetableSaturday;
  843.     }
  844.     public function setTimetableSaturday(?string $timetableSaturday): self
  845.     {
  846.         $this->timetableSaturday $timetableSaturday;
  847.         return $this;
  848.     }
  849.     public function isWorksWithCollective(): bool
  850.     {
  851.         return $this->worksWithCollective;
  852.     }
  853.     public function setWorksWithCollective(bool $worksWithCollective): self
  854.     {
  855.         $this->worksWithCollective $worksWithCollective;
  856.         return $this;
  857.     }
  858.     public function getOtherServices(): ?string
  859.     {
  860.         return $this->otherServices;
  861.     }
  862.     public function setOtherServices(?string $otherServices): self
  863.     {
  864.         $this->otherServices $otherServices;
  865.         return $this;
  866.     }
  867.     public function getImageName(): ?string
  868.     {
  869.         return $this->imageName;
  870.     }
  871.     public function setImageName(?string $imageName): self
  872.     {
  873.         $this->imageName $imageName;
  874.         return $this;
  875.     }
  876.     public function getInternObservations(): ?string
  877.     {
  878.         return $this->internObservations;
  879.     }
  880.     public function setInternObservations(?string $internObservations): self
  881.     {
  882.         $this->internObservations $internObservations;
  883.         return $this;
  884.     }
  885.     public function isMaintenancePlansEnabled(): bool
  886.     {
  887.         return $this->maintenancePlansEnabled;
  888.     }
  889.     public function setMaintenancePlansEnabled(bool $maintenancePlansEnabled): self
  890.     {
  891.         $this->maintenancePlansEnabled $maintenancePlansEnabled;
  892.         return $this;
  893.     }
  894.     public function getMaintenancePlans(): ?array
  895.     {
  896.         return $this->maintenancePlans;
  897.     }
  898.     public function setMaintenancePlans(?array $maintenancePlans): self
  899.     {
  900.         $this->maintenancePlans $maintenancePlans;
  901.         return $this;
  902.     }
  903.     public function addMaintenancePlan($plan): self
  904.     {
  905.         if (!in_array($plan$this->maintenancePlanstrue)) {
  906.             $this->maintenancePlans[] = $plan;
  907.         }
  908.         return $this;
  909.     }
  910.     public function hasMaintenancePlan($plan): bool
  911.     {
  912.         return in_array(strtoupper($plan), $this->getMaintenancePlans(), true);
  913.     }
  914.     public function getGarageECImageName(): ?string
  915.     {
  916.         return $this->garageECImageName;
  917.     }
  918.     public function setGarageECImageName(?string $garageECImageName): self
  919.     {
  920.         $this->garageECImageName $garageECImageName;
  921.         return $this;
  922.     }
  923.     public function getGarageECImageUrl(): ?string
  924.     {
  925.         return $this->garageECImageUrl;
  926.     }
  927.     public function setGarageECImageUrl(?string $garageECImageUrl): self
  928.     {
  929.         $this->garageECImageUrl $garageECImageUrl;
  930.         return $this;
  931.     }
  932.     public function getECommerceWarningMessage(): ?string
  933.     {
  934.         return $this->eCommerceWarningMessage;
  935.     }
  936.     public function setECommerceWarningMessage(?string $eCommerceWarningMessage): self
  937.     {
  938.         $this->eCommerceWarningMessage $eCommerceWarningMessage;
  939.         return $this;
  940.     }
  941.     public function getLegalInformation(): ?string
  942.     {
  943.         return $this->legalInformation;
  944.     }
  945.     public function setLegalInformation(?string $legalInformation): self
  946.     {
  947.         $this->legalInformation $legalInformation;
  948.         return $this;
  949.     }
  950.     public function getLegalInformationCa(): ?string
  951.     {
  952.         return $this->legalInformationCa;
  953.     }
  954.     public function setLegalInformationCa(?string $legalInformationCa): self
  955.     {
  956.         $this->legalInformationCa $legalInformationCa;
  957.         return $this;
  958.     }
  959.     public function getFeaturedBox(): ?string
  960.     {
  961.         return $this->featuredBox;
  962.     }
  963.     public function setFeaturedBox(?string $featuredBox): self
  964.     {
  965.         $this->featuredBox $featuredBox;
  966.         return $this;
  967.     }
  968.     public function getFeaturedBoxCa(): ?string
  969.     {
  970.         return $this->featuredBoxCa;
  971.     }
  972.     public function setFeaturedBoxCa(?string $featuredBoxCa): self
  973.     {
  974.         $this->featuredBoxCa $featuredBoxCa;
  975.         return $this;
  976.     }
  977.     public function getFacebookUrl(): ?string
  978.     {
  979.         return $this->facebookUrl;
  980.     }
  981.     public function setFacebookUrl(?string $facebookUrl): self
  982.     {
  983.         $this->facebookUrl $facebookUrl;
  984.         return $this;
  985.     }
  986.     public function getTwitterUrl(): ?string
  987.     {
  988.         return $this->twitterUrl;
  989.     }
  990.     public function setTwitterUrl(?string $twitterUrl): self
  991.     {
  992.         $this->twitterUrl $twitterUrl;
  993.         return $this;
  994.     }
  995.     public function getInstagramUrl(): ?string
  996.     {
  997.         return $this->instagramUrl;
  998.     }
  999.     public function setInstagramUrl(?string $instagramUrl): self
  1000.     {
  1001.         $this->instagramUrl $instagramUrl;
  1002.         return $this;
  1003.     }
  1004.     public function isECommerceWebsite(): bool
  1005.     {
  1006.         return $this->eCommerceWebsite;
  1007.     }
  1008.     public function setECommerceWebsite(bool $eCommerceWebsite): self
  1009.     {
  1010.         $this->eCommerceWebsite $eCommerceWebsite;
  1011.         return $this;
  1012.     }
  1013.     public function isCatalanLanguage(): bool
  1014.     {
  1015.         return $this->catalanLanguage;
  1016.     }
  1017.     public function setCatalanLanguage(bool $catalanLanguage): self
  1018.     {
  1019.         $this->catalanLanguage $catalanLanguage;
  1020.         return $this;
  1021.     }
  1022.     public function getPointsLimit(): float
  1023.     {
  1024.         return $this->pointsLimit;
  1025.     }
  1026.     public function setPointsLimit(float $pointsLimit): self
  1027.     {
  1028.         $this->pointsLimit $pointsLimit;
  1029.         return $this;
  1030.     }
  1031.     public function getERP(): ?string
  1032.     {
  1033.         return $this->ERP;
  1034.     }
  1035.     public function setERP(?string $ERP): self
  1036.     {
  1037.         $this->ERP $ERP;
  1038.         return $this;
  1039.     }
  1040.     public function getGerente(): ?string
  1041.     {
  1042.         return $this->gerente;
  1043.     }
  1044.     public function setGerente(?string $gerente): self
  1045.     {
  1046.         $this->gerente $gerente;
  1047.         return $this;
  1048.     }
  1049.     public function isAllowBudgetRequest(): bool
  1050.     {
  1051.         return $this->allowBudgetRequest;
  1052.     }
  1053.     public function setAllowBudgetRequest(bool $allowBudgetRequest): self
  1054.     {
  1055.         $this->allowBudgetRequest $allowBudgetRequest;
  1056.         return $this;
  1057.     }
  1058.     public function isAllowGarageAppointment(): bool
  1059.     {
  1060.         return $this->allowGarageAppointment;
  1061.     }
  1062.     public function setAllowGarageAppointment(bool $allowGarageAppointment): self
  1063.     {
  1064.         $this->allowGarageAppointment $allowGarageAppointment;
  1065.         return $this;
  1066.     }
  1067.     public function isGrips(): bool
  1068.     {
  1069.         return $this->grips;
  1070.     }
  1071.     public function setGrips(bool $grips): self
  1072.     {
  1073.         $this->grips $grips;
  1074.         return $this;
  1075.     }
  1076.     public function isVulcoTruckRate(): bool
  1077.     {
  1078.         return $this->vulcoTruckRate;
  1079.     }
  1080.     public function setVulcoTruckRate(bool $vulcoTruckRate): self
  1081.     {
  1082.         $this->vulcoTruckRate $vulcoTruckRate;
  1083.         return $this;
  1084.     }
  1085.     public function getEmployees(): ?Collection
  1086.     {
  1087.         return $this->employees;
  1088.     }
  1089.     public function setEmployees(?Collection $employees): self
  1090.     {
  1091.         $this->employees $employees;
  1092.         return $this;
  1093.     }
  1094.     public function addEmployee(User $employee): self
  1095.     {
  1096.         if (!$this->employees->contains($employee)) {
  1097.             $this->employees->add($employee);
  1098.             $employee->setEmployeeGarage($this);
  1099.         }
  1100.         return $this;
  1101.     }
  1102.     public function removeEmployee(User $employee): self
  1103.     {
  1104.         if ($this->employees->contains($employee)) {
  1105.             $this->employees->removeElement($employee);
  1106.             $employee->setEmployeeGarage(null);
  1107.         }
  1108.         return $this;
  1109.     }
  1110.     public function getNameAndCodeString(): string
  1111.     {
  1112.         return $this->name.' ('.$this->code.')';
  1113.     }
  1114.     public function getNameAndCodeStringAndProvince(): string
  1115.     {
  1116.         return $this->name.' ('.$this->code.')'.' - '.$this->provinceName();
  1117.     }
  1118.     public function getPurchasesOf(int $year): ?array
  1119.     {
  1120.         $purchases = [];
  1121.         /** @var GaragePurchase $purchase */
  1122.         foreach ($this->purchases as $purchase) {
  1123.             if ($purchase->getYear() === $year) {
  1124.                 $purchases[] = $purchase;
  1125.             }
  1126.         }
  1127.         return $purchases;
  1128.     }
  1129.     public function diff(Garage $before): array
  1130.     {
  1131.         $diff = array();
  1132.         // general data
  1133.         if ($this->mobileAssociated !== $before->mobileAssociated) {
  1134.             $diff[] = ['garage.mobile_associated'$this->mobileAssociated];
  1135.         }
  1136.         if ($this->phone !== $before->phone) {
  1137.             $diff[] = ['garage.phone'$this->phone];
  1138.         }
  1139.         if ($this->mobile !== $before->mobile) {
  1140.             $diff[] = ['garage.mobile'$this->mobile];
  1141.         }
  1142.         if ($this->whatsapp !== $before->whatsapp) {
  1143.             $diff[] = ['garage.whatsapp'$this->whatsapp];
  1144.         }
  1145.         if ($this->whatsappCampaigns !== $before->whatsappCampaigns) {
  1146.             $diff[] = ['garage.whatsapp_campaigns'$this->whatsappCampaigns];
  1147.         }
  1148.         if ($this->whatsappCampaignsName !== $before->whatsappCampaignsName) {
  1149.             $diff[] = ['garage.whatsapp_campaigns_name'$this->whatsappCampaignsName];
  1150.         }
  1151.         if ($this->facebookUrl !== $before->facebookUrl) {
  1152.             $diff[] = ['garage.facebook'$this->facebookUrl];
  1153.         }
  1154.         if ($this->twitterUrl !== $before->twitterUrl) {
  1155.             $diff[] = ['garage.twitter'$this->twitterUrl];
  1156.         }
  1157.         if ($this->instagramUrl !== $before->instagramUrl) {
  1158.             $diff[] = ['garage.instagram'$this->instagramUrl];
  1159.         }
  1160.         // timetable_data
  1161.         $schedulesDiff $this->schedules->diff($before->schedules);
  1162.         if (!empty($schedulesDiff)) {
  1163.             $diff[] = ['garage.form.timetable_data'$schedulesDiff];
  1164.         }
  1165.         // address
  1166.         $addressDiff $this->address->diff($before->address);
  1167.         if (!empty($addressDiff)) {
  1168.             $diff[] = ['garage.form.address_data'$addressDiff];
  1169.         }
  1170.         // additional_addresses_data
  1171.         if ($this->additionalAddresses->isEmpty() && !$before->additionalAddresses->isEmpty()){
  1172.             $diff[] = ['garage.form.additional_addresses_data''todas las direcciones eliminadas'];
  1173.         } else if (!$this->additionalAddresses->isEmpty() && $before->additionalAddresses->isEmpty()) {
  1174.             foreach ($this->additionalAddresses as $address) {
  1175.                 $diff[] = ['garage.form.additional_address_data'$address->displayRawFields()];
  1176.             }
  1177.         } else if (!$this->additionalAddresses->isEmpty() && !$before->additionalAddresses->isEmpty()
  1178.             && (count($this->additionalAddresses) < count($before->additionalAddresses))) {
  1179.             $diff[] = ['garage.form.additional_addresses_data''hay cambios en las direcciones'];
  1180.         } else if (!$this->additionalAddresses->isEmpty() && !$before->additionalAddresses->isEmpty()
  1181.             && (count($this->additionalAddresses) > count($before->additionalAddresses))) {
  1182.             $diff[] = ['garage.form.additional_addresses_data''hay cambios en las direcciones'];
  1183.         } else if (!$this->additionalAddresses->isEmpty() && !$before->additionalAddresses->isEmpty()
  1184.             && (count($this->additionalAddresses) === count($before->additionalAddresses)))
  1185.         {
  1186.             $additionalAddresses $this->additionalAddresses->getValues(); // because an ArrayCollection could have not sequential indexes
  1187.             $beforeAddresses $before->additionalAddresses->getValues();
  1188.             for ($i 0$i count($additionalAddresses); $i++) {
  1189.                 //if ($additionalAddresses[$i]) { // puede que solo haya las que han sido modificadas
  1190.                     $addressDiff $additionalAddresses[$i]->diff($beforeAddresses[$i]);
  1191.                     if (!empty($addressDiff)) {
  1192.                         $diff[] = ['garage.form.additional_address_data'$additionalAddresses[$i]->displayRawFields()];
  1193.                     }
  1194.                 //}
  1195.             }
  1196.         }
  1197.         // typeVehicles
  1198.         if (empty($this->typeVehicles) && !empty($before->typeVehicles)
  1199.         ) {
  1200.             $diff[] = ['garage.form.vehicle_types_data''ítems eliminados'];
  1201.         } else {
  1202.             if (
  1203.                 (!empty($this->typeVehicles) && empty($before->typeVehicles))
  1204.                 || (!empty($this->typeVehicles) && !empty($before->typeVehicles) && (count($this->typeVehicles) !== count($before->typeVehicles)))
  1205.             )
  1206.             {
  1207.                 $typeVehiclesNames = array();
  1208.                 /** @var GarageVehicleType $item */
  1209.                 foreach ($this->typeVehicles as $item) {
  1210.                     $typeVehiclesNames[] = $item->getName();
  1211.                 }
  1212.                 $diff[] = ['garage.form.vehicle_types_data'implode(', '$typeVehiclesNames)];
  1213.             }
  1214.         }
  1215.         // facilities
  1216.         if (empty($this->facilities) && !empty($before->facilities)
  1217.         ) {
  1218.             $diff[] = ['garage.form.comforts_data''ítems eliminados'];
  1219.         } else {
  1220.             if (
  1221.                 (!empty($this->facilities) && empty($before->facilities))
  1222.                 || (!empty($this->facilities) && !empty($before->facilities) && (count($this->facilities) !== count($before->facilities)))
  1223.             )
  1224.             {
  1225.                 $facilitiesNames = array();
  1226.                 /** @var GarageFacility $item */
  1227.                 foreach ($this->facilities as $item) {
  1228.                     $facilitiesNames[] = $item->getName();
  1229.                 }
  1230.                 $diff[] = ['garage.form.comforts_data'implode(', '$facilitiesNames)];
  1231.             }
  1232.         }
  1233.         // services
  1234.         if (empty($this->services) && !empty($before->services)
  1235.         ) {
  1236.             $diff[] = ['garage.form.services_data''ítems eliminados'];
  1237.         } else {
  1238.             if (
  1239.                 (!empty($this->services) && empty($before->services))
  1240.                 || (!empty($this->services) && !empty($before->services) && (count($this->services) !== count($before->services)))
  1241.             )
  1242.             {
  1243.                 $servicesNames = array();
  1244.                 /** @var GarageService $item */
  1245.                 foreach ($this->services as $item) {
  1246.                     $servicesNames[] = $item->getName();
  1247.                 }
  1248.                 $diff[] = ['garage.form.services_data'implode(', '$servicesNames)];
  1249.             }
  1250.         }
  1251.         return $diff;
  1252.     }
  1253.     public function __toString(): string
  1254.     {
  1255.         return $this->id $this->getName() : MiniAbstractBase::DEFAULT_EMPTY_STRING;
  1256.     }
  1257. }