Add gold credit feature gated by SuperAdmin enable_gold_credit.
Port tables, APIs, and overdue cron from goldali, default the flag off, and keep customer routes behind auth. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Customer;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\GoldCredit;
|
||||
use App\Models\GoldCreditRequest;
|
||||
use App\Services\GoldCreditService;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class GoldCreditController extends Controller
|
||||
{
|
||||
public function __construct(private GoldCreditService $service)
|
||||
{
|
||||
}
|
||||
|
||||
private function ensureEnabled()
|
||||
{
|
||||
if (! app(\App\Services\ConfigService::class)->isGoldCreditEnabled()) {
|
||||
abort(403, 'اعتبار طلایی برای این نسخه فعال نیست');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function show()
|
||||
{
|
||||
$this->ensureEnabled();
|
||||
|
||||
$customerId = auth('customer')->id();
|
||||
$config = $this->service->getPublicConfig();
|
||||
$walletGold = $this->service->getCustomerGoldBalance($customerId);
|
||||
$tier = $this->service->resolveTierForBalance($walletGold);
|
||||
$minBalance = (float) $config['min_balance_gram'];
|
||||
|
||||
$credit = GoldCredit::with('installments')
|
||||
->where('customer_id', $customerId)
|
||||
->whereIn('status', ['pending', 'active', 'completed'])
|
||||
->orderByDesc('id')
|
||||
->first();
|
||||
|
||||
if ($credit) {
|
||||
$this->service->refreshOverdueStatuses($credit);
|
||||
$credit->load('installments');
|
||||
}
|
||||
|
||||
$pendingRequest = GoldCreditRequest::where('customer_id', $customerId)
|
||||
->where('status', 'pending')
|
||||
->latest()
|
||||
->first();
|
||||
|
||||
$remainingSoot = 0;
|
||||
if ($credit) {
|
||||
$remainingSoot = $credit->installments
|
||||
->whereIn('status', ['pending', 'overdue', 'partial'])
|
||||
->sum('amount_soot');
|
||||
}
|
||||
|
||||
$canRequest = !$credit
|
||||
&& !$pendingRequest
|
||||
&& $walletGold >= $minBalance
|
||||
&& $tier !== null;
|
||||
|
||||
return response()->json([
|
||||
'credit' => $credit,
|
||||
'pending_request' => $pendingRequest,
|
||||
'remaining_soot' => $remainingSoot,
|
||||
'gram_price_rial' => $this->service->getGramPriceRial(),
|
||||
'wallet_gold' => $walletGold,
|
||||
'can_request' => $canRequest,
|
||||
'suggested_tier' => $tier,
|
||||
'config' => $config,
|
||||
]);
|
||||
}
|
||||
|
||||
public function requestLoan(Request $request)
|
||||
{
|
||||
$this->ensureEnabled();
|
||||
|
||||
$data = $request->validate([
|
||||
'note' => 'nullable|string|max:500',
|
||||
]);
|
||||
|
||||
$customerId = auth('customer')->id();
|
||||
$config = $this->service->getPublicConfig();
|
||||
$walletGold = $this->service->getCustomerGoldBalance($customerId);
|
||||
$minBalance = (float) $config['min_balance_gram'];
|
||||
$tier = $this->service->resolveTierForBalance($walletGold);
|
||||
|
||||
if ($walletGold < $minBalance || !$tier) {
|
||||
return response()->json([
|
||||
'message' => 'موجودی طلای شما برای ثبت درخواست کافی نیست',
|
||||
], 422);
|
||||
}
|
||||
|
||||
$hasActive = GoldCredit::where('customer_id', $customerId)
|
||||
->whereIn('status', ['pending', 'active'])
|
||||
->exists();
|
||||
if ($hasActive) {
|
||||
return response()->json(['message' => 'شما اعتبار فعال دارید'], 422);
|
||||
}
|
||||
|
||||
$hasPending = GoldCreditRequest::where('customer_id', $customerId)
|
||||
->where('status', 'pending')
|
||||
->exists();
|
||||
if ($hasPending) {
|
||||
return response()->json(['message' => 'درخواست قبلی شما در انتظار بررسی است'], 422);
|
||||
}
|
||||
|
||||
$loanRequest = GoldCreditRequest::create([
|
||||
'customer_id' => $customerId,
|
||||
'requested_gold' => $tier['credit_gram'],
|
||||
'requested_months' => $tier['months'] ?? $config['default_months'],
|
||||
'note' => $data['note'] ?? null,
|
||||
'status' => 'pending',
|
||||
]);
|
||||
|
||||
$this->service->notifyAdminsLoanRequest($loanRequest);
|
||||
|
||||
return response()->json([
|
||||
'request' => $loanRequest,
|
||||
'message' => $config['request_success_text'],
|
||||
'suggested_tier' => $tier,
|
||||
]);
|
||||
}
|
||||
|
||||
public function payInstallments(Request $request)
|
||||
{
|
||||
$this->ensureEnabled();
|
||||
|
||||
$data = $request->validate([
|
||||
'installment_ids' => 'required|array|min:1',
|
||||
'installment_ids.*' => 'integer|exists:gold_credit_installments,id',
|
||||
'pay_method' => 'required|in:gold,rial,mixed',
|
||||
'gold_amount' => 'nullable|numeric|min:0',
|
||||
'rial_amount' => 'nullable|integer|min:0',
|
||||
]);
|
||||
|
||||
$this->service->assertPayMethodAllowed($data['pay_method']);
|
||||
|
||||
$customerId = auth('customer')->id();
|
||||
$credit = GoldCredit::where('customer_id', $customerId)
|
||||
->whereIn('status', ['active'])
|
||||
->orderByDesc('id')
|
||||
->firstOrFail();
|
||||
|
||||
$result = $this->service->payInstallments(
|
||||
$credit,
|
||||
$data['installment_ids'],
|
||||
$data['pay_method'],
|
||||
$data['gold_amount'] ?? null,
|
||||
$data['rial_amount'] ?? null,
|
||||
null
|
||||
);
|
||||
|
||||
return response()->json($result);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user