From ae3d4277400dde889155d6ccb326b333cd73be8f Mon Sep 17 00:00:00 2001 From: Babak Alizadeh Date: Sat, 22 Mar 2025 12:25:28 +0000 Subject: [PATCH] bug fix in pay invoices --- .../src/Controller/Front/PayController.php | 6 +- .../Controller/Front/ShortlinksController.php | 8 +- .../Controller/Front/UiGeneralController.php | 7 +- .../templates/shortlinks/sell.html.twig | 2 +- webUI/index.html | 2 +- webUI/public/manifest.json | 2 +- webUI/src/hesabixConfig.js | 107 ++++++++++++------ webUI/src/i18n/fa_lang.ts | 8 +- webUI/src/router/index.ts | 2 +- webUI/src/views/acc/App.vue | 19 +++- webUI/src/views/user/InstallPWA.vue | 2 +- .../src/views/user/profile/business/list.vue | 24 +++- webUI/src/views/user/profile/profile-main.vue | 22 ++-- webUI/src/views/user/profile/support/list.vue | 2 +- 14 files changed, 142 insertions(+), 71 deletions(-) diff --git a/hesabixCore/src/Controller/Front/PayController.php b/hesabixCore/src/Controller/Front/PayController.php index 497fd80..3380886 100644 --- a/hesabixCore/src/Controller/Front/PayController.php +++ b/hesabixCore/src/Controller/Front/PayController.php @@ -28,7 +28,7 @@ class PayController extends AbstractController #[Route('/pay/sell/{id}', name: 'pay_sell')] public function pay_sell(string $id, PayMGR $payMGR, twigFunctions $twigFunctions, EntityManagerInterface $entityManager, Log $log): Response { - $doc = $entityManager->getRepository(HesabdariDoc::class)->find($id); + $doc = $entityManager->getRepository(HesabdariDoc::class)->findOneBy(['shortlink'=>$id]); if (!$doc) throw $this->createNotFoundException(); @@ -49,7 +49,7 @@ class PayController extends AbstractController $tempPay->setDoc($doc); $entityManager->persist($tempPay); $entityManager->flush(); - $result = $payMGR->createRequest($amountPay, $this->generateUrl('pay_sell_verify', ["id" => $doc->getId()], UrlGeneratorInterface::ABSOLUTE_URL), 'پرداخت فاکتور شماره ' . $doc->getCode() . ' کسب و کار ' . $doc->getBid()->getLegalName()); + $result = $payMGR->createRequest($amountPay, $this->generateUrl('pay_sell_verify', ["id" => $tempPay->getId()], UrlGeneratorInterface::ABSOLUTE_URL), 'پرداخت فاکتور شماره ' . $doc->getCode() . ' کسب و کار ' . $doc->getBid()->getLegalName()); if ($result['Success']) { $tempPay->setGatePay($result['gate']); $tempPay->setVerifyCode($result['authkey']); @@ -77,7 +77,7 @@ class PayController extends AbstractController $res = $payMGR->verify($req->getPrice(), $req->getVerifyCode(), $request); if ($res['Success'] == false) { $log->insert('کیف پول', 'خطا در پرداخت فاکتور فروش ' . $doc->getCode(), $this->getUser(), $doc->getBid()); - return $this->redirectToRoute('shortlinks_show', ['type' => 'sell', 'bid' => $doc->getBid()->getId(), 'link' => $doc->getId(), 'msg' => 'fail']); + return $this->redirectToRoute('shortlinks_show', ['type' => 'sell', 'bid' => $doc->getBid()->getId(), 'link' => $doc->getShortlink(), 'msg' => 'fail']); } else { $req->setStatus(100); $req->setRefID($res['refID']); diff --git a/hesabixCore/src/Controller/Front/ShortlinksController.php b/hesabixCore/src/Controller/Front/ShortlinksController.php index 6ee8942..a4ec2cf 100644 --- a/hesabixCore/src/Controller/Front/ShortlinksController.php +++ b/hesabixCore/src/Controller/Front/ShortlinksController.php @@ -59,13 +59,7 @@ class ShortlinksController extends AbstractController 'bid' => $bus ]); if (!$doc) { - $doc = $entityManager->getRepository(HesabdariDoc::class)->findOneBy([ - 'type' => 'sell', - 'id' => $link, - 'bid' => $bus - ]); - if (!$doc) - throw $this->createNotFoundException(); + throw $this->createNotFoundException(); } $rows = $entityManager->getRepository(HesabdariRow::class)->findBy(['doc' => $doc]); diff --git a/hesabixCore/src/Controller/Front/UiGeneralController.php b/hesabixCore/src/Controller/Front/UiGeneralController.php index 968930b..a76dce7 100644 --- a/hesabixCore/src/Controller/Front/UiGeneralController.php +++ b/hesabixCore/src/Controller/Front/UiGeneralController.php @@ -22,7 +22,12 @@ class UiGeneralController extends AbstractController $name = $registryManager->get('system', 'appName'); return $this->json($name); } - + #[Route('/system/getslogon', name: 'general_get_slogon')] + public function general_get_slogon(registryMGR $registryManager): JsonResponse + { + $name = $registryManager->get('system', 'appSlogon'); + return $this->json($name); + } #[Route('/system/geturl', name: 'general_get_url')] public function general_get_url(registryMGR $registryManager): JsonResponse { diff --git a/hesabixCore/templates/shortlinks/sell.html.twig b/hesabixCore/templates/shortlinks/sell.html.twig index 154a060..e748f64 100644 --- a/hesabixCore/templates/shortlinks/sell.html.twig +++ b/hesabixCore/templates/shortlinks/sell.html.twig @@ -39,7 +39,7 @@ چاپ فاکتور {% if (totalPays < doc.amount) and bid.walletEnable and doc.money.name == 'IRR' %} - + پرداخت آنلاین مبلغ {{ (doc.amount - totalPays) | number_format }} diff --git a/webUI/index.html b/webUI/index.html index 7af9476..0a162be 100644 --- a/webUI/index.html +++ b/webUI/index.html @@ -10,7 +10,7 @@ حسابداری آنلاین - + diff --git a/webUI/public/manifest.json b/webUI/public/manifest.json index 5febf5d..9a2b359 100644 --- a/webUI/public/manifest.json +++ b/webUI/public/manifest.json @@ -6,7 +6,7 @@ "related_applications": [ { "platform": "webapp", - "url": "/u/manifest.json" + "url": "/manifest.json" } ], "display": "standalone", diff --git a/webUI/src/hesabixConfig.js b/webUI/src/hesabixConfig.js index 86511f2..20227bf 100644 --- a/webUI/src/hesabixConfig.js +++ b/webUI/src/hesabixConfig.js @@ -1,52 +1,91 @@ import axios from 'axios'; +// ثابت‌ها +const KEYS = { + DEV_API_URL: 'dev_api_url', + DEV_ALERT_SHOWN: 'dev_mode_alert_shown', + SITE_NAME: 'hesabix_site_name', + SITE_SLOGON: 'hesabix_site_slogon' +}; + +const DEFAULTS = { + SITE_NAME: 'حسابیکس', + SITE_SLOGON: 'حسابیکس سامانه جامع مدیریت کسب‌و‌کار' +}; + export const name = "hesabixConfig"; +// کش برای API URL +let cachedApiUrl = null; + export function getApiUrl() { - const origin = window.location.origin; // دامنه اصلی مثل http://localhost.com - const path = window.location.pathname; // مسیر فعلی مثل /app/etc/u + if (cachedApiUrl) return cachedApiUrl; - // مسیر رو به آرایه تبدیل می‌کنم تا بتونم پوشه‌ها رو جدا کنم - const pathParts = path.split('/').filter(part => part !== ''); // ['app', 'etc', 'u'] + const devApiUrl = localStorage.getItem(KEYS.DEV_API_URL); + const alertShown = localStorage.getItem(KEYS.DEV_ALERT_SHOWN); - // پیدا کردن جایگاه u و حذفش به همراه هر چی بعدش هست - const uIndex = pathParts.indexOf('u'); - if (uIndex !== -1) { - // فقط مسیر تا قبل از u رو نگه می‌دارم - const basePath = pathParts.slice(0, uIndex).join('/'); // app/etc - if (basePath === '') { - return `${origin}`; + if (devApiUrl) { + if (!alertShown) { + alert(`شما در حالت توسعه هستید و به آدرس زیر متصل می‌شوید:\n${devApiUrl}`); + localStorage.setItem(KEYS.DEV_ALERT_SHOWN, 'true'); } - return `${origin}/${basePath}`; // http://localhost.com/app/etc + cachedApiUrl = devApiUrl; + return devApiUrl; } - // اگه u توی مسیر نبود، مسیر روت رو برگشت بده - return `${origin}`; + const origin = window.location.origin; + const pathParts = window.location.pathname.split('/').filter(part => part !== ''); + const uIndex = pathParts.indexOf('u'); + + if (uIndex !== -1) { + const basePath = pathParts.slice(0, uIndex).join('/'); + cachedApiUrl = basePath ? `${origin}/${basePath}` : origin; + } else { + cachedApiUrl = origin; + } + + return cachedApiUrl; +} + +// تابع کمکی برای گرفتن داده از سرور و کش کردن +async function fetchAndCache(url, localStorageKey, defaultValue) { + const storedValue = localStorage.getItem(localStorageKey); + if (storedValue) return storedValue; + + try { + const response = await axios.get(url); + if (response.status === 200) { + const data = response.data; + localStorage.setItem(localStorageKey, data); + return data; + } + throw new Error('پاسخ نامعتبر از سرور'); + } catch (error) { + console.error(`خطا در گرفتن داده از ${url}:`, error); + return defaultValue; + } } export async function getSiteName() { - // کلید ذخیره‌سازی در localStorage - const localStorageKey = 'hesabix_site_name'; + return fetchAndCache( + `${getApiUrl()}/system/getname`, + KEYS.SITE_NAME, + DEFAULTS.SITE_NAME + ); +} - // چک کن که آیا نام برنامه توی localStorage هست یا نه - const storedName = localStorage.getItem(localStorageKey); - if (storedName) { - return storedName; // اگه بود، همون رو برگشت بده - } +export async function getSiteSlogon() { + return fetchAndCache( + `${getApiUrl()}/system/getslogon`, + KEYS.SITE_SLOGON, + DEFAULTS.SITE_SLOGON + ); +} - try { - // اگه نبود، درخواست به سمفونی ارسال کن - const response = await axios.get(`${getApiUrl()}/system/getname`); - const siteName = response.data; // فرض می‌کنم سمفونی نام رو مستقیم برمی‌گردونه - - // ذخیره توی localStorage - localStorage.setItem(localStorageKey, siteName); - return siteName; - } catch (error) { - console.error('خطا در گرفتن نام برنامه از سرور:', error); - // اگه خطایی بود، یه مقدار پیش‌فرض برگشت بده - return 'حسابیکس'; - } +export function getBasePath() { + const fullPath = window.location.pathname; + const uIndex = fullPath.indexOf('/u'); + return uIndex !== -1 ? fullPath.substring(0, uIndex + '/u'.length) + '/' : '/u/'; } export function getVersionCheckerUrl() { diff --git a/webUI/src/i18n/fa_lang.ts b/webUI/src/i18n/fa_lang.ts index 768178b..243854e 100644 --- a/webUI/src/i18n/fa_lang.ts +++ b/webUI/src/i18n/fa_lang.ts @@ -443,8 +443,8 @@ const fa_lang = { name: "نام و نام خانوادگی", name_des: "مثلا علی باقری", password_register_des: "کلمه عبور باید بیشتر از ۱۰ کاراکتر و ترکیبی از اعداد و حروف باشد", - login_label: "ورود به حسابیکس", - register_label: "عضویت در حسابیکس", + login_label: "ورود", + register_label: "عضویت", login: "ورود", email_placeholder: "پست الکترونیکی خود را وارد کنید", email: "پست الکترونیکی", @@ -476,7 +476,7 @@ const fa_lang = { history: "تاریخچه", send_code_forget_password: "ارسال کد بازیابی", number_edited: "شماره تلفن با موفقیت تغییر یافت . کد فعال سازی جدید به شماره شما ارسال شد", - register_terms_des: "عضویت در حسابیکس به معنای قبول شرایط و مقررات استفاده از آن است.برای مشاهده متن توافقنامه به صفحه نخست مراجعه نمایید", + register_terms_des: "عضویت به معنای قبول شرایط و مقررات استفاده از آن است.برای مشاهده متن توافقنامه به صفحه نخست مراجعه نمایید", "referral_link": "لینک دعوت از دیگران", "link_copied": "لینک با موفقیت کپی شد!", "referral_not_available": "لینک عضویت در دسترس نیست", @@ -498,7 +498,7 @@ const fa_lang = { } }, login: { - des: "برای ورود به حسابیکس شماره تلفن و کلمه عبور خود را وارد کنید.در صورتی که هنوز عضو نیستید با کلیک بر روی دکمه عضویت و برای بازیابی کلمه عبور از دکمه فراموشی کلمه عبور استفاده نمایید.", + des: "برای ورود شماره تلفن و کلمه عبور خود را وارد کنید.در صورتی که هنوز عضو نیستید با کلیک بر روی دکمه عضویت و برای بازیابی کلمه عبور از دکمه فراموشی کلمه عبور استفاده نمایید.", input_fail: "شماره تلفن یا کلمه عبور اشتباه است" }, validator: { diff --git a/webUI/src/router/index.ts b/webUI/src/router/index.ts index a6da6d1..173f376 100644 --- a/webUI/src/router/index.ts +++ b/webUI/src/router/index.ts @@ -942,7 +942,7 @@ const router = createRouter({ name: 'install_pwa', component: () => import('../views/user/InstallPWA.vue'), meta: { - 'title': 'نصب وب اپلیکیشن حسابیکس', + 'title': 'نصب وب اپلیکیشن ', } }, { diff --git a/webUI/src/views/acc/App.vue b/webUI/src/views/acc/App.vue index 45a075b..29ad0ec 100644 --- a/webUI/src/views/acc/App.vue +++ b/webUI/src/views/acc/App.vue @@ -2,7 +2,7 @@ import { RouterLink, RouterView } from 'vue-router'; import axios from "axios"; import Swal from "sweetalert2"; -import { getApiUrl, getSiteName } from "@/hesabixConfig"; +import { getApiUrl, getBasePath, getSiteName } from "@/hesabixConfig"; import { ref } from 'vue'; import Profile_btn from '@/components/application/buttons/profile_btn.vue'; import Notifications_btn from '@/components/application/buttons/notifications_btn.vue'; @@ -18,6 +18,8 @@ export default { business: { id: '', name: '' }, timeNow: '', apiUrl: '', + siteName: '', + siteSlogon: '', permissions: {}, showShortcutsDialog: false, isEditingShortcuts: false, @@ -63,14 +65,18 @@ export default { window.addEventListener('keydown', this.handleKeyDown); window.addEventListener('keyup', this.handleKeyUp); }, - created() { - this.siteName = getSiteName(); + async created() { + this.siteName = await getSiteName(); + this.siteSlogon = await getSiteSlogon(); }, beforeUnmount() { window.removeEventListener('keydown', this.handleKeyDown); window.removeEventListener('keyup', this.handleKeyUp); }, methods: { + getbase() { + return getBasePath(); + }, deleteBusiness() { Swal.fire({ text: 'آیا برای حذف این کسب‌و‌کار مطمئن هستید؟ بعد از تایید این عملیات کسب و کار شما به مدت یک ماه در پایگاه داده آرشیو و بعد از آن به صورت دائم حذف خواهد شد', @@ -282,7 +288,7 @@ export default {