src/Model/Shop/Event/EventProduct.php line 87

Open in your IDE?
  1. <?php
  2. /**
  3.  * Created by Elements.at New Media Solutions GmbH
  4.  *
  5.  */
  6. namespace App\Model\Shop\Event;
  7. use App\Ecommerce\AvailabilitySystem\Event\Availability;
  8. use App\Ecommerce\PriceSystem\Event\PriceSystem;
  9. use App\Model\Shop\CancelableInterface;
  10. use App\Model\Shop\OrderItem;
  11. use App\Model\Shop\TeaserInfoInterface;
  12. use Carbon\Carbon;
  13. use Elements\Bundle\RecurringDatesTypeBundle\Templating\RecurringDatesHelper;
  14. use Elements\Bundle\TicketShopFrameworkBundle\Ecommerce\PricingManager\PriceInfo;
  15. use Elements\Bundle\TicketShopFrameworkBundle\Model\DataObject\ProductDateInterface;
  16. use Elements\Bundle\TicketShopFrameworkBundle\Model\Shop\Product\CheckoutableInterface;
  17. use Elements\Bundle\TicketShopFrameworkBundle\Model\Traits\ProductTrait;
  18. use Pimcore\Bundle\EcommerceFrameworkBundle\AvailabilitySystem\AvailabilityInterface;
  19. use Pimcore\Bundle\EcommerceFrameworkBundle\Model\ProductInterface;
  20. use Pimcore\Bundle\EcommerceFrameworkBundle\PriceSystem\PriceInfoInterface;
  21. use Pimcore\Bundle\EcommerceFrameworkBundle\PriceSystem\PriceInterface;
  22. use Pimcore\Model\Asset\Image;
  23. use Pimcore\Model\DataObject\AbstractObject;
  24. use Pimcore\Model\DataObject\ShopEvent;
  25. /**
  26.  * Class EventProduct
  27.  *
  28.  * @method null|ShopDynamicPrice getOrderedPriceItem()
  29.  */
  30. class EventProduct extends ShopEvent implements
  31.     ProductInterface,
  32.     CheckoutableInterface,
  33.     ProductDateInterface,
  34.     TeaserInfoInterface,
  35.     CancelableInterface
  36. {
  37.     use ProductTrait;
  38.     const PRODUCT_TYPE 'event';
  39.     public function getPriceSystemName(): ?string
  40.     {
  41.         return $this->getShopSystemName();
  42.     }
  43.     public function getAvailabilitySystemName(): ?string
  44.     {
  45.         return $this->getShopSystemName();
  46.     }
  47.     protected function getShopSystemName(): ?string
  48.     {
  49.         return self::PRODUCT_TYPE;
  50.     }
  51.     public function needsDelivery(): bool
  52.     {
  53.         return false;
  54.     }
  55.     public function isBookable(int $quantityScale 1bool $useCheckoutable false): bool
  56.     {
  57.         /** @var Availability|null $availability */
  58.         $availability $this->getOSAvailabilityInfo($quantityScale);
  59.         if ($useCheckoutable) {
  60.             return $this->isPublished() && $availability?->isCheckoutable();
  61.         } else {
  62.             return $this->isPublished() && $availability?->getAvailable();
  63.         }
  64.     }
  65.     public function getOSPrice($quantityScale 1): ?PriceInterface
  66.     {
  67.         return $this->getOSPriceInfo($quantityScale)->getPrice();
  68.     }
  69.     public function getOSIsBookable($quantityScale 1): bool
  70.     {
  71.         $price $this->getOSPrice($quantityScale);
  72.         return $this->isBookable() && !empty($price->getGrossAmount()->asNumeric());
  73.     }
  74.     /** @phpstan-ignore-next-line  */
  75.     public function getOSPriceInfo($quantityScale 1$products nullCarbon $date null): ?PriceInfoInterface
  76.     {
  77.         /** @var PriceSystem $priceSystem */
  78.         $priceSystem $this->getPriceSystemImplementation();
  79.         return $priceSystem->getPriceInfo($this$quantityScale$products$date);
  80.     }
  81.     public function getOSAvailabilityInfo($quantity null): ?AvailabilityInterface
  82.     {
  83.         return $this->getAvailabilitySystemImplementation()->getAvailabilityInfo($this$quantity);
  84.     }
  85.     public function getProductStartDate(): ?Carbon
  86.     {
  87.         return $this->getEventStartDate();
  88.     }
  89.     public function getTeaserPrice(): ?PriceInterface
  90.     {
  91.         /** @var PriceInfo $priceInfo */
  92.         $priceInfo $this->getOSPriceInfo();
  93.         return $priceInfo->getBasePrice();
  94.     }
  95.     public function getTeaserTopTitle(): ?string
  96.     {
  97.         if ($category $this->getProductCategory()) {
  98.             return $category->getName();
  99.         }
  100.         return '';
  101.     }
  102.     public function getTeaserDescription(): ?string
  103.     {
  104.         return $this->getShortDescription();
  105.     }
  106.     public function getTeaserImage(): ?Image
  107.     {
  108.         return $this->getMainImage();
  109.     }
  110.     /**
  111.      * Events got no validity date on the teaser
  112.      *
  113.      * @return array<mixed>
  114.      */
  115.     public function getTeaserValidity(): array
  116.     {
  117.         return [];
  118.     }
  119.     /**
  120.      * @return ShopDynamicPrice[]
  121.      */
  122.     public function getPriceObjects(): array
  123.     {
  124.         $priceObjs = [];
  125.         if ($items $this->getPrices()) {
  126.             foreach ($items as $item) {
  127.                 /** @var ShopDynamicPrice $priceObj */
  128.                 $priceObj $item->getObject();
  129.                 if ($priceObj->getPrice()) {
  130.                     $priceObjs[] = $priceObj;
  131.                 }
  132.             }
  133.         }
  134.         return $priceObjs;
  135.     }
  136.     /**
  137.      * @return array<mixed>
  138.      */
  139.     public function getPriceObjectGrouped(): array
  140.     {
  141.         $groupedObjs = [];
  142.         if ($items $this->getPrices()) {
  143.             foreach ($items as $item) {
  144.                 /** @var ShopDynamicPrice $priceObj */
  145.                 $priceObj $item->getObject();
  146.                 if ($priceObj->getPrice()) {
  147.                     $groupedObjs[$item->getGroupname()][] = $priceObj;
  148.                 }
  149.             }
  150.         }
  151.         return $groupedObjs;
  152.     }
  153.     /**
  154.      * Get price group containing the given price description
  155.      *
  156.      * @param ShopDynamicPrice $priceDescription
  157.      *
  158.      * @return string
  159.      */
  160.     public function getPriceGroupForPriceDescription(?ShopDynamicPrice $priceDescription): string
  161.     {
  162.         if ($priceDescription) {
  163.             /** @phpstan-ignore-next-line  */
  164.             foreach ($this->getReference()->getPrices() as $price) {
  165.                 if ($price->getObject()->getId() == $priceDescription->getId()) {
  166.                     return $price->getGroupname();
  167.                 }
  168.             }
  169.         }
  170.         return '';
  171.     }
  172.     /**
  173.      * @param Carbon|null $startDate
  174.      * @param ShopDynamicPrice|null $priceItem
  175.      *
  176.      * @return EventProduct
  177.      *
  178.      * @throws \Exception
  179.      */
  180.     public function getOrCreateOrderableObject(Carbon $startDate nullShopDynamicPrice $priceItem null): self
  181.     {
  182.         if ($this->getBookableOnDayOfEvent()) {
  183.             $startDate->endOfDay();
  184.         }
  185.         $key sprintf('%s-%s-%s',
  186.             $this->getKey(),
  187.             $startDate->toDateTimeString(),
  188.             $priceItem $priceItem->getId() : ''
  189.         );
  190.         $list = new ShopEvent\Listing();
  191.         $list->setObjectTypes([AbstractObject::OBJECT_TYPE_VARIANT]);
  192.         $list->addConditionParam('o_parentId = ?'$this->getId());
  193.         $list->addConditionParam('ifnull(o_key,0) = ?'$key);
  194.         $list->addConditionParam('eventStartDate >= ?'$startDate->timestamp);
  195.         if ($list->count() == 0) {
  196.             // create variant for booking
  197.             $orderObject = new self();
  198.             $orderObject->setPublished(true);
  199.             $orderObject->setType(AbstractObject::OBJECT_TYPE_VARIANT);
  200.             $orderObject->setParent($this);
  201.             $orderObject->setKey($key);
  202.             $orderObject->setEventStartDate($startDate);
  203.             $orderObject->setOrderedPriceItem($priceItem);
  204.             $orderObject->save();
  205.         } else {
  206.             /** @var EventProduct $orderObject */
  207.             $orderObject $list->current();
  208.         }
  209.         return $orderObject;
  210.     }
  211.     public function isPersonsTimeList(): bool
  212.     {
  213.         if ($prices $this->getPrices()) {
  214.             $price array_pop($prices);
  215.             return !empty($price->getGroupname());
  216.         }
  217.         return false;
  218.     }
  219.     public function isCancelable(OrderItem $orderItem null): bool
  220.     {
  221.         return true;
  222.     }
  223.     public function getFirstValidValidityDate(Carbon $date): ?Carbon
  224.     {
  225.         $validityDate null;
  226.         $firstValidityDateRange $this->getFirstValidDateRange($date);
  227.         if (isset($firstValidityDateRange['from'])) {
  228.             /** @var Carbon $fromDateValidity */
  229.             $fromDateValidity $firstValidityDateRange['from'];
  230.             $validityDate $fromDateValidity->lt($date) ? $date $fromDateValidity;
  231.         }
  232.         return $validityDate;
  233.     }
  234.     /**
  235.      * @param Carbon $date
  236.      *
  237.      * @return  array<mixed>
  238.      */
  239.     public function getFirstValidDateRange(Carbon $date): array
  240.     {
  241.         $recurringDatesHelper = new RecurringDatesHelper();
  242.         if ($validityDates $recurringDatesHelper->getCalculatedDates($this'getValidityDates')) {
  243.             foreach ($validityDates as $validityDate) {
  244.                 $fromDate Carbon::parse($validityDate['fromDate']);
  245.                 $toDate Carbon::parse($validityDate['toDate']);
  246.                 if (($validityDate['type'] == 'RecurringDate' || $validityDate['type'] == 'RecurringDateTime')
  247.                     && ($date->between($fromDate$toDate) || $fromDate->gte($date))
  248.                 ) {
  249.                     return [
  250.                         'from' => $fromDate,
  251.                         'to' => $toDate,
  252.                     ];
  253.                 }
  254.             }
  255.         }
  256.         return [];
  257.     }
  258.     /**
  259.      *
  260.      * returns all valid date ranges now and in the future, if no dateformat is given, dats are returned as timestamp
  261.      *
  262.      * @param Carbon $date
  263.      *
  264.      * @return  array<mixed>
  265.      */
  266.     public function getAllValidDateRanges(?Carbon $date nullstring $dateFormat null): array
  267.     {
  268.         $ranges = [];
  269.         if(!$date) {
  270.             $date Carbon::now()->startOfDay();
  271.         }
  272.         if ($validDates $this->getValidityDates()) {
  273.             if ($definitions $validDates->getDefinitionArray()) {
  274.                 foreach ($definitions as $definition) {
  275.                     if(!isset($definition['values']['fromDate']) && isset($definition['values']['date'])) {
  276.                         $fromDate Carbon::parse($definition['values']['date']);
  277.                         $toDate = clone $fromDate;
  278.                     } else {
  279.                         $fromDate Carbon::parse($definition['values']['fromDate']);
  280.                         $toDate Carbon::parse($definition['values']['toDate']);
  281.                     }
  282.                     if (($definition['type'] == 'FixedDate' || $definition['type'] == 'RecurringDate' || $definition['type'] == 'RecurringDateTime')
  283.                         && ($date->between($fromDate$toDate) || $fromDate->gte($date) || $fromDate->getTimestamp()==$date->getTimestamp())
  284.                     ) {
  285.                         $ranges[] = [
  286.                             'from' => $fromDate,
  287.                             'to' => $toDate,
  288.                         ];
  289.                     }
  290.                 }
  291.             }
  292.         }
  293.         return $ranges;
  294.     }
  295. }