almost finish inquiry panel

This commit is contained in:
Hesabix 2025-07-17 09:07:31 +00:00
parent 227767b0d6
commit 2a8ea8cb4a
12 changed files with 1954 additions and 14 deletions

View file

@ -545,6 +545,7 @@ class BusinessController extends AbstractController
'plugHrmDocs' => true,
'plugGhestaManager' => true,
'plugTaxSettings' => true,
'inquiry' => true,
];
} elseif ($perm) {
$result = [
@ -589,6 +590,7 @@ class BusinessController extends AbstractController
'plugHrmDocs' => $perm->isPlugHrmDocs(),
'plugGhestaManager' => $perm->isPlugGhestaManager(),
'plugTaxSettings' => $perm->isPlugTaxSettings(),
'inquiry' => $perm->isInquiry(),
];
}
return $this->json($result);
@ -659,6 +661,7 @@ class BusinessController extends AbstractController
$perm->setPlugHrmDocs($params['plugHrmDocs']);
$perm->setPlugGhestaManager($params['plugGhestaManager']);
$perm->setPlugTaxSettings($params['plugTaxSettings']);
$perm->setInquiry($params['inquiry']);
$entityManager->persist($perm);
$entityManager->flush();
$log->insert('تنظیمات پایه', 'ویرایش دسترسی‌های کاربر با پست الکترونیکی ' . $user->getEmail(), $this->getUser(), $business);

View file

