309 lines
10 KiB
PHP
309 lines
10 KiB
PHP
<?php
|
|
|
|
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;
|
|
|
|
class PargarController extends Controller
|
|
{
|
|
protected function sync(): PargarSyncService
|
|
{
|
|
return app(PargarSyncService::class);
|
|
}
|
|
|
|
public function table(Request $request)
|
|
{
|
|
$query = PargarSyncLog::with('customer')->orderByDesc('id');
|
|
\App\DB\Te\TableEngine::create($query, $request)
|
|
->initSearch(['desc', 'type'])
|
|
->select(['*'])
|
|
->export($query);
|
|
|
|
return response()->json($query);
|
|
}
|
|
|
|
public function show($id)
|
|
{
|
|
return response()->json(PargarSyncLog::with('customer')->findOrFail($id));
|
|
}
|
|
|
|
public function customerSyncStatus(Request $request)
|
|
{
|
|
$panelTotal = Customer::whereNull('deleted_at')->count();
|
|
$panelRegistered = Customer::whereNull('deleted_at')->whereNotNull('pargar_account_id')->count();
|
|
$panelOnly = $panelTotal - $panelRegistered;
|
|
|
|
$panelOnlyQuery = Customer::whereNull('deleted_at')
|
|
->whereNull('pargar_account_id')
|
|
->select('id', 'name', 'mobile', 'created_at');
|
|
|
|
if ($search = $request->input('search')) {
|
|
$panelOnlyQuery->where(function ($q) use ($search) {
|
|
$q->where('name', 'like', "%{$search}%")
|
|
->orWhere('mobile', 'like', "%{$search}%");
|
|
});
|
|
}
|
|
|
|
$panelOnlyList = $panelOnlyQuery->orderBy('id')->paginate(20);
|
|
|
|
$inboundOnlyQuery = PargarSyncLog::query()
|
|
->where('type', 'customer')
|
|
->where('sync_status', PargarSyncService::STATUS_SUCCESS)
|
|
->whereNotNull('pargar_ref')
|
|
->latest('id');
|
|
|
|
$inboundOnlyCount = (clone $inboundOnlyQuery)->count();
|
|
$inboundSample = $inboundOnlyQuery->limit(100)->get(['id', 'customer_id', 'pargar_ref', 'created_at']);
|
|
|
|
return response()->json([
|
|
'panel_total' => $panelTotal,
|
|
'panel_registered' => $panelRegistered,
|
|
'panel_only' => $panelOnly,
|
|
'pargar_total' => $panelRegistered + $inboundOnlyCount,
|
|
'pargar_only_count' => max(0, $inboundOnlyCount),
|
|
'panel_only_list' => $panelOnlyList,
|
|
'pargar_only_list' => [
|
|
'data' => $inboundSample->map(fn ($row) => [
|
|
'code' => $row->pargar_ref,
|
|
'name' => $row->customer?->name ?? '',
|
|
'tel' => $row->customer?->mobile ?? '',
|
|
'gid' => null,
|
|
'group' => '',
|
|
])->values(),
|
|
'total' => $inboundOnlyCount,
|
|
'current_page' => 1,
|
|
'last_page' => 1,
|
|
],
|
|
]);
|
|
}
|
|
|
|
public function syncPanelToPargar()
|
|
{
|
|
$customers = Customer::whereNull('deleted_at')
|
|
->whereNull('pargar_account_id')
|
|
->get(['id', 'name', 'mobile']);
|
|
|
|
$success = 0;
|
|
$failed = 0;
|
|
$errors = [];
|
|
|
|
foreach ($customers as $customer) {
|
|
$result = $this->sync()->registerCustomer($customer);
|
|
if ($result['ok'] ?? false) {
|
|
$success++;
|
|
} else {
|
|
$failed++;
|
|
$errors[] = [
|
|
'name' => $customer->name,
|
|
'mobile' => $customer->mobile,
|
|
'error' => $result['message'] ?? '',
|
|
];
|
|
}
|
|
}
|
|
|
|
return response()->json([
|
|
'ok' => true,
|
|
'success' => $success,
|
|
'failed' => $failed,
|
|
'errors' => $errors,
|
|
]);
|
|
}
|
|
|
|
public function importFromPargar(Request $request)
|
|
{
|
|
$validated = $request->validate([
|
|
'customers' => 'required|array',
|
|
'customers.*.code' => 'required',
|
|
'customers.*.name' => 'required|string',
|
|
'customers.*.tel' => 'nullable|string',
|
|
]);
|
|
|
|
$success = 0;
|
|
$failed = 0;
|
|
$errors = [];
|
|
|
|
foreach ($validated['customers'] as $item) {
|
|
$mobile = Customer::normalizeMobile($item['tel'] ?? '') ?? '';
|
|
$fullName = trim($item['name']);
|
|
$accountId = (string) $item['code'];
|
|
|
|
$existing = Customer::whereNull('deleted_at')
|
|
->where('pargar_account_id', $accountId)
|
|
->first();
|
|
|
|
if ($existing) {
|
|
$success++;
|
|
continue;
|
|
}
|
|
|
|
if ($mobile !== '') {
|
|
$byMobile = Customer::findActiveByMobile($mobile);
|
|
if ($byMobile) {
|
|
$currentAccount = (string) ($byMobile->pargar_account_id ?? '');
|
|
if ($currentAccount !== '' && $currentAccount !== $accountId) {
|
|
$failed++;
|
|
$errors[] = [
|
|
'name' => $item['name'],
|
|
'code' => $item['code'],
|
|
'error' => 'شماره موبایل تکراری است',
|
|
];
|
|
continue;
|
|
}
|
|
|
|
$byMobile->pargar_account_id = $accountId;
|
|
if ($fullName !== '') {
|
|
$byMobile->fname = $fullName;
|
|
$byMobile->name = $fullName;
|
|
}
|
|
$byMobile->save();
|
|
$success++;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
$byAccount = Customer::whereNull('deleted_at')
|
|
->where('pargar_account_id', $accountId)
|
|
->first();
|
|
if ($byAccount) {
|
|
$failed++;
|
|
$errors[] = [
|
|
'name' => $item['name'],
|
|
'code' => $item['code'],
|
|
'error' => 'کد حساب پرگار قبلاً ثبت شده است',
|
|
];
|
|
continue;
|
|
}
|
|
|
|
try {
|
|
$customer = new Customer();
|
|
$customer->fname = $fullName;
|
|
$customer->lname = '';
|
|
$customer->name = $fullName;
|
|
$customer->mobile = $mobile;
|
|
$customer->active = true;
|
|
$customer->pargar_account_id = $accountId;
|
|
$customer->referral_id = $this->uniqueReferralId();
|
|
$customer->type = 2;
|
|
if ($mobile !== '') {
|
|
$customer->password = $mobile;
|
|
}
|
|
$customer->save();
|
|
$success++;
|
|
} catch (\Throwable $e) {
|
|
$failed++;
|
|
$errors[] = ['name' => $item['name'], 'code' => $item['code'], 'error' => $e->getMessage()];
|
|
}
|
|
}
|
|
|
|
return response()->json([
|
|
'ok' => true,
|
|
'success' => $success,
|
|
'failed' => $failed,
|
|
'errors' => $errors,
|
|
]);
|
|
}
|
|
|
|
public function rollbackImport(Request $request)
|
|
{
|
|
$baseQuery = fn () => Customer::whereNotNull('pargar_account_id')
|
|
->where(function ($q) {
|
|
$q->whereNull('name')->orWhere('name', '');
|
|
});
|
|
|
|
$count = $baseQuery()->count();
|
|
$sample = $baseQuery()
|
|
->select('id', 'fname', 'name', 'mobile', 'pargar_account_id', 'created_at')
|
|
->orderByDesc('id')
|
|
->limit(20)
|
|
->get();
|
|
|
|
if ($request->boolean('dry_run')) {
|
|
return response()->json([
|
|
'dry_run' => true,
|
|
'count' => $count,
|
|
'sample' => $sample,
|
|
]);
|
|
}
|
|
|
|
$deleted = $baseQuery()->forceDelete();
|
|
|
|
return response()->json([
|
|
'ok' => true,
|
|
'deleted' => $deleted,
|
|
]);
|
|
}
|
|
|
|
public function retrySanad($id)
|
|
{
|
|
$log = PargarSyncLog::with('customer')->findOrFail($id);
|
|
$result = $this->sync()->retry($log);
|
|
|
|
return response()->json($result, ($result['ok'] ?? false) ? 200 : 422);
|
|
}
|
|
|
|
public function registerCustomer($customerId)
|
|
{
|
|
$customer = Customer::findOrFail($customerId);
|
|
$result = $this->sync()->registerCustomer($customer);
|
|
|
|
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);
|
|
$mandeMessage = (string) ($result['mande']['message'] ?? '');
|
|
|
|
$messages = [];
|
|
if ($appliedDocs > 0) {
|
|
$messages[] = "{$appliedDocs} سند از پرگار اعمال شد";
|
|
}
|
|
if ($appliedMande) {
|
|
$messages[] = 'ماندهٔ پرگار روی کیف اعمال شد';
|
|
}
|
|
if ($mandeMessage !== '' && ! $appliedMande) {
|
|
$messages[] = $mandeMessage;
|
|
}
|
|
|
|
return response()->json([
|
|
'ok' => $appliedDocs > 0 || $appliedMande,
|
|
'message' => $messages !== []
|
|
? implode(' — ', $messages)
|
|
: 'سند قابلاعمالی یافت نشد',
|
|
'result' => $result,
|
|
], $appliedDocs > 0 || $appliedMande ? 200 : 422);
|
|
}
|
|
|
|
private function uniqueReferralId(): string
|
|
{
|
|
do {
|
|
$referral = substr(str_shuffle('0123456789abcdefghijklmnopqrstuvwxyz'), 0, 4);
|
|
} while (Customer::where('referral_id', $referral)->exists());
|
|
|
|
return $referral;
|
|
}
|
|
}
|