vendor/elements/demi-bundle/src/Elements/Demi/Deskline/DataObject/Adapter/AccommodationProduct.php line 121

Open in your IDE?
  1. <?php
  2. /**
  3.  * Elements DeMI
  4.  *
  5.  * This source file is available under the elements DeMI license version 1
  6.  *
  7.  *  @copyright  Copyright (c) elements.at New Media Solutions GmbH (https://www.elements.at/)
  8.  *  @license    elements DeMI Lizenz Version 1 (https://www.elements.at/de/demi-lizenz)
  9.  */
  10. namespace Elements\Demi\Deskline\DataObject\Adapter;
  11. use Carbon\Carbon;
  12. use Doctrine\DBAL\Connection;
  13. use Doctrine\DBAL\ParameterType;
  14. use Elements\Demi\DataObject\Adapter\AbstractAccommodationProduct;
  15. use Elements\Demi\Deskline\Config;
  16. use Elements\Demi\Deskline\Constant\DescriptionInterface;
  17. use Elements\Demi\Deskline\Constant\DocumentInterface;
  18. use Elements\Demi\Helper;
  19. use Elements\Demi\Vacancies\Dependency\VacancyDependencyContainer;
  20. use Exception;
  21. use Pimcore;
  22. use Pimcore\Bundle\EcommerceFrameworkBundle\CartManager\CartCheckoutData;
  23. use Pimcore\Bundle\EcommerceFrameworkBundle\Factory;
  24. use Pimcore\Db;
  25. use Pimcore\Model\DataObject\Fieldcollection\Data\DemiPeriod;
  26. class AccommodationProduct extends AbstractAccommodationProduct implements DocumentInterfaceDescriptionInterface
  27. {
  28.     protected int|float|null $cheapestStdPrice null;
  29.     protected array $defaultDescriptionType = [self::DESCRIPTION_PRODUCT_DESCRIPTION];
  30.     protected array $defaultDocumentTypes = [self::DOCUMENT_TYPE_SERVICE_PROVIDERself::DOCUMENT_TYPE_PRODUCTself::DOCUMENT_TYPE_PRODUCT_GROUPself::DOCUMENT_TYPE_SERVICE];
  31.     public function getImageDocuments(mixed $types null, ?Carbon $filterDate nullbool $withChilds false): array
  32.     {
  33.         if ($types === null) {
  34.             $types $this->defaultDocumentTypes;
  35.         }
  36.         if ($this->object->getProductType() === 'Package') {
  37.             return [];
  38.         }
  39.         return parent::getImageDocuments($types$filterDate);
  40.     }
  41.     public function getDefaultMeals(?Carbon $filterDate null): array
  42.     {
  43.         $cacheKey 'defaultMeals'.$this->object->getId();
  44.         if($filterDate){
  45.             $cacheKey.=$filterDate->format('Y-m-d');
  46.         }
  47.         $cacheKey md5($cacheKey);
  48.         $defaults \Pimcore\Cache::load($cacheKey);
  49.         if($defaults === false) {
  50.             $defaults = [];
  51.             $priceTemplates $this->object->getPriceTemplatesForMeals($filterDate);
  52.             if ($priceTemplates) {
  53.                 foreach ($priceTemplates as $priceTemplate) {
  54.                     if (!empty($priceTemplate->getDefaultMealType())) {
  55.                         $defaults[] = $priceTemplate->getDefaultMealType();
  56.                     }
  57.                 }
  58.             }
  59.             \Pimcore\Cache::save($defaults$cacheKey, [], 3600);
  60.         }
  61.         return $defaults;
  62.     }
  63.     /**
  64.      * getall valid Mealcodes
  65.      */
  66.     public function getValidMeals(int $nights 0, ?Carbon $filterDate null): array
  67.     {
  68.         $cacheKey 'validMeals'.$this->object->getId().$nights;
  69.         if($filterDate){
  70.             $cacheKey.=$filterDate->format('Y-m-d');
  71.         }
  72.         $cacheKey md5($cacheKey);
  73.         $mealCodes \Pimcore\Cache::load($cacheKey);
  74.         if($mealCodes === false || $mealCodes == "empty##"){
  75.             $mealCodes = [];
  76.             $priceTemplates $this->object->getPriceTemplates();
  77.             $dummy = new \Elements\Demi\Model\PriceTemplate();
  78.             $classid $dummy->getClassId();
  79.             $priceTemplatesIds = [];
  80.             foreach ($priceTemplates as $templates) {
  81.                 $priceTemplatesIds[] = $templates->getId();
  82.             }
  83.             $dummy = new DemiPeriod();
  84.             $fieldcollname $dummy->getType();
  85.             $result = [];
  86.             $builder Db::get()->createQueryBuilder();
  87.             $priceTemplateAdd '';
  88.             if (!empty($priceTemplatesIds)) {
  89.                 $priceTemplateAdd $builder->expr()->in('o_id'':templateIds');
  90.             }
  91.             if ($filterDate) {
  92.                 $result $builder
  93.                     ->select('objectCollection.o_id')
  94.                     ->from('object_collection_' $fieldcollname '_' $classid'objectCollection')
  95.                     ->where(
  96.                         $builder->expr()->and(
  97.                             $builder->createNamedParameter($filterDate->getTimestamp(), ParameterType::INTEGER) . ' BETWEEN objectCollection.dateFrom AND objectCollection.dateTo',
  98.                             $priceTemplateAdd
  99.                         )
  100.                     )
  101.                     ->setParameter(':templateIds'$priceTemplatesIdsConnection::PARAM_INT_ARRAY)
  102.                     ->execute()->fetchAll();
  103.             }
  104.             if (count($result) <= 0) {
  105.                 $builder Db::get()->createQueryBuilder();
  106.                 $result $builder
  107.                     ->select('objectClass.o_id')
  108.                     ->from('object_' $classid'objectClass')
  109.                     ->where(
  110.                         $builder->expr()->and(
  111.                             $priceTemplateAdd,
  112.                             'objectClass.name = ' $builder->createNamedParameter('Standard')
  113.                         )
  114.                     )
  115.                     ->setParameter(':templateIds'$priceTemplatesIdsConnection::PARAM_INT_ARRAY)
  116.                     ->execute()->fetchAll();
  117.             }
  118.             $template \Elements\Demi\Model\PriceTemplate::getById((int) $result[0]['o_id']);
  119.             if ($template !== null) {
  120.                 $mTypes $template->getMealTypes();
  121.                 if ($mTypes !== null) {
  122.                     foreach ($template->getMealTypes() as $mealType) {
  123.                         if ($mealType->getNights() <= $nights) {
  124.                             $dummyCode $mealType->getMealType();
  125.                             $mealCodes[$dummyCode->getFid()] = $dummyCode;
  126.                         }
  127.                     }
  128.                 }
  129.             }
  130.             \Pimcore\Cache::save($mealCodes$cacheKey, [], 36000true);
  131.         }
  132.         return $mealCodes;
  133.     }
  134.     /**
  135.      * Wrapper function to get an array of mealCodes instead of the mealType object
  136.      * will be removed in future and replaced with _getMeals()
  137.      * kept until the mealCode array is unwrestled in the view-code
  138.      *
  139.      *@deprecated
  140.      */
  141.     public function getMeals(int $nights 0, ?Carbon $filterDate null): array
  142.     {
  143.         $mealCodes = [];
  144.         $meals $this->object->_getMeals($nights$filterDate);
  145.         foreach ($meals as $meal) {
  146.             $mealCodes[] = $meal->getFid();
  147.         }
  148.         return $mealCodes;
  149.     }
  150.     public function _getMeals(int $nights, ?Carbon $filterDate null): array
  151.     {
  152.         $cacheKey 'meals'.$this->object->getId().$nights;
  153.         if($filterDate){
  154.             $cacheKey.=$filterDate->format('Y-m-d');
  155.         }
  156.         $cacheKey md5($cacheKey);
  157.         $meals \Pimcore\Cache::load($cacheKey);
  158.         if($meals === false) {
  159.             $meals = [];
  160.             $priceTemplates $this->object->getPriceTemplatesForMeals($filterDate);
  161.             if ($priceTemplates) {
  162.                 foreach ($priceTemplates as $priceTemplate) {
  163.                     if (!empty($priceTemplate->getMealTypes())) {
  164.                         foreach ($priceTemplate->getMealTypes() as $mealType) {
  165.                             if ($mealType->getNights() >= $nights) {
  166.                                 $meals[] = $mealType->getMealType();
  167.                             }
  168.                         }
  169.                     }
  170.                 }
  171.             }
  172.             \Pimcore\Cache::save($meals$cacheKey, [], 3600);
  173.         }
  174.         return $meals;
  175.     }
  176.     public function getPriceTemplatesForMeals(bool $noFilter false, ?Carbon $filterDate null): \Elements\Demi\Model\PriceTemplate
  177.     {
  178.         $priceTemplates $this->object->getPriceTemplates();
  179.         if (!$noFilter && is_array($priceTemplates) && !Pimcore::inAdmin() && !Config::getInstance()->isImporting()) {
  180.             if (!$filterDate) {
  181.                 $nowTst time();
  182.             } else {
  183.                 $nowTst $filterDate->getTimestamp();
  184.             }
  185.             $priceTemplates array_filter($priceTemplates, static function ($object) use ($nowTst) {
  186.                 return $nowTst >= $object->getValidFrom()->getTimestamp();
  187.             });
  188.         }
  189.         return $priceTemplates;
  190.     }
  191.     public function getPriceForParams(array $params): float
  192.     {
  193.         // dateFrom Carbon
  194.         $mandatory = ['dateFrom''occupancy'];
  195.         foreach ($mandatory as $key) {
  196.             if (!isset($params[$key])) {
  197.                 return 0;
  198.             }
  199.         }
  200.         $cacheKey "priceForParams".$this->object->getId().$params['dateFrom']->format('Y-m-d').$params['occupancy'];
  201.         $cacheKey md5($cacheKey);
  202.         $price \Pimcore\Cache::load($cacheKey);
  203.         if($price === false) {
  204.             $price 0;
  205.             $priceTemplates $this->object->getPriceTemplates();
  206.             $useTemplate null;
  207.             $stdTemplate null;
  208.             $today = new Carbon();
  209.             foreach ($priceTemplates as $template) {
  210.                 if ($template->getValidFrom()->getTimestamp() > $today->getTimestamp()) {
  211.                     continue;
  212.                 }
  213.                 $periods $template->getPeriods();
  214.                 if ($template->getIsStandard()) {
  215.                     $stdTemplate $template;
  216.                     continue;
  217.                 }
  218.                 if (!empty($periods)) {
  219.                     foreach ($periods as $period) {
  220.                         if ($period->getDateFrom()->getTimestamp() <= $params['dateFrom']->getTimestamp() && $period->getDateTo()->getTimestamp() >= $params['dateFrom']->getTimestamp()) {
  221.                             $useTemplate $template;
  222.                             break 2;
  223.                         }
  224.                     }
  225.                 }
  226.             }
  227.             if (!$useTemplate) {
  228.                 $useTemplate $stdTemplate;
  229.             }
  230.             if (!$useTemplate) {
  231.                 return 0;
  232.             }
  233.             $prices $useTemplate->getPrices();
  234.             if (!empty($prices)) {
  235.                 foreach ($useTemplate->getPrices() as $priceColl) {
  236.                     if ($priceColl->getOccupancyFrom() <= $params['occupancy'] && $priceColl->getOccupancyTo() >= $params['occupancy']) {
  237.                         $price $priceColl->getPrice();
  238.                         break;
  239.                     }
  240.                 }
  241.             }
  242.             \Pimcore\Cache::save($price$cacheKey, [], 3600);
  243.         }
  244.         return $price;
  245.     }
  246.     public function getService(): ?\Elements\Demi\Model\AccommodationService
  247.     {
  248.         $service $this->object->getParent();
  249.         if($service instanceof \Elements\Demi\Model\AccommodationService){
  250.             return $service;
  251.         } else {
  252.             //this is performance killing legacy code and should only be used as last resort in case the object tree is messed up
  253.             $list \Elements\Demi\Model\AccommodationService::getList(['condition' => 'products LIKE ' Db::get()->quote('%,' $this->object->getId() . ',%')]);
  254.             return Helper::first($list->getObjects());
  255.         }
  256.     }
  257.     /**
  258.      * called by default CommitOrderProcessor to get the product name to store it in the order item
  259.      * should be overwritten in mapped sub classes of product classes
  260.      */
  261.     public function getOSName(): string
  262.     {
  263.         return $this->object->getName();
  264.     }
  265.     /**
  266.      * called by default CommitOrderProcessor to get the product number to store it in the order item
  267.      * should be overwritten in mapped sub classes of product classes
  268.      */
  269.     public function getOSProductNumber(): string
  270.     {
  271.         return $this->object->getFid();
  272.     }
  273.     /**
  274.      * defines the name of the price system for this product.
  275.      * there should either be a attribute in pro product object or
  276.      * it should be overwritten in mapped sub classes of product classes
  277.      */
  278.     public function getPriceSystemName(): string
  279.     {
  280.         return 'deskline';
  281.     }
  282.     /**
  283.      * defines if product is included into the product index. If false, product doesn't appear in product index.
  284.      */
  285.     public function getOSDoIndexProduct(): bool
  286.     {
  287.         return false;
  288.     }
  289.     /**
  290.      * returns if product is active.
  291.      * there should either be a attribute in pro product object or
  292.      * it should be overwritten in mapped sub classes of product classes in case of multiple criteria for product active state
  293.      */
  294.     public function isActive(): bool
  295.     {
  296.         return $this->object->getActive();
  297.     }
  298.     /**
  299.      * returns array of categories.
  300.      * has to be overwritten either in pimcore object or mapped sub class.
  301.      */
  302.     public function getCategories(): array
  303.     {
  304.         return [];
  305.     }
  306.     public function setDesklinePrice($price): void
  307.     {
  308.         $env Factory::getInstance()->getEnvironment();
  309.         $prices $env->getDesklineProductPrices();
  310.         //TODO CHECK IF EXISTS....
  311.         $prices[$this->object->getId()] = $price;
  312.         $env->setDesklineProductPrices($prices);
  313.         $env->save();
  314.     }
  315.     //TODO use trait for additional and accommodation Product
  316.     public function getDesklinePrice()
  317.     {
  318.         $env Factory::getInstance()->getEnvironment();
  319.         $data CartCheckoutData::getByKeyCartId('p_' $this->object->getId(), $env->getCartId());
  320.         $stdObj unserialize($data->getData());
  321.         if (! is_object($stdObj) || empty($stdObj->price)) {
  322.             throw new Exception('No Price Set for Product ' $this->object->getId());
  323.         }
  324.         return $stdObj->price;
  325.     }
  326.     //TODO obsolete
  327.     public function getDesklineQuantity()
  328.     {
  329.         $env Factory::getInstance()->getEnvironment();
  330.         $quantities $env->getDesklineProductQuantities();
  331.         return $quantities[$this->object->getId()] ?? 1;
  332.     }
  333.     public function getCheapestStandardPrice(VacancyDependencyContainer $dc): float|int|null
  334.     {
  335.         if ($this->cheapestStdPrice <= || $this->cheapestStdPrice === null) {
  336.             $query '
  337.                 SELECT bp.price as minPrice, pt.rule type, pt.nights nights
  338.                   FROM    ' $dc->getDBTableName('price_template') . ' pt
  339.                        INNER JOIN
  340.                           ' $dc->getDBTableName('price_template_base_prices') . ' bp
  341.                        ON bp.price_template_id = pt.id
  342.                  WHERE     pt.product_id = ' $this->object->getId() . '
  343.                        AND pt.stdOccupancy BETWEEN bp.occupancyFrom AND bp.occupancyTo
  344.                        AND price > 0
  345.                        order by minPrice
  346.                        limit 1
  347.             ';
  348.             $result $dc->getDb()->fetchAllAssociative($query);
  349.             $this->cheapestStdPrice 0;
  350.             if (!empty($result)) {
  351.                 $this->cheapestStdPrice $result[0];
  352.             }
  353.         }
  354.         return $this->cheapestStdPrice;
  355.     }
  356.     /**
  357.      * @depricated
  358.      */
  359.     public function getMinPriceFromStandardTemplate()
  360.     {
  361.         $templates $this->object->getPriceTemplates();
  362.         $price null;
  363.         if (!empty($templates)) {
  364.             $stdAdults $this->object->getAdultsStd();
  365.             foreach ($templates as $template) {
  366.                 if (strtolower($template->getName()) === 'standard') {
  367.                     $prices $template->getPrices();
  368.                     if (!empty($prices)) {
  369.                         foreach ($prices as $price) {
  370.                             if ($stdAdults >= $price->getOccupancyFrom() && $stdAdults <= $price->getOccupancyTo()) {
  371.                                 $price $price->getPrice();
  372.                                 break;
  373.                             }
  374.                         }
  375.                     }
  376.                     break;
  377.                 }
  378.             }
  379.         }
  380.         return $price;
  381.     }
  382.     public function getPackageMaster(): Pimcore\Model\DataObject\AbstractObject|\Elements\Demi\Model\HousePackageMaster|Pimcore\Model\DataObject\Concrete|null
  383.     {
  384.         $dummy = new \Elements\Demi\Model\HousePackageMaster();
  385.         $classId $dummy->getClassId();
  386.         $builder Db::get()->createQueryBuilder();
  387.         $result $builder
  388.             ->select('objectRelations.src_id')
  389.             ->from('object_relations_' $classId'objectRelations')
  390.             ->where('objectRelations.dest_id = ' $builder->createNamedParameter($this->object->getId(), ParameterType::INTEGER))
  391.             ->execute()->fetchAll();
  392.         $hpm null;
  393.         if (is_array($result) && count($result) === 1) {
  394.             $hpm \Elements\Demi\Model\HousePackageMaster::getById($result[0]['src_id']);
  395.         } elseif (is_array($result)) {
  396.             foreach ($result as $data) {
  397.                 $hpm \Elements\Demi\Model\HousePackageMaster::getById($data['src_id']);
  398.                 if ($hpm && $hpm->isPublished()) {
  399.                     break;
  400.                 }
  401.             }
  402.         }
  403.         return $hpm;
  404.     }
  405. }