]> gitweb.erp-flowers.ru Git - erp24_rep/yii-erp24/.git/commitdiff
Сохранение данных
authorfomichev <vladimir.fomichev@erp-flowers.ru>
Mon, 17 Mar 2025 08:22:45 +0000 (11:22 +0300)
committerfomichev <vladimir.fomichev@erp-flowers.ru>
Mon, 17 Mar 2025 08:22:45 +0000 (11:22 +0300)
erp24/api2/controllers/YandexMarketController.php
erp24/commands/MarketplaceController.php
erp24/services/MarketplaceService.php

index 0facd9430f0a2c938c4615d97613e79be93483e2..d408d45bbb892edf7ce74c90955fd1a6275f7d34 100644 (file)
@@ -208,7 +208,7 @@ class YandexMarketController extends Controller
             ->where(['warehouse_id' => 2])
             ->column();
 
-        $allOrders = MarketplaceService::fetchOrders($campaignIds, $status, $substatus, $fromDate, $toDate);
+        $allOrders = MarketplaceService::fetchOrders($campaignIds, $fromDate, $toDate, $status, $substatus);
 
         $result = MarketplaceService::processOrders($allOrders);
 
index 588c51051a222b6fb8cd2f4723c2f323b74d6f27..6dd62ca260942a341c6bf00fba725c650f789da5 100644 (file)
@@ -4,16 +4,20 @@ namespace yii_app\commands;
 
 use Yii;
 use yii\console\Controller;
+use yii\console\ExitCode;
 use yii\helpers\ArrayHelper;
+use yii\helpers\BaseConsole;
 use yii_app\records\MarketplaceStore;
 use yii_app\records\MatrixErp;
 use yii_app\records\Products1c;
 use yii_app\records\ProductsClass;
+use yii_app\records\UsersMessageManagement;
 use yii_app\services\MarketplaceService;
 use OpenAPI\Client\Configuration;
 use OpenAPI\Client\Api;
 use OpenAPI\Client\Model;
 use GuzzleHttp;
+use yii_app\services\WhatsAppService;
 
 class MarketplaceController extends Controller
 {
@@ -66,4 +70,20 @@ class MarketplaceController extends Controller
 
         echo PHP_EOL . "end of the script" . PHP_EOL;
     }
+
+    public function actionGetFlowwowOrders()
+    {
+        $orders = MarketplaceService::getFlowwowOrdersFromMail();
+        Yii::warning("Заказы " . json_encode($orders, JSON_UNESCAPED_UNICODE));
+
+        $count = MarketplaceService::processFlowwowOrders($orders);
+
+        $this->stdout(
+            "Удалось сохранить {$count} новых заказов из почты.\n",
+            BaseConsole::FG_GREEN
+        );
+
+        return ExitCode::OK;
+    }
+
 }
\ No newline at end of file
index f7df5dded41cf35bbfda11b8db08a0ce801c5b8d..92ac6d847567b772498d8d9d13f1307bd300d426 100644 (file)
@@ -8,9 +8,11 @@ use OpenAPI\Client\Api\ReturnsApi;
 use OpenAPI\Client\ApiException;
 use OpenAPI\Client\Configuration;
 use OpenAPI\Client\Model\UpdateOrderStatusRequest;
+use voku\helper\HtmlDomParser;
 use Yii;
 use yii\helpers\ArrayHelper;
 use yii\helpers\Json;
+use yii\web\Response;
 use yii_app\helpers\DataHelper;
 use yii_app\helpers\File;
 use yii_app\records\Balances;
@@ -823,7 +825,7 @@ class MarketplaceService
      *
      * @return array Массив заказов, сгруппированных по кампании.
      */
-    public static function fetchOrders(array $campaignIds, $status = null, $substatus = null, $fromDate, $toDate)
+    public static function fetchOrders(array $campaignIds, $fromDate, $toDate, $status = null, $substatus = null)
     {
         $config = Configuration::getDefaultConfiguration()
             ->setApiKey('Api-Key', Yii::$app->params['YANDEX_MARKET_API_KEY']);
@@ -1324,4 +1326,246 @@ class MarketplaceService
         }
     }
 
