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 (sin prefijo) con whatsapp para recibir comunicaciones comerciales
  204.      *
  205.      * @ORM\Column(type="string", length=255, nullable=true, unique=true)
  206.      *
  207.      * @Assert\Regex(pattern="/^\d{11}$|^\d{12}$/")
  208.  *
  209.      */
  210.     private ?string $whatsappCampaigns null;
  211.     /**
  212.      * @ORM\Column(type="string", length=255, nullable=true)
  213.      */
  214.     private ?string $whatsappCampaignsName null;
  215.     /**
  216.      * @ORM\Column(type="string", length=255, nullable=true)
  217.      */
  218.     private ?string $website null;
  219.     /**
  220.      * @ORM\Column(type="string", length=255, nullable=true)
  221.      */
  222.     private ?string $fax null;
  223.     /**
  224.      * @ORM\Column(type="boolean", nullable=true)
  225.      */
  226.     private ?bool $sms null;
  227.     /**
  228.      * @ORM\Column(type="string", length=255, nullable=false)
  229.      *
  230.      * @Assert\Email()
  231.      *
  232.      * @Groups({"garage:read"})
  233.      */
  234.     private string $email;
  235.     /**
  236.      * @ORM\Column(type="text", length=10000, nullable=true)
  237.      */
  238.     private ?string $budgetEmail null;
  239.     /**
  240.      * @ORM\Column(type="text", length=10000, nullable=true)
  241.      */
  242.     private ?string $garageAppointmentNotificationEmails null;
  243.     /**
  244.      * @ORM\Column(type="string", length=255, nullable=true)
  245.      */
  246.     private ?string $timetableMorning null;
  247.     /**
  248.      * @ORM\Column(type="string", length=255, nullable=true)
  249.      */
  250.     private ?string $timetableAfternoon null;
  251.     /**
  252.      * @ORM\Column(type="string", length=255, nullable=true)
  253.      */
  254.     private ?string $timetableSaturday null;
  255.     /**
  256.      * @ORM\Column(type="boolean", nullable=false)
  257.      */
  258.     private bool $worksWithCollective;
  259.     /**
  260.      * @ORM\Column(type="string", length=255, nullable=true)
  261.      */
  262.     private ?string $otherServices null;
  263.     /**
  264.      * @ORM\Column(type="string", length=255, nullable=true)
  265.      */
  266.     private ?string $imageName null;
  267.     /**
  268.      * @ORM\Column(type="string", length=255, nullable=true)
  269.      */
  270.     private ?string $internObservations null;
  271.     /**
  272.      * @ORM\Column(type="boolean", nullable=false, options={"default": 0})
  273.      */
  274.     private bool $maintenancePlansEnabled false;
  275.     /**
  276.      * @ORM\Column(type="array", nullable=true)
  277.      */
  278.     private ?array $maintenancePlans null;
  279.     /**
  280.      * @ORM\Column(type="string", length=255, nullable=true)
  281.      */
  282.     private ?string $garageECImageName null;
  283.     /**
  284.      * @ORM\Column(type="text", length=10000, nullable=true)
  285.      */
  286.     private ?string $garageECImageUrl null;
  287.     /**
  288.      * @ORM\Column(type="text", length=10000, nullable=true)
  289.      */
  290.     private ?string $eCommerceWarningMessage null;
  291.     /**
  292.      * @ORM\Column(type="string", length=255, nullable=true)
  293.      */
  294.     private ?string $legalInformation null;
  295.     /**
  296.      * @ORM\Column(type="string", length=255, nullable=true)
  297.      */
  298.     private ?string $legalInformationCa null;
  299.     /**
  300.      * @ORM\Column(type="text", length=10000, nullable=true)
  301.      */
  302.     private ?string $featuredBox null;
  303.     /**
  304.      * @ORM\Column(type="text", length=10000, nullable=true)
  305.      */
  306.     private ?string $featuredBoxCa null;
  307.     /**
  308.      * @ORM\Column(type="text", length=10000, nullable=true)
  309.      */
  310.     private ?string $facebookUrl null;
  311.     /**
  312.      * @ORM\Column(type="text", length=10000, nullable=true)
  313.      */
  314.     private ?string $twitterUrl null;
  315.     /**
  316.      * @ORM\Column(type="text", length=10000, nullable=true)
  317.      */
  318.     private ?string $instagramUrl null;
  319.     /**
  320.      * @ORM\Column(type="boolean", nullable=false, options={"default": 0})
  321.      */
  322.     private bool $eCommerceWebsite false;
  323.     /**
  324.      * @ORM\Column(type="boolean", nullable=false, options={"default": 0})
  325.      */
  326.     private bool $catalanLanguage false;
  327.     /**
  328.      * @ORM\Column(type="float", nullable=false, options={"default": 4800})
  329.      */
  330.     private float $pointsLimit self::DEFAULT_POINTS_LIMIT;
  331.     /**
  332.      * @ORM\Column(type="string", length=255, nullable=true)
  333.      */
  334.     private ?string $ERP null;
  335.     /**
  336.      * @ORM\Column(type="string", length=255, nullable=true)
  337.      */
  338.     private ?string $gerente null;
  339.     /**
  340.      * @ORM\Column(type="boolean", nullable=false, options={"default": 1})
  341.      */
  342.     private bool $allowBudgetRequest true;
  343.     /**
  344.      * @ORM\Column(type="boolean", nullable=false, options={"default": 1})
  345.      */
  346.     private bool $allowGarageAppointment true;
  347.     /**
  348.      * @ORM\Column(type="boolean", nullable=false, options={"default": 0})
  349.      * The garage has GRIPS software
  350.      */
  351.     private bool $grips false;
  352.     /**
  353.      * @ORM\Column(type="boolean", nullable=false, options={"default": 0})
  354.      * El taller está adherido a la tarifa de Vulco interna para camiones y aparecerá en el mapa del site para camiones
  355.      */
  356.     private bool $vulcoTruckRate false;
  357.     public function __construct()
  358.     {
  359.         $this->services = new ArrayCollection();
  360.         $this->localPromotions = new ArrayCollection();
  361.         $this->facilities = new ArrayCollection();
  362.         $this->typeVehicles = new ArrayCollection();
  363.         $this->additionalAddresses = new ArrayCollection();
  364.         $this->purchases = new ArrayCollection();
  365.         $this->schedules = new GarageSchedules();
  366.         $this->aboutUs = new GarageAboutUs();
  367.     }
  368.     public function __clone() {
  369.         if ($this->id) {
  370.             if (!is_null($this->owner)) {
  371.                 $this->owner = clone $this->owner;
  372.             }
  373.             if (!is_null($this->address)) {
  374.                 $this->address = clone $this->address;
  375.             }
  376.             if (!is_null($this->schedules)) {
  377.                 $this->schedules = clone $this->schedules;
  378.             }
  379.             if (!is_null($this->services)) {
  380.                 $this->services = clone $this->services;
  381.             }
  382.             if (!is_null($this->facilities)) {
  383.                 $this->facilities = clone $this->facilities;
  384.             }
  385.             if (!is_null($this->localPromotions)) {
  386.                 $this->localPromotions = clone $this->localPromotions;
  387.             }
  388.             if (!is_null($this->typeVehicles)) {
  389.                 $this->typeVehicles = clone $this->typeVehicles;
  390.             }
  391.             if (!is_null($this->additionalAddresses)) {
  392.                 $additionalAddresses $this->getAdditionalAddresses();
  393.                 $this->additionalAddresses = new ArrayCollection();
  394.                 if (count($additionalAddresses) > 0) {
  395.                     foreach ($additionalAddresses as $address) {
  396.                         $addressClone = clone $address;
  397.                         $this->additionalAddresses->add($addressClone);
  398.                     }
  399.                 }
  400.             }
  401.             if (!is_null($this->purchases)) {
  402.                 $this->purchases = clone $this->purchases;
  403.             }
  404.             if (!is_null($this->aboutUs)) {
  405.                 $this->aboutUs = clone $this->aboutUs;
  406.             }
  407.             if (!is_null($this->garageOwner)) {
  408.                 $this->garageOwner = clone $this->garageOwner;
  409.             }
  410.         }
  411.     }
  412.     public static function loadValidatorMetadata(ClassMetadata $metadata): void
  413.     {
  414.         $metadata->addConstraint(new Callback('validate'));
  415.     }
  416.     public function validate(ExecutionContextInterface $context): void
  417.     {
  418.         $areBudgetEmailsValid $this->internalEmailsValidationCheck($this->getBudgetEmail());
  419.         $areGarageAppointmentNotificationEmailsValid $this->internalEmailsValidationCheck($this->getGarageAppointmentNotificationEmails());
  420.         if (!$areBudgetEmailsValid) {
  421.             $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.')
  422.                 ->atPath('budgetEmail')
  423.                 ->addViolation()
  424.             ;
  425.         }
  426.         if (!$areGarageAppointmentNotificationEmailsValid) {
  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('garageAppointmentNotificationEmails')
  429.                 ->addViolation()
  430.             ;
  431.         }
  432.     }
  433.     private function internalEmailsValidationCheck(?string $internalEmailsString): bool
  434.     {
  435.         $areIneternalEmailsValid true;
  436.         if ($internalEmailsString) {
  437.             $trimmedString trim($internalEmailsString);
  438.             $emailsArray explode(','$trimmedString);
  439.             foreach ($emailsArray as $email) {
  440.                 if (false === filter_var($emailFILTER_VALIDATE_EMAIL)) {
  441.                     $areIneternalEmailsValid false;
  442.                     break;
  443.                 }
  444.             }
  445.         }
  446.         return $areIneternalEmailsValid;
  447.     }
  448.     public function getOwner(): ?User
  449.     {
  450.         return $this->owner;
  451.     }
  452.     public function setOwner(?User $owner): self
  453.     {
  454.         $this->owner $owner;
  455.         return $this;
  456.     }
  457.     public function getAddress(): Address
  458.     {
  459.         return $this->address;
  460.     }
  461.     public function setAddress(Address $address): self
  462.     {
  463.         $this->address $address;
  464.         return $this;
  465.     }
  466.     public function getSchedules(): GarageSchedules
  467.     {
  468.         return $this->schedules;
  469.     }
  470.     public function setSchedules(GarageSchedules $schedules): self
  471.     {
  472.         $this->schedules $schedules;
  473.         return $this;
  474.     }
  475.     public function hasService(GarageService $service): bool
  476.     {
  477.         $result false;
  478.         /** @var GarageService $item */
  479.         foreach ($this->getServices() as $item) {
  480.             if ($service->getId() === $item->getId()) {
  481.                 $result true;
  482.                 break;
  483.             }
  484.         }
  485.         return $result;
  486.     }
  487.     public function getServices(): ?Collection
  488.     {
  489.         return $this->services;
  490.     }
  491.     public function setServices(?Collection $services): self
  492.     {
  493.         $this->services $services;
  494.         return $this;
  495.     }
  496.     public function addService(GarageService $service): self
  497.     {
  498.         if (!$this->services->contains($service)) {
  499.             $this->services->add($service);
  500.         }
  501.         return $this;
  502.     }
  503.     public function removeService(GarageService $service): self
  504.     {
  505.         if ($this->services->contains($service)) {
  506.             $this->services->removeElement($service);
  507.         }
  508.         return $this;
  509.     }
  510.     public function hasFacility(GarageFacility $facility): bool
  511.     {
  512.         $result false;
  513.         /** @var GarageFacility $item */
  514.         foreach ($this->getFacilities() as $item) {
  515.             if ($facility->getId() === $item->getId()) {
  516.                 $result true;
  517.                 break;
  518.             }
  519.         }
  520.         return $result;
  521.     }
  522.     public function getFacilities(): ?Collection
  523.     {
  524.         return $this->facilities;
  525.     }
  526.     public function setFacilities(?Collection $facilities): self
  527.     {
  528.         $this->facilities $facilities;
  529.         return $this;
  530.     }
  531.     public function addFacility(GarageFacility $facility): self
  532.     {
  533.         if (!$this->facilities->contains($facility)) {
  534.             $this->facilities->add($facility);
  535.         }
  536.         return $this;
  537.     }
  538.     public function removeFacility(GarageFacility $facility): self
  539.     {
  540.         if ($this->facilities->contains($facility)) {
  541.             $this->facilities->removeElement($facility);
  542.         }
  543.         return $this;
  544.     }
  545.     public function getLocalPromotions(): ?Collection
  546.     {
  547.         return $this->localPromotions;
  548.     }
  549.     public function setLocalPromotions(?Collection $localPromotions): self
  550.     {
  551.         $this->localPromotions $localPromotions;
  552.         return $this;
  553.     }
  554.     public function addLocalPromotion(LocalPromotion $localPromotion): self
  555.     {
  556.         if (!$this->localPromotions->contains($localPromotion)) {
  557.             $this->localPromotions->add($localPromotion);
  558.         }
  559.         return $this;
  560.     }
  561.     public function removeLocalPromotion(LocalPromotion $localPromotion): self
  562.     {
  563.         if ($this->localPromotions->contains($localPromotion)) {
  564.             $this->localPromotions->removeElement($localPromotion);
  565.         }
  566.         return $this;
  567.     }
  568.     public function hasTypeVehicle(GarageVehicleType $typeVehicle): bool
  569.     {
  570.         $result false;
  571.         /** @var GarageVehicleType $item */
  572.         foreach ($this->getTypeVehicles() as $item) {
  573.             if ($typeVehicle->getId() === $item->getId()) {
  574.                 $result true;
  575.                 break;
  576.             }
  577.         }
  578.         return $result;
  579.     }
  580.     public function getTypeVehicles(): ?Collection
  581.     {
  582.         return $this->typeVehicles;
  583.     }
  584.     public function setTypeVehicles(?Collection $typeVehicles): self
  585.     {
  586.         $this->typeVehicles $typeVehicles;
  587.         return $this;
  588.     }
  589.     public function addTypeVehicle(GarageVehicleType $typeVehicle): self
  590.     {
  591.         if (!$this->typeVehicles->contains($typeVehicle)) {
  592.             $this->typeVehicles->add($typeVehicle);
  593.         }
  594.         return $this;
  595.     }
  596.     public function removeTypeVehicle(GarageVehicleType $typeVehicle): self
  597.     {
  598.         if ($this->typeVehicles->contains($typeVehicle)) {
  599.             $this->typeVehicles->removeElement($typeVehicle);
  600.         }
  601.         return $this;
  602.     }
  603.     public function getAdditionalAddresses(): ?Collection
  604.     {
  605.         return $this->additionalAddresses;
  606.     }
  607.     public function setAdditionalAddresses(?Collection $additionalAddresses): self
  608.     {
  609.         $this->additionalAddresses $additionalAddresses;
  610.         return $this;
  611.     }
  612.     public function addAdditionalAddresses(Address $additionalAddress): self
  613.     {
  614.         if (!$this->additionalAddresses->contains($additionalAddress)) {
  615.             $this->additionalAddresses->add($additionalAddress);
  616.         }
  617.         return $this;
  618.     }
  619.     public function removeAdditionalAddresses(Address $additionalAddress): self
  620.     {
  621.         if ($this->additionalAddresses->contains($additionalAddress)) {
  622.             $this->additionalAddresses->removeElement($additionalAddress);
  623.         }
  624.         return $this;
  625.     }
  626.     public function getPurchases(): ?Collection
  627.     {
  628.         return $this->purchases;
  629.     }
  630.     public function setPurchases(?Collection $purchases): self
  631.     {
  632.         $this->purchases $purchases;
  633.         return $this;
  634.     }
  635.     public function getAboutUs(): ?GarageAboutUs
  636.     {
  637.         return $this->aboutUs;
  638.     }
  639.     public function setAboutUs(?GarageAboutUs $aboutUs): self
  640.     {
  641.         $this->aboutUs $aboutUs;
  642.         return $this;
  643.     }
  644.     public function getGarageOwner(): ?GarageOwner
  645.     {
  646.         return $this->garageOwner;
  647.     }
  648.     public function setGarageOwner(GarageOwner $garageOwner): self
  649.     {
  650.         $this->garageOwner $garageOwner;
  651.         return $this;
  652.     }
  653.     public function getRelatedAddresses(): array
  654.     {
  655.         $result = [];
  656.         $result[] = $this->getAddress();
  657.         /** @var Address $additionalAddress */
  658.         foreach ($this->getAdditionalAddresses() as $additionalAddress) {
  659.             $result[] = $additionalAddress;
  660.         }
  661.         return $result;
  662.     }
  663.     public function isOwner(UserInterface $user): bool
  664.     {
  665.         if ($this->getOwner() && ($user->getId() === $this->getOwner()->getId())) {
  666.             return true;
  667.         }
  668.         return false;
  669.     }
  670.     public function isCoordinator(UserInterface $user): bool
  671.     {
  672.         return $user->getWorkProvinces() && $user->getWorkProvinces()->contains($this->getAddress()->getProvince());
  673.     }
  674.     public function province(): ?Province
  675.     {
  676.         return $this->address->getProvince() ?: null;
  677.     }
  678.     public function provinceName(): ?string
  679.     {
  680.         return $this->province() ? $this->province()->getName() : null;
  681.     }
  682.     public function getCode(): string
  683.     {
  684.         return $this->code;
  685.     }
  686.     public function setCode(string $code): self
  687.     {
  688.         $this->code $code;
  689.         return $this;
  690.     }
  691.     public function getCif(): string
  692.     {
  693.         return $this->cif;
  694.     }
  695.     public function setCif(string $cif): self
  696.     {
  697.         $this->cif $cif;
  698.         return $this;
  699.     }
  700.     public function getCompanyName(): string
  701.     {
  702.         return $this->companyName;
  703.     }
  704.     public function setCompanyName(string $companyName): self
  705.     {
  706.         $this->companyName $companyName;
  707.         return $this;
  708.     }
  709.     public function getMobile(): ?string
  710.     {
  711.         return $this->mobile;
  712.     }
  713.     public function setMobile(?string $mobile): self
  714.     {
  715.         $this->mobile $mobile;
  716.         return $this;
  717.     }
  718.     public function getMobileAssociated(): ?string
  719.     {
  720.         return $this->mobileAssociated;
  721.     }
  722.     public function setMobileAssociated(?string $mobileAssociated): self
  723.     {
  724.         $this->mobileAssociated $mobileAssociated;
  725.         return $this;
  726.     }
  727.     public function getWhatsapp(): ?string
  728.     {
  729.         return $this->whatsapp;
  730.     }
  731.     public function setWhatsapp(?string $whatsapp): self
  732.     {
  733.         $this->whatsapp $whatsapp;
  734.         return $this;
  735.     }
  736.     public function getWhatsappCampaigns(): ?string
  737.     {
  738.         return $this->whatsappCampaigns;
  739.     }
  740.     public function setWhatsappCampaigns(?string $whatsappCampaigns): self
  741.     {
  742.         $this->whatsappCampaigns $whatsappCampaigns;
  743.         return $this;
  744.     }
  745.     public function getWhatsappCampaignsName(): ?string
  746.     {
  747.         return $this->whatsappCampaignsName;
  748.     }
  749.     public function setWhatsappCampaignsName(?string $whatsappCampaignsName): self
  750.     {
  751.         $this->whatsappCampaignsName $whatsappCampaignsName;
  752.         return $this;
  753.     }
  754.     public function getWebsite(): ?string
  755.     {
  756.         return $this->website;
  757.     }
  758.     public function setWebsite(?string $website): self
  759.     {
  760.         $this->website $website;
  761.         return $this;
  762.     }
  763.     public function getFax(): ?string
  764.     {
  765.         return $this->fax;
  766.     }
  767.     public function setFax(?string $fax): self
  768.     {
  769.         $this->fax $fax;
  770.         return $this;
  771.     }
  772.     public function getSms(): ?bool
  773.     {
  774.         return $this->sms;
  775.     }
  776.     public function setSms(?bool $sms): self
  777.     {
  778.         $this->sms $sms;
  779.         return $this;
  780.     }
  781.     public function getEmail(): string
  782.     {
  783.         return $this->email;
  784.     }
  785.     public function setEmail(string $email): self
  786.     {
  787.         $this->email $email;
  788.         return $this;
  789.     }
  790.     public function getBudgetEmail(): ?string
  791.     {
  792.         return $this->budgetEmail;
  793.     }
  794.     public function setBudgetEmail(?string $budgetEmail): self
  795.     {
  796.         $this->budgetEmail $budgetEmail;
  797.         return $this;
  798.     }
  799.     public function getGarageAppointmentNotificationEmails(): ?string
  800.     {
  801.         return $this->garageAppointmentNotificationEmails;
  802.     }
  803.     public function getGarageAppointmentNotificationEmailsExplodedArrayOrDefaultEmailInstead()
  804.     {
  805.         $result $this->getEmail();
  806.         if ($this->getGarageAppointmentNotificationEmails()) {
  807.             $result explode(','$this->getGarageAppointmentNotificationEmails());
  808.         }
  809.         return $result;
  810.     }
  811.     public function setGarageAppointmentNotificationEmails(?string $garageAppointmentNotificationEmails): self
  812.     {
  813.         $this->garageAppointmentNotificationEmails $garageAppointmentNotificationEmails;
  814.         return $this;
  815.     }
  816.     public function getTimetableMorning(): ?string
  817.     {
  818.         return $this->timetableMorning;
  819.     }
  820.     public function setTimetableMorning(?string $timetableMorning): self
  821.     {
  822.         $this->timetableMorning $timetableMorning;
  823.         return $this;
  824.     }
  825.     public function getTimetableAfternoon(): ?string
  826.     {
  827.         return $this->timetableAfternoon;
  828.     }
  829.     public function setTimetableAfternoon(?string $timetableAfternoon): self
  830.     {
  831.         $this->timetableAfternoon $timetableAfternoon;
  832.         return $this;
  833.     }
  834.     public function getTimetableSaturday(): ?string
  835.     {
  836.         return $this->timetableSaturday;
  837.     }
  838.     public function setTimetableSaturday(?string $timetableSaturday): self
  839.     {
  840.         $this->timetableSaturday $timetableSaturday;
  841.         return $this;
  842.     }
  843.     public function isWorksWithCollective(): bool
  844.     {
  845.         return $this->worksWithCollective;
  846.     }
  847.     public function setWorksWithCollective(bool $worksWithCollective): self
  848.     {
  849.         $this->worksWithCollective $worksWithCollective;
  850.         return $this;
  851.     }
  852.     public function getOtherServices(): ?string
  853.     {
  854.         return $this->otherServices;
  855.     }
  856.     public function setOtherServices(?string $otherServices): self
  857.     {
  858.         $this->otherServices $otherServices;
  859.         return $this;
  860.     }
  861.     public function getImageName(): ?string
  862.     {
  863.         return $this->imageName;
  864.     }
  865.     public function setImageName(?string $imageName): self
  866.     {
  867.         $this->imageName $imageName;
  868.         return $this;
  869.     }
  870.     public function getInternObservations(): ?string
  871.     {
  872.         return $this->internObservations;
  873.     }
  874.     public function setInternObservations(?string $internObservations): self
  875.     {
  876.         $this->internObservations $internObservations;
  877.         return $this;
  878.     }
  879.     public function isMaintenancePlansEnabled(): bool
  880.     {
  881.         return $this->maintenancePlansEnabled;
  882.     }
  883.     public function setMaintenancePlansEnabled(bool $maintenancePlansEnabled): self
  884.     {
  885.         $this->maintenancePlansEnabled $maintenancePlansEnabled;
  886.         return $this;
  887.     }
  888.     public function getMaintenancePlans(): ?array
  889.     {
  890.         return $this->maintenancePlans;
  891.     }
  892.     public function setMaintenancePlans(?array $maintenancePlans): self
  893.     {
  894.         $this->maintenancePlans $maintenancePlans;
  895.         return $this;
  896.     }
  897.     public function addMaintenancePlan($plan): self
  898.     {
  899.         if (!in_array($plan$this->maintenancePlanstrue)) {
  900.             $this->maintenancePlans[] = $plan;
  901.         }
  902.         return $this;
  903.     }
  904.     public function hasMaintenancePlan($plan): bool
  905.     {
  906.         return in_array(strtoupper($plan), $this->getMaintenancePlans(), true);
  907.     }
  908.     public function getGarageECImageName(): ?string
  909.     {
  910.         return $this->garageECImageName;
  911.     }
  912.     public function setGarageECImageName(?string $garageECImageName): self
  913.     {
  914.         $this->garageECImageName $garageECImageName;
  915.         return $this;
  916.     }
  917.     public function getGarageECImageUrl(): ?string
  918.     {
  919.         return $this->garageECImageUrl;
  920.     }
  921.     public function setGarageECImageUrl(?string $garageECImageUrl): self
  922.     {
  923.         $this->garageECImageUrl $garageECImageUrl;
  924.         return $this;
  925.     }
  926.     public function getECommerceWarningMessage(): ?string
  927.     {
  928.         return $this->eCommerceWarningMessage;
  929.     }
  930.     public function setECommerceWarningMessage(?string $eCommerceWarningMessage): self
  931.     {
  932.         $this->eCommerceWarningMessage $eCommerceWarningMessage;
  933.         return $this;
  934.     }
  935.     public function getLegalInformation(): ?string
  936.     {
  937.         return $this->legalInformation;
  938.     }
  939.     public function setLegalInformation(?string $legalInformation): self
  940.     {
  941.         $this->legalInformation $legalInformation;
  942.         return $this;
  943.     }
  944.     public function getLegalInformationCa(): ?string
  945.     {
  946.         return $this->legalInformationCa;
  947.     }
  948.     public function setLegalInformationCa(?string $legalInformationCa): self
  949.     {
  950.         $this->legalInformationCa $legalInformationCa;
  951.         return $this;
  952.     }
  953.     public function getFeaturedBox(): ?string
  954.     {
  955.         return $this->featuredBox;
  956.     }
  957.     public function setFeaturedBox(?string $featuredBox): self
  958.     {
  959.         $this->featuredBox $featuredBox;
  960.         return $this;
  961.     }
  962.     public function getFeaturedBoxCa(): ?string
  963.     {
  964.         return $this->featuredBoxCa;
  965.     }
  966.     public function setFeaturedBoxCa(?string $featuredBoxCa): self
  967.     {
  968.         $this->featuredBoxCa $featuredBoxCa;
  969.         return $this;
  970.     }
  971.     public function getFacebookUrl(): ?string
  972.     {
  973.         return $this->facebookUrl;
  974.     }
  975.     public function setFacebookUrl(?string $facebookUrl): self
  976.     {
  977.         $this->facebookUrl $facebookUrl;
  978.         return $this;
  979.     }
  980.     public function getTwitterUrl(): ?string
  981.     {
  982.         return $this->twitterUrl;
  983.     }
  984.     public function setTwitterUrl(?string $twitterUrl): self
  985.     {
  986.         $this->twitterUrl $twitterUrl;
  987.         return $this;
  988.     }
  989.     public function getInstagramUrl(): ?string
  990.     {
  991.         return $this->instagramUrl;
  992.     }
  993.     public function setInstagramUrl(?string $instagramUrl): self
  994.     {
  995.         $this->instagramUrl $instagramUrl;
  996.         return $this;
  997.     }
  998.     public function isECommerceWebsite(): bool
  999.     {
  1000.         return $this->eCommerceWebsite;
  1001.     }
  1002.     public function setECommerceWebsite(bool $eCommerceWebsite): self
  1003.     {
  1004.         $this->eCommerceWebsite $eCommerceWebsite;
  1005.         return $this;
  1006.     }
  1007.     public function isCatalanLanguage(): bool
  1008.     {
  1009.         return $this->catalanLanguage;
  1010.     }
  1011.     public function setCatalanLanguage(bool $catalanLanguage): self
  1012.     {
  1013.         $this->catalanLanguage $catalanLanguage;
  1014.         return $this;
  1015.     }
  1016.     public function getPointsLimit(): float
  1017.     {
  1018.         return $this->pointsLimit;
  1019.     }
  1020.     public function setPointsLimit(float $pointsLimit): self
  1021.     {
  1022.         $this->pointsLimit $pointsLimit;
  1023.         return $this;
  1024.     }
  1025.     public function getERP(): ?string
  1026.     {
  1027.         return $this->ERP;
  1028.     }
  1029.     public function setERP(?string $ERP): self
  1030.     {
  1031.         $this->ERP $ERP;
  1032.         return $this;
  1033.     }
  1034.     public function getGerente(): ?string
  1035.     {
  1036.         return $this->gerente;
  1037.     }
  1038.     public function setGerente(?string $gerente): self
  1039.     {
  1040.         $this->gerente $gerente;
  1041.         return $this;
  1042.     }
  1043.     public function isAllowBudgetRequest(): bool
  1044.     {
  1045.         return $this->allowBudgetRequest;
  1046.     }
  1047.     public function setAllowBudgetRequest(bool $allowBudgetRequest): self
  1048.     {
  1049.         $this->allowBudgetRequest $allowBudgetRequest;
  1050.         return $this;
  1051.     }
  1052.     public function isAllowGarageAppointment(): bool
  1053.     {
  1054.         return $this->allowGarageAppointment;
  1055.     }
  1056.     public function setAllowGarageAppointment(bool $allowGarageAppointment): self
  1057.     {
  1058.         $this->allowGarageAppointment $allowGarageAppointment;
  1059.         return $this;
  1060.     }
  1061.     public function isGrips(): bool
  1062.     {
  1063.         return $this->grips;
  1064.     }
  1065.     public function setGrips(bool $grips): self
  1066.     {
  1067.         $this->grips $grips;
  1068.         return $this;
  1069.     }
  1070.     public function isVulcoTruckRate(): bool
  1071.     {
  1072.         return $this->vulcoTruckRate;
  1073.     }
  1074.     public function setVulcoTruckRate(bool $vulcoTruckRate): self
  1075.     {
  1076.         $this->vulcoTruckRate $vulcoTruckRate;
  1077.         return $this;
  1078.     }
  1079.     public function getNameAndCodeString(): string
  1080.     {
  1081.         return $this->name.' ('.$this->code.')';
  1082.     }
  1083.     public function getNameAndCodeStringAndProvince(): string
  1084.     {
  1085.         return $this->name.' ('.$this->code.')'.' - '.$this->provinceName();
  1086.     }
  1087.     public function getPurchasesOf(int $year): ?array
  1088.     {
  1089.         $purchases = [];
  1090.         /** @var GaragePurchase $purchase */
  1091.         foreach ($this->purchases as $purchase) {
  1092.             if ($purchase->getYear() === $year) {
  1093.                 $purchases[] = $purchase;
  1094.             }
  1095.         }
  1096.         return $purchases;
  1097.     }
  1098.     public function diff(Garage $before): array
  1099.     {
  1100.         $diff = array();
  1101.         // general data
  1102.         if ($this->mobileAssociated !== $before->mobileAssociated) {
  1103.             $diff[] = ['garage.mobile_associated'$this->mobileAssociated];
  1104.         }
  1105.         if ($this->phone !== $before->phone) {
  1106.             $diff[] = ['garage.phone'$this->phone];
  1107.         }
  1108.         if ($this->mobile !== $before->mobile) {
  1109.             $diff[] = ['garage.mobile'$this->mobile];
  1110.         }
  1111.         if ($this->whatsapp !== $before->whatsapp) {
  1112.             $diff[] = ['garage.whatsapp'$this->whatsapp];
  1113.         }
  1114.         if ($this->whatsappCampaigns !== $before->whatsappCampaigns) {
  1115.             $diff[] = ['garage.whatsapp_campaigns'$this->whatsappCampaigns];
  1116.         }
  1117.         if ($this->whatsappCampaignsName !== $before->whatsappCampaignsName) {
  1118.             $diff[] = ['garage.whatsapp_campaigns_name'$this->whatsappCampaignsName];
  1119.         }
  1120.         if ($this->facebookUrl !== $before->facebookUrl) {
  1121.             $diff[] = ['garage.facebook'$this->facebookUrl];
  1122.         }
  1123.         if ($this->twitterUrl !== $before->twitterUrl) {
  1124.             $diff[] = ['garage.twitter'$this->twitterUrl];
  1125.         }
  1126.         if ($this->instagramUrl !== $before->instagramUrl) {
  1127.             $diff[] = ['garage.instagram'$this->instagramUrl];
  1128.         }
  1129.         // timetable_data
  1130.         $schedulesDiff $this->schedules->diff($before->schedules);
  1131.         if (!empty($schedulesDiff)) {
  1132.             $diff[] = ['garage.form.timetable_data'$schedulesDiff];
  1133.         }
  1134.         // address
  1135.         $addressDiff $this->address->diff($before->address);
  1136.         if (!empty($addressDiff)) {
  1137.             $diff[] = ['garage.form.address_data'$addressDiff];
  1138.         }
  1139.         // additional_addresses_data
  1140.         if ($this->additionalAddresses->isEmpty() && !$before->additionalAddresses->isEmpty()){
  1141.             $diff[] = ['garage.form.additional_addresses_data''todas las direcciones eliminadas'];
  1142.         } else if (!$this->additionalAddresses->isEmpty() && $before->additionalAddresses->isEmpty()) {
  1143.             foreach ($this->additionalAddresses as $address) {
  1144.                 $diff[] = ['garage.form.additional_address_data'$address->displayRawFields()];
  1145.             }
  1146.         } else if (!$this->additionalAddresses->isEmpty() && !$before->additionalAddresses->isEmpty()
  1147.             && (count($this->additionalAddresses) < count($before->additionalAddresses))) {
  1148.             $diff[] = ['garage.form.additional_addresses_data''hay cambios en las direcciones'];
  1149.         } else if (!$this->additionalAddresses->isEmpty() && !$before->additionalAddresses->isEmpty()
  1150.             && (count($this->additionalAddresses) > count($before->additionalAddresses))) {
  1151.             $diff[] = ['garage.form.additional_addresses_data''hay cambios en las direcciones'];
  1152.         } else if (!$this->additionalAddresses->isEmpty() && !$before->additionalAddresses->isEmpty()
  1153.             && (count($this->additionalAddresses) === count($before->additionalAddresses)))
  1154.         {
  1155.             $additionalAddresses $this->additionalAddresses->getValues(); // because an ArrayCollection could have not sequential indexes
  1156.             $beforeAddresses $before->additionalAddresses->getValues();
  1157.             for ($i 0$i count($additionalAddresses); $i++) {
  1158.                 //if ($additionalAddresses[$i]) { // puede que solo haya las que han sido modificadas
  1159.                     $addressDiff $additionalAddresses[$i]->diff($beforeAddresses[$i]);
  1160.                     if (!empty($addressDiff)) {
  1161.                         $diff[] = ['garage.form.additional_address_data'$additionalAddresses[$i]->displayRawFields()];
  1162.                     }
  1163.                 //}
  1164.             }
  1165.         }
  1166.         // typeVehicles
  1167.         if (empty($this->typeVehicles) && !empty($before->typeVehicles)
  1168.         ) {
  1169.             $diff[] = ['garage.form.vehicle_types_data''ítems eliminados'];
  1170.         } else {
  1171.             if (
  1172.                 (!empty($this->typeVehicles) && empty($before->typeVehicles))
  1173.                 || (!empty($this->typeVehicles) && !empty($before->typeVehicles) && (count($this->typeVehicles) !== count($before->typeVehicles)))
  1174.             )
  1175.             {
  1176.                 $typeVehiclesNames = array();
  1177.                 /** @var GarageVehicleType $item */
  1178.                 foreach ($this->typeVehicles as $item) {
  1179.                     $typeVehiclesNames[] = $item->getName();
  1180.                 }
  1181.                 $diff[] = ['garage.form.vehicle_types_data'implode(', '$typeVehiclesNames)];
  1182.             }
  1183.         }
  1184.         // facilities
  1185.         if (empty($this->facilities) && !empty($before->facilities)
  1186.         ) {
  1187.             $diff[] = ['garage.form.comforts_data''ítems eliminados'];
  1188.         } else {
  1189.             if (
  1190.                 (!empty($this->facilities) && empty($before->facilities))
  1191.                 || (!empty($this->facilities) && !empty($before->facilities) && (count($this->facilities) !== count($before->facilities)))
  1192.             )
  1193.             {
  1194.                 $facilitiesNames = array();
  1195.                 /** @var GarageFacility $item */
  1196.                 foreach ($this->facilities as $item) {
  1197.                     $facilitiesNames[] = $item->getName();
  1198.                 }
  1199.                 $diff[] = ['garage.form.comforts_data'implode(', '$facilitiesNames)];
  1200.             }
  1201.         }
  1202.         // services
  1203.         if (empty($this->services) && !empty($before->services)
  1204.         ) {
  1205.             $diff[] = ['garage.form.services_data''ítems eliminados'];
  1206.         } else {
  1207.             if (
  1208.                 (!empty($this->services) && empty($before->services))
  1209.                 || (!empty($this->services) && !empty($before->services) && (count($this->services) !== count($before->services)))
  1210.             )
  1211.             {
  1212.                 $servicesNames = array();
  1213.                 /** @var GarageService $item */
  1214.                 foreach ($this->services as $item) {
  1215.                     $servicesNames[] = $item->getName();
  1216.                 }
  1217.                 $diff[] = ['garage.form.services_data'implode(', '$servicesNames)];
  1218.             }
  1219.         }
  1220.         return $diff;
  1221.     }
  1222.     public function __toString(): string
  1223.     {
  1224.         return $this->id $this->getName() : MiniAbstractBase::DEFAULT_EMPTY_STRING;
  1225.     }
  1226. }