]> gitweb.erp-flowers.ru Git - erp24_rep/yii-erp24/.git/commitdiff
Отладка
authorfomichev <vladimir.fomichev@erp-flowers.ru>
Wed, 19 Mar 2025 15:21:27 +0000 (18:21 +0300)
committerfomichev <vladimir.fomichev@erp-flowers.ru>
Wed, 19 Mar 2025 15:21:27 +0000 (18:21 +0300)
erp24/commands/MarketplaceController.php
erp24/media/controllers/FlowwowController.php
erp24/services/MarketplaceService.php

index 6dd62ca260942a341c6bf00fba725c650f789da5..56c90b7e20d2e4da4e098e79d9d078f98d85ec4e 100644 (file)
@@ -73,10 +73,10 @@ class MarketplaceController extends Controller
 
     public function actionGetFlowwowOrders()
     {
-        $orders = MarketplaceService::getFlowwowOrdersFromMail();
-        Yii::warning("Заказы " . json_encode($orders, JSON_UNESCAPED_UNICODE));
+        $messages = MarketplaceService::getFlowwowOrdersFromMail();
+        Yii::warning("Заказы " . json_encode($messages, JSON_UNESCAPED_UNICODE));
 
-        $count = MarketplaceService::processFlowwowOrders($orders);
+        $count = MarketplaceService::processMessages($messages);
 
         $this->stdout(
             "Удалось сохранить {$count} новых заказов из почты.\n",
index 49539eb745b5403896148fd6a4df646af52d1ac1..1f26ee4e5c4295c650a50509a5b2ae155f9c0920 100644 (file)
@@ -2,6 +2,7 @@
 
 namespace app\controllers;
 
+
 use voku\helper\HtmlDomParser;
 use voku\helper\SimpleHtmlDom;
 use Yii;
@@ -112,7 +113,24 @@ class FlowwowController extends Controller
                                 }
                             }
                         }
