<?php
declare(strict_types=1);
namespace NetInventors\NetiNextOrderAmountHandler;
use Doctrine\DBAL\Connection;
use NetInventors\NetiNextOrderAmountHandler\Service\CompilerPass;
use NetInventors\NetiNextOrderAmountHandler\Service\PaymentHandler\FreePayment;
use Shopware\Core\Framework\Plugin;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\Plugin\Context\ActivateContext;
use Shopware\Core\Framework\Plugin\Context\DeactivateContext;
use Shopware\Core\Framework\Plugin\Context\InstallContext;
use Shopware\Core\Framework\Plugin\Context\UninstallContext;
use Shopware\Core\Framework\Plugin\Context\UpdateContext;
use Shopware\Core\Framework\Plugin\Util\PluginIdProvider;
use Shopware\Core\Framework\Uuid\Uuid;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class NetiNextOrderAmountHandler extends Plugin
{
public const RULE_NAME = 'Free | OrderAmountHandler';
public function install(InstallContext $context): void
{
$this->addPaymentMethod($context->getContext());
}
public function update(UpdateContext $updateContext): void
{
$this->addPaymentMethod($updateContext->getContext());
}
public function uninstall(UninstallContext $context): void
{
$this->setPaymentMethodIsActive(false, $context->getContext());
}
public function activate(ActivateContext $context): void
{
$this->setPaymentMethodIsActive(true, $context->getContext());
parent::activate($context);
}
public function deactivate(DeactivateContext $context): void
{
$this->setPaymentMethodIsActive(false, $context->getContext());
parent::deactivate($context);
}
private function addPaymentMethod(Context $context): void
{
$paymentMethodExists = $this->getPaymentMethodId($context);
if (null === $paymentMethodExists) {
/** @var PluginIdProvider $pluginIdProvider */
$pluginIdProvider = $this->container->get(PluginIdProvider::class);
$pluginId = $pluginIdProvider->getPluginIdByBaseClass(get_class($this), $context);
$examplePaymentData = [
'handlerIdentifier' => FreePayment::class,
'name' => 'Free',
'description' => 'Can only be used when the invoice amount is zero.',
'pluginId' => $pluginId,
'afterOrderEnabled' => false,
];
/** @var EntityRepositoryInterface $paymentRepository */
$paymentRepository = $this->container->get('payment_method.repository');
$paymentRepository->create([ $examplePaymentData ], $context);
}
$this->createAndAssignPaymentMethodRule($context);
}
private function setPaymentMethodIsActive(bool $active, Context $context): void
{
/** @var EntityRepositoryInterface $paymentRepository */
$paymentRepository = $this->container->get('payment_method.repository');
$paymentMethodId = $this->getPaymentMethodId($context);
if ($paymentMethodId) {
$paymentMethod = [
'id' => $paymentMethodId,
'active' => $active,
];
$paymentRepository->update([ $paymentMethod ], $context);
}
}
private function getPaymentMethodId(Context $context): ?string
{
/** @var EntityRepositoryInterface $paymentRepository */
$paymentRepository = $this->container->get('payment_method.repository');
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('handlerIdentifier', FreePayment::class));
return $paymentRepository->searchIds($criteria, $context)->firstId();
}
private function createAndAssignPaymentMethodRule(Context $context): void
{
/** @var EntityRepositoryInterface $ruleRepository */
$ruleRepository = $this->container->get('rule.repository');
// Check if rule exists
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('name', self::RULE_NAME));
$ruleId = $ruleRepository->searchIds($criteria, $context)->firstId();
// Create rule
if (null === $ruleId) {
$ruleId = Uuid::randomHex();
$ruleRepository->create(
[
[
'id' => $ruleId,
'name' => self::RULE_NAME,
'priority' => 100,
'conditions' => [
[
'type' => 'orContainer',
'children' => [
[
'type' => 'andContainer',
'children' => [
[
'type' => 'cartCartAmount',
'value' => [ 'amount' => 0, 'operator' => '<=' ],
],
[
'type' => 'cartLineItemsInCartCount',
'value' => [ 'count' => 0, 'operator' => '>' ],
],
],
],
],
],
],
],
],
$context
);
}
// Assign rule
/** @var EntityRepositoryInterface $paymentRepository */
$paymentRepository = $this->container->get('payment_method.repository');
$paymentMethodId = $this->getPaymentMethodId($context);
$paymentMethod = [
'id' => $paymentMethodId,
'availabilityRuleId' => $ruleId,
];
$paymentRepository->update([ $paymentMethod ], $context);
}
public function build(ContainerBuilder $container): void
{
parent::build($container);
$container->addCompilerPass(new CompilerPass());
}
}