From b29cb4e37a41de670c5b59b43ded398721a3ecf8 Mon Sep 17 00:00:00 2001 From: adonis Date: Sun, 12 Jul 2026 18:31:17 +0330 Subject: [PATCH] fix bug 2 --- .../Controllers/Customer/WalletController.php | 86 +++++++++++++++++-- ..._000002_add_support_messengers_setting.php | 51 +++++++++++ ...12_000003_add_tracking_systems_setting.php | 29 +++++++ .../sql/add_support_messengers_setting.sql | 33 +++++++ database/sql/add_tracking_systems_setting.sql | 14 +++ database/sql/deploy_settings_const.sql | 10 ++- ...ngs_const_preserve_value_sync_can_edit.sql | 9 +- 7 files changed, 223 insertions(+), 9 deletions(-) create mode 100644 database/migrations/2026_07_12_000002_add_support_messengers_setting.php create mode 100644 database/migrations/2026_07_12_000003_add_tracking_systems_setting.php create mode 100644 database/sql/add_support_messengers_setting.sql create mode 100644 database/sql/add_tracking_systems_setting.sql diff --git a/app/Http/Controllers/Customer/WalletController.php b/app/Http/Controllers/Customer/WalletController.php index 3a642c2..8e129bd 100644 --- a/app/Http/Controllers/Customer/WalletController.php +++ b/app/Http/Controllers/Customer/WalletController.php @@ -130,13 +130,10 @@ class WalletController extends Controller $customerId = (int) auth('customer')->id(); $this->repairMisclassifiedRialTransactions($customerId); - if (isset($request->wallet_id)){ - $wallet = Wallet::with('product')->where('id', $request->wallet_id)->where('owner', auth('customer')->id())->get(); - }else{ - $wallet = Wallet::with('product')->where('owner', auth('customer')->id())->get(); - } + $mainWalletProductIds = app(ConfigService::class)->mainWalletProductIds(); + $walletIds = $this->resolveTransactionTableWalletIds($customerId, $request, $mainWalletProductIds); - if ($wallet->isEmpty()) { + if ($walletIds->isEmpty()) { $records = ['query' => ['total' => 0], 'rows' => []]; } else { $records = Transaction::with([ @@ -148,7 +145,7 @@ class WalletController extends Controller }, 'wallet.product', 'product', - ])->whereIn('wallet', $wallet->pluck('id'))->whereNull('fund_id'); + ])->whereIn('wallet', $walletIds)->whereNull('fund_id'); TableEngine::create($records, $request->all()) ->initSearch(['customer.name']) @@ -211,6 +208,81 @@ class WalletController extends Controller return response()->json($records); } + /** + * کیف(های) مؤثر برای جدول تراکنش. + * محصولات main_wallet_products: تراکنش‌ها روی کیف اصلی (+ کیف legacy محصول) ثبت شده‌اند. + * + * @return \Illuminate\Support\Collection + */ + private function resolveTransactionTableWalletIds( + int $customerId, + Request $request, + array $mainWalletProductIds + ) { + $requestedWalletId = $request->input('wallet_id'); + $requestedProductId = (int) $request->input('product_id'); + + if ($requestedWalletId) { + $requestedWallet = Wallet::query() + ->where('id', $requestedWalletId) + ->where('owner', $customerId) + ->first(); + + if (!$requestedWallet) { + return collect(); + } + + if ( + $mainWalletProductIds !== [] + && ( + ($requestedWallet->product_id && self::isMainWalletProduct((int) $requestedWallet->product_id)) + || ( + $requestedWallet->product_id === null + && $requestedWallet->fund_id === null + && $requestedProductId > 0 + && self::isMainWalletProduct($requestedProductId) + ) + ) + ) { + return $this->mainWalletProductTransactionWalletIds($customerId, $mainWalletProductIds); + } + + return collect([(int) $requestedWallet->id]); + } + + if ( + $mainWalletProductIds !== [] + && $requestedProductId > 0 + && self::isMainWalletProduct($requestedProductId) + ) { + return $this->mainWalletProductTransactionWalletIds($customerId, $mainWalletProductIds); + } + + return Wallet::query() + ->where('owner', $customerId) + ->pluck('id'); + } + + /** + * کیف اصلی + کیف‌های legacy محصولات متصل به کیف اصلی. + * + * @return \Illuminate\Support\Collection + */ + private function mainWalletProductTransactionWalletIds(int $customerId, array $mainWalletProductIds) + { + return Wallet::query() + ->where('owner', $customerId) + ->whereNull('fund_id') + ->where(function ($query) use ($mainWalletProductIds) { + $query->whereNull('product_id') + ->orWhereIn('product_id', $mainWalletProductIds); + }) + ->pluck('id') + ->map(fn ($id) => (int) $id) + ->unique() + ->values(); + } + /** * دادهٔ قدیمی: type=4 با cash مثبت (واریز ادمین) — قبل از فیلتر جدول اصلاح می‌شود. */ diff --git a/database/migrations/2026_07_12_000002_add_support_messengers_setting.php b/database/migrations/2026_07_12_000002_add_support_messengers_setting.php new file mode 100644 index 0000000..bbb09d9 --- /dev/null +++ b/database/migrations/2026_07_12_000002_add_support_messengers_setting.php @@ -0,0 +1,51 @@ +where('key', 'support_messengers')->exists()) { + DB::table('settings')->insert([ + 'key' => 'support_messengers', + 'value' => '', + 'title_fa' => 'پیام‌رسان‌های پشتیبانی', + 'type' => 'longtext', + 'can_edit' => 1, + 'is_active' => 1, + 'description' => 'لیست JSON پیام‌رسان‌ها — هر مورد: messenger + id', + 'created_at' => now(), + 'updated_at' => now(), + ]); + } + + $current = trim((string) DB::table('settings')->where('key', 'support_messengers')->value('value')); + if ($current !== '') { + return; + } + + $legacyType = trim((string) DB::table('settings')->where('key', 'support_messenger')->value('value')); + $legacyId = trim((string) DB::table('settings')->where('key', 'support_messenger_id')->value('value')); + + if ($legacyId === '') { + return; + } + + $messenger = $legacyType !== '' ? $legacyType : 'bale'; + $payload = json_encode([ + ['messenger' => $messenger, 'id' => $legacyId], + ], JSON_UNESCAPED_UNICODE); + + DB::table('settings')->where('key', 'support_messengers')->update([ + 'value' => $payload, + 'updated_at' => now(), + ]); + } + + public function down(): void + { + DB::table('settings')->where('key', 'support_messengers')->delete(); + } +}; diff --git a/database/migrations/2026_07_12_000003_add_tracking_systems_setting.php b/database/migrations/2026_07_12_000003_add_tracking_systems_setting.php new file mode 100644 index 0000000..e9af690 --- /dev/null +++ b/database/migrations/2026_07_12_000003_add_tracking_systems_setting.php @@ -0,0 +1,29 @@ +where('key', 'tracking_systems')->exists()) { + DB::table('settings')->insert([ + 'key' => 'tracking_systems', + 'value' => '[]', + 'title_fa' => 'سامانه‌های ردیابی', + 'type' => 'longtext', + 'can_edit' => 0, + 'is_active' => 1, + 'description' => 'JSON لیست سامانه‌های آنالیتیکس/ردیابی — فقط دیپلوی', + 'created_at' => now(), + 'updated_at' => now(), + ]); + } + } + + public function down(): void + { + DB::table('settings')->where('key', 'tracking_systems')->delete(); + } +}; diff --git a/database/sql/add_support_messengers_setting.sql b/database/sql/add_support_messengers_setting.sql new file mode 100644 index 0000000..8d07218 --- /dev/null +++ b/database/sql/add_support_messengers_setting.sql @@ -0,0 +1,33 @@ +-- چند پیام‌رسان پشتیبانی — migrate از support_messenger + support_messenger_id + +INSERT INTO `settings` (`key`, `value`, `title_fa`, `type`, `can_edit`, `is_active`, `description`, `created_at`, `updated_at`) +SELECT + 'support_messengers', + '', + 'پیام‌رسان‌های پشتیبانی', + 'longtext', + 1, + 1, + 'JSON: [{"messenger":"bale","id":"username"}] — واتساپ: شماره با کد کشور', + NOW(), + NOW() +WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'support_messengers' LIMIT 1); + +UPDATE `settings` AS sm +JOIN ( + SELECT + TRIM(COALESCE( + (SELECT `value` FROM `settings` WHERE `key` = 'support_messenger_id' LIMIT 1), + '' + )) AS legacy_id, + TRIM(COALESCE( + NULLIF((SELECT `value` FROM `settings` WHERE `key` = 'support_messenger' LIMIT 1), ''), + 'bale' + )) AS legacy_type +) AS src +SET sm.`value` = CONCAT( + '[{"messenger":"', REPLACE(src.legacy_type, '"', '\\"'), '","id":"', REPLACE(src.legacy_id, '"', '\\"'), '"}]' +) +WHERE sm.`key` = 'support_messengers' + AND TRIM(COALESCE(sm.`value`, '')) = '' + AND src.legacy_id <> ''; diff --git a/database/sql/add_tracking_systems_setting.sql b/database/sql/add_tracking_systems_setting.sql new file mode 100644 index 0000000..9b99cac --- /dev/null +++ b/database/sql/add_tracking_systems_setting.sql @@ -0,0 +1,14 @@ +-- سامانه‌های ردیابی (آنالیتیکس) — can_edit=0، مقدار JSON + +INSERT INTO `settings` (`key`, `value`, `title_fa`, `type`, `can_edit`, `is_active`, `description`, `created_at`, `updated_at`) +SELECT + 'tracking_systems', + '[]', + 'سامانه‌های ردیابی', + 'longtext', + 0, + 1, + 'JSON: [{"type":"gtag","id":"G-XXXXXXX","enabled":true}] — type: gtag|gtm|clarity|custom', + NOW(), + NOW() +WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'tracking_systems' LIMIT 1); diff --git a/database/sql/deploy_settings_const.sql b/database/sql/deploy_settings_const.sql index 1b338ad..446c073 100644 --- a/database/sql/deploy_settings_const.sql +++ b/database/sql/deploy_settings_const.sql @@ -292,6 +292,11 @@ INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `de SELECT 'sse_path', '/api/price/stream', 'مسیر SSE قیمت', 0, 1, 'GET لاراول — استریم event:last و event:list با payload کامل', 'text' WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'sse_path' LIMIT 1); +INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`, `type`) +SELECT 'tracking_systems', '[]', 'سامانه‌های ردیابی', 0, 1, + 'JSON لیست آنالیتیکس — type: gtag|gtm|clarity|custom؛ id شناسه/کد؛ enabled روشن/خاموش', 'longtext' +WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'tracking_systems' LIMIT 1); + INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`, `type`) SELECT 'montify_name', '', 'نام فروشگاه در درگاه', 0, 1, NULL, 'text' WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'montify_name' LIMIT 1); @@ -785,7 +790,7 @@ WHERE `key` = 'main_product'; UPDATE `settings` SET `type` = 'longtext' WHERE `key` IN ( 'text_rule', 'text_about', 'support_messenger_text', 'invite_link_text', 'deposit_support_message_text', 'price_channel_message_text', - 'montzar_order_response', 'montzar_last_product_log' + 'montzar_order_response', 'montzar_last_product_log', 'tracking_systems' ); -- select (+ گزینه‌ها در description) @@ -1182,6 +1187,7 @@ UPDATE `settings` SET `description` = 'کلید مشترک امضای HMAC بر UPDATE `settings` SET `description` = 'روشن: API دریافت کیف پول و ثبت سفارش از سرویس فروشگاه خارجی فعال است. نیاز به node_client_id و node_shared_secret دارد.' WHERE `key` = 'external_order_api_enabled'; UPDATE `settings` SET `description` = 'روشن: اپ به SSE (sse_path) وصل می‌شود و last/list با payload می‌آید؛ خاموش: polling.' WHERE `key` = 'wss_enabled'; UPDATE `settings` SET `description` = 'مسیر GET لاراول برای استریم قیمت — پیش‌فرض /api/price/stream' WHERE `key` = 'sse_path'; +UPDATE `settings` SET `description` = 'JSON لیست سامانه‌های آنالیتیکس — هر مورد: type (gtag|gtm|clarity|custom)، id، enabled. فقط دیپلوی.' WHERE `key` = 'tracking_systems'; UPDATE `settings` SET `description` = 'نام فروشگاه که در درگاه پرداخت و رسید بانکی به کاربر نمایش داده می‌شود.' WHERE `key` = 'montify_name'; UPDATE `settings` SET `description` = 'روشن: پس از واریز/برداشت، تراکنش به سامانه حسابداری fin همگام‌سازی می‌شود.' WHERE `key` = 'payping_fin_sync_enabled'; @@ -1394,6 +1400,7 @@ UPDATE `settings` SET `title_fa` = 'عنوان PWA' WHERE `key` = 'title_pwa'; UPDATE `settings` SET `title_fa` = 'واحد وزن دارایی و معاملات' WHERE `key` = 'unit'; UPDATE `settings` SET `title_fa` = 'بیشترین قیمت امروز' WHERE `key` = 'up_price'; UPDATE `settings` SET `title_fa` = 'قیمت لحظه‌ای (SSE)' WHERE `key` = 'wss_enabled'; +UPDATE `settings` SET `title_fa` = 'سامانه‌های ردیابی' WHERE `key` = 'tracking_systems'; UPDATE `settings` SET `title_fa` = 'آدرس API تابلو Zaarbox' WHERE `key` = 'zaarbox_api_url'; UPDATE `settings` SET `title_fa` = 'شناسه ردیف تابلو (key یا UUID)' WHERE `key` = 'zaarbox_price_key'; @@ -1426,6 +1433,7 @@ UPDATE `settings` SET `can_edit` = 0 WHERE `key` IN ( 'price_extreme_date', 'price_provider', 'profit_gold_api_enabled', 'send_to_tahesab', 'service_charge_percentage', 'sse_path', + 'tracking_systems', 'tahesab_bank_account', 'tahesab_db', 'tahesab_host', 'tahesab_port', 'tahesab_token', 'telegram_bot_token', 'rubika_bot_token', 'price_channel_bale_to', 'price_channel_telegram_to', 'price_channel_rubika_to', 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 e7fd7f2..ca3ff12 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 @@ -245,6 +245,11 @@ INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `de SELECT 'sse_path', '/api/price/stream', 'مسیر SSE قیمت', 0, 1, 'GET لاراول — استریم event:last و event:list با payload کامل', 'text' WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'sse_path' LIMIT 1); +INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`, `type`) +SELECT 'tracking_systems', '[]', 'سامانه‌های ردیابی', 0, 1, + 'JSON لیست آنالیتیکس — type: gtag|gtm|clarity|custom؛ id شناسه/کد؛ enabled روشن/خاموش', 'longtext' +WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'tracking_systems' LIMIT 1); + INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`, `type`) SELECT 'montify_name', '', 'نام فروشگاه در درگاه', 1, 1, NULL, 'text' WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'montify_name' LIMIT 1); @@ -667,7 +672,7 @@ WHERE `key` = 'main_product'; -- ============================================================================= -- longtext -UPDATE `settings` SET `type` = 'longtext' WHERE `key` IN ('text_rule', 'text_about', 'support_messenger_text', 'invite_link_text', 'deposit_support_message_text', 'montzar_order_response'); +UPDATE `settings` SET `type` = 'longtext' WHERE `key` IN ('text_rule', 'text_about', 'support_messenger_text', 'invite_link_text', 'deposit_support_message_text', 'montzar_order_response', 'tracking_systems'); -- select (+ گزینه‌ها در description) UPDATE `settings` SET `type` = 'select', `description` = 'منبع فعال قیمت|montzar,zaarbox,main_product' WHERE `key` = 'price_provider'; @@ -1087,6 +1092,7 @@ UPDATE `settings` SET `description` = 'کلید مشترک امضای HMAC بر UPDATE `settings` SET `description` = 'روشن: API دریافت کیف پول و ثبت سفارش از سرویس فروشگاه خارجی فعال است. نیاز به node_client_id و node_shared_secret دارد.' WHERE `key` = 'external_order_api_enabled'; UPDATE `settings` SET `description` = 'روشن: اپ به SSE (sse_path) وصل می‌شود و last/list با payload می‌آید؛ خاموش: polling.' WHERE `key` = 'wss_enabled'; UPDATE `settings` SET `description` = 'مسیر GET لاراول برای استریم قیمت — پیش‌فرض /api/price/stream' WHERE `key` = 'sse_path'; +UPDATE `settings` SET `description` = 'JSON لیست سامانه‌های آنالیتیکس — هر مورد: type (gtag|gtm|clarity|custom)، id، enabled. فقط دیپلوی.' WHERE `key` = 'tracking_systems'; UPDATE `settings` SET `description` = 'نام فروشگاه که در درگاه پرداخت و رسید بانکی به کاربر نمایش داده می‌شود.' WHERE `key` = 'montify_name'; UPDATE `settings` SET `description` = 'روشن: پس از واریز/برداشت، تراکنش به سامانه حسابداری fin همگام‌سازی می‌شود.' WHERE `key` = 'payping_fin_sync_enabled'; @@ -1184,6 +1190,7 @@ UPDATE `settings` SET `can_edit` = 0 WHERE `key` IN ( 'price_extreme_date', 'price_provider', 'profit_gold_api_enabled', 'send_to_tahesab', 'service_charge_percentage', 'sse_path', + 'tracking_systems', 'tahesab_bank_account', 'tahesab_db', 'tahesab_host', 'tahesab_port', 'tahesab_token', 'telegram_bot_token', 'unit',