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