diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index 25f722c..ad35bd1 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -155,11 +155,111 @@ class Controller extends BaseController return Setting::where('key',$name)->first()->value ?? false; } - public static function metalTypeLabel(): string + protected static function metalTypeSettingValue(): ?string { $metalType = Setting::where('key', 'metal_type')->value('value'); + if ($metalType === null) { + return null; + } - return ($metalType !== null && trim((string) $metalType) !== '') ? trim((string) $metalType) : 'طلا'; + $metalType = trim((string) $metalType); + + return $metalType !== '' ? $metalType : null; + } + + /** برچسب موجودی کیف اصلی: مقدار setting یا «طلا» */ + public static function metalTypeLabel(): string + { + return self::metalTypeSettingValue() ?? 'طلا'; + } + + /** برچسب معاملات آبشده: مقدار setting یا «آبشده» */ + public static function meltedGoldLabel(): string + { + return self::metalTypeSettingValue() ?? 'آبشده'; + } + + public static function cashTransactionTitles(): array + { + return ['برداشت وجه نقد', 'واریز وجه نقد']; + } + + public static function legacyMeltedTransactionTitles(): array + { + return [ + 'واریز طلای ابشده', + 'واریز طلای آبشده', + 'برداشت طلای ابشده', + 'برداشت طلای آبشده', + ]; + } + + protected static function metalLabelVariants(): array + { + return array_values(array_unique([ + self::meltedGoldLabel(), + self::metalTypeLabel(), + 'طلا', + 'آبشده', + ])); + } + + public static function genericMetalTransactionTitles(): array + { + $titles = self::legacyMeltedTransactionTitles(); + + foreach (self::metalLabelVariants() as $label) { + $titles[] = "موجودی {$label}"; + $titles[] = "برداشت {$label}"; + $titles[] = "خرید {$label}"; + $titles[] = "فروش {$label}"; + } + + return array_values(array_unique($titles)); + } + + public static function isCashTransactionTitle(?string $title): bool + { + return $title !== null && in_array($title, self::cashTransactionTitles(), true); + } + + public static function isGenericMetalTransactionTitle(?string $title): bool + { + if ($title === null || self::isCashTransactionTitle($title)) { + return false; + } + + return in_array($title, self::genericMetalTransactionTitles(), true); + } + + public static function productBuyTitle(string $productTitle): string + { + return 'خرید ' . $productTitle; + } + + public static function productSellTitle(string $productTitle): string + { + return 'فروش ' . $productTitle; + } + + public static function meltedGoldBuyTitle(): string + { + return 'خرید ' . self::meltedGoldLabel(); + } + + public static function meltedGoldSellTitle(): string + { + return 'فروش ' . self::meltedGoldLabel(); + } + + public static function meltedGoldDepositTitle(): string + { + return 'موجودی ' . self::meltedGoldLabel(); + } + + public static function meltedGoldWithdrawTitle(): string + { + return 'برداشت ' . self::meltedGoldLabel(); } public static function jibit($method, $p1 = null, $p2 = null, $p3 = null) diff --git a/app/Http/Controllers/Customer/WalletController.php b/app/Http/Controllers/Customer/WalletController.php index 6ccd710..521dc74 100644 --- a/app/Http/Controllers/Customer/WalletController.php +++ b/app/Http/Controllers/Customer/WalletController.php @@ -110,21 +110,28 @@ class WalletController extends Controller $wallet = Wallet::with('product')->where('id', $record->wallet)->first(); if (isset($wallet->product)) { - if ($record->gold > 0) { - $record->title = " خرید "; + $direction = $record->order->direction ?? null; + if ((int) $direction === 1) { + $record->title = self::productBuyTitle($wallet->product->title); + } elseif ((int) $direction === 2) { + $record->title = self::productSellTitle($wallet->product->title); } else { - $record->title = " فروش "; + $record->title = ($record->gold > 0 ? self::productBuyTitle($wallet->product->title) : self::productSellTitle($wallet->product->title)); } - - $record->title .= $wallet->product->title; $record->unit = "عدد"; + } else { + $record->title = $this->resolveMainWalletTransactionTitle($record); } + } else { + $record->title = $record->type_str; } $record->save(); } $this->applyMetalTypeTransactionTitle($record); + $this->applyProductTransactionTitle($record); + $this->applyProductOrderDisplayFields($record); } return response()->json($records); @@ -344,15 +351,147 @@ class WalletController extends Controller private function applyMetalTypeTransactionTitle($record): void { - $metalLabel = self::metalTypeLabel(); - $legacyDepositTitles = ['واریز طلای ابشده', 'واریز طلای آبشده']; - $legacyWithdrawTitles = ['برداشت طلای ابشده', 'برداشت طلای آبشده']; + if (!empty($record->product_id)) { + return; + } - if (in_array($record->title, $legacyDepositTitles, true)) { - $record->title = "موجودی {$metalLabel}"; - } elseif (in_array($record->title, $legacyWithdrawTitles, true)) { - $record->title = "برداشت {$metalLabel}"; + $wallet = $record->wallet ?? null; + if ($wallet && !empty($wallet->product)) { + return; + } + + if (self::isCashTransactionTitle($record->title)) { + return; + } + + if (!self::isGenericMetalTransactionTitle($record->title)) { + return; + } + + if (preg_match('/^(موجودی|واریز)/u', (string) $record->title)) { + $record->title = self::meltedGoldDepositTitle(); + } elseif (preg_match('/^برداشت /u', (string) $record->title)) { + $record->title = self::meltedGoldWithdrawTitle(); + } elseif (preg_match('/^خرید /u', (string) $record->title)) { + $record->title = self::meltedGoldBuyTitle(); + } elseif (preg_match('/^فروش /u', (string) $record->title)) { + $record->title = self::meltedGoldSellTitle(); } } + private function applyProductTransactionTitle($record): void + { + if (empty($record->product_id)) { + return; + } + + if (self::isCashTransactionTitle($record->title)) { + return; + } + + $productTitle = $record->wallet->product->title ?? $record->product->title ?? null; + if (!$productTitle) { + return; + } + + $expectedBuy = self::productBuyTitle($productTitle); + $expectedSell = self::productSellTitle($productTitle); + + if ($record->title === $expectedBuy || $record->title === $expectedSell) { + return; + } + + if (!self::isGenericMetalTransactionTitle($record->title)) { + return; + } + + $direction = $record->order->direction ?? null; + if ((int) $direction === 1) { + $record->title = $expectedBuy; + return; + } + + if ((int) $direction === 2) { + $record->title = $expectedSell; + } + } + + private function resolveMainWalletTransactionTitle($record): string + { + if ((int) $record->type === 1) { + return self::meltedGoldBuyTitle(); + } + + if ((int) $record->type === 2) { + return self::meltedGoldSellTitle(); + } + + return $record->type_str; + } + + private function applyProductOrderDisplayFields($record): void + { + if (empty($record->order_id) || empty($record->order) || empty($record->product_id)) { + return; + } + + $order = $record->order; + $totalPrice = (int) ($order->total_price ?? $order->payment_amount ?? 0); + if ($totalPrice <= 0) { + return; + } + + if ((int) ($record->cash ?? 0) === 0) { + $direction = (int) ($order->direction ?? 0); + $record->cash = $direction === 1 ? -$totalPrice : $totalPrice; + } + + if ($this->isProductWalletTransaction($record)) { + $mainBalanceCash = $this->resolveMainWalletBalanceCashForOrder($record); + if ($mainBalanceCash !== null) { + $record->balance_cash = $mainBalanceCash; + } + } + + if (!empty($record->wallet?->product)) { + $record->unit = $record->wallet->product->unit ?: 'عدد'; + } + } + + private function isProductWalletTransaction($record): bool + { + return !empty($record->wallet?->product); + } + + private function resolveMainWalletBalanceCashForOrder($record): ?int + { + $customerId = $record->customer_id ?? auth('customer')->id(); + $mainWalletIds = Wallet::where('owner', $customerId) + ->whereNull('product_id') + ->whereNull('fund_id') + ->pluck('id'); + + if ($mainWalletIds->isEmpty()) { + return null; + } + + $mainTx = Transaction::where('order_id', $record->order_id) + ->whereIn('wallet', $mainWalletIds) + ->whereNotNull('balance_cash') + ->orderBy('id') + ->first(); + + if ($mainTx) { + return (int) $mainTx->balance_cash; + } + + $previousTx = Transaction::whereIn('wallet', $mainWalletIds) + ->where('id', '<', $record->id) + ->whereNotNull('balance_cash') + ->orderByDesc('id') + ->first(); + + return $previousTx ? (int) $previousTx->balance_cash : null; + } + } diff --git a/app/Http/Controllers/Single/SingleOrderController.php b/app/Http/Controllers/Single/SingleOrderController.php index 4653845..d662af4 100644 --- a/app/Http/Controllers/Single/SingleOrderController.php +++ b/app/Http/Controllers/Single/SingleOrderController.php @@ -209,6 +209,7 @@ class SingleOrderController extends Controller 'active' => true, 'order_id' => $order->id, 'start_at' => now(), + 'title' => self::meltedGoldBuyTitle(), ], 1, true, false); $response['1'] = 2; //send to provider @@ -253,6 +254,7 @@ class SingleOrderController extends Controller 'active' => true, 'order_id' => $order->id, 'start_at' => now(), + 'title' => self::productBuyTitle($data['product']['title'] ?? ''), ], 1, true, false); @@ -285,7 +287,7 @@ class SingleOrderController extends Controller 'expire_at' => now(), 'active' => true, 'order_id' => $order->id, - 'title' => $this->goldWithdrawTitle() + 'title' => self::productBuyTitle($data['product']['title'] ?? '') ], 12, false, true); $wallet_interface_product = new WalletInterface(auth('customer')->id(), auth('customer')->user()->type, null, $data["product_id"]); $wallet_interface_product->wallet->gold = intval($wallet_interface_product->wallet->gold); @@ -297,6 +299,7 @@ class SingleOrderController extends Controller 'active' => true, 'order_id' => $order->id, 'start_at' => now(), + 'title' => self::productBuyTitle($data['product']['title'] ?? ''), ], 1, true, false); } @@ -319,7 +322,8 @@ class SingleOrderController extends Controller "cash" => $data['total_price'], 'expire_at' => now(), 'active' => true, - 'order_id' => $order->id + 'order_id' => $order->id, + 'title' => self::meltedGoldSellTitle(), ], 2, false, true); //send to Goldir @@ -355,6 +359,7 @@ class SingleOrderController extends Controller 'active' => true, 'order_id' => $order->id, 'start_at' => now(), + 'title' => self::productSellTitle($data['product']['title'] ?? ''), ], 1, false, false); $data['transaction'][] = new TransactionInterface($wallet_interface, $_inp = [ "number" => $data['number'], @@ -393,7 +398,7 @@ class SingleOrderController extends Controller 'expire_at' => now(), 'active' => true, 'order_id' => $order->id, - 'title' => $this->goldDepositTitle() + 'title' => self::productSellTitle($data['product']['title'] ?? '') ], 12, true, false); $wallet_interface_product->wallet->gold = intval($wallet_interface_product->wallet->gold); $wallet_interface_product->wallet->save(); @@ -404,6 +409,7 @@ class SingleOrderController extends Controller 'active' => true, 'order_id' => $order->id, 'start_at' => now(), + 'title' => self::productSellTitle($data['product']['title'] ?? ''), ], 1, false, false); } @@ -477,20 +483,20 @@ class SingleOrderController extends Controller : 0 ); $totalPrice = $data['total_price'] ?? ($data['payment_amount'] ?? 0); - $productTitle = $data['product']['title'] ?? self::metalTypeLabel(); + $subjectTitle = $this->transactionSubjectTitle($data); - $message = "کاربر {$customer->name} با شماره موبایل {$customer->mobile} اقدام به $transactionType {$productTitle} به مقدار " . + $message = "کاربر {$customer->name} با شماره موبایل {$customer->mobile} اقدام به $transactionType {$subjectTitle} به مقدار " . "{$amount} گرم به مبلغ " . number_format($totalPrice) . " ریال کرد. با تشکر، $companyName"; User::where('send_sms', 1)->get()->each(function ($admin) use ($message, $data, $transactionType, $companyName) { $this->send($admin->mobile, $message); }); $wallet = Wallet::where('owner', $data['customer_id'])->whereNull('fund_id')->first(); - $metalLabel = self::metalTypeLabel(); + $balanceLabel = self::metalTypeLabel(); // $pricePerGram = $totalPrice / $amount; - $customerMessage = "$companyName\n$transactionType {$metalLabel}\nگرم: {$amount}\n" . + $customerMessage = "$companyName\n$transactionType {$subjectTitle}\nگرم: {$amount}\n" . "مبلغ کل: " . number_format($totalPrice) . "\n\n" . - "موجودی {$metalLabel}: {$wallet->gold}\n" . + "موجودی {$balanceLabel}: {$wallet->gold}\n" . "مانده ریالی: " . number_format($wallet->cash) . "\n" . $this->Config('app_url'); @@ -672,14 +678,18 @@ class SingleOrderController extends Controller ->count() < (int)$count; } - private function goldDepositTitle(): string + private function isProductOrder(array $data): bool { - return 'موجودی ' . self::metalTypeLabel(); + return !empty($data['product_id']) && !empty($data['product']['title']); } - private function goldWithdrawTitle(): string + private function transactionSubjectTitle(array $data): string { - return 'برداشت ' . self::metalTypeLabel(); + if ($this->isProductOrder($data)) { + return $data['product']['title']; + } + + return self::meltedGoldLabel(); } private function insufficientGoldBalanceMessage(array $data): string diff --git a/packages/rooyesh/wallet/src/interfaces/TransactionInterface.php b/packages/rooyesh/wallet/src/interfaces/TransactionInterface.php index 266ad27..b8ae934 100644 --- a/packages/rooyesh/wallet/src/interfaces/TransactionInterface.php +++ b/packages/rooyesh/wallet/src/interfaces/TransactionInterface.php @@ -72,16 +72,16 @@ class TransactionInterface if (isset($_inp['gold'])){ $_inp['gold'] = abs($_inp['gold']) * ($deposit_gold ? 1 : -1); $wallet->gold += $_inp['gold']; - $_inp['balance_gold'] = $wallet->gold; } if (isset($_inp['cash'])){ $_inp['cash'] = abs($_inp['cash']) * ($deposit_cash ? 1 : -1); $wallet->cash += $_inp['cash']; - $_inp['balance_cash'] = $wallet->cash; } if($gold_block != 0){ $wallet->gold_block += $gold_block; } + $_inp['balance_gold'] = $wallet->gold; + $_inp['balance_cash'] = $wallet->cash; $_inp['wallet'] = $wallet->id; $_inp['type'] = $_type; // $_inp['transaction_type'] = $_type;