<?php declare(strict_types=1);
namespace CioOrderConfirmation;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use Shopware\Core\Checkout\Order\OrderStates;
use Shopware\Core\Content\MailTemplate\Aggregate\MailTemplateType\MailTemplateTypeEntity;
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;
use Shopware\Core\Framework\Plugin\Context\InstallContext;
use Shopware\Core\Framework\Plugin\Context\UninstallContext;
use Shopware\Core\Framework\Uuid\Uuid;
use Shopware\Core\System\StateMachine\Aggregation\StateMachineState\StateMachineStateEntity;
use Shopware\Core\System\StateMachine\Aggregation\StateMachineTransition\StateMachineTransitionEntity;
use Shopware\Core\System\StateMachine\StateMachineEntity;
class CioOrderConfirmation extends Plugin
{
const WAITING_FOR_RELEASE_STATE_TECHNICAL_NAME = 'waiting_for_release';
const WAITING_FOR_RELEASE_STATE_TRANSITION_NAME = 'wait_for_release';
public function install(InstallContext $installContext): void
{
parent::install($installContext);
$context = $installContext;
/** @var EntityRepositoryInterface $stateMachineRepository */
$stateMachineRepository = $this->container->get('state_machine.repository');
/** @var EntityRepositoryInterface $stateMachineStateRepository */
$stateMachineStateRepository = $this->container->get('state_machine_state.repository');
/** @var EntityRepositoryInterface $stateMachineTransitionRepository */
$stateMachineTransitionRepository = $this->container->get('state_machine_transition.repository');
$stateMachine = $this->getStateMachine($stateMachineRepository, $context->getContext());
$stateMachineState = $this->getStateMachineState(self::WAITING_FOR_RELEASE_STATE_TECHNICAL_NAME, $stateMachine->getId(), $stateMachineStateRepository, $context->getContext());
if (!$stateMachineState instanceof StateMachineStateEntity) {
$newState = [
'technicalName' => self::WAITING_FOR_RELEASE_STATE_TECHNICAL_NAME,
'stateMachineId' => $stateMachine->getId(),
'translations' => [
'de-DE' => [
'name' => 'Warten auf Freigabe'
],
'en-GB' => [
'name' => 'Waiting for release'
]
]
];
$stateMachineStateRepository->create([$newState], $context->getContext());
}
$newStateMachineTransitions = [
[
'actionName' => 'reopen',
'stateMachineId' => $stateMachine->getId(),
'fromStateId' => $this->getStateMachineState(self::WAITING_FOR_RELEASE_STATE_TECHNICAL_NAME, $stateMachine->getId(), $stateMachineStateRepository, $context->getContext())->getId(),
'toStateId' => $this->getStateMachineState(OrderStates::STATE_OPEN, $stateMachine->getId(), $stateMachineStateRepository, $context->getContext())->getId(),
],
[
'actionName' => self::WAITING_FOR_RELEASE_STATE_TRANSITION_NAME,
'stateMachineId' => $stateMachine->getId(),
'fromStateId' => $this->getStateMachineState(OrderStates::STATE_OPEN, $stateMachine->getId(), $stateMachineStateRepository, $context->getContext())->getId(),
'toStateId' => $this->getStateMachineState(self::WAITING_FOR_RELEASE_STATE_TECHNICAL_NAME, $stateMachine->getId(), $stateMachineStateRepository, $context->getContext())->getId(),
]
];
foreach ($newStateMachineTransitions as $newStateMachineTransition) {
$stateMachineTransition = $this->getStateMachineTransition($newStateMachineTransition, $stateMachineTransitionRepository, $context->getContext());
if (!$stateMachineTransition instanceof StateMachineTransitionEntity) {
$stateMachineTransitionRepository->create([$newStateMachineTransition], $context->getContext());
}
}
// add mail templates
$mailTemplateTypeId = Uuid::randomHex();
$this->createEmailTypeWithTemplates([
'id' => $mailTemplateTypeId,
'name' => 'Freigabe erforderlich Email für den Käufer',
'technicalName' => 'checkout_order_release_process_order_customer_type',
'availableEntities' => [
'order' => 'order',
'customer' => 'customer'
]
],
[
[
'id' => Uuid::randomHex(),
'mailTemplateTypeId' => $mailTemplateTypeId,
'subject' => [
'en-GB' => 'Ihre Bestellung mit der Nummer {{ order.orderNumber }} wartet auf die Freigabe',
'de-DE' => 'Ihre Bestellung mit der Nummer {{ order.orderNumber }} wartet auf die Freigabe'
],
'contentPlain' => "Ihrer Bestellung mit der Nummer {{ order.orderNumber }} muss erst noch die Freigabe erteilt werden.\n\nBei Rückfragen zu der Freigabe erreichen sie ihren Ansprechpartner unter der Email {{ releaserEmail }}.",
'contentHtml' => "<p>Ihrer Bestellung mit der Nummer {{ order.orderNumber }} muss erst noch die Freigabe erteilt werden.</p><p>Bei Fragen zum Status der Freigabe erreichen sie ihren Ansprechpartner unter der Email {{ releaserEmail }}.</p>",
]
], $installContext->getContext());
$mailTemplateTypeId = Uuid::randomHex();
$this->createEmailTypeWithTemplates([
'id' => $mailTemplateTypeId,
'name' => 'Freigabe Email für den Vertriebsbeauftragten',
'technicalName' => 'checkout_order_release_process_type',
'availableEntities' => [
'order' => 'order',
'customer' => 'customer'
]
],
[
[
'id' => Uuid::randomHex(),
'mailTemplateTypeId' => $mailTemplateTypeId,
'subject' => [
'en-GB' => 'Bestellung befindet sich jetzt im Zustand "Freigabe erforderlich"',
'de-DE' => 'Bestellung befindet sich jetzt im Zustand "Freigabe erforderlich"'
],
'contentPlain' => "Es wurde eine neue Bestellung mit der Nummer {{ order.orderNumber }} aufgegeben die ihre Freigabe erwartet.\n\n{{ releaseUrl }}",
'contentHtml' => "<p>Es wurde eine neue Bestellung mit der Nummer {{ order.orderNumber }} aufgegeben die ihre Freigabe erwartet.</p><p><a href=\"{{ releaseUrl }}\">{{ releaseUrl }}</a></p>",
]
], $installContext->getContext());
}
public function uninstall(UninstallContext $uninstallContext): void
{
parent::uninstall($uninstallContext);
//Keep UserData? Then do nothing here
if ($uninstallContext->keepUserData()) {
return;
}
$this->removeEmailTypeWithTemplates('checkout_order_release_process_type', $uninstallContext->getContext());
$this->removeEmailTypeWithTemplates('checkout_order_release_process_order_customer_type', $uninstallContext->getContext());
}
protected function getStateMachine(EntityRepositoryInterface $stateMachineRepository, Context $context): ?StateMachineEntity
{
$stateMachineCriteria = new Criteria();
$stateMachineCriteria->addFilter(new EqualsFilter('technicalName', 'order.state'));
return $stateMachineRepository->search($stateMachineCriteria, $context)->first();
}
protected function getStateMachineState($technicalName, $stateMachineId, EntityRepositoryInterface $stateMachineStateRepository, Context $context): ?StateMachineStateEntity
{
$stateMachineStateCriteria = new Criteria();
$stateMachineStateCriteria->addFilter(new EqualsFilter('stateMachineId', $stateMachineId));
$stateMachineStateCriteria->addFilter(new EqualsFilter('technicalName', $technicalName));
return $stateMachineStateRepository->search($stateMachineStateCriteria, $context)->first();
}
protected function getStateMachineTransition(array $newStateMachineTransition, EntityRepositoryInterface $stateMachineTransitionRepository, Context $context): ?StateMachineTransitionEntity
{
$stateMachineTransitionCriteria = new Criteria();
$stateMachineTransitionCriteria->addFilter(new EqualsFilter('actionName', $newStateMachineTransition['actionName']));
$stateMachineTransitionCriteria->addFilter(new EqualsFilter('stateMachineId', $newStateMachineTransition['stateMachineId']));
$stateMachineTransitionCriteria->addFilter(new EqualsFilter('fromStateId', $newStateMachineTransition['fromStateId']));
$stateMachineTransitionCriteria->addFilter(new EqualsFilter('toStateId', $newStateMachineTransition['toStateId']));
return $stateMachineTransitionRepository->search($stateMachineTransitionCriteria, $context)->first();
}
protected function createEmailTypeWithTemplates(array $type, array $templates, Context $context)
{
/** @var EntityRepositoryInterface $mailTemplateTypeRepository */
$mailTemplateTypeRepository = $this->container->get('mail_template_type.repository');
/** @var EntityRepositoryInterface $mailTemplateRepository */
$mailTemplateRepository = $this->container->get('mail_template.repository');
try {
$mailTemplateTypeRepository->create([$type], $context);
$mailTemplateRepository->create($templates, $context);
} catch (UniqueConstraintViolationException $exception) {
// No, we've already installed the fields, it's fine.
}
}
protected function removeEmailTypeWithTemplates(string $typeName, Context $context)
{
/** @var EntityRepositoryInterface $mailTemplateTypeRepository */
$mailTemplateTypeRepository = $this->container->get('mail_template_type.repository');
/** @var EntityRepositoryInterface $mailTemplateRepository */
$mailTemplateRepository = $this->container->get('mail_template.repository');
/** @var MailTemplateTypeEntity $myCustomMailTemplateType */
$myCustomMailTemplateType = $mailTemplateTypeRepository->search(
(new Criteria())->addFilter(new EqualsFilter('technicalName', $typeName)), $context
)->first();
$ids = [];
if ($myCustomMailTemplateType instanceof MailTemplateTypeEntity) {
$mailTemplateIds = $mailTemplateRepository->searchIds(
(new Criteria())->addFilter(new EqualsFilter('mailTemplateTypeId', $myCustomMailTemplateType->getId())), $context
)->getIds();
//Get the Ids from the fetched Entities
$ids = array_map(static function ($id) {
return ['id' => $id];
}, $mailTemplateIds);
}
$mailTemplateTypeRepository->delete([
['id' => $myCustomMailTemplateType->getId()]
], $context);
$mailTemplateRepository->delete($ids, $context);
}
}