diff --git a/hesabixCore/migrations/Version20241201000000.php b/hesabixCore/migrations/Version20241201000000.php new file mode 100644 index 00000000..dfaaa62b --- /dev/null +++ b/hesabixCore/migrations/Version20241201000000.php @@ -0,0 +1,37 @@ +addSql('CREATE TABLE postal_code_inquiry ( + id INT AUTO_INCREMENT NOT NULL, + postal_code VARCHAR(10) NOT NULL, + address_data JSON NOT NULL, + created_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', + updated_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', + UNIQUE INDEX UNIQ_POSTAL_CODE (postal_code), + PRIMARY KEY(id) + ) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); + } + + public function down(Schema $schema): void + { + $this->addSql('DROP TABLE postal_code_inquiry'); + } +} \ No newline at end of file diff --git a/hesabixCore/src/Controller/AdminController.php b/hesabixCore/src/Controller/AdminController.php index d6090104..230dab44 100644 --- a/hesabixCore/src/Controller/AdminController.php +++ b/hesabixCore/src/Controller/AdminController.php @@ -454,6 +454,7 @@ class AdminController extends AbstractController $resp['inquiryZohalAPIKey'] = $registryMGR->get('system', key: 'inquiryZohalAPIKey'); $resp['enablePostalCodeToAddress'] = $registryMGR->get('system', key: 'enablePostalCodeToAddress'); $resp['inquiryPanelEnable'] = $registryMGR->get('system', key: 'inquiryPanelEnable'); + $resp['postalCodeToAddressFee'] = $registryMGR->get('system', key: 'postalCodeToAddressFee'); return $this->json($resp); } @@ -482,6 +483,7 @@ class AdminController extends AbstractController $registryMGR->update('system', 'inquiryZohalAPIKey', $params['inquiryZohalAPIKey']); $registryMGR->update('system', 'enablePostalCodeToAddress', $params['enablePostalCodeToAddress']); $registryMGR->update('system', 'inquiryPanelEnable', $params['inquiryPanelEnable']); + $registryMGR->update('system', 'postalCodeToAddressFee', $params['postalCodeToAddressFee']); $entityManager->persist($item); $entityManager->flush(); return $this->json(['result' => 1]); diff --git a/hesabixCore/src/Controller/Plugins/inquiry/PlugInquiryMainController.php b/hesabixCore/src/Controller/Plugins/inquiry/PlugInquiryMainController.php index 15ebbc15..5d915a65 100644 --- a/hesabixCore/src/Controller/Plugins/inquiry/PlugInquiryMainController.php +++ b/hesabixCore/src/Controller/Plugins/inquiry/PlugInquiryMainController.php @@ -17,6 +17,8 @@ use App\Service\Printers; use App\Entity\PrintOptions; use App\Service\Log; use App\Entity\Business; +use App\Service\registryMGR; +use App\Service\Inquiry; class PlugInquiryMainController extends AbstractController { @@ -27,11 +29,105 @@ class PlugInquiryMainController extends AbstractController $this->entityManager = $entityManager; } - #[Route('/api/admin/plugins/inquiry/settings/get', name: 'plugin_inquiry_settings_get', methods: ['GET'])] - public function plugin_inquiry_settings_get(EntityManagerInterface $entityManager, Access $access) : JsonResponse + #[Route('/api/plugins/inquiry/settings/get', name: 'plugin_inquiry_settings_get', methods: ['GET'])] + public function plugin_inquiry_settings_get(registryMGR $registryMGR): JsonResponse { - - return $this->json([]); + + $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'); + 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'); + if (!$acc) { + return $this->json([ + 'success' => false, + 'message' => 'شما دسترسی به این سرویس را ندارید' + ]); + } + + // دریافت کد پستی از درخواست + $data = json_decode($request->getContent(), true); + $postalCode = $data['postal_code'] ?? null; + if (!$postalCode) { + return $this->json([ + 'success' => false, + 'message' => 'کد پستی ارسال نشده است' + ]); + } + + // فراخوانی سرویس استعلام کد پستی + $result = $inquiry->postalCodeToAddress($postalCode); + + // بررسی نتیجه و بازگرداندن پاسخ مناسب + if (isset($result['result']) && $result['result'] == 1) { + $isFromCache = isset($result['response_body']['message']) && + strpos($result['response_body']['message'], 'از کش') !== false; + + // ثبت لاگ بر اساس منبع داده + $logMessage = $isFromCache + ? "استعلام کد پستی {$postalCode} از کش (بدون کسر کارمزد)" + : "استعلام کد پستی {$postalCode} از API (کسر کارمزد: " . $registryMGR->get('system', key: 'postalCodeToAddressFee') . " ریال)"; + + $log->insert( + 'استعلام', + $logMessage, + $acc['user'], + $acc['bid'] + ); + + // فقط در صورت عدم وجود در کش، کارمزد کسر شود + if (!$isFromCache) { + if ($acc['bid']->getSmsCharge() < $registryMGR->get('system', key: 'postalCodeToAddressFee')) { + // ثبت لاگ عدم موجودی کافی + $log->insert( + 'استعلام', + "عدم موجودی کافی برای استعلام کد پستی {$postalCode}", + $acc['user'], + $acc['bid'] + ); + + return $this->json([ + 'success' => false, + 'message' => 'موجودی شما برای این سرویس کافی نیست' + ]); + } + + $business = $acc['bid']; + $business->setSmsCharge($business->getSmsCharge() - $registryMGR->get('system', key: 'postalCodeToAddressFee')); + $this->entityManager->persist($business); + $this->entityManager->flush(); + } + + return $this->json([ + 'success' => true, + 'data' => $result['response_body']['data']['address'] ?? null, + 'message' => $result['response_body']['message'] ?? 'موفق', + 'from_cache' => $isFromCache + ]); + } else { + // ثبت لاگ خطا + $errorMessage = $result['message'] ?? 'خطا در استعلام کد پستی'; + $log->insert( + 'استعلام', + "خطا در استعلام کد پستی {$postalCode}: {$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/PostalCodeInquiry.php b/hesabixCore/src/Entity/PostalCodeInquiry.php new file mode 100644 index 00000000..f4ab52d5 --- /dev/null +++ b/hesabixCore/src/Entity/PostalCodeInquiry.php @@ -0,0 +1,83 @@ +createdAt = new \DateTimeImmutable(); + $this->updatedAt = new \DateTimeImmutable(); + } + + public function getId(): ?int + { + return $this->id; + } + + public function getPostalCode(): ?string + { + return $this->postalCode; + } + + public function setPostalCode(string $postalCode): static + { + $this->postalCode = $postalCode; + return $this; + } + + public function getAddressData(): array + { + return $this->addressData; + } + + public function setAddressData(array $addressData): static + { + $this->addressData = $addressData; + return $this; + } + + public function getCreatedAt(): ?\DateTimeImmutable + { + return $this->createdAt; + } + + public function setCreatedAt(\DateTimeImmutable $createdAt): static + { + $this->createdAt = $createdAt; + 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/Repository/PostalCodeInquiryRepository.php b/hesabixCore/src/Repository/PostalCodeInquiryRepository.php new file mode 100644 index 00000000..bf550641 --- /dev/null +++ b/hesabixCore/src/Repository/PostalCodeInquiryRepository.php @@ -0,0 +1,46 @@ + + * + * @method PostalCodeInquiry|null find($id, $lockMode = null, $lockVersion = null) + * @method PostalCodeInquiry|null findOneBy(array $criteria, array $orderBy = null) + * @method PostalCodeInquiry[] findAll() + * @method PostalCodeInquiry[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) + */ +class PostalCodeInquiryRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, PostalCodeInquiry::class); + } + + public function findByPostalCode(string $postalCode): ?PostalCodeInquiry + { + return $this->findOneBy(['postalCode' => $postalCode]); + } + + public function save(PostalCodeInquiry $entity, bool $flush = false): void + { + $this->getEntityManager()->persist($entity); + + if ($flush) { + $this->getEntityManager()->flush(); + } + } + + public function remove(PostalCodeInquiry $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 new file mode 100644 index 00000000..2b5581c0 --- /dev/null +++ b/hesabixCore/src/Service/Inquiry.php @@ -0,0 +1,158 @@ +entityManager->getRepository(PostalCodeInquiry::class)->findByPostalCode($postalCode); + + if ($existingInquiry) { + // اگر در دیتابیس موجود است، از آن استفاده کن + $addressData = $existingInquiry->getAddressData(); + return [ + 'result' => 1, + 'response_body' => [ + 'data' => [ + 'address' => $addressData + ], + '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/postal_code_inquiry"; + + // آمادهسازی دادههای JSON + $postData = json_encode([ + 'postal_code' => $postalCode + ]); + + // تنظیمات 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']['address'])) { + $this->saveToDatabase($postalCode, $data['response_body']['data']['address']); + } + 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 { + $inquiry = new PostalCodeInquiry(); + $inquiry->setPostalCode($postalCode); + $inquiry->setAddressData($addressData); + $inquiry->setUpdatedAt(new \DateTimeImmutable()); + + $this->entityManager->persist($inquiry); + $this->entityManager->flush(); + + // ثبت لاگ ذخیره موفق در دیتابیس + error_log("کد پستی {$postalCode} با موفقیت در کش ذخیره شد"); + } catch (\Exception $e) { + // در صورت خطا در ذخیره، فقط لاگ کن و ادامه بده + error_log('خطا در ذخیره استعلام کد پستی: ' . $e->getMessage()); + } + } +} diff --git a/webUI/src/components/widgets/inquiry/postalcode2address.vue b/webUI/src/components/widgets/inquiry/postalcode2address.vue new file mode 100644 index 00000000..402042ee --- /dev/null +++ b/webUI/src/components/widgets/inquiry/postalcode2address.vue @@ -0,0 +1,188 @@ + + + + + + + + + mdi-map-marker + + + + + + + + تبدیل کد پستی به آدرس + + + mdi-close + + + + + + + با استفاده از این سرویس میتوانید کد پستی را به آدرس کامل تبدیل کنید. + + + + + + mdi-information + + + کارمزد سرویس: {{ settings.postalCodeToAddressFee.toLocaleString() }} ریال + + + 💡 اگر این کد پستی قبلاً استعلام شده باشد، کارمزدی کسر نمیشود + + + + + + + + تبدیل به آدرس + + + + + {{ error }} + + + + + + diff --git a/webUI/src/i18n/fa_lang.ts b/webUI/src/i18n/fa_lang.ts index 22355e82..07db4548 100644 --- a/webUI/src/i18n/fa_lang.ts +++ b/webUI/src/i18n/fa_lang.ts @@ -817,6 +817,7 @@ const fa_lang = { inquiry_zohal_api_key_placeholder: "کلید API زحل", inquiry_zohal_api_key_label: "کلید API زحل", enable_postalcode_to_address: "تبدیل کد پستی به آدرس", + postalcode_to_address_fee: "کارمزد تبدیل کد پستی به آدرس", inquiry_panel_enable: "فعال سازی پنل سامانه استعلامات", inquiry_panel: "پنل سامانه استعلامات", inquiry_panel_zohal: "زحل", diff --git a/webUI/src/views/acc/persons/insert.vue b/webUI/src/views/acc/persons/insert.vue index a6e71ce2..f55fdbc4 100644 --- a/webUI/src/views/acc/persons/insert.vue +++ b/webUI/src/views/acc/persons/insert.vue @@ -141,7 +141,11 @@ + prepend-inner-icon="mdi-mailbox" hide-details> + + + + + + + + {{ snackbar.text }} + + + بستن + + + diff --git a/webUI/src/views/user/manager/settings/system.vue b/webUI/src/views/user/manager/settings/system.vue index f5bca66c..9b9bd296 100644 --- a/webUI/src/views/user/manager/settings/system.vue +++ b/webUI/src/views/user/manager/settings/system.vue @@ -49,6 +49,7 @@ export default defineComponent({ inquiryZohalAPIKey: '', enablePostalCodeToAddress: false, inquiryPanelEnable: false, + postalCodeToAddressFee: 0, }, loading: true, } @@ -152,7 +153,7 @@ export default defineComponent({ - + - + + +
+ با استفاده از این سرویس میتوانید کد پستی را به آدرس کامل تبدیل کنید. +