<?php
declare(strict_types=1);
namespace Wbfk\Offer\Subscriber;
use Shopware\Core\Checkout\Order\OrderEntity;
use Shopware\Core\Checkout\Order\OrderEvents;
use Shopware\Core\Defaults;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\EntityWriteResult;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\Uuid\Uuid;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Wbfk\Offer\Core\Entity\Offer\OfferEntity;
use Wbfk\Offer\Core\Offer\Storefront\OfferService;
use WbfkExtensions\Core\Checkout\WbfkOrderExtension\WbfkOrderExtensionEntity;
class AddOfferDetailsToOrder implements EventSubscriberInterface
{
public function __construct(
private readonly OfferService $offerService,
private readonly EntityRepository $orderRepository,
private readonly EntityRepository $offerRepository,
private readonly EntityRepository $wbfkOrderExtensionRepository,
private readonly EntityRepository $kzphLastchangeRepository
)
{
}
public static function getSubscribedEvents(): array
{
return [
OrderEvents::ORDER_WRITTEN_EVENT => 'addOfferDetailsToOrder',
];
}
public function addOfferDetailsToOrder(EntityWrittenEvent $event): void
{
foreach ($event->getWriteResults() as $result) {
if (!in_array($result->getOperation(), [EntityWriteResult::OPERATION_INSERT, EntityWriteResult::OPERATION_UPDATE])) {
continue;
}
$orderId = $result->getPayload()['id'] ?? null;
if (!$orderId) {
continue;
}
// Fetch offer
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('orderId', $orderId));
$criteria->setLimit(1);
/** @var OfferEntity $offer */
$offer = $this->offerRepository->search($criteria, $event->getContext())->first();
if (!$offer) return;
// Fetch order
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('id', $orderId));
$criteria->addAssociation('lineItems');
$criteria->addAssociation('wbfkOrderExtension');
$criteria->setLimit(1);
/** @var ?OrderEntity $order */
$order = $this->orderRepository->search($criteria, $event->getContext())->first();
if (!$order) return;
$updatedOrderData = [];
$updatedOrderCustomFields = $order->getCustomFields() ?? [];
if ($result->getOperation() === EntityWriteResult::OPERATION_INSERT & $event->getContext()->getVersionId() === Defaults::LIVE_VERSION) {
// Set order shipping prime cost
if (!!$offer->getShippingPrimeCost()) {
$updatedOrderCustomFields['wbfk_shipping_prime_cost'] = $offer->getShippingPrimeCost();
$updatedOrderData['customFields'] = $updatedOrderCustomFields;
}
// Set XInvoice routing id
if (!!$offer->getXInvoice()) {
$updatedOrderCustomFields['wbfk_invoice_x_invoice_routing_id'] = $offer->getXInvoice();
$updatedOrderData['customFields'] = $updatedOrderCustomFields;
}
// Set project / order reference
if (!!$offer->getProjectNumber()) {
$updatedOrderCustomFields['wbfk_order_reference'] = $offer->getProjectNumber();
$updatedOrderData['customFields'] = $updatedOrderCustomFields;
}
// Set order payment target
if ($offer->getPaymentTarget()) {
$updatedOrderCustomFields['wbfk_invoice_payment_target'] = $offer->getPaymentTarget();
$updatedOrderData['customFields'] = $updatedOrderCustomFields;
}
// Set Hide Billing Address Contact Name
if (!!$offer->getCustomFields() && isset($offer->getCustomFields()['wbfk_hide_billing_address_name'])) {
$updatedOrderCustomFields['wbfk_hide_billing_address_name'] = $offer->getCustomFields()['wbfk_hide_billing_address_name'];
$updatedOrderData['customFields'] = $updatedOrderCustomFields;
}
// Set Hide Shipping Address Contact Name
if (!!$offer->getCustomFields() && isset($offer->getCustomFields()['wbfk_hide_shipping_address_name'])) {
$updatedOrderCustomFields['wbfk_hide_shipping_address_name'] = $offer->getCustomFields()['wbfk_hide_shipping_address_name'];
$updatedOrderData['customFields'] = $updatedOrderCustomFields;
}
// Set order creator
if (isset($_REQUEST['creatorUsername']) && $creatorUsername = $_REQUEST['creatorUsername']) {
$this->createKzphLastchangeOrderCreationRecord($orderId, $creatorUsername, $event->getContext());
}
// Set order assignee
/** @var WbfkOrderExtensionEntity $wbfkOrderExtension */
if ($offer->getAssigneeId() && $wbfkOrderExtension = $order->getExtension('wbfkOrderExtension')) {
$this->updateWbfkOrderExtension($wbfkOrderExtension->getId(), ['assigneeId' => $offer->getAssigneeId()], $event->getContext());
}
}
if (!empty($updatedOrderData) && json_encode($updatedOrderData) !== json_encode(['customFields' => $order->getCustomFields()])) {
$this->updateOrder($orderId, $updatedOrderData, $event->getContext());
}
}
}
/**
* @param string $orderId
* @param array $params
* @param Context $context
*/
private function updateOrder(string $orderId, array $params, Context $context): void
{
$rowData = ['id' => $orderId];
foreach ($params as $paramKey => $paramValue) {
$rowData[$paramKey] = $paramValue;
}
$this->orderRepository->update([$rowData], $context);
}
/**
* @param string $wbfkOrderExtensionId
* @param array $params
* @param Context $context
*/
private function updateWbfkOrderExtension(string $wbfkOrderExtensionId, array $params, Context $context): void
{
$rowData = ['id' => $wbfkOrderExtensionId];
foreach ($params as $paramKey => $paramValue) {
$rowData[$paramKey] = $paramValue;
}
$this->wbfkOrderExtensionRepository->update([$rowData], $context);
}
/**
* @param string $wbfkOrderExtensionId
* @param array $params
* @param Context $context
*/
private function createKzphLastchangeOrderCreationRecord(string $orderId, string $creatorUsername, Context $context): void
{
$this->kzphLastchangeRepository->create(
[[
'id' => Uuid::randomHex(),
'entityId' => $orderId,
'entityType' => 'order',
'type' => 'created',
'username' => $creatorUsername
]],
$context);
}
}