From 7a18d76ad954481c853a1a55881ed571857a821e Mon Sep 17 00:00:00 2001 From: mohammad sedighi Date: Wed, 24 Jun 2026 01:17:34 +0330 Subject: [PATCH] fix report --- .../Controllers/Admin/WalletController.php | 42 ++--- app/Http/Controllers/Controller.php | 41 ++++- .../Controllers/Customer/WalletController.php | 24 ++- app/Services/ConfigService.php | 29 ++++ app/Services/TransactionMetalService.php | 154 ++++++++++++++++++ 5 files changed, 256 insertions(+), 34 deletions(-) create mode 100644 app/Services/TransactionMetalService.php diff --git a/app/Http/Controllers/Admin/WalletController.php b/app/Http/Controllers/Admin/WalletController.php index 42bfbb3..784d79b 100644 --- a/app/Http/Controllers/Admin/WalletController.php +++ b/app/Http/Controllers/Admin/WalletController.php @@ -20,6 +20,8 @@ use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException; use App\Http\Controllers\Admin\TahesabController; use App\Models\Setting; use App\Models\User; +use App\Services\ConfigService; +use App\Services\TransactionMetalService; use Hekmatinasser\Verta\Verta; @@ -178,12 +180,14 @@ class WalletController extends Controller "note" => $data['note'], 'sts' => 4, ]); + $representative = app(ConfigService::class)->mainWalletRepresentativeProduct(); new TransactionInterface($wallet_interface, $_inp = [ 'cash' => 0, 'gold' => $data['value'], 'expire_at' => now(), "note" => $data['note'], 'withdraw_id' => $Withdraw->id, + 'product_id' => $representative?->id, 'active' => true ], 7, $deposit, false, $gold_block); @@ -199,8 +203,9 @@ class WalletController extends Controller } //send sms to users and customer $status = $data['value'] > 0 ?" شارژ شد ": " کسر شد "; + $weightUnit = self::tradeWeightUnit(); if($this->Config('charge_notif') == "true"){ - $message = 'کیف پول کاربر ' . $customer->name . ' به مقدار ' . self::formatSmsGoldWeight($data['value']) . " گرم در تاریخ " . verta()->format('Y/n/j H:i:s') .$status . "بابت" . "\n" + $message = 'کیف پول کاربر ' . $customer->name . ' به مقدار ' . self::formatSmsGoldWeight($data['value']) . " {$weightUnit} در تاریخ " . verta()->format('Y/n/j H:i:s') .$status . "بابت" . "\n" . $data['note'] . "\n" . $this->Config('name_fa'); @@ -209,44 +214,27 @@ class WalletController extends Controller }); } - $message = 'کیف پول شما به اندازه ' . self::formatSmsGoldWeight($data['value']) . " گرم در تاریخ " . verta()->format('Y/n/j H:i:s') . $status . " بابت" . "\n" + $message = 'کیف پول شما به اندازه ' . self::formatSmsGoldWeight($data['value']) . " {$weightUnit} در تاریخ " . verta()->format('Y/n/j H:i:s') . $status . " بابت" . "\n" . $data['note'] . $this->Config('name_fa'); $this->Send($customer->mobile, $message); return response()->json(true); } - public function index(Request $request) + public function index(Request $request, TransactionMetalService $transactionMetalService) { - $records = Transaction::with(['customer'])->whereNull('fund_id'); + $records = Transaction::with(['customer', 'wallet.product:id,metal_id', 'product:id,metal_id']) + ->whereNull('fund_id'); TableEngine::create($records, $request->all()) ->initSearch(['order_id', 'customer.name']) ->select([ '*', Transaction::$SELECT_CAJ, Transaction::$SELECT_TYPE_STR, Transaction::$SELECT_SAJ, Transaction::$SELECT_EAJ ])->export($records); -// foreach ($records['rows'] as &$record) { -// if (empty($record->title) or $record->title == "تعریف نشده"){ -// $record->title = $record->type_str ; -// $record->unit = "گرم"; -// if (isset($record->wallet)) { -// $wallet = Wallet::with('product')->where('id',$record->wallet)->first(); -// if (isset($wallet->product)) { -// if ($record->gold > 0){ -// $record->title = " خرید " ; -// -// }else{ -// $record->title = " فروش " ; -// -// } -// $record->title .= $wallet->product->title ; -// $record->unit = "عدد"; -// -// } -// } -// $record->save(); -// } -// -// } + + if (isset($records['rows'])) { + $records['rows'] = $transactionMetalService->enrichTransactionRows($records['rows']); + } + $records['catalogMetals'] = $transactionMetalService->catalogMetals(); return response()->json($records); } diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index adc83ec..578b1c0 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -206,6 +206,27 @@ class Controller extends BaseController return self::metalTypeSettingValue() ?? 'طلا'; } + public static function metalIdLabel(int $metalId): string + { + return match ($metalId) { + 1 => 'طلا', + 2 => 'نقره', + 3 => 'مس', + default => self::metalTypeLabel(), + }; + } + + /** برچسب فلز کیف اصلی از `main_wallet_products` یا setting */ + public static function mainWalletMetalLabel(): string + { + $product = app(ConfigService::class)->mainWalletRepresentativeProduct(); + if ($product && (int) ($product->metal_id ?? 0) > 0) { + return self::metalIdLabel((int) $product->metal_id); + } + + return self::metalTypeLabel(); + } + /** برچسب معاملات آبشده: مقدار setting یا «آبشده» */ public static function meltedGoldLabel(): string { @@ -239,10 +260,14 @@ class Controller extends BaseController public static function genericMetalTransactionTitles(): array { - $titles = self::legacyMeltedTransactionTitles(); + $titles = array_merge(self::legacyMeltedTransactionTitles(), [ + 'واریز طلایی', + 'برداشت طلایی', + ]); foreach (self::metalLabelVariants() as $label) { $titles[] = "موجودی {$label}"; + $titles[] = "واریز {$label}"; $titles[] = "برداشت {$label}"; $titles[] = "خرید {$label}"; $titles[] = "فروش {$label}"; @@ -277,12 +302,22 @@ class Controller extends BaseController public static function mainMetalBuyTitle(): string { - return self::productBuyTitle(self::metalTypeLabel()); + return self::productBuyTitle(self::mainWalletMetalLabel()); } public static function mainMetalSellTitle(): string { - return self::productSellTitle(self::metalTypeLabel()); + return self::productSellTitle(self::mainWalletMetalLabel()); + } + + public static function mainMetalDepositTitle(): string + { + return 'واریز ' . self::mainWalletMetalLabel(); + } + + public static function mainMetalWithdrawTitle(): string + { + return 'برداشت ' . self::mainWalletMetalLabel(); } /** diff --git a/app/Http/Controllers/Customer/WalletController.php b/app/Http/Controllers/Customer/WalletController.php index bf1de39..81a38ef 100644 --- a/app/Http/Controllers/Customer/WalletController.php +++ b/app/Http/Controllers/Customer/WalletController.php @@ -476,9 +476,17 @@ class WalletController extends Controller } if (preg_match('/^(موجودی|واریز)/u', (string) $record->title)) { - $record->title = self::meltedGoldDepositTitle(); + if ((int) ($record->type ?? 0) === 7) { + $record->title = self::mainMetalDepositTitle(); + } else { + $record->title = self::meltedGoldDepositTitle(); + } } elseif (preg_match('/^برداشت /u', (string) $record->title)) { - $record->title = self::meltedGoldWithdrawTitle(); + if ((int) ($record->type ?? 0) === 10) { + $record->title = self::mainMetalWithdrawTitle(); + } else { + $record->title = self::meltedGoldWithdrawTitle(); + } } elseif (preg_match('/^خرید /u', (string) $record->title)) { $record->title = self::meltedGoldBuyTitle(); } elseif (preg_match('/^فروش /u', (string) $record->title)) { @@ -525,11 +533,19 @@ class WalletController extends Controller private function resolveMainWalletTransactionTitle($record): string { if ((int) $record->type === 1) { - return self::meltedGoldBuyTitle(); + return self::mainMetalBuyTitle(); } if ((int) $record->type === 2) { - return self::meltedGoldSellTitle(); + return self::mainMetalSellTitle(); + } + + if ((int) $record->type === 7) { + return self::mainMetalDepositTitle(); + } + + if ((int) $record->type === 10) { + return self::mainMetalWithdrawTitle(); } return $record->type_str; diff --git a/app/Services/ConfigService.php b/app/Services/ConfigService.php index 5fe5abf..4be95a9 100644 --- a/app/Services/ConfigService.php +++ b/app/Services/ConfigService.php @@ -215,6 +215,35 @@ class ConfigService return in_array($productId, $this->mainWalletProductIds(), true); } + /** اولین محصول فعال از `main_wallet_products` — نماینده کیف اصلی */ + public function mainWalletRepresentativeProduct(): ?Product + { + foreach ($this->mainWalletProductIds() as $productId) { + $product = Product::query()->where('active', 1)->find($productId); + if ($product) { + return $product; + } + } + + foreach ($this->mainWalletProductIds() as $productId) { + $product = Product::query()->find($productId); + if ($product) { + return $product; + } + } + + return null; + } + + /** metal_id محصول نماینده کیف اصلی — پیش‌فرض ۱ (طلا) */ + public function mainWalletMetalId(): int + { + $product = $this->mainWalletRepresentativeProduct(); + $metalId = $product ? (int) ($product->metal_id ?? 0) : 0; + + return $metalId > 0 ? $metalId : 1; + } + /** * شناسه محصول آبشده: اول settings، بعد const. * مقدار settings می‌تواند id عددی (مثل 13) یا reading_method (مثل estjt_...) باشد. diff --git a/app/Services/TransactionMetalService.php b/app/Services/TransactionMetalService.php new file mode 100644 index 0000000..4143251 --- /dev/null +++ b/app/Services/TransactionMetalService.php @@ -0,0 +1,154 @@ + 'طلا', + 2 => 'نقره', + 3 => 'مس', + ]; + + public function __construct( + private readonly ConfigService $configService + ) { + } + + public function metalLabel(int $metalId): string + { + return self::METAL_LABELS[$metalId] ?? Controller::metalTypeLabel(); + } + + /** @return array */ + public function catalogMetals(): array + { + return Product::query() + ->where('active', 1) + ->pluck('metal_id') + ->filter(fn ($id) => (int) $id > 0) + ->map(fn ($id) => (int) $id) + ->unique() + ->sort() + ->values() + ->map(fn (int $metalId) => [ + 'metal_id' => $metalId, + 'label' => $this->metalLabel($metalId), + 'display_unit' => Controller::tradeWeightUnit(), + ]) + ->all(); + } + + public function resolveMetalIdForTransaction(object $transaction): int + { + $productId = (int) ($transaction->product_id ?? 0); + if ($productId > 0) { + $metalId = (int) (Product::query()->whereKey($productId)->value('metal_id') ?? 0); + if ($metalId > 0) { + return $metalId; + } + } + + $wallet = $transaction->wallet ?? null; + if (is_numeric($wallet)) { + $wallet = Wallet::with('product:id,metal_id')->find($wallet); + } elseif (is_object($wallet) && !$wallet->relationLoaded('product')) { + $wallet->load('product:id,metal_id'); + } + + if (is_object($wallet) && $wallet->product_id && $wallet->product) { + $metalId = (int) ($wallet->product->metal_id ?? 0); + if ($metalId > 0) { + return $metalId; + } + } + + if ($this->isMainWalletMetalTransaction($transaction, $wallet)) { + return $this->configService->mainWalletMetalId(); + } + + return 1; + } + + private function isMainWalletMetalTransaction(object $transaction, mixed $wallet): bool + { + $type = (int) ($transaction->type ?? 0); + if (!in_array($type, [1, 2, 7, 10], true)) { + return false; + } + + if (!$wallet || !is_object($wallet)) { + return true; + } + + return $wallet->product_id === null && $wallet->fund_id === null; + } + + public function resolveDisplayTypeStr(object $transaction): ?string + { + $type = (int) ($transaction->type ?? 0); + if (!in_array($type, [1, 2, 7, 10], true)) { + return null; + } + + $metalLabel = $this->metalLabel($this->resolveMetalIdForTransaction($transaction)); + + return match ($type) { + 1 => Controller::productBuyTitle($metalLabel), + 2 => Controller::productSellTitle($metalLabel), + 7 => 'واریز ' . $metalLabel, + 10 => 'برداشت ' . $metalLabel, + default => null, + }; + } + + /** @param iterable|object> $rows */ + public function enrichTransactionRows(iterable $rows): array + { + $metalIds = array_column($this->catalogMetals(), 'metal_id'); + $enriched = []; + + foreach ($rows as $row) { + $record = is_array($row) ? (object) $row : $row; + $metalId = $this->resolveMetalIdForTransaction($record); + $displayType = $this->resolveDisplayTypeStr($record); + $type = (int) (is_array($row) ? ($row['type'] ?? 0) : ($row->type ?? 0)); + $gold = (float) (is_array($row) ? ($row['gold'] ?? 0) : ($row->gold ?? 0)); + $isMoney = in_array($type, [3, 4], true); + + if ($displayType !== null) { + if (is_array($row)) { + $row['type_str'] = $displayType; + } else { + $row->type_str = $displayType; + } + } + + foreach ($metalIds as $mid) { + $key = "metal_gold_{$mid}"; + $value = (!$isMoney && $metalId === $mid) ? $gold : 0; + if (is_array($row)) { + $row[$key] = $value; + } else { + $row->{$key} = $value; + } + } + + if (is_array($row)) { + $row['transaction_metal_id'] = $metalId; + $row['transaction_metal_label'] = $this->metalLabel($metalId); + } else { + $row->transaction_metal_id = $metalId; + $row->transaction_metal_label = $this->metalLabel($metalId); + } + + $enriched[] = $row; + } + + return $enriched; + } +}