diff --git a/hesabixCore/src/Controller/BusinessController.php b/hesabixCore/src/Controller/BusinessController.php index 400aebbc..3a31682b 100644 --- a/hesabixCore/src/Controller/BusinessController.php +++ b/hesabixCore/src/Controller/BusinessController.php @@ -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); diff --git a/hesabixCore/src/Controller/Plugins/inquiry/PlugInquiryMainController.php b/hesabixCore/src/Controller/Plugins/inquiry/PlugInquiryMainController.php index 575f9c02..2e6eccea 100644 --- a/hesabixCore/src/Controller/Plugins/inquiry/PlugInquiryMainController.php +++ b/hesabixCore/src/Controller/Plugins/inquiry/PlugInquiryMainController.php @@ -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 + ]); + } + } } \ No newline at end of file diff --git a/hesabixCore/src/Entity/AccountToShebaInquiry.php b/hesabixCore/src/Entity/AccountToShebaInquiry.php new file mode 100644 index 00000000..1e9667ac --- /dev/null +++ b/hesabixCore/src/Entity/AccountToShebaInquiry.php @@ -0,0 +1,63 @@ +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; + } +} \ No newline at end of file diff --git a/hesabixCore/src/Entity/CardToShebaInquiry.php b/hesabixCore/src/Entity/CardToShebaInquiry.php new file mode 100644 index 00000000..6c271407 --- /dev/null +++ b/hesabixCore/src/Entity/CardToShebaInquiry.php @@ -0,0 +1,63 @@ +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; + } +} \ No newline at end of file diff --git a/hesabixCore/src/Entity/Permission.php b/hesabixCore/src/Entity/Permission.php index 47aedd1b..1d0b4140 100644 --- a/hesabixCore/src/Entity/Permission.php +++ b/hesabixCore/src/Entity/Permission.php @@ -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; + } } diff --git a/hesabixCore/src/Repository/AccountToShebaInquiryRepository.php b/hesabixCore/src/Repository/AccountToShebaInquiryRepository.php new file mode 100644 index 00000000..45280bf4 --- /dev/null +++ b/hesabixCore/src/Repository/AccountToShebaInquiryRepository.php @@ -0,0 +1,46 @@ + + * + * @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(); + } + } +} \ No newline at end of file diff --git a/hesabixCore/src/Repository/CardToShebaInquiryRepository.php b/hesabixCore/src/Repository/CardToShebaInquiryRepository.php new file mode 100644 index 00000000..6a2dd388 --- /dev/null +++ b/hesabixCore/src/Repository/CardToShebaInquiryRepository.php @@ -0,0 +1,46 @@ + + * + * @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(); + } + } +} \ No newline at end of file diff --git a/hesabixCore/src/Service/Inquiry.php b/hesabixCore/src/Service/Inquiry.php index 2b5581c0..6fe3fc4b 100644 --- a/hesabixCore/src/Service/Inquiry.php +++ b/hesabixCore/src/Service/Inquiry.php @@ -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()); + } + } } diff --git a/webUI/src/views/acc/App.vue b/webUI/src/views/acc/App.vue index e98424f8..97c43214 100644 --- a/webUI/src/views/acc/App.vue +++ b/webUI/src/views/acc/App.vue @@ -791,8 +791,8 @@ export default { - - + + {{ $t('drawer.inquiry') }} {{ getShortcutKey('/acc/inquiry/panel') }} diff --git a/webUI/src/views/acc/inquiry/README.md b/webUI/src/views/acc/inquiry/README.md new file mode 100644 index 00000000..e161ce84 --- /dev/null +++ b/webUI/src/views/acc/inquiry/README.md @@ -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 کاربر کسر می‌شود +- نتایج در کش ذخیره می‌شوند تا از تکرار درخواست‌های مشابه جلوگیری شود +- تمام عملیات لاگ می‌شوند + +## توسعه آینده + +- تکمیل سرویس‌های تبدیل کارت و حساب به شبا +- اضافه کردن سرویس‌های جدید +- بهبود رابط کاربری +- اضافه کردن گزارش‌گیری \ No newline at end of file diff --git a/webUI/src/views/acc/inquiry/panel.vue b/webUI/src/views/acc/inquiry/panel.vue index 30cc2cc3..318b9243 100644 --- a/webUI/src/views/acc/inquiry/panel.vue +++ b/webUI/src/views/acc/inquiry/panel.vue @@ -1,24 +1,1166 @@ - diff --git a/webUI/src/views/acc/settings/user_perm_edit.vue b/webUI/src/views/acc/settings/user_perm_edit.vue index f54e41cc..97bd05b8 100644 --- a/webUI/src/views/acc/settings/user_perm_edit.vue +++ b/webUI/src/views/acc/settings/user_perm_edit.vue @@ -59,6 +59,7 @@ + @@ -161,6 +162,18 @@ :disabled="loadingSwitches.archiveView" > + + + @@ -627,7 +640,6 @@ -