diff --git a/app/Http/Controllers/Admin/WalletController.php b/app/Http/Controllers/Admin/WalletController.php index c0d28db..e2c9718 100644 --- a/app/Http/Controllers/Admin/WalletController.php +++ b/app/Http/Controllers/Admin/WalletController.php @@ -395,10 +395,21 @@ class WalletController extends Controller ])->export($records); if (isset($records['rows'])) { - foreach ($records['rows'] as &$row) { + $records['rows'] = collect($records['rows'])->map(function ($row) use ($balanceReport, $catalogMetalIds) { $balanceReport->enrichTransactionTableRow($row, $catalogMetalIds); - } - unset($row); + + if ($row instanceof Transaction) { + $array = $row->toArray(); + $rawTypeStr = $row->getAttributes()['type_str'] ?? null; + if (is_string($rawTypeStr) && !is_numeric(trim($rawTypeStr))) { + $array['type_str'] = $rawTypeStr; + } + + return $array; + } + + return is_array($row) ? $row : (array) $row; + })->values()->all(); } $records['catalogMetals'] = $balanceReport->catalogMetalsMeta(); diff --git a/app/Services/BalanceReportService.php b/app/Services/BalanceReportService.php index 7495338..116acb5 100644 --- a/app/Services/BalanceReportService.php +++ b/app/Services/BalanceReportService.php @@ -285,58 +285,20 @@ class BalanceReportService return null; } - $currentLabel = trim((string) ($this->lineValue($transaction, 'type_str') ?? '')); - $prefix = $this->resolveTransactionActionPrefix($transaction); $productLabel = $this->resolveTransactionProductLabel($transaction); - - if ($prefix !== null && $productLabel !== null) { - return trim($prefix . ' ' . $productLabel); - } - - if ($prefix !== null) { - $metalId ??= $this->resolveTransactionMetalId($transaction); - - return trim($prefix . ' ' . $this->metalLabel($metalId)); - } - - if ($currentLabel === 'تعریف نشده' || $currentLabel === '') { - return $this->resolveFallbackMetalTransactionLabel($transaction, $metalId); - } - - if ($this->shouldReplaceGenericTransactionLabel($currentLabel) && $productLabel !== null) { - $fallbackPrefix = $this->resolveTransactionActionPrefix($transaction) - ?? $this->inferActionPrefixFromLabel($currentLabel) - ?? $this->inferActionPrefixFromGold($transaction); - - if ($fallbackPrefix !== null) { - return trim($fallbackPrefix . ' ' . $productLabel); - } - } - - return null; - } - - private function resolveFallbackMetalTransactionLabel(mixed $transaction, ?int $metalId = null): ?string - { - $gold = (float) ($this->lineValue($transaction, 'gold') ?? 0); - if (abs($gold) < 0.0000001) { + if ($productLabel === null) { return null; } $prefix = $this->resolveTransactionActionPrefix($transaction) + ?? $this->inferActionPrefixFromLabel(trim((string) ($this->lineValue($transaction, 'type_str') ?? ''))) ?? $this->inferActionPrefixFromGold($transaction); + if ($prefix === null) { return null; } - $productLabel = $this->resolveTransactionProductLabel($transaction); - if ($productLabel !== null) { - return trim($prefix . ' ' . $productLabel); - } - - $metalId ??= $this->resolveTransactionMetalId($transaction); - - return trim($prefix . ' ' . $this->metalLabel($metalId)); + return trim($prefix . ' ' . $productLabel); } private function resolveTransactionType(mixed $transaction): int @@ -346,6 +308,16 @@ class BalanceReportService return (int) $type; } + if (is_object($transaction) && method_exists($transaction, 'getAttributes')) { + $attrs = $transaction->getAttributes(); + if (isset($attrs['type']) && is_numeric($attrs['type'])) { + return (int) $attrs['type']; + } + if (isset($attrs['type_str']) && is_numeric($attrs['type_str'])) { + return (int) $attrs['type_str']; + } + } + return 0; } @@ -397,7 +369,7 @@ class BalanceReportService private function shouldReplaceGenericTransactionLabel(string $label): bool { - if ($label === 'تعریف نشده') { + if ($label === 'تعریف نشده' || $label === '') { return true; } @@ -431,9 +403,33 @@ class BalanceReportService return $labels !== '' ? $labels : null; } + return $this->parseProductLabelFromNote($transaction); + } + + private function parseProductLabelFromNote(mixed $transaction): ?string + { + $note = trim((string) ($this->lineValue($transaction, 'note') ?? '')); + if ($note === '') { + return null; + } + + if (preg_match('/(?:برداشت|واریز)\s+محصول\s+(.+?)\s+شماره\s+سند/u', $note, $matches)) { + return trim($matches[1]); + } + return null; } + private function resolveTransactionTitleLabel(mixed $transaction): ?string + { + $title = trim((string) ($this->lineValue($transaction, 'title') ?? '')); + if ($title === '' || $title === 'تعریف نشده') { + return null; + } + + return $title; + } + public function transactionGoldGrams(mixed $transaction): float { $gold = (float) ($this->lineValue($transaction, 'gold') ?? 0); @@ -490,11 +486,12 @@ class BalanceReportService $metalMap = $this->buildTransactionMetalDisplayMap($row, $catalogMetalIds); $metalId = $this->resolveTransactionMetalId($row); $metalLabel = $this->metalLabel($metalId); - $displayType = $this->resolveTransactionDisplayTypeStr($row, $metalId); $currentTypeStr = trim((string) ($this->lineValue($row, 'type_str') ?? '')); + $displayType = $this->resolveTransactionTitleLabel($row) + ?? $this->resolveTransactionDisplayTypeStr($row, $metalId); - if ($displayType === null && ($currentTypeStr === 'تعریف نشده' || $currentTypeStr === '')) { - $displayType = $this->resolveFallbackMetalTransactionLabel($row, $metalId); + if ($displayType === null && $this->shouldReplaceGenericTransactionLabel($currentTypeStr)) { + $displayType = $this->resolveTransactionDisplayTypeStr($row, $metalId); } if (is_array($row)) { @@ -516,7 +513,7 @@ class BalanceReportService $row->transaction_metal_id = $metalId; $row->transaction_metal_label = $metalLabel; if ($displayType !== null) { - $row->type_str = $displayType; + $row->setAttribute('type_str', $displayType); } foreach ($catalogMetalIds as $mid) { $row->{'metal_gold_' . $mid} = $metalMap[(string) $mid] ?? 0.0; diff --git a/packages/rooyesh/wallet/src/models/Transaction.php b/packages/rooyesh/wallet/src/models/Transaction.php index 9843a8f..8280b68 100644 --- a/packages/rooyesh/wallet/src/models/Transaction.php +++ b/packages/rooyesh/wallet/src/models/Transaction.php @@ -5,6 +5,7 @@ namespace Rooyesh\Wallet\models; use App\Models\Selector; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Arr; class Transaction extends Model @@ -27,6 +28,23 @@ class Transaction extends Model 9 => 'سود زیر مجموعه', 10 => 'برداشت طلایی', ]; + + /** + * type_str گاهی از API enrich می‌شود (مثلاً «واریز کاتد مس»). + * اگر مقدار از قبل متن باشد، accessor نباید آن را به «تعریف نشده» برگرداند. + */ + public function getTypeStrAttribute($value) + { + if ($value === null) { + return null; + } + + if (is_string($value) && !is_numeric(trim($value))) { + return $value; + } + + return Arr::get(self::$TYPES, (int) $value, 'تعریف نشده'); + } public function customer() { return $this->belongsTo('App\Models\Customer')->select(['id','name']);