@ -32,19 +32,21 @@ class PlugInquiryMainController extends AbstractController
#[Route('/api/plugins/inquiry/settings/get', name: 'plugin_inquiry_settings_get', methods: ['GET'])]
public function plugin_inquiry_settings_get(registryMGR $registryMGR): JsonResponse
{
$resp['inquiryPanel'] = $registryMGR->get('system', key: 'inquiryPanel');
$resp['enablePostalCodeToAddress'] = $registryMGR->get('system', key: 'enablePostalCodeToAddress');
$resp['inquiryPanelEnable'] = $registryMGR->get('system', key: 'inquiryPanelEnable');
$resp['postalCodeToAddressFee'] = $registryMGR->get('system', key: 'postalCodeToAddressFee');
$resp['enableCardToSheba'] = $registryMGR->get('system', key: 'enableCardToSheba');
$resp['cardToShebaFee'] = $registryMGR->get('system', key: 'cardToShebaFee');
$resp['enableAccountToSheba'] = $registryMGR->get('system', key: 'enableAccountToSheba');
$resp['accountToShebaFee'] = $registryMGR->get('system', key: 'accountToShebaFee');
return $this->json($resp);
}
#[Route('/api/plugins/inquiry/postalcode-to-address', name: 'plugin_inquiry_postalcode_to_address', methods: ['POST'])]
public function plugin_inquiry_postalcode_to_address(Inquiry $inquiry, Access $access, Request $request, registryMGR $registryMGR, Log $log): JsonResponse
{
$acc = $access->hasRole('join');
$acc = $access->hasRole('inquiry');
if (!$acc) {
return $this->json([
'success' => false,
@ -128,4 +130,198 @@ class PlugInquiryMainController extends AbstractController
]);
}
}
#[Route('/api/plugins/inquiry/card-to-sheba', name: 'plugin_inquiry_card_to_sheba', methods: ['POST'])]
public function plugin_inquiry_card_to_sheba(Inquiry $inquiry, Access $access, Request $request, registryMGR $registryMGR, Log $log): JsonResponse
{
$acc = $access->hasRole('inquiry');
if (!$acc) {
return $this->json([
'success' => false,
'message' => 'شما دسترسی به این سرویس را ندارید'
]);
}
// بررسی فعال بودن سرویس
if (!$registryMGR->get('system', key: 'enableCardToSheba')) {
return $this->json([
'success' => false,
'message' => 'این سرویس در حال حاضر غیرفعال است'
]);
}
// دریافت شماره کارت از درخواست
$data = json_decode($request->getContent(), true);
$cardNumber = $data['card_number'] ?? null;
if (!$cardNumber) {
return $this->json([
'success' => false,
'message' => 'شماره کارت ارسال نشده است'
]);
}
// فراخوانی سرویس استعلام کارت به شبا
$result = $inquiry->cardToSheba($cardNumber);
// بررسی نتیجه و بازگرداندن پاسخ مناسب
if (isset($result['result']) && $result['result'] == 1) {
$isFromCache = isset($result['response_body']['message']) &&
strpos($result['response_body']['message'], 'از حافظه موقت') !== false;
// ثبت لاگ بر اساس منبع داده
$logMessage = $isFromCache
? "استعلام کارت به شبا {$cardNumber} از حافظه موقت (بدون کسر کارمزد)"
: "استعلام کارت به شبا {$cardNumber} از API (کسر کارمزد: " . $registryMGR->get('system', key: 'cardToShebaFee') . " ریال)";
$log->insert(
'استعلام',
$logMessage,
$acc['user'],
$acc['bid']
);
// فقط در صورت عدم وجود در کش، کارمزد کسر شود
if (!$isFromCache) {
if ($acc['bid']->getSmsCharge() < $registryMGR->get('system', key: 'cardToShebaFee')) {
// ثبت لاگ عدم موجودی کافی
$log->insert(
'استعلام',
"عدم موجودی کافی برای استعلام کارت به شبا {$cardNumber}",
$acc['user'],
$acc['bid']
);
return $this->json([
'success' => false,
'message' => 'موجودی شما برای این سرویس کافی نیست'
]);
}
$business = $acc['bid'];
$business->setSmsCharge($business->getSmsCharge() - $registryMGR->get('system', key: 'cardToShebaFee'));
$this->entityManager->persist($business);
$this->entityManager->flush();
}
return $this->json([
'success' => true,
'data' => $result['response_body']['data'] ?? null,
'message' => $result['response_body']['message'] ?? 'موفق',
'from_cache' => $isFromCache
]);
} else {
// ثبت لاگ خطا
$errorMessage = $result['message'] ?? 'خطا در استعلام کارت به شبا';
$log->insert(
'استعلام',
"خطا در استعلام کارت به شبا {$cardNumber}: {$errorMessage}",
$acc['user'],
$acc['bid']
);
return $this->json([
'success' => false,
'message' => $errorMessage,
'error_code' => $result['error_code'] ?? null
]);
}
}
#[Route('/api/plugins/inquiry/account-to-sheba', name: 'plugin_inquiry_account_to_sheba', methods: ['POST'])]
public function plugin_inquiry_account_to_sheba(Inquiry $inquiry, Access $access, Request $request, registryMGR $registryMGR, Log $log): JsonResponse
{
$acc = $access->hasRole('inquiry');
if (!$acc) {
return $this->json([
'success' => false,
'message' => 'شما دسترسی به این سرویس را ندارید'
]);
}
// بررسی فعال بودن سرویس
if (!$registryMGR->get('system', key: 'enableAccountToSheba')) {
return $this->json([
'success' => false,
'message' => 'این سرویس در حال حاضر غیرفعال است'
]);
}
// دریافت داده‌ها از درخواست
$data = json_decode($request->getContent(), true);
$bankCode = $data['bank_code'] ?? null;
$accountNumber = $data['account_number'] ?? null;
if (!$bankCode || !$accountNumber) {
return $this->json([
'success' => false,
'message' => 'کد بانک و شماره حساب الزامی است'
]);
}
// فراخوانی سرویس استعلام حساب به شبا
$result = $inquiry->accountToSheba($bankCode, $accountNumber);
// بررسی نتیجه و بازگرداندن پاسخ مناسب
if (isset($result['result']) && $result['result'] == 1) {
$isFromCache = isset($result['response_body']['message']) &&
strpos($result['response_body']['message'], 'از حافظه موقت') !== false;
// ثبت لاگ بر اساس منبع داده
$logMessage = $isFromCache
? "استعلام حساب به شبا {$bankCode}/{$accountNumber} از حافظه موقت (بدون کسر کارمزد)"
: "استعلام حساب به شبا {$bankCode}/{$accountNumber} از API (کسر کارمزد: " . $registryMGR->get('system', key: 'accountToShebaFee') . " ریال)";
$log->insert(
'استعلام',
$logMessage,
$acc['user'],
$acc['bid']
);
// فقط در صورت عدم وجود در کش، کارمزد کسر شود
if (!$isFromCache) {
if ($acc['bid']->getSmsCharge() < $registryMGR->get('system', key: 'accountToShebaFee')) {
// ثبت لاگ عدم موجودی کافی
$log->insert(
'استعلام',
"عدم موجودی کافی برای استعلام حساب به شبا {$bankCode}/{$accountNumber}",
$acc['user'],
$acc['bid']
);
return $this->json([
'success' => false,
'message' => 'موجودی شما برای این سرویس کافی نیست'
]);
}
$business = $acc['bid'];
$business->setSmsCharge($business->getSmsCharge() - $registryMGR->get('system', key: 'accountToShebaFee'));
$this->entityManager->persist($business);
$this->entityManager->flush();
}
return $this->json([
'success' => true,
'data' => $result['response_body']['data'] ?? null,
'message' => $result['response_body']['message'] ?? 'موفق',
'from_cache' => $isFromCache
]);
} else {
// ثبت لاگ خطا
$errorMessage = $result['message'] ?? 'خطا در استعلام حساب به شبا';
$log->insert(
'استعلام',
"خطا در استعلام حساب به شبا {$bankCode}/{$accountNumber}: {$errorMessage}",
$acc['user'],
$acc['bid']
);
return $this->json([
'success' => false,
'message' => $errorMessage,
'error_code' => $result['error_code'] ?? null
]);
}
}
}

