<?php declare(strict_types=1);
namespace DreiwmBrandstetterPlugin\Subscriber;
use DateTime;
use DreiwmBrandstetterPlugin\Service\DateValidator;
use DreiwmBrandstetterPlugin\Service\RadbotenService;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use Shopware\Core\Checkout\Cart\SalesChannel\CartService;
use Shopware\Core\Checkout\Order\Aggregate\OrderAddress\OrderAddressEntity;
use Shopware\Core\Checkout\Order\Aggregate\OrderCustomer\OrderCustomerEntity;
use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemCollection;
use Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionEntity;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\System\StateMachine\Event\StateMachineStateChangeEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class ShippingMethodSubscriber implements EventSubscriberInterface
{
private $flashBag;
private $cartService;
private DateValidator $dateValidator;
private EntityRepository $orderTransactionRepository;
private RadbotenService $radbotenService;
private EntityRepository $productRepository;
public function __construct(
$flashBag,
CartService $cartService,
DateValidator $dateValidator,
EntityRepository $orderTransactionRepository,
RadbotenService $radbotenService,
EntityRepository $productRepository
) {
$this->flashBag = $flashBag;
$this->cartService = $cartService;
$this->dateValidator = $dateValidator;
$this->orderTransactionRepository = $orderTransactionRepository;
$this->radbotenService = $radbotenService;
$this->productRepository = $productRepository;
}
public static function getSubscribedEvents(): array
{
return [
// wenn sich der Zahlungsstatus ändert
'state_machine.order_transaction.state_changed' => 'onOrderTransactionPaid',
];
}
/**
* Wird aufgerufen, wenn sich der Zahlungsstatus einer Bestellung ändert
* Wird gebraucht um die Bestellung an EasyTrans (Radboten) zu senden
* @param StateMachineStateChangeEvent $event
* @return void
* @throws GuzzleException
*/
public function onOrderTransactionPaid(StateMachineStateChangeEvent $event): void
{
if ($event->getStateEventName() === 'state_enter.order_transaction.state.paid') {
// Lade die Transaktion, um auf die Bestellinformationen zuzugreifen
$transactionId = $event->getTransition()->getEntityId();
$context = $event->getContext();
$criteria = new Criteria([$transactionId]);
$criteria->addAssociation('order');
$criteria->addAssociation('order.addresses');
$criteria->addAssociation('order.lineItems');
$criteria->addAssociation('order.deliveries.shippingMethod');
/**@var OrderTransactionEntity $transaction */
$transaction = $this->orderTransactionRepository->search($criteria, $context)->first();
if (!$transaction || !$transaction->getOrder()) {
return;
}
// Zugriff auf die Bestellung
$order = $transaction->getOrder();
// nur Bestellungen mit Radboten-Versandart
$shippingMethod = $order->getDeliveries()->first()->getShippingMethod()->getId();
if (!$this->dateValidator->isRadbotenShippingMethod($shippingMethod)) {
return;
}
//hole den Kunden
/**@var OrderCustomerEntity $customer */
$customer = $order->getOrderCustomer();
/**@var OrderAddressEntity $customerAddress */
$customerAddress = $order->getDeliveries()->getShippingAddress()->first();
// hole das Gewicht des Warenkorbs
$lineItems = $order->getLineItems();
$ls_desiredRadbotenTimeRange = $order->getCustomFields()['brandstetter_orders_desired_delivery_timeRange_radboten'];
// Verwende die Methode calculateTotalWeightAndPackstationMultiplier, um das Gewicht zu berechnen
$calculatedValues = $this->calculateTotalWeightAndPackstationMultiplier($lineItems, $context);
$weight = $calculatedValues['totalWeight'];
// Hole das gewünschte Lieferdatum und das Lieferzeitfenster aus den Custom Fields der Bestellung
$customFields = $order->getCustomFields();
// Der ursprüngliche Wert von $desiredDeliveryDate
$originalValue = $customFields['brandstetter_orders_desired_delivery_date'] ?? null;
// Überprüfen, ob ein Wert vorhanden ist
if ($originalValue !== null) {
try {
// Erstellen eines DateTime-Objekts aus dem ursprünglichen Wert
$date = new DateTime($originalValue);
// Formatieren des Datums in das gewünschte Format 'Y-m-d H:i'
$formattedDate = $date->format('Y-m-d');
// Zuweisen des formatierten Datums zu $desiredDeliveryDate
$ls_desiredDeliveryDate = $formattedDate;
} catch (Exception $e) {
// @todo Loggen des Fehlers und abbrechen der Bestellung
echo "Fehler bei der Datumsumwandlung: " . $e->getMessage();
$ls_desiredDeliveryDate = null;
}
} else {
// Kein Wert vorhanden, $desiredDeliveryDate bleibt null
$ls_desiredDeliveryDate = null;
}
// Abstellort
$pickupLocation = $order->getCustomFields()['brandstetter_orders_desired_dropoff_location'];
if ($pickupLocation !== null) {
$pickupLocation = ' Abstellort: ' . $order->getCustomFields()['brandstetter_orders_desired_dropoff_location'];
}
$orderContent = [
[
'date' => $ls_desiredDeliveryDate,
'status' => 'submit',
'productno' => $this->calculateProductNumberForRadbotenOrder($ls_desiredDeliveryDate),
'email_receiver' => $customer->getEmail(),
'order_destinations' => [
[
"company_name" => "Marktcafé Brandstetter GmbH & Co. KG",
"address" => "Marktgasse",
"houseno" => "3",
"postal_code" => "97070",
"city" => "Würzburg",
],
[
'company_name' => $customerAddress->getCompany(),
'contact' => $customerAddress->getFirstName() . ' ' . $customerAddress->getLastName(),
'address' => $customerAddress->getStreet(),
'postal_code' => $customerAddress->getZipcode(),
'city' => $customerAddress->getCity(),
'delivery_date' => $ls_desiredDeliveryDate,
'delivery_time' => explode(' - ', $ls_desiredRadbotenTimeRange)[1],
'delivery_time_from' => explode(' - ', $ls_desiredRadbotenTimeRange)[0],
"customer_reference" => 'Ihre Bestellung ' . $order->getOrderNumber(),
"destination_remark" => $pickupLocation,
],
],
'order_packages' => [
[
'amount' => 1,
'weight' => $weight,
]
]
]
];
$this->radbotenService->sendOrderToEasyTrans($orderContent);
}
}
/**
* Prüfe, ob Packstation ein freies Fach hat
*/
public
function checkFreeLockerInPackstation()
{
$data = array(
"api_id" => "6e4k3xhzzrcm067p986891mtwlq54n",
"api_key" => "f21z374c75730881k2q09mx2qtmt7y",
"pkkid" => "9323466505932151"
);
$ch = curl_init('https://api.paketin.de/v1/find/locker/');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_TIMEOUT, 30); //timeout in seconds
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
$curl_result = curl_exec($ch);
$result = json_decode($curl_result);
dd($result);
}
/**
* prüft jedes Mal, wenn ein LineItem hinzugefügt oder entfernt wird, ob die Packstation noch ein freies Fach hat
*
*/
public
function checkFreeLockerInPackstationOnCartChange()
{
$data = array(
"api_id" => "6e4k3xhzzrcm067p986891mtwlq54n",
"api_key" => "f21z374c75730881k2q09mx2qtmt7y",
"pkkid" => "9323 4665 0593 21519323 4665 0593 2151",
"boxgroup_id" => "418",
);
}
/**
* Berechnet die Produkt-Nummer (EayseTrnas) für eine Radboten-Bestellung
* Wird benötigt, um die Bestellung an EasyTrans zu senden
* @param $desiredDeliveryDate
* @return int
* @throws Exception
*/
private function calculateProductNumberForRadbotenOrder($desiredDeliveryDate): int
{
// ist das Bestelldatum das Lieferdatum? ja: Produkt-Nummer 34, nein: Produkt-Nummer 33
if ($this->dateValidator->isDeliveryDateToday($desiredDeliveryDate)) {
return 34;
} else {
return 33;
}
}
private function calculateTotalWeightAndPackstationMultiplier(?OrderLineItemCollection $lineItems, $context): array
{
$totalWeight = 0.0;
$packstationMultiplierSum = 0;
foreach ($lineItems as $lineItem) {
// Berechnung des Gewichts
if ($lineItem->getType() === 'product' && $lineItem->getProductId()) {
$criteria = new Criteria([$lineItem->getProductId()]);
$product = $this->productRepository->search($criteria, $context)->first();
$productWeight = 0.0;
if ($product) {
$productWeight = $product->getWeight() ?? 0;
// Wenn das Produkt eine Variante ist und kein Gewicht hat, versuche das Gewicht vom Parent zu bekommen
if ($product->getParentId() && $productWeight === 0) {
$parentCriteria = new Criteria([$product->getParentId()]);
$parentProduct = $this->productRepository->search($parentCriteria, $context)->first();
$productWeight = $parentProduct ? $parentProduct->getWeight() ?? 0 : 0;
}
}
$lineItemWeight = $productWeight * $lineItem->getQuantity();
$totalWeight += $lineItemWeight;
}
// Berechnung des packstationMultipliers aus den Custom Fields
// $customFields = $lineItem->getPayload()['customFields'] ?? [];
// if (isset($customFields['packstationMultiplier'])) {
// $multiplier = $customFields['packstationMultiplier'];
// $packstationMultiplierSum += $multiplier * $lineItem->getQuantity();
// }
}
// Rückgabe beider Werte in einem Array
return [
'totalWeight' => $totalWeight,
'packstationMultiplierSum' => $packstationMultiplierSum,
];
}
}