custom/plugins/NimbitsPriceOnRequestNext/src/Service/PriceOnRequestService.php line 212

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Nimbits\NimbitsPriceOnRequestNext\Service;
  3. use Nimbits\NimbitsPriceOnRequestNext\Setting\Service\SettingService;
  4. use Shopware\Core\Checkout\Cart\Delivery\Struct\DeliveryInformation;
  5. use Shopware\Core\Checkout\Cart\Delivery\Struct\DeliveryTime;
  6. use Shopware\Core\Checkout\Cart\Exception\InvalidPayloadException;
  7. use Shopware\Core\Checkout\Cart\Exception\InvalidQuantityException;
  8. use Shopware\Core\Checkout\Cart\LineItem\LineItem;
  9. use Shopware\Core\Checkout\Cart\Price\Struct\CalculatedPrice;
  10. use Shopware\Core\Checkout\Cart\Rule\LineItemScope;
  11. use Shopware\Core\Content\Product\ProductEntity;
  12. use Shopware\Core\Content\Product\SalesChannel\SalesChannelProductEntity;
  13. use Shopware\Core\Framework\Struct\Struct;
  14. use Shopware\Core\Framework\Struct\StructCollection;
  15. use Shopware\Core\Content\Product\Cart\ProductLineItemFactory;
  16. use Shopware\Core\Checkout\Cart\SalesChannel\CartService;
  17. use Shopware\Core\Checkout\Cart\RuleLoader;
  18. use Shopware\Core\Checkout\Cart\CartRuleLoader;
  19. use Shopware\Core\Checkout\Cart\AbstractRuleLoader;
  20. use Shopware\Core\Checkout\Cart\CachedRuleLoader;
  21. use Shopware\Core\Framework\Rule\Rule;
  22. use Shopware\Core\Framework\Uuid\Uuid;
  23. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  24. class PriceOnRequestService
  25. {
  26.     /** @var SettingService $settingsService */
  27.     private SettingService $settingsService;
  28.     private CartService $cartService;
  29.     private CartRuleLoader $cartRuleLoader;
  30.     private CachedRuleLoader $cachedRuleLoader;
  31.     private ProductLineItemFactory $productLineItemFactory;
  32.     
  33.     /**
  34.      * Creates a new instance of the service.
  35.      *
  36.      * @param SettingService $settingsService
  37.      */
  38.     public function __construct(
  39.         SettingService $settingsService,
  40.         CartService $cartService,
  41.         CartRuleLoader $cartRuleLoader,
  42.         CachedRuleLoader $cachedRuleLoader,
  43.         ProductLineItemFactory $productLineItemFactory
  44.     )
  45.     {
  46.         $this->settingsService $settingsService;
  47.         $this->cartService $cartService;
  48.         $this->cartRuleLoader $cartRuleLoader;
  49.         $this->cachedRuleLoader $cachedRuleLoader;
  50.         $this->productLineItemFactory $productLineItemFactory;
  51.     }
  52.     //helper for the plugin config
  53.     private function getPluginConfig($salesChannelContext){
  54.         $config $this->settingsService->getSettingsAsStruct($salesChannelContext->getSalesChannel()->getId());
  55.         return $config;
  56.     }
  57.     //helperfunction
  58.     //returns default por ruleset to match shopware standard config
  59.     public function getDefaultPorProductRuleset(){
  60.         $defaultruleset = [
  61.             "por_btn_visible" => false,
  62.             "por_dont_show_price" => false,
  63.             "por_add_to_cart_not_visible" => false,
  64.             "por_product_not_purchasable" => false,
  65.         ];
  66.         return $defaultruleset;
  67.     }
  68.     //helperfunction
  69.     //returns default por ruleset to match shopware standard config
  70.     public function getDefaultPorCartRuleset(){
  71.         $defaultruleset = [
  72.             "show_por_btn" => false,
  73.             "cart_is_not_purchaseable" => false
  74.         ];
  75.         return $defaultruleset;
  76.     }
  77.     //helperfunction
  78.     //calculates an array of rulesets to one major ruleset which applies to the father and all its children articles
  79.     public function sortRulesets($rulesets){
  80.         
  81.         //default set
  82.         $fnRuleset $this->getDefaultPorProductRuleset();
  83.         
  84.         foreach($rulesets AS $ruleset){
  85.             if($ruleset->por_btn_visible == true){
  86.                 $fnRuleset["por_btn_visible"] = true;
  87.             }
  88.             if($ruleset->por_dont_show_price == true){
  89.                 $fnRuleset["por_dont_show_price"] = true;
  90.             }
  91.             if($ruleset->por_add_to_cart_not_visible == true){
  92.                 $fnRuleset["por_add_to_cart_not_visible"] = true;
  93.             }
  94.             if($ruleset->por_product_not_purchasable == true){
  95.                 $fnRuleset["por_product_not_purchasable"] = true;
  96.             }
  97.         }
  98.         
  99.         return (new StructCollection())->assign($fnRuleset);
  100.     }
  101.     //cart rule evaluation
  102.     public function getCartRuleSet($salesChannelContext){
  103.         $config $this->getPluginConfig($salesChannelContext);
  104.         $context $salesChannelContext->getContext();
  105.         //load all rules on this saleschannel
  106.         $rulecollection $this->cachedRuleLoader->load($context);
  107.         //get the cart - needed for validation of the rules
  108.         $currentCart $this->cartService->getCart($salesChannelContext->getToken(), $salesChannelContext);
  109.         //filter for only active rules and sort them by priority
  110.         $ruleCollectionCleaned $rulecollection->filterMatchingRules($currentCart$salesChannelContext);
  111.         $ruleCollectionCleaned->sortByPriority();
  112.         $cartRuleset $this->getDefaultPorCartRuleset();
  113.         $cartRuleset["show_por_btn"] = $this->getCartShowPorBtn($ruleCollectionCleaned$config);
  114.         $cartRuleset["cart_is_not_purchaseable"] = $this->getCartIsNotPurchaseable($ruleCollectionCleaned$config);
  115.         return (new StructCollection())->assign($cartRuleset);
  116.     }
  117.     public function getCartShowPorBtn($ruleCollectionCleaned$config): bool
  118.     {
  119.         if(empty($config->get('nbporcartshowporbtnrule'))){
  120.             return false;
  121.         }
  122.         if($ruleCollectionCleaned->has($config->get('nbporcartshowporbtnrule'))){
  123.             return true;
  124.         }
  125.         return false;
  126.     }
  127.     public function getCartIsNotPurchaseable($ruleCollectionCleaned$config): bool
  128.     {
  129.         if(empty($config->get('nbporcartisnotpurchaseablerule'))){
  130.             return false;
  131.         }
  132.         if($ruleCollectionCleaned->has($config->get('nbporcartisnotpurchaseablerule'))){
  133.            return true;
  134.         }
  135.         return false;
  136.     }
  137.     /**
  138.      * @throws InvalidQuantityException
  139.      * @throws InvalidPayloadException
  140.      */
  141.     public function createMockLineItem(SalesChannelProductEntity $productint $quantity 1): LineItem
  142.     {
  143.         $payload array_filter($product->getVars(), function($v)
  144.         {
  145.             return is_scalar($v) || is_array($v);
  146.         });
  147.         return (new LineItem(
  148.             Uuid::randomHex(),
  149.             LineItem::PRODUCT_LINE_ITEM_TYPE,
  150.             $product->getId(),
  151.             $quantity
  152.         ))
  153.             ->setPayload($payload)
  154.             ->setPrice($product->getCalculatedPrice())
  155.             ->setCover($product->getCover() != null $product->getCover()->getMedia() : null)
  156.             ->setDeliveryInformation(
  157.             new DeliveryInformation(
  158.                 (int) $product->getAvailableStock(),
  159.                 (float) $product->getWeight(),
  160.                 $product->getShippingFree() === true,
  161.                 $product->getRestockTime(),
  162.                 $product->getDeliveryTime() != null DeliveryTime::createFromEntity($product->getDeliveryTime()) : null,
  163.                 $product->getHeight(),
  164.                 $product->getWidth(),
  165.                 $product->getLength()
  166.             )
  167.         );
  168.     }
  169.     //returns the price on request ruleset for a single product
  170.     public function getProductRuleSet(SalesChannelContext $salesChannelContextLineItem $lineItem){
  171.         $config $this->getPluginConfig($salesChannelContext);
  172.         $productRuleset $this->getDefaultPorProductRuleset();
  173.         $productRuleset["por_btn_visible"] = $this->checkLineItemPorRule($salesChannelContext$config->get('nbpordetailporbtnvisiblerule') , $lineItem);
  174.         $productRuleset["por_dont_show_price"] = $this->checkLineItemPorRule($salesChannelContext$config->get('nbpordetaildontshowpricerule') , $lineItem);
  175.         $productRuleset["por_add_to_cart_not_visible"] = $this->checkLineItemPorRule($salesChannelContext$config->get('nbpordetailaddtocartbtnnotvisiblerule') , $lineItem);
  176.         $productRuleset["por_product_not_purchasable"] = $this->checkLineItemPorRule($salesChannelContext$config->get('nbpordetailproductnotpurchaseablerule') , $lineItem);
  177.         return (new StructCollection())->assign($productRuleset);
  178.     }
  179.     //helper function
  180.     //evaulates a rule on a lineitem
  181.     public function checkLineItemPorRule(SalesChannelContext $salesChannelContext, ?string $ruleIdLineItem $lineItem)
  182.     {
  183.         $context $salesChannelContext->getContext();
  184.         $cachedRulesCollection $this->cachedRuleLoader->load($context);
  185.         $rule $cachedRulesCollection->get($ruleId);
  186.         if($rule == NULL)
  187.             return false;
  188.         $lineItemScope = new LineItemScope($lineItem$salesChannelContext);
  189.         //if rule matches on lineitem we have por case
  190.         if($rule->getPayload()->match($lineItemScope)){
  191.             return true;
  192.         }
  193.         return false;
  194.     }
  195. }