custom/plugins/ProcLiveOrderHistory/src/Subscriber/LiveOrderHistorySubscriber.php line 112

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Proc\ProcLiveOrderHistory\Subscriber;
  3. use Proc\ProcFoundation\Helper\ErrorHandler;
  4. use Proc\ProcFoundation\Helper\RequestHandler;
  5. use Proc\ProcFoundation\Service\ProcFoundationService;
  6. use Proc\ProcLiveOrderHistory\Helper\OrderHistoryStruct;
  7. use Proc\ProcLiveOrderHistory\Helper\BuildRequestHelper;
  8. use Shopware\Storefront\Page\Account\Order\AccountOrderPageLoadedEvent;
  9. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  10. use DateTime;
  11. use Exception;
  12. /**
  13.  * Class LiveOrderHistorySubscriber
  14.  * @package Proc\ProcLiveOrderHistory\Subscriber
  15.  */
  16. class LiveOrderHistorySubscriber implements EventSubscriberInterface
  17. {
  18.     private const PATH_HEADLIST '/iman/order-history-headlist';
  19.     private const PATH_DETAILS '/iman/order-history-details';
  20.     /**
  21.      * @todo
  22.      * Richtig muss es '/iman/order-history-document' heißen. Dies muss aber noch im iMan angepasst werden.
  23.      */
  24.     private const PATH_DOCUMENTS '/iman/order-history-documents';
  25. //     private const PATH_DOCUMENTS = '/iman/order-history-document';
  26.     /**
  27.      * @var RequestHandler
  28.      */
  29.     private $requestHandler;
  30.     /**
  31.      * @var ErrorHandler
  32.      */
  33.     private $errorHandler;
  34.     /**
  35.      * @var string
  36.      */
  37.     private $host,
  38.             $port,
  39.             $customerNumber,
  40.             $fromDate,
  41.             $toDate;
  42.     private $error null;
  43.     /**
  44.      * @var ProcFoundationService
  45.      */
  46.     private $foundationService;
  47.     /**
  48.      * @var AccountOrderPageLoadedEvent
  49.      */
  50.     private $event;
  51.     /**
  52.      * @var int
  53.      */
  54.     private $elementsPerPage,
  55.             $page;
  56.     /**
  57.      * @inheritDoc
  58.      */
  59.     public static function getSubscribedEvents()
  60.     {
  61.         return [
  62.             AccountOrderPageLoadedEvent::class => ['onAccountOrderPageLoaded' ,1]
  63.         ];
  64.     }
  65.     /**
  66.      * LiveOrderHistorySubscriber constructor.
  67.      * @param ProcFoundationService $foundationService
  68.      * @param RequestHandler $requestHandler
  69.      * @param ErrorHandler $errorHandler
  70.      * @throws Exception
  71.      */
  72.     public function __construct(ProcFoundationService $foundationServiceRequestHandler $requestHandlerErrorHandler $errorHandler)
  73.     {
  74.         $this->foundationService $foundationService;
  75.         $this->requestHandler $requestHandler;
  76.         $this->errorHandler $errorHandler;
  77.     }
  78.     /**
  79.      * @param AccountOrderPageLoadedEvent $event
  80.      */
  81.     public function onAccountOrderPageLoaded(AccountOrderPageLoadedEvent $event)
  82.     {
  83.         $this->event $event;
  84.         /**
  85.          * Prüfung ob Benutzer angemeldet ist, sonst keine Live-Abfrage.
  86.          */
  87.         if (!($this->checkLogin()) || !($this->checkConfig()))
  88.         {
  89.             $orderNotComplete['fromDate'] = (new DateTime())->format('Y-m-d');
  90.             $orderNotComplete['toDate'] = (new DateTime())->format('Y-m-d');
  91.             $orderNotComplete['numElements'] = 0;
  92.             $orderNotComplete['order-history-list'] = '';
  93.             $orderNotCompleteStruct = new OrderHistoryStruct();
  94.             $orderNotCompleteStruct->setOrderHistory($orderNotComplete);
  95.             $this->event->getPage()->addExtension('order_history'$orderNotCompleteStruct);
  96.             return;
  97.         }
  98.         $this->handleOrderHistory();
  99.     }
  100.     private function checkLogin()
  101.     {
  102.         $this->customerNumber $this->foundationService->checkLogin($this->event->getSalesChannelContext(), (string)get_class($this));
  103.         if (!($this->customerNumber)) return false;
  104.         return true;
  105.     }
  106.     /**
  107.      * Hauptfunktion welche das einlesen der OrderHistory primär steuert.
  108.      * Die OrderHistory wird anhand vorhandener Daten eingelesen. Wird kein Datum ermittelt werden alle Order von 1.1.2021 bis zum aktuellen Datum vom iMan geholt.
  109.      * Standard Anzahl der Elemente pro Seite ist bei 10, kann aber über das Menü der OrderHistory auch anders ausgewählt werden.
  110.      */
  111.     public function handleOrderHistory()
  112.     {
  113.         $request $this->event->getRequest();
  114.         if ($request->getQueryString() == '') {
  115.             $orderNotComplete['fromDate'] = (new DateTime())->format('Y-m-d');
  116.             $orderNotComplete['toDate'] = (new DateTime())->format('Y-m-d');
  117.             $orderNotComplete['numElements'] = 0;
  118.             $orderNotComplete['order-history-list'] = '';
  119.             $orderNotCompleteStruct = new OrderHistoryStruct();
  120.             $orderNotCompleteStruct->setOrderHistory($orderNotComplete);
  121.             $this->event->getPage()->addExtension('order_history'$orderNotCompleteStruct);
  122.             return;
  123.         }
  124.         $fromDate           $request->get('fromDate');
  125.         $toDate             $request->get('toDate');
  126.         $this->elementsPerPage    = (int)$request->get('numElements');
  127.         $this->page               = (int)$request->get('page');
  128.         $orderHistory $this->getOrderHistory($fromDate$toDate);
  129.         if ($orderHistory['head']['status'] === 'NOK') {
  130.             $this->error $this->errorHandler->error($this->errorHandler::SAP_RESPONSE_ERRORget_class($this), 'SAP Status Fehler.' print_r($orderHistorytrue));
  131.             $this->errorHandler->writeErrorLog($this->error);
  132.             $orderNotComplete['fromDate'] = $request->get('fromDate');
  133.             $orderNotComplete['toDate'] = $request->get('toDate');
  134.             $orderNotComplete['numElements'] = 0;
  135.             $orderNotComplete['order-history-list'] = '';
  136.             $orderNotCompleteStruct = new OrderHistoryStruct();
  137.             $orderNotCompleteStruct->setOrderHistory($orderNotComplete);
  138.             $this->event->getPage()->addExtension('order_history'$orderNotCompleteStruct);
  139.         } else {
  140.             $orderHistory $this->formatOrderHistory($orderHistory);
  141.             $pageOrders $this->getOrdersPerPage($orderHistory);
  142.             $orderComplete $this->getOrderDetails($pageOrders);
  143.             // $numElements = count($orderComplete['order-history-list']['order']);
  144.             $numElements $this->elementsPerPage;
  145.             $orderComplete['numElements'] = $numElements;
  146.             if (null !== $qs $this->event->getRequest()->getQueryString()) {
  147.                 $qs '?'.$qs;
  148.             }
  149.             $orderComplete['baseUri'] = $this->event->getSalesChannelContext()->getSalesChannel()->getDomains()->first()->getUrl() .$this->event->getRequest()->getPathInfo().$qs;
  150.             $orderComplete['fromDate'] = $this->fromDate;
  151.             $orderComplete['toDate'] = $this->toDate;
  152.             $orderCompleteStruct = new OrderHistoryStruct();
  153.             $orderCompleteStruct->setOrderHistory($orderComplete);
  154.             $this->event->getPage()->addExtension('order_history'$orderCompleteStruct);
  155.         }
  156.     }
  157.     /**
  158.      * Nimm die Liste der OrderHistory-Elemente für die Zeit von-bis, wie beim Aufruf der getOrderHistory definiert
  159.      * schneidet" die Elemente für die gewünschte Seite aus und gibt das gekürzte Array zurück.
  160.      * @param $orderHistory
  161.      * @return array
  162.      */
  163.     protected function getOrdersPerPage($orderHistory) : array
  164.     {
  165.         $numElements count($orderHistory['order-history-list']['order']);
  166.         if ($this->page === '' || $this->elementsPerPage === '' || $this->elementsPerPage === null) {
  167.             $this->page 1;
  168.             $this->elementsPerPage 10;
  169.         }
  170.         if ($numElements <= $this->elementsPerPage) {
  171.             return $orderHistory;
  172.         }
  173.         $start = ($this->page 1) * $this->elementsPerPage;
  174.         $end = ($this->page $this->elementsPerPage) - 1;
  175.         $resultArray['head'] = $orderHistory['head'];
  176.         $resultArray['order-history-list']['order'] = array_slice($orderHistory['order-history-list']['order'], $start$this->elementsPerPage);
  177.         $resultArray['numPages'] = (int)ceil($numElements $this->elementsPerPage);
  178.         return $resultArray;
  179.     }
  180.     /**
  181.      * Liest die OrderHistory aus und die hinterlegten Dokumente
  182.      * füllte das Basis-Array mit diesen Daten und gibt das angereicherte Array zurück.
  183.      * @param array $iterationArray
  184.      * @param int $shopInstance
  185.      * @param string $language
  186.      * @return array
  187.      */
  188.     protected function getOrderDetails(array $iterationArrayint $shopInstance 1string $language 'DE') : array
  189.     {
  190.         foreach ($iterationArray['order-history-list']['order'] as $key => $orderElement)
  191.         {
  192.             $params = [
  193.                 'shop-instance' => $shopInstance,
  194.                 'sap-order-id'  => $orderElement['sap-order-id'],
  195.                 'language'      => $language
  196.             ];
  197.             $buildRequestHelper = new BuildRequestHelper($params'details'$this->errorHandler);
  198.             /**
  199.              * @var string $request
  200.              */
  201.             $request $this->requestHandler->buildRequest($buildRequestHelper, (string)get_class($this));
  202.             if ($request !== '') {
  203.                 /**
  204.                  * @var string $detailResult
  205.                  */
  206.                 $detailResult $this->requestHandler->sendRequest($this->host$this->portself::PATH_DETAILS$request);
  207.             } else {
  208.                 $this->error $this->errorHandler->error($this->errorHandler::UNKNOWN_REQUESTget_class($this), 'Fehler im Aufbau des Request');
  209.                 $this->errorHandler->writeErrorLog($this->error);
  210.                 continue;
  211.             }
  212.             $detailArray RequestHandler::parseResult($detailResult);
  213.             if ($detailArray['head']['status'] === 'NOK' || count($detailArray) === 0) {
  214.                 continue;
  215.             }
  216.             /**
  217.              * Holen der Dokumente zu den einzelnen Orders
  218.              * @todo Deaktiviert, da SAP noch keine Dokumente liefern kann. Muss noch getestet werden, sobald SAP Dokumente liefern kan.
  219.              */
  220.             if (array_key_exists('sap-order-id'$detailArray['document-list']['document'])) {
  221.                 $detailIterationArray['head'] = $detailArray['head'];
  222.                 $detailIterationArray['document-list']['document'][0] = $detailArray['document-list']['document'];
  223.             } else {
  224.                 $detailIterationArray $detailArray;
  225.             }
  226.             /**
  227.              * @todo Die Foreach war für  um nur Rechunungen heraus zu filtern. Hier sollte es konfigurierbar gemacht werden.
  228.              */
  229.             foreach ($detailIterationArray['document-list']['document'] as $key2 => $documentElement)
  230.             {
  231.                 if (($documentElement['document-type-code'] != 'M') && ($documentElement['document-type-code'] != 'C'))
  232.                 {
  233.                     unset($detailIterationArray['document-list']['document'][$key2]);
  234.                 }
  235.             }
  236. //             $detailCompleteArray = $this->getOrderDocuments($detailIterationArray);
  237.             $iterationArray['order-history-list']['order'][$key]['document-list'] = $detailIterationArray['document-list'];
  238.             $iterationArray['order-history-list']['order'][$key]['head'] = $detailArray['head'];
  239.             if ($iterationArray['order-history-list']['order'][$key]['customer-order-id'] === []) {
  240.                 $iterationArray['order-history-list']['order'][$key]['customer-order-id'] = 'keine Kunden-Bestellnummer';
  241.             }
  242.         }
  243.         return $iterationArray;
  244.     }
  245.     /**
  246.      * Liest die OrderDetails aus und die hinterlegten Dokumente
  247.      * füllte das Details-Array mit den Dokumenten und gibt das angereicherte Array zurück.
  248.      * @param array $detailsArray
  249.      * @param int$shopInstance
  250.      * @return array
  251.      * @todo In Controller auslagern, um die document.php im Plugin zu halten
  252.      */
  253.     public function getOrderDocuments(array $detailsArrayint $shopInstance 1)
  254.     {
  255.         foreach ($detailsArray['document-list']['document'] as $key => $documentElement)
  256.         {
  257.             /**
  258.              * @todo
  259.              * Hier muss noch wegen der Dokumententypen angepasst werden.
  260.              */
  261. //             if ($documentElement['document-type-code'] == 'M') {
  262.             if (true) {
  263.                 $params = [
  264.                     'shop-instance' => $shopInstance,
  265.                     'customer' => $this->customerNumber,
  266.                     'document-number' => $documentElement['document-number'],
  267.                     'document-type-code' => $documentElement['document-type-code']
  268.                 ];
  269.                 $buildRequestHelper = new BuildRequestHelper($params'documents'$this->errorHandler);
  270.                 /**
  271.                  * @var string $request
  272.                  */
  273.                 $request $this->requestHandler->buildRequest($buildRequestHelper, (string)get_class($this));
  274.                 if ($request !== '') {
  275.                     /**
  276.                      * @var string $documentResult
  277.                      */
  278.                     $documentResult $this->requestHandler->sendRequest($this->host$this->portself::PATH_DOCUMENTS$request);
  279.                 } else {
  280.                     $this->error $this->errorHandler->error($this->errorHandler::UNKNOWN_REQUESTget_class($this), 'Fehler im Aufbau des Request');
  281.                     $this->errorHandler->writeErrorLog($this->error);
  282.                     continue;
  283.                 }
  284.                 $documentArray RequestHandler::parseResult($documentResult);
  285.                 if ($documentArray['head']['status'] === 'NOK' || count($documentArray) === 0) {
  286.                     continue;
  287.                 }
  288.                 if (array_key_exists('data'$documentArray['head'])) {
  289.                     $documentIterationArray['data'] = $documentArray['head']['data'];
  290.                 } else {
  291.                     $documentIterationArray['data'] = $documentArray['head']['status'];
  292.                 }
  293.                 $detailsArray['document-list']['document'][$key]['document-data'] = $documentIterationArray['data'];
  294.             /**
  295.              * @todo Hier werden alle nicht Rechnungen entfernt. Muss raus genommen werden, wenn andere Dokumente gehen
  296.              */
  297.             } else {
  298.                 unset($detailsArray['document-list']['document'][$key]);
  299.             }
  300.         }
  301.         return $detailsArray;
  302.     }
  303.     /**
  304.      * Bereitet mit dem Requesthandler die Request auf und holt die Daten vom iMan
  305.      *
  306.      * @param string|null $fromDate
  307.      * @param string|null $toDate
  308.      * @param int $shopInstance
  309.      * @param string $language
  310.      * @return array
  311.      */
  312.     protected function getOrderHistory(string $fromDate null,
  313.                                        string $toDate null,
  314.                                        int $shopInstance 1,
  315.                                        string $language 'DE') : array
  316.     {
  317.         if ($fromDate !== null && $toDate !== null) {
  318.             $this->checkDateRange($fromDate$toDate);
  319.         }
  320.         if ($fromDate === null) {
  321.             $fromDate '2021-01-01';
  322.         }
  323.         if ($toDate === null) {
  324.             $toDate = (new DateTime())->format('Y-m-d');
  325.         }
  326.         $this->fromDate $fromDate;
  327.         $this->toDate $toDate;
  328.         $params = [
  329.             'shop-instance' => $shopInstance,
  330.             'customer'      => $this->customerNumber,
  331.             'date-from'     => $this->fromDate,
  332.             'date-to'       => $this->toDate,
  333.             'language'      => $language
  334.         ];
  335.         $buildRequestHelper = new BuildRequestHelper($params'headlist'$this->errorHandler);
  336.         /**
  337.          * @var string $request
  338.          */
  339.         $request $this->requestHandler->buildRequest($buildRequestHelper, (string)get_class($this));
  340.         if ($request !== '') {
  341.             /**
  342.              * @var string $result
  343.              */
  344.             $result $this->requestHandler->sendRequest($this->host$this->portself::PATH_HEADLIST$request);
  345.             $this->error $this->errorHandler->error($this->errorHandler::UNKNOWN_REQUESTget_class($this), 'Result: ' print_r($this->resulttrue));
  346.             $this->errorHandler->writeErrorLog($this->error);
  347.         } else {
  348.             /**
  349.              * @todo Fehlerbehandlung
  350.              */
  351.             Return array();
  352.         }
  353.         return $this->requestHandler->parseResult($result);
  354.     }
  355.     /**
  356.      * Prüft die übergebenen Daten auf ihren Wert und bei vertauschte Angabe werden diese ausgewechselt.
  357.      *
  358.      * @param string|null $fromDate
  359.      * @param string|null $toDate
  360.      */
  361.     protected function checkDateRange(string &$fromDatestring &$toDate) : void
  362.     {
  363.         try {
  364.             $startDate = new DateTime($fromDate);
  365.             $endDate = new DateTime($toDate);
  366.         } catch (Exception $e) {
  367.             $this->error $this->errorHandler->error($this->errorHandler::GENERAL_ERRORget_class($this), 'Eine Datumsangabe entspricht nicht dem vorgegeben Format. - ' $e->getCode() . ' - ' $e->getMessage());
  368.             $this->errorHandler->writeErrorLog($this->error);
  369.             $fromDate '';
  370.             $toDate '';
  371.         }
  372.         if ($endDate $startDate)
  373.         {
  374.             $fromDate   $endDate->format('Y-m-d');
  375.             $toDate     $startDate->format('Y-m-d');
  376.         }
  377.     }
  378.     /**
  379.      * Array des Response wird in ein einheitliches Format gebracht zur Vereinfachung der weiteren Handhabung
  380.      * @param array $orderHistory
  381.      * @return array
  382.      */
  383.     protected function formatOrderHistory(array $orderHistory) : array
  384.     {
  385.         if (array_key_exists('sap-order-id'$orderHistory['order-history-list']['order'])) {
  386.             $iterationArray['head'] = $orderHistory['head'];
  387.             $iterationArray['order-history-list']['order'][0] = $orderHistory['order-history-list']['order'];
  388.         } else {
  389.             $iterationArray $orderHistory;
  390.         }
  391.         if (empty($iterationArray['head']['customer']) || is_array($iterationArray['head']['customer'])) {
  392.             $iterationArray['head']['customer'] = $this->customerNumber;
  393.         }
  394.         return $iterationArray;
  395.     }
  396.     /**
  397.      * @return bool
  398.      */
  399.     private function checkConfig() : bool
  400.     {
  401.         if ($this->foundationService->getConfigStatus()) {
  402.             $this->host $this->foundationService->getHost();
  403.             $this->port $this->foundationService->getPort();
  404.             return true;
  405.         }
  406.         $this->error $this->errorHandler->error($this->errorHandler::CONFIG_NOT_VALIDget_class($this), 'Konnte die Konfiguration nicht ermitteln');
  407.         $this->errorHandler->writeErrorLog($this->error);
  408.         return false;
  409.     }
  410. }