fix pargar bugs
This commit is contained in:
@@ -5,6 +5,8 @@ namespace App\Http\Controllers\Admin;
|
|||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\Customer;
|
use App\Models\Customer;
|
||||||
use App\Models\PargarSyncLog;
|
use App\Models\PargarSyncLog;
|
||||||
|
use App\Services\ConfigService;
|
||||||
|
use App\Services\PargarInboundWalletService;
|
||||||
use App\Services\PargarSyncService;
|
use App\Services\PargarSyncService;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
@@ -253,6 +255,36 @@ class PargarController extends Controller
|
|||||||
return response()->json($result, ($result['ok'] ?? false) ? 200 : 422);
|
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
|
private function uniqueReferralId(): string
|
||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
|
|||||||
@@ -122,17 +122,161 @@ class PargarInboundWalletService
|
|||||||
return $result;
|
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
|
public function isDocumentApplied(string $docId): bool
|
||||||
{
|
{
|
||||||
if ($docId === '') {
|
if ($docId === '') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return PargarSyncLog::query()
|
$logs = PargarSyncLog::query()
|
||||||
->where('type', PargarSyncService::TYPE_DOCUMENT)
|
->where('type', PargarSyncService::TYPE_DOCUMENT)
|
||||||
->where('pargar_ref', $docId)
|
->where('pargar_ref', $docId)
|
||||||
->where('sync_status', PargarSyncService::STATUS_SUCCESS)
|
->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::get('pargar/{id}', [PargarController::class, 'show']);
|
||||||
Route::post('pargar/{id}/retry', [PargarController::class, 'retrySanad']);
|
Route::post('pargar/{id}/retry', [PargarController::class, 'retrySanad']);
|
||||||
Route::post('customer/{id}/pargar/register', [PargarController::class, 'registerCustomer']);
|
Route::post('customer/{id}/pargar/register', [PargarController::class, 'registerCustomer']);
|
||||||
|
Route::post('customer/{id}/pargar/sync-wallet', [PargarController::class, 'syncCustomerWallet']);
|
||||||
|
|
||||||
Route::get('test', function () {
|
Route::get('test', function () {
|
||||||
$data = [
|
$data = [
|
||||||
|
|||||||
Reference in New Issue
Block a user