fix kashkool

This commit is contained in:
2026-06-30 21:44:39 +03:30
parent 4a697af4c7
commit cd81ea8af0
9 changed files with 130 additions and 86 deletions
@@ -360,11 +360,12 @@ class ProductController extends SuperController
public function activationSnapshotStatus() public function activationSnapshotStatus()
{ {
$row = Cnt::where('key', self::ACTIVATION_SNAPSHOT_KEY)->first(); $row = Cnt::where('key', self::ACTIVATION_SNAPSHOT_KEY)->first();
$items = $row?->value_json['items'] ?? []; $payload = $row?->jsonPayload() ?? [];
$items = $payload['items'] ?? [];
return response()->json([ return response()->json([
'has_snapshot' => ! empty($items), 'has_snapshot' => ! empty($items),
'saved_at' => $row?->value_json['saved_at'] ?? null, 'saved_at' => $payload['saved_at'] ?? null,
'count' => count($items), 'count' => count($items),
]); ]);
} }
@@ -387,15 +388,13 @@ class ProductController extends SuperController
'open_sell' => (bool) $product->open_sell, 'open_sell' => (bool) $product->open_sell,
])->values()->all(); ])->values()->all();
Cnt::updateOrCreate( Cnt::saveJsonPayload(
['key' => self::ACTIVATION_SNAPSHOT_KEY], self::ACTIVATION_SNAPSHOT_KEY,
[ [
'title_fa' => 'ذخیره وضعیت محصولات', 'saved_at' => now()->timezone('Asia/Tehran')->format('Y-m-d H:i:s'),
'value_json' => [ 'items' => $items,
'saved_at' => now()->timezone('Asia/Tehran')->format('Y-m-d H:i:s'), ],
'items' => $items, 'ذخیره وضعیت محصولات'
],
]
); );
$affected = Product::query()->update([ $affected = Product::query()->update([
@@ -418,7 +417,7 @@ class ProductController extends SuperController
public function restoreActivationSnapshot() public function restoreActivationSnapshot()
{ {
$row = Cnt::where('key', self::ACTIVATION_SNAPSHOT_KEY)->first(); $row = Cnt::where('key', self::ACTIVATION_SNAPSHOT_KEY)->first();
$items = $row?->value_json['items'] ?? []; $items = $row?->jsonPayload()['items'] ?? [];
if (empty($items)) { if (empty($items)) {
return response()->json(['error' => 'اسنAPSHOTی برای بازگردانی وجود ندارد.'], 422); return response()->json(['error' => 'اسنAPSHOTی برای بازگردانی وجود ندارد.'], 422);
+1 -1
View File
@@ -164,7 +164,7 @@ class AuthController extends Controller
return response()->json(['message' => 'کد نامعتبر می باشد'], 422); return response()->json(['message' => 'کد نامعتبر می باشد'], 422);
} }
} else { } else {
if ($this->Config('referral_id') == 'required') { if ($cfg->isReferralRequired()) {
return response()->json(['message' => 'کد معرف اجباریست'], 422); return response()->json(['message' => 'کد معرف اجباریست'], 422);
} }
} }
+1 -53
View File
@@ -494,15 +494,13 @@ class ReportController extends Controller
} }
/** /**
* فروشگاه — منطق lastPrice قبل مرج (ghatreh): montzar_price / nasiryan / prices * فروشگاه — منطق lastPrice: montzar_price / prices
*/ */
protected function storeLastPrice(ConfigService $config): array protected function storeLastPrice(ConfigService $config): array
{ {
$toBool = fn ($value) => filter_var($value, FILTER_VALIDATE_BOOLEAN); $toBool = fn ($value) => filter_var($value, FILTER_VALIDATE_BOOLEAN);
$difference = (float) config('fee.single');
$talaIr = 0; $talaIr = 0;
$nasiryan = 0;
$montzar = 0; $montzar = 0;
$montzarExists = Setting::where('key', 'montzar_price')->exists(); $montzarExists = Setting::where('key', 'montzar_price')->exists();
@@ -560,58 +558,9 @@ class ReportController extends Controller
} }
} }
$nasiryanEnabled = $config->Config('price_from_nasiryan') == 'true';
if ($nasiryanEnabled) {
try {
$nasiryanRes = Http::withoutVerifying()
->timeout(2)
->withToken(Cnt::where('key', 'nasiryan')->first()['value'] ?? '')
->get('https://nasiryan.com/server/customer/product/list')
->json();
if ((isset($nasiryanRes['message']) && $nasiryanRes['message'] == 'no authorised') || $nasiryanRes == null) {
$cnt = new Cnt();
$cnt->nasiryan_login();
$nasiryanRes = Http::withoutVerifying()
->timeout(2)
->withToken(Cnt::where('key', 'nasiryan')->first()['value'] ?? '')
->get('https://nasiryan.com/server/customer/product/list')
->json();
}
$lp = collect($nasiryanRes)->firstWhere('id', 1);
if (! $lp || ! isset($lp['sub_agent'])) {
throw new \Exception('Nasiryan product/sub_agent not found');
}
$buy = (float) $lp['sub_agent']['rate_buy_gram_price'];
$sell = (float) $lp['sub_agent']['rate_sell_gram_price'];
$customPrice = [
'price' => ($buy + $sell) / 2,
'diff' => ($buy - $sell) / 2,
];
Cnt::where('key', 'nasiryan_price')->update(['value' => (float) $customPrice['price']]);
Cnt::where('key', 'nasiryan_diff')->update(['value' => (float) $customPrice['diff']]);
Cnt::where('key', 'nasiryan_mazaneh')->update(['value' => ((float) $customPrice['price'] * 4.331802)]);
Cnt::where('key', 'nasiryan_truly_buy_mazaneh')->update(['value' => $lp['sub_agent']['rate_buy_price']]);
Cnt::where('key', 'nasiryan_truly_sell_mazaneh')->update(['value' => $lp['sub_agent']['rate_sell_price']]);
Cnt::where('key', 'log')->update(['value' => json_encode($nasiryanRes, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)]);
$nasiryan = (int) $customPrice['price'];
Cnt::where('key', 'nasiryan_closed')->update(['value' => $nasiryan == 0 ? 'true' : 'false']);
} catch (\Throwable $e) {
$nasiryan = 0;
Cnt::where('key', 'nasiryan_closed')->update(['value' => 'true']);
}
}
if ($montzarEnabled && $montzar !== 0) { if ($montzarEnabled && $montzar !== 0) {
$priceValue = $montzar; $priceValue = $montzar;
$priceSource = 'montzar'; $priceSource = 'montzar';
} elseif ($nasiryanEnabled && $nasiryan !== 0) {
$priceValue = $nasiryan;
$priceSource = 'nasiryan';
} else { } else {
$priceValue = $talaIr; $priceValue = $talaIr;
$priceSource = 'tala_ir'; $priceSource = 'tala_ir';
@@ -637,7 +586,6 @@ class ReportController extends Controller
'price_last' => $display['priceLast'], 'price_last' => $display['priceLast'],
'price' => $priceValue, 'price' => $priceValue,
'tala_ir' => $talaIr, 'tala_ir' => $talaIr,
'nasiryan' => $nasiryan,
]; ];
if ($montzarExists) { if ($montzarExists) {
+6 -1
View File
@@ -54,8 +54,13 @@ class ValidationMiddleware
private function fa2en_numbers($input) { private function fa2en_numbers($input) {
if (is_string($input)) { if (is_string($input)) {
$fa_numbers = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹']; $fa_numbers = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'];
$ar_numbers = ['٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩'];
$en_numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; $en_numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
return str_replace($fa_numbers, $en_numbers, $input); $input = str_replace($fa_numbers, $en_numbers, $input);
$input = str_replace($ar_numbers, $en_numbers, $input);
$input = str_replace('٫', '.', $input);
return $input;
} elseif (is_array($input)) { } elseif (is_array($input)) {
return array_map([$this, __FUNCTION__], $input); return array_map([$this, __FUNCTION__], $input);
} else { } else {
+56 -4
View File
@@ -2,22 +2,74 @@
namespace App\Models; namespace App\Models;
use App\Http\Controllers\Controller;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Schema;
class Cnt extends Model class Cnt extends Model
{ {
use HasFactory; use HasFactory;
private static ?bool $valueJsonColumnExists = null;
protected $table = 'const'; protected $table = 'const';
protected $fillable = [ protected $fillable = [
'key', 'key',
'title_fa', 'title_fa',
'value', 'value',
'value_json' 'value_json',
]; ];
protected $casts = [ protected $casts = [
'value_json'=>'array' 'value_json' => 'array',
]; ];
public static function hasValueJsonColumn(): bool
{
if (static::$valueJsonColumnExists !== null) {
return static::$valueJsonColumnExists;
}
try {
static::$valueJsonColumnExists = Schema::hasColumn((new static)->getTable(), 'value_json');
} catch (\Throwable) {
static::$valueJsonColumnExists = false;
}
return static::$valueJsonColumnExists;
}
public function jsonPayload(): array
{
if (static::hasValueJsonColumn() && is_array($this->value_json)) {
return $this->value_json;
}
$raw = $this->value ?? '';
if ($raw === '' || $raw === null) {
return [];
}
$decoded = json_decode((string) $raw, true);
return is_array($decoded) ? $decoded : [];
}
public static function saveJsonPayload(string $key, array $payload, ?string $titleFa = null): self
{
$data = [];
if ($titleFa !== null) {
$data['title_fa'] = $titleFa;
}
if (static::hasValueJsonColumn()) {
$data['value_json'] = $payload;
} else {
$data['value'] = json_encode($payload, JSON_UNESCAPED_UNICODE);
}
return static::updateOrCreate(['key' => $key], $data);
}
} }
+6
View File
@@ -63,6 +63,12 @@ class ConfigService
return $this->getBool('is_store', false); return $this->getBool('is_store', false);
} }
/** کد معرف در ثبت‌نام اجباری است (تنظیم referral_id = required) */
public function isReferralRequired(): bool
{
return strtolower(trim($this->getString('referral_id'))) === 'required';
}
public function getInt(string $key, int $default = 0): int public function getInt(string $key, int $default = 0): int
{ {
$value = $this->get($key, $default); $value = $this->get($key, $default);
@@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
if (! Schema::hasTable('const') || Schema::hasColumn('const', 'value_json')) {
return;
}
Schema::table('const', function (Blueprint $table) {
if (Schema::hasColumn('const', 'value')) {
$table->json('value_json')->nullable()->after('value');
} else {
$table->json('value_json')->nullable();
}
});
}
public function down(): void
{
if (! Schema::hasTable('const') || ! Schema::hasColumn('const', 'value_json')) {
return;
}
Schema::table('const', function (Blueprint $table) {
$table->dropColumn('value_json');
});
}
};
+8 -8
View File
@@ -942,14 +942,14 @@ UPDATE `settings` SET `description` = 'شناسه عددی یا نام reading_m
UPDATE `settings` SET `description` = 'آدرس پایه API سرویس تابلو آنلاین (بدون مسیر انتهایی). مثال: https://example.com/api' WHERE `key` = 'zaarbox_api_url'; UPDATE `settings` SET `description` = 'آدرس پایه API سرویس تابلو آنلاین (بدون مسیر انتهایی). مثال: https://example.com/api' WHERE `key` = 'zaarbox_api_url';
UPDATE `settings` SET `description` = 'کلید یا UUID ردیف قیمت در پاسخ API تابلو. باید با محصول/ردیف موردنظر در سرویس خارجی یکسان باشد.' WHERE `key` = 'zaarbox_price_key'; UPDATE `settings` SET `description` = 'کلید یا UUID ردیف قیمت در پاسخ API تابلو. باید با محصول/ردیف موردنظر در سرویس خارجی یکسان باشد.' WHERE `key` = 'zaarbox_price_key';
UPDATE `settings` SET `description` = 'روشن: اگر API قیمت در دسترس نباشد، آخرین قیمت ذخیره‌شده در دیتابیس به کاربر نشان داده می‌شود. خاموش: در قطعی API ممکن است قیمت صفر نمایش داده شود.' WHERE `key` = 'show_last_price'; UPDATE `settings` SET `description` = 'روشن: اگر API قیمت در دسترس نباشد، آخرین قیمت ذخیره‌شده در دیتابیس به کاربر نشان داده می‌شود. خاموش: در قطعی API ممکن است قیمت صفر نمایش داده شود.' WHERE `key` = 'show_last_price';
UPDATE `settings` SET `description` = 'روشن: خارج از بازه startDay تا endDay معامله و نمایش قیمت بسته می‌شود. خاموش: محدودیت ساعتی اعمال نمی‌شود.' WHERE `key` = 'close_price'; UPDATE `settings` SET `description` = 'روشن: خارج از بازه «ساعت شروع» تا «ساعت پایان» معامله و نمایش قیمت بسته می‌شود. خاموش: محدودیت ساعتی سراسری اعمال نمی‌شود.' WHERE `key` = 'close_price';
UPDATE `settings` SET `description` = 'ساعت شروع بازه معامله روزانه (فرمت 24 ساعته، مثال 09:00). فقط وقتی close_price روشن باشد اثر دارد.' WHERE `key` = 'startDay'; UPDATE `settings` SET `description` = 'ساعت شروع فعالیت روزانه. فقط وقتی «بستن خودکار خارج از ساعت کاری» روشن باشد اعمال می‌شود (مثلاً ۰۹:۰۰).' WHERE `key` = 'startDay';
UPDATE `settings` SET `description` = 'ساعت پایان بازه معامله روزانه (فرمت 24 ساعته، مثال 22:00). فقط وقتی close_price روشن باشد اثر دارد.' WHERE `key` = 'endDay'; UPDATE `settings` SET `description` = 'ساعت پایان فعالیت روزانه. فقط وقتی «بستن خودکار خارج از ساعت کاری» روشن باشد اعمال می‌شود (مثلاً ۲۲:۰۰).' WHERE `key` = 'endDay';
UPDATE `settings` SET `description` = 'اختلاف پایه (ریال) برای محاسبه قیمت خرید و فروش نمایشی روی مظنه. معمولاً نصف فاصله اسپرد کل است.' WHERE `key` = 'fee_single'; UPDATE `settings` SET `description` = 'اختلاف پایه (ریال) بین قیمت خرید و فروش روی مظنه. معمولاً نصف فاصله اسپرد کل است.' WHERE `key` = 'fee_single';
UPDATE `settings` SET `description` = 'مبلغ اضافه (ریال) روی قیمت پایه برای نمایش/محاسبه سمت خرید. خالی = استفاده از fee_single.' WHERE `key` = 'buy_fee'; UPDATE `settings` SET `description` = 'مبلغ اضافه (ریال) روی قیمت پایه برای سمت خرید. خالی = استفاده از «اختلاف پایه».' WHERE `key` = 'buy_fee';
UPDATE `settings` SET `description` = 'مبلغ کسر (ریال) از قیمت پایه برای نمایش/محاسبه سمت فروش. خالی = استفاده از fee_single.' WHERE `key` = 'sell_fee'; UPDATE `settings` SET `description` = 'مبلغ کسر (ریال) از قیمت پایه برای سمت فروش. خالی = استفاده از «اختلاف پایه».' WHERE `key` = 'sell_fee';
UPDATE `settings` SET `description` = 'کارمزد ثابت ریالی هر سفارش (legacy). در صورت تنظیم fee_service_charge_percentage معمولاً اولویت با درصد است.' WHERE `key` = 'fee_cash'; UPDATE `settings` SET `description` = 'کارمزد ثابت ریالی هر سفارش (قدیمی). اگر «درصد کارمزد معامله» تنظیم شده باشد، معمولاً اولویت با درصد است.' WHERE `key` = 'fee_cash';
UPDATE `settings` SET `description` = 'درصد کارمزد هر سفارش از مبلغ معامله (اعشاری، مثال 0.005 یعنی ۰٫۵٪). روی payment_amount اعمال می‌شود.' WHERE `key` = 'fee_service_charge_percentage'; UPDATE `settings` SET `description` = 'درصد کارمزد هر سفارش از مبلغ معامله (اعشاری؛ مثلاً ۰٫۰۰۵ یعنی نیم در هزار).' WHERE `key` = 'fee_service_charge_percentage';
UPDATE `settings` SET `description` = 'تعداد اولین سفارش‌های هر کاربر که از کارمزد معاف می‌شوند. ۰ = غیرفعال.' WHERE `key` = 'fee_free'; UPDATE `settings` SET `description` = 'تعداد اولین سفارش‌های هر کاربر که از کارمزد معاف می‌شوند. ۰ = غیرفعال.' WHERE `key` = 'fee_free';
UPDATE `settings` SET `description` = 'حداقل مبلغ درخواست برداشت وجه (ریال). درخواست‌های کمتر رد می‌شوند.' WHERE `key` = 'min_withdraw'; UPDATE `settings` SET `description` = 'حداقل مبلغ درخواست برداشت وجه (ریال). درخواست‌های کمتر رد می‌شوند.' WHERE `key` = 'min_withdraw';
UPDATE `settings` SET `description` = 'حداقل مبلغ اولین خرید هر کاربر (ریال). برای فعال‌سازی کیف یا احراز سطح اول استفاده می‌شود.' WHERE `key` = 'min_first_buy'; UPDATE `settings` SET `description` = 'حداقل مبلغ اولین خرید هر کاربر (ریال). برای فعال‌سازی کیف یا احراز سطح اول استفاده می‌شود.' WHERE `key` = 'min_first_buy';
@@ -945,14 +945,14 @@ UPDATE `settings` SET `description` = 'شناسه عددی یا نام reading_m
UPDATE `settings` SET `description` = 'آدرس پایه API سرویس تابلو آنلاین (بدون مسیر انتهایی). مثال: https://example.com/api' WHERE `key` = 'zaarbox_api_url'; UPDATE `settings` SET `description` = 'آدرس پایه API سرویس تابلو آنلاین (بدون مسیر انتهایی). مثال: https://example.com/api' WHERE `key` = 'zaarbox_api_url';
UPDATE `settings` SET `description` = 'کلید یا UUID ردیف قیمت در پاسخ API تابلو. باید با محصول/ردیف موردنظر در سرویس خارجی یکسان باشد.' WHERE `key` = 'zaarbox_price_key'; UPDATE `settings` SET `description` = 'کلید یا UUID ردیف قیمت در پاسخ API تابلو. باید با محصول/ردیف موردنظر در سرویس خارجی یکسان باشد.' WHERE `key` = 'zaarbox_price_key';
UPDATE `settings` SET `description` = 'روشن: اگر API قیمت در دسترس نباشد، آخرین قیمت ذخیره‌شده در دیتابیس به کاربر نشان داده می‌شود. خاموش: در قطعی API ممکن است قیمت صفر نمایش داده شود.' WHERE `key` = 'show_last_price'; UPDATE `settings` SET `description` = 'روشن: اگر API قیمت در دسترس نباشد، آخرین قیمت ذخیره‌شده در دیتابیس به کاربر نشان داده می‌شود. خاموش: در قطعی API ممکن است قیمت صفر نمایش داده شود.' WHERE `key` = 'show_last_price';
UPDATE `settings` SET `description` = 'روشن: خارج از بازه startDay تا endDay معامله و نمایش قیمت بسته می‌شود. خاموش: محدودیت ساعتی اعمال نمی‌شود.' WHERE `key` = 'close_price'; UPDATE `settings` SET `description` = 'روشن: خارج از بازه «ساعت شروع» تا «ساعت پایان» معامله و نمایش قیمت بسته می‌شود. خاموش: محدودیت ساعتی سراسری اعمال نمی‌شود.' WHERE `key` = 'close_price';
UPDATE `settings` SET `description` = 'ساعت شروع بازه معامله روزانه (فرمت 24 ساعته، مثال 09:00). فقط وقتی close_price روشن باشد اثر دارد.' WHERE `key` = 'startDay'; UPDATE `settings` SET `description` = 'ساعت شروع فعالیت روزانه. فقط وقتی «بستن خودکار خارج از ساعت کاری» روشن باشد اعمال می‌شود (مثلاً ۰۹:۰۰).' WHERE `key` = 'startDay';
UPDATE `settings` SET `description` = 'ساعت پایان بازه معامله روزانه (فرمت 24 ساعته، مثال 22:00). فقط وقتی close_price روشن باشد اثر دارد.' WHERE `key` = 'endDay'; UPDATE `settings` SET `description` = 'ساعت پایان فعالیت روزانه. فقط وقتی «بستن خودکار خارج از ساعت کاری» روشن باشد اعمال می‌شود (مثلاً ۲۲:۰۰).' WHERE `key` = 'endDay';
UPDATE `settings` SET `description` = 'اختلاف پایه (ریال) برای محاسبه قیمت خرید و فروش نمایشی روی مظنه. معمولاً نصف فاصله اسپرد کل است.' WHERE `key` = 'fee_single'; UPDATE `settings` SET `description` = 'اختلاف پایه (ریال) بین قیمت خرید و فروش روی مظنه. معمولاً نصف فاصله اسپرد کل است.' WHERE `key` = 'fee_single';
UPDATE `settings` SET `description` = 'مبلغ اضافه (ریال) روی قیمت پایه برای نمایش/محاسبه سمت خرید. خالی = استفاده از fee_single.' WHERE `key` = 'buy_fee'; UPDATE `settings` SET `description` = 'مبلغ اضافه (ریال) روی قیمت پایه برای سمت خرید. خالی = استفاده از «اختلاف پایه».' WHERE `key` = 'buy_fee';
UPDATE `settings` SET `description` = 'مبلغ کسر (ریال) از قیمت پایه برای نمایش/محاسبه سمت فروش. خالی = استفاده از fee_single.' WHERE `key` = 'sell_fee'; UPDATE `settings` SET `description` = 'مبلغ کسر (ریال) از قیمت پایه برای سمت فروش. خالی = استفاده از «اختلاف پایه».' WHERE `key` = 'sell_fee';
UPDATE `settings` SET `description` = 'کارمزد ثابت ریالی هر سفارش (legacy). در صورت تنظیم fee_service_charge_percentage معمولاً اولویت با درصد است.' WHERE `key` = 'fee_cash'; UPDATE `settings` SET `description` = 'کارمزد ثابت ریالی هر سفارش (قدیمی). اگر «درصد کارمزد معامله» تنظیم شده باشد، معمولاً اولویت با درصد است.' WHERE `key` = 'fee_cash';
UPDATE `settings` SET `description` = 'درصد کارمزد هر سفارش از مبلغ معامله (اعشاری، مثال 0.005 یعنی ۰٫۵٪). روی payment_amount اعمال می‌شود.' WHERE `key` = 'fee_service_charge_percentage'; UPDATE `settings` SET `description` = 'درصد کارمزد هر سفارش از مبلغ معامله (اعشاری؛ مثلاً ۰٫۰۰۵ یعنی نیم در هزار).' WHERE `key` = 'fee_service_charge_percentage';
UPDATE `settings` SET `description` = 'تعداد اولین سفارش‌های هر کاربر که از کارمزد معاف می‌شوند. ۰ = غیرفعال.' WHERE `key` = 'fee_free'; UPDATE `settings` SET `description` = 'تعداد اولین سفارش‌های هر کاربر که از کارمزد معاف می‌شوند. ۰ = غیرفعال.' WHERE `key` = 'fee_free';
UPDATE `settings` SET `description` = 'حداقل مبلغ درخواست برداشت وجه (ریال). درخواست‌های کمتر رد می‌شوند.' WHERE `key` = 'min_withdraw'; UPDATE `settings` SET `description` = 'حداقل مبلغ درخواست برداشت وجه (ریال). درخواست‌های کمتر رد می‌شوند.' WHERE `key` = 'min_withdraw';
UPDATE `settings` SET `description` = 'حداقل مبلغ اولین خرید هر کاربر (ریال). برای فعال‌سازی کیف یا احراز سطح اول استفاده می‌شود.' WHERE `key` = 'min_first_buy'; UPDATE `settings` SET `description` = 'حداقل مبلغ اولین خرید هر کاربر (ریال). برای فعال‌سازی کیف یا احراز سطح اول استفاده می‌شود.' WHERE `key` = 'min_first_buy';