bug fix in persons s/r
This commit is contained in:
parent
63472c1d13
commit
290b272872
|
@ -897,10 +897,14 @@ class PersonsController extends AbstractController
|
||||||
$queryBuilder->orderBy('d.des', $sortDirection);
|
$queryBuilder->orderBy('d.des', $sortDirection);
|
||||||
break;
|
break;
|
||||||
case 'persons':
|
case 'persons':
|
||||||
|
// برای سورت بر اساس اشخاص
|
||||||
|
if (empty($search)) {
|
||||||
$queryBuilder->leftJoin('d.hesabdariRows', 'hr_person')
|
$queryBuilder->leftJoin('d.hesabdariRows', 'hr_person')
|
||||||
->leftJoin('hr_person.person', 'p')
|
->leftJoin('hr_person.person', 'p');
|
||||||
->groupBy('d.id, d.date, d.code, d.des, d.amount, p.nikename')
|
}
|
||||||
->orderBy('p.nikename', $sortDirection);
|
// استفاده از MIN برای جلوگیری از مشکل GROUP BY
|
||||||
|
$queryBuilder->groupBy('d.id, d.date, d.code, d.des, d.amount')
|
||||||
|
->orderBy('MIN(p.nikename)', $sortDirection);
|
||||||
break;
|
break;
|
||||||
case 'accounts':
|
case 'accounts':
|
||||||
// سورت بر اساس طرف حسابها (بانک، صندوق، تنخواه)
|
// سورت بر اساس طرف حسابها (بانک، صندوق، تنخواه)
|
||||||
|
@ -908,8 +912,8 @@ class PersonsController extends AbstractController
|
||||||
->leftJoin('hr_account.bank', 'ba')
|
->leftJoin('hr_account.bank', 'ba')
|
||||||
->leftJoin('hr_account.cashdesk', 'cd')
|
->leftJoin('hr_account.cashdesk', 'cd')
|
||||||
->leftJoin('hr_account.salary', 's')
|
->leftJoin('hr_account.salary', 's')
|
||||||
->groupBy('d.id, d.date, d.code, d.des, d.amount, ba.name, cd.name, s.name')
|
->groupBy('d.id, d.date, d.code, d.des, d.amount')
|
||||||
->orderBy('COALESCE(ba.name, cd.name, s.name)', $sortDirection);
|
->orderBy('CASE WHEN ba.name IS NOT NULL THEN ba.name WHEN cd.name IS NOT NULL THEN cd.name WHEN s.name IS NOT NULL THEN s.name ELSE \'\' END', $sortDirection);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$queryBuilder->orderBy('d.id', 'DESC');
|
$queryBuilder->orderBy('d.id', 'DESC');
|
||||||
|
@ -923,8 +927,67 @@ class PersonsController extends AbstractController
|
||||||
->setParameter('ids', $ids);
|
->setParameter('ids', $ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
// دریافت تعداد کل رکوردها
|
// دریافت تعداد کل رکوردها - ایجاد کوئری جدید بدون GROUP BY
|
||||||
$totalItems = $queryBuilder->select('COUNT(d.id)')
|
$totalQueryBuilder = $entityManager->getRepository(HesabdariDoc::class)->createQueryBuilder('d')
|
||||||
|
->where('d.bid = :bid')
|
||||||
|
->andWhere('d.type = :type')
|
||||||
|
->andWhere('d.year = :year')
|
||||||
|
->andWhere('d.money = :money')
|
||||||
|
->setParameter('bid', $acc['bid'])
|
||||||
|
->setParameter('type', 'person_receive')
|
||||||
|
->setParameter('year', $acc['year'])
|
||||||
|
->setParameter('money', $acc['money']);
|
||||||
|
|
||||||
|
// اعمال فیلترهای جستوجو و تاریخ
|
||||||
|
if (isset($params['search']) && !empty($params['search'])) {
|
||||||
|
$totalQueryBuilder->leftJoin('d.hesabdariRows', 'hr')
|
||||||
|
->leftJoin('hr.person', 'p')
|
||||||
|
->andWhere(
|
||||||
|
$totalQueryBuilder->expr()->orX(
|
||||||
|
'd.code LIKE :search',
|
||||||
|
'd.des LIKE :search',
|
||||||
|
'p.nikename LIKE :search'
|
||||||
|
)
|
||||||
|
)->setParameter('search', "%{$params['search']}%");
|
||||||
|
}
|
||||||
|
|
||||||
|
// فیلتر تاریخ
|
||||||
|
if (isset($params['dateFilter']) && $params['dateFilter'] !== 'all') {
|
||||||
|
$today = $jdate->GetTodayDate();
|
||||||
|
switch ($params['dateFilter']) {
|
||||||
|
case 'today':
|
||||||
|
$totalQueryBuilder->andWhere('d.date = :today')
|
||||||
|
->setParameter('today', $today);
|
||||||
|
break;
|
||||||
|
case 'thisWeek':
|
||||||
|
$dayOfWeek = (int) $jdate->jdate('w', time());
|
||||||
|
$startOfWeek = $jdate->shamsiDate(0, 0, -$dayOfWeek);
|
||||||
|
$endOfWeek = $jdate->shamsiDate(0, 0, 6 - $dayOfWeek);
|
||||||
|
$totalQueryBuilder->andWhere('d.date BETWEEN :start AND :end')
|
||||||
|
->setParameter('start', $startOfWeek)
|
||||||
|
->setParameter('end', $endOfWeek);
|
||||||
|
break;
|
||||||
|
case 'thisMonth':
|
||||||
|
$currentYear = (int) $jdate->jdate('Y', time());
|
||||||
|
$currentMonth = (int) $jdate->jdate('n', time());
|
||||||
|
$daysInMonth = (int) $jdate->jdate('t', time());
|
||||||
|
$startOfMonth = sprintf('%d/%02d/01', $currentYear, $currentMonth);
|
||||||
|
$endOfMonth = sprintf('%d/%02d/%02d', $currentYear, $currentMonth, $daysInMonth);
|
||||||
|
$totalQueryBuilder->andWhere('d.date BETWEEN :start AND :end')
|
||||||
|
->setParameter('start', $startOfMonth)
|
||||||
|
->setParameter('end', $endOfMonth);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// اگر آیتمهای خاصی درخواست شدهاند
|
||||||
|
if (array_key_exists('items', $params)) {
|
||||||
|
$ids = array_map(function($item) { return $item['id']; }, $params['items']);
|
||||||
|
$totalQueryBuilder->andWhere('d.id IN (:ids)')
|
||||||
|
->setParameter('ids', $ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
$totalItems = (int) $totalQueryBuilder->select('COUNT(d.id)')
|
||||||
->getQuery()
|
->getQuery()
|
||||||
->getSingleScalarResult();
|
->getSingleScalarResult();
|
||||||
|
|
||||||
|
@ -1089,6 +1152,60 @@ class PersonsController extends AbstractController
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// محاسبه تعداد کل قبل از اعمال GROUP BY
|
||||||
|
$totalQueryBuilder = $entityManager->getRepository(HesabdariDoc::class)->createQueryBuilder('d')
|
||||||
|
->where('d.bid = :bid')
|
||||||
|
->andWhere('d.type = :type')
|
||||||
|
->andWhere('d.year = :year')
|
||||||
|
->andWhere('d.money = :money')
|
||||||
|
->setParameter('bid', $acc['bid'])
|
||||||
|
->setParameter('type', 'person_receive')
|
||||||
|
->setParameter('year', $acc['year'])
|
||||||
|
->setParameter('money', $acc['money']);
|
||||||
|
|
||||||
|
// اعمال فیلترهای جستوجو و تاریخ برای کوئری تعداد
|
||||||
|
if (!empty($search)) {
|
||||||
|
$totalQueryBuilder->leftJoin('d.hesabdariRows', 'hr')
|
||||||
|
->leftJoin('hr.person', 'p')
|
||||||
|
->andWhere(
|
||||||
|
$totalQueryBuilder->expr()->orX(
|
||||||
|
'd.code LIKE :search',
|
||||||
|
'd.des LIKE :search',
|
||||||
|
'p.nikename LIKE :search'
|
||||||
|
)
|
||||||
|
)->setParameter('search', "%$search%");
|
||||||
|
}
|
||||||
|
|
||||||
|
// فیلتر تاریخ برای کوئری تعداد
|
||||||
|
switch ($dateFilter) {
|
||||||
|
case 'today':
|
||||||
|
$totalQueryBuilder->andWhere('d.date = :today')
|
||||||
|
->setParameter('today', $today);
|
||||||
|
break;
|
||||||
|
case 'thisWeek':
|
||||||
|
$dayOfWeek = (int) $jdate->jdate('w', time());
|
||||||
|
$startOfWeek = $jdate->shamsiDate(0, 0, -$dayOfWeek);
|
||||||
|
$endOfWeek = $jdate->shamsiDate(0, 0, 6 - $dayOfWeek);
|
||||||
|
$totalQueryBuilder->andWhere('d.date BETWEEN :start AND :end')
|
||||||
|
->setParameter('start', $startOfWeek)
|
||||||
|
->setParameter('end', $endOfWeek);
|
||||||
|
break;
|
||||||
|
case 'thisMonth':
|
||||||
|
$currentYear = (int) $jdate->jdate('Y', time());
|
||||||
|
$currentMonth = (int) $jdate->jdate('n', time());
|
||||||
|
$daysInMonth = (int) $jdate->jdate('t', time());
|
||||||
|
$startOfMonth = sprintf('%d/%02d/01', $currentYear, $currentMonth);
|
||||||
|
$endOfMonth = sprintf('%d/%02d/%02d', $currentYear, $currentMonth, $daysInMonth);
|
||||||
|
$totalQueryBuilder->andWhere('d.date BETWEEN :start AND :end')
|
||||||
|
->setParameter('start', $startOfMonth)
|
||||||
|
->setParameter('end', $endOfMonth);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$total = (int) $totalQueryBuilder->select('COUNT(d.id)')
|
||||||
|
->getQuery()
|
||||||
|
->getSingleScalarResult();
|
||||||
|
|
||||||
// اعمال سورت
|
// اعمال سورت
|
||||||
$sortDirection = $sortDesc ? 'DESC' : 'ASC';
|
$sortDirection = $sortDesc ? 'DESC' : 'ASC';
|
||||||
switch ($sortBy) {
|
switch ($sortBy) {
|
||||||
|
@ -1106,10 +1223,14 @@ class PersonsController extends AbstractController
|
||||||
$queryBuilder->orderBy('d.des', $sortDirection);
|
$queryBuilder->orderBy('d.des', $sortDirection);
|
||||||
break;
|
break;
|
||||||
case 'persons':
|
case 'persons':
|
||||||
|
// برای سورت بر اساس اشخاص
|
||||||
|
if (empty($search)) {
|
||||||
$queryBuilder->leftJoin('d.hesabdariRows', 'hr_person')
|
$queryBuilder->leftJoin('d.hesabdariRows', 'hr_person')
|
||||||
->leftJoin('hr_person.person', 'p')
|
->leftJoin('hr_person.person', 'p');
|
||||||
->groupBy('d.id, d.date, d.code, d.des, d.amount, p.nikename')
|
}
|
||||||
->orderBy('p.nikename', $sortDirection);
|
// استفاده از MIN برای جلوگیری از مشکل GROUP BY
|
||||||
|
$queryBuilder->groupBy('d.id, d.date, d.code, d.des, d.amount')
|
||||||
|
->orderBy('MIN(p.nikename)', $sortDirection);
|
||||||
break;
|
break;
|
||||||
case 'accounts':
|
case 'accounts':
|
||||||
// سورت بر اساس طرف حسابها (بانک، صندوق، تنخواه)
|
// سورت بر اساس طرف حسابها (بانک، صندوق، تنخواه)
|
||||||
|
@ -1117,21 +1238,14 @@ class PersonsController extends AbstractController
|
||||||
->leftJoin('hr_account.bank', 'ba')
|
->leftJoin('hr_account.bank', 'ba')
|
||||||
->leftJoin('hr_account.cashdesk', 'cd')
|
->leftJoin('hr_account.cashdesk', 'cd')
|
||||||
->leftJoin('hr_account.salary', 's')
|
->leftJoin('hr_account.salary', 's')
|
||||||
->groupBy('d.id, d.date, d.code, d.des, d.amount, ba.name, cd.name, s.name')
|
->groupBy('d.id, d.date, d.code, d.des, d.amount')
|
||||||
->orderBy('COALESCE(ba.name, cd.name, s.name)', $sortDirection);
|
->orderBy('CASE WHEN ba.name IS NOT NULL THEN ba.name WHEN cd.name IS NOT NULL THEN cd.name WHEN s.name IS NOT NULL THEN s.name ELSE \'\' END', $sortDirection);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$queryBuilder->orderBy('d.id', 'DESC');
|
$queryBuilder->orderBy('d.id', 'DESC');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// محاسبه تعداد کل
|
|
||||||
$totalQuery = (clone $queryBuilder)
|
|
||||||
->select('COUNT(DISTINCT d.id) as total')
|
|
||||||
->getQuery()
|
|
||||||
->getSingleResult();
|
|
||||||
$total = (int) $totalQuery['total'];
|
|
||||||
|
|
||||||
// گرفتن اسناد با صفحهبندی
|
// گرفتن اسناد با صفحهبندی
|
||||||
$docs = $queryBuilder
|
$docs = $queryBuilder
|
||||||
->setFirstResult(($page - 1) * $itemsPerPage)
|
->setFirstResult(($page - 1) * $itemsPerPage)
|
||||||
|
@ -1754,10 +1868,14 @@ class PersonsController extends AbstractController
|
||||||
$queryBuilder->orderBy('d.des', $sortDirection);
|
$queryBuilder->orderBy('d.des', $sortDirection);
|
||||||
break;
|
break;
|
||||||
case 'persons':
|
case 'persons':
|
||||||
|
// برای سورت بر اساس اشخاص
|
||||||
|
if (empty($search)) {
|
||||||
$queryBuilder->leftJoin('d.hesabdariRows', 'hr_person')
|
$queryBuilder->leftJoin('d.hesabdariRows', 'hr_person')
|
||||||
->leftJoin('hr_person.person', 'p')
|
->leftJoin('hr_person.person', 'p');
|
||||||
->groupBy('d.id, d.date, d.code, d.des, d.amount, p.nikename')
|
}
|
||||||
->orderBy('p.nikename', $sortDirection);
|
// استفاده از MIN برای جلوگیری از مشکل GROUP BY
|
||||||
|
$queryBuilder->groupBy('d.id, d.date, d.code, d.des, d.amount')
|
||||||
|
->orderBy('MIN(p.nikename)', $sortDirection);
|
||||||
break;
|
break;
|
||||||
case 'accounts':
|
case 'accounts':
|
||||||
// سورت بر اساس طرف حسابها (بانک، صندوق، تنخواه)
|
// سورت بر اساس طرف حسابها (بانک، صندوق، تنخواه)
|
||||||
|
@ -1765,8 +1883,8 @@ class PersonsController extends AbstractController
|
||||||
->leftJoin('hr_account.bank', 'ba')
|
->leftJoin('hr_account.bank', 'ba')
|
||||||
->leftJoin('hr_account.cashdesk', 'cd')
|
->leftJoin('hr_account.cashdesk', 'cd')
|
||||||
->leftJoin('hr_account.salary', 's')
|
->leftJoin('hr_account.salary', 's')
|
||||||
->groupBy('d.id, d.date, d.code, d.des, d.amount, ba.name, cd.name, s.name')
|
->groupBy('d.id, d.date, d.code, d.des, d.amount')
|
||||||
->orderBy('COALESCE(ba.name, cd.name, s.name)', $sortDirection);
|
->orderBy('CASE WHEN ba.name IS NOT NULL THEN ba.name WHEN cd.name IS NOT NULL THEN cd.name WHEN s.name IS NOT NULL THEN s.name ELSE \'\' END', $sortDirection);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$queryBuilder->orderBy('d.id', 'DESC');
|
$queryBuilder->orderBy('d.id', 'DESC');
|
||||||
|
@ -1916,10 +2034,14 @@ class PersonsController extends AbstractController
|
||||||
$queryBuilder->orderBy('d.des', $sortDirection);
|
$queryBuilder->orderBy('d.des', $sortDirection);
|
||||||
break;
|
break;
|
||||||
case 'persons':
|
case 'persons':
|
||||||
|
// برای سورت بر اساس اشخاص
|
||||||
|
if (empty($search)) {
|
||||||
$queryBuilder->leftJoin('d.hesabdariRows', 'hr_person')
|
$queryBuilder->leftJoin('d.hesabdariRows', 'hr_person')
|
||||||
->leftJoin('hr_person.person', 'p')
|
->leftJoin('hr_person.person', 'p');
|
||||||
->groupBy('d.id, d.date, d.code, d.des, d.amount, p.nikename')
|
}
|
||||||
->orderBy('p.nikename', $sortDirection);
|
// استفاده از MIN برای جلوگیری از مشکل GROUP BY
|
||||||
|
$queryBuilder->groupBy('d.id, d.date, d.code, d.des, d.amount')
|
||||||
|
->orderBy('MIN(p.nikename)', $sortDirection);
|
||||||
break;
|
break;
|
||||||
case 'accounts':
|
case 'accounts':
|
||||||
// سورت بر اساس طرف حسابها (بانک، صندوق، تنخواه)
|
// سورت بر اساس طرف حسابها (بانک، صندوق، تنخواه)
|
||||||
|
@ -1927,8 +2049,8 @@ class PersonsController extends AbstractController
|
||||||
->leftJoin('hr_account.bank', 'ba')
|
->leftJoin('hr_account.bank', 'ba')
|
||||||
->leftJoin('hr_account.cashdesk', 'cd')
|
->leftJoin('hr_account.cashdesk', 'cd')
|
||||||
->leftJoin('hr_account.salary', 's')
|
->leftJoin('hr_account.salary', 's')
|
||||||
->groupBy('d.id, d.date, d.code, d.des, d.amount, ba.name, cd.name, s.name')
|
->groupBy('d.id, d.date, d.code, d.des, d.amount')
|
||||||
->orderBy('COALESCE(ba.name, cd.name, s.name)', $sortDirection);
|
->orderBy('CASE WHEN ba.name IS NOT NULL THEN ba.name WHEN cd.name IS NOT NULL THEN cd.name WHEN s.name IS NOT NULL THEN s.name ELSE \'\' END', $sortDirection);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$queryBuilder->orderBy('d.id', 'DESC');
|
$queryBuilder->orderBy('d.id', 'DESC');
|
||||||
|
@ -1942,8 +2064,67 @@ class PersonsController extends AbstractController
|
||||||
->setParameter('ids', $ids);
|
->setParameter('ids', $ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
// دریافت تعداد کل رکوردها
|
// دریافت تعداد کل رکوردها - ایجاد کوئری جدید بدون GROUP BY
|
||||||
$totalItems = $queryBuilder->select('COUNT(d.id)')
|
$totalQueryBuilder = $entityManager->getRepository(HesabdariDoc::class)->createQueryBuilder('d')
|
||||||
|
->where('d.bid = :bid')
|
||||||
|
->andWhere('d.type = :type')
|
||||||
|
->andWhere('d.year = :year')
|
||||||
|
->andWhere('d.money = :money')
|
||||||
|
->setParameter('bid', $acc['bid'])
|
||||||
|
->setParameter('type', 'person_send')
|
||||||
|
->setParameter('year', $acc['year'])
|
||||||
|
->setParameter('money', $acc['money']);
|
||||||
|
|
||||||
|
// اعمال فیلترهای جستوجو و تاریخ
|
||||||
|
if (isset($params['search']) && !empty($params['search'])) {
|
||||||
|
$totalQueryBuilder->leftJoin('d.hesabdariRows', 'hr')
|
||||||
|
->leftJoin('hr.person', 'p')
|
||||||
|
->andWhere(
|
||||||
|
$totalQueryBuilder->expr()->orX(
|
||||||
|
'd.code LIKE :search',
|
||||||
|
'd.des LIKE :search',
|
||||||
|
'p.nikename LIKE :search'
|
||||||
|
)
|
||||||
|
)->setParameter('search', "%{$params['search']}%");
|
||||||
|
}
|
||||||
|
|
||||||
|
// فیلتر تاریخ
|
||||||
|
if (isset($params['dateFilter']) && $params['dateFilter'] !== 'all') {
|
||||||
|
$today = $jdate->GetTodayDate();
|
||||||
|
switch ($params['dateFilter']) {
|
||||||
|
case 'today':
|
||||||
|
$totalQueryBuilder->andWhere('d.date = :today')
|
||||||
|
->setParameter('today', $today);
|
||||||
|
break;
|
||||||
|
case 'thisWeek':
|
||||||
|
$dayOfWeek = (int) $jdate->jdate('w', time());
|
||||||
|
$startOfWeek = $jdate->shamsiDate(0, 0, -$dayOfWeek);
|
||||||
|
$endOfWeek = $jdate->shamsiDate(0, 0, 6 - $dayOfWeek);
|
||||||
|
$totalQueryBuilder->andWhere('d.date BETWEEN :start AND :end')
|
||||||
|
->setParameter('start', $startOfWeek)
|
||||||
|
->setParameter('end', $endOfWeek);
|
||||||
|
break;
|
||||||
|
case 'thisMonth':
|
||||||
|
$currentYear = (int) $jdate->jdate('Y', time());
|
||||||
|
$currentMonth = (int) $jdate->jdate('n', time());
|
||||||
|
$daysInMonth = (int) $jdate->jdate('t', time());
|
||||||
|
$startOfMonth = sprintf('%d/%02d/01', $currentYear, $currentMonth);
|
||||||
|
$endOfMonth = sprintf('%d/%02d/%02d', $currentYear, $currentMonth, $daysInMonth);
|
||||||
|
$totalQueryBuilder->andWhere('d.date BETWEEN :start AND :end')
|
||||||
|
->setParameter('start', $startOfMonth)
|
||||||
|
->setParameter('end', $endOfMonth);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// اگر آیتمهای خاصی درخواست شدهاند
|
||||||
|
if (array_key_exists('items', $params)) {
|
||||||
|
$ids = array_map(function($item) { return $item['id']; }, $params['items']);
|
||||||
|
$totalQueryBuilder->andWhere('d.id IN (:ids)')
|
||||||
|
->setParameter('ids', $ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
$totalItems = (int) $totalQueryBuilder->select('COUNT(d.id)')
|
||||||
->getQuery()
|
->getQuery()
|
||||||
->getSingleScalarResult();
|
->getSingleScalarResult();
|
||||||
|
|
||||||
|
@ -2014,4 +2195,282 @@ class PersonsController extends AbstractController
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[Route('/api/person/send/list/search', name: 'app_persons_send_list_search', methods: ['POST'])]
|
||||||
|
public function app_persons_send_list_search(
|
||||||
|
Request $request,
|
||||||
|
Access $access,
|
||||||
|
EntityManagerInterface $entityManager,
|
||||||
|
Jdate $jdate
|
||||||
|
): JsonResponse {
|
||||||
|
$acc = $access->hasRole('getpay');
|
||||||
|
if (!$acc) {
|
||||||
|
throw $this->createAccessDeniedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// دریافت پارامترها
|
||||||
|
$params = json_decode($request->getContent(), true) ?? [];
|
||||||
|
$page = (int) ($params['page'] ?? 1);
|
||||||
|
$itemsPerPage = (int) ($params['itemsPerPage'] ?? 10);
|
||||||
|
$search = $params['search'] ?? '';
|
||||||
|
$dateFilter = $params['dateFilter'] ?? 'all';
|
||||||
|
|
||||||
|
// پردازش پارامترهای سورت
|
||||||
|
$sortBy = 'id';
|
||||||
|
$sortDesc = true;
|
||||||
|
|
||||||
|
if (isset($params['sortBy'])) {
|
||||||
|
if (is_array($params['sortBy']) && !empty($params['sortBy'])) {
|
||||||
|
// فرمت جدید: [{"key":"date","order":"asc"}]
|
||||||
|
$sortBy = $params['sortBy'][0]['key'] ?? 'id';
|
||||||
|
$sortDesc = ($params['sortBy'][0]['order'] ?? 'desc') === 'desc';
|
||||||
|
} else {
|
||||||
|
// فرمت قدیمی: "date"
|
||||||
|
$sortBy = $params['sortBy'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($params['sortDesc'])) {
|
||||||
|
$sortDesc = (bool) $params['sortDesc'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// کوئری پایه برای اسناد
|
||||||
|
$queryBuilder = $entityManager->getRepository(HesabdariDoc::class)
|
||||||
|
->createQueryBuilder('d')
|
||||||
|
->select('DISTINCT d.id, d.date, d.code, d.des, d.amount')
|
||||||
|
->where('d.bid = :bid')
|
||||||
|
->andWhere('d.type = :type')
|
||||||
|
->andWhere('d.year = :year')
|
||||||
|
->andWhere('d.money = :money')
|
||||||
|
->setParameter('bid', $acc['bid'])
|
||||||
|
->setParameter('type', 'person_send')
|
||||||
|
->setParameter('year', $acc['year'])
|
||||||
|
->setParameter('money', $acc['money']);
|
||||||
|
|
||||||
|
// جستوجو
|
||||||
|
if (!empty($search)) {
|
||||||
|
$queryBuilder->leftJoin('d.hesabdariRows', 'hr')
|
||||||
|
->leftJoin('hr.person', 'p')
|
||||||
|
->andWhere(
|
||||||
|
$queryBuilder->expr()->orX(
|
||||||
|
'd.code LIKE :search',
|
||||||
|
'd.des LIKE :search',
|
||||||
|
'p.nikename LIKE :search'
|
||||||
|
)
|
||||||
|
)->setParameter('search', "%$search%");
|
||||||
|
}
|
||||||
|
|
||||||
|
// فیلتر تاریخ
|
||||||
|
$today = $jdate->GetTodayDate();
|
||||||
|
switch ($dateFilter) {
|
||||||
|
case 'today':
|
||||||
|
$queryBuilder->andWhere('d.date = :today')
|
||||||
|
->setParameter('today', $today);
|
||||||
|
break;
|
||||||
|
case 'thisWeek':
|
||||||
|
$dayOfWeek = (int) $jdate->jdate('w', time());
|
||||||
|
$startOfWeek = $jdate->shamsiDate(0, 0, -$dayOfWeek);
|
||||||
|
$endOfWeek = $jdate->shamsiDate(0, 0, 6 - $dayOfWeek);
|
||||||
|
$queryBuilder->andWhere('d.date BETWEEN :start AND :end')
|
||||||
|
->setParameter('start', $startOfWeek)
|
||||||
|
->setParameter('end', $endOfWeek);
|
||||||
|
break;
|
||||||
|
case 'thisMonth':
|
||||||
|
$currentYear = (int) $jdate->jdate('Y', time());
|
||||||
|
$currentMonth = (int) $jdate->jdate('n', time());
|
||||||
|
$daysInMonth = (int) $jdate->jdate('t', time());
|
||||||
|
$startOfMonth = sprintf('%d/%02d/01', $currentYear, $currentMonth);
|
||||||
|
$endOfMonth = sprintf('%d/%02d/%02d', $currentYear, $currentMonth, $daysInMonth);
|
||||||
|
$queryBuilder->andWhere('d.date BETWEEN :start AND :end')
|
||||||
|
->setParameter('start', $startOfMonth)
|
||||||
|
->setParameter('end', $endOfMonth);
|
||||||
|
break;
|
||||||
|
case 'all':
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// محاسبه تعداد کل قبل از اعمال GROUP BY
|
||||||
|
$totalQueryBuilder = $entityManager->getRepository(HesabdariDoc::class)->createQueryBuilder('d')
|
||||||
|
->where('d.bid = :bid')
|
||||||
|
->andWhere('d.type = :type')
|
||||||
|
->andWhere('d.year = :year')
|
||||||
|
->andWhere('d.money = :money')
|
||||||
|
->setParameter('bid', $acc['bid'])
|
||||||
|
->setParameter('type', 'person_send')
|
||||||
|
->setParameter('year', $acc['year'])
|
||||||
|
->setParameter('money', $acc['money']);
|
||||||
|
|
||||||
|
// اعمال فیلترهای جستوجو و تاریخ برای کوئری تعداد
|
||||||
|
if (!empty($search)) {
|
||||||
|
$totalQueryBuilder->leftJoin('d.hesabdariRows', 'hr')
|
||||||
|
->leftJoin('hr.person', 'p')
|
||||||
|
->andWhere(
|
||||||
|
$totalQueryBuilder->expr()->orX(
|
||||||
|
'd.code LIKE :search',
|
||||||
|
'd.des LIKE :search',
|
||||||
|
'p.nikename LIKE :search'
|
||||||
|
)
|
||||||
|
)->setParameter('search', "%$search%");
|
||||||
|
}
|
||||||
|
|
||||||
|
// فیلتر تاریخ برای کوئری تعداد
|
||||||
|
switch ($dateFilter) {
|
||||||
|
case 'today':
|
||||||
|
$totalQueryBuilder->andWhere('d.date = :today')
|
||||||
|
->setParameter('today', $today);
|
||||||
|
break;
|
||||||
|
case 'thisWeek':
|
||||||
|
$dayOfWeek = (int) $jdate->jdate('w', time());
|
||||||
|
$startOfWeek = $jdate->shamsiDate(0, 0, -$dayOfWeek);
|
||||||
|
$endOfWeek = $jdate->shamsiDate(0, 0, 6 - $dayOfWeek);
|
||||||
|
$totalQueryBuilder->andWhere('d.date BETWEEN :start AND :end')
|
||||||
|
->setParameter('start', $startOfWeek)
|
||||||
|
->setParameter('end', $endOfWeek);
|
||||||
|
break;
|
||||||
|
case 'thisMonth':
|
||||||
|
$currentYear = (int) $jdate->jdate('Y', time());
|
||||||
|
$currentMonth = (int) $jdate->jdate('n', time());
|
||||||
|
$daysInMonth = (int) $jdate->jdate('t', time());
|
||||||
|
$startOfMonth = sprintf('%d/%02d/01', $currentYear, $currentMonth);
|
||||||
|
$endOfMonth = sprintf('%d/%02d/%02d', $currentYear, $currentMonth, $daysInMonth);
|
||||||
|
$totalQueryBuilder->andWhere('d.date BETWEEN :start AND :end')
|
||||||
|
->setParameter('start', $startOfMonth)
|
||||||
|
->setParameter('end', $endOfMonth);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$total = (int) $totalQueryBuilder->select('COUNT(d.id)')
|
||||||
|
->getQuery()
|
||||||
|
->getSingleScalarResult();
|
||||||
|
|
||||||
|
// اعمال سورت
|
||||||
|
$sortDirection = $sortDesc ? 'DESC' : 'ASC';
|
||||||
|
switch ($sortBy) {
|
||||||
|
case 'code':
|
||||||
|
$queryBuilder->orderBy('d.code', $sortDirection);
|
||||||
|
break;
|
||||||
|
case 'date':
|
||||||
|
// تبدیل تاریخ شمسی به فرمت قابل مقایسه برای سورت
|
||||||
|
$queryBuilder->orderBy('CONCAT(SUBSTRING(d.date, 1, 4), SUBSTRING(d.date, 6, 2), SUBSTRING(d.date, 9, 2))', $sortDirection);
|
||||||
|
break;
|
||||||
|
case 'amount':
|
||||||
|
$queryBuilder->orderBy('CAST(d.amount AS DECIMAL)', $sortDirection);
|
||||||
|
break;
|
||||||
|
case 'des':
|
||||||
|
$queryBuilder->orderBy('d.des', $sortDirection);
|
||||||
|
break;
|
||||||
|
case 'persons':
|
||||||
|
// برای سورت بر اساس اشخاص
|
||||||
|
if (empty($search)) {
|
||||||
|
$queryBuilder->leftJoin('d.hesabdariRows', 'hr_person')
|
||||||
|
->leftJoin('hr_person.person', 'p');
|
||||||
|
}
|
||||||
|
// استفاده از MIN برای جلوگیری از مشکل GROUP BY
|
||||||
|
$queryBuilder->groupBy('d.id, d.date, d.code, d.des, d.amount')
|
||||||
|
->orderBy('MIN(p.nikename)', $sortDirection);
|
||||||
|
break;
|
||||||
|
case 'accounts':
|
||||||
|
// سورت بر اساس طرف حسابها (بانک، صندوق، تنخواه)
|
||||||
|
$queryBuilder->leftJoin('d.hesabdariRows', 'hr_account')
|
||||||
|
->leftJoin('hr_account.bank', 'ba')
|
||||||
|
->leftJoin('hr_account.cashdesk', 'cd')
|
||||||
|
->leftJoin('hr_account.salary', 's')
|
||||||
|
->groupBy('d.id, d.date, d.code, d.des, d.amount')
|
||||||
|
->orderBy('CASE WHEN ba.name IS NOT NULL THEN ba.name WHEN cd.name IS NOT NULL THEN cd.name WHEN s.name IS NOT NULL THEN s.name ELSE \'\' END', $sortDirection);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$queryBuilder->orderBy('d.id', 'DESC');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// گرفتن اسناد با صفحهبندی
|
||||||
|
$docs = $queryBuilder
|
||||||
|
->setFirstResult(($page - 1) * $itemsPerPage)
|
||||||
|
->setMaxResults($itemsPerPage)
|
||||||
|
->getQuery()
|
||||||
|
->getArrayResult();
|
||||||
|
|
||||||
|
// گرفتن اشخاص و طرف حسابها مرتبط
|
||||||
|
$docIds = array_column($docs, 'id');
|
||||||
|
$persons = [];
|
||||||
|
$accounts = [];
|
||||||
|
if (!empty($docIds)) {
|
||||||
|
// کوئری برای اشخاص
|
||||||
|
$personQuery = $entityManager->createQueryBuilder()
|
||||||
|
->select('IDENTITY(hr.doc) as doc_id, p.code as person_code, p.nikename as person_nikename')
|
||||||
|
->from('App\Entity\HesabdariRow', 'hr')
|
||||||
|
->leftJoin('hr.person', 'p')
|
||||||
|
->where('hr.doc IN (:docIds)')
|
||||||
|
->andWhere('p.id IS NOT NULL')
|
||||||
|
->setParameter('docIds', $docIds)
|
||||||
|
->getQuery()
|
||||||
|
->getArrayResult();
|
||||||
|
|
||||||
|
foreach ($personQuery as $row) {
|
||||||
|
if (!empty($row['person_code'])) {
|
||||||
|
$persons[$row['doc_id']][] = [
|
||||||
|
'code' => $row['person_code'],
|
||||||
|
'nikename' => $row['person_nikename'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// کوئری برای طرف حسابها (بانک، صندوق، تنخواه گردان)
|
||||||
|
$accountQuery = $entityManager->createQueryBuilder()
|
||||||
|
->select('IDENTITY(hr.doc) as doc_id, hr.bs as amount,
|
||||||
|
CASE
|
||||||
|
WHEN hr.bank IS NOT NULL THEN CONCAT(\'بانک: \', ba.name)
|
||||||
|
WHEN hr.cashdesk IS NOT NULL THEN CONCAT(\'صندوق: \', cd.name)
|
||||||
|
WHEN hr.salary IS NOT NULL THEN CONCAT(\'تنخواه: \', s.name)
|
||||||
|
ELSE \'نامشخص\'
|
||||||
|
END as account_name,
|
||||||
|
CASE
|
||||||
|
WHEN hr.bank IS NOT NULL THEN \'bank\'
|
||||||
|
WHEN hr.cashdesk IS NOT NULL THEN \'cashdesk\'
|
||||||
|
WHEN hr.salary IS NOT NULL THEN \'salary\'
|
||||||
|
ELSE \'unknown\'
|
||||||
|
END as account_type')
|
||||||
|
->from('App\Entity\HesabdariRow', 'hr')
|
||||||
|
->leftJoin('hr.bank', 'ba')
|
||||||
|
->leftJoin('hr.cashdesk', 'cd')
|
||||||
|
->leftJoin('hr.salary', 's')
|
||||||
|
->where('hr.doc IN (:docIds)')
|
||||||
|
->andWhere('hr.bs > 0')
|
||||||
|
->andWhere('(hr.bank IS NOT NULL OR hr.cashdesk IS NOT NULL OR hr.salary IS NOT NULL)')
|
||||||
|
->setParameter('docIds', $docIds)
|
||||||
|
->getQuery()
|
||||||
|
->getArrayResult();
|
||||||
|
|
||||||
|
foreach ($accountQuery as $row) {
|
||||||
|
if (!empty($row['account_name']) && $row['account_name'] !== 'نامشخص') {
|
||||||
|
$accounts[$row['doc_id']][] = [
|
||||||
|
'name' => $row['account_name'],
|
||||||
|
'type' => $row['account_type'],
|
||||||
|
'amount' => $row['amount'],
|
||||||
|
'formattedAmount' => number_format($row['amount'], 0, '.', ','),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ساختاردهی خروجی
|
||||||
|
$items = [];
|
||||||
|
foreach ($docs as $doc) {
|
||||||
|
$items[] = [
|
||||||
|
'id' => $doc['id'],
|
||||||
|
'date' => $doc['date'],
|
||||||
|
'code' => $doc['code'],
|
||||||
|
'des' => $doc['des'],
|
||||||
|
'amount' => $doc['amount'],
|
||||||
|
'persons' => $persons[$doc['id']] ?? [],
|
||||||
|
'accounts' => $accounts[$doc['id']] ?? [],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json([
|
||||||
|
'items' => $items,
|
||||||
|
'total' => $total,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue