added some feature for accounting and enhance performance for dashboard
This commit is contained in:
@@ -19,6 +19,8 @@ use Rooyesh\Wallet\interfaces\WalletInterface;
|
||||
* overwrite=true → اختلاف را اعمال کن
|
||||
* keep=true → موجودی اپ را دست نزن
|
||||
* ask_if_conflict → اگر اپ مانده دارد و با تهحساب فرق دارد، بدون نوشتن برگردان
|
||||
* always_ask → هر اختلافی (حتی کیف خالی) بدون نوشتن برای تأیید ادمین برمیگردد
|
||||
* جمع دو مانده هرگز انجام نمیشود تا موجودی دو برابر نشود.
|
||||
*/
|
||||
class TahesabInboundWalletService
|
||||
{
|
||||
@@ -67,7 +69,7 @@ class TahesabInboundWalletService
|
||||
|
||||
/**
|
||||
* @param array{gold?: float, cash?: float}|null $mande
|
||||
* @param array{overwrite?: bool, keep?: bool, ask_if_conflict?: bool} $options
|
||||
* @param array{overwrite?: bool, keep?: bool, ask_if_conflict?: bool, always_ask?: bool} $options
|
||||
* @return array{
|
||||
* applied: bool,
|
||||
* needs_decision?: bool,
|
||||
@@ -86,6 +88,7 @@ class TahesabInboundWalletService
|
||||
$overwrite = (bool) ($options['overwrite'] ?? false);
|
||||
$keep = (bool) ($options['keep'] ?? false);
|
||||
$askIfConflict = (bool) ($options['ask_if_conflict'] ?? false);
|
||||
$alwaysAsk = (bool) ($options['always_ask'] ?? false);
|
||||
|
||||
$code = (int) ($customer->moshtari_code ?? 0);
|
||||
if ($code <= 0) {
|
||||
@@ -101,31 +104,11 @@ class TahesabInboundWalletService
|
||||
return ['applied' => false, 'message' => 'مانده از تهحساب دریافت نشد'];
|
||||
}
|
||||
|
||||
$goldInv = (float) ($mande['gold'] ?? 0);
|
||||
$rialInv = (float) ($mande['cash'] ?? 0);
|
||||
|
||||
$ownerType = (int) ($customer->type ?? 2);
|
||||
$walletInterface = new WalletInterface((int) $customer->id, $ownerType);
|
||||
$wallet = $walletInterface->wallet;
|
||||
|
||||
$mainGold = $this->walletBalance
|
||||
->accountingVisibleMainWalletGold((int) $customer->id, $ownerType);
|
||||
$mainCash = (float) ($wallet->cash ?? 0);
|
||||
|
||||
$goldDiff = $goldInv - $mainGold;
|
||||
$rialDiff = $rialInv - $mainCash;
|
||||
|
||||
$goldSame = abs($goldDiff) < self::EPSILON_GOLD;
|
||||
$rialSame = abs($rialDiff) < self::EPSILON_CASH;
|
||||
|
||||
$comparison = [
|
||||
'app_gold' => $mainGold,
|
||||
'app_cash' => $mainCash,
|
||||
'tahesab_gold' => $goldInv,
|
||||
'tahesab_cash' => $rialInv,
|
||||
'gold_delta' => $goldDiff,
|
||||
'rial_delta' => $rialDiff,
|
||||
];
|
||||
$compared = $this->compareWithWallet($customer, $mande);
|
||||
$comparison = $compared['comparison'];
|
||||
$goldSame = $compared['gold_same'];
|
||||
$rialSame = $compared['rial_same'];
|
||||
$appHasBalance = $compared['app_has_balance'];
|
||||
|
||||
if ($goldSame && $rialSame) {
|
||||
return array_merge($comparison, [
|
||||
@@ -142,11 +125,11 @@ class TahesabInboundWalletService
|
||||
]);
|
||||
}
|
||||
|
||||
$appHasBalance = abs($mainGold) >= self::EPSILON_GOLD
|
||||
|| abs($mainCash) >= self::EPSILON_CASH;
|
||||
|
||||
// اگر اپ مانده دارد و با تهحساب فرق دارد و ادمین هنوز تصمیم نگرفته
|
||||
if ($askIfConflict && ! $overwrite && $appHasBalance) {
|
||||
$needsAsk = ! $overwrite && (
|
||||
($alwaysAsk)
|
||||
|| ($askIfConflict && $appHasBalance)
|
||||
);
|
||||
if ($needsAsk) {
|
||||
return array_merge($comparison, [
|
||||
'applied' => false,
|
||||
'needs_decision' => true,
|
||||
@@ -154,6 +137,11 @@ class TahesabInboundWalletService
|
||||
]);
|
||||
}
|
||||
|
||||
$goldDiff = (float) $comparison['gold_delta'];
|
||||
$rialDiff = (float) $comparison['rial_delta'];
|
||||
$ownerType = (int) ($customer->type ?? 2);
|
||||
$walletInterface = new WalletInterface((int) $customer->id, $ownerType);
|
||||
|
||||
$input = [
|
||||
'title' => 'تطبیق ماندهٔ تهحساب',
|
||||
'note' => 'tahesab-mande:'.$code,
|
||||
@@ -186,8 +174,8 @@ class TahesabInboundWalletService
|
||||
Log::info('Tahesab mande applied to wallet', [
|
||||
'customer_id' => (int) $customer->id,
|
||||
'moshtari_code' => $code,
|
||||
'gold_target' => $goldInv,
|
||||
'cash_target' => $rialInv,
|
||||
'gold_target' => $comparison['tahesab_gold'],
|
||||
'cash_target' => $comparison['tahesab_cash'],
|
||||
'gold_delta' => $goldDiff,
|
||||
'rial_delta' => $rialDiff,
|
||||
'overwrite' => $overwrite,
|
||||
@@ -199,6 +187,94 @@ class TahesabInboundWalletService
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* مقایسه بدون نوشتن — برای تأیید ادمین قبل از ست کردن کد.
|
||||
*
|
||||
* @return array{
|
||||
* applied: bool,
|
||||
* needs_decision?: bool,
|
||||
* ok?: bool,
|
||||
* app_gold?: float,
|
||||
* app_cash?: float,
|
||||
* tahesab_gold?: float,
|
||||
* tahesab_cash?: float,
|
||||
* gold_delta?: float,
|
||||
* rial_delta?: float,
|
||||
* message: string
|
||||
* }
|
||||
*/
|
||||
public function previewForCustomer(Customer $customer, int $code): array
|
||||
{
|
||||
if ($code <= 0) {
|
||||
return ['applied' => false, 'ok' => false, 'message' => 'کد تهحساب نامعتبر است'];
|
||||
}
|
||||
|
||||
$all = $this->fetchMandeByCodes([$code]);
|
||||
$mande = $all[(string) $code] ?? null;
|
||||
if ($mande === null) {
|
||||
return ['applied' => false, 'ok' => false, 'message' => 'مانده از تهحساب دریافت نشد'];
|
||||
}
|
||||
|
||||
$compared = $this->compareWithWallet($customer, $mande);
|
||||
$same = $compared['gold_same'] && $compared['rial_same'];
|
||||
|
||||
return array_merge($compared['comparison'], [
|
||||
'applied' => false,
|
||||
'ok' => true,
|
||||
'needs_decision' => ! $same,
|
||||
'message' => $same
|
||||
? 'مانده با تهحساب یکسان است'
|
||||
: 'موجودی اپ با تهحساب فرق دارد — تصمیم ادمین لازم است',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @param array<string, mixed> $row */
|
||||
public function mandeFromAccountingRow(array $row): ?array
|
||||
{
|
||||
return $this->parseMandeRow($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{gold?: float, cash?: float} $mande
|
||||
* @return array{
|
||||
* comparison: array{app_gold: float, app_cash: float, tahesab_gold: float, tahesab_cash: float, gold_delta: float, rial_delta: float},
|
||||
* gold_same: bool,
|
||||
* rial_same: bool,
|
||||
* app_has_balance: bool
|
||||
* }
|
||||
*/
|
||||
private function compareWithWallet(Customer $customer, array $mande): array
|
||||
{
|
||||
$goldInv = (float) ($mande['gold'] ?? 0);
|
||||
$rialInv = (float) ($mande['cash'] ?? 0);
|
||||
|
||||
$ownerType = (int) ($customer->type ?? 2);
|
||||
$walletInterface = new WalletInterface((int) $customer->id, $ownerType);
|
||||
$wallet = $walletInterface->wallet;
|
||||
|
||||
$mainGold = $this->walletBalance
|
||||
->accountingVisibleMainWalletGold((int) $customer->id, $ownerType);
|
||||
$mainCash = (float) ($wallet->cash ?? 0);
|
||||
|
||||
$goldDiff = $goldInv - $mainGold;
|
||||
$rialDiff = $rialInv - $mainCash;
|
||||
|
||||
return [
|
||||
'comparison' => [
|
||||
'app_gold' => $mainGold,
|
||||
'app_cash' => $mainCash,
|
||||
'tahesab_gold' => $goldInv,
|
||||
'tahesab_cash' => $rialInv,
|
||||
'gold_delta' => $goldDiff,
|
||||
'rial_delta' => $rialDiff,
|
||||
],
|
||||
'gold_same' => abs($goldDiff) < self::EPSILON_GOLD,
|
||||
'rial_same' => abs($rialDiff) < self::EPSILON_CASH,
|
||||
'app_has_balance' => abs($mainGold) >= self::EPSILON_GOLD
|
||||
|| abs($mainCash) >= self::EPSILON_CASH,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* بعد از import: اگر کیف خالی باشد مانده را بنشان؛ اگر مانده دارد صبر کن تا ادمین تصمیم بگیرد.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user