The Pricing Engine is designed to be highly flexible and extendable. So based on this purpose you have only to do three steps do create your own condition:
In the following example we will add a condition with is based on the firstname of the logged in customer.
First we have to extend the CustomerContext:
<?php declare(strict_types=1);
namespace SwagCustomCondition\Source;
use SwagEnterprisePricingEngine\Source\Common\CustomerContextInterface;
class CustomerContextExtended implements CustomerContextInterface
{
/**
* @var CustomerContextInterface
*/
private $originalCustomerContext;
public function __construct(CustomerContextInterface $originalCustomerContext)
{
$this->originalCustomerContext = $originalCustomerContext;
}
public function getCustomerId(): int
{
return $this->originalCustomerContext->getCustomerId();
}
// and so on to implement the original interface
// our own condition method to provide the firstname
public function getCustomerFirstName(): string
{
$userData = Shopware()->Modules()->Admin()->sGetUserData();
return $userData['billingaddress']['firstname'] ?? '';
}
}
After that we will decorate the ContextFactory to return our new CustomerContextExtended
<?php declare(strict_types=1);
namespace SwagCustomCondition\Source;
use Doctrine\DBAL\Connection;
use Shopware\B2B\StoreFrontAuthentication\Framework\AuthenticationService;
use Shopware\B2B\StoreFrontAuthentication\Framework\NotAuthenticatedException;
use Shopware\Bundle\StoreFrontBundle\Service\ContextServiceInterface;
use SwagEnterprisePricingEngine\Bridge\PricingEngineContextFactory;
use SwagEnterprisePricingEngine\Source\Common\CustomerContextInterface;
use SwagEnterprisePricingEngine\Source\PriceListCondition\PriceListConditionFactory;
class PricingEngineContextFactoryDecorated extends PricingEngineContextFactory
{
/**
* @param ContextServiceInterface $contextService
* @param PriceListConditionFactory $conditionFactory
* @param Connection $connection
*/
public function __construct(
ContextServiceInterface $contextService,
PriceListConditionFactory $conditionFactory,
Connection $connection,
AuthenticationService $authenticationService = null
) {
parent::__construct($contextService, $conditionFactory, $connection, $authenticationService);
}
/**
* @return CustomerContextInterface
*/
public function getCustomerContext(): CustomerContextInterface
{
return new CustomerContextExtended(parent::getCustomerContext());
}
}
Now we will create our own condition for the Pricing Engine. To activate the condition it needs the tag swag_enterprise_pricing_engine.price_list_condition
in the service.xml!
<?php declare(strict_types=1);
namespace SwagCustomCondition\Source;
use Shopware\Bundle\StoreFrontBundle\Struct\ShopContextInterface;
use SwagEnterprisePricingEngine\Source\Common\CustomerContextInterface;
use SwagEnterprisePricingEngine\Source\PriceListCondition\Conditions\AbstractCondition;
class CustomerFirstNameCondition extends AbstractCondition
{
const NAME = 'CustomerFirstNameCondition';
/**
* @var string
*/
private $firstName;
public function __construct(string $firstName = null)
{
$this->firstName = $firstName;
}
/**
* {@inheritdoc}
*/
public function checkValidity(ShopContextInterface $shopContext, CustomerContextInterface $customerContext): bool
{
return $customerContext->getCustomerFirstName() === $this->firstName;
}
}
At least we have to register our components in the dependency injection container:
<?xml version="1.0" ?>
<container xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://symfony.com/schema/dic/services"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service class="SwagCustomCondition\Source\PricingEngineContextFactoryDecorated"
id="swag_custom_condition.source.pricing_engine_context_factory_decorated"
decorates="swag_enterprise_pricing_engine.bridge.pricing_engine_context_factory"
public="false">
<argument id="shopware_storefront.context_service" type="service"/>
<argument id="swag_enterprise_pricing_engine.source.price_list_condition.price_list_condition_factory"
type="service"/>
<argument id="dbal_connection" type="service"/>
<argument id="b2b_front_auth.authentication_service" type="service" on-invalid="null"/>
</service>
<service class="SwagCustomCondition\Source\CustomerFirstNameCondition"
id="swag_custom_condition.source.customer_first_name_condition">
<tag name="swag_enterprise_pricing_engine.price_list_condition"/>
</service>
</services>
</container>
To add a own condition is quite simple. If you need the whole plugin, please have a look into our example-plugins directory.