View file

@ -0,0 +1,63 @@
<?php
namespace App\Entity;
use App\Repository\AccountToShebaInquiryRepository;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: AccountToShebaInquiryRepository::class)]
#[ORM\Table(name: 'account_to_sheba_inquiry')]
class AccountToShebaInquiry
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 50, unique: true)]
private ?string $cacheKey = null;
#[ORM\Column(type: 'json')]
private array $shebaData = [];
#[ORM\Column]
private ?\DateTimeImmutable $updatedAt = null;
public function getId(): ?int
{
return $this->id;
}
public function getCacheKey(): ?string
{
return $this->cacheKey;
}
public function setCacheKey(string $cacheKey): static
{
$this->cacheKey = $cacheKey;
return $this;
}
public function getShebaData(): array
{
return $this->shebaData;
}
public function setShebaData(array $shebaData): static
{
$this->shebaData = $shebaData;
return $this;
}
public function getUpdatedAt(): ?\DateTimeImmutable
{
return $this->updatedAt;
}
public function setUpdatedAt(\DateTimeImmutable $updatedAt): static
{
$this->updatedAt = $updatedAt;
return $this;
}
}

View file

@ -0,0 +1,63 @@
<?php
namespace App\Entity;
use App\Repository\CardToShebaInquiryRepository;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: CardToShebaInquiryRepository::class)]
#[ORM\Table(name: 'card_to_sheba_inquiry')]
class CardToShebaInquiry
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 16, unique: true)]
private ?string $cardNumber = null;
#[ORM\Column(type: 'json')]
private array $shebaData = [];
#[ORM\Column]
private ?\DateTimeImmutable $updatedAt = null;
public function getId(): ?int
{
return $this->id;
}
public function getCardNumber(): ?string
{
return $this->cardNumber;
}
public function setCardNumber(string $cardNumber): static
{
$this->cardNumber = $cardNumber;
return $this;
}
public function getShebaData(): array
{
return $this->shebaData;
}
public function setShebaData(array $shebaData): static
{
$this->shebaData = $shebaData;
return $this;
}
public function getUpdatedAt(): ?\DateTimeImmutable
{
return $this->updatedAt;
}
public function setUpdatedAt(\DateTimeImmutable $updatedAt): static
{
$this->updatedAt = $updatedAt;
return $this;
}
}

View file

