fix bug 2

This commit is contained in:
2026-07-12 18:31:17 +03:30
parent 2cade8a334
commit b29cb4e37a
7 changed files with 223 additions and 9 deletions
@@ -130,13 +130,10 @@ class WalletController extends Controller
$customerId = (int) auth('customer')->id(); $customerId = (int) auth('customer')->id();
$this->repairMisclassifiedRialTransactions($customerId); $this->repairMisclassifiedRialTransactions($customerId);
if (isset($request->wallet_id)){ $mainWalletProductIds = app(ConfigService::class)->mainWalletProductIds();
$wallet = Wallet::with('product')->where('id', $request->wallet_id)->where('owner', auth('customer')->id())->get(); $walletIds = $this->resolveTransactionTableWalletIds($customerId, $request, $mainWalletProductIds);
}else{
$wallet = Wallet::with('product')->where('owner', auth('customer')->id())->get();
}
if ($wallet->isEmpty()) { if ($walletIds->isEmpty()) {
$records = ['query' => ['total' => 0], 'rows' => []]; $records = ['query' => ['total' => 0], 'rows' => []];
} else { } else {
$records = Transaction::with([ $records = Transaction::with([
@@ -148,7 +145,7 @@ class WalletController extends Controller
}, },
'wallet.product', 'wallet.product',
'product', 'product',
])->whereIn('wallet', $wallet->pluck('id'))->whereNull('fund_id'); ])->whereIn('wallet', $walletIds)->whereNull('fund_id');
TableEngine::create($records, $request->all()) TableEngine::create($records, $request->all())
->initSearch(['customer.name']) ->initSearch(['customer.name'])
@@ -211,6 +208,81 @@ class WalletController extends Controller
return response()->json($records); return response()->json($records);
} }
/**
* کیف(های) مؤثر برای جدول تراکنش.
* محصولات main_wallet_products: تراکنش‌ها روی کیف اصلی (+ کیف legacy محصول) ثبت شده‌اند.
*
* @return \Illuminate\Support\Collection<int, int>
*/
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<int, int>
*/
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 مثبت (واریز ادمین) — قبل از فیلتر جدول اصلاح می‌شود. * دادهٔ قدیمی: type=4 با cash مثبت (واریز ادمین) — قبل از فیلتر جدول اصلاح می‌شود.
*/ */
@@ -0,0 +1,51 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
public function up(): void
{
if (! DB::table('settings')->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();
}
};
@@ -0,0 +1,29 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
public function up(): void
{
if (! DB::table('settings')->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();
}
};
@@ -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 <> '';
@@ -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);
+9 -1
View File
@@ -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' 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); 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`) INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`, `type`)
SELECT 'montify_name', '', 'نام فروشگاه در درگاه', 0, 1, NULL, 'text' SELECT 'montify_name', '', 'نام فروشگاه در درگاه', 0, 1, NULL, 'text'
WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'montify_name' LIMIT 1); 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 ( UPDATE `settings` SET `type` = 'longtext' WHERE `key` IN (
'text_rule', 'text_about', 'support_messenger_text', 'invite_link_text', 'text_rule', 'text_about', 'support_messenger_text', 'invite_link_text',
'deposit_support_message_text', 'price_channel_message_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) -- 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` = 'روشن: 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` = 'روشن: اپ به 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` = 'مسیر 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` = 'نام فروشگاه که در درگاه پرداخت و رسید بانکی به کاربر نمایش داده می‌شود.' WHERE `key` = 'montify_name';
UPDATE `settings` SET `description` = 'روشن: پس از واریز/برداشت، تراکنش به سامانه حسابداری fin همگام‌سازی می‌شود.' WHERE `key` = 'payping_fin_sync_enabled'; 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` = 'unit';
UPDATE `settings` SET `title_fa` = 'بیشترین قیمت امروز' WHERE `key` = 'up_price'; UPDATE `settings` SET `title_fa` = 'بیشترین قیمت امروز' WHERE `key` = 'up_price';
UPDATE `settings` SET `title_fa` = 'قیمت لحظه‌ای (SSE)' WHERE `key` = 'wss_enabled'; 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` = 'آدرس API تابلو Zaarbox' WHERE `key` = 'zaarbox_api_url';
UPDATE `settings` SET `title_fa` = 'شناسه ردیف تابلو (key یا UUID)' WHERE `key` = 'zaarbox_price_key'; 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', 'price_extreme_date', 'price_provider', 'profit_gold_api_enabled',
'send_to_tahesab', 'service_charge_percentage', 'send_to_tahesab', 'service_charge_percentage',
'sse_path', 'sse_path',
'tracking_systems',
'tahesab_bank_account', 'tahesab_db', 'tahesab_host', 'tahesab_port', 'tahesab_token', 'tahesab_bank_account', 'tahesab_db', 'tahesab_host', 'tahesab_port', 'tahesab_token',
'telegram_bot_token', 'rubika_bot_token', 'telegram_bot_token', 'rubika_bot_token',
'price_channel_bale_to', 'price_channel_telegram_to', 'price_channel_rubika_to', 'price_channel_bale_to', 'price_channel_telegram_to', 'price_channel_rubika_to',
@@ -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' 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); 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`) INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`, `type`)
SELECT 'montify_name', '', 'نام فروشگاه در درگاه', 1, 1, NULL, 'text' SELECT 'montify_name', '', 'نام فروشگاه در درگاه', 1, 1, NULL, 'text'
WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'montify_name' LIMIT 1); WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'montify_name' LIMIT 1);
@@ -667,7 +672,7 @@ WHERE `key` = 'main_product';
-- ============================================================================= -- =============================================================================
-- longtext -- 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) -- select (+ گزینه‌ها در description)
UPDATE `settings` SET `type` = 'select', `description` = 'منبع فعال قیمت|montzar,zaarbox,main_product' WHERE `key` = 'price_provider'; 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` = 'روشن: 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` = 'روشن: اپ به 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` = 'مسیر 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` = 'نام فروشگاه که در درگاه پرداخت و رسید بانکی به کاربر نمایش داده می‌شود.' WHERE `key` = 'montify_name';
UPDATE `settings` SET `description` = 'روشن: پس از واریز/برداشت، تراکنش به سامانه حسابداری fin همگام‌سازی می‌شود.' WHERE `key` = 'payping_fin_sync_enabled'; 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', 'price_extreme_date', 'price_provider', 'profit_gold_api_enabled',
'send_to_tahesab', 'service_charge_percentage', 'send_to_tahesab', 'service_charge_percentage',
'sse_path', 'sse_path',
'tracking_systems',
'tahesab_bank_account', 'tahesab_db', 'tahesab_host', 'tahesab_port', 'tahesab_token', 'tahesab_bank_account', 'tahesab_db', 'tahesab_host', 'tahesab_port', 'tahesab_token',
'telegram_bot_token', 'telegram_bot_token',
'unit', 'unit',