<?php
namespace EnetCredit\Subscriber;
use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemEntity;
use Shopware\Core\Checkout\Order\OrderEvents;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class OrderPlacedSubscriber implements EventSubscriberInterface
{
/** @var EntityRepository $orderRepository */
private $orderRepository;
/** @var EntityRepository $customerRepository */
private $customerRepository;
/** @var EntityRepository $orderTransactionRepository */
private $orderTransactionRepository;
public function __construct(EntityRepository $orderRepository, EntityRepository $orderTransactionRepository, EntityRepository $customerRepository)
{
$this->orderRepository = $orderRepository;
$this->customerRepository = $customerRepository;
$this->orderTransactionRepository = $orderTransactionRepository;
}
public static function getSubscribedEvents()
{
return [
// OrderEvents::ORDER_WRITTEN_EVENT => 'onOrderPlaced',
// TODO: dieses event nutzen, das triggered wenn der paymentstatus sich ändern
OrderEvents::ORDER_TRANSACTION_WRITTEN_EVENT => 'onOrderPlaced',
];
}
// TODO: den bezahlstatus auf true setzen
public function onOrderPlaced(EntityWrittenEvent $event)
{
if ($writeResults = $event->getWriteResults()) {
$context = $event->getContext();
if (isset($writeResults[0])) {
$payload = $writeResults[0]->getPayload();
// check for payload existence
// when using PayPal the first statusChange has no stateId in payload
if(!isset($payload['stateId'])) {
return;
}
// TODO: get status by technical name, not the id!
if($payload['stateId'] !== '5f96feede9e94ffbaa98b60c8dfac558') { // paid
return;
}
$orderEntity = $this->getOrder($payload, $context);
$lineItem = $orderEntity->getLineItems();
$orderCustomerEntity = $orderEntity->getOrderCustomer();
if(count($lineItem->getElements()) > 0) {
foreach($lineItem->getElements() as $lineItemEntity) {
$product = $lineItemEntity->getProduct();
$customFields = $product->getCustomFields();
if(isset($customFields['enet_credit_product']) && $customFields['enet_credit_product'] === true) {
$bonus = floatval($customFields['enet_credit_bonus']);
$quantity = $lineItemEntity->getQuantity();
$totalPrice = $lineItemEntity->getTotalPrice();
$customerAvailCredit = $this->getCustomerAvailCredit($orderCustomerEntity, $context);
$newCreditValue = $totalPrice + ($bonus * $quantity) + $customerAvailCredit;
$this->customerRepository->update(
[
[
'id' => $orderCustomerEntity->getCustomerId(),
'customFields' => ['enet_credit_value' => $newCreditValue]
]
],
$context
);
}
}
}
}
}
}
private function getCustomerAvailCredit($orderCustomerEntity, $context)
{
$orderCustomerId = $orderCustomerEntity->getCustomerId();
$criteria = new Criteria([$orderCustomerId]);
$customerEntity = $this->customerRepository->search($criteria, $context)->first();
$creditValue = $customerEntity->getCustomFields();
if(isset($creditValue['enet_credit_value']) && $creditValue['enet_credit_value']) {
return floatval($creditValue['enet_credit_value']);
}
return 0;
}
private function getOrder($payload, $context)
{
$criteria = new Criteria([$payload['id']]);
$criteria->addAssociation('order');
$criteria->addAssociation('order.lineItems');
$criteria->addAssociation('order.lineItems.product');
$criteria->addAssociation('order.transactions');
$orderTransactionResult = $this->orderTransactionRepository->search(
$criteria,
$context
);
return $orderTransactionResult->getElements()[
array_keys($orderTransactionResult->getElements())[0]
]->getOrder();
}
}