@ -132,6 +132,9 @@ class Permission
#[ORM\Column(nullable: true)]
private ?bool $plugTaxSettings = null;
#[ORM\Column(nullable: true)]
private ?bool $inquiry = null;
public function getId(): ?int
{
return $this->id;
@ -605,4 +608,15 @@ class Permission
return $this;
}
public function isInquiry(): ?bool
{
return $this->inquiry;
}
public function setInquiry(?bool $inquiry): static
{
$this->inquiry = $inquiry;
return $this;
}
}

View file

@ -0,0 +1,46 @@
<?php
namespace App\Repository;
use App\Entity\AccountToShebaInquiry;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<AccountToShebaInquiry>
*
* @method AccountToShebaInquiry|null find($id, $lockMode = null, $lockVersion = null)
* @method AccountToShebaInquiry|null findOneBy(array $criteria, array $orderBy = null)
* @method AccountToShebaInquiry[] findAll()
* @method AccountToShebaInquiry[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class AccountToShebaInquiryRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, AccountToShebaInquiry::class);
}
public function findByCacheKey(string $cacheKey): ?AccountToShebaInquiry
{
return $this->findOneBy(['cacheKey' => $cacheKey]);
}
public function save(AccountToShebaInquiry $entity, bool $flush = false): void
{
$this->getEntityManager()->persist($entity);
if ($flush) {
$this->getEntityManager()->flush();
}
}
public function remove(AccountToShebaInquiry $entity, bool $flush = false): void
{
$this->getEntityManager()->remove($entity);
if ($flush) {
$this->getEntityManager()->flush();
}
}
}

View file

@ -0,0 +1,46 @@
<?php
namespace App\Repository;
use App\Entity\CardToShebaInquiry;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<CardToShebaInquiry>
*
* @method CardToShebaInquiry|null find($id, $lockMode = null, $lockVersion = null)
* @method CardToShebaInquiry|null findOneBy(array $criteria, array $orderBy = null)
* @method CardToShebaInquiry[] findAll()
* @method CardToShebaInquiry[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class CardToShebaInquiryRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, CardToShebaInquiry::class);
}
public function findByCardNumber(string $cardNumber): ?CardToShebaInquiry
{
return $this->findOneBy(['cardNumber' => $cardNumber]);
}
public function save(CardToShebaInquiry $entity, bool $flush = false): void
{
$this->getEntityManager()->persist($entity);
if ($flush) {
$this->getEntityManager()->flush();
}
}
public function remove(CardToShebaInquiry $entity, bool $flush = false): void
{
$this->getEntityManager()->remove($entity);
if ($flush) {
$this->getEntityManager()->flush();
}
}
}

View file