-
+                        $htmlMessage = html_entity_decode($htmlMessage, ENT_QUOTES, 'UTF-8');
+                       // $htmlMessage = str_replace('\"', '"', $htmlMessage);
+                       // $htmlMessage = str_replace(['\r', '\n', '\r\n'], '', $htmlMessage);
+                        $htmlMessage = preg_replace('/\s+/', ' ', $htmlMessage);
+                       // $htmlMessage = stripslashes($htmlMessage);
+                       return $htmlMessage;
+                        $doc = new HtmlDomParser($htmlMessage);
+                        $orderNumber = '';
+                        $main = $doc->findOneOrFalse("body");
+
+                        if ($main !== false) {
+                            $orderTitleNode = $main->findOne("h1");
+
+                            if ($orderTitleNode && preg_match('/№(\d+)/', $orderTitleNode->innertext, $matches)) {
+                                $orderNumber = (int)$matches[1];
+                            }
+                        }
+                        return $orderNumber;
                         $messages[] = [
                             'subject' => $subject,
                             'subject_index' => $subjectIndex,
@@ -326,12 +344,12 @@ class FlowwowController extends Controller
         set_time_limit(300);
         Yii::$app->response->format = Response::FORMAT_JSON;
 
-        $html = file_get_contents('./runtime/file.html');
-
+        $html = '';
+        //$html = quoted_printable_decode($html);
         if (!empty($html)) {
-            $html = html_entity_decode($html, ENT_QUOTES | ENT_HTML5, 'UTF-8');
+            $html = html_entity_decode($html, ENT_COMPAT, 'UTF-8');
 
-            $doc = new HtmlDomParser($html);
+         $doc = new HtmlDomParser($html);
 
             $main = $doc->findOneOrFalse("body");
 
@@ -351,6 +369,8 @@ class FlowwowController extends Controller
 
 
             $deliveryBlock = $main->findOne('p:contains("Доставить")');
+
+
             $pickupBlock = $main->findOne('p:contains("Самовывоз")');
 
             if ($deliveryBlock && $deliveryBlock->nextNonWhitespaceSibling()) {
@@ -411,6 +431,7 @@ class FlowwowController extends Controller
 
 
             $itemsBlock = $main->findOneOrFalse('h2:contains("Детали заказа")') ? $main->findOne('h2:contains("Детали заказа")') : $main->findOneOrFalse('p:contains("Детали заказа")');
+
             if ($itemsBlock) {
                 $itemsTable = $itemsBlock->parentNode()->find('table', 2);
 
index 8b3dbfb7593dda68bde920b6eafc155548733237..aededd7b06488491dcb8df3a359ac0ac4a809fd0 100644 (file)
@@ -77,12 +77,19 @@ class MarketplaceService
         ]
     ];
 
+    const SUBJECT_NEW = '/^Новый_оплаченный_заказ$/';
+    const SUBJECT_APPROVED = '/^Заказ_№\d+_принят!$/';
+    const SUBJECT_CANCELLED = '/^Заказ_№\d+_отменён$/';
+    const SUBJECT_CHANGED = '/^Изменения_в_заказе_№\d+$/';
+    const SUBJECT_DELIVERED = '/^Flowwow. Заказ_выполнен._Напишите_отзыв_о_клиенте$/';
+
+
     const SUBJECT_INDEX = [
-        '/^Новый_оплаченный_заказ$/' => 1,
-        '/^Заказ_№\d+_принят!$/' => 2,
-        '/^Заказ_№\d+_отменён$/' => 3,
-        '/^Изменения_в_заказе_№\d+$/' => 4,
-        '/^Flowwow. Заказ_выполнен._Напишите_отзыв_о_клиенте$/' => 5,
+        self::SUBJECT_NEW => 1,
+        self::SUBJECT_APPROVED => 2,
+        self::SUBJECT_CHANGED => 3,
+        self::SUBJECT_CANCELLED => 4,
+        self::SUBJECT_DELIVERED => 5,
     ];
 
     public static function infoForMarketplace(int $marketId) {
@@ -1342,6 +1349,10 @@ class MarketplaceService
         $username = 'Zakaz-bazacvetov24@yandex.ru';
         $password = 'jyxnwwwvgpwhzbdu';
 
+        /*$hostname = '{imap.yandex.ru:993/imap/ssl}INBOX';
+        $username = 'flow@bazacvetov24.ru';
+        $password = 'ctqamxqeshgxwsgn';*/
+
         // Устанавливаем таймауты IMAP
         imap_timeout(IMAP_OPENTIMEOUT, 120);
         imap_timeout(IMAP_READTIMEOUT, 120);
@@ -1356,15 +1367,16 @@ class MarketplaceService
         //$inboxInfo = imap_mailboxmsginfo($inbox);
         //Yii::warning(' Состояние ящика: ' . print_r($inboxInfo, true), __METHOD__);
         $emails = imap_search($inbox, 'ON "14-Feb-2025" FROM "info@flowwow.com" ');
+        //$emails = imap_search($inbox, 'ON "18-Mar-2025" FROM "info@flowwow.com" ');
 
         $messages = [];
 
         $subjectPatterns = [
-            '/^Новый_оплаченный_заказ$/',
-            '/^Заказ_№\d+_принят!$/',
-            '/^Заказ_№\d+_отменён$/',
-            '/^Изменения_в_заказе_№\d+$/',
-            '/^Flowwow. Заказ_выполнен._Напишите_отзыв_о_клиенте$/',
+            self::SUBJECT_NEW,
+            self::SUBJECT_APPROVED,
+            self::SUBJECT_CHANGED,
+            self::SUBJECT_CANCELLED,
+            self::SUBJECT_DELIVERED,
         ];
 
         if ($emails) {
@@ -1383,7 +1395,7 @@ class MarketplaceService
                             foreach ($structure->parts as $partNum => $part) {
                                 if ($part->subtype == 'HTML') {
                                     $htmlMessage = imap_fetchbody($inbox, $email_number, $partNum + 1);
-                                    $htmlMessage = quoted_printable_decode($htmlMessage);
+                                   // $htmlMessage = quoted_printable_decode($htmlMessage);
                                     break;
                                 }
                             }
@@ -1413,42 +1425,52 @@ class MarketplaceService
         $count = 0;
         if ($messages) {
             foreach ($messages as $message) {
-                if ($message['subject_index'] == 1) {
-                    $order = self::getOrdersDataFromMessage($message);
-                    $count += self::processFlowwowOrders($order);
-
-                } elseif ($message['subject_index'] == 2) {
-                    $order = self::getOrdersDataFromMessage($message);
-                    $count += self::processFlowwowOrders($order);
-
-                } elseif ($message['subject_index'] == 3) {
-                    $order = self::getOrdersDataFromMessage($message);
-
-                } elseif ($message['subject_index'] == 4) {
-                    $order = self::getOrdersDataFromMessage($message);
-
-                } elseif ($message['subject_index'] == 5) {
-                    $order = self::getOrdersDataFromMessage($message);
-
+                $store = MarketplaceStore::getWarehouseGuidByAccountEmail($message['to']) ?? 206008;
+               // Yii::warning('Message' . json_encode($message, JSON_UNESCAPED_UNICODE));
+                $order = self::getOrdersDataFromMessage($message);
+                Yii::warning('Order' . json_encode($order, JSON_UNESCAPED_UNICODE));
+                if ($message['subject_index'] == self::SUBJECT_INDEX[self::SUBJECT_NEW]) {
+                    $statusCode = 'PROCESSING';
+                    $substatusCode = 'STARTED';
+                } elseif ($message['subject_index'] == self::SUBJECT_INDEX[self::SUBJECT_APPROVED]) {
+                    $statusCode = 'PROCESSING';
+                    $substatusCode = 'APPROVED';
+                } elseif ($message['subject_index'] == self::SUBJECT_INDEX[self::SUBJECT_CANCELLED]) {
+                    $statusCode = 'CANCELLED';
+                    $substatusCode = 'USER_CHANGED_MIND';
+                } elseif ($message['subject_index'] == self::SUBJECT_INDEX[self::SUBJECT_CHANGED]) {
+                    $statusCode = 'PROCESSING';
+                    $substatusCode = 'CHANGED';
+                } elseif ($message['subject_index'] == self::SUBJECT_INDEX[self::SUBJECT_DELIVERED]) {
+                    $statusCode = 'DELIVERED';
+                    $substatusCode = 'DELIVERY_SERVICE_DELIVERED';
+                } else {
+                    $statusCode = 'PROCESSING';
+                    $substatusCode = 'STARTED';
                 }
-
-
-
+                $count += self::processFlowwowOrders($order, $store, $statusCode, $substatusCode, $message['subject_index']);
             }
         }
         return $count;
     }
 
-    
     public static function getOrdersDataFromMessage($message) {
         $html = $message['body'];
+       // Yii::warning('Message body' . $html);
         $orderDetails = null;
         $order = null;
         if (!empty($html)) {
-            $html = html_entity_decode($html, ENT_QUOTES | ENT_HTML5, 'UTF-8');
+            $html = quoted_printable_decode($html);
+            $html = preg_replace('/\s+/', ' ', $html);
+            // Декодируем HTML-сущности
+            $html = html_entity_decode($html, ENT_COMPAT, 'UTF-8');
 
-            $doc = new HtmlDomParser($html);
+            // Удаляем лишние пробелы и переносы строк
+           // $html = preg_replace('/\s+/', ' ', $html);
+           // Yii::warning('Message body' . $html);
 
+            $doc = new HtmlDomParser($html);
+            $orderNumber = '';
             $main = $doc->findOneOrFalse("body");
 
             if ($main !== false) {
@@ -1459,6 +1481,7 @@ class MarketplaceService
                 }
             }
             $orderDetails['number'] = $orderNumber;
+            $orderDetails['date'] = $message['date'];
             $deliveryText = '';
             $commentText = '';
             $clientText = '';
@@ -1523,10 +1546,19 @@ class MarketplaceService
                 $orderDetails['recipient'] = $recipientText;
             }
 
+            $itemsBlock = false;
+            if ($main->findOneOrFalse('table h2:contains("Детали заказа")') != false) {
+                $itemsBlock = $main->findOneOrFalse('table h2:contains("Детали заказа")');
+                Yii::warning('Детали заказа 1: ' . json_encode($itemsBlock->innerText(), JSON_UNESCAPED_UNICODE), __METHOD__);
+            } elseif ($main->findOneOrFalse('table p:contains("Детали заказа")') != false) {
+                $itemsBlock = $main->findOneOrFalse('table p:contains("Детали заказа")');
+                Yii::warning('Детали заказа 2: ' . json_encode($itemsBlock->innerText(), JSON_UNESCAPED_UNICODE), __METHOD__);
+            }
 
-            $itemsBlock = $main->findOneOrFalse('h2:contains("Детали заказа")') ? $main->findOne('h2:contains("Детали заказа")') : $main->findOneOrFalse('p:contains("Детали заказа")');
             if ($itemsBlock) {
-                $itemsTable = $itemsBlock->parentNode()->find('table', 2);
+                Yii::warning('Детали заказа 3: ' . json_encode($itemsBlock->parentNode()->innerText(), JSON_UNESCAPED_UNICODE), __METHOD__);
+               // $itemsTable = $itemsBlock->parentNode()->find('table', 2);
+                $itemsTable = $itemsBlock->parentNode();
 
                 $itemsRows = $itemsTable->find('tr');
                 foreach ($itemsRows as $itemsRow) {
@@ -1537,31 +1569,26 @@ class MarketplaceService
                         'price' => '',
                     ];
 
-
                     // Извлекаем название и количество из второго <td>
                     $tds = $itemsRow->find('td');
                     if (count($tds) >= 2) {
                         $itemData['name'] = trim(str_replace("\u{00A0}", ' ', strip_tags(preg_replace('/\s+/', ' ',$tds[1]->find('p', 0)->innerText()))));
                         $itemData['count'] = trim(str_replace(["\u{00A0}", 'шт.'], '', strip_tags(preg_replace('/\s+/', '', $tds[1]->find('p', 1)->innerText()))));
                     }
-
                     // Извлекаем цену из третьего <td>
                     if (count($tds) >= 3) {
                         $itemData['price'] = (float)trim(str_replace(["\u{00A0}", '₽' , ' '], '', strip_tags(preg_replace('/\s+/', ' ', $tds[2]->find('p', 0)->innerText()))));
                     }
-
-
                     // Добавляем данные в массив
                     $orderItems[] = $itemData;
                 }
                 $totalSum = 0;
-                $sumBlock = $itemsBlock->parentNode()->find('table', 3);
+                $sumBlock = $itemsBlock->parentNode()->nextNonWhitespaceSibling();
                 $sumRow = $sumBlock->find('tr');
 
                 $sumTds = $sumRow->find('td');
-                if (count($sumTds) >= 2) {
+                if ($sumTds && count($sumTds) >= 2) {
                     $totalSum = (float)trim(str_replace(["\u{00A0}", '₽' , ' '], '', strip_tags(preg_replace('/\s+/', ' ', $sumTds[1]->innerText()))));
-
                 }
                 $orderDetails['items'] = $orderItems;
                 $orderDetails['totalSum'] =  $totalSum;
@@ -1574,9 +1601,7 @@ class MarketplaceService
     }
 
 
-
-
-    public static function processFlowwowOrders(array $allOrders)
+    public static function processFlowwowOrders($order, $store, $statusCode, $substatusCode, $index)
     {
         $statuses = MarketplaceOrderStatusTypes::find()
             ->select(['id', 'code'])
@@ -1586,39 +1611,62 @@ class MarketplaceService
         $statuses = ArrayHelper::map($statuses, 'code', 'id');
         $statusCodes = array_unique(array_keys($statuses));
         $newOrdersCount = 0;
-        $campaignId = 206008;
+        $campaignId = $store;
 
-        foreach ($allOrders as $number => $order) {
-            $statusCode = 'PROCESS';
-            $substatusCode = 'STARTED';
+        $orderNumber = key($order);
+        $orderDetails = reset($order);
 
-            $statusId = self::getOrCreateStatus($statusCode, $statuses, $statusCodes);
-            $substatusId = self::getOrCreateStatus($substatusCode, $statuses, $statusCodes);
-
-            $marketplaceOrder = MarketplaceOrders::find()
-                ->where(['marketplace_order_id' => (string)$number])
-                ->one();
-
-            if (!$marketplaceOrder) {
-                Yii::warning("Номер " . json_encode($number, JSON_UNESCAPED_UNICODE));
-                Yii::warning("Заказ " . json_encode($order, JSON_UNESCAPED_UNICODE));
+        $statusId = self::getOrCreateStatus($statusCode, $statuses, $statusCodes);
+        $substatusId = self::getOrCreateStatus($substatusCode, $statuses, $statusCodes);
+        Yii::warning("Статус " . $statusId);
+        Yii::warning("Субстатус " . $substatusId);
+        $marketplaceOrder = MarketplaceOrders::find()
+            ->where(['marketplace_order_id' => (string)$orderNumber])
+            ->one();
 
-                $marketplaceOrder = self::createOrder($order, $campaignId, $statusId, $substatusId);
+        if (!$marketplaceOrder) {
+            Yii::warning("Номер " . json_encode($orderNumber, JSON_UNESCAPED_UNICODE));
+            Yii::warning("Заказ " . json_encode($orderDetails, JSON_UNESCAPED_UNICODE));
+            if ($index == self::SUBJECT_INDEX[self::SUBJECT_NEW]) {
+                $marketplaceOrder = self::createOrder($orderDetails, $campaignId, $statusId, $substatusId);
                 if ($marketplaceOrder->save()) {
-                    $newOrdersCount += 1;
-                    self::createStatusHistory($marketplaceOrder->id, $statusId, $substatusId);
-                    self::saveOrderItems($order, $marketplaceOrder->id, $marketplaceOrder->warehouse_guid);
-
+                     $newOrdersCount += 1;
+                     self::createOrUpdateStatusHistory($marketplaceOrder->id, $statusId, $substatusId);
+                     self::saveOrderItems($orderDetails, $marketplaceOrder->id, $marketplaceOrder->warehouse_guid);
                 } else {
-                    Yii::error(
-                        'Ошибка сохранения заказа: ' . json_encode(
-                            $marketplaceOrder->getErrors(),
-                            JSON_UNESCAPED_UNICODE
-                        )
-                    );
+                     Yii::error(
+                         'Ошибка сохранения заказа: ' . json_encode(
+                             $marketplaceOrder->getErrors(),
+                             JSON_UNESCAPED_UNICODE
+                         )
+                     );
+                }
+            }
+        } else {
+            if ($index == self::SUBJECT_APPROVED || $index == self::SUBJECT_CHANGED) {
+                //заказ принят или изменен
+                $marketplaceOrder->status_id = $statusId;
+                $marketplaceOrder->substatus_id = $substatusId;
+                if ($marketplaceOrder->raw_data !== json_encode($orderDetails, JSON_UNESCAPED_UNICODE)) {
+                    $marketplaceOrder->raw_data = json_encode($orderDetails, JSON_UNESCAPED_UNICODE);
+                }
+                if ($marketplaceOrder->save()) {
+                    self::createOrUpdateStatusHistory($marketplaceOrder->id, $statusId, $substatusId);
+                } else {
+                    Yii::error('Не удалось обновить заказ' . json_encode($marketplaceOrder->getErrors(), JSON_UNESCAPED_UNICODE));
+                }
+            } else {
+                // отмена или успешное выполнение
+                $marketplaceOrder->status_id = $statusId;
+                $marketplaceOrder->substatus_id = $substatusId;
+                if ($marketplaceOrder->save()) {
+                    self::createOrUpdateStatusHistory($marketplaceOrder->id, $statusId, $substatusId);
+                } else {
+                    Yii::error('Не удалось обновить заказ' . json_encode($marketplaceOrder->getErrors(), JSON_UNESCAPED_UNICODE));
                 }
             }
         }
+
         return $newOrdersCount;
     }
 
@@ -1669,18 +1717,56 @@ class MarketplaceService
         return $marketplaceOrder;
     }
 
-    private static function createStatusHistory($orderId, $statusId, $substatusId)
+    private static function createOrUpdateStatusHistory($orderId, $statusId, $substatusId)
     {
-        $history = new MarketplaceOrderStatusHistory();
-        $history->order_id = $orderId;
-        $history->status_id = $statusId;
-        $history->substatus_id = $substatusId;
-        $history->active = 1;
-        $history->initiator = "ERP";
-        $history->date_from = date('Y-m-d H:i:s');
-        $history->date_end = '2100-01-01 00:00:00';
-        $history->save();
+        $statusHistoryRecord = MarketplaceOrderStatusHistory::find()->where(['order_id' => $orderId])->andWhere(['active' => 1])->one();
+        if (
+            $statusHistoryRecord &&
+            ($statusHistoryRecord->status_id !== (int)$statusId ||
+                $statusHistoryRecord->substatus_id !== (int)$substatusId)
+        ) {
+            $statusHistoryRecord->active = 0;
+            $statusHistoryRecord->date_end = date('Y-m-d H:i:s');
+            $statusHistoryRecord->save();
+
+            $newStatusHistoryRecord = new MarketplaceOrderStatusHistory();
+            $newStatusHistoryRecord->order_id = $orderId;
+            $newStatusHistoryRecord->status_id = (int)$statusId;
+            $newStatusHistoryRecord->substatus_id = (int)$substatusId;
+            $newStatusHistoryRecord->active = 1;
+            $newStatusHistoryRecord->initiator = "ERP";
+            $newStatusHistoryRecord->date_from = date('Y-m-d H:i:s');
+            $newStatusHistoryRecord->date_end = date('Y-m-d H:i:s', strtotime("2100-01-01"));
+            if (!$newStatusHistoryRecord->save()) {
+                Yii::error(
+                    'Ошибка сохранения новой истории статуса: ' . json_encode(
+                        $newStatusHistoryRecord->getErrors(),
+                        JSON_UNESCAPED_UNICODE
+                    )
+                );
+            }
+        } else {
+            $history = new MarketplaceOrderStatusHistory();
+            $history->order_id = $orderId;
+            $history->status_id = $statusId;
+            $history->substatus_id = $substatusId;
+            $history->active = 1;
+            $history->initiator = "ERP";
+            $history->date_from = date('Y-m-d H:i:s');
+            $history->date_end = '2100-01-01 00:00:00';
+
+            if (!$history->save()) {
+                Yii::error(
+                    'Ошибка сохранения новой истории статуса: ' . json_encode(
+                        $history->getErrors(),
+                        JSON_UNESCAPED_UNICODE
+                    )
+                );
+            }
+        }
     }
+    
+
     private static function saveOrderItems($order, $orderId, $warehouseGuid)
     {
         $items = $order['items'];