]> gitweb.erp-flowers.ru Git - erp24_rep/yii-erp24/.git/commitdiff
ERP-355 Автоматизация звонков роботом из когорт
authorMarina Zozirova <marina.zozirova@erp-flowers.ru>
Thu, 27 Mar 2025 20:43:35 +0000 (20:43 +0000)
committerAleksey Filippov <aleksey.filippov@erp-flowers.ru>
Thu, 27 Mar 2025 20:43:35 +0000 (20:43 +0000)
erp24/commands/CronController.php
erp24/config/console.php
erp24/records/LPTrackerApi.php [new file with mode: 0644]
erp24/records/SentKogort.php

index 7249821632969d64b64370082e3a9bec73ce4bf7..eb43965d22f4ed981164e1b247c50c4d71473a45 100644 (file)
@@ -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;
index b15ac017a2cd04f1ef56e3dd34573df2688c4470..abb400af9214b1a1bdad5872fb33188f7894a76d 100755 (executable)
@@ -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 (file)
index 0000000..cea5438
--- /dev/null
@@ -0,0 +1,90 @@
+<?php
+
+namespace yii_app\records;
+
+use Exception;
+use GuzzleHttp\Client;
+
+class LPTrackerApi
+{
+
+    private const LOGIN = 'Zakaz-bazacvetov24@yandex.ru1';
+    private const PASSWORD = 'B8-YY7d3K2ekNdK';
+    public const SERVICE = 117605;
+    private const TIMEOUT = 10;
+
+    public const SUCCESS_STATUS = 'success';
+    public const ERROR_STATUS = 'error';
+
+    public const NEW_LEAD = 2086013;
+    public const TO_CALL = 2140957;
+    public const REASON_FOR_THE_CALL = 2391182;
+
+
+    public const MEMORABLE_DATE  = 'Памятная дата';
+    public const PURCHASE_EARLIER = 'Покупал ранее';
+
+    private $token;
+    public $client;
+
+    public const BASE_URI = 'https://direct.lptracker.ru';
+
+    public function __construct()
+    {
+        try {
+            $this->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
index 2fa033dc7f778ff270b0da6a831df6ae76a1b522..c2367fc9102a0e16dbb55cbef97a1a814916d800 100644 (file)
@@ -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']);
+
+    }
 }