- <?php
- /**
-  * Created by Elements.at New Media Solutions GmbH
-  *
-  */
- namespace App\Model\Shop\Event;
- use App\Ecommerce\AvailabilitySystem\Event\Availability;
- use App\Ecommerce\PriceSystem\Event\PriceSystem;
- use App\Model\Shop\CancelableInterface;
- use App\Model\Shop\OrderItem;
- use App\Model\Shop\TeaserInfoInterface;
- use Carbon\Carbon;
- use Elements\Bundle\RecurringDatesTypeBundle\Templating\RecurringDatesHelper;
- use Elements\Bundle\TicketShopFrameworkBundle\Ecommerce\PricingManager\PriceInfo;
- use Elements\Bundle\TicketShopFrameworkBundle\Model\DataObject\ProductDateInterface;
- use Elements\Bundle\TicketShopFrameworkBundle\Model\Shop\Product\CheckoutableInterface;
- use Elements\Bundle\TicketShopFrameworkBundle\Model\Traits\ProductTrait;
- use Pimcore\Bundle\EcommerceFrameworkBundle\AvailabilitySystem\AvailabilityInterface;
- use Pimcore\Bundle\EcommerceFrameworkBundle\Model\ProductInterface;
- use Pimcore\Bundle\EcommerceFrameworkBundle\PriceSystem\PriceInfoInterface;
- use Pimcore\Bundle\EcommerceFrameworkBundle\PriceSystem\PriceInterface;
- use Pimcore\Model\Asset\Image;
- use Pimcore\Model\DataObject\AbstractObject;
- use Pimcore\Model\DataObject\ShopEvent;
- /**
-  * Class EventProduct
-  *
-  * @method null|ShopDynamicPrice getOrderedPriceItem()
-  */
- class EventProduct extends ShopEvent implements
-     ProductInterface,
-     CheckoutableInterface,
-     ProductDateInterface,
-     TeaserInfoInterface,
-     CancelableInterface
- {
-     use ProductTrait;
-     const PRODUCT_TYPE = 'event';
-     public function getPriceSystemName(): ?string
-     {
-         return $this->getShopSystemName();
-     }
-     public function getAvailabilitySystemName(): ?string
-     {
-         return $this->getShopSystemName();
-     }
-     protected function getShopSystemName(): ?string
-     {
-         return self::PRODUCT_TYPE;
-     }
-     public function needsDelivery(): bool
-     {
-         return false;
-     }
-     public function isBookable(int $quantityScale = 1, bool $useCheckoutable = false): bool
-     {
-         /** @var Availability|null $availability */
-         $availability = $this->getOSAvailabilityInfo($quantityScale);
-         if ($useCheckoutable) {
-             return $this->isPublished() && $availability?->isCheckoutable();
-         } else {
-             return $this->isPublished() && $availability?->getAvailable();
-         }
-     }
-     public function getOSPrice($quantityScale = 1): ?PriceInterface
-     {
-         return $this->getOSPriceInfo($quantityScale)->getPrice();
-     }
-     public function getOSIsBookable($quantityScale = 1): bool
-     {
-         $price = $this->getOSPrice($quantityScale);
-         return $this->isBookable() && !empty($price->getGrossAmount()->asNumeric());
-     }
-     /** @phpstan-ignore-next-line  */
-     public function getOSPriceInfo($quantityScale = 1, $products = null, Carbon $date = null): ?PriceInfoInterface
-     {
-         /** @var PriceSystem $priceSystem */
-         $priceSystem = $this->getPriceSystemImplementation();
-         return $priceSystem->getPriceInfo($this, $quantityScale, $products, $date);
-     }
-     public function getOSAvailabilityInfo($quantity = null): ?AvailabilityInterface
-     {
-         return $this->getAvailabilitySystemImplementation()->getAvailabilityInfo($this, $quantity);
-     }
-     public function getProductStartDate(): ?Carbon
-     {
-         return $this->getEventStartDate();
-     }
-     public function getTeaserPrice(): ?PriceInterface
-     {
-         /** @var PriceInfo $priceInfo */
-         $priceInfo = $this->getOSPriceInfo();
-         return $priceInfo->getBasePrice();
-     }
-     public function getTeaserTopTitle(): ?string
-     {
-         if ($category = $this->getProductCategory()) {
-             return $category->getName();
-         }
-         return '';
-     }
-     public function getTeaserDescription(): ?string
-     {
-         return $this->getShortDescription();
-     }
-     public function getTeaserImage(): ?Image
-     {
-         return $this->getMainImage();
-     }
-     /**
-      * Events got no validity date on the teaser
-      *
-      * @return array<mixed>
-      */
-     public function getTeaserValidity(): array
-     {
-         return [];
-     }
-     /**
-      * @return ShopDynamicPrice[]
-      */
-     public function getPriceObjects(): array
-     {
-         $priceObjs = [];
-         if ($items = $this->getPrices()) {
-             foreach ($items as $item) {
-                 /** @var ShopDynamicPrice $priceObj */
-                 $priceObj = $item->getObject();
-                 if ($priceObj->getPrice()) {
-                     $priceObjs[] = $priceObj;
-                 }
-             }
-         }
-         return $priceObjs;
-     }
-     /**
-      * @return array<mixed>
-      */
-     public function getPriceObjectGrouped(): array
-     {
-         $groupedObjs = [];
-         if ($items = $this->getPrices()) {
-             foreach ($items as $item) {
-                 /** @var ShopDynamicPrice $priceObj */
-                 $priceObj = $item->getObject();
-                 if ($priceObj->getPrice()) {
-                     $groupedObjs[$item->getGroupname()][] = $priceObj;
-                 }
-             }
-         }
-         return $groupedObjs;
-     }
-     /**
-      * Get price group containing the given price description
-      *
-      * @param ShopDynamicPrice $priceDescription
-      *
-      * @return string
-      */
-     public function getPriceGroupForPriceDescription(?ShopDynamicPrice $priceDescription): string
-     {
-         if ($priceDescription) {
-             /** @phpstan-ignore-next-line  */
-             foreach ($this->getReference()->getPrices() as $price) {
-                 if ($price->getObject()->getId() == $priceDescription->getId()) {
-                     return $price->getGroupname();
-                 }
-             }
-         }
-         return '';
-     }
-     /**
-      * @param Carbon|null $startDate
-      * @param ShopDynamicPrice|null $priceItem
-      *
-      * @return EventProduct
-      *
-      * @throws \Exception
-      */
-     public function getOrCreateOrderableObject(Carbon $startDate = null, ShopDynamicPrice $priceItem = null): self
-     {
-         if ($this->getBookableOnDayOfEvent()) {
-             $startDate->endOfDay();
-         }
-         $key = sprintf('%s-%s-%s',
-             $this->getKey(),
-             $startDate->toDateTimeString(),
-             $priceItem ? $priceItem->getId() : ''
-         );
-         $list = new ShopEvent\Listing();
-         $list->setObjectTypes([AbstractObject::OBJECT_TYPE_VARIANT]);
-         $list->addConditionParam('o_parentId = ?', $this->getId());
-         $list->addConditionParam('ifnull(o_key,0) = ?', $key);
-         $list->addConditionParam('eventStartDate >= ?', $startDate->timestamp);
-         if ($list->count() == 0) {
-             // create variant for booking
-             $orderObject = new self();
-             $orderObject->setPublished(true);
-             $orderObject->setType(AbstractObject::OBJECT_TYPE_VARIANT);
-             $orderObject->setParent($this);
-             $orderObject->setKey($key);
-             $orderObject->setEventStartDate($startDate);
-             $orderObject->setOrderedPriceItem($priceItem);
-             $orderObject->save();
-         } else {
-             /** @var EventProduct $orderObject */
-             $orderObject = $list->current();
-         }
-         return $orderObject;
-     }
-     public function isPersonsTimeList(): bool
-     {
-         if ($prices = $this->getPrices()) {
-             $price = array_pop($prices);
-             return !empty($price->getGroupname());
-         }
-         return false;
-     }
-     public function isCancelable(OrderItem $orderItem = null): bool
-     {
-         return true;
-     }
-     public function getFirstValidValidityDate(Carbon $date): ?Carbon
-     {
-         $validityDate = null;
-         $firstValidityDateRange = $this->getFirstValidDateRange($date);
-         if (isset($firstValidityDateRange['from'])) {
-             /** @var Carbon $fromDateValidity */
-             $fromDateValidity = $firstValidityDateRange['from'];
-             $validityDate = $fromDateValidity->lt($date) ? $date : $fromDateValidity;
-         }
-         return $validityDate;
-     }
-     /**
-      * @param Carbon $date
-      *
-      * @return  array<mixed>
-      */
-     public function getFirstValidDateRange(Carbon $date): array
-     {
-         $recurringDatesHelper = new RecurringDatesHelper();
-         if ($validityDates = $recurringDatesHelper->getCalculatedDates($this, 'getValidityDates')) {
-             foreach ($validityDates as $validityDate) {
-                 $fromDate = Carbon::parse($validityDate['fromDate']);
-                 $toDate = Carbon::parse($validityDate['toDate']);
-                 if (($validityDate['type'] == 'RecurringDate' || $validityDate['type'] == 'RecurringDateTime')
-                     && ($date->between($fromDate, $toDate) || $fromDate->gte($date))
-                 ) {
-                     return [
-                         'from' => $fromDate,
-                         'to' => $toDate,
-                     ];
-                 }
-             }
-         }
-         return [];
-     }
-     /**
-      *
-      * returns all valid date ranges now and in the future, if no dateformat is given, dats are returned as timestamp
-      *
-      * @param Carbon $date
-      *
-      * @return  array<mixed>
-      */
-     public function getAllValidDateRanges(?Carbon $date = null, string $dateFormat = null): array
-     {
-         $ranges = [];
-         if(!$date) {
-             $date = Carbon::now()->startOfDay();
-         }
-         if ($validDates = $this->getValidityDates()) {
-             if ($definitions = $validDates->getDefinitionArray()) {
-                 foreach ($definitions as $definition) {
-                     if(!isset($definition['values']['fromDate']) && isset($definition['values']['date'])) {
-                         $fromDate = Carbon::parse($definition['values']['date']);
-                         $toDate = clone $fromDate;
-                     } else {
-                         $fromDate = Carbon::parse($definition['values']['fromDate']);
-                         $toDate = Carbon::parse($definition['values']['toDate']);
-                     }
-                     if (($definition['type'] == 'FixedDate' || $definition['type'] == 'RecurringDate' || $definition['type'] == 'RecurringDateTime')
-                         && ($date->between($fromDate, $toDate) || $fromDate->gte($date) || $fromDate->getTimestamp()==$date->getTimestamp())
-                     ) {
-                         $ranges[] = [
-                             'from' => $fromDate,
-                             'to' => $toDate,
-                         ];
-                     }
-                 }
-             }
-         }
-         return $ranges;
-     }
- }
-