From: Marina Zozirova Date: Thu, 27 Mar 2025 20:43:35 +0000 (+0000) Subject: ERP-355 Автоматизация звонков роботом из когорт X-Git-Url: https://gitweb.erp-flowers.ru/?a=commitdiff_plain;h=de89c82b173c6a27b9bb8c2c11f2ff2cf724c4fa;p=erp24_rep%2Fyii-erp24%2F.git ERP-355 Автоматизация звонков роботом из когорт --- diff --git a/erp24/commands/CronController.php b/erp24/commands/CronController.php index 72498216..eb43965d 100644 --- a/erp24/commands/CronController.php +++ b/erp24/commands/CronController.php @@ -16,6 +16,12 @@ use yii\helpers\Json; use yii_app\helpers\ClientHelper; use yii_app\helpers\DataHelper; use yii_app\records\BonusLevels; +use yii_app\records\EqualizationRemains; +use yii_app\records\LPTrackerApi; +use yii_app\records\Product1cReplacement; +use yii_app\records\Products1c; +use yii_app\records\ReplacementInvoice; +use yii_app\records\ReplacementInvoiceProducts; use yii_app\records\MarketplaceOrder1cStatuses; use yii_app\records\Sales; use yii_app\records\SentKogort; @@ -51,12 +57,13 @@ class CronController extends Controller // 'export-catalog' => \app\actions\cron\ExportCatalogAction::class, // 'cloudpayments-region' => \app\actions\cron\CloudpaymentsRegionAction::class, // 'bonus-users-sale-update' => \app\actions\cron\BonusUsersSaleUpdateAction::class, - // '1c-check-1day' => \app\actions\cron\OneCCheckOneDayAction::class, + // '1c-check-1day' => \app\actions\cron\OneCCheckOneDayAction::class, ]; } //cron/one-c - public function actionOneC() { + public function actionOneC() + { $req_id = time(); $json_post = '{"request_id": "' . $req_id . '" ,"incomings":{"start_time":"' . date("Y-m-d", time() - 86400) . ' 00:00:00","end_time":"' . date("Y-m-d", time()) . ' 23:59:59"},"checks":{"start_time":"' . date("Y-m-d", time() - 24400) . ' 00:00:00","end_time":"' . date("Y-m-d", time()) . ' 23:59:59"}, "write_offs":{"start_time":"' . date("Y-m-d", time() - 86400 * 7) . ' 00:00:00","end_time":"' . date("Y-m-d", time()) . ' 23:59:59"}}'; @@ -102,9 +109,10 @@ class CronController extends Controller } //cron/one-c-check-one-day - public function actionOneCCheckOneDay() { - $req_id=time(); - $json_post='{"request_id": "'.$req_id.'" ,"checks":{"start_time":"'.date("Y-m-d",time()-86400).' 00:00:00","end_time":"'.date("Y-m-d H:i:s",time()).'"}}'; + public function actionOneCCheckOneDay() + { + $req_id = time(); + $json_post = '{"request_id": "' . $req_id . '" ,"checks":{"start_time":"' . date("Y-m-d", time() - 86400) . ' 00:00:00","end_time":"' . date("Y-m-d H:i:s", time()) . '"}}'; $this->setApiCron($req_id, $json_post); @@ -112,9 +120,10 @@ class CronController extends Controller } //cron/one-c-sellers - public function actionOneCSellers() { - $req_id=time(); - $json_post='{"request_id": "'.$req_id.'","nomenclature":true,"sellers":true, "prices":{"type_price":"Розничная цена"}, "balances":true, "payment_types":true}'; + public function actionOneCSellers() + { + $req_id = time(); + $json_post = '{"request_id": "' . $req_id . '","nomenclature":true,"sellers":true, "prices":{"type_price":"Розничная цена"}, "balances":true, "payment_types":true}'; $this->setApiCron($req_id, $json_post); @@ -122,9 +131,10 @@ class CronController extends Controller } //cron/one-c-price-msk - public function actionOneCPriceMsk() { - $req_id=time(); - $json_post='{"request_id": "'.$req_id.'","nomenclature":true,"sellers":true, "prices":{"type_price":"Розничная Маг на Московск"}, "balances":true, "payment_types":true}'; + public function actionOneCPriceMsk() + { + $req_id = time(); + $json_post = '{"request_id": "' . $req_id . '","nomenclature":true,"sellers":true, "prices":{"type_price":"Розничная Маг на Московск"}, "balances":true, "payment_types":true}'; $this->setApiCron($req_id, $json_post); @@ -132,11 +142,12 @@ class CronController extends Controller } //cron/custom-one-c-cron - public function actionCustomOneCCron() { - $req_id=time(); + public function actionCustomOneCCron() + { + $req_id = time(); //чеки за 7 дней назад прогружаем - $json_post='{"request_id": "'.$req_id.'", "checks":{"start_time":"'.date("Y-m-d",time()-86400*7).' 00:00:00","end_time":"'.date("Y-m-d",time()).' 23:59:59"}}'; + $json_post = '{"request_id": "' . $req_id . '", "checks":{"start_time":"' . date("Y-m-d", time() - 86400 * 7) . ' 00:00:00","end_time":"' . date("Y-m-d", time()) . ' 23:59:59"}}'; $this->setApiCron($req_id, $json_post); @@ -144,11 +155,12 @@ class CronController extends Controller } //cron/one-c-cron-self-cost-day - public function actionOneCCronSelfCostDay() { - $req_id=time(); + public function actionOneCCronSelfCostDay() + { + $req_id = time(); //себестоимость за текущий день - $json_post='{"request_id": "'.$req_id.'", "self_cost":{"start_time":"'.date("Y-m-d",time()).' 00:00:00","end_time":"'.date("Y-m-d",time()).' 23:59:59"}}'; + $json_post = '{"request_id": "' . $req_id . '", "self_cost":{"start_time":"' . date("Y-m-d", time()) . ' 00:00:00","end_time":"' . date("Y-m-d", time()) . ' 23:59:59"}}'; $this->setApiCron($req_id, $json_post); @@ -199,7 +211,8 @@ class CronController extends Controller // } - public function actionBalanceHistory() { + public function actionBalanceHistory() + { $data = Yii::$app->db->createCommand("SELECT * FROM balances")->queryAll(); $command = Yii::$app->db->createCommand()->batchInsert('balances_history', @@ -220,7 +233,8 @@ class CronController extends Controller $command->execute(); } - private function setApiCron($req_id, $json_post) { + private function setApiCron($req_id, $json_post) + { Yii::$app->db->createCommand()->insert('api_cron', [ 'date' => new Expression('NOW()'), 'date_up' => new Expression('NOW()'), @@ -435,10 +449,10 @@ class CronController extends Controller ], [ - 'kogort_date' => $kogortDate, - 'target_date' => $targetDate, + 'kogort_date' => $kogortDate, + 'target_date' => $targetDate, 'kogort_number' => SentKogort::KOGORT_NUMBERS['target'], - 'phone' => $phonesArray, + 'phone' => $phonesArray, ] ); @@ -458,7 +472,7 @@ class CronController extends Controller $ip = "tst"; $tip_sale = "target"; $name = "Начисление бонусов на дату {$kogortDate}"; - $daysToEnd = $step1 + 1; + $daysToEnd = $step1 + 1; $userBonusExist = UsersBonus::find() ->select(['phone']) ->where(['phone' => $kogortPhones]) @@ -625,7 +639,6 @@ class CronController extends Controller return ExitCode::OK; } - public function actionSendSecondTelegramMessage() { $messagesSettings = UsersMessageManagement::find()->one(); @@ -690,8 +703,8 @@ class CronController extends Controller ); if (!empty($telegramUsers)) { - $messageText = $messagesSettings - ->replaceShortcodes($messagesSettings->offer_2, $targetDate); + $messageText = $messagesSettings + ->replaceShortcodes($messagesSettings->offer_2, $targetDate); foreach ($telegramUsers as $telegramUser) { if (!in_array($telegramUser['phone'], $sentStatusKogort)) { $messageData = []; @@ -930,7 +943,7 @@ class CronController extends Controller $this->stdout("Некорректный формат времени\n", BaseConsole::FG_RED); return ExitCode::DATAERR; } - $currentDate = $this->time ? date('Y-m-d', (int)$this->time) : date('Y-m-d'); + $currentDate = $this->time ? date('Y-m-d', (int)$this->time) : date('Y-m-d'); $stepsBack = $this->stepsBack ?? 0; $step3 = $messagesSettings ? $messagesSettings->day_before_step3 : 2; $testActive = $messagesSettings ? (bool)($messagesSettings->test_phones_active) : false; @@ -1002,6 +1015,94 @@ class CronController extends Controller return ExitCode::OK; } + /** + * ERP-355 + * Отправка контактов для обзвона в LPTracker + */ + public function actionSendContactsToLptracker() + { + $messagesSettings = UsersMessageManagement::find()->one(); + if (!$messagesSettings) { + $this->stdout( + "Рассылка неактивна (не найдена настройка). Отправка сообщений прервана.\n", + BaseConsole::FG_RED + ); + return ExitCode::UNAVAILABLE; + } + if (!$messagesSettings->active) { + $this->stdout( + "Рассылка неактивна (поле active = 0). Отправка сообщений прервана.\n", + BaseConsole::FG_RED + ); + return ExitCode::UNAVAILABLE; + } + try { + + $numbers = SentKogort::findAll(['kogort_number' => SentKogort::CALL, 'kogort_date' => date('Y-m-d'), 'status' => SentKogort::READY_TO_UPLOAD_LPTRACKER_STATUS]); + + if (!empty($messagesSettings->test_phones_list)) { + $testPhones = array_map('trim', explode(',', $messagesSettings->test_phones_list)); + if ( + isset($messagesSettings->test_phones_active) + && + $messagesSettings->test_phones_active == 1 + ) { + $numbers = $testPhones; + } + } + $this->stdout( + "Отправка лидов в LPTrackerApi.\n", + BaseConsole::FG_RED + ); + foreach ($numbers as $number) { + $api = new LPTrackerApi(); + $response = $api->post('lead', [ + 'contact' => [ + 'project_id' => LPTrackerApi::SERVICE, + 'name' => $number->user?->name, + 'details' => [ + [ + 'type' => 'phone', + 'data' => $number->phone, + ] + ] + ], + 'custom' => [ + LPTrackerApi::REASON_FOR_THE_CALL => LPTrackerApi::PURCHASE_EARLIER, + ], + //признак того что звонок должен поступать сразу после загрузки лида + //поставить true при согласовании с маркетингом + //также добавить признак повод звонка при необходимости + 'callback' => false, + 'funnel' => LPTrackerApi::NEW_LEAD, + 'lead_date' => date('d.m.Y H:i'), + 'owner' => 0, + 'payments' => [ + ], + ]); + + $status = $response['status'] == LPTrackerApi::SUCCESS_STATUS + ? SentKogort::SUCCESS_UPLOAD_TO_LPTRACKER_STATUS + : SentKogort::ERROR_UPLOAD_TO_LPTRACKER_STATUS; + + SentKogort::updateAll(['status' => $status], ['id' => $number->id]); + + if ($status === SentKogort::ERROR_UPLOAD_TO_LPTRACKER_STATUS) { + throw new \Exception( + "ОШИБКА С LPTRACKER\n" . implode('. ', array_column($response['errors'], 'message')) + ); + } else { + $this->stdout( + "Лид с номером {$number->phone} успешно создан.\n", + BaseConsole::FG_RED + ); + } + } + } catch (\Exception $exception) { + throw new \Exception($exception); + } + } + public function options($actionID) { $options = parent::options($actionID); @@ -1018,16 +1119,16 @@ class CronController extends Controller $batchSize = 500; $offset = 0; - // $csvFilePath = Yii::getAlias('@data/missing_users.csv'); - // $fileHandle = fopen($csvFilePath, 'w'); - // fputcsv($fileHandle, ['phone', 'username', 'chat_id', 'is-blocked', 'is_registered', 'reason'], ';'); + // $csvFilePath = Yii::getAlias('@data/missing_users.csv'); + // $fileHandle = fopen($csvFilePath, 'w'); + // fputcsv($fileHandle, ['phone', 'username', 'chat_id', 'is-blocked', 'is_registered', 'reason'], ';'); while (true) { $chatbotUsers = $remoteDb ->createCommand('SELECT * FROM chatbot_telegram_users LIMIT :limit OFFSET :offset', [ - ':limit' => $batchSize, - ':offset' => $offset, - ])->queryAll(); + ':limit' => $batchSize, + ':offset' => $offset, + ])->queryAll(); if (empty($chatbotUsers)) { break; diff --git a/erp24/config/console.php b/erp24/config/console.php index b15ac017..abb400af 100755 --- a/erp24/config/console.php +++ b/erp24/config/console.php @@ -62,6 +62,11 @@ $config = [ 'class' => 'yii\log\FileTarget', 'levels' => ['error', 'warning'], ], + [ + 'class' => 'app\log\TelegramTarget', + 'levels' => ['error', 'warning'], + // 'categories' => ['api.error', 'js.error', 'command.error'], + ], ], ], 'db' => require dirname(__DIR__) . '/config/db.php', diff --git a/erp24/records/LPTrackerApi.php b/erp24/records/LPTrackerApi.php new file mode 100644 index 00000000..cea54385 --- /dev/null +++ b/erp24/records/LPTrackerApi.php @@ -0,0 +1,90 @@ +client = new Client([ + 'base_uri' => self::BASE_URI, + 'timeout' => self::TIMEOUT, + ]); + + if (empty($this->token)) { + $this->auth(); + } + } catch (Exception $exception) { + throw new Exception($exception); + } + } + + + private function auth() + { + $response = $this->post('/login', [ + 'login' => self::LOGIN, + 'password' => self::PASSWORD, + 'service' => self::SERVICE, + 'version' => '1.0' + ]); + + if (!empty($response) && $response['status'] == self::SUCCESS_STATUS && $response['result']['token']) { + $this->token = $response['result']['token']; + } else { + throw new Exception('Не удалось получить токен!'); + } + } + + public function get($endpoint) + { + $response = $this->client->get($endpoint, [ + 'headers' => [ + 'token' => $this->token, + 'Content-type' => 'application/json', + ] + ]); + + return json_decode($response->getBody(), true); + } + + public function post($endpoint, array $data = []) + { + $response = $this->client->post($endpoint, [ + 'json' => $data, + 'headers' => [ + 'token' => $this->token, + 'Content-Type' => 'application/json', + ] + ]); + + return json_decode($response->getBody(), true); + } + +} \ No newline at end of file diff --git a/erp24/records/SentKogort.php b/erp24/records/SentKogort.php index 2fa033dc..c2367fc9 100644 --- a/erp24/records/SentKogort.php +++ b/erp24/records/SentKogort.php @@ -20,6 +20,11 @@ use Yii; */ class SentKogort extends \yii\db\ActiveRecord { + public const CALL = 3; + public const READY_TO_UPLOAD_LPTRACKER_STATUS = 1; + public const SUCCESS_UPLOAD_TO_LPTRACKER_STATUS = 11; + public const ERROR_UPLOAD_TO_LPTRACKER_STATUS = 22; + public const KOGORT_NUMBERS = [ 'target' => 1, 'whatsapp' => 2, @@ -87,4 +92,10 @@ class SentKogort extends \yii\db\ActiveRecord $this->updateAttributes(['updated_at' => date('Y-m-d H:i:s')]); } } + + public function getUser() + { + return $this->hasOne(Users::class, ['phone' => 'phone']); + + } }