@ -3,6 +3,8 @@
namespace App\Service;
use App\Entity\PostalCodeInquiry;
use App\Entity\CardToShebaInquiry;
use App\Entity\AccountToShebaInquiry;
use Doctrine\ORM\EntityManagerInterface;
class Inquiry
@ -137,6 +139,130 @@ class Inquiry
];
}
public function cardToSheba($cardNumber)
{
// بررسی دیتابیس برای کش
$existingInquiry = $this->entityManager->getRepository(CardToShebaInquiry::class)->findByCardNumber($cardNumber);
if ($existingInquiry) {
// اگر در دیتابیس موجود است، از آن استفاده کن
$shebaData = $existingInquiry->getShebaData();
return [
'result' => 1,
'response_body' => [
'data' => $shebaData,
'message' => 'موفق (از حافظه موقت)',
'error_code' => null
]
];
}
// اگر در دیتابیس موجود نیست، از API استفاده کن
$registryMGR = new RegistryMGR($this->entityManager);
$inquiryPanel = $registryMGR->get('system', key: 'inquiryPanel');
if($inquiryPanel == 'zohal'){
$inquiryZohalAPIKey = $registryMGR->get('system', key: 'inquiryZohalAPIKey');
// بررسی وجود API Key
if (empty($inquiryZohalAPIKey)) {
return [
'result' => 0,
'message' => 'API Key تنظیم نشده است',
'error_code' => 'API_KEY_MISSING'
];
}
// استفاده از API زحل برای تبدیل کارت به شبا
$url = "https://service.zohal.io/api/v0/services/inquiry/card_to_iban";
// آماده‌سازی داده‌های JSON
$postData = json_encode([
'card_number' => $cardNumber
]);
// تنظیمات cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Length: ' . strlen($postData),
'Authorization: Bearer ' . $inquiryZohalAPIKey,
'X-API-Key: ' . $inquiryZohalAPIKey
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
curl_close($ch);
// بررسی خطای cURL
if ($curlError) {
return [
'result' => 0,
'message' => 'خطا در ارتباط با سرور: ' . $curlError,
'error_code' => 'CURL_ERROR'
];
}
if ($httpCode === 200) {
$data = json_decode($response, true);
// بررسی کدهای result
if (isset($data['result'])) {
switch ($data['result']) {
case 1:
// موفق - ذخیره در دیتابیس
if (isset($data['response_body']['data'])) {
$this->saveCardToShebaToDatabase($cardNumber, $data['response_body']['data']);
}
return $data;
case 4:
return [
'result' => 4,
'message' => 'توکن غیر فعال شده است',
'error_code' => 'TOKEN_INACTIVE'
];
case 5:
return [
'result' => 5,
'message' => 'سرویس در دسترسی نمی‌باشد',
'error_code' => 'SERVICE_UNAVAILABLE'
];
case 6:
return [
'result' => 6,
'message' => 'فراخوانی وب‌سرویس با پارامترهای ورودی صحیح نمی‌باشد',
'error_code' => 'INVALID_PARAMETERS'
];
default:
return [
'result' => $data['result'],
'message' => $data['message'] ?? 'خطای نامشخص',
'error_code' => $data['error_code'] ?? 'UNKNOWN_ERROR'
];
}
}
return $data;
} else {
return [
'result' => 0,
'message' => 'خطا در ارتباط با سرویس تبدیل کارت به شبا (کد خطا: ' . $httpCode . ')',
'error_code' => 'HTTP_ERROR_' . $httpCode
];
}
}
return [
'result' => 0,
'message' => 'سرویس تبدیل کارت به شبا فعال نیست',
'error_code' => 'SERVICE_NOT_ACTIVE'
];
}
private function saveToDatabase(string $postalCode, array $addressData): void
{
try {
@ -155,4 +281,168 @@ class Inquiry
error_log('خطا در ذخیره استعلام کد پستی: ' . $e->getMessage());
}
}
public function accountToSheba($bankCode, $accountNumber)
{
// بررسی دیتابیس برای کش
$cacheKey = $bankCode . '_' . $accountNumber;
$existingInquiry = $this->entityManager->getRepository(AccountToShebaInquiry::class)->findByCacheKey($cacheKey);
if ($existingInquiry) {
// اگر در دیتابیس موجود است، از آن استفاده کن
$shebaData = $existingInquiry->getShebaData();
return [
'result' => 1,
'response_body' => [
'data' => $shebaData,
'message' => 'موفق (از حافظه موقت)',
'error_code' => null
]
];
}
// اگر در دیتابیس موجود نیست، از API استفاده کن
$registryMGR = new RegistryMGR($this->entityManager);
$inquiryPanel = $registryMGR->get('system', key: 'inquiryPanel');
if($inquiryPanel == 'zohal'){
$inquiryZohalAPIKey = $registryMGR->get('system', key: 'inquiryZohalAPIKey');
// بررسی وجود API Key
if (empty($inquiryZohalAPIKey)) {
return [
'result' => 0,
'message' => 'API Key تنظیم نشده است',
'error_code' => 'API_KEY_MISSING'
];
}
// استفاده از API زحل برای تبدیل حساب به شبا
$url = "https://service.zohal.io/api/v0/services/inquiry/account_to_iban";
// آماده‌سازی داده‌های JSON
$postData = json_encode([
'bank_code' => $bankCode,
'bank_account' => $accountNumber
]);
// تنظیمات cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Length: ' . strlen($postData),
'Authorization: Bearer ' . $inquiryZohalAPIKey,
'X-API-Key: ' . $inquiryZohalAPIKey
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
curl_close($ch);
// بررسی خطای cURL
if ($curlError) {
return [
'result' => 0,
'message' => 'خطا در ارتباط با سرور: ' . $curlError,
'error_code' => 'CURL_ERROR'
];
}
if ($httpCode === 200) {
$data = json_decode($response, true);
// بررسی کدهای result
if (isset($data['result'])) {
switch ($data['result']) {
case 1:
// موفق - ذخیره در دیتابیس
if (isset($data['response_body']['data'])) {
$this->saveAccountToShebaToDatabase($cacheKey, $data['response_body']['data']);
}
return $data;
case 4:
return [
'result' => 4,
'message' => 'توکن غیر فعال شده است',
'error_code' => 'TOKEN_INACTIVE'
];
case 5:
return [
'result' => 5,
'message' => 'سرویس در دسترسی نمی‌باشد',
'error_code' => 'SERVICE_UNAVAILABLE'
];
case 6:
return [
'result' => 6,
'message' => 'فراخوانی وب‌سرویس با پارامترهای ورودی صحیح نمی‌باشد',
'error_code' => 'INVALID_PARAMETERS'
];
default:
return [
'result' => $data['result'],
'message' => $data['message'] ?? 'خطای نامشخص',
'error_code' => $data['error_code'] ?? 'UNKNOWN_ERROR'
];
}
}
return $data;
} else {
return [
'result' => 0,
'message' => 'خطا در ارتباط با سرویس تبدیل حساب به شبا (کد خطا: ' . $httpCode . ')',
'error_code' => 'HTTP_ERROR_' . $httpCode
];
}
}
return [
'result' => 0,
'message' => 'سرویس تبدیل حساب به شبا فعال نیست',
'error_code' => 'SERVICE_NOT_ACTIVE'
];
}
private function saveCardToShebaToDatabase(string $cardNumber, array $shebaData): void
{
try {
$inquiry = new CardToShebaInquiry();
$inquiry->setCardNumber($cardNumber);
$inquiry->setShebaData($shebaData);
$inquiry->setUpdatedAt(new \DateTimeImmutable());
$this->entityManager->persist($inquiry);
$this->entityManager->flush();
// ثبت لاگ ذخیره موفق در دیتابیس
error_log("شماره کارت {$cardNumber} با موفقیت در حافظه موقت ذخیره شد");
} catch (\Exception $e) {
// در صورت خطا در ذخیره، فقط لاگ کن و ادامه بده
error_log('خطا در ذخیره استعلام کارت به شبا: ' . $e->getMessage());
}
}
private function saveAccountToShebaToDatabase(string $cacheKey, array $shebaData): void
{
try {
$inquiry = new AccountToShebaInquiry();
$inquiry->setCacheKey($cacheKey);
$inquiry->setShebaData($shebaData);
$inquiry->setUpdatedAt(new \DateTimeImmutable());
$this->entityManager->persist($inquiry);
$this->entityManager->flush();
// ثبت لاگ ذخیره موفق در دیتابیس
error_log("حساب با کلید {$cacheKey} با موفقیت در حافظه موقت ذخیره شد");
} catch (\Exception $e) {
// در صورت خطا در ذخیره، فقط لاگ کن و ادامه بده
error_log('خطا در ذخیره استعلام حساب به شبا: ' . $e->getMessage());
}
}
}

