<?php
namespace CioFormBuilder\Subscriber;
use CioFormBuilder\Definition\CioForm\CioFormEntity;
use CioFormBuilder\Error\CioFormBuilderBasicProductError;
use CioFormBuilder\Model\CioFormBuilder;
use Shopware\Core\Checkout\Cart\Cart;
use Shopware\Core\Checkout\Cart\Event\CheckoutOrderPlacedEvent;
use Shopware\Core\Checkout\Customer\CustomerEntity;
use Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionEntity;
use Shopware\Core\Checkout\Payment\PaymentMethodEntity;
use Shopware\Core\Content\Product\ProductEntity;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Storefront\Event\StorefrontRenderEvent;
use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPage;
use Shopware\Storefront\Page\Checkout\Finish\CheckoutFinishPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Contracts\Translation\TranslatorInterface;
use function PHPUnit\Framework\isInstanceOf;
class CheckoutConfirmSubscriber implements EventSubscriberInterface
{
private EntityRepository $productRepository;
private EntityRepository $cioFormRepository;
private ?Request $request;
private EntityRepository $orderRepository;
private EntityRepository $productManufacturerRepository;
private SystemConfigService $systemConfigService;
private TranslatorInterface $translator;
public function __construct(
RequestStack $requestStack,
EntityRepository $productRepository,
EntityRepository $cioFormRepository,
EntityRepository $orderRepository,
EntityRepository $productManufacturerRepository,
SystemConfigService $systemConfigService,
TranslatorInterface $translator
){
$this->request = $requestStack->getCurrentRequest();
$this->productRepository = $productRepository;
$this->cioFormRepository = $cioFormRepository;
$this->orderRepository = $orderRepository;
$this->productManufacturerRepository = $productManufacturerRepository;
$this->systemConfigService = $systemConfigService;
$this->translator = $translator;
}
public static function getSubscribedEvents(): array
{
return [
StorefrontRenderEvent::class => 'onStorefrontRenderEvent',
CheckoutOrderPlacedEvent::class => 'onCheckoutOrderPlacedEvent',
CheckoutFinishPageLoadedEvent::class => 'onCheckoutFinishPageLoadedEvent'
];
}
public function onStorefrontRenderEvent(StorefrontRenderEvent $event): void
{
$formToManufacturer = [];
$manufacturerForms = [];
$setCostcenter = false;
$customer = $event->getSalesChannelContext()->getCustomer();
$noBasicProduct = true;
$allEventProduct = true;
$errors = [];
$cioCostcenter = $this->systemConfigService->get('CioFormBuilder.config.eventReleaseCostcenter');
if ($customer instanceof CustomerEntity) {
if (is_array($event->getParameters()) && key_exists('page', $event->getParameters())) {
$page = $event->getParameters()['page'];
if ($page instanceof CheckoutConfirmPage) {
$items = $page->getCart()->getLineItems();
foreach ($items as $item) {
$productNumber = $item->getPayload()['productNumber'];
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('productNumber', $productNumber));
$criteria->addAssociation('manufacturer');
$criteria->addAssociation('formData');
$criteria->addAssociation('fields');
/** @var ?ProductEntity $productEntity */
$productEntity = $this->productRepository->search($criteria, $event->getContext())->first();
if ($productEntity ){
$customFields = $productEntity->getCustomFields();
if(isset($customFields['custom_event_basic_package']) && $customFields['custom_event_basic_package'] === true){
$noBasicProduct = false;
}
if(isset($customFields['custom_event_article']) && $customFields['custom_event_article'] === true){
$setCostcenter = true;
}else{
$allEventProduct = false;
}
}
if ($productEntity && $productEntity->getManufacturer()) {
$manufacturerEntity = $productEntity->getManufacturer();
if (!is_null($manufacturerEntity->getExtension('formData'))) {
/** @var CioFormEntity $formBuilderEntity */
$formBuilderEntity = $manufacturerEntity->getExtension('formData');
if (!isset($manufacturerForms[$manufacturerEntity->getId()])) {
$formCriteria = new Criteria();
$formCriteria->addFilter(new EqualsFilter('id', $formBuilderEntity->getId()));
$formCriteria->addAssociation('fields');
$formCriteria->addAssociation('mailTemplate');
$formEntity = $this->cioFormRepository->search($formCriteria, $event->getContext())->first();
$formBuilder = new CioFormBuilder($formEntity);
if (!isset($formToManufacturer[$formEntity->getId()]) && !isset($manufacturerForms[$manufacturerEntity->getId()])) {
$manufacturerForms[$manufacturerEntity->getId()] = $formBuilder;
}
if (!isset($formToManufacturer[$formEntity->getId()]) || !in_array($formEntity->getId() . '_' . $manufacturerEntity->getId(), $formToManufacturer)) {
$formToManufacturer[$formEntity->getId()][] = $formEntity->getId() . '_' . $manufacturerEntity->getId();
}
}
}
}
}
if ($setCostcenter === true ){
/** @var Cart $cart */
$cart = $event->getParameters()['page']->getCart();
if( $noBasicProduct === true || $allEventProduct === false) {
$cart->addErrors(new CioFormBuilderBasicProductError());
}
if( $noBasicProduct === true) {
$errors[] = ['type' => 'raw', 'message' => 'checkout.event.noBasisProduct' ];
}
if( $allEventProduct === false) {
$errors[] = ['type' => 'norm', 'message' => 'checkout.event.notAllEventProducts' ];
}
}
}
}
}
$event->setParameter('manufacturerForms', $manufacturerForms);
$event->setParameter('formToManufacturer', $formToManufacturer);
if(!empty($errors)){
if (array_key_exists('errors', $event->getParameters())) {
$event->setParameter('errors', array_merge($event->getParameters()['errors'], $errors));
} else {
$event->setParameter('errors', $errors);
}
}
if($setCostcenter && !empty($cioCostcenter)){
$event->setParameter('cio_costcenter', $cioCostcenter);
}
}
public function onCheckoutOrderPlacedEvent(CheckoutOrderPlacedEvent $event): void
{
$request = $this->request->request;
$order = $event->getOrder();
$customFields = $order->getCustomFields();
if ($this->request && $request->get('cioFormManufactorerIds') &&
$order->getTransactions()->first() instanceof OrderTransactionEntity &&
$order->getTransactions()->first()->getPaymentMethod() instanceof PaymentMethodEntity &&
$order->getTransactions()->first()->getPaymentMethod()->getName() == 'Kostenstelle Event'
) {
$cioFormManufactorerIds = (array)$request->get('cioFormManufactorerIds');
$manufacturerForm = [];
$formIds = [];
$i = 0;
foreach ($cioFormManufactorerIds as $formManIds) {
$form = [];
$tmp = explode('_', $formManIds);
if (count($tmp) == 2) {
$formEntity = $this->getCioFormById($tmp[0], $event->getContext());
if (!is_null($formEntity)) {
$fields = $formEntity->getFields();
if(!in_array($tmp[0] , $formIds)){
$formIds[] = $tmp[0];
$form = [
'id' => $tmp[0],
'name' => $formEntity->getName(),
'description' => $formEntity->getDescription(),
'fields' => []
];
foreach ($fields as $key => $field) {
$form['fields'][] = [
'id' => $key,
'position' => intval($field->getPosition()),
'name' => $field->getLabel(),
'value' => $request->get($key),
'required' => $field->getRequired(),
'type' => $field->getType()
];
}
$dataColumns = array_column($form['fields'], 'position');
array_multisort($dataColumns,SORT_ASC, $form['fields']);
$manufacturerForm['form'][] = $form;
}
$manufacturerForm['manufacturer'][] = [
'id' => $tmp[1],
'name' => $this->getManufacturerNameById($tmp[1], $event->getContext()),
'formId' => $tmp[0],
];
}
}
}
$customFields['dynamicForms'] = $manufacturerForm;
$event->getOrder()->setCustomFields($customFields);
try {
$this->orderRepository->update([
[
'id' => $event->getOrder()->getId(),
'customFields' => $customFields
]
], $event->getContext());
} catch (\Throwable $e) {
}
}
}
public function getCioFormById(string $formId, $context): ?CioFormEntity
{
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('id', $formId));
$criteria->addAssociation('fields');
$criteria->addAssociation('mailTemplate');
$criteria->addSorting(new FieldSorting('fields.position', FieldSorting::ASCENDING));
$formEntity = $this->cioFormRepository->search($criteria, $context)->first();
if ($formEntity instanceof CioFormEntity) {
return $formEntity;
}
return null;
}
public function onCheckoutFinishPageLoadedEvent(CheckoutFinishPageLoadedEvent $event)
{
$orderEntity = $event->getPage()->getOrder();
$customFields = $orderEntity->getCustomFields();
$manufacturerForms = [];
if (isset($customFields['dynamicForms'])) {
$formData = [];
$dynamicForms = $customFields['dynamicForms'];
foreach ($dynamicForms['form'] as $form) {
$formEntity = $this->getCioFormById($form['id'], $event->getContext());
$formBuilder = new CioFormBuilder($formEntity);
if(!isset($formData[$formEntity->getId()])){
$formData[$formEntity->getId()] = $form;
$manufacturerForms[] = $formBuilder->buildEmailDataFromArray($form);
}
}
$event->getPage()->assign([
'formData' => $formData,
'manufacturerForms' => $manufacturerForms
]);
}
}
private function getManufacturerNameById(string $manufacturerId, Context $context)
{
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('id', $manufacturerId));
$formEntity = $this->productManufacturerRepository->search($criteria, $context)->first();
if ($formEntity instanceof CioFormEntity) {
return $formEntity->getTranslation('name');
}
return null;
}
}