Show Tahesab balance docs on conflict and label adjust txs for customers.

Preview and conflict paths now include recent wallet and Tahesab documents, and applied adjustments use a visible type/title/note so customers can see the sync document.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-30 21:18:24 +03:30
co-authored by Cursor
parent c27cfabd22
commit f1fb3c1e74
2 changed files with 91 additions and 4 deletions
+90 -4
View File
@@ -3,10 +3,13 @@
namespace App\Services; namespace App\Services;
use App\Models\Customer; use App\Models\Customer;
use App\Models\Tahesab;
use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Rooyesh\Wallet\interfaces\TransactionInterface; use Rooyesh\Wallet\interfaces\TransactionInterface;
use Rooyesh\Wallet\interfaces\WalletInterface; use Rooyesh\Wallet\interfaces\WalletInterface;
use Rooyesh\Wallet\models\Transaction;
use Rooyesh\Wallet\models\Wallet;
/** /**
* ماندهٔ طلا/ریال ته‌حساب → کیف اپ. * ماندهٔ طلا/ریال ته‌حساب → کیف اپ.
@@ -130,7 +133,7 @@ class TahesabInboundWalletService
|| ($askIfConflict && $appHasBalance) || ($askIfConflict && $appHasBalance)
); );
if ($needsAsk) { if ($needsAsk) {
return array_merge($comparison, [ return array_merge($comparison, $this->listPreviewDocuments($customer), [
'applied' => false, 'applied' => false,
'needs_decision' => true, 'needs_decision' => true,
'message' => 'موجودی اپ با ته‌حساب فرق دارد — تصمیم ادمین لازم است', 'message' => 'موجودی اپ با ته‌حساب فرق دارد — تصمیم ادمین لازم است',
@@ -143,8 +146,8 @@ class TahesabInboundWalletService
$walletInterface = new WalletInterface((int) $customer->id, $ownerType); $walletInterface = new WalletInterface((int) $customer->id, $ownerType);
$input = [ $input = [
'title' => 'تطبیق ماندهٔ ته‌حساب', 'title' => 'تعدیل حسابداری ته‌حساب',
'note' => 'tahesab-mande:'.$code, 'note' => $this->customerVisibleAdjustNote($code, $goldDiff, $rialDiff, $goldSame, $rialSame),
'expire_at' => now(), 'expire_at' => now(),
'active' => true, 'active' => true,
]; ];
@@ -218,7 +221,7 @@ class TahesabInboundWalletService
$compared = $this->compareWithWallet($customer, $mande); $compared = $this->compareWithWallet($customer, $mande);
$same = $compared['gold_same'] && $compared['rial_same']; $same = $compared['gold_same'] && $compared['rial_same'];
return array_merge($compared['comparison'], [ return array_merge($compared['comparison'], $this->listPreviewDocuments($customer), [
'applied' => false, 'applied' => false,
'ok' => true, 'ok' => true,
'needs_decision' => ! $same, 'needs_decision' => ! $same,
@@ -228,6 +231,89 @@ class TahesabInboundWalletService
]); ]);
} }
/**
* آخرین سندهای کیف اپ و ته‌حساب — برای تصمیم ادمین روی اختلاف مانده.
*
* @return array{wallet_docs: list<array<string, mixed>>, tahesab_docs: list<array<string, mixed>>}
*/
private function listPreviewDocuments(Customer $customer): array
{
$ownerType = (int) ($customer->type ?? 2);
$wallet = Wallet::query()
->where('owner', (int) $customer->id)
->where('owner_type', $ownerType)
->whereNull('fund_id')
->whereNull('product_id')
->first();
$walletDocs = [];
if ($wallet) {
$txs = Transaction::query()
->where('wallet', $wallet->id)
->orderByDesc('id')
->limit(8)
->get(['id', 'title', 'type', 'gold', 'cash', 'created_at']);
foreach ($txs as $tx) {
$typeKey = (int) $tx->getRawOriginal('type');
$typeLabel = Transaction::$TYPES[$typeKey] ?? '';
$walletDocs[] = [
'id' => (int) $tx->id,
'title' => (string) ($tx->title ?: $typeLabel ?: 'تراکنش کیف'),
'gold' => (float) ($tx->gold ?? 0),
'cash' => (float) ($tx->cash ?? 0),
'created_at' => optional($tx->created_at)->toDateTimeString(),
];
}
}
$tahesabDocs = [];
$rows = Tahesab::query()
->where('customer_id', (int) $customer->id)
->orderByDesc('id')
->limit(8)
->get(['id', 'desc', 'amount', 'type', 'factor_number', 'date', 'created_at']);
foreach ($rows as $row) {
$title = trim((string) ($row->desc ?? ''));
if ($title === '' && $row->factor_number) {
$title = 'فاکتور '.$row->factor_number;
}
$tahesabDocs[] = [
'id' => (int) $row->id,
'title' => $title !== '' ? $title : 'سند ته‌حساب',
'amount' => (float) ($row->amount ?? 0),
'type' => (string) ($row->type ?? ''),
'date' => (string) ($row->date ?? ''),
'created_at' => optional($row->created_at)->toDateTimeString(),
];
}
return [
'wallet_docs' => $walletDocs,
'tahesab_docs' => $tahesabDocs,
];
}
private function customerVisibleAdjustNote(
int $code,
float $goldDiff,
float $rialDiff,
bool $goldSame,
bool $rialSame
): string {
$parts = ['تعدیل مانده با ته‌حساب، کد '.$code];
if (! $goldSame) {
$sign = $goldDiff > 0 ? '+' : '';
$gold = rtrim(rtrim(sprintf('%.3f', $goldDiff), '0'), '.');
$parts[] = 'طلا '.$sign.$gold;
}
if (! $rialSame) {
$sign = $rialDiff > 0 ? '+' : '';
$parts[] = 'ریال '.$sign.(int) round($rialDiff);
}
return implode('، ', $parts);
}
/** @param array<string, mixed> $row */ /** @param array<string, mixed> $row */
public function mandeFromAccountingRow(array $row): ?array public function mandeFromAccountingRow(array $row): ?array
{ {
@@ -29,6 +29,7 @@ class Transaction extends Model
10 => 'برداشت طلایی', 10 => 'برداشت طلایی',
12 => 'برداشت وجه نقد', 12 => 'برداشت وجه نقد',
22 => 'تعدیل حسابداری پرگار', 22 => 'تعدیل حسابداری پرگار',
23 => 'تعدیل حسابداری ته‌حساب',
]; ];
/** /**