-<?php\r
-\r
-namespace app\controllers;\r
-\r
-use yii_app\jobs\SendBonusInfoToSiteJob;\r
-use DateTime;\r
-use DateTimeZone;\r
-use Yii;\r
-use yii\helpers\ArrayHelper;\r
-use yii\helpers\Json;\r
-use yii_app\helpers\ClientHelper;\r
-use yii_app\records\BonusLevels;\r
-use yii_app\records\Contest001;\r
-use yii_app\records\ExportImportTable;\r
-use yii_app\records\MessagerUser;\r
-use yii_app\records\NotifiableUser;\r
-use yii_app\records\Products1c;\r
-use yii_app\records\Sales;\r
-use yii_app\records\Timetable;\r
-use yii_app\records\UniversalCatalogItem;\r
-use yii_app\records\UserBonusSendToTgLogs;\r
-use yii_app\records\Users;\r
-use yii_app\records\UsersAuthCallLog;\r
-use yii_app\records\UsersBonus;\r
-use yii_app\records\UsersBonusLevels;\r
-use yii_app\records\UsersEvents;\r
-use yii_app\records\UsersPhones;\r
-use yii_app\records\UsersStopList;\r
-use yii_app\records\Promocode;\r
-use yii_app\services\LogService;\r
-use yii_app\services\SiteService;\r
-\r
-class BonusController extends BaseController\r
-{\r
- private const LOG_CATEGORY_BONUS = 'bonus.auth';\r
-\r
- private static $YEAR_PERIOD = 366;\r
- private static $FIRST_SALE_PROCENT = 0.1;\r
- private static $SECOND_SALE_PROCENT = 0.15;\r
- private static $MAX_PROCENT = 0.2;\r
- private static $CREDIT_PROCENT = 0.1;\r
- private static $CREDIT_HIGH_PROCENT = 0.3;\r
- private static $CREDIT_HIGH_PROCENT_PART20 = 0.2;\r
-\r
- const OUT_DIR =\r
-// "/tmp";\r
- "/var/www/erp24/api2/json"; // "/www/api2/json";\r
-// __DIR__ . "/../json"; //local\r
-\r
- public function actionGetBonuses()\r
- {\r
- Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;\r
- $data = file_get_contents('php://input');\r
- $result = json_decode($data, true);\r
-\r
- $fl = date('_Y_m_d__H_i_s_');\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . $result['phone']);\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
-\r
- $__API_PARAMS = ['store_id', 'seller_id', 'phone']; // check_amount, items\r
-\r
- foreach ($__API_PARAMS as $paramName) {\r
- if (empty($result[$paramName])) {\r
-\r
- if ($paramName != 'phone') {\r
- LogService::apiErrorLog(json_encode(["error_id" => 0, "error" => "$paramName is required"], JSON_UNESCAPED_UNICODE));\r
- }\r
-\r
- return $this->asJson(["error_id" => 0, "error" => "$paramName is required"]);\r
- }\r
- }\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
-\r
- $phone = ClientHelper::phoneClear($result['phone']);\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- if (!ClientHelper::phoneVerify($phone)) {\r
- return $this->asJson(["error_id" => 0.2, "error" => "phone is required"]);\r
- }\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $result['phone'] = $phone;\r
-\r
- $check_amount = intval($result['check_amount'] ?? 0);\r
-\r
- $user = Users::find()->where(['phone' => $result['phone']])->andWhere(['phone_true' => '1'])->one();\r
- $bonusLevels = BonusLevels::find()->where(['active' => 1])->indexBy('alias')->asArray()->all();\r
- $bonusLevel = $user->bonus_level ?? "silver";\r
-\r
- $bonus_rate = isset($bonusLevels[$bonusLevel]['bonus_rate'])\r
- ? $bonusLevels[$bonusLevel]['bonus_rate'] / 100\r
- : self::$FIRST_SALE_PROCENT;\r
-\r
- $cashback_rate = isset($bonusLevels[$bonusLevel]['cashback_rate'])\r
- ? $bonusLevels[$bonusLevel]['cashback_rate'] / 100\r
- : self::$FIRST_SALE_PROCENT;\r
-\r
- $mess = [];\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- // массив с id товарыми не участвующих в бонусной\r
- $items_arr_no = array_values(ArrayHelper::map(\r
- UniversalCatalogItem::find()->where(['catalog_alias' => 'unused_nomenclature'])->all(), 'guid', 'guid'));\r
- $items_arr_no_bonus_writeoffs = array_values(ArrayHelper::map(\r
- UniversalCatalogItem::find()->where(['catalog_alias' => 'non_bonusable_goods'])->all(), 'guid', 'guid'));\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
-\r
- $all_amount = 0;\r
- $has_actions = false;\r
- $summa_no = 0;\r
- $summa_no_writeoffs = 0;\r
- if (!empty($result["items"])) {\r
- foreach ($result["items"] as $item) {\r
- if (in_array($item["product_id"], $items_arr_no)) {\r
- $summa_no = $summa_no + $item["price"] * $item["quantity"];\r
- $has_actions = true;\r
- } elseif (in_array($item["product_id"], $items_arr_no_bonus_writeoffs)) {\r
- $summa_no_writeoffs = $summa_no_writeoffs + $item["price"] * $item["quantity"];\r
- }\r
- $all_amount += $item["price"] * $item["quantity"];\r
- }\r
- }\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $baza_nachislenie = $all_amount - $summa_no;\r
-\r
- $check_amount = $check_amount - $summa_no;\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- //$cnt = intval(Sales::find()->where(['phone' => $result['phone'], 'operation' => Sales::OPERATION_SALE])->count());\r
- //$max_procent = $cnt == 0 ? self::$FIRST_SALE_PROCENT : ($cnt == 1 ? self::$SECOND_SALE_PROCENT : self::$MAX_PROCENT);\r
- $max_procent = $bonus_rate;\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $percent = ($result['phone'] == "79049031399") ? 0.9 : $max_procent;\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $userFound = Users::find()->where(['phone' => $result['phone']])->one();\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- /** @var $userFound Users */\r
- $salesCount = -1; /* Из-за нулевого значения по умолчанию куча клиентов получило бонус 20% за покупку */\r
- if ($userFound && $userFound->telegram_created_at) {\r
- $salesCount = intval(Sales::find()->where(['phone' => $result['phone'], 'operation' => Sales::OPERATION_SALE])\r
- ->andWhere(['>=', 'date', $userFound->telegram_created_at])->count());\r
- }\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $credit_procent = $userFound && $userFound->source > 0 && $salesCount == 0 ? self::$CREDIT_HIGH_PROCENT : $cashback_rate;\r
- $will_be_credited_bonuses = $credit_procent * $baza_nachislenie;\r
-\r
- $will_be_credited_bonuses = round($will_be_credited_bonuses);\r
- $mess["will_be_credited_bonuses"] = $will_be_credited_bonuses;\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $store_id = ClientHelper::getExportId($result['store_id'], "city_store", 1);\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- // Логи введённых номеров телефонов кассирами\r
- $userPhone = UsersPhones::find()->where(['phone' => $result['phone']])->andWhere(['store_id' => $store_id])\r
- ->andWhere(['seller_id' => $result['seller_id']])->one();\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- if (!$userPhone) {\r
- $userPhone = new UsersPhones();\r
- $userPhone->phone = $result['phone'];\r
- $userPhone->store_id = $store_id;\r
- $userPhone->store_guid = $result['store_id'];\r
- $userPhone->seller_id = $result['seller_id'];\r
- }\r
- if (!$userPhone->store_guid) {\r
- $userPhone->store_guid = $result['store_id'];\r
- }\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $userPhone->date = date('Y-m-d H:i:s');\r
- $userPhone->save();\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- if ($userPhone->getErrors()) {\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- LogService::apiErrorLog(json_encode(["error_id" => 1, "error" => $userPhone->getErrors()], JSON_UNESCAPED_UNICODE));\r
-\r
- return $this->asJson(["error_id" => 1, "error" => $userPhone->getErrors()]);\r
- }\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $user = Users::find()->where(['phone' => $result['phone']])->andWhere(['phone_true' => '1'])->one();\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- if (!$user) {\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '-нет в бонусной программе-' . __LINE__, FILE_APPEND);\r
- $mess["new_client"] = true;\r
- $mess["message_cashier"] = "Заполните данные клиента";\r
- $mess["error"] = "Покупателя " . $result['phone'] . " нет в бонусной программе!";\r
-\r
- return $this->asJson($mess);\r
- }\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $keycode = $user->keycode;\r
- $black_list = $user->black_list;\r
-\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- if (!$black_list) {\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $stop = UsersStopList::find()->select(['phone'])->where(['phone' => $result['phone']])->one();\r
- if ($stop) {\r
- $black_list = 1;\r
- $user->black_list = 1;\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $user->save();\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- if ($user->getErrors()) {\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- LogService::apiErrorLog(json_encode(["error_id" => 3, "error" => $user->getErrors()], JSON_UNESCAPED_UNICODE));\r
-\r
- return $this->asJson(["error_id" => 3, "error" => $user->getErrors()]);\r
- }\r
- }\r
- }\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $name = $user->name;\r
- $user_balans = ClientHelper::getBonusBalance($result['phone']);\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $baza_spisanie = $baza_nachislenie - $summa_no_writeoffs;\r
- if ($baza_spisanie < 0) {\r
- $baza_spisanie = 0;\r
- }\r
- $max = $baza_spisanie * $percent; // максимально можем разрешить списывать до 30 процентов от суммы заказа\r
- $max = round($max);\r
- $available_bonus = $user_balans;\r
- if ($available_bonus > $max) { // если баллов бонусов больше чем 30 процентов списываем по максимуму 30\r
- $available_bonus = $max;\r
- }\r
-// $baza = $check_amount - $bonus;\r
-\r
- $mess["message_cashier"] = "Клиент $name найден"; // Код: $keycode\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- if ($black_list) {\r
- $mess['error'] = 'Этот номер в черном списке';\r
-\r
- return $this->asJson($mess);\r
- }\r
-\r
- $txt = $has_actions ? 'В чеке есть акционные товары, на них бонусы не начислятся.' : '';\r
-\r
- $mess["result"] = true;\r
- $mess["auth_code"] = $keycode;\r
- $mess["name"] = $name;\r
- $mess["total_bonuses"] = $user_balans;\r
- $mess["bonus_level"] = $bonusLevel;\r
- $mess["burn_balans"] = $user->burn_balans;\r
- $mess["available_bonuses"] = $available_bonus;\r
- $mess["message_cashier"] = $txt . " Спросите последние 4 цифры телефона который позвонит клиенту $user_balans";\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- LogService::apiLogs(1, json_encode($mess, JSON_UNESCAPED_UNICODE));\r
-\r
- file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__ . ' OK ', FILE_APPEND);\r
- return $this->asJson($mess);\r
- }\r
-\r
-// public function actionSendMessage()\r
-// {\r
-// Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;\r
-// $data = file_get_contents('php://input');\r
-// $result = json_decode($data, true);\r
-//\r
-// $__API_PARAMS = ['store_id', 'seller_id', 'phone'];\r
-//\r
-// foreach ($__API_PARAMS as $paramName) {\r
-// if (empty($result[$paramName])) {\r
-//\r
-// if ($paramName != 'phone') {\r
-// LogService::apiErrorLog(json_encode(["error_id" => 1, "error" => "$paramName is required"], JSON_UNESCAPED_UNICODE));\r
-// }\r
-//\r
-// return $this->asJson(["error" => "$paramName is required"]);\r
-// }\r
-// }\r
-//\r
-// $phone = ClientHelper::phoneClear($result['phone']);\r
-// if (!ClientHelper::phoneVerify($phone)) {\r
-// return $this->asJson(["error_id" => 0.2, "error" => "phone is required"]);\r
-// }\r
-// $result['phone'] = $phone;\r
-//\r
-// $user = Users::find()->where(['phone' => $result['phone']])->andWhere(['phone_true' => '1'])->andWhere(['black_list' => '0'])->one();\r
-// if (!$user) {\r
-// $mess["error"] = "Покупателя " . $result['phone'] . " нет в бонусной программе!";\r
-//\r
-// return $this->asJson($mess);\r
-// }\r
-// $keycode = $user->keycode;\r
-//\r
-// $mess = [];\r
-// $mess["result"] = true;\r
-//\r
-// $mess['auth_code'] = $user->keycode;\r
-// $mess['message_cashier'] = 'Отсканируйте QR код из телеграм бота или введите его руками';\r
-//\r
-// LogService::apiLogs(1, json_encode($mess, JSON_UNESCAPED_UNICODE));\r
-//\r
-// return $this->asJson($mess);\r
-// }\r
-\r
- public function actionSendMessage() {\r
- Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;\r
- $data = file_get_contents('php://input');\r
- $result = json_decode($data, true);\r
-\r
- $__API_PARAMS = ['store_id', 'seller_id', 'phone'];\r
-\r
- foreach ($__API_PARAMS as $paramName) {\r
- if (empty($result[$paramName])) {\r
-\r
- if ($paramName != 'phone') {\r
- LogService::apiErrorLog(json_encode(["error_id" => 1, "error" => "$paramName is required"], JSON_UNESCAPED_UNICODE));\r
- }\r
-\r
- return $this->asJson(["error" => "$paramName is required"]);\r
- }\r
- }\r
-\r
- $phone = ClientHelper::phoneClear($result['phone']);\r
- if (!ClientHelper::phoneVerify($phone)) {\r
- return $this->asJson(["error_id" => 0.2, "error" => "phone is required"]);\r
- }\r
- $result['phone'] = $phone;\r
-\r
- $user = Users::find()->where(['phone' => $result['phone']])->andWhere(['phone_true' => '1'])->andWhere(['black_list' => '0'])->one();\r
- if (!$user) {\r
- $mess["error"] = "Покупателя " . $result['phone'] . " нет в бонусной программе!";\r
-\r
- return $this->asJson($mess);\r
- }\r
-\r
- $mess["message_cashier"] = "Звонок-последние 4 цифры телефона";\r
-\r
- $userAuthCallLog = UsersAuthCallLog::find()->select(['COUNT(*) as cnt'])->where(['phone' => $result['phone']])\r
- ->andWhere(['store_id' => $result['store_id']])->andWhere(['>=', 'date', date('Y-m-d H:i:s', strtotime('-10 minutes'))])->one();\r
-\r
- $cnt = $userAuthCallLog ? $userAuthCallLog->cnt : 1;\r
-\r
- $keycode = '';\r
-\r
- if ($cnt < 2) {\r
- $body = @file_get_contents("https://sms.ru/code/call?phone=" . $result['phone'] . "&api_id=4DFE45F9-1897-79C0-6872-08F05D6B7FA4&ip=" . $_SERVER["REMOTE_ADDR"]);\r
- $json_res = json_decode($body, true, 512, JSON_UNESCAPED_UNICODE);\r
- if ($json_res["status"] == "OK") {\r
- $keycode = $json_res["code"];\r
- $user->keycode = '' . $keycode;\r
- $user->password = ClientHelper::generatePassword(8);;\r
- $user->save();\r
- if ($user->getErrors()) {\r
- LogService::apiErrorLog(json_encode(["error_id" => 3.1415, "error" => $user->getErrors()], JSON_UNESCAPED_UNICODE));\r
- return $this->asJson(["error_id" => 3.1415, "error" => $user->getErrors()]);\r
- }\r
- $mess["auth_code"] = $keycode;\r
- $mess["message_cashier"] = "Попытка:$cnt Звонок клиенту! последние 4 цифры номера";\r
- }\r
- } elseif ($cnt > 2) {\r
- $mess["message_cashier"] = "Попытка $cnt -извиняемся перед клиентом";\r
- }\r
- $name = "$keycode Попытка $cnt " . $_SERVER["REMOTE_ADDR"];\r
- $userAuthCallLog = new UsersAuthCallLog;\r
- $userAuthCallLog->date = date('Y-m-d H:i:s');\r
- $userAuthCallLog->store_id = $result['store_id'];\r
- $userAuthCallLog->seller_id = $result['seller_id'];\r
- $userAuthCallLog->phone = $result['phone'];\r
- $userAuthCallLog->name = $name;\r
- $userAuthCallLog->save();\r
- if ($userAuthCallLog->getErrors()) {\r
- LogService::apiErrorLog(json_encode(["error_id" => 4.15, "error" => $userAuthCallLog->getErrors()], JSON_UNESCAPED_UNICODE));\r
- return $this->asJson(["error_id" => 4.15, "error" => $userAuthCallLog->getErrors()]);\r
- }\r
-\r
- Yii::info("keykod={$user->keycode} store_id={$result['store_id']} seller_id={$result['seller_id']} phone={$result['phone']} $name", self::LOG_CATEGORY_BONUS);\r
-\r
- $mess["timeout"] = 15;\r
-\r
- LogService::apiLogs(1, json_encode($mess, JSON_UNESCAPED_UNICODE));\r
-\r
- return $this->asJson($mess);\r
- }\r
-\r
-// $mess["message_cashier"] = "Звонок-последние 4 цифры телефона";\r
-//\r
-// $userAuthCallLog = UsersAuthCallLog::find()->select(['COUNT(*) as cnt'])->where(['phone' => $result['phone']])\r
-// ->andWhere(['store_id' => $result['store_id']])->andWhere(['>=', 'date', date('Y-m-d H:i:s', strtotime('-10 minutes'))])->one();\r
-//\r
-// $cnt = $userAuthCallLog ? $userAuthCallLog->cnt : 1;\r
-//\r
-// if ($cnt < 2) {\r
-// $body = @file_get_contents("https://sms.ru/code/call?phone=" . $result['phone'] . "&api_id=4DFE45F9-1897-79C0-6872-08F05D6B7FA4&ip=" . $_SERVER["REMOTE_ADDR"]);\r
-// $json_res = json_decode($body, true, 512, JSON_UNESCAPED_UNICODE);\r
-//\r
-// if ($json_res["status"] == "OK") {\r
-// $keycode = $json_res["code"];\r
-// $user->keycode = '' . $keycode;\r
-// $user->password = ClientHelper::generatePassword(8);;\r
-// $user->save();\r
-//\r
-// if ($user->getErrors()) {\r
-//\r
-// LogService::apiErrorLog(json_encode(["error_id" => 3, "error" => $user->getErrors()], JSON_UNESCAPED_UNICODE));\r
-//\r
-// return $this->asJson(["error_id" => 3, "error" => $user->getErrors()]);\r
-// }\r
-//\r
-// $mess["auth_code"] = $keycode;\r
-// $mess["message_cashier"] = "Попытка:$cnt Звонок клиенту! последние 4 цифры номера";\r
-// }\r
-// } else if ($cnt > 2) {\r
-// $mess["message_cashier"] = "Попытка $cnt -извиняемся перед клиентом";\r
-// }\r
-//\r
-// $name = "$keycode Попытка $cnt " . $_SERVER["REMOTE_ADDR"];\r
-// $userAuthCallLog = new UsersAuthCallLog;\r
-// $userAuthCallLog->date = date('Y-m-d H:i:s');\r
-// $userAuthCallLog->store_id = $result['store_id'];\r
-// $userAuthCallLog->seller_id = $result['seller_id'];\r
-// $userAuthCallLog->phone = $result['phone'];\r
-// $userAuthCallLog->name = $name;\r
-// $userAuthCallLog->save();\r
-// if ($userAuthCallLog->getErrors()) {\r
-//\r
-// LogService::apiErrorLog(json_encode(["error_id" => 4, "error" => $userAuthCallLog->getErrors()], JSON_UNESCAPED_UNICODE));\r
-//\r
-// return $this->asJson(["error_id" => 4, "error" => $userAuthCallLog->getErrors()]);\r
-// }\r
-//\r
-\r
- public function actionSaveClientInfo()\r
- {\r
- Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;\r
- $data = file_get_contents('php://input');\r
- $result = json_decode($data, true);\r
-\r
- $fl = date('_Y_m_d__H_i_s_');\r
- file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . $result['phone']);\r
- file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
-\r
-\r
- $__API_PARAMS = ['store_id', 'seller_id', 'phone']; // first_name, second_name, sex, birth_day, referral_id, comment, events\r
-\r
- foreach ($__API_PARAMS as $paramName) {\r
- if (empty($result[$paramName])) {\r
-\r
- if ($paramName != 'phone') {\r
- LogService::apiErrorLog(json_encode(["error_id" => 1, "error" => "$paramName is required"], JSON_UNESCAPED_UNICODE));\r
- }\r
-\r
- return $this->asJson(["error_id" => 1, "error" => "$paramName is required"]);\r
- }\r
- }\r
- file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $phone = ClientHelper::phoneClear($result['phone']);\r
- file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- if (!ClientHelper::phoneVerify($phone)) {\r
- file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- return $this->asJson(["error_id" => 1.2, "error" => "phone is required"]);\r
- }\r
- $result['phone'] = $phone;\r
-\r
- $source = $result["source"] ?? 0;\r
- $store_id = $result["store_id"];\r
- $store_id_guid = $store_id;\r
- $seller_id = $result["seller_id"];\r
- $phone = $result["phone"];\r
- $first_name = $result["first_name"] ?? "";\r
- $second_name = $result["second_name"] ?? "";\r
- $sex2 = $result["sex"] ?? "";\r
- $birth_day = $result["birth_day"] ?? "";\r
- $referral_id = $result["referral_id"] ?? null;\r
- $comment = $result["comment"] ?? "";\r
- $events = $result["events"] ?? [];\r
- $sex = "man";\r
- if ($sex2 == "male") {\r
- $sex = "man";\r
- }\r
- if ($sex2 == "female") {\r
- $sex = "women";\r
- }\r
-// if ($referral_phone == $phone) {\r
-// $referral_phone = "";\r
-// }\r
-\r
- $mess = [];\r
- file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- /* @var $user Users */\r
- $user = Users::find()->where(['phone' => $result['phone']])->andWhere(['phone_true' => '1'])->andWhere(['black_list' => '0'])->one();\r
- file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- if ($user) {\r
- file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $user->referral_id = $referral_id != $user->id ? $referral_id : null;\r
- $user->pol = $sex;\r
- $user->bdate = $birth_day;\r
- $user->name = "$first_name $second_name";\r
- $user->comment = $comment;\r
- $user->password = ClientHelper::generatePassword(8);\r
- $user->keycode = '' . rand(1000, 9999);\r
- $user->source = $source == 2 ? 1 : 0;\r
- $user->save(); // иначе не пройдём валидацию, т.к. множество полей в бд не заполнены.\r
- file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- if ($user->getErrors()) {\r
- file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
-\r
- LogService::apiErrorLog(json_encode(["error_id" => 2, "error" => $user->getErrors()], JSON_UNESCAPED_UNICODE));\r
-\r
- return $this->asJson(["error_id" => 2, "error" => $user->getErrors()]);\r
- }\r
- file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $userEventOld = UsersEvents::find()->where(['phone' => $phone])->orderBy(['date_add' => SORT_ASC])->one();\r
- if ($userEventOld && $userEventOld->date_add < date('Y-m-d H:i:s', time() - 2 * 86400)) { // Дата добавление последнего события не старше двух дней\r
- file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $mess["result"] = true;\r
- $mess["message_cashier"] = "Возможность внесения памятных дат ограничена";\r
-\r
- LogService::apiLogs(1, json_encode($mess, JSON_UNESCAPED_UNICODE));\r
-\r
- return $this->asJson($mess);\r
- }\r
- file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
-\r
- $nomer_event = 1;\r
- $dates = [];\r
-\r
- foreach ($events as $k => $mass) {\r
- $date = $mass["date"] ?? '';\r
- $event_id = intval($mass['event_id'] ?? 0);\r
-\r
- $datea = explode("-", $date);\r
- $date_end = date("Y", time() + self::$YEAR_PERIOD * 86400) . "-" . $datea[1] . "-" . $datea[2];\r
- $userEvent2 = UsersEvents::find()->where(['phone' => $phone])->andWhere(['date_day' => $datea[2]])->andWhere(['date_month' => $datea[1]])->one();\r
- file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- if ($userEvent2) {\r
- $userEvent2->delete();\r
- }\r
- $userEvent3 = new UsersEvents;\r
- $userEvent3->number = $nomer_event;\r
- $userEvent3->date = $date;\r
- $userEvent3->tip_id = $event_id;\r
- $userEvent3->phone = $phone;\r
- $userEvent3->date_day = $datea[2];\r
- $userEvent3->date_month = $datea[1];\r
- $userEvent3->date_add = date('Y-m-d H:i:s');\r
- $userEvent3->tip = strval('???');\r
- $userEvent3->name = 'М';\r
- $userEvent3->sex = 'm';\r
- $userEvent3->date_edit = date("Y-m-d H:i:s");\r
- $userEvent3->date_edit_info = date("Y-m-d H:i:s");\r
- file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $userEvent3->save(); // иначе не пройдём валидацию, т.к. множество полей в бд не заполнены.\r
- if ($userEvent3->getErrors()) {\r
- file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
-\r
- LogService::apiErrorLog(json_encode(["error_id" => 3, "error" => $userEvent3->getErrors()], JSON_UNESCAPED_UNICODE));\r
-\r
- return $this->asJson(["error_id" => 3, "error" => $userEvent3->getErrors()]);\r
- }\r
- $dates [] = $date;\r
- $nomer_event++;\r
- }\r
- } else {\r
- file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $created_name = $seller_id;\r
- $rand = rand(1000, 9999);\r
- $name = "$first_name $second_name";\r
- $pass = ClientHelper::generatePassword(8);\r
- $product1 = Products1c::find()->select(['name'])->where(['tip' => 'admin'])->andWhere(['id' => $seller_id])->one();\r
- $product2 = Products1c::find()->select(['name'])->where(['tip' => 'city_store'])->andWhere(['id' => $store_id])->one();\r
-\r
- $created_name = $product1 ? $product1->name : '';\r
- $created_store = $product2 ? $product2->name : '';\r
-\r
- $store_id_new = ExportImportTable::find()->select(['entity_id'])->where(['entity' => 'city_store'])->andWhere(['export_id' => '1'])\r
- ->andWhere(['export_val' => $store_id])->one();\r
- $seller_id_new = ExportImportTable::find()->select(['entity_id'])->where(['entity' => 'admin'])->andWhere(['export_id' => '1'])\r
- ->andWhere(['export_val' => $seller_id])->one();\r
- if ($store_id_new) {\r
- $store_id_int = $store_id_new->entity_id;\r
- }\r
- if ($seller_id_new) {\r
- $seller_id_int = $seller_id_new->entity_id;\r
- }\r
- file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- Users::deleteAll(['phone' => $phone, 'phone_true' => '0']);\r
- file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $user2 = new Users;\r
- $user2->source = $source;\r
- $user2->pol = $sex;\r
- $user2->keycode = strval($rand);\r
- $user2->phone = $phone;\r
- $user2->name = $name;\r
- $user2->name_name = $first_name;\r
- $user2->name_last = $second_name;\r
- $user2->password = $pass;\r
- $user2->phone_true = strval(1);\r
- $user2->bdate = $birth_day;\r
- $user2->referral_id = $referral_id;\r
- $user2->comment = $comment;\r
- $user2->created_id = $seller_id_int ?? 0;\r
- $user2->created_name = $created_name;\r
- $user2->seller_id = strval($seller_id);\r
- $user2->store_id = $store_id_guid;\r
- $user2->created_store_id = $store_id_int ?? 0;\r
- $user2->created_store = $created_store;\r
- $user2->date = date('Y-m-d H:i:s');\r
- $user2->sale_store_id = $store_id_int ?? 0;\r
- $user2->sale_store = '';\r
- $user2->sms_info = 1;\r
- $user2->reklama_info = 1;\r
- $user2->info = '';\r
- $setka_id = 1;\r
- $user2->setka_id = $setka_id;\r
- $user2->card = "" . ($phone * 2 + 1608 + $setka_id); // генерируем номер карты который зависит от номера сетки + ДР Тимура\r
- $user2->save(); // иначе не пройдём валидацию, т.к. множество полей в бд не заполнены.\r
- file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- if ($user2->getErrors()) {\r
- file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
-\r
- LogService::apiErrorLog(json_encode(["error_id" => 4, "error" => $user2->getErrors()], JSON_UNESCAPED_UNICODE));\r
-\r
- return $this->asJson(["error_id" => 4, "error" => $user2->getErrors()]);\r
- }\r
-\r
- file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- if ($store_id == '56524cb1-4763-11ea-8cce-b42e991aff6c') {\r
- file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $admin_id = ClientHelper::getExportId($seller_id, "admin", 1);\r
-\r
- $usersBonus = new UsersBonus;\r
- $usersBonus->date = date('Y-m-d H:i:s');\r
- $usersBonus->tip = 'plus';\r
- $usersBonus->tip_sale = 'podarok';\r
- $usersBonus->phone = $phone;\r
- $usersBonus->name = "Приветственные бонусы посетителю сайта";\r
- $usersBonus->store_id = $store_id_int ?? 0;\r
- $usersBonus->site_id = 0;\r
- $usersBonus->referal_id = 0;\r
- $usersBonus->admin_id = $admin_id;\r
- $usersBonus->price = 0;\r
- $usersBonus->price_skidka = 0;\r
- $usersBonus->bonus = 50;\r
- $usersBonus->store_id_1c = $store_id;\r
- $usersBonus->seller_id_1c = $seller_id;\r
- $usersBonus->date_start = date('Y-m-d 08:00:00', strtotime('+1 day', strtotime($usersBonus->date)));\r
- $usersBonus->date_end = date('Y-m-d H:i:s', strtotime('+1 week', strtotime($usersBonus->date_start)));\r
- $usersBonus->save();\r
- file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- if ($usersBonus->getErrors()) {\r
- file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- LogService::apiErrorLog(json_encode(["error_id" => 5, "error" => $usersBonus->getErrors()], JSON_UNESCAPED_UNICODE));\r
-\r
- return $this->asJson(["error_id" => 5, "error" => $usersBonus->getErrors()]);\r
- }\r
- }\r
- }\r
-\r
- $mess["result"] = true;\r
- $mess["message_cashier"] = "Данные клиента сохранены";\r
-\r
- LogService::apiLogs(1, json_encode($mess, JSON_UNESCAPED_UNICODE));\r
-\r
- file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__ . ' OK ', FILE_APPEND);\r
- return $this->asJson($mess);\r
- }\r
-\r
- public function actionSale()\r
- {\r
- Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;\r
- $data = file_get_contents('php://input');\r
- $result = json_decode($data, true);\r
- $resultTest = $result;\r
- $fl = date('_Y_m_d__H_i_s_');\r
- $json=json_encode($resultTest,JSON_UNESCAPED_UNICODE);\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '_info.json', PHP_EOL . '--' . $result['phone']);\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '_info.json', ' '.date("d.m.Y H:i:s",time()).' JSON: '.$json.' ', FILE_APPEND);\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . $result['phone']);\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
-\r
- $__API_PARAMS = ['store_id', 'seller_id', 'phone', 'check_amount', 'check_id', 'check_name']; // items, auth_code, write_off_bonuses\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- foreach ($__API_PARAMS as $paramName) {\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- if (empty($result[$paramName])) {\r
-\r
- if ($paramName != 'phone') {\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '-error-' . __LINE__, FILE_APPEND);\r
- LogService::apiErrorLog(json_encode(["error_id" => 1, "error" => "$paramName is required"], JSON_UNESCAPED_UNICODE));\r
- }\r
-\r
- return $this->asJson(["error_id" => 1, "error" => "$paramName is required"]);\r
- }\r
- }\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $phone = ClientHelper::phoneClear($result['phone']);\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- if (!ClientHelper::phoneVerify($phone)) {\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '-error-' . __LINE__, FILE_APPEND);\r
- return $this->asJson(["error_id" => 1.2, "error" => "phone is required"]);\r
- }\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $result['phone'] = $phone;\r
- $result['items'] = $result['items'] ?? [];\r
-\r
- $store_id = $result["store_id"];\r
- $seller_id = $result["seller_id"];\r
- $check_amount = $result["check_amount"];\r
- $check_id = $result["check_id"];\r
- $check_name = $result["check_name"];\r
- $lid_id = $result["lid_id"] ?? 0;\r
- $auth_code = $result['auth_code'] ?? 0;\r
- $write_off_bonuses = intval($result["write_off_bonuses"] ?? 0); // только при продаже\r
-\r
- $user = Users::find()->where(['phone' => $result['phone']])->andWhere(['phone_true' => '1'])->one();\r
- $bonusLevels = BonusLevels::find()->where(['active' => 1])->indexBy('alias')->asArray()->all();\r
- $bonusLevel = $user->bonus_level ?? "silver";\r
- $cashback_rate = isset($bonusLevels[$bonusLevel]['cashback_rate'])\r
- ? $bonusLevels[$bonusLevel]['cashback_rate'] / 100\r
- : self::$FIRST_SALE_PROCENT;\r
-\r
-// $referal_rate = isset($bonusLevels[$bonusLevel]['referal_rate'])\r
-// ? $bonusLevels[$bonusLevel]['referal_rate'] / 100\r
-// : self::$CREDIT_HIGH_PROCENT;\r
-\r
- $bonus_rate = isset($bonusLevels[$bonusLevel]['bonus_rate'])\r
- ? $bonusLevels[$bonusLevel]['bonus_rate'] / 100\r
- : self::$FIRST_SALE_PROCENT;\r
-\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $amount_real = 0;\r
- $items_arr_no = array_values(ArrayHelper::map(\r
- UniversalCatalogItem::find()->where(['catalog_alias' => 'unused_nomenclature'])->all(), 'guid', 'guid'));\r
- $items_arr_no_bonus_writeoffs = array_values(ArrayHelper::map(\r
- UniversalCatalogItem::find()->where(['catalog_alias' => 'non_bonusable_goods'])->all(), 'guid', 'guid'));\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $summa_no = 0;\r
- $summa_no_writeoffs = 0;\r
- $amount_all = 0;\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- foreach ($result['items'] as $item) {\r
- if (in_array($item["product_id"], $items_arr_no)) {\r
- $summa_no = $summa_no + $item["price"] * $item["quantity"];\r
- } else if (in_array($item["product_id"], $items_arr_no_bonus_writeoffs)) {\r
- $summa_no_writeoffs = $summa_no_writeoffs + $item["price"] * $item["quantity"];\r
- } else {\r
- $amount_real = $amount_real + $item["price"] * $item["quantity"];\r
- }\r
- $amount_all = $amount_all + $item["price"] * $item["quantity"];\r
- }\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
-\r
- $cnt = intval(Sales::find()->where(['phone' => $result['phone'], 'operation' => Sales::OPERATION_SALE])->count());\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- // $max_procent = $cnt == 0 ? self::$FIRST_SALE_PROCENT : ($cnt == 1 ? self::$SECOND_SALE_PROCENT : self::$MAX_PROCENT);\r
- $max_procent = $bonus_rate;\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- // если списывается в попытке больше бонусов чем может списаться -\r
- $percent = $phone == "79049031399" ? 0.9 : $max_procent;\r
- $write_off_bonuses_theory = round($amount_real * $percent);\r
- if ($write_off_bonuses > $write_off_bonuses_theory) {\r
- $write_off_bonuses = $write_off_bonuses_theory;\r
- }\r
- $user_balans = ClientHelper::getBonusBalance($phone);\r
- if ($user_balans < $write_off_bonuses) {\r
- $write_off_bonuses = $user_balans;\r
- }\r
-\r
- // TO8-22: Промо-списание БЛАГО\r
- // Проверяем: если у клиента есть промо-баланс >= 350, покупка >= 1700 и 350 > стандартного максимума — списываем промо\r
- $usePromoWriteOff = false;\r
- $promoWriteOffAmount = 350;\r
- $promoMinCheckAmount = 1700;\r
-\r
- $now = date('Y-m-d H:i:s');\r
- $promoPlusSum = (float) UsersBonus::find()\r
- ->where(['phone' => $phone, 'tip' => 'plus', 'tip_sale' => Promocode::TIP_SALE_PROMOBONUS])\r
- ->andWhere(['<=', 'date_start', $now])\r
- ->andWhere(['>=', 'date_end', $now])\r
- ->sum('bonus');\r
- $promoMinusSum = (float) UsersBonus::find()\r
- ->where(['phone' => $phone, 'tip' => 'minus', 'tip_sale' => Promocode::TIP_SALE_PROMOBONUS])\r
- ->sum('bonus');\r
- $promoBalance = max(0, $promoPlusSum - $promoMinusSum);\r
-\r
- if ($promoBalance >= $promoWriteOffAmount\r
- && $amount_all >= $promoMinCheckAmount\r
- && $promoWriteOffAmount > $write_off_bonuses_theory\r
- ) {\r
- $usePromoWriteOff = true;\r
- $write_off_bonuses = $promoWriteOffAmount;\r
- }\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- // сумма со скидкой\r
- $summa_chek = $amount_all - $write_off_bonuses;\r
- $baza_back = $amount_real + $summa_no_writeoffs - $write_off_bonuses;\r
-\r
- $mess = [];\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
-\r
- /** @var $user Users */\r
- if (!$user) {\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $mess["error"] = "Покупателя " . $result['phone'] . " нет в бонусной программе!";\r
-\r
- return $this->asJson($mess);\r
- }\r
- // TO8-22: При промо-списании burn_balans не трогаем — списываются промо-бонусы, а не обычные\r
- if (!$usePromoWriteOff) {\r
- $user->burn_balans = max(0, $user->burn_balans - $write_off_bonuses);\r
- }\r
- // [balans - burn_balance, burn_balans] - показать клиенту что мы сожгли сжигаемый баланс\r
-\r
-// старая точка проверки кода\r
-// file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
-// if ($user->keycode != strval($auth_code)) {\r
-//\r
-// file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '-auth_code not valid-' . __LINE__ . ' keycode ' .$user->keycode . '| auth_code ' . strval($auth_code), FILE_APPEND);\r
-// return $this->asJson(['error' => 'auth_code not valid']);\r
-// }\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $user_id = $user->id;\r
-// $keycode = $user->keycode;\r
-// $name = $user->name;\r
-// $referral_id = $user->referral_id;\r
-// $sale_avg_price = $user->sale_avg_price;\r
- $sale_price = $user->sale_price;\r
- $sale_cnt = $user->sale_cnt;\r
-// if ($referral_id == $user_id) {\r
-// $referral_id = 0;\r
-// }\r
- $ip = $_SERVER['REMOTE_ADDR'];\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
-\r
-\r
- $store_id_1c = $store_id;\r
- $site_id = 0;\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- // получаем внутренний ID продаца - сотрудника из таблицы admin\r
- $admin_id = ClientHelper::getExportId($seller_id, "admin", 1);\r
- // получаем внутренний ID продаца - сотрудника из таблицы admin\r
- $store_id = ClientHelper::getExportId($store_id_1c, "city_store", 1);\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $writeOffAlready = false;\r
- if (!empty($lid_id)) {\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $tipSaleForCheck = $usePromoWriteOff ? Promocode::TIP_SALE_PROMOBONUS : 'sale';\r
- $writeOffAlready = UsersBonus::find()->where(['lid_id' => $lid_id, 'phone' => $phone, 'tip_sale' => $tipSaleForCheck, 'tip' => 'minus'])->one() != null;\r
- }\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
-\r
- $user_balans_new = $user_balans;\r
- if ($write_off_bonuses && !$writeOffAlready) {\r
- // TO8-22: При промо-списании auth_code не требуется (списание автоматическое)\r
- if (!$usePromoWriteOff) {\r
- // Проверка кода только при стандартном списании\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- if ($user->keycode != strval($auth_code)) {\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '-auth_code not valid-' . __LINE__ . ' keycode ' .$user->keycode . '| auth_code ' . strval($auth_code), FILE_APPEND);\r
- return $this->asJson(['error' => 'auth_code not valid']);\r
- }\r
- }\r
-\r
- // TO8-22: При промо-списании обычный баланс не уменьшается — списываются промо-бонусы\r
- $user_balans_new = $usePromoWriteOff ? $user_balans : ($user_balans - $write_off_bonuses);\r
- $tipSaleForWriteOff = $usePromoWriteOff ? Promocode::TIP_SALE_PROMOBONUS : 'sale';\r
- $name_b = $usePromoWriteOff\r
- ? "Списание промо-бонусов БЛАГО по чеку $check_name"\r
- : "Спиcание бонусов по чеку $check_name";\r
- $usersBonus = new UsersBonus;\r
- $usersBonus->date = date('Y-m-d H:i:s');\r
- $usersBonus->tip = 'minus';\r
- $usersBonus->tip_sale = $tipSaleForWriteOff;\r
- $usersBonus->phone = $phone;\r
- $usersBonus->name = $name_b;\r
- $usersBonus->check_id = $check_id;\r
- $usersBonus->store_id = $store_id;\r
- $usersBonus->ip = $ip;\r
- $usersBonus->site_id = $site_id; // ???\r
- $usersBonus->referal_id = 0;// $referal_id;\r
- $usersBonus->admin_id = $admin_id;\r
- $usersBonus->price = $summa_chek;\r
- $usersBonus->price_skidka = $write_off_bonuses;\r
- $usersBonus->bonus = $write_off_bonuses;\r
- $usersBonus->store_id_1c = $store_id_1c;\r
- $usersBonus->seller_id_1c = $seller_id;\r
- $usersBonus->user_id = $user_id; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении\r
- $usersBonus->lid_id = $lid_id; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении\r
- $usersBonus->date_start = $usersBonus->date; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении\r
- $usersBonus->date_end = $usersBonus->date; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении\r
- $usersBonus->date_dell = $usersBonus->date; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
-\r
- $usersBonus->save(); // иначе не пройдём валидацию, т.к. множество полей в бд не заполнены.\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
-\r
- if ($user->first_minus_balance === null) {\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $user->first_minus_balance = $usersBonus->date;\r
- $user->save();\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- }\r
-\r
- if ($usersBonus->getErrors()) {\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
-\r
- LogService::apiErrorLog(json_encode(["error_id" => 4, "error" => $usersBonus->getErrors()], JSON_UNESCAPED_UNICODE));\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- return $this->asJson(["error_id" => 4, "error" => $usersBonus->getErrors()]);\r
- }\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- Yii::info("MINUS write_off_bonuses={$write_off_bonuses}", self::LOG_CATEGORY_BONUS);\r
- }\r
- // TO8-22: При промо-списании кэшбек НЕ начисляется\r
- if ($usePromoWriteOff) {\r
- Yii::info("PROMO write_off={$write_off_bonuses}, no cashback for {$phone}", self::LOG_CATEGORY_BONUS);\r
-\r
- // Обновляем поля пользователя (аналогично стандартному пути)\r
- $sale_price += $check_amount;\r
- $sale_avg_price = round($sale_price / ($sale_cnt + 1));\r
-\r
- $user->keycode = "" . rand(1000, 9999);\r
- $user->password = ClientHelper::generatePassword(8);\r
- $user->date_last_sale = date('Y-m-d H:i:s');\r
- $user->sale_cnt = $sale_cnt + 1;\r
- if ($user->sale_cnt == 1) {\r
- $user->date_first_sale = $user->date_last_sale;\r
- }\r
- $user->sale_store_id = $store_id;\r
- $user->sale_price = $sale_price;\r
- $user->sale_avg_price = $sale_avg_price;\r
- $user->check_id_last_sale = $check_id;\r
- if (!$user->date) {\r
- $user->date = (new \DateTime('now', new \DateTimeZone('Europe/Moscow')))->format('Y-m-d H:i:sP');\r
- }\r
- $user->balans = ClientHelper::getBonusBalance($phone);\r
- $user->save();\r
-\r
- if ($user->getErrors()) {\r
- LogService::apiErrorLog(json_encode(["error_id" => 6, "error" => $user->getErrors()], JSON_UNESCAPED_UNICODE));\r
- return $this->asJson(["error_id" => 6, "error" => $user->getErrors()]);\r
- }\r
-\r
- $this->updateUserBonusLevel($user, $sale_price, $check_id, $check_name);\r
-\r
- $mess["write_off_bonuses"] = $write_off_bonuses;\r
- $mess["summa_chek"] = $summa_chek;\r
- $mess["bonus_back"] = 0;\r
- $mess["user_balans"] = $user_balans_new;\r
- $mess["user_balans_actual"] = $user->balans;\r
- $mess["promo_writeoff"] = true;\r
-\r
- return $this->asJson($mess);\r
- }\r
-\r
- //начисляем кэшбек клиенту 10% от покупки - с базы за вычитом бонусов которые он списывает\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $userFound = Users::find()->where(['phone' => $result['phone']])->one();\r
- /** @var $userFound Users */\r
- $salesCount = -1; /* Из-за нулевого значения по умолчанию куча клиентов получило бонус 20% за покупку */\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- if ($userFound && $userFound->telegram_created_at) {\r
- $salesCount = intval(Sales::find()->where(['phone' => $result['phone'], 'operation' => Sales::OPERATION_SALE])\r
- ->andWhere(['>=', 'date', $userFound->telegram_created_at])->count());\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- }\r
- $credit_procent_index = $userFound && $userFound->source > 0 && $salesCount == 0 ? 1 : 0;\r
-\r
-\r
- $back10 = $back20 = 0;\r
- $back1 = $back = round($baza_back * $cashback_rate);\r
- $nm = "Возврат с покупки " . (100 * $cashback_rate) . "% $check_name сумма чека $check_amount";\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $userBonus2 = UsersBonus::find()->where(['phone' => $phone])->andWhere(['check_id' => $check_id])->andWhere(['site_id' => $site_id])\r
- ->andWhere(['store_id' => $store_id])->andWhere(['tip' => 'plus'])->andWhere(['bonus' => $back])->andWhere(['name' => $nm])->one();\r
- if (!$userBonus2) {\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $user_balans_new += $back;\r
-\r
- $userBonus2 = new UsersBonus;\r
- $userBonus2->tip = 'plus';\r
- $userBonus2->tip_sale = 'sale';\r
- $userBonus2->date = date('Y-m-d H:i:s');\r
- $userBonus2->date_start = date('Y-m-d H:i:s', strtotime('+1 day', time()));\r
- $userBonus2->date_end = date('Y-m-d H:i:s', strtotime('+' . self::$YEAR_PERIOD . ' day', time()));\r
- $userBonus2->phone = $phone;\r
- $userBonus2->name = $nm;\r
- $userBonus2->check_id = $check_id;\r
- $userBonus2->store_id = $store_id;\r
- $userBonus2->bonus = $back;\r
- $userBonus2->ip = $ip;\r
- $userBonus2->site_id = $site_id;\r
- $userBonus2->referal_id = 0; // $referal_id;\r
- $userBonus2->admin_id = $admin_id;\r
- $userBonus2->price = $summa_chek;\r
- $userBonus2->store_id_1c = $store_id_1c;\r
- $userBonus2->seller_id_1c = $seller_id;\r
- $userBonus2->user_id = $user_id;\r
- $userBonus2->lid_id = $lid_id;\r
- $userBonus2->price_skidka = 0;\r
- $userBonus2->date_dell = $userBonus2->date_end;\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $userBonus2->save();\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- if ($userBonus2->getErrors()) {\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
-\r
- LogService::apiErrorLog(json_encode(["error_id" => 5, "error" => $userBonus2->getErrors()], JSON_UNESCAPED_UNICODE));\r
-\r
- return $this->asJson(["error_id" => 5, "error" => $userBonus2->getErrors()]);\r
- } else {\r
- $back10 = $back;\r
- }\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- Yii::info("PLUS bonus={$back}", self::LOG_CATEGORY_BONUS);\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- if ($credit_procent_index) {\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $back = round($baza_back * self::$CREDIT_HIGH_PROCENT_PART20);\r
- $nm = "Возврат с покупки " . (100 * self::$CREDIT_HIGH_PROCENT_PART20) . "% $check_name сумма чека $check_amount";\r
-\r
- $user_balans_new += $back;\r
-\r
- $userBonus2 = new UsersBonus();\r
- $userBonus2->tip = 'plus';\r
- $userBonus2->tip_sale = 'sale';\r
- $userBonus2->date = date('Y-m-d H:i:s');\r
- $userBonus2->date_start = date('Y-m-d H:i:s', strtotime('+1 day', time()));\r
- $userBonus2->date_end = date('Y-m-d H:i:s', strtotime('+3 month', time()));\r
- $userBonus2->phone = $phone;\r
- $userBonus2->name = $nm;\r
- $userBonus2->check_id = $check_id;\r
- $userBonus2->store_id = $store_id;\r
- $userBonus2->bonus = $back;\r
- $userBonus2->ip = $ip;\r
- $userBonus2->site_id = $site_id;\r
- $userBonus2->referal_id = 0;\r
- $userBonus2->admin_id = $admin_id;\r
- $userBonus2->price = $summa_chek;\r
- $userBonus2->store_id_1c = $store_id_1c;\r
- $userBonus2->seller_id_1c = $seller_id;\r
- $userBonus2->user_id = $user_id;\r
- $userBonus2->lid_id = $lid_id;\r
- $userBonus2->price_skidka = 0;\r
- $userBonus2->date_dell = $userBonus2->date_end;\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $userBonus2->save();\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- if ($userBonus2->getErrors()) {\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
-\r
- LogService::apiErrorLog(json_encode(["error_id" => 5.2, "error" => $userBonus2->getErrors()], JSON_UNESCAPED_UNICODE));\r
-\r
- return $this->asJson(["error_id" => 5.2, "error" => $userBonus2->getErrors()]);\r
- } else {\r
- $back20 = $back;\r
- }\r
- if ($userFound->telegram_created_at == null) {\r
- $userFound->telegram_created_at = date("Y-m-d H:i:s");\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $userFound->save();\r
- if ($userFound->getErrors()) {\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
-\r
- LogService::apiErrorLog(json_encode(["error_id" => 5.3, "error" => $userFound->getErrors()], JSON_UNESCAPED_UNICODE));\r
-\r
- return $this->asJson(["error_id" => 5.3, "error" => $userFound->getErrors()]);\r
- }\r
- }\r
-\r
- $notifiableUser = new NotifiableUser;\r
- $notifiableUser->phone = $phone;\r
- $notifiableUser->type = "first_given_bonus";\r
- $notifiableUser->data = "" . ($back1 + $back);\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $notifiableUser->save();\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- if ($notifiableUser->getErrors()) {\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- return $this->asJson(["error_id" => 5.4, "error" => $notifiableUser->getErrors()]);\r
- }\r
- }\r
- }\r
-\r
-// /////// Добавляем бонусов рефералу\r
-// if ($referal_id && $back) {\r
-// $name = "Вознаграждение за приведенного друга";\r
-// $referalBonus = UsersBonus::find()->where(['phone' => $phone])->andWhere(['referal_id' => $referal_id])->andWhere(['tip' => 'plus'])->one(); // phone = referal_id ???\r
-// if (!$referalBonus) {\r
-// $referalBonus = new UsersBonus;\r
-// $referalBonus->tip = 'plus';\r
-// $referalBonus->tip_sale = 'referal';\r
-// $referalBonus->date = date('Y-m-d H:i:s');\r
-// $referalBonus->date_start = date('Y-m-d H:i:s', strtotime('+1 day', time()));\r
-// $referalBonus->date_end = date('Y-m-d H:i:s', strtotime('+' . self::$YEAR_PERIOD . ' day', time()));\r
-// $referalBonus->phone = $phone;\r
-// $referalBonus->name = $name;\r
-// $referalBonus->check_id = $check_id;\r
-// $referalBonus->store_id = $store_id;\r
-// $referalBonus->bonus = $back;\r
-// $referalBonus->ip = $ip;\r
-// $referalBonus->site_id = $site_id; // ??? $user_id_referal\r
-// $referalBonus->referal_id = $referal_id; // ???\r
-// $referalBonus->admin_id = $admin_id;\r
-// $referalBonus->price = $summa_chek;\r
-// $referalBonus->store_id_1c = $store_id_1c;\r
-// $referalBonus->seller_id_1c = $seller_id;\r
-// $referalBonus->save();\r
-// if ($referalBonus->getErrors()) {\r
-// return $this->asJson(["error_id" => 3, "error" => $referalBonus->getErrors()]);\r
-// }\r
-// }\r
-// }\r
-\r
- ///////\r
-// $itogo = 0;\r
-// foreach ($result["items"] as $k => $mass) {\r
-// $seller_id_item = $mass["seller_id"];\r
-// $product_id = $mass["product_id"];\r
-// $price = $mass["price"];\r
-// $quantity = $mass["quantity"];\r
-// $sm = $price * $quantity;\r
-// //$info .=" id=$product_id ($quantity шт. x $price руб.) = $sm руб.,";\r
-// $itogo += $sm;\r
-//\r
-// //получаем внутренний ID товара\r
-// $item_id = ClientHelper::get_export_id($product_id, "products",1);\r
-//\r
-// //товары к продаже\r
-// $salesItem = new SalesItems;\r
-// $salesItem->date = date('Y-m-d H:i:s');\r
-// $salesItem->phone = $phone;\r
-// $salesItem->check_id = $check_id;\r
-// $salesItem->store_id = $store_id;\r
-// $salesItem->store_id_1c = $store_id_1c;\r
-// $salesItem->seller_id = $seller_id_item;\r
-// $salesItem->admin_id = $admin_id;\r
-// $salesItem->id_1c = $product_id;\r
-// $salesItem->item_id = $item_id;\r
-// $salesItem->kol = $quantity;\r
-// $salesItem->summa = $sm;\r
-// $salesItem->referal_id = 0; // $referal_id;\r
-// $salesItem->color_id = 0; // $color_id ???\r
-// $salesItem->lid_id = $lid_id;\r
-// $salesItem->complect_id = 0; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении\r
-// $salesItem->name = '???'; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении\r
-// $salesItem->skidka = $mass['discount'] ?? 0; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении\r
-// $salesItem->vozvrat = 0; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении\r
-// $salesItem->save();\r
-// if ($salesItem->getErrors()) {\r
-// return $this->asJson(["error_id" => 4, "error" => $salesItem->getErrors()]);\r
-// }\r
-// }\r
- // sale_avg_price sale_price\r
- $sale_price += $check_amount;\r
- $sale_avg_price = round($sale_price / ($sale_cnt + 1));\r
-\r
- $user->keycode = "" . rand(1000, 9999);\r
- $user->password = ClientHelper::generatePassword(8);\r
- $user->date_last_sale = date('Y-m-d H:i:s');\r
- $user->sale_cnt = $sale_cnt + 1;\r
- if ($user->sale_cnt == 1) {\r
- $user->date_first_sale = $user->date_last_sale;\r
- }\r
- $user->sale_store_id = $store_id;\r
- $user->sale_price = $sale_price;\r
- $user->sale_avg_price = $sale_avg_price;\r
- $user->check_id_last_sale = $check_id;\r
- if (!$user->date) {\r
- $user->date = (new DateTime('now', new DateTimeZone('Europe/Moscow')))->format('Y-m-d H:i:sP');\r
- }\r
- $user->balans = ClientHelper::getBonusBalance($phone);\r
-\r
-// $user->email_old = "example@example.ru"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении\r
-// $user->phone_old = "71111111111"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении\r
-// $user->check_id_forgot = "???"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении\r
-// $user->sid_forgot = "???"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении\r
-// $user->alerts_balans = "???"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении\r
-// $user->alerts_date = "???"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении\r
-// $user->alerts_reklama = "???"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении\r
-// $user->seller_id = "???"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $user->save();\r
- if ($user->getErrors()) {\r
-\r
-\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- LogService::apiErrorLog(json_encode(["error_id" => 6, "error" => $user->getErrors()], JSON_UNESCAPED_UNICODE));\r
-\r
- Yii::info("BEFORE END errors=" . json_encode($user->getErrors(), JSON_UNESCAPED_UNICODE), self::LOG_CATEGORY_BONUS);\r
-\r
- return $this->asJson(["error_id" => 6, "error" => $user->getErrors()]);\r
- } else {\r
- $this->updateUserBonusLevel($user, $sale_price, $check_id, $check_name);\r
- }\r
- Yii::info("BEFORE END", self::LOG_CATEGORY_BONUS);\r
-// $itogo -= $write_off_bonuses;\r
-\r
-// // продажа заносим в таблицу\r
-// $sale = new Sales;\r
-// $sale->date = date("Y-m-d H:i:s");\r
-// $sale->phone = $phone;\r
-// $sale->operation = 'Продажа';\r
-// $sale->store_id = $store_id;\r
-// $sale->admin_id = $admin_id;\r
-// $sale->seller_id = $seller_id;\r
-// $sale->store_id_1c = $store_id_1c;\r
-// $sale->id = $check_id;\r
-// $sale->number = $check_name;\r
-// $sale->summ = $amount_all;\r
-// $sale->skidka = $write_off_bonuses;\r
-// $sale->status = "???"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении\r
-// $sale->payments = "???"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении\r
-// $sale->pay_arr = "???"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении\r
-// $sale->sales_check = "???"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении\r
-// $sale->order_id = ""; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении\r
-// $sale->terminal_id = "???"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении\r
-// $sale->terminal = "???"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении\r
-// $sale->kkm_id = "???"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении\r
-// $sale->held = 0; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении\r
-// $sale->date_up = $sale->date; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении\r
-// $sale->save();\r
-// if ($sale->getErrors()) {\r
-// return $this->asJson(["error_id" => 6, "error" => $sale->getErrors()]);\r
-// }\r
-\r
- $mess["result"] = true;\r
- $mess["message_cashier"] = "Бонусы списаны";\r
- $mess["user_balans_old"] = $user_balans;\r
- $mess["user_balans_new"] = $user_balans_new;\r
- $mess["user_balans_actual"] = $user->balans;\r
- LogService::apiLogs(1, json_encode($mess, JSON_UNESCAPED_UNICODE));\r
- file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__ . ' OK ', FILE_APPEND);\r
-\r
- $totalBonus = $back10 + $back20;\r
-\r
- $input = [\r
- 'phone' => $phone,\r
- 'bonusCount' => $totalBonus,\r
- 'purchaseDate' => date("Y-m-d H:i:s"),\r
- 'orderId' => $check_id,\r
- ];\r
-\r
- $userBonusSendToTgLogs = new UserBonusSendToTgLogs;\r
- $userBonusSendToTgLogs->input_hash = md5(Json::encode($input));\r
- $userBonusSendToTgLogs->input = Json::encode($input);\r
- $userBonusSendToTgLogs->check_id = $check_id;\r
- $userBonusSendToTgLogs->phone = $phone;\r
- $userBonusSendToTgLogs->bonusCount = $totalBonus;\r
- $userBonusSendToTgLogs->status = 1;\r
- $userBonusSendToTgLogs->date = date('Y-m-d H:I:s');\r
- $userBonusSendToTgLogs->save();\r
- if ($userBonusSendToTgLogs->getErrors()) {\r
- LogService::apiErrorLog(json_encode(["error_id" => 100.001, "error" => $userBonusSendToTgLogs->getErrors()], JSON_UNESCAPED_UNICODE));\r
- }\r
- Yii::$app->queue->push(new SendBonusInfoToSiteJob($input));\r
-\r
-// SiteService::notifySiteAboutBonuses($phone, $totalBonus, date("Y-m-d H:i:s"), $check_id);\r
-\r
- return $this->asJson($mess);\r
- }\r
-\r
- /**\r
- * Создаёт новую запись в таблице UsersBonusLevels.\r
- *\r
- * @param Users $user\r
- * @param string $bonusLevel\r
- * @param string $check_id\r
- * @param string $check_name\r
- * @param string $createdAt\r
- * @return bool\r
- */\r
- protected function createBonusHistoryRecord($user, $bonusLevel, $check_id, $check_name, $createdAt)\r
- {\r
- $bonusRecord = new UsersBonusLevels();\r
- $bonusRecord->phone = $user->phone;\r
- $bonusRecord->user_id = $user->id;\r
- $bonusRecord->bonus_level = $bonusLevel;\r
- $bonusRecord->date_from = $createdAt;\r
- $bonusRecord->check_id = $check_id;\r
- $bonusRecord->check_name = $check_name;\r
- $bonusRecord->active = 1;\r
-\r
- if (!$bonusRecord->save()) {\r
- LogService::apiErrorLog(\r
- json_encode(["error_id" => 100, "error" => $bonusRecord->getErrors()], JSON_UNESCAPED_UNICODE)\r
- );\r
- return false;\r
- }\r
- return true;\r
- }\r
-\r
- /**\r
- * Обновляет бонусный уровень пользователя.\r
- *\r
- * @param Users $user Модель пользователя.\r
- * @param float $sale_price Текущая сумма покупок.\r
- * @param string $check_id Идентификатор чека.\r
- * @param string $check_name Имя (номер) чека.\r
- */\r
- protected function updateUserBonusLevel($user, $sale_price, $check_id, $check_name)\r
- {\r
- $bonusLevels = BonusLevels::find()\r
- ->where(['active' => 1])\r
- ->orderBy(['threshold' => SORT_ASC])\r
- ->all();\r
-\r
- $computedBonusLevel = null;\r
- foreach ($bonusLevels as $level) {\r
- if ($sale_price > $level->threshold) {\r
- $computedBonusLevel = $level->alias;\r
- }\r
- }\r
- $newBonusLevel = $computedBonusLevel ?? 'silver';\r
-\r
- $existingHistoryLevel = UsersBonusLevels::find()\r
- ->where(['or', ['phone' => $user->phone], ['user_id' => $user->id]])\r
- ->andWhere(['active' => 1])\r
- ->one();\r
-\r
- $now = date('Y-m-d H:i:s');\r
-\r
- if (empty($user->bonus_level) || $user->bonus_level !== $newBonusLevel) {\r
- $user->bonus_level = $newBonusLevel;\r
- if (!$user->save()) {\r
- LogService::apiErrorLog(\r
- json_encode(["error_id" => 6.1, "error" => $user->getErrors()], JSON_UNESCAPED_UNICODE)\r
- );\r
- }\r
-\r
- if ($existingHistoryLevel) {\r
- $existingHistoryLevel->active = 0;\r
- $existingHistoryLevel->date_to = $now;\r
- if (!$existingHistoryLevel->save()) {\r
- LogService::apiErrorLog(\r
- json_encode(\r
- ["error_id" => 6.2, "error" => $existingHistoryLevel->getErrors()],\r
- JSON_UNESCAPED_UNICODE\r
- )\r
- );\r
- }\r
- }\r
-\r
- $this->createBonusHistoryRecord($user, $newBonusLevel, $check_id, $check_name, $now);\r
- }\r
- }\r
-\r
- public function actionGetClientInfo()\r
- {\r
- Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;\r
- $data = file_get_contents('php://input');\r
- $result = json_decode($data, true);\r
-\r
- $__API_PARAMS = ['phone'];\r
-\r
- foreach ($__API_PARAMS as $paramName) {\r
- if (empty($result[$paramName])) {\r
-\r
- if ($paramName != 'phone') {\r
- LogService::apiErrorLog(json_encode(["error_id" => 1, "error" => "$paramName is required"], JSON_UNESCAPED_UNICODE));\r
- }\r
-\r
- return $this->asJson(["error_id" => 1, "error" => "$paramName is required"]);\r
- }\r
- }\r
-\r
- $phone = ClientHelper::phoneClear($result['phone']);\r
- if (!ClientHelper::phoneVerify($phone)) {\r
- return $this->asJson(["error_id" => 1.2, "error" => "phone is required"]);\r
- }\r
-\r
- $mess = [];\r
- $user = Users::find()->select(['id', 'keycode', 'bonus_level', 'burn_balans', 'name', 'referral_id', 'bdate', 'comment', 'pol', 'extract(epoch FROM date) as date'])\r
- ->where(['phone' => $phone])->one();\r
- if (!$user) {\r
- $mess["error"] = "Покупателя " . $phone . " нет в бонусной программе!";\r
-\r
- return $this->asJson($mess);\r
- }\r
- $name = explode(" ", $user->name);\r
- $birth_day = $user->bdate;\r
- $first_name = $name[0] ?? '';\r
- $second_name = $name[1] ?? '';\r
- $comment = $user->comment;\r
- $pol = "male";\r
- if ($user->pol == "women") {\r
- $pol = "female";\r
- }\r
- // если с момента добавления клиента прошло не более 5 часов позволяем редактировать даты иначе запрещаем редактирование\r
- if ($user->date > time() - 3600 * 5) {\r
- $mess["birth_day_readonly"] = true;\r
- $mess["events_readonly"] = false;\r
- }\r
- if ($birth_day) {\r
- $mess["birth_day_readonly"] = true;\r
- }\r
-\r
- $data = UsersEvents::find()->where(['phone' => $phone])->orderBy(['date' => SORT_DESC])->all();\r
- foreach ($data as $row) {\r
- if (strlen($row->date_day) == 1) {\r
- $row->date_day = "0" . $row->date_day;\r
- }\r
- if (strlen($row->date_month) == 1) {\r
- $row->date_month = "0" . $row->date_month;\r
- }\r
- if (!isset($mess["events"])) {\r
- $mess["events"] = [];\r
- }\r
- $mess["events"][] = ["date" => $row->date, "event_id" => $row->tip_id];\r
- }\r
-\r
- $user_balance = ClientHelper::getBonusBalance($phone);\r
-\r
- $mess["result"] = true;\r
- $mess["sex"] = $pol;\r
- $mess["first_name"] = $first_name;\r
- $mess["second_name"] = $second_name;\r
- $mess["birth_day"] = $birth_day;\r
- $mess["comment"] = $comment;\r
- $mess["balance"] = $user_balance;\r
- $mess["bonus_level"] = $user->bonus_level;\r
- $mess["burn_balans"] = $user->burn_balans;\r
-\r
- LogService::apiLogs(1, json_encode($mess, JSON_UNESCAPED_UNICODE));\r
-\r
- return $this->asJson($mess);\r
- }\r
-\r
- public function actionReturn()\r
- {\r
- Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;\r
- $data = file_get_contents('php://input');\r
- $result = json_decode($data, true);\r
-\r
- $__API_PARAMS = ['store_id', 'check_id']; // check_name, seller_id\r
-\r
- foreach ($__API_PARAMS as $paramName) {\r
- if (!isset($result[$paramName])) {\r
-\r
- LogService::apiErrorLog(json_encode(["error_id" => 1, "error" => "$paramName is required"], JSON_UNESCAPED_UNICODE));\r
-\r
- return $this->asJson(["error_id" => 1, "error" => "$paramName is required"]);\r
- }\r
- }\r
-\r
- $store_id = $result["store_id"];\r
-// $seller_id = $result["seller_id"] ?? '';\r
- $check_id = $result["check_id"];\r
-// $check_name = $result["check_name"] ?? '';\r
-\r
- UsersBonus::deleteAll(['and', ['check_id' => $check_id],\r
- ['>', 'date', date('Y-m-d H:i:s', strtotime('-3 day', time()))]]);\r
-\r
- // api_logs... event: return, seller_id, when, check\r
-\r
- LogService::apiLogs(1, json_encode(['Удачный возврат'], JSON_UNESCAPED_UNICODE));\r
-\r
- return $this->asJson(['ok']);\r
- }\r
-\r
- public function actionAuthCodeFail()\r
- {\r
- Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;\r
- $data = file_get_contents('php://input');\r
- $result = json_decode($data, true);\r
-\r
- $__API_PARAMS = [/*'store_id', 'seller_id',*/\r
- 'phone'];\r
-\r
- foreach ($__API_PARAMS as $paramName) {\r
- if (empty($result[$paramName])) {\r
-\r
- if ($paramName != 'phone') {\r
- LogService::apiErrorLog(json_encode(["error_id" => 1, "error" => "$paramName is required"], JSON_UNESCAPED_UNICODE));\r
- }\r
-\r
- return $this->asJson(["error_id" => 1, "error" => "$paramName is required"]);\r
- }\r
- }\r
-\r
- $phone = ClientHelper::phoneClear($result['phone']);\r
- if (!ClientHelper::phoneVerify($phone)) {\r
- return $this->asJson(["error_id" => 1.2, "error" => "phone is required"]);\r
- }\r
- $result['phone'] = $phone;\r
-\r
-// $seller_id = $result['seller_id'];\r
-// $store_id = $result['store_id'];\r
-\r
- $user = Users::find()->where(['phone' => $result['phone']])->andWhere(['phone_true' => '1'])->one();\r
- if (!$user) {\r
- $mess["error"] = "Покупателя $phone нет в бонусной программе!";\r
-\r
- return $this->asJson($mess);\r
- }\r
-\r
- $user->keycode = "" . rand(1000, 9999);\r
- $user->save();\r
-\r
- if ($user->getErrors()) {\r
-\r
- LogService::apiErrorLog(json_encode(["error_id" => 3, "error" => $user->getErrors()], JSON_UNESCAPED_UNICODE));\r
-\r
- return $this->asJson(["error_id" => 3, "error" => $user->getErrors()]);\r
- }\r
-\r
- $mess = [];\r
- $mess["result"] = true;\r
- // api_logs seller, store\r
-\r
- LogService::apiLogs(1, json_encode($mess, JSON_UNESCAPED_UNICODE));\r
-\r
- return $this->asJson($mess);\r
- }\r
-\r
- public function actionCurrentItems()\r
- {\r
- Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;\r
- $data = file_get_contents('php://input');\r
- $result = json_decode($data, true);\r
-\r
- $__API_PARAMS = ['store_id', 'seller_id', 'phone', 'amount_no_discount', 'amount_to_pay'];\r
-\r
- foreach ($__API_PARAMS as $paramName) {\r
- if (empty($result[$paramName])) {\r
-\r
- if ($paramName != 'phone') {\r
- LogService::apiErrorLog(json_encode(["error_id" => 1, "error" => "$paramName is required"], JSON_UNESCAPED_UNICODE));\r
- }\r
-\r
- return $this->asJson(["error_id" => 1, "error" => "$paramName is required"]);\r
- }\r
- }\r
-\r
- $phone = ClientHelper::phoneClear($result['phone']);\r
- if (!ClientHelper::phoneVerify($phone)) {\r
- return $this->asJson(["error_id" => 1.2, "error" => "phone is required"]);\r
- }\r
- $result['phone'] = $phone;\r
-\r
-// $store_id = $result["store_id"];\r
-// $seller_id = $result["seller_id"];\r
- $phone = $result["phone"];\r
-// $check_amount = intval($result["check_amount"] ?? 0);\r
-// $check_id = $result["check_id"] ?? '';\r
-// $check_name = $result["check_name"] ?? '';\r
-// $items = $result['items'] ?? [];\r
-\r
- $mess = [];\r
-\r
- $user = Users::find()->where(['phone' => $result['phone']])->andWhere(['phone_true' => '1'])->one();\r
- if (!$user) {\r
- $mess["error"] = "Покупателя $phone нет в бонусной программе!";\r
-\r
- return $this->asJson($mess);\r
- }\r
-\r
-// $user_balans = ClientHelper::getBonusBalance($phone);\r
-// $max = $itogo * self::$MAX_PROCENT; // максимально можем разрешить списывать до 30 процентов от суммы заказа\r
-// $max = ceil($max);\r
-// $available_bonus = $user_balans;\r
-// if ($available_bonus > $max) { // если баллов бонусов больше чем 30 процентов списываем по максимуму 30\r
-// $available_bonus = $max;\r
-// }\r
-// $baza = $check_amount - $available_bonus;\r
-// $back = ceil(self::$CREDIT_PROCENT * $baza);\r
-\r
-\r
-// foreach ($items as $k => $mass) {\r
-// $seller_id_item = $mass["seller_id"];\r
-// $product_id = $mass["product_id"];\r
-// $price = $mass["price"];\r
-// $quantity = $mass["quantity"];\r
-// $sm = $price * $quantity;\r
-// $info .=" id=$product_id ($quantity шт. x $price руб.) = $sm руб.,";\r
-// $itogo += $sm;\r
-//\r
-// //получаем внутренний ID товара\r
-// $item_id = ClientHelper::getExportId($product_id, "products",1);\r
-// }\r
-\r
- LogService::apiLogs(1, json_encode($mess, JSON_UNESCAPED_UNICODE));\r
-\r
- return $this->asJson(["NOT IMPLEMENTED"]);\r
- }\r
-\r
- public function actionGetSettings()\r
- {\r
- Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;\r
- $data = file_get_contents('php://input');\r
- $result = json_decode($data, true);\r
-\r
- $__API_PARAMS = ['store_id', 'seller_id'];\r
-\r
- foreach ($__API_PARAMS as $paramName) {\r
- if (!isset($result[$paramName])) {\r
-\r
- LogService::apiErrorLog(json_encode(["error_id" => 1, "error" => "$paramName is required"], JSON_UNESCAPED_UNICODE));\r
-\r
- return $this->asJson(["error_id" => 1, "error" => "$paramName is required"]);\r
- }\r
- }\r
-\r
- $store_id = $result['store_id'];\r
- $seller_id = $result['seller_id'];\r
-\r
- $mess = [];\r
- $mess["result"] = true;\r
- $mess["attempts_auth_code"] = 5; // Количество возможных попыток ввода кода подтверждения\r
- $mess["list_events"] = [\r
- ["id" => 1, "name" => "День рождения"],\r
- ["id" => 2, "name" => "8 марта"],\r
- ["id" => 3, "name" => "День матери"],\r
- ["id" => 4, "name" => "День влюбленных"],\r
- ["id" => 5, "name" => "День свадьбы"],\r
- ["id" => 6, "name" => "Другое"]\r
- ];\r
- $mess["send_current_items"] = false; // Отправлять или нет текущие позиции чека\r
-\r
- LogService::apiLogs(1, json_encode($mess, JSON_UNESCAPED_UNICODE));\r
-\r
- return $this->asJson($mess);\r
- }\r
-\r
- public function actionGetUnusedNumenclatur() {\r
- $items_arr_no = array_values(ArrayHelper::map(\r
- UniversalCatalogItem::find()->where(['catalog_alias' => 'unused_nomenclature'])->all(), 'guid', 'guid'));\r
- return $this->asJson(['unused_nomenclature' => $items_arr_no]);\r
- }\r
-\r
- public function actionGetContest001Participant() {\r
- Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;\r
-\r
- $request = Yii::$app->request->getRawBody();\r
-\r
- try {\r
- $result = Json::decode($request);\r
- } catch (\Exception $ex) {\r
- return $this->asJson(['error' => ['code' => 400, 'message' => 'Json body invalid']]);\r
- }\r
-\r
- if (!isset($result['phone'])) {\r
- return $this->asJson(["error_id" => 1, "error" => "phone is required"]);\r
- }\r
-\r
- $phone = ClientHelper::phoneClear($result['phone']);\r
- if (!ClientHelper::phoneVerify($phone)) {\r
- return $this->asJson(["error_id" => 1.2, "error" => "phone is required"]);\r
- }\r
- $result['phone'] = $phone;\r
-\r
- $mess = [];\r
-\r
- $contestants = Contest001::find()->where(['phone' => $phone])->all();\r
- if (count($contestants) > 0) {\r
- $mess['is_participant'] = true;\r
- $raffle_numbers = [];\r
- foreach ($contestants as $contestant) {\r
- $raffle_numbers[] = $contestant->number;\r
- }\r
- $mess['raffle_numbers'] = implode(', ', $raffle_numbers);\r
- } else {\r
- $mess['is_participant'] = false;\r
- }\r
-\r
- LogService::apiLogs(1, json_encode($mess, JSON_UNESCAPED_UNICODE));\r
-\r
- return $this->asJson(['response' => $mess]);\r
- }\r
-\r
- public function actionAdd() {\r
- Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;\r
-\r
- $request = Yii::$app->request->getRawBody();\r
-\r
- $requestTest = json_decode(\Yii::$app->getRequest()->getRawBody(), true);\r
-\r
- $fl = date('_Y_m_d__H_i_s_');\r
-\r
- file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', implode(',', $requestTest));\r
- file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- try {\r
- $result = Json::decode($request);\r
- file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- } catch (\Exception $ex) {\r
- file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- return $this->asJson(['error' => ['code' => 400, 'message' => 'Json body invalid']]);\r
- }\r
-\r
- $__API_PARAMS = ['phone', 'description', 'tip_sale', 'bonus', 'date_end'];\r
-\r
- foreach ($__API_PARAMS as $paramName) {\r
- if (!isset($result[$paramName])) {\r
- file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- if ($paramName != 'phone') {\r
- file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- LogService::apiErrorLog(json_encode(["error_id" => 1, "error" => "$paramName is required"], JSON_UNESCAPED_UNICODE));\r
- }\r
- file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- return $this->asJson(["error_id" => 1, "error" => "$paramName is required"]);\r
- }\r
- }\r
- file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- //\r
- if (!in_array($result['tip_sale'], ['podarok', 'senat', 'nino802', 'sale', '14feb', '23feb', '8mar', 'quest001'])) {\r
- file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- return $this->asJson(["error_id" => 1.1, "error" => "tip_sale не разрешён (podarok, senat, nino802)"]);\r
- }\r
-\r
- $phone = ClientHelper::phoneClear($result['phone']);\r
- file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- if (!ClientHelper::phoneVerify($phone)) {\r
- file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- return $this->asJson(["error_id" => 1.2, "error" => "phone is required"]);\r
- }\r
- $result['phone'] = $phone;\r
-\r
- $stop = UsersStopList::find()->select(['phone'])->where(['phone' => $result['phone']])->one();\r
- file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- if ($stop) {\r
- file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- return $this->asJson(["error_id" => 4, "error" => 'Номер телефона числится в стоп листе']);\r
- }\r
-\r
- $bonus = min((int)$result['bonus'], 1000);\r
- file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $found = UsersBonus::find()->where(['phone' => $phone])->andWhere(['>=', 'date_start', date('Y-m-d H:i:s', time() - self::$YEAR_PERIOD * 86400)])\r
- ->andWhere(['tip_sale' => $result['tip_sale']])->andWhere(['tip' => 'plus'])->andWhere(['bonus' => $bonus])->one();\r
- file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- if ($found) {\r
- file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- return $this->asJson(["error_id" => 3, "error" => 'Бонусы уже начисляли']);\r
- }\r
- file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- $userBonus = new UsersBonus;\r
- $userBonus->phone = $phone;\r
- $userBonus->name = $result['description'];\r
- $userBonus->date = date('Y-m-d H:i:s');\r
- $userBonus->site_id = 1;\r
- $userBonus->setka_id = 1;\r
- $userBonus->tip = 'plus';\r
- $userBonus->tip_sale = $result['tip_sale'];\r
- $userBonus->bonus = $bonus;\r
-\r
- $userBonusDateStart = $result['date_start'] ?? $userBonus->date;\r
- $userBonus->date_start = date('Y-m-d H:i:s', strtotime($userBonusDateStart));\r
-\r
- $userBonusDateEnd = $result['date_end'];\r
- $userBonus->date_end = date('Y-m-d H:i:s', strtotime($userBonusDateEnd));\r
-\r
- $userBonus->save();\r
- file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- if ($userBonus->getErrors()) {\r
- file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);\r
- LogService::apiErrorLog(json_encode(["error_id" => 2, "error" => $userBonus->getErrors()], JSON_UNESCAPED_UNICODE));\r
- return $this->asJson(["error_id" => 2, "error" => $userBonus->getErrors()]);\r
- }\r
- file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__ . ' OK', FILE_APPEND);\r
- return $this->asJson(['response' => true]);\r
- }\r
-\r
- /**\r
- * TO8-22: Активация промокода БЛАГО.\r
- * POST /bonus/activate-promocode\r
- * Параметры: phone, code\r
- *\r
- * Логика:\r
- * 1. Найти промокод по коду\r
- * 2. Проверить isActivatable()\r
- * 3. Найти клиента по телефону\r
- * 4. В транзакции: начислить 350 промо-бонусов (tip_sale='promobonus'), пометить промокод used=1\r
- */\r
- public function actionActivatePromocode()\r
- {\r
- Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;\r
- $data = file_get_contents('php://input');\r
- $result = json_decode($data, true);\r
-\r
- if (empty($result['code'])) {\r
- return $this->asJson(["error_id" => 1, "error" => "code is required"]);\r
- }\r
- if (empty($result['phone'])) {\r
- return $this->asJson(["error_id" => 4, "error" => "phone is required"]);\r
- }\r
-\r
- $phone = ClientHelper::phoneClear($result['phone']);\r
- if (!ClientHelper::phoneVerify($phone)) {\r
- return $this->asJson(["error_id" => 4, "error" => "phone is not valid"]);\r
- }\r
-\r
- $user = Users::find()\r
- ->where(['phone' => $phone])\r
- ->andWhere(['phone_true' => '1'])\r
- ->one();\r
-\r
- if (!$user) {\r
- return $this->asJson(["error_id" => 4, "error" => "Пользователь с телефоном $phone не найден"]);\r
- }\r
-\r
- $transaction = Yii::$app->db->beginTransaction();\r
- try {\r
- // SELECT FOR UPDATE — блокируем строку промокода от параллельной активации\r
- $promocode = Promocode::find()\r
- ->where(['code' => $result['code']])\r
- ->forUpdate()\r
- ->one();\r
-\r
- if (!$promocode) {\r
- $transaction->rollBack();\r
- return $this->asJson(["error_id" => 1, "error" => "Промокод не найден"]);\r
- }\r
-\r
- $activatable = $promocode->isActivatable();\r
- if ($activatable !== true) {\r
- $transaction->rollBack();\r
- $errorMessages = [\r
- 1 => "Промокод неактивен",\r
- 2 => "Промокод уже использован",\r
- 3 => "Срок действия промокода истёк",\r
- ];\r
- return $this->asJson([\r
- "error_id" => $activatable,\r
- "error" => $errorMessages[$activatable] ?? "Промокод недоступен",\r
- ]);\r
- }\r
-\r
- $bonusAmount = $promocode->bonus ?: 350;\r
- $duration = $promocode->duration ?: self::$YEAR_PERIOD;\r
-\r
- $usersBonus = new UsersBonus();\r
- $usersBonus->phone = $phone;\r
- $usersBonus->name = "Активация промокода {$promocode->code}";\r
- $usersBonus->date = date('Y-m-d H:i:s');\r
- $usersBonus->tip = 'plus';\r
- $usersBonus->tip_sale = Promocode::TIP_SALE_PROMOBONUS;\r
- $usersBonus->bonus = $bonusAmount;\r
- $usersBonus->price = 0;\r
- $usersBonus->price_skidka = 0;\r
- $usersBonus->user_id = $user->id;\r
- $usersBonus->store_id = 0;\r
- $usersBonus->site_id = 0;\r
- $usersBonus->setka_id = 0;\r
- $usersBonus->referal_id = 0;\r
- $usersBonus->admin_id = 0;\r
- $usersBonus->lid_id = 0;\r
- $usersBonus->date_start = date('Y-m-d H:i:s');\r
- $usersBonus->date_end = date('Y-m-d H:i:s', strtotime('+' . $duration . ' day'));\r
- $usersBonus->date_dell = $usersBonus->date_end;\r
- $usersBonus->ip = $_SERVER['REMOTE_ADDR'] ?? '';\r
-\r
- if (!$usersBonus->save()) {\r
- throw new \Exception('Ошибка сохранения бонуса: ' . json_encode($usersBonus->getErrors()));\r
- }\r
-\r
- $promocode->used = Promocode::USED_YES;\r
- $promocode->activated_by = $user->id;\r
- $promocode->activated_at = date('Y-m-d H:i:s');\r
- if (!$promocode->save(false)) {\r
- throw new \Exception('Ошибка обновления промокода: ' . json_encode($promocode->getErrors()));\r
- }\r
-\r
- $transaction->commit();\r
-\r
- Yii::info("Промокод {$promocode->code} активирован для {$phone}, бонус={$bonusAmount}", self::LOG_CATEGORY_BONUS);\r
-\r
- return $this->asJson([\r
- "success" => true,\r
- "bonus" => $bonusAmount,\r
- "message" => "Промокод активирован, начислено {$bonusAmount} бонусов",\r
- ]);\r
- } catch (\Exception $e) {\r
- $transaction->rollBack();\r
- LogService::apiErrorLog(json_encode([\r
- "error_id" => 10,\r
- "error" => $e->getMessage(),\r
- "phone" => $phone,\r
- "code" => $result['code'],\r
- ], JSON_UNESCAPED_UNICODE));\r
- return $this->asJson(["error_id" => 10, "error" => "Ошибка активации промокода"]);\r
- }\r
- }\r
-}\r
+<?php
+
+namespace app\controllers;
+
+use yii_app\jobs\SendBonusInfoToSiteJob;
+use DateTime;
+use DateTimeZone;
+use Yii;
+use yii\helpers\ArrayHelper;
+use yii\helpers\Json;
+use yii_app\helpers\ClientHelper;
+use yii_app\records\BonusLevels;
+use yii_app\records\Contest001;
+use yii_app\records\ExportImportTable;
+use yii_app\records\MessagerUser;
+use yii_app\records\NotifiableUser;
+use yii_app\records\Products1c;
+use yii_app\records\Sales;
+use yii_app\records\Timetable;
+use yii_app\records\UniversalCatalogItem;
+use yii_app\records\UserBonusSendToTgLogs;
+use yii_app\records\Users;
+use yii_app\records\UsersAuthCallLog;
+use yii_app\records\UsersBonus;
+use yii_app\records\UsersBonusLevels;
+use yii_app\records\UsersEvents;
+use yii_app\records\UsersPhones;
+use yii_app\records\UsersStopList;
+use yii_app\records\Promocode;
+use yii_app\services\LogService;
+use yii_app\services\SiteService;
+
+class BonusController extends BaseController
+{
+ private const LOG_CATEGORY_BONUS = 'bonus.auth';
+
+ private static $YEAR_PERIOD = 366;
+ private static $FIRST_SALE_PROCENT = 0.1;
+ private static $SECOND_SALE_PROCENT = 0.15;
+ private static $MAX_PROCENT = 0.2;
+ private static $CREDIT_PROCENT = 0.1;
+ private static $CREDIT_HIGH_PROCENT = 0.3;
+ private static $CREDIT_HIGH_PROCENT_PART20 = 0.2;
+
+ const OUT_DIR =
+// "/tmp";
+ "/var/www/erp24/api2/json"; // "/www/api2/json";
+// __DIR__ . "/../json"; //local
+
+ public function actionGetBonuses()
+ {
+ Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
+ $data = file_get_contents('php://input');
+ $result = json_decode($data, true);
+
+ $fl = date('_Y_m_d__H_i_s_');
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . $result['phone']);
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+
+ $__API_PARAMS = ['store_id', 'seller_id', 'phone']; // check_amount, items
+
+ foreach ($__API_PARAMS as $paramName) {
+ if (empty($result[$paramName])) {
+
+ if ($paramName != 'phone') {
+ LogService::apiErrorLog(json_encode(["error_id" => 0, "error" => "$paramName is required"], JSON_UNESCAPED_UNICODE));
+ }
+
+ return $this->asJson(["error_id" => 0, "error" => "$paramName is required"]);
+ }
+ }
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+
+ $phone = ClientHelper::phoneClear($result['phone']);
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ if (!ClientHelper::phoneVerify($phone)) {
+ return $this->asJson(["error_id" => 0.2, "error" => "phone is required"]);
+ }
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $result['phone'] = $phone;
+
+ $check_amount = intval($result['check_amount'] ?? 0);
+
+ $user = Users::find()->where(['phone' => $result['phone']])->andWhere(['phone_true' => '1'])->one();
+ $bonusLevels = BonusLevels::find()->where(['active' => 1])->indexBy('alias')->asArray()->all();
+ $bonusLevel = $user->bonus_level ?? "silver";
+
+ $bonus_rate = isset($bonusLevels[$bonusLevel]['bonus_rate'])
+ ? $bonusLevels[$bonusLevel]['bonus_rate'] / 100
+ : self::$FIRST_SALE_PROCENT;
+
+ $cashback_rate = isset($bonusLevels[$bonusLevel]['cashback_rate'])
+ ? $bonusLevels[$bonusLevel]['cashback_rate'] / 100
+ : self::$FIRST_SALE_PROCENT;
+
+ $mess = [];
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ // массив с id товарыми не участвующих в бонусной
+ $items_arr_no = array_values(ArrayHelper::map(
+ UniversalCatalogItem::find()->where(['catalog_alias' => 'unused_nomenclature'])->all(), 'guid', 'guid'));
+ $items_arr_no_bonus_writeoffs = array_values(ArrayHelper::map(
+ UniversalCatalogItem::find()->where(['catalog_alias' => 'non_bonusable_goods'])->all(), 'guid', 'guid'));
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+
+ $all_amount = 0;
+ $has_actions = false;
+ $summa_no = 0;
+ $summa_no_writeoffs = 0;
+ if (!empty($result["items"])) {
+ foreach ($result["items"] as $item) {
+ if (in_array($item["product_id"], $items_arr_no)) {
+ $summa_no = $summa_no + $item["price"] * $item["quantity"];
+ $has_actions = true;
+ } elseif (in_array($item["product_id"], $items_arr_no_bonus_writeoffs)) {
+ $summa_no_writeoffs = $summa_no_writeoffs + $item["price"] * $item["quantity"];
+ }
+ $all_amount += $item["price"] * $item["quantity"];
+ }
+ }
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $baza_nachislenie = $all_amount - $summa_no;
+
+ $check_amount = $check_amount - $summa_no;
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ //$cnt = intval(Sales::find()->where(['phone' => $result['phone'], 'operation' => Sales::OPERATION_SALE])->count());
+ //$max_procent = $cnt == 0 ? self::$FIRST_SALE_PROCENT : ($cnt == 1 ? self::$SECOND_SALE_PROCENT : self::$MAX_PROCENT);
+ $max_procent = $bonus_rate;
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $percent = ($result['phone'] == "79049031399") ? 0.9 : $max_procent;
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $userFound = Users::find()->where(['phone' => $result['phone']])->one();
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ /** @var $userFound Users */
+ $salesCount = -1; /* Из-за нулевого значения по умолчанию куча клиентов получило бонус 20% за покупку */
+ if ($userFound && $userFound->telegram_created_at) {
+ $salesCount = intval(Sales::find()->where(['phone' => $result['phone'], 'operation' => Sales::OPERATION_SALE])
+ ->andWhere(['>=', 'date', $userFound->telegram_created_at])->count());
+ }
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $credit_procent = $userFound && $userFound->source > 0 && $salesCount == 0 ? self::$CREDIT_HIGH_PROCENT : $cashback_rate;
+ $will_be_credited_bonuses = $credit_procent * $baza_nachislenie;
+
+ $will_be_credited_bonuses = round($will_be_credited_bonuses);
+ $mess["will_be_credited_bonuses"] = $will_be_credited_bonuses;
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $store_id = ClientHelper::getExportId($result['store_id'], "city_store", 1);
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ // Логи введённых номеров телефонов кассирами
+ $userPhone = UsersPhones::find()->where(['phone' => $result['phone']])->andWhere(['store_id' => $store_id])
+ ->andWhere(['seller_id' => $result['seller_id']])->one();
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ if (!$userPhone) {
+ $userPhone = new UsersPhones();
+ $userPhone->phone = $result['phone'];
+ $userPhone->store_id = $store_id;
+ $userPhone->store_guid = $result['store_id'];
+ $userPhone->seller_id = $result['seller_id'];
+ }
+ if (!$userPhone->store_guid) {
+ $userPhone->store_guid = $result['store_id'];
+ }
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $userPhone->date = date('Y-m-d H:i:s');
+ $userPhone->save();
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ if ($userPhone->getErrors()) {
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ LogService::apiErrorLog(json_encode(["error_id" => 1, "error" => $userPhone->getErrors()], JSON_UNESCAPED_UNICODE));
+
+ return $this->asJson(["error_id" => 1, "error" => $userPhone->getErrors()]);
+ }
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $user = Users::find()->where(['phone' => $result['phone']])->andWhere(['phone_true' => '1'])->one();
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ if (!$user) {
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '-нет в бонусной программе-' . __LINE__, FILE_APPEND);
+ $mess["new_client"] = true;
+ $mess["message_cashier"] = "Заполните данные клиента";
+ $mess["error"] = "Покупателя " . $result['phone'] . " нет в бонусной программе!";
+
+ return $this->asJson($mess);
+ }
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $keycode = $user->keycode;
+ $black_list = $user->black_list;
+
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ if (!$black_list) {
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $stop = UsersStopList::find()->select(['phone'])->where(['phone' => $result['phone']])->one();
+ if ($stop) {
+ $black_list = 1;
+ $user->black_list = 1;
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $user->save();
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ if ($user->getErrors()) {
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ LogService::apiErrorLog(json_encode(["error_id" => 3, "error" => $user->getErrors()], JSON_UNESCAPED_UNICODE));
+
+ return $this->asJson(["error_id" => 3, "error" => $user->getErrors()]);
+ }
+ }
+ }
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $name = $user->name;
+ $user_balans = ClientHelper::getBonusBalance($result['phone']);
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $baza_spisanie = $baza_nachislenie - $summa_no_writeoffs;
+ if ($baza_spisanie < 0) {
+ $baza_spisanie = 0;
+ }
+ $max = $baza_spisanie * $percent; // максимально можем разрешить списывать до 30 процентов от суммы заказа
+ $max = round($max);
+ $available_bonus = $user_balans;
+ if ($available_bonus > $max) { // если баллов бонусов больше чем 30 процентов списываем по максимуму 30
+ $available_bonus = $max;
+ }
+// $baza = $check_amount - $bonus;
+
+ $mess["message_cashier"] = "Клиент $name найден"; // Код: $keycode
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ if ($black_list) {
+ $mess['error'] = 'Этот номер в черном списке';
+
+ return $this->asJson($mess);
+ }
+
+ $txt = $has_actions ? 'В чеке есть акционные товары, на них бонусы не начислятся.' : '';
+
+ $mess["result"] = true;
+ $mess["auth_code"] = $keycode;
+ $mess["name"] = $name;
+ $mess["total_bonuses"] = $user_balans;
+ $mess["bonus_level"] = $bonusLevel;
+ $mess["burn_balans"] = $user->burn_balans;
+ $mess["available_bonuses"] = $available_bonus;
+ $mess["message_cashier"] = $txt . " Спросите последние 4 цифры телефона который позвонит клиенту $user_balans";
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ LogService::apiLogs(1, json_encode($mess, JSON_UNESCAPED_UNICODE));
+
+ file_put_contents(self::OUT_DIR . '/get_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__ . ' OK ', FILE_APPEND);
+ return $this->asJson($mess);
+ }
+
+// public function actionSendMessage()
+// {
+// Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
+// $data = file_get_contents('php://input');
+// $result = json_decode($data, true);
+//
+// $__API_PARAMS = ['store_id', 'seller_id', 'phone'];
+//
+// foreach ($__API_PARAMS as $paramName) {
+// if (empty($result[$paramName])) {
+//
+// if ($paramName != 'phone') {
+// LogService::apiErrorLog(json_encode(["error_id" => 1, "error" => "$paramName is required"], JSON_UNESCAPED_UNICODE));
+// }
+//
+// return $this->asJson(["error" => "$paramName is required"]);
+// }
+// }
+//
+// $phone = ClientHelper::phoneClear($result['phone']);
+// if (!ClientHelper::phoneVerify($phone)) {
+// return $this->asJson(["error_id" => 0.2, "error" => "phone is required"]);
+// }
+// $result['phone'] = $phone;
+//
+// $user = Users::find()->where(['phone' => $result['phone']])->andWhere(['phone_true' => '1'])->andWhere(['black_list' => '0'])->one();
+// if (!$user) {
+// $mess["error"] = "Покупателя " . $result['phone'] . " нет в бонусной программе!";
+//
+// return $this->asJson($mess);
+// }
+// $keycode = $user->keycode;
+//
+// $mess = [];
+// $mess["result"] = true;
+//
+// $mess['auth_code'] = $user->keycode;
+// $mess['message_cashier'] = 'Отсканируйте QR код из телеграм бота или введите его руками';
+//
+// LogService::apiLogs(1, json_encode($mess, JSON_UNESCAPED_UNICODE));
+//
+// return $this->asJson($mess);
+// }
+
+ public function actionSendMessage() {
+ Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
+ $data = file_get_contents('php://input');
+ $result = json_decode($data, true);
+
+ $__API_PARAMS = ['store_id', 'seller_id', 'phone'];
+
+ foreach ($__API_PARAMS as $paramName) {
+ if (empty($result[$paramName])) {
+
+ if ($paramName != 'phone') {
+ LogService::apiErrorLog(json_encode(["error_id" => 1, "error" => "$paramName is required"], JSON_UNESCAPED_UNICODE));
+ }
+
+ return $this->asJson(["error" => "$paramName is required"]);
+ }
+ }
+
+ $phone = ClientHelper::phoneClear($result['phone']);
+ if (!ClientHelper::phoneVerify($phone)) {
+ return $this->asJson(["error_id" => 0.2, "error" => "phone is required"]);
+ }
+ $result['phone'] = $phone;
+
+ $user = Users::find()->where(['phone' => $result['phone']])->andWhere(['phone_true' => '1'])->andWhere(['black_list' => '0'])->one();
+ if (!$user) {
+ $mess["error"] = "Покупателя " . $result['phone'] . " нет в бонусной программе!";
+
+ return $this->asJson($mess);
+ }
+
+ $mess["message_cashier"] = "Звонок-последние 4 цифры телефона";
+
+ $userAuthCallLog = UsersAuthCallLog::find()->select(['COUNT(*) as cnt'])->where(['phone' => $result['phone']])
+ ->andWhere(['store_id' => $result['store_id']])->andWhere(['>=', 'date', date('Y-m-d H:i:s', strtotime('-10 minutes'))])->one();
+
+ $cnt = $userAuthCallLog ? $userAuthCallLog->cnt : 1;
+
+ $keycode = '';
+
+ if ($cnt < 2) {
+ $body = @file_get_contents("https://sms.ru/code/call?phone=" . $result['phone'] . "&api_id=4DFE45F9-1897-79C0-6872-08F05D6B7FA4&ip=" . $_SERVER["REMOTE_ADDR"]);
+ $json_res = json_decode($body, true, 512, JSON_UNESCAPED_UNICODE);
+ if ($json_res["status"] == "OK") {
+ $keycode = $json_res["code"];
+ $user->keycode = '' . $keycode;
+ $user->password = ClientHelper::generatePassword(8);;
+ $user->save();
+ if ($user->getErrors()) {
+ LogService::apiErrorLog(json_encode(["error_id" => 3.1415, "error" => $user->getErrors()], JSON_UNESCAPED_UNICODE));
+ return $this->asJson(["error_id" => 3.1415, "error" => $user->getErrors()]);
+ }
+ $mess["auth_code"] = $keycode;
+ $mess["message_cashier"] = "Попытка:$cnt Звонок клиенту! последние 4 цифры номера";
+ }
+ } elseif ($cnt > 2) {
+ $mess["message_cashier"] = "Попытка $cnt -извиняемся перед клиентом";
+ }
+ $name = "$keycode Попытка $cnt " . $_SERVER["REMOTE_ADDR"];
+ $userAuthCallLog = new UsersAuthCallLog;
+ $userAuthCallLog->date = date('Y-m-d H:i:s');
+ $userAuthCallLog->store_id = $result['store_id'];
+ $userAuthCallLog->seller_id = $result['seller_id'];
+ $userAuthCallLog->phone = $result['phone'];
+ $userAuthCallLog->name = $name;
+ $userAuthCallLog->save();
+ if ($userAuthCallLog->getErrors()) {
+ LogService::apiErrorLog(json_encode(["error_id" => 4.15, "error" => $userAuthCallLog->getErrors()], JSON_UNESCAPED_UNICODE));
+ return $this->asJson(["error_id" => 4.15, "error" => $userAuthCallLog->getErrors()]);
+ }
+
+ Yii::info("keykod={$user->keycode} store_id={$result['store_id']} seller_id={$result['seller_id']} phone={$result['phone']} $name", self::LOG_CATEGORY_BONUS);
+
+ $mess["timeout"] = 15;
+
+ LogService::apiLogs(1, json_encode($mess, JSON_UNESCAPED_UNICODE));
+
+ return $this->asJson($mess);
+ }
+
+// $mess["message_cashier"] = "Звонок-последние 4 цифры телефона";
+//
+// $userAuthCallLog = UsersAuthCallLog::find()->select(['COUNT(*) as cnt'])->where(['phone' => $result['phone']])
+// ->andWhere(['store_id' => $result['store_id']])->andWhere(['>=', 'date', date('Y-m-d H:i:s', strtotime('-10 minutes'))])->one();
+//
+// $cnt = $userAuthCallLog ? $userAuthCallLog->cnt : 1;
+//
+// if ($cnt < 2) {
+// $body = @file_get_contents("https://sms.ru/code/call?phone=" . $result['phone'] . "&api_id=4DFE45F9-1897-79C0-6872-08F05D6B7FA4&ip=" . $_SERVER["REMOTE_ADDR"]);
+// $json_res = json_decode($body, true, 512, JSON_UNESCAPED_UNICODE);
+//
+// if ($json_res["status"] == "OK") {
+// $keycode = $json_res["code"];
+// $user->keycode = '' . $keycode;
+// $user->password = ClientHelper::generatePassword(8);;
+// $user->save();
+//
+// if ($user->getErrors()) {
+//
+// LogService::apiErrorLog(json_encode(["error_id" => 3, "error" => $user->getErrors()], JSON_UNESCAPED_UNICODE));
+//
+// return $this->asJson(["error_id" => 3, "error" => $user->getErrors()]);
+// }
+//
+// $mess["auth_code"] = $keycode;
+// $mess["message_cashier"] = "Попытка:$cnt Звонок клиенту! последние 4 цифры номера";
+// }
+// } else if ($cnt > 2) {
+// $mess["message_cashier"] = "Попытка $cnt -извиняемся перед клиентом";
+// }
+//
+// $name = "$keycode Попытка $cnt " . $_SERVER["REMOTE_ADDR"];
+// $userAuthCallLog = new UsersAuthCallLog;
+// $userAuthCallLog->date = date('Y-m-d H:i:s');
+// $userAuthCallLog->store_id = $result['store_id'];
+// $userAuthCallLog->seller_id = $result['seller_id'];
+// $userAuthCallLog->phone = $result['phone'];
+// $userAuthCallLog->name = $name;
+// $userAuthCallLog->save();
+// if ($userAuthCallLog->getErrors()) {
+//
+// LogService::apiErrorLog(json_encode(["error_id" => 4, "error" => $userAuthCallLog->getErrors()], JSON_UNESCAPED_UNICODE));
+//
+// return $this->asJson(["error_id" => 4, "error" => $userAuthCallLog->getErrors()]);
+// }
+//
+
+ public function actionSaveClientInfo()
+ {
+ Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
+ $data = file_get_contents('php://input');
+ $result = json_decode($data, true);
+
+ $fl = date('_Y_m_d__H_i_s_');
+ file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . $result['phone']);
+ file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+
+
+ $__API_PARAMS = ['store_id', 'seller_id', 'phone']; // first_name, second_name, sex, birth_day, referral_id, comment, events
+
+ foreach ($__API_PARAMS as $paramName) {
+ if (empty($result[$paramName])) {
+
+ if ($paramName != 'phone') {
+ LogService::apiErrorLog(json_encode(["error_id" => 1, "error" => "$paramName is required"], JSON_UNESCAPED_UNICODE));
+ }
+
+ return $this->asJson(["error_id" => 1, "error" => "$paramName is required"]);
+ }
+ }
+ file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $phone = ClientHelper::phoneClear($result['phone']);
+ file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ if (!ClientHelper::phoneVerify($phone)) {
+ file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ return $this->asJson(["error_id" => 1.2, "error" => "phone is required"]);
+ }
+ $result['phone'] = $phone;
+
+ $source = $result["source"] ?? 0;
+ $store_id = $result["store_id"];
+ $store_id_guid = $store_id;
+ $seller_id = $result["seller_id"];
+ $phone = $result["phone"];
+ $first_name = $result["first_name"] ?? "";
+ $second_name = $result["second_name"] ?? "";
+ $sex2 = $result["sex"] ?? "";
+ $birth_day = $result["birth_day"] ?? "";
+ $referral_id = $result["referral_id"] ?? null;
+ $comment = $result["comment"] ?? "";
+ $events = $result["events"] ?? [];
+ $sex = "man";
+ if ($sex2 == "male") {
+ $sex = "man";
+ }
+ if ($sex2 == "female") {
+ $sex = "women";
+ }
+// if ($referral_phone == $phone) {
+// $referral_phone = "";
+// }
+
+ $mess = [];
+ file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ /* @var $user Users */
+ $user = Users::find()->where(['phone' => $result['phone']])->andWhere(['phone_true' => '1'])->andWhere(['black_list' => '0'])->one();
+ file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ if ($user) {
+ file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $user->referral_id = $referral_id != $user->id ? $referral_id : null;
+ $user->pol = $sex;
+ $user->bdate = $birth_day;
+ $user->name = "$first_name $second_name";
+ $user->comment = $comment;
+ $user->password = ClientHelper::generatePassword(8);
+ $user->keycode = '' . rand(1000, 9999);
+ $user->source = $source == 2 ? 1 : 0;
+ $user->save(); // иначе не пройдём валидацию, т.к. множество полей в бд не заполнены.
+ file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ if ($user->getErrors()) {
+ file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+
+ LogService::apiErrorLog(json_encode(["error_id" => 2, "error" => $user->getErrors()], JSON_UNESCAPED_UNICODE));
+
+ return $this->asJson(["error_id" => 2, "error" => $user->getErrors()]);
+ }
+ file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $userEventOld = UsersEvents::find()->where(['phone' => $phone])->orderBy(['date_add' => SORT_ASC])->one();
+ if ($userEventOld && $userEventOld->date_add < date('Y-m-d H:i:s', time() - 2 * 86400)) { // Дата добавление последнего события не старше двух дней
+ file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $mess["result"] = true;
+ $mess["message_cashier"] = "Возможность внесения памятных дат ограничена";
+
+ LogService::apiLogs(1, json_encode($mess, JSON_UNESCAPED_UNICODE));
+
+ return $this->asJson($mess);
+ }
+ file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+
+ $nomer_event = 1;
+ $dates = [];
+
+ foreach ($events as $k => $mass) {
+ $date = $mass["date"] ?? '';
+ $event_id = intval($mass['event_id'] ?? 0);
+
+ $datea = explode("-", $date);
+ $date_end = date("Y", time() + self::$YEAR_PERIOD * 86400) . "-" . $datea[1] . "-" . $datea[2];
+ $userEvent2 = UsersEvents::find()->where(['phone' => $phone])->andWhere(['date_day' => $datea[2]])->andWhere(['date_month' => $datea[1]])->one();
+ file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ if ($userEvent2) {
+ $userEvent2->delete();
+ }
+ $userEvent3 = new UsersEvents;
+ $userEvent3->number = $nomer_event;
+ $userEvent3->date = $date;
+ $userEvent3->tip_id = $event_id;
+ $userEvent3->phone = $phone;
+ $userEvent3->date_day = $datea[2];
+ $userEvent3->date_month = $datea[1];
+ $userEvent3->date_add = date('Y-m-d H:i:s');
+ $userEvent3->tip = strval('???');
+ $userEvent3->name = 'М';
+ $userEvent3->sex = 'm';
+ $userEvent3->date_edit = date("Y-m-d H:i:s");
+ $userEvent3->date_edit_info = date("Y-m-d H:i:s");
+ file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $userEvent3->save(); // иначе не пройдём валидацию, т.к. множество полей в бд не заполнены.
+ if ($userEvent3->getErrors()) {
+ file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+
+ LogService::apiErrorLog(json_encode(["error_id" => 3, "error" => $userEvent3->getErrors()], JSON_UNESCAPED_UNICODE));
+
+ return $this->asJson(["error_id" => 3, "error" => $userEvent3->getErrors()]);
+ }
+ $dates [] = $date;
+ $nomer_event++;
+ }
+ } else {
+ file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $created_name = $seller_id;
+ $rand = rand(1000, 9999);
+ $name = "$first_name $second_name";
+ $pass = ClientHelper::generatePassword(8);
+ $product1 = Products1c::find()->select(['name'])->where(['tip' => 'admin'])->andWhere(['id' => $seller_id])->one();
+ $product2 = Products1c::find()->select(['name'])->where(['tip' => 'city_store'])->andWhere(['id' => $store_id])->one();
+
+ $created_name = $product1 ? $product1->name : '';
+ $created_store = $product2 ? $product2->name : '';
+
+ $store_id_new = ExportImportTable::find()->select(['entity_id'])->where(['entity' => 'city_store'])->andWhere(['export_id' => '1'])
+ ->andWhere(['export_val' => $store_id])->one();
+ $seller_id_new = ExportImportTable::find()->select(['entity_id'])->where(['entity' => 'admin'])->andWhere(['export_id' => '1'])
+ ->andWhere(['export_val' => $seller_id])->one();
+ if ($store_id_new) {
+ $store_id_int = $store_id_new->entity_id;
+ }
+ if ($seller_id_new) {
+ $seller_id_int = $seller_id_new->entity_id;
+ }
+ file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ Users::deleteAll(['phone' => $phone, 'phone_true' => '0']);
+ file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $user2 = new Users;
+ $user2->source = $source;
+ $user2->pol = $sex;
+ $user2->keycode = strval($rand);
+ $user2->phone = $phone;
+ $user2->name = $name;
+ $user2->name_name = $first_name;
+ $user2->name_last = $second_name;
+ $user2->password = $pass;
+ $user2->phone_true = strval(1);
+ $user2->bdate = $birth_day;
+ $user2->referral_id = $referral_id;
+ $user2->comment = $comment;
+ $user2->created_id = $seller_id_int ?? 0;
+ $user2->created_name = $created_name;
+ $user2->seller_id = strval($seller_id);
+ $user2->store_id = $store_id_guid;
+ $user2->created_store_id = $store_id_int ?? 0;
+ $user2->created_store = $created_store;
+ $user2->date = date('Y-m-d H:i:s');
+ $user2->sale_store_id = $store_id_int ?? 0;
+ $user2->sale_store = '';
+ $user2->sms_info = 1;
+ $user2->reklama_info = 1;
+ $user2->info = '';
+ $setka_id = 1;
+ $user2->setka_id = $setka_id;
+ $user2->card = "" . ($phone * 2 + 1608 + $setka_id); // генерируем номер карты который зависит от номера сетки + ДР Тимура
+ $user2->save(); // иначе не пройдём валидацию, т.к. множество полей в бд не заполнены.
+ file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ if ($user2->getErrors()) {
+ file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+
+ LogService::apiErrorLog(json_encode(["error_id" => 4, "error" => $user2->getErrors()], JSON_UNESCAPED_UNICODE));
+
+ return $this->asJson(["error_id" => 4, "error" => $user2->getErrors()]);
+ }
+
+ file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ if ($store_id == '56524cb1-4763-11ea-8cce-b42e991aff6c') {
+ file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $admin_id = ClientHelper::getExportId($seller_id, "admin", 1);
+
+ $usersBonus = new UsersBonus;
+ $usersBonus->date = date('Y-m-d H:i:s');
+ $usersBonus->tip = 'plus';
+ $usersBonus->tip_sale = 'podarok';
+ $usersBonus->phone = $phone;
+ $usersBonus->name = "Приветственные бонусы посетителю сайта";
+ $usersBonus->store_id = $store_id_int ?? 0;
+ $usersBonus->site_id = 0;
+ $usersBonus->referal_id = 0;
+ $usersBonus->admin_id = $admin_id;
+ $usersBonus->price = 0;
+ $usersBonus->price_skidka = 0;
+ $usersBonus->bonus = 50;
+ $usersBonus->store_id_1c = $store_id;
+ $usersBonus->seller_id_1c = $seller_id;
+ $usersBonus->date_start = date('Y-m-d 08:00:00', strtotime('+1 day', strtotime($usersBonus->date)));
+ $usersBonus->date_end = date('Y-m-d H:i:s', strtotime('+1 week', strtotime($usersBonus->date_start)));
+ $usersBonus->save();
+ file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ if ($usersBonus->getErrors()) {
+ file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ LogService::apiErrorLog(json_encode(["error_id" => 5, "error" => $usersBonus->getErrors()], JSON_UNESCAPED_UNICODE));
+
+ return $this->asJson(["error_id" => 5, "error" => $usersBonus->getErrors()]);
+ }
+ }
+ }
+
+ $mess["result"] = true;
+ $mess["message_cashier"] = "Данные клиента сохранены";
+
+ LogService::apiLogs(1, json_encode($mess, JSON_UNESCAPED_UNICODE));
+
+ file_put_contents(self::OUT_DIR . '/save_client_info_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__ . ' OK ', FILE_APPEND);
+ return $this->asJson($mess);
+ }
+
+ public function actionSale()
+ {
+ Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
+ $data = file_get_contents('php://input');
+ $result = json_decode($data, true);
+ $resultTest = $result;
+ $fl = date('_Y_m_d__H_i_s_');
+ $json=json_encode($resultTest,JSON_UNESCAPED_UNICODE);
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '_info.json', PHP_EOL . '--' . $result['phone']);
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '_info.json', ' '.date("d.m.Y H:i:s",time()).' JSON: '.$json.' ', FILE_APPEND);
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . $result['phone']);
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+
+ $__API_PARAMS = ['store_id', 'seller_id', 'phone', 'check_amount', 'check_id', 'check_name']; // items, auth_code, write_off_bonuses
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ foreach ($__API_PARAMS as $paramName) {
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ if (empty($result[$paramName])) {
+
+ if ($paramName != 'phone') {
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '-error-' . __LINE__, FILE_APPEND);
+ LogService::apiErrorLog(json_encode(["error_id" => 1, "error" => "$paramName is required"], JSON_UNESCAPED_UNICODE));
+ }
+
+ return $this->asJson(["error_id" => 1, "error" => "$paramName is required"]);
+ }
+ }
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $phone = ClientHelper::phoneClear($result['phone']);
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ if (!ClientHelper::phoneVerify($phone)) {
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '-error-' . __LINE__, FILE_APPEND);
+ return $this->asJson(["error_id" => 1.2, "error" => "phone is required"]);
+ }
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $result['phone'] = $phone;
+ $result['items'] = $result['items'] ?? [];
+
+ $store_id = $result["store_id"];
+ $seller_id = $result["seller_id"];
+ $check_amount = $result["check_amount"];
+ $check_id = $result["check_id"];
+ $check_name = $result["check_name"];
+ $lid_id = $result["lid_id"] ?? 0;
+ $auth_code = $result['auth_code'] ?? 0;
+ $write_off_bonuses = intval($result["write_off_bonuses"] ?? 0); // только при продаже
+
+ $user = Users::find()->where(['phone' => $result['phone']])->andWhere(['phone_true' => '1'])->one();
+ $bonusLevels = BonusLevels::find()->where(['active' => 1])->indexBy('alias')->asArray()->all();
+ $bonusLevel = $user->bonus_level ?? "silver";
+ $cashback_rate = isset($bonusLevels[$bonusLevel]['cashback_rate'])
+ ? $bonusLevels[$bonusLevel]['cashback_rate'] / 100
+ : self::$FIRST_SALE_PROCENT;
+
+// $referal_rate = isset($bonusLevels[$bonusLevel]['referal_rate'])
+// ? $bonusLevels[$bonusLevel]['referal_rate'] / 100
+// : self::$CREDIT_HIGH_PROCENT;
+
+ $bonus_rate = isset($bonusLevels[$bonusLevel]['bonus_rate'])
+ ? $bonusLevels[$bonusLevel]['bonus_rate'] / 100
+ : self::$FIRST_SALE_PROCENT;
+
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $amount_real = 0;
+ $items_arr_no = array_values(ArrayHelper::map(
+ UniversalCatalogItem::find()->where(['catalog_alias' => 'unused_nomenclature'])->all(), 'guid', 'guid'));
+ $items_arr_no_bonus_writeoffs = array_values(ArrayHelper::map(
+ UniversalCatalogItem::find()->where(['catalog_alias' => 'non_bonusable_goods'])->all(), 'guid', 'guid'));
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $summa_no = 0;
+ $summa_no_writeoffs = 0;
+ $amount_all = 0;
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ foreach ($result['items'] as $item) {
+ if (in_array($item["product_id"], $items_arr_no)) {
+ $summa_no = $summa_no + $item["price"] * $item["quantity"];
+ } else if (in_array($item["product_id"], $items_arr_no_bonus_writeoffs)) {
+ $summa_no_writeoffs = $summa_no_writeoffs + $item["price"] * $item["quantity"];
+ } else {
+ $amount_real = $amount_real + $item["price"] * $item["quantity"];
+ }
+ $amount_all = $amount_all + $item["price"] * $item["quantity"];
+ }
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+
+ $cnt = intval(Sales::find()->where(['phone' => $result['phone'], 'operation' => Sales::OPERATION_SALE])->count());
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ // $max_procent = $cnt == 0 ? self::$FIRST_SALE_PROCENT : ($cnt == 1 ? self::$SECOND_SALE_PROCENT : self::$MAX_PROCENT);
+ $max_procent = $bonus_rate;
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ // если списывается в попытке больше бонусов чем может списаться -
+ $percent = $phone == "79049031399" ? 0.9 : $max_procent;
+ $write_off_bonuses_theory = round($amount_real * $percent);
+ if ($write_off_bonuses > $write_off_bonuses_theory) {
+ $write_off_bonuses = $write_off_bonuses_theory;
+ }
+ $user_balans = ClientHelper::getBonusBalance($phone);
+ if ($user_balans < $write_off_bonuses) {
+ $write_off_bonuses = $user_balans;
+ }
+
+ // TO8-22: Промо-списание БЛАГО
+ // Проверяем: если у клиента есть промо-баланс >= 350, покупка >= 1700 и 350 > стандартного максимума — списываем промо
+ $usePromoWriteOff = false;
+ $promoWriteOffAmount = 350;
+ $promoMinCheckAmount = 1700;
+
+ $now = date('Y-m-d H:i:s');
+ $promoPlusSum = (float) UsersBonus::find()
+ ->where(['phone' => $phone, 'tip' => 'plus', 'tip_sale' => Promocode::TIP_SALE_PROMOBONUS])
+ ->andWhere(['<=', 'date_start', $now])
+ ->andWhere(['>=', 'date_end', $now])
+ ->sum('bonus');
+ $promoMinusSum = (float) UsersBonus::find()
+ ->where(['phone' => $phone, 'tip' => 'minus', 'tip_sale' => Promocode::TIP_SALE_PROMOBONUS])
+ ->sum('bonus');
+ $promoBalance = max(0, $promoPlusSum - $promoMinusSum);
+
+ if ($promoBalance >= $promoWriteOffAmount
+ && $amount_all >= $promoMinCheckAmount
+ && $promoWriteOffAmount > $write_off_bonuses_theory
+ ) {
+ $usePromoWriteOff = true;
+ $write_off_bonuses = $promoWriteOffAmount;
+ }
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ // сумма со скидкой
+ $summa_chek = $amount_all - $write_off_bonuses;
+ $baza_back = $amount_real + $summa_no_writeoffs - $write_off_bonuses;
+
+ $mess = [];
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+
+ /** @var $user Users */
+ if (!$user) {
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $mess["error"] = "Покупателя " . $result['phone'] . " нет в бонусной программе!";
+
+ return $this->asJson($mess);
+ }
+ // TO8-22: При промо-списании burn_balans не трогаем — списываются промо-бонусы, а не обычные
+ if (!$usePromoWriteOff) {
+ $user->burn_balans = max(0, $user->burn_balans - $write_off_bonuses);
+ }
+ // [balans - burn_balance, burn_balans] - показать клиенту что мы сожгли сжигаемый баланс
+
+// старая точка проверки кода
+// file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+// if ($user->keycode != strval($auth_code)) {
+//
+// file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '-auth_code not valid-' . __LINE__ . ' keycode ' .$user->keycode . '| auth_code ' . strval($auth_code), FILE_APPEND);
+// return $this->asJson(['error' => 'auth_code not valid']);
+// }
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $user_id = $user->id;
+// $keycode = $user->keycode;
+// $name = $user->name;
+// $referral_id = $user->referral_id;
+// $sale_avg_price = $user->sale_avg_price;
+ $sale_price = $user->sale_price;
+ $sale_cnt = $user->sale_cnt;
+// if ($referral_id == $user_id) {
+// $referral_id = 0;
+// }
+ $ip = $_SERVER['REMOTE_ADDR'];
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+
+
+ $store_id_1c = $store_id;
+ $site_id = 0;
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ // получаем внутренний ID продаца - сотрудника из таблицы admin
+ $admin_id = ClientHelper::getExportId($seller_id, "admin", 1);
+ // получаем внутренний ID продаца - сотрудника из таблицы admin
+ $store_id = ClientHelper::getExportId($store_id_1c, "city_store", 1);
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $writeOffAlready = false;
+ if (!empty($lid_id)) {
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $tipSaleForCheck = $usePromoWriteOff ? Promocode::TIP_SALE_PROMOBONUS : 'sale';
+ $writeOffAlready = UsersBonus::find()->where(['lid_id' => $lid_id, 'phone' => $phone, 'tip_sale' => $tipSaleForCheck, 'tip' => 'minus'])->one() != null;
+ }
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+
+ $user_balans_new = $user_balans;
+ if ($write_off_bonuses && !$writeOffAlready) {
+ // TO8-22: При промо-списании auth_code не требуется (списание автоматическое)
+ if (!$usePromoWriteOff) {
+ // Проверка кода только при стандартном списании
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ if ($user->keycode != strval($auth_code)) {
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '-auth_code not valid-' . __LINE__ . ' keycode ' .$user->keycode . '| auth_code ' . strval($auth_code), FILE_APPEND);
+ return $this->asJson(['error' => 'auth_code not valid']);
+ }
+ }
+
+ // TO8-22: При промо-списании обычный баланс не уменьшается — списываются промо-бонусы
+ $user_balans_new = $usePromoWriteOff ? $user_balans : ($user_balans - $write_off_bonuses);
+ $tipSaleForWriteOff = $usePromoWriteOff ? Promocode::TIP_SALE_PROMOBONUS : 'sale';
+ $name_b = $usePromoWriteOff
+ ? "Списание промо-бонусов БЛАГО по чеку $check_name"
+ : "Спиcание бонусов по чеку $check_name";
+ $usersBonus = new UsersBonus;
+ $usersBonus->date = date('Y-m-d H:i:s');
+ $usersBonus->tip = 'minus';
+ $usersBonus->tip_sale = $tipSaleForWriteOff;
+ $usersBonus->phone = $phone;
+ $usersBonus->name = $name_b;
+ $usersBonus->check_id = $check_id;
+ $usersBonus->store_id = $store_id;
+ $usersBonus->ip = $ip;
+ $usersBonus->site_id = $site_id; // ???
+ $usersBonus->referal_id = 0;// $referal_id;
+ $usersBonus->admin_id = $admin_id;
+ $usersBonus->price = $summa_chek;
+ $usersBonus->price_skidka = $write_off_bonuses;
+ $usersBonus->bonus = $write_off_bonuses;
+ $usersBonus->store_id_1c = $store_id_1c;
+ $usersBonus->seller_id_1c = $seller_id;
+ $usersBonus->user_id = $user_id; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении
+ $usersBonus->lid_id = $lid_id; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении
+ $usersBonus->date_start = $usersBonus->date; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении
+ $usersBonus->date_end = $usersBonus->date; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении
+ $usersBonus->date_dell = $usersBonus->date; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+
+ $usersBonus->save(); // иначе не пройдём валидацию, т.к. множество полей в бд не заполнены.
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+
+ if ($user->first_minus_balance === null) {
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $user->first_minus_balance = $usersBonus->date;
+ $user->save();
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ }
+
+ if ($usersBonus->getErrors()) {
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+
+ LogService::apiErrorLog(json_encode(["error_id" => 4, "error" => $usersBonus->getErrors()], JSON_UNESCAPED_UNICODE));
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ return $this->asJson(["error_id" => 4, "error" => $usersBonus->getErrors()]);
+ }
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ Yii::info("MINUS write_off_bonuses={$write_off_bonuses}", self::LOG_CATEGORY_BONUS);
+ }
+ // TO8-22: При промо-списании кэшбек НЕ начисляется
+ if ($usePromoWriteOff) {
+ Yii::info("PROMO write_off={$write_off_bonuses}, no cashback for {$phone}", self::LOG_CATEGORY_BONUS);
+
+ // Обновляем поля пользователя (аналогично стандартному пути)
+ $sale_price += $check_amount;
+ $sale_avg_price = round($sale_price / ($sale_cnt + 1));
+
+ $user->keycode = "" . rand(1000, 9999);
+ $user->password = ClientHelper::generatePassword(8);
+ $user->date_last_sale = date('Y-m-d H:i:s');
+ $user->sale_cnt = $sale_cnt + 1;
+ if ($user->sale_cnt == 1) {
+ $user->date_first_sale = $user->date_last_sale;
+ }
+ $user->sale_store_id = $store_id;
+ $user->sale_price = $sale_price;
+ $user->sale_avg_price = $sale_avg_price;
+ $user->check_id_last_sale = $check_id;
+ if (!$user->date) {
+ $user->date = (new \DateTime('now', new \DateTimeZone('Europe/Moscow')))->format('Y-m-d H:i:sP');
+ }
+ $user->balans = ClientHelper::getBonusBalance($phone);
+ $user->save();
+
+ if ($user->getErrors()) {
+ LogService::apiErrorLog(json_encode(["error_id" => 6, "error" => $user->getErrors()], JSON_UNESCAPED_UNICODE));
+ return $this->asJson(["error_id" => 6, "error" => $user->getErrors()]);
+ }
+
+ $this->updateUserBonusLevel($user, $sale_price, $check_id, $check_name);
+
+ $mess["write_off_bonuses"] = $write_off_bonuses;
+ $mess["summa_chek"] = $summa_chek;
+ $mess["bonus_back"] = 0;
+ $mess["user_balans"] = $user_balans_new;
+ $mess["user_balans_actual"] = $user->balans;
+ $mess["promo_writeoff"] = true;
+
+ return $this->asJson($mess);
+ }
+
+ //начисляем кэшбек клиенту 10% от покупки - с базы за вычитом бонусов которые он списывает
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $userFound = Users::find()->where(['phone' => $result['phone']])->one();
+ /** @var $userFound Users */
+ $salesCount = -1; /* Из-за нулевого значения по умолчанию куча клиентов получило бонус 20% за покупку */
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ if ($userFound && $userFound->telegram_created_at) {
+ $salesCount = intval(Sales::find()->where(['phone' => $result['phone'], 'operation' => Sales::OPERATION_SALE])
+ ->andWhere(['>=', 'date', $userFound->telegram_created_at])->count());
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ }
+ $credit_procent_index = $userFound && $userFound->source > 0 && $salesCount == 0 ? 1 : 0;
+
+
+ $back10 = $back20 = 0;
+ $back1 = $back = round($baza_back * $cashback_rate);
+ $nm = "Возврат с покупки " . (100 * $cashback_rate) . "% $check_name сумма чека $check_amount";
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $userBonus2 = UsersBonus::find()->where(['phone' => $phone])->andWhere(['check_id' => $check_id])->andWhere(['site_id' => $site_id])
+ ->andWhere(['store_id' => $store_id])->andWhere(['tip' => 'plus'])->andWhere(['bonus' => $back])->andWhere(['name' => $nm])->one();
+ if (!$userBonus2) {
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $user_balans_new += $back;
+
+ $userBonus2 = new UsersBonus;
+ $userBonus2->tip = 'plus';
+ $userBonus2->tip_sale = 'sale';
+ $userBonus2->date = date('Y-m-d H:i:s');
+ $userBonus2->date_start = date('Y-m-d H:i:s', strtotime('+1 day', time()));
+ $userBonus2->date_end = date('Y-m-d H:i:s', strtotime('+' . self::$YEAR_PERIOD . ' day', time()));
+ $userBonus2->phone = $phone;
+ $userBonus2->name = $nm;
+ $userBonus2->check_id = $check_id;
+ $userBonus2->store_id = $store_id;
+ $userBonus2->bonus = $back;
+ $userBonus2->ip = $ip;
+ $userBonus2->site_id = $site_id;
+ $userBonus2->referal_id = 0; // $referal_id;
+ $userBonus2->admin_id = $admin_id;
+ $userBonus2->price = $summa_chek;
+ $userBonus2->store_id_1c = $store_id_1c;
+ $userBonus2->seller_id_1c = $seller_id;
+ $userBonus2->user_id = $user_id;
+ $userBonus2->lid_id = $lid_id;
+ $userBonus2->price_skidka = 0;
+ $userBonus2->date_dell = $userBonus2->date_end;
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $userBonus2->save();
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ if ($userBonus2->getErrors()) {
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+
+ LogService::apiErrorLog(json_encode(["error_id" => 5, "error" => $userBonus2->getErrors()], JSON_UNESCAPED_UNICODE));
+
+ return $this->asJson(["error_id" => 5, "error" => $userBonus2->getErrors()]);
+ } else {
+ $back10 = $back;
+ }
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ Yii::info("PLUS bonus={$back}", self::LOG_CATEGORY_BONUS);
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ if ($credit_procent_index) {
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $back = round($baza_back * self::$CREDIT_HIGH_PROCENT_PART20);
+ $nm = "Возврат с покупки " . (100 * self::$CREDIT_HIGH_PROCENT_PART20) . "% $check_name сумма чека $check_amount";
+
+ $user_balans_new += $back;
+
+ $userBonus2 = new UsersBonus();
+ $userBonus2->tip = 'plus';
+ $userBonus2->tip_sale = 'sale';
+ $userBonus2->date = date('Y-m-d H:i:s');
+ $userBonus2->date_start = date('Y-m-d H:i:s', strtotime('+1 day', time()));
+ $userBonus2->date_end = date('Y-m-d H:i:s', strtotime('+3 month', time()));
+ $userBonus2->phone = $phone;
+ $userBonus2->name = $nm;
+ $userBonus2->check_id = $check_id;
+ $userBonus2->store_id = $store_id;
+ $userBonus2->bonus = $back;
+ $userBonus2->ip = $ip;
+ $userBonus2->site_id = $site_id;
+ $userBonus2->referal_id = 0;
+ $userBonus2->admin_id = $admin_id;
+ $userBonus2->price = $summa_chek;
+ $userBonus2->store_id_1c = $store_id_1c;
+ $userBonus2->seller_id_1c = $seller_id;
+ $userBonus2->user_id = $user_id;
+ $userBonus2->lid_id = $lid_id;
+ $userBonus2->price_skidka = 0;
+ $userBonus2->date_dell = $userBonus2->date_end;
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $userBonus2->save();
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ if ($userBonus2->getErrors()) {
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+
+ LogService::apiErrorLog(json_encode(["error_id" => 5.2, "error" => $userBonus2->getErrors()], JSON_UNESCAPED_UNICODE));
+
+ return $this->asJson(["error_id" => 5.2, "error" => $userBonus2->getErrors()]);
+ } else {
+ $back20 = $back;
+ }
+ if ($userFound->telegram_created_at == null) {
+ $userFound->telegram_created_at = date("Y-m-d H:i:s");
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $userFound->save();
+ if ($userFound->getErrors()) {
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+
+ LogService::apiErrorLog(json_encode(["error_id" => 5.3, "error" => $userFound->getErrors()], JSON_UNESCAPED_UNICODE));
+
+ return $this->asJson(["error_id" => 5.3, "error" => $userFound->getErrors()]);
+ }
+ }
+
+ $notifiableUser = new NotifiableUser;
+ $notifiableUser->phone = $phone;
+ $notifiableUser->type = "first_given_bonus";
+ $notifiableUser->data = "" . ($back1 + $back);
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $notifiableUser->save();
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ if ($notifiableUser->getErrors()) {
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ return $this->asJson(["error_id" => 5.4, "error" => $notifiableUser->getErrors()]);
+ }
+ }
+ }
+
+// /////// Добавляем бонусов рефералу
+// if ($referal_id && $back) {
+// $name = "Вознаграждение за приведенного друга";
+// $referalBonus = UsersBonus::find()->where(['phone' => $phone])->andWhere(['referal_id' => $referal_id])->andWhere(['tip' => 'plus'])->one(); // phone = referal_id ???
+// if (!$referalBonus) {
+// $referalBonus = new UsersBonus;
+// $referalBonus->tip = 'plus';
+// $referalBonus->tip_sale = 'referal';
+// $referalBonus->date = date('Y-m-d H:i:s');
+// $referalBonus->date_start = date('Y-m-d H:i:s', strtotime('+1 day', time()));
+// $referalBonus->date_end = date('Y-m-d H:i:s', strtotime('+' . self::$YEAR_PERIOD . ' day', time()));
+// $referalBonus->phone = $phone;
+// $referalBonus->name = $name;
+// $referalBonus->check_id = $check_id;
+// $referalBonus->store_id = $store_id;
+// $referalBonus->bonus = $back;
+// $referalBonus->ip = $ip;
+// $referalBonus->site_id = $site_id; // ??? $user_id_referal
+// $referalBonus->referal_id = $referal_id; // ???
+// $referalBonus->admin_id = $admin_id;
+// $referalBonus->price = $summa_chek;
+// $referalBonus->store_id_1c = $store_id_1c;
+// $referalBonus->seller_id_1c = $seller_id;
+// $referalBonus->save();
+// if ($referalBonus->getErrors()) {
+// return $this->asJson(["error_id" => 3, "error" => $referalBonus->getErrors()]);
+// }
+// }
+// }
+
+ ///////
+// $itogo = 0;
+// foreach ($result["items"] as $k => $mass) {
+// $seller_id_item = $mass["seller_id"];
+// $product_id = $mass["product_id"];
+// $price = $mass["price"];
+// $quantity = $mass["quantity"];
+// $sm = $price * $quantity;
+// //$info .=" id=$product_id ($quantity шт. x $price руб.) = $sm руб.,";
+// $itogo += $sm;
+//
+// //получаем внутренний ID товара
+// $item_id = ClientHelper::get_export_id($product_id, "products",1);
+//
+// //товары к продаже
+// $salesItem = new SalesItems;
+// $salesItem->date = date('Y-m-d H:i:s');
+// $salesItem->phone = $phone;
+// $salesItem->check_id = $check_id;
+// $salesItem->store_id = $store_id;
+// $salesItem->store_id_1c = $store_id_1c;
+// $salesItem->seller_id = $seller_id_item;
+// $salesItem->admin_id = $admin_id;
+// $salesItem->id_1c = $product_id;
+// $salesItem->item_id = $item_id;
+// $salesItem->kol = $quantity;
+// $salesItem->summa = $sm;
+// $salesItem->referal_id = 0; // $referal_id;
+// $salesItem->color_id = 0; // $color_id ???
+// $salesItem->lid_id = $lid_id;
+// $salesItem->complect_id = 0; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении
+// $salesItem->name = '???'; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении
+// $salesItem->skidka = $mass['discount'] ?? 0; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении
+// $salesItem->vozvrat = 0; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении
+// $salesItem->save();
+// if ($salesItem->getErrors()) {
+// return $this->asJson(["error_id" => 4, "error" => $salesItem->getErrors()]);
+// }
+// }
+ // sale_avg_price sale_price
+ $sale_price += $check_amount;
+ $sale_avg_price = round($sale_price / ($sale_cnt + 1));
+
+ $user->keycode = "" . rand(1000, 9999);
+ $user->password = ClientHelper::generatePassword(8);
+ $user->date_last_sale = date('Y-m-d H:i:s');
+ $user->sale_cnt = $sale_cnt + 1;
+ if ($user->sale_cnt == 1) {
+ $user->date_first_sale = $user->date_last_sale;
+ }
+ $user->sale_store_id = $store_id;
+ $user->sale_price = $sale_price;
+ $user->sale_avg_price = $sale_avg_price;
+ $user->check_id_last_sale = $check_id;
+ if (!$user->date) {
+ $user->date = (new DateTime('now', new DateTimeZone('Europe/Moscow')))->format('Y-m-d H:i:sP');
+ }
+ $user->balans = ClientHelper::getBonusBalance($phone);
+
+// $user->email_old = "example@example.ru"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении
+// $user->phone_old = "71111111111"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении
+// $user->check_id_forgot = "???"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении
+// $user->sid_forgot = "???"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении
+// $user->alerts_balans = "???"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении
+// $user->alerts_date = "???"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении
+// $user->alerts_reklama = "???"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении
+// $user->seller_id = "???"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $user->save();
+ if ($user->getErrors()) {
+
+
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ LogService::apiErrorLog(json_encode(["error_id" => 6, "error" => $user->getErrors()], JSON_UNESCAPED_UNICODE));
+
+ Yii::info("BEFORE END errors=" . json_encode($user->getErrors(), JSON_UNESCAPED_UNICODE), self::LOG_CATEGORY_BONUS);
+
+ return $this->asJson(["error_id" => 6, "error" => $user->getErrors()]);
+ } else {
+ $this->updateUserBonusLevel($user, $sale_price, $check_id, $check_name);
+ }
+ Yii::info("BEFORE END", self::LOG_CATEGORY_BONUS);
+// $itogo -= $write_off_bonuses;
+
+// // продажа заносим в таблицу
+// $sale = new Sales;
+// $sale->date = date("Y-m-d H:i:s");
+// $sale->phone = $phone;
+// $sale->operation = 'Продажа';
+// $sale->store_id = $store_id;
+// $sale->admin_id = $admin_id;
+// $sale->seller_id = $seller_id;
+// $sale->store_id_1c = $store_id_1c;
+// $sale->id = $check_id;
+// $sale->number = $check_name;
+// $sale->summ = $amount_all;
+// $sale->skidka = $write_off_bonuses;
+// $sale->status = "???"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении
+// $sale->payments = "???"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении
+// $sale->pay_arr = "???"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении
+// $sale->sales_check = "???"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении
+// $sale->order_id = ""; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении
+// $sale->terminal_id = "???"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении
+// $sale->terminal = "???"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении
+// $sale->kkm_id = "???"; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении
+// $sale->held = 0; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении
+// $sale->date_up = $sale->date; // Поле не заполнялось в старом апи, но без него бд выдаёт ошибку при сохранении
+// $sale->save();
+// if ($sale->getErrors()) {
+// return $this->asJson(["error_id" => 6, "error" => $sale->getErrors()]);
+// }
+
+ $mess["result"] = true;
+ $mess["message_cashier"] = "Бонусы списаны";
+ $mess["user_balans_old"] = $user_balans;
+ $mess["user_balans_new"] = $user_balans_new;
+ $mess["user_balans_actual"] = $user->balans;
+ LogService::apiLogs(1, json_encode($mess, JSON_UNESCAPED_UNICODE));
+ file_put_contents(self::OUT_DIR . '/sale_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__ . ' OK ', FILE_APPEND);
+
+ $totalBonus = $back10 + $back20;
+
+ $input = [
+ 'phone' => $phone,
+ 'bonusCount' => $totalBonus,
+ 'purchaseDate' => date("Y-m-d H:i:s"),
+ 'orderId' => $check_id,
+ ];
+
+ $userBonusSendToTgLogs = new UserBonusSendToTgLogs;
+ $userBonusSendToTgLogs->input_hash = md5(Json::encode($input));
+ $userBonusSendToTgLogs->input = Json::encode($input);
+ $userBonusSendToTgLogs->check_id = $check_id;
+ $userBonusSendToTgLogs->phone = $phone;
+ $userBonusSendToTgLogs->bonusCount = $totalBonus;
+ $userBonusSendToTgLogs->status = 1;
+ $userBonusSendToTgLogs->date = date('Y-m-d H:I:s');
+ $userBonusSendToTgLogs->save();
+ if ($userBonusSendToTgLogs->getErrors()) {
+ LogService::apiErrorLog(json_encode(["error_id" => 100.001, "error" => $userBonusSendToTgLogs->getErrors()], JSON_UNESCAPED_UNICODE));
+ }
+ Yii::$app->queue->push(new SendBonusInfoToSiteJob($input));
+
+// SiteService::notifySiteAboutBonuses($phone, $totalBonus, date("Y-m-d H:i:s"), $check_id);
+
+ return $this->asJson($mess);
+ }
+
+ /**
+ * Создаёт новую запись в таблице UsersBonusLevels.
+ *
+ * @param Users $user
+ * @param string $bonusLevel
+ * @param string $check_id
+ * @param string $check_name
+ * @param string $createdAt
+ * @return bool
+ */
+ protected function createBonusHistoryRecord($user, $bonusLevel, $check_id, $check_name, $createdAt)
+ {
+ $bonusRecord = new UsersBonusLevels();
+ $bonusRecord->phone = $user->phone;
+ $bonusRecord->user_id = $user->id;
+ $bonusRecord->bonus_level = $bonusLevel;
+ $bonusRecord->date_from = $createdAt;
+ $bonusRecord->check_id = $check_id;
+ $bonusRecord->check_name = $check_name;
+ $bonusRecord->active = 1;
+
+ if (!$bonusRecord->save()) {
+ LogService::apiErrorLog(
+ json_encode(["error_id" => 100, "error" => $bonusRecord->getErrors()], JSON_UNESCAPED_UNICODE)
+ );
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Обновляет бонусный уровень пользователя.
+ *
+ * @param Users $user Модель пользователя.
+ * @param float $sale_price Текущая сумма покупок.
+ * @param string $check_id Идентификатор чека.
+ * @param string $check_name Имя (номер) чека.
+ */
+ protected function updateUserBonusLevel($user, $sale_price, $check_id, $check_name)
+ {
+ $bonusLevels = BonusLevels::find()
+ ->where(['active' => 1])
+ ->orderBy(['threshold' => SORT_ASC])
+ ->all();
+
+ $computedBonusLevel = null;
+ foreach ($bonusLevels as $level) {
+ if ($sale_price > $level->threshold) {
+ $computedBonusLevel = $level->alias;
+ }
+ }
+ $newBonusLevel = $computedBonusLevel ?? 'silver';
+
+ $existingHistoryLevel = UsersBonusLevels::find()
+ ->where(['or', ['phone' => $user->phone], ['user_id' => $user->id]])
+ ->andWhere(['active' => 1])
+ ->one();
+
+ $now = date('Y-m-d H:i:s');
+
+ if (empty($user->bonus_level) || $user->bonus_level !== $newBonusLevel) {
+ $user->bonus_level = $newBonusLevel;
+ if (!$user->save()) {
+ LogService::apiErrorLog(
+ json_encode(["error_id" => 6.1, "error" => $user->getErrors()], JSON_UNESCAPED_UNICODE)
+ );
+ }
+
+ if ($existingHistoryLevel) {
+ $existingHistoryLevel->active = 0;
+ $existingHistoryLevel->date_to = $now;
+ if (!$existingHistoryLevel->save()) {
+ LogService::apiErrorLog(
+ json_encode(
+ ["error_id" => 6.2, "error" => $existingHistoryLevel->getErrors()],
+ JSON_UNESCAPED_UNICODE
+ )
+ );
+ }
+ }
+
+ $this->createBonusHistoryRecord($user, $newBonusLevel, $check_id, $check_name, $now);
+ }
+ }
+
+ public function actionGetClientInfo()
+ {
+ Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
+ $data = file_get_contents('php://input');
+ $result = json_decode($data, true);
+
+ $__API_PARAMS = ['phone'];
+
+ foreach ($__API_PARAMS as $paramName) {
+ if (empty($result[$paramName])) {
+
+ if ($paramName != 'phone') {
+ LogService::apiErrorLog(json_encode(["error_id" => 1, "error" => "$paramName is required"], JSON_UNESCAPED_UNICODE));
+ }
+
+ return $this->asJson(["error_id" => 1, "error" => "$paramName is required"]);
+ }
+ }
+
+ $phone = ClientHelper::phoneClear($result['phone']);
+ if (!ClientHelper::phoneVerify($phone)) {
+ return $this->asJson(["error_id" => 1.2, "error" => "phone is required"]);
+ }
+
+ $mess = [];
+ $user = Users::find()->select(['id', 'keycode', 'bonus_level', 'burn_balans', 'name', 'referral_id', 'bdate', 'comment', 'pol', 'extract(epoch FROM date) as date'])
+ ->where(['phone' => $phone])->one();
+ if (!$user) {
+ $mess["error"] = "Покупателя " . $phone . " нет в бонусной программе!";
+
+ return $this->asJson($mess);
+ }
+ $name = explode(" ", $user->name);
+ $birth_day = $user->bdate;
+ $first_name = $name[0] ?? '';
+ $second_name = $name[1] ?? '';
+ $comment = $user->comment;
+ $pol = "male";
+ if ($user->pol == "women") {
+ $pol = "female";
+ }
+ // если с момента добавления клиента прошло не более 5 часов позволяем редактировать даты иначе запрещаем редактирование
+ if ($user->date > time() - 3600 * 5) {
+ $mess["birth_day_readonly"] = true;
+ $mess["events_readonly"] = false;
+ }
+ if ($birth_day) {
+ $mess["birth_day_readonly"] = true;
+ }
+
+ $data = UsersEvents::find()->where(['phone' => $phone])->orderBy(['date' => SORT_DESC])->all();
+ foreach ($data as $row) {
+ if (strlen($row->date_day) == 1) {
+ $row->date_day = "0" . $row->date_day;
+ }
+ if (strlen($row->date_month) == 1) {
+ $row->date_month = "0" . $row->date_month;
+ }
+ if (!isset($mess["events"])) {
+ $mess["events"] = [];
+ }
+ $mess["events"][] = ["date" => $row->date, "event_id" => $row->tip_id];
+ }
+
+ $user_balance = ClientHelper::getBonusBalance($phone);
+
+ $mess["result"] = true;
+ $mess["sex"] = $pol;
+ $mess["first_name"] = $first_name;
+ $mess["second_name"] = $second_name;
+ $mess["birth_day"] = $birth_day;
+ $mess["comment"] = $comment;
+ $mess["balance"] = $user_balance;
+ $mess["bonus_level"] = $user->bonus_level;
+ $mess["burn_balans"] = $user->burn_balans;
+
+ LogService::apiLogs(1, json_encode($mess, JSON_UNESCAPED_UNICODE));
+
+ return $this->asJson($mess);
+ }
+
+ public function actionReturn()
+ {
+ Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
+ $data = file_get_contents('php://input');
+ $result = json_decode($data, true);
+
+ $__API_PARAMS = ['store_id', 'check_id']; // check_name, seller_id
+
+ foreach ($__API_PARAMS as $paramName) {
+ if (!isset($result[$paramName])) {
+
+ LogService::apiErrorLog(json_encode(["error_id" => 1, "error" => "$paramName is required"], JSON_UNESCAPED_UNICODE));
+
+ return $this->asJson(["error_id" => 1, "error" => "$paramName is required"]);
+ }
+ }
+
+ $store_id = $result["store_id"];
+// $seller_id = $result["seller_id"] ?? '';
+ $check_id = $result["check_id"];
+// $check_name = $result["check_name"] ?? '';
+
+ UsersBonus::deleteAll(['and', ['check_id' => $check_id],
+ ['>', 'date', date('Y-m-d H:i:s', strtotime('-3 day', time()))]]);
+
+ // api_logs... event: return, seller_id, when, check
+
+ LogService::apiLogs(1, json_encode(['Удачный возврат'], JSON_UNESCAPED_UNICODE));
+
+ return $this->asJson(['ok']);
+ }
+
+ public function actionAuthCodeFail()
+ {
+ Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
+ $data = file_get_contents('php://input');
+ $result = json_decode($data, true);
+
+ $__API_PARAMS = [/*'store_id', 'seller_id',*/
+ 'phone'];
+
+ foreach ($__API_PARAMS as $paramName) {
+ if (empty($result[$paramName])) {
+
+ if ($paramName != 'phone') {
+ LogService::apiErrorLog(json_encode(["error_id" => 1, "error" => "$paramName is required"], JSON_UNESCAPED_UNICODE));
+ }
+
+ return $this->asJson(["error_id" => 1, "error" => "$paramName is required"]);
+ }
+ }
+
+ $phone = ClientHelper::phoneClear($result['phone']);
+ if (!ClientHelper::phoneVerify($phone)) {
+ return $this->asJson(["error_id" => 1.2, "error" => "phone is required"]);
+ }
+ $result['phone'] = $phone;
+
+// $seller_id = $result['seller_id'];
+// $store_id = $result['store_id'];
+
+ $user = Users::find()->where(['phone' => $result['phone']])->andWhere(['phone_true' => '1'])->one();
+ if (!$user) {
+ $mess["error"] = "Покупателя $phone нет в бонусной программе!";
+
+ return $this->asJson($mess);
+ }
+
+ $user->keycode = "" . rand(1000, 9999);
+ $user->save();
+
+ if ($user->getErrors()) {
+
+ LogService::apiErrorLog(json_encode(["error_id" => 3, "error" => $user->getErrors()], JSON_UNESCAPED_UNICODE));
+
+ return $this->asJson(["error_id" => 3, "error" => $user->getErrors()]);
+ }
+
+ $mess = [];
+ $mess["result"] = true;
+ // api_logs seller, store
+
+ LogService::apiLogs(1, json_encode($mess, JSON_UNESCAPED_UNICODE));
+
+ return $this->asJson($mess);
+ }
+
+ public function actionCurrentItems()
+ {
+ Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
+ $data = file_get_contents('php://input');
+ $result = json_decode($data, true);
+
+ $__API_PARAMS = ['store_id', 'seller_id', 'phone', 'amount_no_discount', 'amount_to_pay'];
+
+ foreach ($__API_PARAMS as $paramName) {
+ if (empty($result[$paramName])) {
+
+ if ($paramName != 'phone') {
+ LogService::apiErrorLog(json_encode(["error_id" => 1, "error" => "$paramName is required"], JSON_UNESCAPED_UNICODE));
+ }
+
+ return $this->asJson(["error_id" => 1, "error" => "$paramName is required"]);
+ }
+ }
+
+ $phone = ClientHelper::phoneClear($result['phone']);
+ if (!ClientHelper::phoneVerify($phone)) {
+ return $this->asJson(["error_id" => 1.2, "error" => "phone is required"]);
+ }
+ $result['phone'] = $phone;
+
+// $store_id = $result["store_id"];
+// $seller_id = $result["seller_id"];
+ $phone = $result["phone"];
+// $check_amount = intval($result["check_amount"] ?? 0);
+// $check_id = $result["check_id"] ?? '';
+// $check_name = $result["check_name"] ?? '';
+// $items = $result['items'] ?? [];
+
+ $mess = [];
+
+ $user = Users::find()->where(['phone' => $result['phone']])->andWhere(['phone_true' => '1'])->one();
+ if (!$user) {
+ $mess["error"] = "Покупателя $phone нет в бонусной программе!";
+
+ return $this->asJson($mess);
+ }
+
+// $user_balans = ClientHelper::getBonusBalance($phone);
+// $max = $itogo * self::$MAX_PROCENT; // максимально можем разрешить списывать до 30 процентов от суммы заказа
+// $max = ceil($max);
+// $available_bonus = $user_balans;
+// if ($available_bonus > $max) { // если баллов бонусов больше чем 30 процентов списываем по максимуму 30
+// $available_bonus = $max;
+// }
+// $baza = $check_amount - $available_bonus;
+// $back = ceil(self::$CREDIT_PROCENT * $baza);
+
+
+// foreach ($items as $k => $mass) {
+// $seller_id_item = $mass["seller_id"];
+// $product_id = $mass["product_id"];
+// $price = $mass["price"];
+// $quantity = $mass["quantity"];
+// $sm = $price * $quantity;
+// $info .=" id=$product_id ($quantity шт. x $price руб.) = $sm руб.,";
+// $itogo += $sm;
+//
+// //получаем внутренний ID товара
+// $item_id = ClientHelper::getExportId($product_id, "products",1);
+// }
+
+ LogService::apiLogs(1, json_encode($mess, JSON_UNESCAPED_UNICODE));
+
+ return $this->asJson(["NOT IMPLEMENTED"]);
+ }
+
+ public function actionGetSettings()
+ {
+ Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
+ $data = file_get_contents('php://input');
+ $result = json_decode($data, true);
+
+ $__API_PARAMS = ['store_id', 'seller_id'];
+
+ foreach ($__API_PARAMS as $paramName) {
+ if (!isset($result[$paramName])) {
+
+ LogService::apiErrorLog(json_encode(["error_id" => 1, "error" => "$paramName is required"], JSON_UNESCAPED_UNICODE));
+
+ return $this->asJson(["error_id" => 1, "error" => "$paramName is required"]);
+ }
+ }
+
+ $store_id = $result['store_id'];
+ $seller_id = $result['seller_id'];
+
+ $mess = [];
+ $mess["result"] = true;
+ $mess["attempts_auth_code"] = 5; // Количество возможных попыток ввода кода подтверждения
+ $mess["list_events"] = [
+ ["id" => 1, "name" => "День рождения"],
+ ["id" => 2, "name" => "8 марта"],
+ ["id" => 3, "name" => "День матери"],
+ ["id" => 4, "name" => "День влюбленных"],
+ ["id" => 5, "name" => "День свадьбы"],
+ ["id" => 6, "name" => "Другое"]
+ ];
+ $mess["send_current_items"] = false; // Отправлять или нет текущие позиции чека
+
+ LogService::apiLogs(1, json_encode($mess, JSON_UNESCAPED_UNICODE));
+
+ return $this->asJson($mess);
+ }
+
+ public function actionGetUnusedNumenclatur() {
+ $items_arr_no = array_values(ArrayHelper::map(
+ UniversalCatalogItem::find()->where(['catalog_alias' => 'unused_nomenclature'])->all(), 'guid', 'guid'));
+ return $this->asJson(['unused_nomenclature' => $items_arr_no]);
+ }
+
+ public function actionGetContest001Participant() {
+ Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
+
+ $request = Yii::$app->request->getRawBody();
+
+ try {
+ $result = Json::decode($request);
+ } catch (\Exception $ex) {
+ return $this->asJson(['error' => ['code' => 400, 'message' => 'Json body invalid']]);
+ }
+
+ if (!isset($result['phone'])) {
+ return $this->asJson(["error_id" => 1, "error" => "phone is required"]);
+ }
+
+ $phone = ClientHelper::phoneClear($result['phone']);
+ if (!ClientHelper::phoneVerify($phone)) {
+ return $this->asJson(["error_id" => 1.2, "error" => "phone is required"]);
+ }
+ $result['phone'] = $phone;
+
+ $mess = [];
+
+ $contestants = Contest001::find()->where(['phone' => $phone])->all();
+ if (count($contestants) > 0) {
+ $mess['is_participant'] = true;
+ $raffle_numbers = [];
+ foreach ($contestants as $contestant) {
+ $raffle_numbers[] = $contestant->number;
+ }
+ $mess['raffle_numbers'] = implode(', ', $raffle_numbers);
+ } else {
+ $mess['is_participant'] = false;
+ }
+
+ LogService::apiLogs(1, json_encode($mess, JSON_UNESCAPED_UNICODE));
+
+ return $this->asJson(['response' => $mess]);
+ }
+
+ public function actionAdd() {
+ Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
+
+ $request = Yii::$app->request->getRawBody();
+
+ $requestTest = json_decode(\Yii::$app->getRequest()->getRawBody(), true);
+
+ $fl = date('_Y_m_d__H_i_s_');
+
+ file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', implode(',', $requestTest));
+ file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ try {
+ $result = Json::decode($request);
+ file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ } catch (\Exception $ex) {
+ file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ return $this->asJson(['error' => ['code' => 400, 'message' => 'Json body invalid']]);
+ }
+
+ $__API_PARAMS = ['phone', 'description', 'tip_sale', 'bonus', 'date_end'];
+
+ foreach ($__API_PARAMS as $paramName) {
+ if (!isset($result[$paramName])) {
+ file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ if ($paramName != 'phone') {
+ file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ LogService::apiErrorLog(json_encode(["error_id" => 1, "error" => "$paramName is required"], JSON_UNESCAPED_UNICODE));
+ }
+ file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ return $this->asJson(["error_id" => 1, "error" => "$paramName is required"]);
+ }
+ }
+ file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ //
+ if (!in_array($result['tip_sale'], ['podarok', 'senat', 'nino802', 'sale', '14feb', '23feb', '8mar', 'quest001'])) {
+ file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ return $this->asJson(["error_id" => 1.1, "error" => "tip_sale не разрешён (podarok, senat, nino802)"]);
+ }
+
+ $phone = ClientHelper::phoneClear($result['phone']);
+ file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ if (!ClientHelper::phoneVerify($phone)) {
+ file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ return $this->asJson(["error_id" => 1.2, "error" => "phone is required"]);
+ }
+ $result['phone'] = $phone;
+
+ $stop = UsersStopList::find()->select(['phone'])->where(['phone' => $result['phone']])->one();
+ file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ if ($stop) {
+ file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ return $this->asJson(["error_id" => 4, "error" => 'Номер телефона числится в стоп листе']);
+ }
+
+ $bonus = min((int)$result['bonus'], 1000);
+ file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $found = UsersBonus::find()->where(['phone' => $phone])->andWhere(['>=', 'date_start', date('Y-m-d H:i:s', time() - self::$YEAR_PERIOD * 86400)])
+ ->andWhere(['tip_sale' => $result['tip_sale']])->andWhere(['tip' => 'plus'])->andWhere(['bonus' => $bonus])->one();
+ file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ if ($found) {
+ file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ return $this->asJson(["error_id" => 3, "error" => 'Бонусы уже начисляли']);
+ }
+ file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ $userBonus = new UsersBonus;
+ $userBonus->phone = $phone;
+ $userBonus->name = $result['description'];
+ $userBonus->date = date('Y-m-d H:i:s');
+ $userBonus->site_id = 1;
+ $userBonus->setka_id = 1;
+ $userBonus->tip = 'plus';
+ $userBonus->tip_sale = $result['tip_sale'];
+ $userBonus->bonus = $bonus;
+
+ $userBonusDateStart = $result['date_start'] ?? $userBonus->date;
+ $userBonus->date_start = date('Y-m-d H:i:s', strtotime($userBonusDateStart));
+
+ $userBonusDateEnd = $result['date_end'];
+ $userBonus->date_end = date('Y-m-d H:i:s', strtotime($userBonusDateEnd));
+
+ $userBonus->save();
+ file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ if ($userBonus->getErrors()) {
+ file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__, FILE_APPEND);
+ LogService::apiErrorLog(json_encode(["error_id" => 2, "error" => $userBonus->getErrors()], JSON_UNESCAPED_UNICODE));
+ return $this->asJson(["error_id" => 2, "error" => $userBonus->getErrors()]);
+ }
+ file_put_contents(self::OUT_DIR . '/add_bonuses_' . $fl . '.json', PHP_EOL . '--' . __LINE__ . ' OK', FILE_APPEND);
+ return $this->asJson(['response' => true]);
+ }
+
+ /**
+ * TO8-22: Активация промокода БЛАГО.
+ * POST /bonus/activate-promocode
+ * Параметры: phone, code
+ *
+ * Логика:
+ * 1. Найти промокод по коду
+ * 2. Проверить isActivatable()
+ * 3. Найти клиента по телефону
+ * 4. В транзакции: начислить 350 промо-бонусов (tip_sale='promobonus'), пометить промокод used=1
+ */
+ public function actionActivatePromocode()
+ {
+ Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
+ $data = file_get_contents('php://input');
+ $result = json_decode($data, true);
+
+ if (empty($result['code'])) {
+ return $this->asJson(["error_id" => 1, "error" => "code is required"]);
+ }
+ if (empty($result['phone'])) {
+ return $this->asJson(["error_id" => 4, "error" => "phone is required"]);
+ }
+
+ $phone = ClientHelper::phoneClear($result['phone']);
+ if (!ClientHelper::phoneVerify($phone)) {
+ return $this->asJson(["error_id" => 4, "error" => "phone is not valid"]);
+ }
+
+ $user = Users::find()
+ ->where(['phone' => $phone])
+ ->andWhere(['phone_true' => '1'])
+ ->one();
+
+ if (!$user) {
+ return $this->asJson(["error_id" => 4, "error" => "Пользователь с телефоном $phone не найден"]);
+ }
+
+ $transaction = Yii::$app->db->beginTransaction();
+ try {
+ // SELECT FOR UPDATE — блокируем строку промокода от параллельной активации
+ $promocode = Promocode::find()
+ ->where(['code' => $result['code']])
+ ->forUpdate()
+ ->one();
+
+ if (!$promocode) {
+ $transaction->rollBack();
+ return $this->asJson(["error_id" => 1, "error" => "Промокод не найден"]);
+ }
+
+ $activatable = $promocode->isActivatable();
+ if ($activatable !== true) {
+ $transaction->rollBack();
+ $errorMessages = [
+ 1 => "Промокод неактивен",
+ 2 => "Промокод уже использован",
+ 3 => "Срок действия промокода истёк",
+ ];
+ return $this->asJson([
+ "error_id" => $activatable,
+ "error" => $errorMessages[$activatable] ?? "Промокод недоступен",
+ ]);
+ }
+
+ $bonusAmount = $promocode->bonus ?: 350;
+ $duration = $promocode->duration ?: self::$YEAR_PERIOD;
+
+ $usersBonus = new UsersBonus();
+ $usersBonus->phone = $phone;
+ $usersBonus->name = "Активация промокода {$promocode->code}";
+ $usersBonus->date = date('Y-m-d H:i:s');
+ $usersBonus->tip = 'plus';
+ $usersBonus->tip_sale = Promocode::TIP_SALE_PROMOBONUS;
+ $usersBonus->bonus = $bonusAmount;
+ $usersBonus->price = 0;
+ $usersBonus->price_skidka = 0;
+ $usersBonus->user_id = $user->id;
+ $usersBonus->store_id = 0;
+ $usersBonus->site_id = 0;
+ $usersBonus->setka_id = 0;
+ $usersBonus->referal_id = 0;
+ $usersBonus->admin_id = 0;
+ $usersBonus->lid_id = 0;
+ $usersBonus->date_start = date('Y-m-d H:i:s');
+ $usersBonus->date_end = date('Y-m-d H:i:s', strtotime('+' . $duration . ' day'));
+ $usersBonus->date_dell = $usersBonus->date_end;
+ $usersBonus->ip = $_SERVER['REMOTE_ADDR'] ?? '';
+
+ if (!$usersBonus->save()) {
+ throw new \Exception('Ошибка сохранения бонуса: ' . json_encode($usersBonus->getErrors()));
+ }
+
+ $promocode->used = Promocode::USED_YES;
+ $promocode->activated_by = $user->id;
+ $promocode->activated_at = date('Y-m-d H:i:s');
+ if (!$promocode->save(false)) {
+ throw new \Exception('Ошибка обновления промокода: ' . json_encode($promocode->getErrors()));
+ }
+
+ $transaction->commit();
+
+ Yii::info("Промокод {$promocode->code} активирован для {$phone}, бонус={$bonusAmount}", self::LOG_CATEGORY_BONUS);
+
+ return $this->asJson([
+ "success" => true,
+ "bonus" => $bonusAmount,
+ "message" => "Промокод активирован, начислено {$bonusAmount} бонусов",
+ ]);
+ } catch (\Exception $e) {
+ $transaction->rollBack();
+ LogService::apiErrorLog(json_encode([
+ "error_id" => 10,
+ "error" => $e->getMessage(),
+ "phone" => $phone,
+ "code" => $result['code'],
+ ], JSON_UNESCAPED_UNICODE));
+ return $this->asJson(["error_id" => 10, "error" => "Ошибка активации промокода"]);
+ }
+ }
+}