From: fomichev Date: Mon, 17 Mar 2025 08:22:45 +0000 (+0300) Subject: Сохранение данных X-Git-Url: https://gitweb.erp-flowers.ru/?a=commitdiff_plain;h=b384230191e04540e5a8e61224336f2453f03d56;p=erp24_rep%2Fyii-erp24%2F.git Сохранение данных --- diff --git a/erp24/api2/controllers/YandexMarketController.php b/erp24/api2/controllers/YandexMarketController.php index 0facd943..d408d45b 100644 --- a/erp24/api2/controllers/YandexMarketController.php +++ b/erp24/api2/controllers/YandexMarketController.php @@ -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); diff --git a/erp24/commands/MarketplaceController.php b/erp24/commands/MarketplaceController.php index 588c5105..6dd62ca2 100644 --- a/erp24/commands/MarketplaceController.php +++ b/erp24/commands/MarketplaceController.php @@ -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 diff --git a/erp24/services/MarketplaceService.php b/erp24/services/MarketplaceService.php index f7df5dde..92ac6d84 100644 --- a/erp24/services/MarketplaceService.php +++ b/erp24/services/MarketplaceService.php @@ -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(); + } + } + + }