+    public static function getFlowwowOrdersFromMail()
+    {
+        set_time_limit(300);
+
+        $hostname = '{imap.yandex.ru:993/imap/ssl}INBOX';
+        $username = 'Zakaz-bazacvetov24@yandex.ru';
+        $password = 'jyxnwwwvgpwhzbdu';
+
+        // Устанавливаем таймауты IMAP
+        imap_timeout(IMAP_OPENTIMEOUT, 120);
+        imap_timeout(IMAP_READTIMEOUT, 120);
+        imap_timeout(IMAP_WRITETIMEOUT, 120);
+        imap_timeout(IMAP_CLOSETIMEOUT, 120);
+
+        $inbox = imap_open($hostname, $username, $password);
+        if (!$inbox) {
+            Yii::error('Ошибка подключения: ' . imap_last_error(), __METHOD__);
+            return ['success' => false];
+        }
+        //$inboxInfo = imap_mailboxmsginfo($inbox);
+        //Yii::warning(' Состояние ящика: ' . print_r($inboxInfo, true), __METHOD__);
+        $emails = imap_search($inbox, 'ON "14-Feb-2025" FROM "info@flowwow.com" ');
+
+        $orders = [];
+        if ($emails) {
+            foreach ($emails as $email_number) {
+                $overview = imap_fetch_overview($inbox, $email_number, 0);
+
+                $structure = imap_fetchstructure($inbox, $email_number);
+                $htmlMessage = '';
+                $subject = mb_decode_mimeheader($overview[0]->subject);
+                $date = mb_decode_mimeheader($overview[0]->date);
+                $date = date('Y-m-d H:i:s', strtotime($date));
+
+                if ($subject == 'Новый_оплаченный_заказ') {
+                    if (isset($structure->parts) && count($structure->parts)) {
+                        foreach ($structure->parts as $partNum => $part) {
+                            if ($part->subtype == 'HTML') {
+                                $htmlMessage = imap_fetchbody($inbox, $email_number, $partNum + 1);
+                                $htmlMessage = quoted_printable_decode($htmlMessage);
+                                break;
+                            }
+                        }
+                    }
+
+                    $orderNumber = null;
+                    $items = [];
+                    $totalSum = 0;
+
+                    try {
+                        if (!empty($htmlMessage)) {
+                            $htmlMessage = html_entity_decode($htmlMessage, ENT_QUOTES | ENT_HTML5, 'UTF-8');
+
+                            $doc = new HtmlDomParser($htmlMessage);
+
+                            $main = $doc->findOneOrFalse("body");
+
+                            if ($main !== false) {
+                                $orderTitleNode = $main->findOne("h1");
+
+                                if ($orderTitleNode && preg_match('/№(\d+)/', $orderTitleNode->innertext, $matches)) {
+                                    $orderNumber = (int)$matches[1];
+                                }
+
+                                // Извлечение товаров
+                                $elements = $main->findOne("p:contains('Детали заказа')")->parentNode();
+                                if ($elements) {
+                                    foreach ($elements->findMultiOrFalse("tr") as $itemRow) {
+                                        $img = $itemRow->findOne("td img");
+                                        $nameNode = $itemRow->findOne("td:nth-child(2) p");
+                                        if (!$img || !trim($nameNode->plaintext)) continue;
+
+                                        $name = trim($nameNode->plaintext);
+
+                                        // Количество
+                                        $countNode = $itemRow->findOne("td:nth-child(2) p[style*='#8C8C8C']");
+                                        $countText = $countNode ? $countNode->plaintext : '1';
+                                        $count = (int) filter_var($countText, FILTER_SANITIZE_NUMBER_INT);
+
+                                        // Сумма
+                                        $sumNode = $itemRow->findOne("td:nth-child(3) p");
+                                        $sumText = $sumNode ? $sumNode->plaintext : '0';
+                                        $sum = (float) str_replace([' ', '₽'], '', $sumText);
+
+                                        $items[] = ['name' => $name, 'count' => $count, 'sum' => $sum];
+                                    }
+                                }
+
+                                // Общая сумма
+                                $totalSumNodes = $elements->parentNode()->getElementsByTagName('table');
+                                $totalSumNode = ($totalSumNodes[3])->findOne("tr:contains('Итого оплачено')");
+                                if ($totalSumNode) {
+                                    $totalSum = (float) str_replace([' ', '₽'], '', trim(($totalSumNode->findMulti("td"))[1]->plaintext));
+                                }
+                            }
+                        }
+                    } catch (\Exception $e) {
+                        Yii::error('Ошибка: ' . json_encode($e->getMessage(), JSON_UNESCAPED_UNICODE) . " " .  $e->getLine() . " " .  json_encode($e->getTrace(), JSON_UNESCAPED_UNICODE), __METHOD__);
+                    }
+
+                    if ($orderNumber !== null) {
+                        $orders[$orderNumber] =  [
+                                'items'     => $items,
+                                'totalSum'  => $totalSum,
+                                'number'    => $orderNumber,
+                                'date'      => $date,
+                        ];
+                    }
+
+                    Yii::warning('HTML Тело письма: ' . json_encode($orders, JSON_UNESCAPED_UNICODE), __METHOD__);
+                    break;
+                }
+
+                // imap_setflag_full($inbox, $email_number, "\\Seen");
+            }
+        }
+        imap_close($inbox);
+        return $orders;
+    }
+
+
+    public static function processFlowwowOrders(array $allOrders)
+    {
+        $statuses = MarketplaceOrderStatusTypes::find()
+            ->select(['id', 'code'])
+            ->indexBy('code')
+            ->asArray()
+            ->all();
+        $statuses = ArrayHelper::map($statuses, 'code', 'id');
+        $statusCodes = array_unique(array_keys($statuses));
+        $newOrdersCount = 0;
+        $campaignId = 206008;
+
+        foreach ($allOrders as $number => $order) {
+            $statusCode = 'PROCESS';
+            $substatusCode = 'STARTED';
+
+            $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));
+
+                $marketplaceOrder = self::createOrder($order, $campaignId, $statusId, $substatusId);
+                if ($marketplaceOrder->save()) {
+                    $newOrdersCount++;
+                    self::createStatusHistory($marketplaceOrder->id, $statusId, $substatusId);
+                    self::saveOrderItems($order, $marketplaceOrder->id);
+
+                } else {
+                    Yii::error(
+                        'Ошибка сохранения заказа: ' . json_encode(
+                            $marketplaceOrder->getErrors(),
+                            JSON_UNESCAPED_UNICODE
+                        )
+                    );
+                }
+            }
+        }
+        return $newOrdersCount;
+    }
+
+    private static function getOrCreateStatus($statusCode, &$statuses, &$statusCodes)
+    {
+        if (!in_array($statusCode, $statusCodes)) {
+            $newStatus = new MarketplaceOrderStatusTypes();
+            $newStatus->code = $statusCode;
+            if ($newStatus->save()) {
+                $statuses[$statusCode] = $newStatus->id;
+                $statusCodes[] = $statusCode;
+            } else {
+                Yii::error(
+                    'Ошибка сохранения статуса: ' . json_encode($newStatus->getErrors(), JSON_UNESCAPED_UNICODE)
+                );
+                return null;
+            }
+        }
+        return $statuses[$statusCode];
+    }
+
+    private static function createOrder($order, $campaignId, $statusId, $substatusId)
+    {
+        $marketplaceOrder = new MarketplaceOrders();
+        $marketplaceOrder->marketplace_order_id = (string)$order['number'];
+        $marketplaceOrder->creation_date = date('Y-m-d H:i:s', strtotime($order['date']));
+        $marketplaceOrder->updated_at = date('Y-m-d H:i:s');
+        $marketplaceOrder->warehouse_guid = (string)$campaignId;
+        $marketplaceOrder->total = $order['totalSum'];
+        $marketplaceOrder->delivery_total = 0;
+        $marketplaceOrder->buyer_total_before_discount = $order['totalSum'];
+        $marketplaceOrder->tax_system = 'UNKNOWN';
+        $marketplaceOrder->payment_type = 'UNKNOWN';
+        $marketplaceOrder->payment_method = 'UNKNOWN';
+        $marketplaceOrder->cancel_requested = 0;
+        $marketplaceOrder->status_id = $statusId;
+        $marketplaceOrder->substatus_id = $substatusId;
+        $marketplaceOrder->raw_data = json_encode($order, JSON_UNESCAPED_UNICODE);
+        $marketplaceOrder->guid = DataHelper::createGuidMy('08');
+        $marketplaceOrder->fake = 0;
+        $marketplaceOrder->marketplace_name = 'ФлауВау';
+        $marketplaceOrder->marketplace_id = 1;
+
+
+        return $marketplaceOrder;
+    }
+
+    private static function createStatusHistory($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();
+    }
+    private static function saveOrderItems($order, $orderId)
+    {
+        $items = $order['items'];
+        if (!$items) {
+            return;
+        }
+        foreach ($items as $item) {
+            $orderItem = new MarketplaceOrderItems();
+            $orderItem->order_id = $orderId;
+            $orderItem->external_item_id = $order['number'];
+            $orderItem->offer_id = $item['name'];
+            $orderItem->price = $item['price'];
+            $orderItem->count = $item['count'];
+            $orderItem->save();
+        }
+    }
+
+
 }