feat(migrations): add national_code_verified flag to users and normalize bank_account representation
- Added a new column `national_code_verified` to the `users` table. - Normalized the `bank_account` field in the `representations` table from a single object to an array of IBANs with a default `verified` status of false. feat(ApiIrService): implement identity verification client for api.ir - Created `ApiIrService` to handle identity verification via api.ir. - Implemented methods for matching national code with mobile and IBAN with national code and birth date. - Added error handling and logging for external API requests.
This commit is contained in:
@@ -24,6 +24,7 @@ class SettlementController extends BaseController
|
||||
public function __construct(
|
||||
private readonly SettlementRepository $settlementRepo,
|
||||
private readonly WalletTransactionRepository $walletRepo,
|
||||
private readonly \App\Representation\Repository\RepresentationRepository $representationRepo,
|
||||
private readonly \App\Shared\Service\FileValidatorService $fileValidator,
|
||||
private readonly string $projectDir,
|
||||
) {}
|
||||
@@ -131,17 +132,34 @@ class SettlementController extends BaseController
|
||||
{
|
||||
$data = json_decode($request->getContent(), true) ?? [];
|
||||
$amountRials = (int) ($data['amount_rials'] ?? 0);
|
||||
$bankAccount = $data['bank_account'] ?? null;
|
||||
$ibanId = trim((string) ($data['iban_id'] ?? ''));
|
||||
|
||||
if ($amountRials <= 0) {
|
||||
return $this->error(ErrorCodes::ERR_VALIDATION_001, 'مبلغ برداشت باید بیشتر از صفر باشد', 422);
|
||||
}
|
||||
|
||||
if ($ibanId === '') {
|
||||
return $this->error(ErrorCodes::ERR_VALIDATION_002, 'انتخاب شماره شبا الزامی است', 422, 'iban_id');
|
||||
}
|
||||
|
||||
$rep = $this->representationRepo->findByUser($user);
|
||||
$iban = $rep?->findVerifiedIban($ibanId);
|
||||
if ($iban === null) {
|
||||
return $this->error(ErrorCodes::ERR_VALIDATION_001, 'شماره شبا نامعتبر یا تأییدنشده است', 422, 'iban_id');
|
||||
}
|
||||
|
||||
$balance = $this->settlementRepo->getWalletBalance($user);
|
||||
if ($amountRials > $balance) {
|
||||
return $this->error(ErrorCodes::ERR_CONFLICT_001, 'موجودی کافی نیست', 422);
|
||||
}
|
||||
|
||||
// snapshot شبای انتخابی در خود رکورد ذخیره میشود تا حذف بعدی شبا، این رکورد را خراب نکند
|
||||
$bankAccount = [
|
||||
'iban' => $iban['iban'],
|
||||
'bank_name' => $iban['bank_name'] ?? null,
|
||||
'owner_name' => $iban['owner_name'] ?? null,
|
||||
];
|
||||
|
||||
$settlement = new Settlement($user, $amountRials, $bankAccount);
|
||||
$this->settlementRepo->save($settlement);
|
||||
|
||||
@@ -401,6 +419,50 @@ class SettlementController extends BaseController
|
||||
return $this->success(['data' => $settlement->toArray()]);
|
||||
}
|
||||
|
||||
#[OA\Post(
|
||||
path: '/api/v1/settlement/{uuid}/receipt',
|
||||
summary: 'ذخیرهی رسید پرداخت بدون نهاییسازی (ROLE_ADMIN)',
|
||||
security: [['bearerAuth' => []]],
|
||||
requestBody: new OA\RequestBody(
|
||||
required: true,
|
||||
content: new OA\JsonContent(
|
||||
required: ['receipt'],
|
||||
properties: [new OA\Property(property: 'receipt', type: 'string', description: 'URL رسید آپلودشده')]
|
||||
)
|
||||
),
|
||||
parameters: [new OA\Parameter(name: 'uuid', in: 'path', required: true, schema: new OA\Schema(type: 'string'))],
|
||||
responses: [
|
||||
new OA\Response(response: 200, description: 'رسید ذخیره شد'),
|
||||
new OA\Response(response: 404, description: 'یافت نشد'),
|
||||
new OA\Response(response: 422, description: 'وضعیت نامعتبر یا رسید خالی'),
|
||||
]
|
||||
)]
|
||||
#[IsGranted('ROLE_ADMIN')]
|
||||
#[Route('/api/v1/settlement/{uuid}/receipt', methods: ['POST'])]
|
||||
public function saveReceipt(string $uuid, Request $request): JsonResponse
|
||||
{
|
||||
$settlement = $this->settlementRepo->findByUuid($uuid);
|
||||
if ($settlement === null) {
|
||||
return $this->error(ErrorCodes::ERR_NOT_FOUND_001, 'درخواست یافت نشد', 404);
|
||||
}
|
||||
|
||||
// فقط روی تسویهی تأییدشده میتوان رسید گذاشت (قبل از تکمیل).
|
||||
if ($settlement->getStatus() !== Settlement::STATUS_APPROVED) {
|
||||
return $this->error(ErrorCodes::ERR_VALIDATION_001, 'فقط تسویهی تأییدشده قابل ثبت رسید است', 422);
|
||||
}
|
||||
|
||||
$data = json_decode($request->getContent(), true) ?? [];
|
||||
$receipt = trim((string) ($data['receipt'] ?? ''));
|
||||
if ($receipt === '') {
|
||||
return $this->error(ErrorCodes::ERR_VALIDATION_002, 'رسید پرداخت الزامی است', 422, 'receipt');
|
||||
}
|
||||
|
||||
$settlement->setReceipt($receipt);
|
||||
$this->settlementRepo->save($settlement);
|
||||
|
||||
return $this->success(['data' => $settlement->toArray()]);
|
||||
}
|
||||
|
||||
private function handleFileUpload(Request $request, string $subDir): JsonResponse
|
||||
{
|
||||
$content = $request->getContent();
|
||||
|
||||
@@ -74,6 +74,13 @@ class Settlement
|
||||
public function getAdminNote(): ?string { return $this->adminNote; }
|
||||
public function getReceipt(): ?string { return $this->receipt; }
|
||||
|
||||
public function setReceipt(?string $receipt): self
|
||||
{
|
||||
$this->receipt = $receipt;
|
||||
$this->updatedAt = time();
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function approve(int $adminUserId, ?string $note = null): self
|
||||
{
|
||||
$this->status = self::STATUS_APPROVED;
|
||||
|
||||
Reference in New Issue
Block a user