diff --git a/app/Console/Commands/GivePendingReferralGiftCommand.php b/app/Console/Commands/GivePendingReferralGiftCommand.php index 66a1be8..e884d5e 100644 --- a/app/Console/Commands/GivePendingReferralGiftCommand.php +++ b/app/Console/Commands/GivePendingReferralGiftCommand.php @@ -39,7 +39,7 @@ class GivePendingReferralGiftCommand extends Command $already = TransactionsAdmin::where('customer_id', $customer->id) ->where('customer_to_id', $referrer->id) - ->where('note', 'پاداش بابت معرفی') + ->whereIn('note', \App\Http\Controllers\Controller::accountingReferralRewardDescAliases()) ->exists(); if ($already) { @@ -58,7 +58,7 @@ class GivePendingReferralGiftCommand extends Command $given = TransactionsAdmin::where('customer_id', $customer->id) ->where('customer_to_id', $referrer->id) - ->where('note', 'پاداش بابت معرفی') + ->whereIn('note', \App\Http\Controllers\Controller::accountingReferralRewardDescAliases()) ->exists(); if ($given) { diff --git a/app/Http/Controllers/Admin/TahesabController.php b/app/Http/Controllers/Admin/TahesabController.php index e9856ef..16354de 100644 --- a/app/Http/Controllers/Admin/TahesabController.php +++ b/app/Http/Controllers/Admin/TahesabController.php @@ -575,9 +575,11 @@ class TahesabController extends Controller $customer = Customer::where('id', $data['customer_id'])->first(); } $data['handler'] = 'wallet'; + $isDeposit = (int) ($data['direction'] ?? 0) === 0; + $sharh = self::accountingWalletDesc($isDeposit, $data['note'] ?? null); $tahesab = $existing ?? Tahesab::create([ "customer_id" => $customer->id, - "desc" => $data['direction'] == 0 ? "شارژ حساب" : "برداشت از حساب", + "desc" => $sharh, "amount" => $data['value'], "type" => "ريال", "date" => Carbon::now(), @@ -610,7 +612,7 @@ class TahesabController extends Controller (int)$day,//Shamsi_Day (int)$data['direction'],//IsDayaftAzMoshtariOrPardakhtBeMoshtari_0_1 (int)$data['value'],//Mablagh - $data['direction'] == 0 ? "شارژ حساب" : "برداشت از حساب",//Sharh + $sharh,//Sharh (string)$this->Config('tahesab_bank_account'), //Name_Bank "$tahesab->id",//Code_Rahgiri -1,//Factor_Code @@ -722,7 +724,7 @@ class TahesabController extends Controller /** * پاداش معرفی — همیشه روی حساب معرف (نه کاربر تازه‌ثبت‌نام‌شده). */ - public function referrerGoldReward(Customer $invitedCustomer, float $gold, string $desc = 'پاداش بابت معرفی') + public function referrerGoldReward(Customer $invitedCustomer, float $gold, string $desc = 'پاداش معرفی') { $referrer = $invitedCustomer->referrer(); if (!$referrer) { @@ -876,13 +878,10 @@ class TahesabController extends Controller $isDeposit = (int) ($data['direction'] ?? 1) === 1; $isVorood = $isDeposit ? 1 : 0; - $action = $isDeposit ? 'شارژ' : 'دشارژ'; - $kindFa = $mapper->kindLabel($kind); - $sharh = !empty($data['note']) - ? (string) $data['note'] - : (!empty($data['desc']) - ? (string) $data['desc'] - : trim($title !== '' ? "{$action} {$title}" : "{$action} {$kindFa}")); + $sharh = self::accountingWalletDesc( + $isDeposit, + !empty($data['note']) ? (string) $data['note'] : (!empty($data['desc']) ? (string) $data['desc'] : null) + ); $data['note'] = $sharh; $data['handler'] = 'walletGold'; diff --git a/app/Http/Controllers/Admin/ZarinController.php b/app/Http/Controllers/Admin/ZarinController.php index 8a51544..669eeec 100644 --- a/app/Http/Controllers/Admin/ZarinController.php +++ b/app/Http/Controllers/Admin/ZarinController.php @@ -1512,9 +1512,11 @@ class ZarinController extends Controller } $data['handler'] = 'wallet'; + $isDeposit = (int) ($data['direction'] ?? 0) === 0; + $sharh = self::accountingWalletDesc($isDeposit, $data['note'] ?? null); $zarin = $existing ?? Zarin::create([ 'customer_id' => $customer->id, - 'desc' => $data['direction'] == 0 ? 'شارژ حساب' : 'برداشت از حساب', + 'desc' => $sharh, 'amount' => $data['value'], 'type' => 'ريال', 'date' => Carbon::now(), @@ -1545,7 +1547,7 @@ class ZarinController extends Controller 'meghdar' => $data['value'], 'fi' => $mazaneh, 'hesab' => $customer->moshtari_code, - 'sharh' => $data['direction'] == 0 ? 'شارژ حساب' : 'برداشت از حساب', + 'sharh' => $sharh, 'ayar' => '750', 'movaghat' => '', 'idFactor' => '', @@ -1584,7 +1586,7 @@ class ZarinController extends Controller /** * پاداش معرفی — همیشه روی حساب معرف (نه کاربر تازه‌ثبت‌نام‌شده). */ - public function referrerGoldReward(Customer $invitedCustomer, float $gold, string $desc = 'پاداش بابت معرفی') + public function referrerGoldReward(Customer $invitedCustomer, float $gold, string $desc = 'پاداش معرفی') { $referrer = $invitedCustomer->referrer(); if (!$referrer) { @@ -1744,12 +1746,10 @@ class ZarinController extends Controller $vazn = $mapper->accountingWeight($product, $rawValue, $data); $isDeposit = (int) ($data['direction'] ?? 1) === 1; $title = $mapper->productTitle($product); - $action = $isDeposit ? 'شارژ' : 'دشارژ'; - $sharh = !empty($data['note']) - ? (string) $data['note'] - : (!empty($data['desc']) - ? (string) $data['desc'] - : trim($title !== '' ? "{$action} {$title}" : "{$action} {$mapper->kindLabel($mapper->resolveKind($product))}")); + $sharh = self::accountingWalletDesc( + $isDeposit, + !empty($data['note']) ? (string) $data['note'] : (!empty($data['desc']) ? (string) $data['desc'] : null) + ); $data['note'] = $sharh; $data['handler'] = 'walletGold'; $syncAmount = $mapper->isCountDoc($product) ? $count : $vazn; diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index c0c4b28..3c948f6 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -345,6 +345,70 @@ class Controller extends BaseController return 'برداشت ریالی'; } + /** شرح سند حسابداری برای واریز کیف (ریال/طلا) — پرگار، ته‌حساب، زرین */ + public static function accountingDepositDesc(?string $note = null): string + { + return self::normalizeAccountingWalletNote($note, true); + } + + /** شرح سند حسابداری برای برداشت کیف (ریال/طلا) — پرگار، ته‌حساب، زرین */ + public static function accountingWithdrawDesc(?string $note = null): string + { + return self::normalizeAccountingWalletNote($note, false); + } + + public static function accountingWalletDesc(bool $isDeposit, ?string $note = null): string + { + return $isDeposit + ? self::accountingDepositDesc($note) + : self::accountingWithdrawDesc($note); + } + + /** + * شرح سند کیف: پیش‌فرض «واریز»/«برداشت»؛ + * note خاص (مثل پاداش معرفی یا توضیح ادمین) حفظ می‌شود؛ + * عناوین عمومی واریز/برداشت/شارژ به همان دو کلمه نرمال می‌شوند. + */ + public static function normalizeAccountingWalletNote(?string $note, bool $isDeposit): string + { + $note = trim((string) $note); + if ($note === '') { + return $isDeposit ? 'واریز' : 'برداشت'; + } + + if (in_array($note, self::accountingReferralRewardDescAliases(), true)) { + return self::accountingReferralRewardDesc(); + } + + $generic = [ + 'واریز', 'برداشت', + 'واریز ریالی', 'برداشت ریالی', + 'واریز طلایی', 'برداشت طلایی', + 'واریز درگاه', 'واریز آنلاین', + 'واریز به کیف پول', 'برداشت از کیف پول', + 'شارژ حساب', 'برداشت از حساب', + 'شارژ', 'دشارژ', + 'شارژ طلای کیف اصلی', 'برداشت طلای کیف اصلی', + ]; + if (in_array($note, $generic, true)) { + return $isDeposit ? 'واریز' : 'برداشت'; + } + + return $note; + } + + /** شرح سند پاداش معرف — باید عین همین متن در همهٔ حسابداری‌ها برود */ + public static function accountingReferralRewardDesc(): string + { + return 'پاداش معرفی'; + } + + /** عناوین قدیمی پاداش معرف برای idempotency / تشخیص دادهٔ قبلی */ + public static function accountingReferralRewardDescAliases(): array + { + return ['پاداش معرفی', 'پاداش بابت معرفی']; + } + /** * type و title تراکنش ریالی — بر اساس علامت cash (داده‌های قدیمی گاهی type=4 با cash مثبت دارند). */ diff --git a/app/Http/Controllers/Pargar/PargarInboundController.php b/app/Http/Controllers/Pargar/PargarInboundController.php index 7c338a1..9c22eb8 100644 --- a/app/Http/Controllers/Pargar/PargarInboundController.php +++ b/app/Http/Controllers/Pargar/PargarInboundController.php @@ -702,13 +702,16 @@ class PargarInboundController extends Controller $orderId = $withdrawId > 0 ? 'W-' . $withdrawId : 'WLOG-' . $log->id; $isDeposit = $signed >= 0; + $note = trim((string) ($payload['note'] ?? '')); + $docDesc = self::accountingWalletDesc($isDeposit, $note !== '' ? $note : null); // قرارداد پرگار (همان چیزی که سند سفارش هم با آن ساخته می‌شود): // OrderType = 1 → سند «خرید» فروشگاه: وزن بدهکار، ریال بستانکار // OrderType = -1 → سند «فروش» فروشگاه: وزن بستانکار، ریال بدهکار - // مانده در پرگار = بستانکار − بدهکار، پس برای اینکه شارژ در حساب مشتری مثبت بنشیند: - // شارژ طلای کیف اصلی → باید وزن بستانکار شود → OrderType = -1 - // واریز ریالی → باید ریال بستانکار شود → OrderType = 1 + // مانده در پرگار = بستانکار − بدهکار، پس برای اینکه واریز در حساب مشتری مثبت بنشیند: + // واریز طلای کیف اصلی → باید وزن بستانکار شود → OrderType = -1 + // واریز ریالی → باید ریال بستانکار شود → OrderType = 1 + // برچسب UI پرگار ممکن است همچنان «خرید/فروش پولی» بسازد؛ شرح ارسالی همیشه واریز/برداشت/پاداش است. $orderType = $kind === 'gold' ? ($isDeposit ? -1 : 1) : ($isDeposit ? 1 : -1); @@ -727,7 +730,7 @@ class PargarInboundController extends Controller 'Weight' => abs($signed), 'Price' => 0, 'Carat' => 750, - 'Description' => $isDeposit ? 'شارژ طلای کیف اصلی' : 'برداشت طلای کیف اصلی', + 'Description' => $docDesc, ]; } @@ -739,14 +742,14 @@ class PargarInboundController extends Controller 'PriceType' => 1, 'CustomerAccountId' => (int) ($customer->pargar_account_id ?? 0), 'ItemId' => $rialItemId > 0 ? $rialItemId : $sync->pargarItemIdGold(), - 'ItemName' => $isDeposit ? 'واریز ریالی' : 'برداشت ریالی', + 'ItemName' => $docDesc, 'OrderDate' => Jalalian::fromDateTime($log->date ?? $log->created_at)->format('Y/m/d-H:i:s'), 'Fee' => 0, 'Count' => 0, 'Weight' => 0, 'Price' => abs($signed), 'Carat' => 750, - 'Description' => $isDeposit ? 'واریز ریالی' : 'برداشت ریالی', + 'Description' => $docDesc, ]; } } diff --git a/app/Services/PargarInboundWalletService.php b/app/Services/PargarInboundWalletService.php index 1e88667..edeada6 100644 --- a/app/Services/PargarInboundWalletService.php +++ b/app/Services/PargarInboundWalletService.php @@ -535,8 +535,8 @@ class PargarInboundWalletService { return match ($log->type) { PargarSyncService::TYPE_ORDER => 'سفارش ' . $log->order_id, - PargarSyncService::TYPE_WALLET_GOLD => 'شارژ طلای کیف', - PargarSyncService::TYPE_WALLET_CASH => 'سند ریالی کیف', + PargarSyncService::TYPE_WALLET_GOLD => 'واریز/برداشت طلای کیف', + PargarSyncService::TYPE_WALLET_CASH => 'واریز/برداشت ریالی کیف', default => (string) $log->type, }; } diff --git a/app/Services/PargarSyncService.php b/app/Services/PargarSyncService.php index dbea45d..d3ddb18 100644 --- a/app/Services/PargarSyncService.php +++ b/app/Services/PargarSyncService.php @@ -204,11 +204,9 @@ class PargarSyncService } $isDeposit = $signedAmount > 0; - if ($kind === 'cash') { - $desc = $isDeposit ? 'واریز ریالی — ارسال به پرگار' : 'برداشت ریالی — ارسال به پرگار'; - } else { - $desc = $isDeposit ? 'شارژ طلای کیف اصلی — ارسال به پرگار' : 'برداشت طلای کیف اصلی — ارسال به پرگار'; - } + $note = isset($meta['note']) ? trim((string) $meta['note']) : ''; + $docDesc = \App\Http\Controllers\Controller::accountingWalletDesc($isDeposit, $note !== '' ? $note : null); + $desc = $docDesc . ' — ارسال به پرگار'; $absAmount = abs($signedAmount); // اگر هنوز مایگریشن widen اجرا نشده، مبلغ بزرگ را از همان اول در ستون نگذار diff --git a/app/Services/PriceChannelBroadcastService.php b/app/Services/PriceChannelBroadcastService.php index 904001b..bb169f0 100644 --- a/app/Services/PriceChannelBroadcastService.php +++ b/app/Services/PriceChannelBroadcastService.php @@ -57,6 +57,10 @@ TXT; */ public function scheduleBroadcastIfEligible(): void { + if (! $this->hasPriceChannelAccess()) { + return; + } + if (! $this->config->getBool('price_channel_enabled', false)) { return; } @@ -81,6 +85,10 @@ TXT; public function broadcastIfEligible(): void { try { + if (! $this->hasPriceChannelAccess()) { + return; + } + if (! $this->config->getBool('price_channel_enabled', false)) { return; } @@ -202,6 +210,10 @@ TXT; public function broadcastAfterTemplateChange(): void { try { + if (! $this->hasPriceChannelAccess()) { + return; + } + if (! $this->config->getBool('price_channel_enabled', false)) { return; } @@ -323,7 +335,7 @@ TXT; 'selected' => $isSelected, 'has_token' => $token !== '', 'destinations' => $chatIds, - 'will_send' => $isSelected && $token !== '' && $chatIds !== [], + 'will_send' => $this->hasPriceChannelAccess() && $isSelected && $token !== '' && $chatIds !== [], ]; } @@ -333,6 +345,7 @@ TXT; $display = $trade !== null ? $this->computeDisplayPrices() : null; return [ + 'access' => $this->hasPriceChannelAccess(), 'enabled' => $this->config->getBool('price_channel_enabled', false), 'selected_messengers' => $selected, 'min_seconds' => $this->config->getInt('price_channel_min_seconds', 120), @@ -850,6 +863,11 @@ TXT; } /** @return array */ + private function hasPriceChannelAccess(): bool + { + return $this->config->getBool('price_channel_access', false); + } + private function parseList(string $raw): array { $parts = preg_split('/[,\n]+/', trim($raw)) ?: []; diff --git a/app/Services/ReferralGiftService.php b/app/Services/ReferralGiftService.php index acae836..634ea85 100644 --- a/app/Services/ReferralGiftService.php +++ b/app/Services/ReferralGiftService.php @@ -9,6 +9,7 @@ use App\Models\Order; use App\Models\Setting; use App\Models\TransactionsAdmin; use App\Models\Withdraw; +use Illuminate\Support\Facades\Log; use Rooyesh\Wallet\interfaces\TransactionInterface; use Rooyesh\Wallet\interfaces\WalletInterface; use Rooyesh\Wallet\models\Transaction; @@ -60,7 +61,7 @@ class ReferralGiftService /** * واریز معوق/دستی پاداش (مثلاً جبران وقتی گیت اشتباه جلوی واریز را گرفته). - * Idempotent — اگر قبلاً «پاداش بابت معرفی» خورده باشد دوباره نمی‌زند. + * Idempotent — اگر قبلاً «پاداش معرفی» (یا عنوان قدیمی) خورده باشد دوباره نمی‌زند. */ public function givePendingGifts(Customer $customer, bool $requireExistingOrder = false): void { @@ -128,7 +129,7 @@ class ReferralGiftService { return TransactionsAdmin::where('customer_id', $invited->id) ->where('customer_to_id', $referrer->id) - ->where('note', 'پاداش بابت معرفی') + ->whereIn('note', Controller::accountingReferralRewardDescAliases()) ->exists(); } @@ -139,6 +140,63 @@ class ReferralGiftService ->exists(); } + /** + * وقتی price_provider=montzar و کلید referral_gift_buy_from_montzar روشن است، + * قبل از واریز پاداش همان وزن از همکار خرید می‌شود. + * خاموش بودن کلید = روال قبلی (واریز محلی بدون خرید همکار). + * شکست خرید → واریز نمی‌شود (ثبت‌نام/سفارش خراب نمی‌شود؛ با givePendingGifts قابل جبران است). + */ + private function ensureMontzarCoverPurchase( + float $grams, + Customer $beneficiary, + string $reason, + ConfigService $config + ): bool { + if (!$config->usesMontzarPricing()) { + return true; + } + + if (!$config->getBool('referral_gift_buy_from_montzar', true)) { + return true; + } + + if ($grams <= 0) { + return true; + } + + $livePrice = (float) $config->Config('montzar_live_price'); + $data = [ + 'amount' => $grams, + 'direction' => 1, // خرید پوشش از همکار + 'customer' => [ + 'name' => trim($reason . ' - ' . (string) ($beneficiary->name ?? '')), + ], + 'total_price' => (int) round($livePrice * $grams), + ]; + + try { + $parsed = app(MontzarService::class)->submitOrder($data); + Log::info('Referral gift covered by Montzar buy', [ + 'grams' => $grams, + 'reason' => $reason, + 'beneficiary_id' => $beneficiary->id, + 'provider_id' => $parsed['provider_id'] ?? null, + ]); + + return true; + } catch (\Throwable $e) { + report($e); + Log::error('Referral gift blocked: Montzar cover buy failed', [ + 'grams' => $grams, + 'reason' => $reason, + 'beneficiary_id' => $beneficiary->id, + 'error' => $e->getMessage(), + ]); + + return false; + } + } + private function giveReferrerGift( Customer $customer, Customer $referrer, @@ -147,6 +205,12 @@ class ReferralGiftService string $companyUrl, ConfigService $config ): void { + $rewardDesc = Controller::accountingReferralRewardDesc(); + + if (!$this->ensureMontzarCoverPurchase($giftForInviter, $referrer, $rewardDesc, $config)) { + return; + } + $withdraw = Withdraw::create([ 'user_id' => $customer->id, 'customer_id' => $referrer->id, @@ -161,7 +225,7 @@ class ReferralGiftService 'gold' => $giftForInviter, 'expire_at' => now(), 'active' => true, - 'title' => 'پاداش بابت معرفی', + 'title' => $rewardDesc, 'withdraw_id' => $withdraw->id, 'start_at' => now(), ], 8, true, false); @@ -174,7 +238,7 @@ class ReferralGiftService 'wallet' => null, 'transaction_id' => $transaction->id, 'cash' => 0, - 'note' => 'پاداش بابت معرفی', + 'note' => $rewardDesc, 'type' => 1, 'gold' => $giftForInviter, 'balance_cash' => 0, @@ -186,7 +250,7 @@ class ReferralGiftService app(TahesabController::class)->referrerGoldReward( $customer, $giftForInviter, - 'پاداش بابت معرفی' + $rewardDesc ); } catch (\Exception $e) { report($e); @@ -198,13 +262,28 @@ class ReferralGiftService app(\App\Http\Controllers\Admin\ZarinController::class)->referrerGoldReward( $customer, $giftForInviter, - 'پاداش بابت معرفی' + $rewardDesc ); } catch (\Exception $e) { report($e); } } + try { + app(PargarSyncService::class)->queueWalletDocument( + $referrer, + 'gold', + (float) $giftForInviter, + [ + 'withdraw_id' => $withdraw->id, + 'note' => $rewardDesc, + 'source' => 'referral_gift', + ] + ); + } catch (\Throwable $e) { + report($e); + } + $currentGold = Controller::formatSmsGoldWeight((float) $walletInterface->wallet->refresh()->gold); $message = "سلام {$referrer->name} عزیز،\n\n{$giftForInviter} گرم طلا بابت معرفی {$customer->name} به حساب شما واریز شد.\nموجودی فعلی: {$currentGold} گرم.\n\nاطلاعات بیشتر: {$companyUrl}\n\nبا احترام،\n{$companyName}"; Controller::Send($referrer->mobile, $message); @@ -217,6 +296,10 @@ class ReferralGiftService string $companyUrl, ConfigService $config ): void { + if (!$this->ensureMontzarCoverPurchase($giftForInvited, $customer, 'پاداش بابت ثبت نام', $config)) { + return; + } + $withdraw = Withdraw::create([ 'user_id' => $customer->id, 'customer_id' => $customer->id, @@ -275,6 +358,21 @@ class ReferralGiftService } } + try { + app(PargarSyncService::class)->queueWalletDocument( + $customer, + 'gold', + (float) $giftForInvited, + [ + 'withdraw_id' => $withdraw->id, + 'note' => 'پاداش بابت ثبت نام', + 'source' => 'referral_register_gift', + ] + ); + } catch (\Throwable $e) { + report($e); + } + $currentGold = Controller::formatSmsGoldWeight((float) $walletInterface->wallet->refresh()->gold); $message = "سلام {$customer->name} عزیز،\n\n{$giftForInvited} گرم طلا بابت ثبت نام به حساب شما واریز شد.\nموجودی فعلی: {$currentGold} گرم.\n\nاطلاعات بیشتر: {$companyUrl}\n\nبا احترام،\n{$companyName}"; Controller::Send($customer->mobile, $message); diff --git a/database/sql/deploy_settings_const.sql b/database/sql/deploy_settings_const.sql index 5a6d5ce..e2b28ec 100644 --- a/database/sql/deploy_settings_const.sql +++ b/database/sql/deploy_settings_const.sql @@ -510,6 +510,13 @@ INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `de SELECT 'referral_gift_on_first_order', 'false', 'پاداش معرف پس از اولین سفارش', 1, 1, NULL WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'referral_gift_on_first_order' LIMIT 1); +-- default: true — وقتی montzar روشن است پاداش معرفی از همکار خرید می‌شود؛ خاموش = واریز محلی مثل قبل +INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`, `type`) +SELECT 'referral_gift_buy_from_montzar', 'true', 'خرید پاداش معرفی از همکار', 1, 1, + 'روشن: اگر منبع قیمت montzar باشد، قبل از واریز پاداش معرف/معرف‌شونده همان وزن از همکار خرید می‌شود؛ شکست خرید = واریز نمی‌شود. خاموش: مثل قبل فقط به کیف واریز می‌شود بدون خرید از همکار.', + 'switch' +WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'referral_gift_buy_from_montzar' LIMIT 1); + INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`) SELECT 'referral_limit', '', 'محدودیت دعوت', 1, 1, NULL WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'referral_limit' LIMIT 1); @@ -618,10 +625,16 @@ WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'rubika_bot_token' LIMI -- =========================================================================== -- ارسال قیمت به کانال‌های پیام‌رسان (بله / تلگرام / روبیکا) +-- • دسترسی (can_edit=0): price_channel_access — تا روشن نشود، گروه کانال در تنظیمات عادی مخفی است -- • محتوا (can_edit=1): روشن/خاموش، انتخاب پیام‌رسان، اختلاف، خطوط پایانی، فاصله -- • سیستمی (can_edit=0): مقصد ارسال هر پیام‌رسان (آیدی چنل/گروه) -- • توکن‌ها همان bale_bot_token / telegram_bot_token / rubika_bot_token (can_edit=0) -- =========================================================================== +INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`, `type`) +SELECT 'price_channel_access', 'false', 'دسترسی ارسال قیمت به کانال', 0, 1, + 'روشن: گروه «ارسال قیمت به کانال» در تنظیمات عادی پنل دیده می‌شود. خاموش: مخفی است (فقط از تنظیمات پیشرفته).', 'switch' +WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'price_channel_access' LIMIT 1); + INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`, `type`) SELECT 'price_channel_enabled', 'false', 'ارسال قیمت به کانال', 1, 1, 'روشن: بعد از هر تغییر قیمت، مظنه به کانال‌های پیام‌رسان انتخاب‌شده ارسال می‌شود.', 'switch' @@ -1093,7 +1106,7 @@ UPDATE `settings` SET `type` = 'switch' WHERE `key` IN ( 'montzar_closed', 'montzar_open_buy', 'montzar_open_sell', 'payping_fin_sync_enabled', 'external_order_api_enabled', 'is_store', 'wss_enabled', 'tracking_systems_enabled', 'register_referral_sms_to_referrer', 'register_referral_bonus_message', - 'referral_gift_on_first_order', + 'referral_gift_on_first_order', 'referral_gift_buy_from_montzar', 'banner_enabled', 'permision__enabled' ); @@ -1282,7 +1295,7 @@ UPDATE `settings` SET WHERE `key` = 'referral_id'; UPDATE `settings` SET `type` = 'switch' -WHERE `key` IN ('register_referral_sms_to_referrer', 'register_referral_bonus_message', 'referral_gift_on_first_order'); +WHERE `key` IN ('register_referral_sms_to_referrer', 'register_referral_bonus_message', 'referral_gift_on_first_order', 'referral_gift_buy_from_montzar'); UPDATE `settings` SET `type` = 'switch', @@ -1457,11 +1470,17 @@ UPDATE `settings` SET `description` = 'متن کامل قوانین و مقرر UPDATE `settings` SET `description` = 'متن «درباره ما» شامل معرفی مجموعه، راه‌های ارتباطی و توضیح خدمات. در صفحه مربوطه در اپ کاربر نمایش داده می‌شود.' WHERE `key` = 'text_about'; UPDATE `settings` SET `description` = 'روشن: وارد کردن کد معرف در ثبت‌نام اجباری است. خاموش: کد معرف اختیاری است.' WHERE `key` = 'referral_id'; -UPDATE `settings` SET `description` = 'مقدار پاداش (معمولاً وزن فلز به گرم) که به کیف معرف واریز می‌شود. ۰ = بدون پاداش. زمان واریز بسته به «پاداش معرف پس از اولین سفارش» است.' WHERE `key` = 'gift_for_referrer'; -UPDATE `settings` SET `description` = 'مقدار پاداش (معمولاً وزن فلز) که به معرف‌شونده واریز می‌شود. ۰ = بدون پاداش. زمان واریز بسته به «پاداش معرف پس از اولین سفارش» است.' WHERE `key` = 'gift_for_referral'; +UPDATE `settings` SET `description` = 'مقدار پاداش (گرم) به کیف معرف. ۰ = بدون پاداش. زمان واریز بسته به «پاداش معرف پس از اولین سفارش» است. خرید پوشش از همکار با کلید «خرید پاداش معرفی از همکار» کنترل می‌شود.' WHERE `key` = 'gift_for_referrer'; +UPDATE `settings` SET `description` = 'مقدار پاداش (گرم) به معرف‌شونده. ۰ = بدون پاداش. زمان واریز بسته به «پاداش معرف پس از اولین سفارش» است. خرید پوشش از همکار با کلید «خرید پاداش معرفی از همکار» کنترل می‌شود.' WHERE `key` = 'gift_for_referral'; UPDATE `settings` SET `description` = 'روشن: پس از ثبت‌نام کاربر جدید، پیامک اطلاع‌رسانی برای معرف ارسال می‌شود.' WHERE `key` = 'register_referral_sms_to_referrer'; UPDATE `settings` SET `description` = 'روشن: متن پاداش معرف در پیامک خوش‌آمد ثبت‌نام گنجانده می‌شود.' WHERE `key` = 'register_referral_bonus_message'; UPDATE `settings` SET `description` = 'روشن: پاداش معرف (gift_for_referrer) و معرف‌شونده (gift_for_referral) پس از تکمیل اولین سفارش معرف‌شونده به کیف واریز می‌شود — فقط اگر مقدار هر پاداش بیشتر از صفر باشد. خاموش: پاداش بلافاصله پس از ثبت‌نام موفق یا تأیید احراز هویت واریز می‌شود (باز هم فقط برای مقادیر بیشتر از صفر).' WHERE `key` = 'referral_gift_on_first_order'; +UPDATE `settings` SET + `title_fa` = 'خرید پاداش معرفی از همکار', + `can_edit` = 1, + `type` = 'switch', + `description` = 'روشن: اگر منبع قیمت montzar باشد، قبل از واریز پاداش معرف/معرف‌شونده همان وزن از همکار خرید می‌شود؛ شکست خرید = واریز نمی‌شود. خاموش: مثل قبل فقط به کیف واریز می‌شود بدون خرید از همکار.' +WHERE `key` = 'referral_gift_buy_from_montzar'; UPDATE `settings` SET `description` = 'حداکثر تعداد دعوت‌های مجاز برای هر کاربر. خالی = بدون محدودیت.' WHERE `key` = 'referral_limit'; UPDATE `settings` SET `description` = 'مبلغ یا مقدار پاداش معرف (متن آزاد — بسته به پیاده‌سازی پیامک/اعتبار). برای نمایش در پیام‌ها.' WHERE `key` = 'referral_bonus_amount'; UPDATE `settings` SET `description` = 'روشن: تطبیق شماره کارت بانکی کاربر با سرویس احراز هویت جیبیت هنگام ثبت/ویرایش کارت.' WHERE `key` = 'jibit_verification'; @@ -1470,6 +1489,12 @@ UPDATE `settings` SET `description` = 'روشن: منوی «کسب درآمد / UPDATE `settings` SET `description` = 'روشن: منوی هشدار قیمت در اپ کاربر نمایش داده می‌شود. خاموش: منو و صفحه مخفی است. فقط از دیپلوی قابل تغییر است.' WHERE `key` = 'has_page_price_trigger'; UPDATE `settings` SET `description` = 'روشن: زنگوله اعلان در اپ کاربر و منوی ثبت اعلان در ادمین فعال است. خاموش: مخفی است. فقط از دیپلوی قابل تغییر است.' WHERE `key` = 'has_page_notification'; UPDATE `settings` SET `title_fa` = 'اعلان داخل اپ' WHERE `key` = 'has_page_notification'; +UPDATE `settings` SET + `title_fa` = 'دسترسی ارسال قیمت به کانال', + `type` = 'switch', + `can_edit` = 0, + `description` = 'روشن: گروه «ارسال قیمت به کانال» در تنظیمات عادی پنل دیده می‌شود. خاموش: مخفی است (فقط از تنظیمات پیشرفته).' +WHERE `key` = 'price_channel_access'; -- محصول: اعلان داخل اپ پیش‌فرض روشن برای همه دیپلوی‌ها (can_edit=0؛ فقط از دیپلوی) UPDATE `settings` SET `value` = 'true' WHERE `key` = 'has_page_notification'; @@ -1748,6 +1773,7 @@ UPDATE `settings` SET `title_fa` = 'تأیید کدملی/موبایل در ثب UPDATE `settings` SET `title_fa` = 'پیام پاداش در SMS ثبت‌نام' WHERE `key` = 'register_referral_bonus_message'; UPDATE `settings` SET `title_fa` = 'SMS به معرف هنگام ثبت‌نام' WHERE `key` = 'register_referral_sms_to_referrer'; UPDATE `settings` SET `title_fa` = 'پاداش معرف پس از اولین سفارش' WHERE `key` = 'referral_gift_on_first_order'; +UPDATE `settings` SET `title_fa` = 'خرید پاداش معرفی از همکار' WHERE `key` = 'referral_gift_buy_from_montzar'; UPDATE `settings` SET `title_fa` = 'سود فروش نمایش' WHERE `key` = 'sell_fee'; UPDATE `settings` SET `title_fa` = 'ارسال به ته‌حساب' WHERE `key` = 'send_to_tahesab'; UPDATE `settings` SET `title_fa` = 'آدرس API سرور' WHERE `key` = 'server_url'; @@ -1837,6 +1863,7 @@ UPDATE `settings` SET `can_edit` = 0 WHERE `key` IN ( 'sse_path', 'tahesab_bank_account', 'tahesab_db', 'tahesab_host', 'tahesab_port', 'tahesab_token', 'telegram_bot_token', 'rubika_bot_token', + 'price_channel_access', 'price_channel_bale_to', 'price_channel_telegram_to', 'price_channel_rubika_to', 'unit', 'up_price', 'down_price', @@ -1869,7 +1896,7 @@ UPDATE `settings` SET `can_edit` = 1 WHERE `key` IN ( 'montzar_mobile', 'montzar_open_buy', 'montzar_open_sell', 'montzar_password', 'montzar_product_id', 'open_register', - 'referral_id', 'referral_limit', 'referral_gift_on_first_order', + 'referral_id', 'referral_limit', 'referral_gift_on_first_order', 'referral_gift_buy_from_montzar', 'register_jibit_verify', 'register_referral_bonus_message', 'register_referral_sms_to_referrer', 'sell_fee', 'show_last_price', 'show_home_price_when_closed', 'show_gold_ounce_price', 'show_product_details', 'show_product_trade_status', 'show_product_card_meta', diff --git a/database/sql/deploy_settings_const_preserve_value_sync_can_edit.sql b/database/sql/deploy_settings_const_preserve_value_sync_can_edit.sql index e622b77..e8817de 100644 --- a/database/sql/deploy_settings_const_preserve_value_sync_can_edit.sql +++ b/database/sql/deploy_settings_const_preserve_value_sync_can_edit.sql @@ -465,6 +465,13 @@ INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `de SELECT 'referral_gift_on_first_order', 'false', 'پاداش معرف پس از اولین سفارش', 1, 1, NULL WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'referral_gift_on_first_order' LIMIT 1); +-- default: true — وقتی montzar روشن است پاداش معرفی از همکار خرید می‌شود؛ خاموش = واریز محلی مثل قبل +INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`, `type`) +SELECT 'referral_gift_buy_from_montzar', 'true', 'خرید پاداش معرفی از همکار', 1, 1, + 'روشن: اگر منبع قیمت montzar باشد، قبل از واریز پاداش معرف/معرف‌شونده همان وزن از همکار خرید می‌شود؛ شکست خرید = واریز نمی‌شود. خاموش: مثل قبل فقط به کیف واریز می‌شود بدون خرید از همکار.', + 'switch' +WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'referral_gift_buy_from_montzar' LIMIT 1); + INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`) SELECT 'referral_limit', '', 'محدودیت دعوت', 1, 1, NULL WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'referral_limit' LIMIT 1); @@ -877,7 +884,7 @@ UPDATE `settings` SET `type` = 'switch' WHERE `key` IN ( 'montzar_closed', 'montzar_open_buy', 'montzar_open_sell', 'payping_fin_sync_enabled', 'external_order_api_enabled', 'is_store', 'wss_enabled', 'tracking_systems_enabled', 'register_referral_sms_to_referrer', 'register_referral_bonus_message', - 'referral_gift_on_first_order', + 'referral_gift_on_first_order', 'referral_gift_buy_from_montzar', 'banner_enabled', 'permision__enabled' ); @@ -1049,7 +1056,7 @@ UPDATE `settings` SET WHERE `key` = 'referral_id'; UPDATE `settings` SET `type` = 'switch' -WHERE `key` IN ('register_referral_sms_to_referrer', 'register_referral_bonus_message', 'referral_gift_on_first_order'); +WHERE `key` IN ('register_referral_sms_to_referrer', 'register_referral_bonus_message', 'referral_gift_on_first_order', 'referral_gift_buy_from_montzar'); UPDATE `settings` SET `type` = 'switch', @@ -1265,11 +1272,17 @@ UPDATE `settings` SET `description` = 'متن کامل قوانین و مقرر UPDATE `settings` SET `description` = 'متن «درباره ما» شامل معرفی مجموعه، راه‌های ارتباطی و توضیح خدمات. در صفحه مربوطه در اپ کاربر نمایش داده می‌شود.' WHERE `key` = 'text_about'; UPDATE `settings` SET `description` = 'روشن: وارد کردن کد معرف در ثبت‌نام اجباری است. خاموش: کد معرف اختیاری است.' WHERE `key` = 'referral_id'; -UPDATE `settings` SET `description` = 'مقدار پاداش (معمولاً وزن فلز به گرم) که به کیف معرف واریز می‌شود. ۰ = بدون پاداش. زمان واریز بسته به «پاداش معرف پس از اولین سفارش» است.' WHERE `key` = 'gift_for_referrer'; -UPDATE `settings` SET `description` = 'مقدار پاداش (معمولاً وزن فلز) که به معرف‌شونده واریز می‌شود. ۰ = بدون پاداش. زمان واریز بسته به «پاداش معرف پس از اولین سفارش» است.' WHERE `key` = 'gift_for_referral'; +UPDATE `settings` SET `description` = 'مقدار پاداش (گرم) به کیف معرف. ۰ = بدون پاداش. زمان واریز بسته به «پاداش معرف پس از اولین سفارش» است. خرید پوشش از همکار با کلید «خرید پاداش معرفی از همکار» کنترل می‌شود.' WHERE `key` = 'gift_for_referrer'; +UPDATE `settings` SET `description` = 'مقدار پاداش (گرم) به معرف‌شونده. ۰ = بدون پاداش. زمان واریز بسته به «پاداش معرف پس از اولین سفارش» است. خرید پوشش از همکار با کلید «خرید پاداش معرفی از همکار» کنترل می‌شود.' WHERE `key` = 'gift_for_referral'; UPDATE `settings` SET `description` = 'روشن: پس از ثبت‌نام کاربر جدید، پیامک اطلاع‌رسانی برای معرف ارسال می‌شود.' WHERE `key` = 'register_referral_sms_to_referrer'; UPDATE `settings` SET `description` = 'روشن: متن پاداش معرف در پیامک خوش‌آمد ثبت‌نام گنجانده می‌شود.' WHERE `key` = 'register_referral_bonus_message'; UPDATE `settings` SET `description` = 'روشن: پاداش معرف (gift_for_referrer) و معرف‌شونده (gift_for_referral) پس از تکمیل اولین سفارش معرف‌شونده به کیف واریز می‌شود — فقط اگر مقدار هر پاداش بیشتر از صفر باشد. خاموش: پاداش بلافاصله پس از ثبت‌نام موفق یا تأیید احراز هویت واریز می‌شود (باز هم فقط برای مقادیر بیشتر از صفر).' WHERE `key` = 'referral_gift_on_first_order'; +UPDATE `settings` SET + `title_fa` = 'خرید پاداش معرفی از همکار', + `can_edit` = 1, + `type` = 'switch', + `description` = 'روشن: اگر منبع قیمت montzar باشد، قبل از واریز پاداش معرف/معرف‌شونده همان وزن از همکار خرید می‌شود؛ شکست خرید = واریز نمی‌شود. خاموش: مثل قبل فقط به کیف واریز می‌شود بدون خرید از همکار.' +WHERE `key` = 'referral_gift_buy_from_montzar'; UPDATE `settings` SET `description` = 'حداکثر تعداد دعوت‌های مجاز برای هر کاربر. خالی = بدون محدودیت.' WHERE `key` = 'referral_limit'; UPDATE `settings` SET `description` = 'مبلغ یا مقدار پاداش معرف (متن آزاد — بسته به پیاده‌سازی پیامک/اعتبار). برای نمایش در پیام‌ها.' WHERE `key` = 'referral_bonus_amount'; UPDATE `settings` SET `description` = 'روشن: تطبیق شماره کارت بانکی کاربر با سرویس احراز هویت جیبیت هنگام ثبت/ویرایش کارت.' WHERE `key` = 'jibit_verification'; @@ -1462,7 +1475,7 @@ UPDATE `settings` SET `can_edit` = 1 WHERE `key` IN ( 'montzar_mobile', 'montzar_open_buy', 'montzar_open_sell', 'montzar_password', 'montzar_product_id', 'open_register', - 'referral_id', 'referral_limit', 'referral_gift_on_first_order', + 'referral_id', 'referral_limit', 'referral_gift_on_first_order', 'referral_gift_buy_from_montzar', 'register_jibit_verify', 'register_referral_bonus_message', 'register_referral_sms_to_referrer', 'sell_fee', 'show_last_price', 'show_home_price_when_closed', 'show_product_details', 'show_product_trade_status', 'show_product_card_meta', diff --git a/database/sql/price_channel_settings.sql b/database/sql/price_channel_settings.sql index 91c9d5e..ac6c95f 100644 --- a/database/sql/price_channel_settings.sql +++ b/database/sql/price_channel_settings.sql @@ -47,6 +47,12 @@ INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `de SELECT 'rubika_bot_token', '', 'توکن بات روبیکا', 0, 1, NULL WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'rubika_bot_token' LIMIT 1); +-- دسترسی دیپلوی — فقط تنظیمات پیشرفته (can_edit=0) +INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`, `type`) +SELECT 'price_channel_access', 'false', 'دسترسی ارسال قیمت به کانال', 0, 1, + 'روشن: گروه «ارسال قیمت به کانال» در تنظیمات عادی پنل دیده می‌شود. خاموش: مخفی است (فقط از تنظیمات پیشرفته).', 'switch' +WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'price_channel_access' LIMIT 1); + -- محتوا — قابل ویرایش (can_edit=1) INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`, `type`) SELECT 'price_channel_enabled', 'false', 'ارسال قیمت به کانال', 1, 1, @@ -120,8 +126,15 @@ WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'price_channel_rubika_t -- استانداردسازی can_edit UPDATE `settings` SET `can_edit` = 0 WHERE `key` IN ( 'rubika_bot_token', + 'price_channel_access', 'price_channel_bale_to', 'price_channel_telegram_to', 'price_channel_rubika_to' ); +UPDATE `settings` SET + `title_fa` = 'دسترسی ارسال قیمت به کانال', + `type` = 'switch', + `can_edit` = 0, + `description` = 'روشن: گروه «ارسال قیمت به کانال» در تنظیمات عادی پنل دیده می‌شود. خاموش: مخفی است (فقط از تنظیمات پیشرفته).' +WHERE `key` = 'price_channel_access'; UPDATE `settings` SET `can_edit` = 1 WHERE `key` IN ( 'price_channel_enabled', 'price_channel_messengers', 'price_channel_diff', 'price_channel_min_seconds', 'price_channel_message_text', diff --git a/packages/rooyesh/wallet/src/models/Transaction.php b/packages/rooyesh/wallet/src/models/Transaction.php index e926024..2ef5537 100644 --- a/packages/rooyesh/wallet/src/models/Transaction.php +++ b/packages/rooyesh/wallet/src/models/Transaction.php @@ -24,7 +24,7 @@ class Transaction extends Model 4 => 'برداشت ریالی', 5 => 'واریز', 6 => 'برداشت', - 8 => ' پاداش بابت معرفی', + 8 => 'پاداش معرفی', 9 => 'سود زیر مجموعه', 10 => 'برداشت طلایی', 12 => 'برداشت وجه نقد', diff --git a/resources/views/app.blade.php b/resources/views/app.blade.php index f349030..e0bd081 100644 --- a/resources/views/app.blade.php +++ b/resources/views/app.blade.php @@ -646,7 +646,7 @@ @endphp @foreach($transactions_admins as $transactions_admin) - @if($transactions_admin->note == "پاداش بابت معرفی") + @if(in_array($transactions_admin->note, ['پاداش معرفی', 'پاداش بابت معرفی'], true)) @php $totalGold += $transactions_admin->gold; @endphp