src/Entity/Promocion.php line 25

Open in your IDE?
  1. <?php
  2. namespace App\Entity;
  3. use App\Enum\EstadoRelojEnum;
  4. use DateTime;
  5. use DateTimeInterface;
  6. use Doctrine\Common\Collections\ArrayCollection;
  7. use Doctrine\Common\Collections\Collection;
  8. use Doctrine\Common\Collections\Criteria;
  9. use Doctrine\DBAL\Types\Types;
  10. use Doctrine\ORM\Mapping as ORM;
  11. use JMS\Serializer\Annotation as JMS;
  12. use Gedmo\Mapping\Annotation as Gedmo;
  13. use Symfony\Component\HttpFoundation\File\File;
  14. use Vich\UploaderBundle\Mapping\Annotation as Vich;
  15. /**
  16.  * @ORM\Entity(repositoryClass="App\Repository\PromocionRepository")
  17.  * @ORM\Table(name="promocion")
  18.  * @ORM\EntityListeners({"App\EntityListener\Promocion\CalcularIDPerseoListener"})
  19.  * @Gedmo\SoftDeleteable(fieldName="deletedAt", timeAware=false, hardDelete=true)
  20.  * @Vich\Uploadable
  21.  */
  22. class Promocion
  23. {
  24.     /**
  25.      * @ORM\Id
  26.      * @ORM\Column(type="bigint", options={"unsigned":true})
  27.      * @ORM\GeneratedValue(strategy="AUTO")
  28.      * @JMS\Groups({
  29.      *     "api_v1_promocion_serialize"
  30.      * })
  31.      */
  32.     protected $id;
  33.     /**
  34.      * @ORM\Column(type="string", nullable=true)
  35.      */
  36.     protected $IDperseo;
  37.     /**
  38.      * @ORM\Column(
  39.      *     type="string",
  40.      *     nullable=false,
  41.      *     options={"default":"COMPRA","comment":"valores a tomar (Compra, Gestión)"}
  42.      * )
  43.      * @JMS\Groups({
  44.      *      "api_v1_promocion_serialize"
  45.      *  })
  46.      */
  47.     protected $tipo;
  48.     /**
  49.      * @ORM\Column(type="datetime", nullable=true, name="fecha_listo", options={"comment":"La más antigua"})
  50.      */
  51.     protected $fechaListo;
  52.     /**
  53.      * @ORM\Column(type="datetime", nullable=true, name="fecha_promocion", options={"comment":"Fecha de la promoción vigente"})
  54.      * @JMS\Groups({
  55.      *      "api_v1_promocion_serialize"
  56.      *  })
  57.      */
  58.     protected $fechaPromocion;
  59.     /**
  60.      * @ORM\Column(
  61.      *     type="datetime",
  62.      *     nullable=true,
  63.      *     name="fecha_anuncio",
  64.      *     options={"comment":"La fecha del primer anuncio"}
  65.      * )
  66.      */
  67.     private $fechaAnuncio;
  68.     /**
  69.      * @deprecated 30-01-2026
  70.      * Este campo queda obsoleto porque la fecha de venta ya se obtiene directamente
  71.      * de la información propia del reloj, evitando duplicidad y posibles inconsistencias.
  72.      *
  73.      * @ORM\Column(type="datetime", nullable=true, name="fecha_venta")
  74.      */
  75.     protected $fechaVenta;
  76.     /**
  77.      * @ORM\Column(type="float", nullable=true, precision=2, options={"comment":"Precio de la promoción vigente"})
  78.      * @JMS\Groups({
  79.      *      "api_v1_promocion_serialize"
  80.      *  })
  81.      */
  82.     protected $precio;
  83.     /**
  84.      * @ORM\Column(type="float", nullable=true, precision=2)
  85.      */
  86.     protected $precioChrono24;
  87.     /**
  88.      * @ORM\Column(type="float", nullable=true, precision=2)
  89.      */
  90.     protected $margenBrutoEsperado;
  91.     /**
  92.      * @ORM\Column(type="float", nullable=true, precision=2)
  93.      */
  94.     protected $margenNetoEsperado;
  95.     /**
  96.      * @ORM\Column(type="float", nullable=true, precision=2, options={"comment":"% tiempo desde la compra"})
  97.      */
  98.     protected $tiempo;
  99.     /**
  100.      * @ORM\Column(type="text", length=16834, nullable=true, options={"comment":"formato html"})
  101.      */
  102.     protected $comentarioPublico;
  103.     /**
  104.      * @ORM\Column(type="text", length=256, nullable=true)
  105.      */
  106.     protected $comentarioPrivado;
  107.     /**
  108.      * @ORM\Column(type="text", nullable=true)
  109.      */
  110.     protected $descripcion;
  111.     /**
  112.      * @ORM\Column(type="string", nullable=true, name="ubicacion_actual", options={"comment":"Ubicación actual"})
  113.      * @JMS\Groups({
  114.      *      "api_v1_promocion_serialize"
  115.      *  })
  116.      */
  117.     protected $ubicacionActual;
  118.     /**
  119.      * @ORM\Column(type="datetime", nullable=true, name="fecha_ubicacion_actual")
  120.      * @JMS\Groups({
  121.      *       "api_v1_promocion_serialize"
  122.      *   })
  123.      */
  124.     protected $fechaUbicacionActual;
  125.     /**
  126.      * @ORM\Column(type="string", nullable=true, name="estado_actual")
  127.      * @JMS\Groups({
  128.      *      "api_v1_promocion_serialize"
  129.      *  })
  130.      */
  131.     protected $estadoActual;
  132.     /**
  133.      * @ORM\Column(type="datetime", nullable=true, name="fecha_estado_actual")
  134.      * @JMS\Groups({
  135.      *      "api_v1_promocion_serialize"
  136.      *  })
  137.      */
  138.     private $fechaEstadoActual;
  139.     /**
  140.      * @ORM\Column(type="json", nullable=true, options={"comment":"Servicio y Mejoras"})
  141.      */
  142.     protected $costes;
  143.     /**
  144.      * @ORM\Column(type="string", nullable=true, name="reloj_foto")
  145.      */
  146.     protected $relojFoto;
  147.     /**
  148.      * @Vich\UploadableField(mapping="reloj", fileNameProperty="reloj_foto")
  149.      * @var \Symfony\Component\HttpFoundation\File\File
  150.      */
  151.     protected $relojFotoFile;
  152.     /**
  153.      * @ORM\Column(type="string", nullable=true, name="reloj_foto_valoracion")
  154.      */
  155.     private $relojFotoValoracion;
  156.     /**
  157.      * @Vich\UploadableField(mapping="reloj", fileNameProperty="reloj_foto_valoracion")
  158.      * @var File
  159.      */
  160.     protected $relojFotoValoracionFile;
  161.     /**
  162.      * @ORM\Column(type="string", nullable=true, name="reloj_foto_set")
  163.      */
  164.     private $relojFotoSet;
  165.     /**
  166.      * @Vich\UploadableField(mapping="reloj", fileNameProperty="reloj_foto_set")
  167.      * @var File
  168.      */
  169.     protected $relojFotoSetFile;
  170.     /**
  171.      * @ORM\Column(type="string", nullable=true, name="reloj_foto_crono", options={"comment":"foto del cronocomparador"})
  172.      */
  173.     private $relojFotoCrono;
  174.     /**
  175.      * @Vich\UploadableField(mapping="reloj", fileNameProperty="reloj_foto_crono")
  176.      * @var File
  177.      */
  178.     protected $relojFotoCronoFile;
  179.     /**
  180.      * @ORM\Column(type="string", nullable=true, name="reloj_video")
  181.      */
  182.     private $relojVideo;
  183.     /**
  184.      * @Vich\UploadableField(mapping="reloj", fileNameProperty="reloj_video")
  185.      * @var File
  186.      */
  187.     protected $relojVideoFile;
  188.     /**
  189.      * @ORM\Column(type="float", nullable=true, precision=2)
  190.      */
  191.     private $recompra;
  192.     /**
  193.      * @ORM\Column(type="string", nullable=true)
  194.      */
  195.     private $garantia;
  196.     /**
  197.      * @ORM\Column(
  198.      *     type="boolean",
  199.      *     nullable=true,
  200.      *     options={
  201.      *         "default":1,
  202.      *         "comment":"Utilizado cuando ya existe promoción y has deshecho parte de operación y hay que desactivar
  203.      *     promoción hasta que operación este en estado aceptada."
  204.      *     }
  205.      * )
  206.      * @JMS\Groups({
  207.      *      "api_v1_promocion_serialize"
  208.      *  })
  209.      */
  210.     protected $active;
  211.     /**
  212.      * @ORM\Column(type="datetime", nullable=true, name="deleted_at")
  213.      * @JMS\Groups({
  214.      *      "api_v1_promocion_serialize"
  215.      *  })
  216.      */
  217.     protected $deletedAt;
  218.     /**
  219.      * @ORM\Column(type="datetime", nullable=false, name="updated_at", options={"default":"2022-01-01 00:00:00"})
  220.      * @Gedmo\Timestampable(on="update")
  221.      */
  222.     protected $updatedAt;
  223.     /**
  224.      * @ORM\Column(type="datetime", nullable=false, name="created_at", options={"default":"2022-01-01 00:00:00"})
  225.      * @Gedmo\Timestampable(on="create")
  226.      */
  227.     protected $createdAt;
  228.     /**
  229.      * @ORM\JoinColumn(name="reloj_id", referencedColumnName="id", unique=true)
  230.      * @ORM\OneToOne(targetEntity=\App\Entity\Reloj::class, inversedBy="promociones")
  231.      * @JMS\Type(Reloj::class)
  232.      * @JMS\Groups({
  233.      *      "api_v1_promocion_serialize"
  234.      *  })
  235.      */
  236.     protected $reloj;
  237.     /**
  238.      * @ORM\OneToMany(targetEntity="App\Entity\AccionAbstract", mappedBy="promocion")
  239.      */
  240.     protected $acciones;
  241.     public function __construct()
  242.     {
  243.         $this->acciones = new ArrayCollection();
  244.     }
  245.     public function __toString(): string
  246.     {
  247.         return $this->getIDperseo().'';
  248.     }
  249.     public function getId(): ?string
  250.     {
  251.         return $this->id;
  252.     }
  253.     public function getFechaInicio(): ?DateTimeInterface
  254.     {
  255.         return $this->fechaInicio;
  256.     }
  257.     public function setFechaInicio(?DateTimeInterface $fechaInicio): self
  258.     {
  259.         $this->fechaInicio = $fechaInicio;
  260.         return $this;
  261.     }
  262.     public function getFechaFin(): ?DateTimeInterface
  263.     {
  264.         return $this->fechaFin;
  265.     }
  266.     public function setFechaFin(?DateTimeInterface $fechaFin): self
  267.     {
  268.         $this->fechaFin = $fechaFin;
  269.         return $this;
  270.     }
  271.     public function getPrecio(): ?float
  272.     {
  273.         return $this->precio;
  274.     }
  275.     public function setPrecio(?float $precio): self
  276.     {
  277.         $this->precio = $precio;
  278.         return $this;
  279.     }
  280.     public function getDeletedAt(): ?DateTimeInterface
  281.     {
  282.         return $this->deletedAt;
  283.     }
  284.     public function setDeletedAt(?DateTimeInterface $deletedAt): self
  285.     {
  286.         $this->deletedAt = $deletedAt;
  287.         return $this;
  288.     }
  289.     public function getUpdatedAt(): ?DateTimeInterface
  290.     {
  291.         return $this->updatedAt;
  292.     }
  293.     public function setUpdatedAt(DateTimeInterface $updatedAt): self
  294.     {
  295.         $this->updatedAt = $updatedAt;
  296.         return $this;
  297.     }
  298.     public function getCreatedAt(): ?DateTimeInterface
  299.     {
  300.         return $this->createdAt;
  301.     }
  302.     public function setCreatedAt(DateTimeInterface $createdAt): self
  303.     {
  304.         $this->createdAt = $createdAt;
  305.         return $this;
  306.     }
  307.     public function getCanal(): ?Canal
  308.     {
  309.         return $this->canal;
  310.     }
  311.     public function setCanal(?Canal $canal): self
  312.     {
  313.         $this->canal = $canal;
  314.         return $this;
  315.     }
  316.     public function getFechaPromocion(): ?DateTimeInterface
  317.     {
  318.         return $this->fechaPromocion;
  319.     }
  320.     public function setFechaPromocion(?DateTimeInterface $fechaPromocion): self
  321.     {
  322.         $this->fechaPromocion = $fechaPromocion;
  323.         return $this;
  324.     }
  325.     public function getMargenBrutoEsperado(): ?float
  326.     {
  327.         return $this->margenBrutoEsperado;
  328.     }
  329.     public function setMargenBrutoEsperado(?float $margenBrutoEsperado): self
  330.     {
  331.         $this->margenBrutoEsperado = $margenBrutoEsperado;
  332.         return $this;
  333.     }
  334.     public function getMargenNetoEsperado(): ?float
  335.     {
  336.         return $this->margenNetoEsperado;
  337.     }
  338.     public function setMargenNetoEsperado(?float $margenNetoEsperado): self
  339.     {
  340.         $this->margenNetoEsperado = $margenNetoEsperado;
  341.         return $this;
  342.     }
  343.     public function getTiempo(): ?float
  344.     {
  345.         return $this->tiempo;
  346.     }
  347.     public function setTiempo(?float $tiempo): self
  348.     {
  349.         $this->tiempo = $tiempo;
  350.         return $this;
  351.     }
  352.     public function getComentarioPublico(): ?string
  353.     {
  354.         return $this->comentarioPublico;
  355.     }
  356.     public function setComentarioPublico(?string $comentarioPublico): self
  357.     {
  358.         $this->comentarioPublico = $comentarioPublico;
  359.         return $this;
  360.     }
  361.     public function getComentarioPrivado(): ?string
  362.     {
  363.         return $this->comentarioPrivado;
  364.     }
  365.     public function setComentarioPrivado(?string $comentarioPrivado): self
  366.     {
  367.         $this->comentarioPrivado = $comentarioPrivado;
  368.         return $this;
  369.     }
  370.     /**
  371.      * @return Collection<int, AccionAbstract>
  372.      */
  373.     public function getAcciones(): Collection
  374.     {
  375.         return $this->acciones;
  376.     }
  377.     public function addAccione(AccionAbstract $accione): self
  378.     {
  379.         if (!$this->acciones->contains($accione)) {
  380.             $this->acciones->add($accione);
  381.             $accione->setPromocion($this);
  382.         }
  383.         return $this;
  384.     }
  385.     public function removeAccione(AccionAbstract $accione): self
  386.     {
  387.         if ($this->acciones->removeElement($accione)) {
  388.             // set the owning side to null (unless already changed)
  389.             if ($accione->getPromocion() === $this) {
  390.                 $accione->setPromocion(null);
  391.             }
  392.         }
  393.         return $this;
  394.     }
  395.     public function getReloj(): ?Reloj
  396.     {
  397.         return $this->reloj;
  398.     }
  399.     public function setReloj(?Reloj $reloj): static
  400.     {
  401.         $this->reloj = $reloj;
  402.         return $this;
  403.     }
  404.     public function getIDperseo(): ?string
  405.     {
  406.         return $this->IDperseo;
  407.     }
  408.     public function setIDperseo(?string $IDperseo): static
  409.     {
  410.         $this->IDperseo = $IDperseo;
  411.         return $this;
  412.     }
  413.     public function getPrecioChrono24(): ?float
  414.     {
  415.         return $this->precioChrono24;
  416.     }
  417.     public function setPrecioChrono24(?float $precioChrono24): static
  418.     {
  419.         $this->precioChrono24 = $precioChrono24;
  420.         return $this;
  421.     }
  422.     public function getDescripcion(): ?string
  423.     {
  424.         return $this->descripcion;
  425.     }
  426.     public function setDescripcion(?string $descripcion): static
  427.     {
  428.         $this->descripcion = $descripcion;
  429.         return $this;
  430.     }
  431.     public function getUbicacionActual(): ?string
  432.     {
  433.         return $this->ubicacionActual;
  434.     }
  435.     public function setUbicacionActual(?string $ubicacionActual): static
  436.     {
  437.         $this->ubicacionActual = $ubicacionActual;
  438.         return $this;
  439.     }
  440.     public function getEstadoActual(): ?string
  441.     {
  442.         $sort = new Criteria(null, ['fecha' => Criteria::DESC, 'createdAt' => Criteria::DESC]);
  443.         $acciones = $this->getAcciones()->matching($sort);
  444.         foreach ($acciones as $accion)
  445.         {
  446.             if(!$accion instanceof AccionServicio && !$accion instanceof AccionMejora && !$accion instanceof AccionCompetencia) break;
  447.         }
  448.         $checked = @$accion instanceof AccionCheck && $accion->getEstado() !== null;
  449.         return $checked ? '---' : $this->estadoActual;
  450.     }
  451.     public function setEstadoActual(?string $estadoActual): static
  452.     {
  453.         $this->estadoActual = $estadoActual;
  454.         return $this;
  455.     }
  456.     public function getCostes(): ?array
  457.     {
  458.         return $this->costes;
  459.     }
  460.     public function setCostes(?array $costes): static
  461.     {
  462.         $this->costes = $costes;
  463.         return $this;
  464.     }
  465.     public function getUbicacion(): string
  466.     {
  467.         return '---';
  468.     }
  469.     public function getTipo(): ?string
  470.     {
  471.         return $this->tipo;
  472.     }
  473.     public function setTipo(string $tipo): static
  474.     {
  475.         $this->tipo = $tipo;
  476.         return $this;
  477.     }
  478.     public function getFechaListo(): ?DateTimeInterface
  479.     {
  480.         return $this->fechaListo;
  481.     }
  482.     public function setFechaListo(?DateTimeInterface $fechaListo): static
  483.     {
  484.         $this->fechaListo = $fechaListo;
  485.         return $this;
  486.     }
  487.     public function getFechaVenta(): ?DateTimeInterface
  488.     {
  489.         return $this->fechaVenta;
  490.     }
  491.     public function setFechaVenta(?DateTimeInterface $fechaVenta): static
  492.     {
  493.         $this->fechaVenta = $fechaVenta;
  494.         return $this;
  495.     }
  496.     public function getRelojFoto(): ?string
  497.     {
  498.         return $this->relojFoto;
  499.     }
  500.     public function setRelojFoto(?string $relojFoto): static
  501.     {
  502.         $this->relojFoto = $relojFoto;
  503.         return $this;
  504.     }
  505.     public function getRelojFotoFile(): ?File
  506.     {
  507.         return $this->relojFotoFile;
  508.     }
  509.     public function setRelojFotoFile(?File $relojFotoFile): static
  510.     {
  511.         $this->relojFotoFile = $relojFotoFile;
  512.         if($relojFotoFile)
  513.         {
  514.             $this->setUpdatedAt(new DateTime('now'));
  515.         }
  516.         return $this;
  517.     }
  518.     public function getRelojFotoValoracion(): ?string
  519.     {
  520.         return $this->relojFotoValoracion;
  521.     }
  522.     public function setRelojFotoValoracion(?string $relojFotoValoracion): static
  523.     {
  524.         $this->relojFotoValoracion = $relojFotoValoracion;
  525.         return $this;
  526.     }
  527.     public function getRelojFotoValoracionFile(): ?File
  528.     {
  529.         return $this->relojFotoValoracionFile;
  530.     }
  531.     public function setRelojFotoValoracionFile(?File $relojFotoValoracionFile): static
  532.     {
  533.         $this->relojFotoValoracionFile = $relojFotoValoracionFile;
  534.         if($relojFotoValoracionFile)
  535.         {
  536.             $this->setUpdatedAt(new DateTime('now'));
  537.         }
  538.         return $this;
  539.     }
  540.     public function getRelojFotoSet(): ?string
  541.     {
  542.         return $this->relojFotoSet;
  543.     }
  544.     public function setRelojFotoSet(?string $relojFotoSet): static
  545.     {
  546.         $this->relojFotoSet = $relojFotoSet;
  547.         return $this;
  548.     }
  549.     public function getRelojFotoSetFile(): ?File
  550.     {
  551.         return $this->relojFotoSetFile;
  552.     }
  553.     public function setRelojFotoSetFile(?File $relojFotoSetFile): static
  554.     {
  555.         $this->relojFotoSetFile = $relojFotoSetFile;
  556.         if($relojFotoSetFile)
  557.         {
  558.             $this->setUpdatedAt(new DateTime('now'));
  559.         }
  560.         return $this;
  561.     }
  562.     public function getRelojFotoCrono(): ?string
  563.     {
  564.         return $this->relojFotoCrono;
  565.     }
  566.     public function setRelojFotoCrono(?string $relojFotoCrono): static
  567.     {
  568.         $this->relojFotoCrono = $relojFotoCrono;
  569.         return $this;
  570.     }
  571.     public function getRelojFotoCronoFile(): ?File
  572.     {
  573.         return $this->relojFotoCronoFile;
  574.     }
  575.     public function setRelojFotoCronoFile(?File $relojFotoCronoFile): static
  576.     {
  577.         $this->relojFotoCronoFile = $relojFotoCronoFile;
  578.         if($relojFotoCronoFile)
  579.         {
  580.             $this->setUpdatedAt(new DateTime('now'));
  581.         }
  582.         return $this;
  583.     }
  584.     public function getRelojVideo(): ?string
  585.     {
  586.         return $this->relojVideo;
  587.     }
  588.     public function setRelojVideo(?string $relojVideo): static
  589.     {
  590.         $this->relojVideo = $relojVideo;
  591.         return $this;
  592.     }
  593.     public function getRelojVideoFile(): ?File
  594.     {
  595.         return $this->relojVideoFile;
  596.     }
  597.     public function setRelojVideoFile(?File $relojVideoFile): static
  598.     {
  599.         $this->relojVideoFile = $relojVideoFile;
  600.         if($relojVideoFile)
  601.         {
  602.             $this->setUpdatedAt(new DateTime('now'));
  603.         }
  604.         return $this;
  605.     }
  606.     public function isActive(): ?bool
  607.     {
  608.         return $this->active;
  609.     }
  610.     public function setActive(?bool $active): static
  611.     {
  612.         $this->active = $active;
  613.         return $this;
  614.     }
  615.     public function getRecompra(): ?float
  616.     {
  617.         return $this->recompra;
  618.     }
  619.     public function setRecompra(?float $recompra): static
  620.     {
  621.         $this->recompra = $recompra;
  622.         return $this;
  623.     }
  624.     public function getGarantia(): ?string
  625.     {
  626.         return $this->garantia;
  627.     }
  628.     public function setGarantia(?string $garantia): static
  629.     {
  630.         $this->garantia = $garantia;
  631.         return $this;
  632.     }
  633.     public function getExportFechaPromocion(): ?string
  634.     {
  635.         return $this->getFechaPromocion()?->format('d/m/Y');
  636.     }
  637.     public function fechaEstadoCompraStr(): ?string
  638.     {
  639.         return $this->fechaEstadoCompra()?->format('d/m/Y');
  640.     }
  641.     /**
  642.      * Obtiene la fecha en la que la entidad pasó al estado de compra.
  643.      *
  644.      * El valor se obtiene a partir de las acciones asociadas a la entidad.
  645.      * Se expone como propiedad virtual para aquellos mecanismos que necesiten
  646.      * serializar o consultar este valor.
  647.      *
  648.      * @JMS\VirtualProperty()
  649.      * @JMS\SerializedName("fecha_estado_compra")
  650.      * @JMS\Groups({
  651.      *     "api_v1_promocion_serialize"
  652.      * })
  653.      * @return DateTimeInterface|null
  654.      */
  655.     public function fechaEstadoCompra(): ?DateTimeInterface
  656.     {
  657.         $estado = $this->getAcciones()->filter(fn($accion) => $accion instanceof AccionEstado && $accion->getEstado()?->getKey() === EstadoRelojEnum::ESTADO_COMPRA )->first();
  658.         return $estado ? $estado->getFecha() : null;
  659.     }
  660.     public function fechaEstadoRecepcionStr(): ?string
  661.     {
  662.         return $this->fechaEstadoRecepcion()?->format('d/m/Y');
  663.     }
  664.     public function fechaEstadoRecepcion(): ?DateTimeInterface
  665.     {
  666.         $estado = $this->getAcciones()->filter(fn($accion) => $accion instanceof AccionEstado && $accion->getEstado()?->getKey() === EstadoRelojEnum::ESTADO_RECEPCION )->first();
  667.         return $estado ? $estado->getFecha() : null;
  668.     }
  669.     public function getFechaUbicacionActual(): ?DateTimeInterface
  670.     {
  671.         return $this->fechaUbicacionActual;
  672.     }
  673.     public function setFechaUbicacionActual(?DateTimeInterface $fechaUbicacionActual): static
  674.     {
  675.         $this->fechaUbicacionActual = $fechaUbicacionActual;
  676.         return $this;
  677.     }
  678.     public function getFechaAnuncio(): ?DateTimeInterface
  679.     {
  680.         return $this->fechaAnuncio;
  681.     }
  682.     public function setFechaAnuncio(?DateTimeInterface $fechaAnuncio): static
  683.     {
  684.         $this->fechaAnuncio = $fechaAnuncio;
  685.         return $this;
  686.     }
  687.     public function getFechaEstadoActual(): ?DateTimeInterface
  688.     {
  689.         return $this->fechaEstadoActual;
  690.     }
  691.     public function setFechaEstadoActual(?DateTimeInterface $fechaEstadoActual): static
  692.     {
  693.         $this->fechaEstadoActual = $fechaEstadoActual;
  694.         return $this;
  695.     }
  696.     public function calculateUbicacion()
  697.     {
  698.         $ubicacionMasReciente = $this->getAcciones()
  699.             ->filter(fn($accion) => $accion instanceof AccionUbicacion)
  700.             ->reduce(
  701.                 function (?AccionUbicacion $masReciente, AccionUbicacion $actual) {
  702.                     if ($masReciente === null || $actual->getFecha() > $masReciente->getFecha()) {
  703.                         return $actual;
  704.                     }
  705.                     return $masReciente;
  706.                 },
  707.                 null
  708.             );
  709.         $this->setUbicacionActual($ubicacionMasReciente);
  710.         $this->setFechaUbicacionActual($ubicacionMasReciente?->getFecha());
  711.         return $ubicacionMasReciente;
  712.     }
  713.     public function calculateFirstAnuncio(): ?AccionEstado
  714.     {
  715.         $anuncioFirst = $this->getAccionesAnuncio()
  716.             ->reduce(
  717.                 function (?AccionEstado $primero, AccionEstado $actual): ?AccionEstado {
  718.                     return $primero === null || $actual->getFecha() < $primero->getFecha()
  719.                         ? $actual
  720.                         : $primero;
  721.                 },
  722.                 null
  723.             );
  724.         $this->setfechaAnuncio($anuncioFirst?->getFecha());
  725.         return $anuncioFirst;
  726.     }
  727.     public function calculateLastAnuncio(): ?AccionEstado
  728.     {
  729.         $anuncioLast = $this->getAccionesAnuncio()
  730.             ->reduce(
  731.                 function (?AccionEstado $ultimo, AccionEstado $actual): ?AccionEstado {
  732.                     return $ultimo === null || $actual->getFecha() > $ultimo->getFecha()
  733.                         ? $actual
  734.                         : $ultimo;
  735.                 },
  736.                 null
  737.             );
  738.         $this->setPrecio($anuncioLast?->getPrecio());
  739.         $this->setfechaPromocion($anuncioLast?->getFecha());
  740.         return $anuncioLast;
  741.     }
  742.     private function getAccionesAnuncio(): Collection
  743.     {
  744.         return $this->getAcciones()->filter(
  745.             fn($accion) =>
  746.                 $accion instanceof AccionEstado
  747.                 && $accion->getEstado()->getKey() === EstadoRelojEnum::ESTADO_ANUNCIO
  748.         );
  749.     }
  750. }