fix pargar bugs
This commit is contained in:
@@ -5,6 +5,8 @@ namespace App\Http\Controllers\Admin;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Customer;
|
||||
use App\Models\PargarSyncLog;
|
||||
use App\Services\ConfigService;
|
||||
use App\Services\PargarInboundWalletService;
|
||||
use App\Services\PargarSyncService;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
@@ -253,6 +255,36 @@ class PargarController extends Controller
|
||||
return response()->json($result, ($result['ok'] ?? false) ? 200 : 422);
|
||||
}
|
||||
|
||||
public function syncCustomerWallet($customerId)
|
||||
{
|
||||
if (! app(ConfigService::class)->isPargarAccounting()) {
|
||||
return response()->json([
|
||||
'ok' => false,
|
||||
'message' => 'حسابداری پرگار فعال نیست',
|
||||
], 422);
|
||||
}
|
||||
|
||||
$customer = Customer::findOrFail($customerId);
|
||||
if (trim((string) ($customer->pargar_account_id ?? '')) === '') {
|
||||
return response()->json([
|
||||
'ok' => false,
|
||||
'message' => 'این مشتری کد حساب پرگار ندارد',
|
||||
], 422);
|
||||
}
|
||||
|
||||
$result = app(PargarInboundWalletService::class)->syncWalletFromPargar($customer);
|
||||
$appliedDocs = (int) ($result['documents']['applied'] ?? 0);
|
||||
$appliedMande = (bool) ($result['mande']['applied'] ?? false);
|
||||
|
||||
return response()->json([
|
||||
'ok' => $appliedDocs > 0 || $appliedMande,
|
||||
'message' => $appliedDocs > 0 || $appliedMande
|
||||
? 'مانده از پرگار روی کیف اعمال شد'
|
||||
: ($result['mande']['message'] ?? 'سند قابلاعمالی یافت نشد'),
|
||||
'result' => $result,
|
||||
], $appliedDocs > 0 || $appliedMande ? 200 : 422);
|
||||
}
|
||||
|
||||
private function uniqueReferralId(): string
|
||||
{
|
||||
do {
|
||||
|
||||
@@ -122,17 +122,161 @@ class PargarInboundWalletService
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* اسناد ذخیرهشدهٔ قبلی (قبل از deploy) را از لاگ دوباره اعمال میکند.
|
||||
*
|
||||
* @return array{applied: int, skipped: int, errors: list<string>, logs: list<int>}
|
||||
*/
|
||||
public function replayStoredDocuments(Customer $customer): array
|
||||
{
|
||||
$accountId = trim((string) ($customer->pargar_account_id ?? ''));
|
||||
|
||||
$logs = PargarSyncLog::query()
|
||||
->where('type', PargarSyncService::TYPE_DOCUMENT)
|
||||
->where(function ($q) use ($customer, $accountId) {
|
||||
$q->where('customer_id', $customer->id);
|
||||
if ($accountId !== '') {
|
||||
$q->orWhere('pargar_ref', $accountId);
|
||||
}
|
||||
})
|
||||
->orderBy('id')
|
||||
->get();
|
||||
|
||||
$total = [
|
||||
'applied' => 0,
|
||||
'skipped' => 0,
|
||||
'errors' => [],
|
||||
'logs' => [],
|
||||
];
|
||||
|
||||
foreach ($logs as $log) {
|
||||
$data = json_decode((string) $log->data, true);
|
||||
if (! is_array($data) || empty($data['transactions']) || ! is_array($data['transactions'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$batch = $this->applyDocuments($customer, $data);
|
||||
$total['applied'] += $batch['applied'];
|
||||
$total['skipped'] += $batch['skipped'];
|
||||
$total['errors'] = array_merge($total['errors'], $batch['errors']);
|
||||
$total['logs'] = array_merge($total['logs'], $batch['logs']);
|
||||
}
|
||||
|
||||
return $total;
|
||||
}
|
||||
|
||||
/**
|
||||
* آخرین ماندهٔ پرگار را (در صورت اختلاف) یکبار روی کیف اعمال میکند — فقط با درخواست ادمین.
|
||||
*
|
||||
* @return array{applied: bool, gold_delta?: float, rial_delta?: float, message: string}
|
||||
*/
|
||||
public function applyLatestMandeDifference(Customer $customer): array
|
||||
{
|
||||
$log = PargarSyncLog::query()
|
||||
->where('customer_id', $customer->id)
|
||||
->where('type', PargarSyncService::TYPE_MANDE)
|
||||
->orderByDesc('id')
|
||||
->first();
|
||||
|
||||
if ($log === null) {
|
||||
return ['applied' => false, 'message' => 'لاگ ماندهٔ پرگار برای این مشتری یافت نشد'];
|
||||
}
|
||||
|
||||
$data = json_decode((string) $log->data, true) ?: [];
|
||||
if (! empty($data['wallet_applied_from_mande'])) {
|
||||
return ['applied' => false, 'message' => 'ماندهٔ پرگار قبلاً روی کیف اعمال شده است'];
|
||||
}
|
||||
|
||||
$goldInv = $this->parseNumber($data['GoldInv'] ?? 0);
|
||||
$rialInv = $this->parseNumber($data['RialInv'] ?? 0);
|
||||
|
||||
$ownerType = (int) ($customer->type ?? 2);
|
||||
$walletInterface = new WalletInterface((int) $customer->id, $ownerType);
|
||||
$wallet = $walletInterface->wallet;
|
||||
|
||||
$goldDiff = $goldInv - (float) ($wallet->gold ?? 0);
|
||||
$rialDiff = $rialInv - (float) ($wallet->cash ?? 0);
|
||||
|
||||
if (abs($goldDiff) < 0.01 && abs($rialDiff) < 1) {
|
||||
$data['wallet_applied_from_mande'] = true;
|
||||
$log->data = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||
$log->save();
|
||||
|
||||
return ['applied' => false, 'message' => 'اختلافی بین ماندهٔ پرگار و کیف اپ نیست'];
|
||||
}
|
||||
|
||||
$input = [
|
||||
'title' => 'تطبیق ماندهٔ پرگار',
|
||||
'note' => 'mande-log:' . $log->id,
|
||||
'expire_at' => now(),
|
||||
'active' => true,
|
||||
];
|
||||
if (abs($goldDiff) >= 0.01) {
|
||||
$input['gold'] = abs($goldDiff);
|
||||
}
|
||||
if (abs($rialDiff) >= 1) {
|
||||
$input['cash'] = abs($rialDiff);
|
||||
}
|
||||
|
||||
new TransactionInterface(
|
||||
$walletInterface,
|
||||
$input,
|
||||
self::TX_TYPE_PARGAR,
|
||||
$goldDiff > 0,
|
||||
$rialDiff > 0
|
||||
);
|
||||
|
||||
$data['wallet_applied_from_mande'] = true;
|
||||
$data['applied_gold_delta'] = $goldDiff;
|
||||
$data['applied_rial_delta'] = $rialDiff;
|
||||
$log->data = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||
$log->desc = 'اعمال ماندهٔ پرگار روی کیف اپ';
|
||||
$log->save();
|
||||
|
||||
$this->walletBroadcast->broadcastForCustomer((int) $customer->id, $ownerType);
|
||||
|
||||
return [
|
||||
'applied' => true,
|
||||
'gold_delta' => $goldDiff,
|
||||
'rial_delta' => $rialDiff,
|
||||
'message' => 'ماندهٔ پرگار روی کیف اعمال شد',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{
|
||||
* documents: array{applied: int, skipped: int, errors: list<string>, logs: list<int>},
|
||||
* mande: array{applied: bool, gold_delta?: float, rial_delta?: float, message: string}
|
||||
* }
|
||||
*/
|
||||
public function syncWalletFromPargar(Customer $customer): array
|
||||
{
|
||||
return [
|
||||
'documents' => $this->replayStoredDocuments($customer),
|
||||
'mande' => $this->applyLatestMandeDifference($customer),
|
||||
];
|
||||
}
|
||||
|
||||
public function isDocumentApplied(string $docId): bool
|
||||
{
|
||||
if ($docId === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return PargarSyncLog::query()
|
||||
$logs = PargarSyncLog::query()
|
||||
->where('type', PargarSyncService::TYPE_DOCUMENT)
|
||||
->where('pargar_ref', $docId)
|
||||
->where('sync_status', PargarSyncService::STATUS_SUCCESS)
|
||||
->exists();
|
||||
->get(['data']);
|
||||
|
||||
foreach ($logs as $log) {
|
||||
$data = json_decode((string) $log->data, true);
|
||||
if (($data['wallet_applied'] ?? false) === true) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -186,6 +186,7 @@ Route::middleware('auth:user')->group(function (){
|
||||
Route::get('pargar/{id}', [PargarController::class, 'show']);
|
||||
Route::post('pargar/{id}/retry', [PargarController::class, 'retrySanad']);
|
||||
Route::post('customer/{id}/pargar/register', [PargarController::class, 'registerCustomer']);
|
||||
Route::post('customer/{id}/pargar/sync-wallet', [PargarController::class, 'syncCustomerWallet']);
|
||||
|
||||
Route::get('test', function () {
|
||||
$data = [
|
||||
|
||||
Reference in New Issue
Block a user