View file

@ -791,8 +791,8 @@ export default {
</template>
</v-list-item>
</v-list-group>
<v-list-item class="text-dark" to="/acc/inquiry/panel">
<template v-slot:prepend><v-icon icon="mdi-magnify" color="primary"></v-icon></template>
<v-list-item to="/acc/inquiry/panel">
<template v-slot:prepend><v-icon icon="mdi-magnify"></v-icon></template>
<v-list-item-title>
{{ $t('drawer.inquiry') }}
<span v-if="isCtrlShiftPressed" class="shortcut-key">{{ getShortcutKey('/acc/inquiry/panel') }}</span>

View file

@ -0,0 +1,64 @@
# پنل استعلامات
این بخش شامل قابلیت‌های مختلف استعلام و تبدیل اطلاعات است که بر اساس تنظیمات سیستم فعال یا غیرفعال می‌شوند.
## قابلیت‌های موجود
### 1. تبدیل کد پستی به آدرس
- **وضعیت**: فعال/غیرفعال بر اساس تنظیمات سیستم
- **کارمزد**: قابل تنظیم در بخش مدیریت
- **API Endpoint**: `/api/plugins/inquiry/postalcode-to-address`
- **عملکرد**: تبدیل کد پستی 10 رقمی به آدرس کامل
### 2. تبدیل شماره کارت به شبا
- **وضعیت**: فعال/غیرفعال بر اساس تنظیمات سیستم
- **کارمزد**: قابل تنظیم در بخش مدیریت
- **API Endpoint**: `/api/plugins/inquiry/card-to-sheba`
- **عملکرد**: تبدیل شماره کارت 16 رقمی به شماره شبا (در حال توسعه)
### 3. تبدیل حساب به شبا
- **وضعیت**: فعال/غیرفعال بر اساس تنظیمات سیستم
- **کارمزد**: قابل تنظیم در بخش مدیریت
- **API Endpoint**: `/api/plugins/inquiry/account-to-sheba`
- **عملکرد**: تبدیل شماره حساب بانکی به شماره شبا (در حال توسعه)
## ویژگی‌های رابط کاربری
### نمایش سرویس‌های فعال
- نمایش کارت‌های رنگی برای هر سرویس فعال
- نمایش کارمزد هر سرویس
- نشان‌گذاری وضعیت فعال/غیرفعال
### دیالوگ‌های استعلام
- فرم‌های اعتبارسنجی شده
- نمایش کارمزد قبل از استعلام
- نمایش نتیجه در قالب پیام‌های زیبا
### مدیریت خطاها
- بررسی موجودی کافی
- نمایش پیام‌های خطای مناسب
- لاگ کردن عملیات‌ها
## تنظیمات مورد نیاز
برای فعال‌سازی این قابلیت‌ها، مدیر سیستم باید در بخش تنظیمات سیستم موارد زیر را تنظیم کند:
1. **فعال‌سازی پنل استعلامات**: `inquiryPanelEnable`
2. **انتخاب پنل**: `inquiryPanel` (فعلاً فقط زحل)
3. **کلید API پنل**: `inquiryZohalAPIKey`
4. **فعال‌سازی هر سرویس**: `enablePostalCodeToAddress`, `enableCardToSheba`, `enableAccountToSheba`
5. **تعیین کارمزد**: `postalCodeToAddressFee`, `cardToShebaFee`, `accountToShebaFee`
## نکات فنی
- تمام درخواست‌ها نیاز به احراز هویت دارند
- کارمزد از موجودی SMS کاربر کسر می‌شود
- نتایج در کش ذخیره می‌شوند تا از تکرار درخواست‌های مشابه جلوگیری شود
- تمام عملیات لاگ می‌شوند
## توسعه آینده
- تکمیل سرویس‌های تبدیل کارت و حساب به شبا
- اضافه کردن سرویس‌های جدید
- بهبود رابط کاربری
- اضافه کردن گزارش‌گیری

File diff suppressed because it is too large Load diff

View file

@ -59,6 +59,7 @@
</v-alert>
</div>
</v-alert>
</v-card-text>
<v-row>
<v-col cols="12" md="4">
@ -161,6 +162,18 @@
:disabled="loadingSwitches.archiveView"
></v-switch>
</v-list-item>
<v-list-item>
<v-switch
v-model="info.inquiry"
label="سرویس استعلام"
@change="savePerms('inquiry')"
hide-details
color="success"
density="comfortable"
:loading="loadingSwitches.inquiry"
:disabled="loadingSwitches.inquiry"
></v-switch>
</v-list-item>
</v-list>
</v-card-text>
</v-card>
@ -627,7 +640,6 @@
</v-card>
</v-col>
</v-row>
</v-card-text>
</v-card>
</v-container>
<v-snackbar
@ -706,7 +718,8 @@ export default {
plugCCAdmin: false,
plugHrmDocs: false,
plugGhestaManager: false,
plugTaxSettings: false
plugTaxSettings: false,
inquiry: false
};
axios.post('/api/business/get/user/permissions',