<?php
+
namespace app\controllers;
use voku\helper\HtmlDomParser;
+use voku\helper\SimpleHtmlDom;
use Yii;
use yii\web\Controller;
use yii_app\services\MarketplaceService;
*/
public function actionFeed($id)
{
-
$balanceInfo = MarketplaceService::infoForMarketplace(1);
- $productsInfo = MarketplaceService::getProductsInfoForFeed($id,$balanceInfo);
+ $productsInfo = MarketplaceService::getProductsInfoForFeed($id, $balanceInfo);
- // $productsInfo = MarketplaceService::getAllProductsInfo($id);
+ // $productsInfo = MarketplaceService::getAllProductsInfo($id);
$xmlFeed = MarketplaceService::createXMLFeed($productsInfo);
return $xmlFeed;
}
- public function actionTest(){
-
- $products = MarketplaceService::infoForMarketplace(1);
+ public function actionTest()
+ {
+ $products = MarketplaceService::infoForMarketplace(1);
var_dump($products);
-
-
}
/**
$emails = imap_search($inbox, 'ON "14-Feb-2025" FROM "info@flowwow.com" ');
$count = $emails ? count($emails) : 0;
$orders = [];
+ $messages = [];
+
+ $subjectPatterns = [
+ '/^Новый_оплаченный_заказ$/',
+ '/^Заказ_№\d+_принят!$/',
+ // '/^Flowwow. Заказ_выполнен._Напишите_отзыв_о_клиенте$/',
+ // '/^Заказ_№\d+_отменён$/',
+ // '/^Изменения_в_заказе_№\d+$/',
+ ];
+
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;
+ $date = date('Y-m-d H:i:s', strtotime(mb_decode_mimeheader($overview[0]->date)));
+ Yii::warning('Тема: ' . json_encode($subject, JSON_UNESCAPED_UNICODE), __METHOD__);
+ foreach ($subjectPatterns as $pattern) {
+ if (preg_match($pattern, $subject)) {
+ Yii::warning('Тема прошла: ' . json_encode($subject, JSON_UNESCAPED_UNICODE), __METHOD__);
+ 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;
+ }
}
}
- }
- // Инициализация переменных для избежания undefined
- $orderNumber = null;
- $items = [];
- $totalSum = 0;
+ $messages[] = [
+ 'subject' => $subject,
+ 'date' => $date,
+ 'body' => $htmlMessage,
+ ];
+ break;
+ }
+ }
+ // imap_setflag_full($inbox, $email_number, "\\Seen");
+ }
+ }
+ imap_close($inbox);
+ if ($messages) {
+ foreach ($messages as $message) {
+ $html = $message['body'];
+ $orderNumber = null;
+ $items = [];
+ $totalSum = 0;
+ if (!empty($html)) {
+ $html = html_entity_decode($html, ENT_QUOTES | ENT_HTML5, 'UTF-8');
+
+ $doc = new HtmlDomParser($html);
+
+ $main = $doc->findOneOrFalse("body");
+ $body = new SimpleHtmlDom($main->getNode());
+ if ($main !== false) {
+ $orderTitleNode = $main->findOne("h1");
+
+ if ($orderTitleNode && preg_match('/№(\d+)/', $orderTitleNode->innertext, $matches)) {
+ $orderNumber = (int)$matches[1];
+ }
+ }
+ }
+ if (preg_match($subjectPatterns[0], $message['subject'])) { // Новый заказ
+ continue;
try {
- if (!empty($htmlMessage)) {
- $htmlMessage = html_entity_decode($htmlMessage, ENT_QUOTES | ENT_HTML5, 'UTF-8');
+ // Извлечение товаров
+ $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;
+ }
- $doc = new HtmlDomParser($htmlMessage);
+ $name = trim($nameNode->plaintext);
- $main = $doc->findOneOrFalse("body");
+ // Количество
+ $countNode = $itemRow->findOne("td:nth-child(2) p[style*='#8C8C8C']");
+ $countText = $countNode ? $countNode->plaintext : '1';
+ $count = (int)filter_var($countText, FILTER_SANITIZE_NUMBER_INT);
- if ($main !== false) {
- $orderTitleNode = $main->findOne("h1");
+ // Сумма
+ $sumNode = $itemRow->findOne("td:nth-child(3) p");
+ $sumText = $sumNode ? $sumNode->plaintext : '0';
+ $sum = (float)str_replace([' ', '₽'], '', $sumText);
- if ($orderTitleNode && preg_match('/№(\d+)/', $orderTitleNode->innertext, $matches)) {
- $orderNumber = (int)$matches[1];
- }
+ $items[] = ['name' => $name, 'count' => $count, 'sum' => $sum];
+ }
+ }
- // Извлечение товаров
- $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;
+ // Общая сумма
+ $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__
+ );
+ }
- $name = trim($nameNode->plaintext);
+ if ($orderNumber !== null) {
+ $orders[$orderNumber] = [
+ 'items' => $items,
+ 'totalSum' => $totalSum,
+ 'number' => $orderNumber,
+ 'date' => $message['date'],
- // Количество
- $countNode = $itemRow->findOne("td:nth-child(2) p[style*='#8C8C8C']");
- $countText = $countNode ? $countNode->plaintext : '1';
- $count = (int) filter_var($countText, FILTER_SANITIZE_NUMBER_INT);
+ ];
+ }
+ Yii::warning(
+ 'HTML Тело письма: ' . json_encode($message['body'], JSON_UNESCAPED_UNICODE),
+ __METHOD__
+ );
+ Yii::warning('Новые заказы: ' . json_encode($orders, JSON_UNESCAPED_UNICODE), __METHOD__);
+ } elseif (preg_match($subjectPatterns[1], $message['subject'])) {
+ $orderDetails = [];
+
+// Блок "Доставить"
+ $deliveryBlock = $main->findOne('p:contains("Доставить")');
+ return $main->html();
+ if ($deliveryBlock) {
+ $deliveryBlock = $deliveryBlock->parentNode()->findMulti('p');
+
+ return json_encode(($deliveryBlock[1])->html(), JSON_UNESCAPED_UNICODE);
+ $deliveryText = $deliveryBlock->innertext;
+ Yii::warning('Текст заказа: ' . json_encode($deliveryText, JSON_UNESCAPED_UNICODE), __METHOD__);
+ $orderDetails['delivery'] = trim($deliveryText);
+ }
- // Сумма
- $sumNode = $itemRow->findOne("td:nth-child(3) p");
- $sumText = $sumNode ? $sumNode->plaintext : '0';
- $sum = (float) str_replace([' ', '₽'], '', $sumText);
+// Блок "Комментарий"
+ $commentBlock = $main->findOne('p:contains("Комментарий")');
+ if ($commentBlock) {
+ $commentBlock = $commentBlock->nextSibling();
+ $orderDetails['comment'] = trim($commentBlock->innerText());
+ }
- $items[] = ['name' => $name, 'count' => $count, 'sum' => $sum];
- }
- }
+// Блок "Клиент" (Отправитель)
+ $clientBlock = $main->findOne('p:contains("Клиент")');
+ if ($clientBlock) {
+ $clientBlock = $clientBlock->nextSibling();
+ $clientText = trim($clientBlock->innerText());
+ $orderDetails['sender'] = $clientText;
+ }
- // Общая сумма
- $totalSumNodes = $elements->parentNode()->getElementsByTagName('table');
- $totalSumNode = ($totalSumNodes[3])->findOne("tr:contains('Итого оплачено')");
- if ($totalSumNode) {
- $totalSum = (float) str_replace([' ', '₽'], '', trim(($totalSumNode->findMulti("td"))[1]->plaintext));
- }
+
+ // Извлечение товаров
+
+
+ Yii::warning(
+ 'HTML Тело письма: ' . json_encode($message['body'], JSON_UNESCAPED_UNICODE),
+ __METHOD__
+ );
+
+ $orderItems = [];
+
+// Ищем все комментарии <!-- START ITEM -->
+ $startComments = $main->find('comment:contains("START ITEM")');
+
+ foreach ($startComments as $startComment) {
+ $itemData = [
+ 'image' => '',
+ 'name' => '',
+ 'count' => '',
+ 'price' => '',
+ ];
+
+ // Находим следующий элемент <tr> после комментария
+ $tr = $startComment->nextSibling();
+ if ($tr && $tr->tag === 'tr') {
+ // Извлекаем изображение
+ $img = $tr->find('img')[0];
+ if ($img) {
+ $itemData['image'] = $img->src;
+ }
+
+ // Извлекаем название и количество из второго <td>
+ $tds = $tr->find('td');
+ if (count($tds) >= 2) {
+ $itemData['name'] = trim($tds[1]->find('p')[0]->innerText());
+ $itemData['count'] = trim($tds[1]->find('p')[1]->innerText());
+ }
+
+ // Извлекаем цену из третьего <td>
+ if (count($tds) >= 3) {
+ $itemData['price'] = trim($tds[2]->find('p')[0]->innerText());
}
}
- } catch (\Exception $e) {
- Yii::error('Ошибка: ' . json_encode($e->getMessage(), JSON_UNESCAPED_UNICODE) . " " . $e->getLine() . " " . json_encode($e->getTrace(), JSON_UNESCAPED_UNICODE), __METHOD__);
+
+ // Добавляем данные в массив
+ $orderItems[] = $itemData;
}
- if ($orderNumber !== null) {
- $orders[] = [
- $orderNumber => [
- 'items' => $items,
- 'totalSum' => $totalSum,
- 'number' => $orderNumber,
- 'date' => $date,
- ]
- ];
+ $orderDetails['items'] = $orderItems;
+ // Общая сумма
+ $total = '';
+
+// Ищем комментарий <!-- START TOTAL -->
+ $startTotalComment = $main->findOne('comment:contains("START TOTAL")');
+ if ($startTotalComment) {
+ // Находим следующий элемент <tr> после комментария
+ $tr = $startTotalComment->nextSibling();
+ if ($tr && $tr->tag === 'tr') {
+ // Извлекаем текст из второго <td>
+ $tds = $tr->find('td');
+ if (count($tds) >= 2) {
+ $totalSum = trim($tds[1]->find('p')[0]->innerText());
+ }
+ }
}
+ $orderDetails['totalSum'] = $totalSum;
+ $orders[$orderNumber] = $orderDetails;
- Yii::warning('HTML Тело письма: ' . json_encode($orders, JSON_UNESCAPED_UNICODE), __METHOD__);
- break;
+ Yii::warning('Принятые заказы: ' . json_encode($orders, JSON_UNESCAPED_UNICODE), __METHOD__);
}
-
- // imap_setflag_full($inbox, $email_number, "\\Seen");
+ // Yii::warning('HTML Тело письма: ' . json_encode($message['body'], JSON_UNESCAPED_UNICODE), __METHOD__);
}
} else {
Yii::warning('Новых сообщений не обнаружено.', __METHOD__);
}
- imap_close($inbox);
+
return ['success' => true, 'count' => $count];
}
+
+ public function actionParseMail()
+ {
+ set_time_limit(300);
+ Yii::$app->response->format = Response::FORMAT_JSON;
+
+ $html = file_get_contents('./runtime/file.html');
+
+ if (!empty($html)) {
+ $html = html_entity_decode($html, ENT_QUOTES | ENT_HTML5, 'UTF-8');
+
+ $doc = new HtmlDomParser($html);
+
+ $main = $doc->findOneOrFalse("body");
+
+ if ($main !== false) {
+ $orderTitleNode = $main->findOne("h1");
+
+ if ($orderTitleNode && preg_match('/№(\d+)/', $orderTitleNode->innertext, $matches)) {
+ $orderNumber = (int)$matches[1];
+ }
+ }
+ $orderDetails['number'] = $orderNumber;
+ $deliveryText = '';
+ $commentText = '';
+ $clientText = '';
+ $recipientText = '';
+ $orderItems = [];
+
+
+ $deliveryBlock = $main->findOne('p:contains("Доставить")');
+ $pickupBlock = $main->findOne('p:contains("Самовывоз")');
+
+ if ($deliveryBlock && $deliveryBlock->nextNonWhitespaceSibling()) {
+ $deliveryBlock = $deliveryBlock->nextNonWhitespaceSibling();
+ $deliveryText = "Доставка: " . strip_tags($deliveryBlock->innerText());
+ $deliveryText = preg_replace('/\s+/', ' ', $deliveryText);
+ } elseif ($pickupBlock && $pickupBlock->nextNonWhitespaceSibling()) {
+ $pickupBlock = $pickupBlock->nextNonWhitespaceSibling();
+ $deliveryText = "Самовывоз: " . strip_tags($pickupBlock->innerText());
+ $deliveryText = preg_replace('/\s+/', ' ', $deliveryText);
+ }
+
+ if ($deliveryText) {
+ Yii::warning('Текст заказа: ' . $deliveryText, __METHOD__);
+ $orderDetails['delivery'] = trim($deliveryText);
+ }
+
+ $commentBlock = $main->findOne('p:contains("Комментарий")');
+ if ($commentBlock && $commentBlock->nextNonWhitespaceSibling()) {
+ $commentBlock = $commentBlock->nextNonWhitespaceSibling();
+ $commentText = preg_replace('/\s+/', ' ', $commentBlock->innerText());
+ $orderDetails['comment'] = trim($commentText);
+ }
+
+
+
+ $clientBlock = $main->findOne('p:contains("Клиент")');
+ $senderBlock = $main->findOne('p:contains("Отправитель")');
+
+ if ($clientBlock && $clientBlock->nextNonWhitespaceSibling()) {
+ $clientBlock = $clientBlock->nextNonWhitespaceSibling();
+ $clientText = "Клиент: " . strip_tags($clientBlock->innerText());
+ $phoneLink = $clientBlock->find('a', 0);
+ if ($phoneLink) {
+ $clientText .= ' ' . preg_replace('/tel:/', ' ', $phoneLink->getAttribute('href'));
+ }
+ } elseif ($senderBlock && $senderBlock->nextNonWhitespaceSibling()) {
+ $senderBlock = $senderBlock->nextNonWhitespaceSibling();
+ $clientText = "Отправитель: " . strip_tags($senderBlock->innerText());
+ $phoneLink = $senderBlock->find('a', 0);
+ if ($phoneLink) {
+ $clientText .= ' ' . preg_replace('/tel:/', ' ', $phoneLink->getAttribute('href'));
+ }
+ }
+
+ if ($clientText) {
+ $orderDetails['client'] = str_replace('Позвонить', '', $clientText);
+ }
+
+ $recipientBlock = $main->findOne('p:contains("Получатель")');
+ if ($recipientBlock && $recipientBlock->nextNonWhitespaceSibling()) {
+ $recipientBlock = $recipientBlock->nextNonWhitespaceSibling();
+ $recipientText = strip_tags(
+ str_replace('Позвонить', '', $recipientBlock->innerText())
+ ) . ' ' . preg_replace('/tel:/', ' ', $recipientBlock->find('a', 0)->getAttribute('href'));
+ $orderDetails['recipient'] = $recipientText;
+ }
+
+
+ $itemsBlock = $main->findOneOrFalse('h2:contains("Детали заказа")') ? $main->findOne('h2:contains("Детали заказа")') : $main->findOne('p:contains("Детали заказа")');
+ $itemsTable = $itemsBlock->parentNode()->find('table', 2);
+
+ $itemsRows = $itemsTable->find('tr');
+ foreach ($itemsRows as $itemsRow) {
+ Yii::warning('Строка заказа: ' . json_encode($itemsRow->innerText(), JSON_UNESCAPED_UNICODE), __METHOD__);
+ $itemData = [
+ 'name' => '',
+ 'count' => '',
+ '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);
+ $sumRow = $sumBlock->find('tr');
+
+ $sumTds = $sumRow->find('td');
+ if (count($sumTds) >= 2) {
+ $totalSum = (float)trim(str_replace(["\u{00A0}", '₽' , ' '], '', strip_tags(preg_replace('/\s+/', ' ', $sumTds[1]->innerText()))));
+
+ }
+ $orderDetails['items'] = $orderItems;
+ $orderDetails['totalSum'] = $totalSum;
+ }
+ $order[$orderNumber] = $orderDetails;
+ return [
+ 'success' => true,
+ 'order' => $order
+
+ ];
+ }
+
}
$countText = $countNode ? $countNode->plaintext : '1';
$count = (int) filter_var($countText, FILTER_SANITIZE_NUMBER_INT);
- // СÑ\83мма
- $sumNode = $itemRow->findOne("td:nth-child(3) p");
- $sumText = $sumNode ? $sumNode->plaintext : '0';
- $sum = (float) str_replace([' ', '₽'], '', $sumText);
+ // Цена
+ $priceNode = $itemRow->findOne("td:nth-child(3) p");
+ $priceText = $priceNode ? $priceNode->plaintext : '0';
+ $price = (float) str_replace([' ', '₽'], '', $priceText);
- $items[] = ['name' => $name, 'count' => $count, 'sum' => $sum];
+ $items[] = ['name' => $name, 'count' => $count, 'price' => $price];
}
}
}
Yii::warning('HTML Тело письма: ' . json_encode($orders, JSON_UNESCAPED_UNICODE), __METHOD__);
- break;
+
}
// imap_setflag_full($inbox, $email_number, "\\Seen");
$marketplaceOrder = self::createOrder($order, $campaignId, $statusId, $substatusId);
if ($marketplaceOrder->save()) {
- $newOrdersCount++;
+ $newOrdersCount += 1;
self::createStatusHistory($marketplaceOrder->id, $statusId, $substatusId);
- self::saveOrderItems($order, $marketplaceOrder->id);
+ self::saveOrderItems($order, $marketplaceOrder->id, $marketplaceOrder->warehouse_guid);
} else {
Yii::error(
private static function createOrder($order, $campaignId, $statusId, $substatusId)
{
+ $store = MarketplaceStore::find()
+ ->where(['warehouse_guid' => (string)$campaignId])
+ ->andWhere(['warehouse_id' => 1])->one();
$marketplaceOrder = new MarketplaceOrders();
$marketplaceOrder->marketplace_order_id = (string)$order['number'];
$marketplaceOrder->creation_date = date('Y-m-d H:i:s', strtotime($order['date']));
$marketplaceOrder->fake = 0;
$marketplaceOrder->marketplace_name = 'ФлауВау';
$marketplaceOrder->marketplace_id = 1;
-
+ $marketplaceOrder->store_id = $store->store_id;
return $marketplaceOrder;
}
$history->date_end = '2100-01-01 00:00:00';
$history->save();
}
- private static function saveOrderItems($order, $orderId)
+ private static function saveOrderItems($order, $orderId, $warehouseGuid)
{
$items = $order['items'];
if (!$items) {
$orderItem = new MarketplaceOrderItems();
$orderItem->order_id = $orderId;
$orderItem->external_item_id = $order['number'];
+ $orderItem->offer_name = $item['name'];
$orderItem->offer_id = $item['name'];
$orderItem->price = $item['price'];
$orderItem->count = $item['count'];
- $orderItem->save();
+ $orderItem->buyer_price = $item['price'];
+ $orderItem->buyer_price_before_discount = $item['price'];
+ $orderItem->price_before_discount = $item['price'];
+ $orderItem->vat = "UNKNOWN";
+ $orderItem->shop_sku = $item['name'];
+ $orderItem->subsidy = 0;
+ $orderItem->partner_warehouse_id = $warehouseGuid;
+ $orderItem->promos = null;
+ $orderItem->subsidies = null;
+ if (!$orderItem->save()) {
+ Yii::error(
+ 'Ошибка сохранения элеиента: ' . json_encode($orderItem->getErrors(), JSON_UNESCAPED_UNICODE)
+ );
+ }
+
}
}