<?php declare(strict_types=1);
namespace Nimbits\NimbitsPriceOnRequestNext\Service;
use Nimbits\NimbitsPriceOnRequestNext\Setting\Service\SettingService;
use Shopware\Core\Framework\Struct\StructCollection;
class PriceOnRequestService
{
public const SYSTEM_CONFIG_DOMAIN = 'NimbitsPriceOnRequestNext.config.';
/** @var SettingService $settingsService */
private $settingsService;
/** @var string */
private $salesChannelId;
/**
* Creates a new instance of the service.
*
* @param SettingService $settingsService
*/
public function __construct(
SettingService $settingsService,
?string $salesChannelId = null
)
{
$this->settingsService = $settingsService;
$this->salesChannelId = $salesChannelId;
}
/**
* Sets the sales channel to get the configuration for.
*
* @param string $salesChannelId
*/
public function setSalesChannelId(string $salesChannelId): void
{
$this->salesChannelId = $salesChannelId;
}
//helper for the plugin config
private function getPluginConfig(){
$config = $this->settingsService->getSettingsAsStruct($this->salesChannelId);
return $config;
}
//calculates array of rulesets to one major ruleset which applies to the father and all its children articles
public function sortRulesets($rulesets){
//default set
$fnRuleset = [
"is_por" => false,
"is_purchaseable" => true,
"show_price" => true,
"breakPorRules" => false
];
foreach($rulesets AS $ruleset){
if($ruleset->is_por == true){
$fnRuleset["is_por"] = true;
}
if($ruleset->is_purchaseable == false){
$fnRuleset["is_purchaseable"] = false;
}
if($ruleset->show_price == false){
$fnRuleset["show_price"] = false;
}
if($ruleset->breakPorRules == true){
$fnRuleset["breakPorRules"] = true;
}
}
return (new StructCollection())->assign($fnRuleset);
}
public function getPriceOnRequestRules($product, $cg){
$isPor = $this->checkForPOR($product);
$isPurchaseable = $this->isPurchaseable($product, $isPor);
$showPrice = $this->showPrice($product, $isPor);
$breakPorRules = $this->validateCustomergroupRules($cg);
if($breakPorRules){
$isPor = false;
$isPurchaseable = true;
$showPrice = true;
}
return (new StructCollection())->assign([
"is_por" => $isPor,
"is_purchaseable" => $isPurchaseable,
"show_price" => $showPrice,
"breakPorRules" => $breakPorRules
]);
}
//returns true or false depending if checkout has to be disabled for this single product
public function checkForProductCheckoutDisabled($product, $cg){
$isPor = $this->checkForPOR($product);
$isPurchaseable = $this->isPurchaseable($product, $isPor);
$showPrice = $this->showPrice($product, $isPor);
$breakPorRules = $this->validateCustomergroupRules($cg);
if($breakPorRules){
$isPor = false;
$isPurchaseable = true;
$showPrice = true;
}
if($isPor && !$isPurchaseable && !$showPrice){
return true;
}
return false;
}
//determines weather or not the checkout has to be disabled depending on the products in the cart
public function checkForCheckoutDisabled($products, $cg){
$config = $this->getPluginConfig();
if($config->nbporcheckoutdeactivate){
return (new StructCollection())->assign(['checkoutdisabled' => true]);
}
foreach($products AS $product){
if($this->checkForProductCheckoutDisabled($product, $cg)){
return (new StructCollection())->assign(['checkoutdisabled' => true]);
}
}
return (new StructCollection())->assign(['checkoutdisabled' => false]);
}
//checks if a product is price on request
public function checkForPOR($product){
$config = $this->getPluginConfig();
$highest = 0;
//iteration for advanced pricing
foreach($product->get("price")->getIterator() as $i => $item) {
if($item->getGross() > $highest){
$highest = $item->getGross();
}
}
$productprices = $product->get("prices");
//iteration for advanced pricing
foreach($productprices->getIterator() as $i => $item) {
foreach($item->get("price") as $j => $jtem) {
if($jtem->getGross() > $highest){
$highest = $jtem->getGross();
}
}
}
//config price is above value for advanced pricing
if($highest > $config->porabove){
return true;
}
//onfig price is exactly this value for advanced pricing
if($highest == $config->porequals){
return true;
}
//config price is above value
if($product->get("calculatedPrice")->getTotalPrice() > $config->porabove){
return true;
}
//config price is exactly this value
if($product->get("calculatedPrice")->getTotalPrice() == $config->porequals){
return true;
}
//config stock below or 0
if($product->get("stock")< 1 && $config->nbporactiveviastock){
return true;
}
//custom field settings
$cf = $product->getCustomFields();
if(isset($cf["custom_nimbits_priceonrequest_active"]) && $cf["custom_nimbits_priceonrequest_active"]){
return true;
}
//default
return false;
}
//determines if a article is purchaseable
public function isPurchaseable($product, $isPor){
$config = $this->getPluginConfig();
//just matters if we have a price on request article
if($isPor){
//config whitelist
if($config->nbporpurchaseable){
return true;
}
//case addable but no price
if($config->nbporaddable){
return false;
}
//custom field settings
$cf = $product->getCustomFields();
//whitelist via customfields
if(isset($cf["custom_nimbits_priceonrequest_purchaseable"]) && $cf["custom_nimbits_priceonrequest_purchaseable"]){
return true;
}
//default
return false;
}
return true;
}
//determines if a article is allowed to show its price
public function showPrice($product, $isPor){
$config = $this->getPluginConfig();
if($isPor){
//case addable but no price
if($config->nbporaddable){
return false;
}
//custom field settings
$cf = $product->getCustomFields();
//whitelist via customfields
if(isset($cf["custom_nimbits_priceonrequest_showprice"]) && $cf["custom_nimbits_priceonrequest_showprice"]){
return true;
}
//default
return false;
}
return true;
}
//validates customergroup rules for price on request, returns true if price on request rules are allowed to break
public function validateCustomergroupRules($cg){
$config = $this->getPluginConfig();
if(!$config->nbporcustomergroupcsvactive){
return false;
}
try{
$nbporcustomergroupcsv = $config->nbporcustomergroupcsv;
if(empty($nbporcustomergroupcsv)){
return false;
}
$cgs = explode(";", $nbporcustomergroupcsv);
if(empty($cgs)){
return false;
}
foreach($cgs AS $current){
if($current == $cg){
return true;
}
}
}
catch(\Exception $e){
}
return false;
}
}