From b467589490fcf8a40d7b497d517b7ef512846123 Mon Sep 17 00:00:00 2001 From: marina Date: Tue, 22 Jul 2025 09:20:22 +0300 Subject: [PATCH] =?utf8?q?ERP-438=20=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE?= =?utf8?q?=D1=82=D0=BA=D0=B0=20=D1=8D=D0=BD=D0=B4=D0=BF=D0=BE=D0=B9=D0=BD?= =?utf8?q?=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- erp24/actions/bonus/AddBonuses.php | 5 +- erp24/api2/controllers/ClientController.php | 303 +++++++++++++++++--- erp24/config/env.php | 6 +- 3 files changed, 273 insertions(+), 41 deletions(-) diff --git a/erp24/actions/bonus/AddBonuses.php b/erp24/actions/bonus/AddBonuses.php index e5c56b78..2f2799f3 100644 --- a/erp24/actions/bonus/AddBonuses.php +++ b/erp24/actions/bonus/AddBonuses.php @@ -2,6 +2,7 @@ namespace yii_app\actions\bonus; +use Yii; use yii\base\Action; use yii\data\ActiveDataProvider; use yii\helpers\ArrayHelper; @@ -63,7 +64,7 @@ class AddBonuses extends Action $twentyPercent->tip_sale = 'sale'; $twentyPercent->check_id = $sale->id; $twentyPercent->price = $sale->summ; - $twentyPercent->admin_id = 1294; + $twentyPercent->admin_id = Yii::$app->user->id; $twentyPercent->store_id = $sale->store_id; $twentyPercent->date_start = $sale->date; $twentyPercent->name = "Возврат с покупки 20%. Чек " . $sale->number . " от " @@ -85,7 +86,7 @@ class AddBonuses extends Action $userBonus->tip_sale = 'sale'; $userBonus->check_id = $sale->id; $userBonus->price = $sale->summ; - $userBonus->admin_id = 1294; + $userBonus->admin_id = \Yii::$app->user->id; $userBonus->store_id = $sale->store_id; $userBonus->bonus = floor($sale->summ * 0.1); $userBonus->date_start = $sale->date; diff --git a/erp24/api2/controllers/ClientController.php b/erp24/api2/controllers/ClientController.php index 64917dbb..98805937 100644 --- a/erp24/api2/controllers/ClientController.php +++ b/erp24/api2/controllers/ClientController.php @@ -10,6 +10,7 @@ use yii\db\Expression; use yii\helpers\Json; use yii_app\helpers\ClientHelper; use yii_app\helpers\UtilHelper; +use yii_app\records\BonusLevels; use yii_app\records\CityStore; use yii_app\records\ExportImportTable; use yii_app\records\MessagerUser; @@ -20,12 +21,16 @@ use yii_app\records\ReferralStatus; use yii_app\records\Sales; use yii_app\records\Users; use yii_app\records\UsersBonus; +use yii_app\records\UsersBonusLevels; use yii_app\records\UsersEvents; use yii_app\services\LogService; -class ClientController extends BaseController { +class ClientController extends BaseController +{ private static $LOG = "/var/www/www-root/data/www/erp.bazacvetov24.ru/yii_app/api2/log.txt"; - public function actionAdd() { + + public function actionAdd() + { Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; $data = file_get_contents('php://input'); $result = json_decode($data, true); @@ -62,10 +67,10 @@ class ClientController extends BaseController { $user = Users::find()->where(['and', ['phone' => $result['phone']], ['phone_true' => '1']])->one(); $infArr = ["avatar", "client_type", "date_of_creation", "full_name", "messenger", "message_id", "platform_id"]; $jsn = []; - foreach($infArr as $mass) { + foreach ($infArr as $mass) { $jsn[$mass] = $result[$mass]; } - $jsn = json_encode($jsn,JSON_UNESCAPED_UNICODE); + $jsn = json_encode($jsn, JSON_UNESCAPED_UNICODE); if (!$user) { $user = new Users; $user->phone = $result['phone']; @@ -103,7 +108,8 @@ class ClientController extends BaseController { return $this->asJson($mess); } - public function actionBalance() { + public function actionBalance() + { Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; $data = file_get_contents('php://input'); $result = json_decode($data, true); @@ -147,7 +153,8 @@ class ClientController extends BaseController { return $this->asJson($mess); } - public function actionRetrieve() { + public function actionRetrieve() + { Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; $client = new Client(); $offset = 0; @@ -188,7 +195,7 @@ class ClientController extends BaseController { foreach (range(0, 50) as $day10) { $date_from = $current_time - $diff_time * ($day10 + 1); - $date_to = $current_time - $diff_time * $day10; + $date_to = $current_time - $diff_time * $day10; $body = $client->request('GET', 'https://chatter.salebot.pro/api/325aa5519d0e65ea8c4759a3e6143584/subscribers?date_to=' . $date_to . '&date_from=' . $date_from)->getBody(); @@ -264,7 +271,8 @@ class ClientController extends BaseController { return $this->asJson($finalResult); } - public function actionGet() { + public function actionGet() + { Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; $data = file_get_contents('php://input'); $result = json_decode($data, true); @@ -292,7 +300,8 @@ class ClientController extends BaseController { return $this->asJson(['client_id' => $messagerUser->client_id, 'platform_id' => $messagerUser->platform_id]); } - private function saveEvent($phone, $channel, $event) { + private function saveEvent($phone, $channel, $event) + { foreach (['date', 'number'] as $fieldName) { if (empty($event[$fieldName])) { return "$fieldName is required"; @@ -379,7 +388,8 @@ class ClientController extends BaseController { } } - public function actionEventEdit() { + public function actionEventEdit() + { Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; $data = file_get_contents('php://input'); $result = json_decode($data, true); @@ -414,7 +424,8 @@ class ClientController extends BaseController { return $this->asJson(['response' => true]); } - public function actionShowKeycode() { + public function actionShowKeycode() + { Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; $data = file_get_contents('php://input'); $result = json_decode($data, true); @@ -447,7 +458,7 @@ class ClientController extends BaseController { LogService::apiErrorLog(json_encode(["error_id" => 2, "error" => $user->getErrors()], JSON_UNESCAPED_UNICODE)); } } - $protocol = stripos($_SERVER['SERVER_PROTOCOL'],'https') === 0 ? 'https://' : 'http://'; + $protocol = stripos($_SERVER['SERVER_PROTOCOL'], 'https') === 0 ? 'https://' : 'http://'; $host = $protocol . $_SERVER['HTTP_HOST']; $caption = 'Покажи этот QR-код флористу в магазине, чтобы списать бонусы. Если QR-код не срабатывает, назови код подтверждения - ' . $user->keycode; $key = Yii::$app->request->get('key'); @@ -462,7 +473,8 @@ class ClientController extends BaseController { } } - public function actionStoreGeo() { + public function actionStoreGeo() + { Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; $data = file_get_contents('php://input'); $result = json_decode($data, true); @@ -481,7 +493,7 @@ class ClientController extends BaseController { $key = Yii::$app->request->headers->get('x-access-token'); } - $protocol = stripos($_SERVER['SERVER_PROTOCOL'],'https') === 0 ? 'https://' : 'http://'; + $protocol = stripos($_SERVER['SERVER_PROTOCOL'], 'https') === 0 ? 'https://' : 'http://'; $host = $protocol . $_SERVER['HTTP_HOST']; $result = (new Client)->get($host . '/telegram-salebot/send-geo-and-stores?platform_id=' . $result['platform_id'] @@ -490,7 +502,8 @@ class ClientController extends BaseController { return $this->asJson(json_decode($result, true)); } - public function actionCheckDetails() { + public function actionCheckDetails() + { Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; $request = Yii::$app->request->getRawBody(); @@ -532,8 +545,12 @@ class ClientController extends BaseController { $payment = []; foreach (explode(',', $check->pay_arr ?? '') as $pay_type) { switch ($pay_type) { - case 1: $payment [] = ['type' => 'cash']; break; - case 2: $payment [] = ['type' => 'card']; break; + case 1: + $payment [] = ['type' => 'cash']; + break; + case 2: + $payment [] = ['type' => 'card']; + break; } } $products = []; @@ -561,7 +578,8 @@ class ClientController extends BaseController { return $this->asJson(['response' => ['checks' => $checkResults, 'pages' => ['totalCount' => +$pages->totalCount, 'page' => $pages->page, 'per-page' => $pages->pageSize]]]); } - public function actionCheckDetail() { + public function actionCheckDetail() + { Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; $request = Yii::$app->request->getRawBody(); @@ -600,8 +618,12 @@ class ClientController extends BaseController { $payment = []; foreach (explode(',', $check->pay_arr ?? '') as $pay_type) { switch ($pay_type) { - case 1: $payment [] = ['type' => 'cash']; break; - case 2: $payment [] = ['type' => 'card']; break; + case 1: + $payment [] = ['type' => 'cash']; + break; + case 2: + $payment [] = ['type' => 'card']; + break; } } @@ -628,7 +650,8 @@ class ClientController extends BaseController { return $this->asJson(['response' => $checkResult]); } - public function actionBonusWriteOff() { + public function actionBonusWriteOff() + { Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; $request = Yii::$app->request->getRawBody(); @@ -672,7 +695,191 @@ class ClientController extends BaseController { ]]); } - public function actionMemorableDates() { + public function actionUseBonuses() + { + Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; + + $clientId = Yii::$app->request->getQueryParam('client_id'); + $orderId = Yii::$app->request->getQueryParam('order_id'); + $clientPhone = Yii::$app->request->getQueryParam('client_phone'); + $pointsToAdd = Yii::$app->request->getQueryParam('points_to_add'); + $comment = Yii::$app->request->getQueryParam('comment'); + + $sale = Sales::findOne(['number' => $orderId]); + + if (!$sale) { + return $this->asJson(['error' => ['code' => 404, 'message' => 'Продажа не найдена']]); + } + + $bonusAmount = $pointsToAdd !== null ? (int)$pointsToAdd : floor($sale->summ * 0.1); + + $userBonus = new UsersBonus(); + $userBonus->phone = strval($sale->phone); + $userBonus->name = $comment ?: ("Возврат с покупки 10%. Чек " . $sale->number . " от " . + date("d.m.Y H:i:s", strtotime($sale->date)) . ". Сумма чека " . $sale->summ); + $userBonus->date = date('Y-m-d H:i:s'); + $userBonus->site_id = 1; + $userBonus->setka_id = 1; + $userBonus->tip = 'plus'; + $userBonus->tip_sale = 'sale'; + $userBonus->check_id = $sale->id; + $userBonus->price = $sale->summ; + $userBonus->admin_id = Yii::$app->user->id ?? null; + $userBonus->store_id = $sale->store_id; + $userBonus->bonus = $bonusAmount; + $userBonus->date_start = $sale->date; + $userBonus->date_end = date('Y-m-d H:i:s', strtotime('+365 day', strtotime($userBonus->date))); + + try { + if (!$userBonus->save()) { + return $this->asJson(['error' => ['code' => 400, 'message' => 'Ошибка валидации', 'details' => $userBonus->getErrors()]]); + } + } catch (\Exception $ex) { + return $this->asJson(['error' => ['code' => 500, 'message' => 'Ошибка при сохранении бонуса: ' . $ex->getMessage()]]); + } + + $totalBonus = UsersBonus::find() + ->select([ + new \yii\db\Expression("SUM(CASE WHEN tip = 'plus' THEN bonus ELSE 0 END) - SUM(CASE WHEN tip = 'minus' THEN bonus ELSE 0 END) AS total") + ]) + ->where(['phone' => $clientPhone]) + ->scalar(); + + return $this->asJson([ + 'response' => [ + 'code' => 200, + 'status' => 'success', + 'data' => [ + 'client_id' => $clientId, + 'order_id' => $orderId, + 'addedPoints' => $bonusAmount, + 'totalPoints' => (int)$totalBonus, + ] + ] + ]); + } + + public function actionAddBonus() + { + Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; + + $clientId = Yii::$app->request->getQueryParam('client_id'); + $orderId = Yii::$app->request->getQueryParam('order_id'); + $clientPhone = Yii::$app->request->getQueryParam('client_phone'); + $pointsToAdd = Yii::$app->request->getQueryParam('points_to_add'); + $comment = Yii::$app->request->getQueryParam('comment'); + + $sale = Sales::findOne(['number' => $orderId]); + + if (!$sale) { + return $this->asJson(['error' => ['code' => 404, 'message' => 'Продажа не найдена']]); + } + + $bonusAmount = $pointsToAdd !== null ? (int)$pointsToAdd : floor($sale->summ * 0.1); + + $userBonus = new UsersBonus(); + $userBonus->phone = strval($sale->phone); + $userBonus->name = $comment ?: ("Возврат с покупки 10%. Чек " . $sale->number . " от " . + date("d.m.Y H:i:s", strtotime($sale->date)) . ". Сумма чека " . $sale->summ); + $userBonus->date = date('Y-m-d H:i:s'); + $userBonus->site_id = 1; + $userBonus->setka_id = 1; + $userBonus->tip = 'plus'; + $userBonus->tip_sale = 'sale'; + $userBonus->check_id = $sale->id; + $userBonus->price = $sale->summ; + $userBonus->admin_id = Yii::$app->user->id ?? null; + $userBonus->store_id = $sale->store_id; + $userBonus->bonus = $bonusAmount; + $userBonus->date_start = $sale->date; + $userBonus->date_end = date('Y-m-d H:i:s', strtotime('+365 day', strtotime($userBonus->date))); + + try { + if (!$userBonus->save()) { + return $this->asJson(['error' => ['code' => 400, 'message' => 'Ошибка валидации', 'details' => $userBonus->getErrors()]]); + } + } catch (\Exception $ex) { + return $this->asJson(['error' => ['code' => 500, 'message' => 'Ошибка при сохранении бонуса: ' . $ex->getMessage()]]); + } + + $totalBonus = UsersBonus::find() + ->select([ + new \yii\db\Expression("SUM(CASE WHEN tip = 'plus' THEN bonus ELSE 0 END) - SUM(CASE WHEN tip = 'minus' THEN bonus ELSE 0 END) AS total") + ]) + ->where(['phone' => $clientPhone]) + ->scalar(); + + return $this->asJson([ + 'response' => [ + 'code' => 200, + 'status' => 'success', + 'data' => [ + 'client_id' => $clientId, + 'order_id' => $orderId, + 'addedPoints' => $bonusAmount, + 'totalPoints' => (int)$totalBonus, + ] + ] + ]); + } + + public function actionBonusStatus() + { + Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; + + $data = json_decode(Yii::$app->request->getRawBody(), true); + $clientId = $data['client_id'] ?? null; + $phone = $data['phone'] ?? null; + + if (empty($clientId) || empty($phone)) { + return $this->asJson(['error' => ['code' => 400, 'message' => 'Uncorrect params']]); + } + + $user = UsersBonus::find() + ->andFilterWhere(['id' => $clientId]) + ->andFilterWhere(['phone' => $phone]) + ->one(); + + if (!$user) { + return $this->asJson(['error' => ['code' => 404, 'message' => 'User not found']]); + } + + $bonusLevel = UsersBonusLevels::find() + ->alias('ubl') + ->select([ + 'bl.name as bonus_level', + 'bl.bonus_rate as discount_percent', + 'bl.current_points', + 'bl.id as level_id' + ]) + ->leftJoin('bonus_levels bl', 'bl.alias = ubl.bonus_level AND bl.active = 1') + ->where(['ubl.user_id' => $clientId, 'ubl.phone' => $phone, 'ubl.active' => 1]) + ->asArray() + ->one(); + + if (!$bonusLevel) { + return $this->asJson(['error' => ['code' => 404, 'message' => 'Bonus level not found']]); + } + + $nextLevel = BonusLevels::find() + ->select(['current_points as next_points']) + ->where(['id' => $bonusLevel['level_id'] + 1, 'active' => 1]) + ->asArray() + ->one(); + + $data = [ + 'client_id' => $clientId, + 'bonus_level' => $bonusLevel['bonus_level'], + 'current_points' => $bonusLevel['current_points'], + 'next_points' => $nextLevel['next_points'] ?? null, + 'discount_percent' => $bonusLevel['discount_percent'], + ]; + + return $this->asJson(['response' => $data]); + } + + public function actionMemorableDates() + { Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; $request = Yii::$app->request->getRawBody(); @@ -704,7 +911,8 @@ class ClientController extends BaseController { return $this->asJson(['response' => $userEvents]); } - public function actionSocialIds() { + public function actionSocialIds() + { Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; $request = Yii::$app->request->getRawBody(); @@ -735,7 +943,8 @@ class ClientController extends BaseController { return $this->asJson(['response' => $response]); } - private function listEvents($phone) { + private function listEvents($phone) + { $events = []; $data = UsersEvents::find()->where(['phone' => $phone])->orderBy(['date' => SORT_DESC])->all(); foreach ($data as $row) { @@ -746,12 +955,24 @@ class ClientController extends BaseController { $row->date_month = "0" . $row->date_month; } switch ($row->tip_id) { - case 1: $tip = "День рождения"; break; - case 2: $tip = "8 марта"; break; - case 3: $tip = "День матери"; break; - case 4: $tip = "День влюбленных"; break; - case 5: $tip = "День свадьбы"; break; - default: $tip = empty($row->tip) ? "Другое" : $row->tip; break; + case 1: + $tip = "День рождения"; + break; + case 2: + $tip = "8 марта"; + break; + case 3: + $tip = "День матери"; + break; + case 4: + $tip = "День влюбленных"; + break; + case 5: + $tip = "День свадьбы"; + break; + default: + $tip = empty($row->tip) ? "Другое" : $row->tip; + break; } $events[] = ["date" => $row->date, "event_id" => $row->tip_id, 'event_tip' => $tip, 'number' => $row->number]; } @@ -861,7 +1082,8 @@ class ClientController extends BaseController { // } // return $this->asJson(['response' => $result]); // } - public function actionGetStores() { + public function actionGetStores() + { $stores = CityStore::find()->all(); $result = []; foreach ($stores as $store) { @@ -872,7 +1094,8 @@ class ClientController extends BaseController { return $this->asJson(['response' => $result]); } - public function actionPhoneKeycodeByCard() { + public function actionPhoneKeycodeByCard() + { Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; $request = Yii::$app->request->rawBody; @@ -900,7 +1123,8 @@ class ClientController extends BaseController { return $this->asJson(['error' => 'Номер карты не найден']); } - public function actionGetUserInfo() { + public function actionGetUserInfo() + { Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; $request = Yii::$app->request->rawBody; @@ -944,7 +1168,7 @@ class ClientController extends BaseController { $mess['sale_cnt'] = $user->sale_cnt; // Продажи, шт.; $mess['total_price_rejected'] = (int)$sales_rejected_sum; // Выручка отмененных заявок $mess["events"] = $this->listEvents($phone); - $mess["platform"] = ["telegram" => ["is_subscribed" => $user->telegram_is_subscribed, "created_at" => $user->telegram_created_at ]]; + $mess["platform"] = ["telegram" => ["is_subscribed" => $user->telegram_is_subscribed, "created_at" => $user->telegram_created_at]]; return $this->asJson(['response' => $mess]); } @@ -952,7 +1176,8 @@ class ClientController extends BaseController { return $this->asJson(['error' => 'клиент не найден']); } - public function actionChangeUserSubscription() { + public function actionChangeUserSubscription() + { Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; $request = Yii::$app->request->rawBody; @@ -1003,7 +1228,8 @@ class ClientController extends BaseController { return $this->asJson(['response' => true]); } - public function actionNewsLetter() { + public function actionNewsLetter() + { $sales = Sales::find()->joinWith(['users'])->where(['source' => '0'])->andWhere(['!=', 'phone', '']) ->andWhere(['>=', 'date', date('Y-m-d H:i:s', strtotime('-5 minute', time()))]) ->all(); @@ -1104,14 +1330,15 @@ class ClientController extends BaseController { /* $isDelivered ? запись результатов попытки в news_letter_delivery_status:status = 1 */ /* !$isDelivered ? запись результатов попытки в news_letter_delivery_status:status = -1 */ - $newLetterDeliveryStatus->status = $isDelivered ? 1 : -1 ; + $newLetterDeliveryStatus->status = $isDelivered ? 1 : -1; $newLetterDeliveryStatus->save(); } } } - public function actionApplyPromoCode() { + public function actionApplyPromoCode() + { Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; $request = Yii::$app->request->getRawBody(); diff --git a/erp24/config/env.php b/erp24/config/env.php index cd418591..d54d378f 100644 --- a/erp24/config/env.php +++ b/erp24/config/env.php @@ -6,7 +6,11 @@ try { $dotenv->required(['APP_ENV']); foreach ($_ENV as $key => $value) { - putenv("$key=$value"); + if (is_scalar($value)) { + putenv("$key=$value"); + } else { + Yii::warning("Переменная окружения $key имеет нескалярное значение и не может быть установлена через putenv"); + } } } catch (\Dotenv\Exception\InvalidPathException $e) { putenv("APP_ENV=development"); -- 2.39.5