From 11caf42da804d89d6c99cc10fbb1f7aeded7b8b3 Mon Sep 17 00:00:00 2001 From: Babak Alizadeh Date: Mon, 4 Aug 2025 15:02:55 +0000 Subject: [PATCH] bug fix in cheque and add support person transactions sort by --- hesabixCore/src/Cog/PersonService.php | 82 ++++++++++++++++++++++++--- webUI/src/i18n/fa_lang.ts | 1 + webUI/src/views/acc/persons/card.vue | 2 + webUI/src/views/acc/persons/list.vue | 3 + webUI/src/views/acc/presell/list.vue | 16 +++--- 5 files changed, 89 insertions(+), 15 deletions(-) diff --git a/hesabixCore/src/Cog/PersonService.php b/hesabixCore/src/Cog/PersonService.php index 47a18b0..1d4c319 100644 --- a/hesabixCore/src/Cog/PersonService.php +++ b/hesabixCore/src/Cog/PersonService.php @@ -86,6 +86,7 @@ class PersonService $search = $params['search'] ?? ''; $types = $params['types'] ?? null; $transactionFilters = $params['transactionFilters'] ?? null; + $sortBy = $params['sortBy'] ?? null; $queryBuilder = $this->entityManager->getRepository(Person::class) ->createQueryBuilder('p') @@ -104,18 +105,66 @@ class PersonService ->setParameter('types', $types); } + // بررسی اینکه آیا سورت روی فیلدهای محاسبه‌شده است + $hasCalculatedSort = false; + $calculatedSortField = null; + $calculatedSortOrder = null; + if ($sortBy && is_array($sortBy) && !empty($sortBy)) { + foreach ($sortBy as $sort) { + if (isset($sort['key']) && in_array($sort['key'], ['bs', 'bd', 'balance'])) { + $hasCalculatedSort = true; + $calculatedSortField = $sort['key']; + $calculatedSortOrder = $sort['order']; + break; + } + } + } + + // اگر سورت روی فیلدهای محاسبه‌شده است، ابتدا همه داده‌ها را دریافت کن + if ($hasCalculatedSort) { + $persons = $queryBuilder + ->select('p') + ->getQuery() + ->getResult(); + } else { + // اعمال سورت کردن برای فیلدهای مستقیم + if ($sortBy && is_array($sortBy) && !empty($sortBy)) { + foreach ($sortBy as $sort) { + if (isset($sort['key']) && isset($sort['order'])) { + $field = $sort['key']; + $order = strtoupper($sort['order']); + + // بررسی فیلدهای مجاز برای سورت + $allowedFields = [ + 'code', 'nikename', 'name', 'birthday', 'company', + 'shenasemeli', 'codeeghtesadi', 'sabt', 'keshvar', + 'ostan', 'shahr', 'postalcode', 'tel', 'mobile', + 'mobile2', 'email', 'website', 'fax', 'speedAccess' + ]; + + if (in_array($field, $allowedFields)) { + $queryBuilder->addOrderBy("p.$field", $order); + } + } + } + } else { + // سورت پیش‌فرض بر اساس کد + $queryBuilder->orderBy('p.code', 'ASC'); + } + + $persons = $queryBuilder + ->select('p') + ->setFirstResult(($page - 1) * $itemsPerPage) + ->setMaxResults($itemsPerPage) + ->getQuery() + ->getResult(); + } + $totalItems = (clone $queryBuilder) ->select('COUNT(p.id)') ->getQuery() ->getSingleScalarResult(); - $persons = $queryBuilder - ->select('p') - ->setFirstResult(($page - 1) * $itemsPerPage) - ->setMaxResults($itemsPerPage) - ->getQuery() - ->getResult(); - $response = []; foreach ($persons as $person) { $rows = $this->entityManager->getRepository(HesabdariRow::class)->findBy([ @@ -158,10 +207,27 @@ class PersonService } } + // اگر سورت روی فیلدهای محاسبه‌شده است، اینجا سورت کن + if ($hasCalculatedSort && $calculatedSortField && $calculatedSortOrder) { + usort($response, function($a, $b) use ($calculatedSortField, $calculatedSortOrder) { + $aVal = $a[$calculatedSortField] ?? 0; + $bVal = $b[$calculatedSortField] ?? 0; + + if ($calculatedSortOrder === 'ASC') { + return $aVal <=> $bVal; + } else { + return $bVal <=> $aVal; + } + }); + + // اعمال صفحه‌بندی بعد از سورت + $response = array_slice($response, ($page - 1) * $itemsPerPage, $itemsPerPage); + } + $filteredTotal = count($response); return [ - 'items' => array_slice($response, 0, $itemsPerPage), + 'items' => $response, 'total' => $filteredTotal, 'unfilteredTotal' => $totalItems, ]; diff --git a/webUI/src/i18n/fa_lang.ts b/webUI/src/i18n/fa_lang.ts index a0c9253..af7e8ee 100755 --- a/webUI/src/i18n/fa_lang.ts +++ b/webUI/src/i18n/fa_lang.ts @@ -745,6 +745,7 @@ const fa_lang = { }, "person_card": { accounting_status: 'وضعیت حسابداری', + transfer_cheque: 'واگذاری چک', "title": "کارت حساب اشخاص", "account_card": "کارت حساب", "account_status": "وضعیت حساب", diff --git a/webUI/src/views/acc/persons/card.vue b/webUI/src/views/acc/persons/card.vue index 351e611..5d4c417 100755 --- a/webUI/src/views/acc/persons/card.vue +++ b/webUI/src/views/acc/persons/card.vue @@ -384,6 +384,7 @@ export default { modify_cheque: '/acc/accounting/view/', modify_cheque_output: '/acc/accounting/view/', pass_cheque: '/acc/accounting/view/', + transfer_cheque: '/acc/accounting/view/', }; return routes[type] + code; }, @@ -403,6 +404,7 @@ export default { modify_cheque: this.$t('pages.person_card.modify_cheque'), pass_cheque: this.$t('pages.person_card.pass_cheque'), modify_cheque_output: this.$t('pages.person_card.modify_cheque_output'), + transfer_cheque: this.$t('pages.person_card.transfer_cheque'), }; return labels[type] || type; }, diff --git a/webUI/src/views/acc/persons/list.vue b/webUI/src/views/acc/persons/list.vue index b3a7e9b..e5d4c41 100755 --- a/webUI/src/views/acc/persons/list.vue +++ b/webUI/src/views/acc/persons/list.vue @@ -307,10 +307,13 @@ const fetchData = async () => { const selectedTransactionFilters = transactionFilters.value .filter((filter) => filter.checked) .map((filter) => filter.value); + + // تبدیل سورت‌های Vuetify به فرمت مورد نیاز سرور const sortBy = serverOptions.value.sortBy.map((sort) => ({ key: sort.key, order: sort.order === 'asc' ? 'ASC' : 'DESC', })); + const response = await axios.post('/api/person/list', { page: serverOptions.value.page, itemsPerPage: serverOptions.value.rowsPerPage, diff --git a/webUI/src/views/acc/presell/list.vue b/webUI/src/views/acc/presell/list.vue index a5c59d9..8a215cc 100755 --- a/webUI/src/views/acc/presell/list.vue +++ b/webUI/src/views/acc/presell/list.vue @@ -121,7 +121,7 @@ @@ -187,10 +187,9 @@