fix bug of pargar 4
This commit is contained in:
@@ -33,6 +33,15 @@ class PargarController extends Controller
|
||||
return response()->json(PargarSyncLog::with('customer')->findOrFail($id));
|
||||
}
|
||||
|
||||
/** اسناد پنل که پرگار هنوز تحویل نگرفته — ماندهٔ این مشتریها قفل است */
|
||||
public function stuckOutbound(Request $request)
|
||||
{
|
||||
$minutes = (int) $request->query('minutes', 15);
|
||||
$minutes = max(0, min($minutes, 60 * 24 * 30));
|
||||
|
||||
return response()->json($this->sync()->stuckOutboundDocuments($minutes));
|
||||
}
|
||||
|
||||
public function customerSyncStatus(Request $request)
|
||||
{
|
||||
$panelTotal = Customer::whereNull('deleted_at')->count();
|
||||
|
||||
@@ -7,6 +7,7 @@ use App\Models\Order;
|
||||
use App\Models\PargarSyncLog;
|
||||
use App\Models\Product;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
@@ -405,6 +406,100 @@ class PargarSyncService
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* شناسهای که سند با آن در GET /pargar/orders بیرون میرود.
|
||||
*/
|
||||
public function outboundExportId(PargarSyncLog $log): string
|
||||
{
|
||||
if ($log->type === self::TYPE_ORDER) {
|
||||
return (string) ($log->order_id ?? $log->id);
|
||||
}
|
||||
|
||||
$withdrawId = (int) ($log->withdraw_id ?? 0);
|
||||
|
||||
return $withdrawId > 0 ? 'W-'.$withdrawId : 'WLOG-'.$log->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* اسنادی که در نوبت GET /pargar/orders هستند و پرگار هنوز تأییدشان نکرده است.
|
||||
*
|
||||
* تا وقتی اینها معلقاند، ماندهٔ پرگارِ همان مشتری روی کیف اعمال نمیشود؛ پس باید
|
||||
* در پنل دیده شوند، نه اینکه با شکایت مشتری کشف شوند.
|
||||
*
|
||||
* @return array{
|
||||
* count: int,
|
||||
* customers: int,
|
||||
* waited_minutes: int,
|
||||
* oldest_at: string|null,
|
||||
* last_confirmed_at: string|null,
|
||||
* threshold_minutes: int,
|
||||
* rows: list<array<string, mixed>>
|
||||
* }
|
||||
*/
|
||||
public function stuckOutboundDocuments(int $olderThanMinutes = 15, int $limit = 50): array
|
||||
{
|
||||
$threshold = now()->subMinutes(max(0, $olderThanMinutes));
|
||||
|
||||
$logs = PargarSyncLog::with('customer')
|
||||
->whereIn('type', [self::TYPE_ORDER, self::TYPE_WALLET_CASH, self::TYPE_WALLET_GOLD])
|
||||
->where('sync_status', self::STATUS_PENDING)
|
||||
->where('created_at', '<=', $threshold)
|
||||
->where(function ($q) {
|
||||
// سند کیف تا وقتی pending است در هر fetch فرستاده میشود؛ سفارش فقط
|
||||
// وقتی هنوز در نوبت خروجی است (sts=2 و تأییدنشده).
|
||||
$q->whereIn('type', [self::TYPE_WALLET_CASH, self::TYPE_WALLET_GOLD])
|
||||
->orWhereExists(function ($sub) {
|
||||
$sub->select(DB::raw(1))
|
||||
->from('orders')
|
||||
->whereColumn('orders.id', 'pargar_sync_logs.order_id')
|
||||
->where('orders.sts', 2)
|
||||
->whereNull('orders.pargar_confirmed_at');
|
||||
});
|
||||
})
|
||||
->orderBy('id')
|
||||
->get();
|
||||
|
||||
$oldest = $logs->first()?->created_at;
|
||||
|
||||
return [
|
||||
'count' => $logs->count(),
|
||||
'customers' => $logs->pluck('customer_id')->filter()->unique()->count(),
|
||||
'waited_minutes' => $oldest ? (int) $oldest->diffInMinutes(now()) : 0,
|
||||
'oldest_at' => $oldest?->toDateTimeString(),
|
||||
'last_confirmed_at' => $this->lastOutboundConfirmedAt(),
|
||||
'threshold_minutes' => max(0, $olderThanMinutes),
|
||||
'rows' => $logs->take($limit)->map(fn (PargarSyncLog $log) => [
|
||||
'id' => (int) $log->id,
|
||||
'export_id' => $this->outboundExportId($log),
|
||||
'type' => (string) $log->type,
|
||||
'amount' => $log->amount === null ? null : (float) $log->amount,
|
||||
'desc' => (string) ($log->desc ?? ''),
|
||||
'order_id' => $log->order_id ? (int) $log->order_id : null,
|
||||
'withdraw_id' => $log->withdraw_id ? (int) $log->withdraw_id : null,
|
||||
'customer_id' => $log->customer_id ? (int) $log->customer_id : null,
|
||||
'customer_name' => $log->customer?->name,
|
||||
'customer_mobile' => $log->customer?->mobile,
|
||||
'pargar_account_id' => $log->customer?->pargar_account_id,
|
||||
'created_at' => $log->created_at?->toDateTimeString(),
|
||||
'waited_minutes' => $log->created_at ? (int) $log->created_at->diffInMinutes(now()) : 0,
|
||||
])->values()->all(),
|
||||
];
|
||||
}
|
||||
|
||||
/** آخرین باری که پرگار سندی از پنل را تأیید کرده است */
|
||||
private function lastOutboundConfirmedAt(): ?string
|
||||
{
|
||||
$query = PargarSyncLog::query()
|
||||
->whereIn('type', [self::TYPE_ORDER, self::TYPE_WALLET_CASH, self::TYPE_WALLET_GOLD])
|
||||
->where('sync_status', self::STATUS_SUCCESS);
|
||||
|
||||
$confirmedAt = PargarSyncLog::hasConfirmedAtColumn()
|
||||
? $query->clone()->max('confirmed_at')
|
||||
: null;
|
||||
|
||||
return $confirmedAt ?: $query->max('updated_at');
|
||||
}
|
||||
|
||||
public function retry(PargarSyncLog $log): array
|
||||
{
|
||||
if (! $this->isFailed($log) && ! empty($log->pargar_ref)) {
|
||||
|
||||
@@ -214,6 +214,7 @@ Route::middleware('auth:user')->group(function (){
|
||||
|
||||
Route::post('pargar/table', [PargarController::class, 'table']);
|
||||
Route::get('pargar/customer-sync/status', [PargarController::class, 'customerSyncStatus']);
|
||||
Route::get('pargar/stuck-outbound', [PargarController::class, 'stuckOutbound']);
|
||||
Route::post('pargar/customer-sync/panel-to-pargar', [PargarController::class, 'syncPanelToPargar']);
|
||||
Route::post('pargar/customer-sync/import-from-pargar', [PargarController::class, 'importFromPargar']);
|
||||
Route::post('pargar/customer-sync/rollback-import', [PargarController::class, 'rollbackImport']);
|
||||
|
||||
Reference in New Issue
Block a user