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);
|
||||
break;
|
||||
case 'persons':
|
||||
// برای سورت بر اساس اشخاص
|
||||
if (empty($search)) {
|
||||
$queryBuilder->leftJoin('d.hesabdariRows', 'hr_person')
|
||||
->leftJoin('hr_person.person', 'p')
|
||||
->groupBy('d.id, d.date, d.code, d.des, d.amount, p.nikename')
|
||||
->orderBy('p.nikename', $sortDirection);
|
||||
->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':
|
||||
// سورت بر اساس طرف حسابها (بانک، صندوق، تنخواه)
|
||||
|
@ -908,8 +912,8 @@ class PersonsController extends AbstractController
|
|||
->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, ba.name, cd.name, s.name')
|
||||
->orderBy('COALESCE(ba.name, cd.name, s.name)', $sortDirection);
|
||||
->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');
|
||||
|
@ -923,8 +927,67 @@ class PersonsController extends AbstractController
|
|||
->setParameter('ids', $ids);
|
||||
}
|
||||
|
||||
// دریافت تعداد کل رکوردها
|
||||
$totalItems = $queryBuilder->select('COUNT(d.id)')
|
||||
// دریافت تعداد کل رکوردها - ایجاد کوئری جدید بدون 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 (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()
|
||||
->getSingleScalarResult();
|
||||
|
||||
|
@ -1089,6 +1152,60 @@ class PersonsController extends AbstractController
|
|||
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';
|
||||
switch ($sortBy) {
|
||||
|
@ -1106,10 +1223,14 @@ class PersonsController extends AbstractController
|
|||
$queryBuilder->orderBy('d.des', $sortDirection);
|
||||
break;
|
||||
case 'persons':
|
||||
// برای سورت بر اساس اشخاص
|
||||
if (empty($search)) {
|
||||
$queryBuilder->leftJoin('d.hesabdariRows', 'hr_person')
|
||||
->leftJoin('hr_person.person', 'p')
|
||||
->groupBy('d.id, d.date, d.code, d.des, d.amount, p.nikename')
|
||||
->orderBy('p.nikename', $sortDirection);
|
||||
->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':
|
||||
// سورت بر اساس طرف حسابها (بانک، صندوق، تنخواه)
|
||||
|
@ -1117,21 +1238,14 @@ class PersonsController extends AbstractController
|
|||
->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, ba.name, cd.name, s.name')
|
||||
->orderBy('COALESCE(ba.name, cd.name, s.name)', $sortDirection);
|
||||
->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;
|
||||
}
|
||||
|
||||
// محاسبه تعداد کل
|
||||
$totalQuery = (clone $queryBuilder)
|
||||
->select('COUNT(DISTINCT d.id) as total')
|
||||
->getQuery()
|
||||
->getSingleResult();
|
||||
$total = (int) $totalQuery['total'];
|
||||
|
||||
// گرفتن اسناد با صفحهبندی
|
||||
$docs = $queryBuilder
|
||||
->setFirstResult(($page - 1) * $itemsPerPage)
|
||||
|
@ -1754,10 +1868,14 @@ class PersonsController extends AbstractController
|
|||
$queryBuilder->orderBy('d.des', $sortDirection);
|
||||
break;
|
||||
case 'persons':
|
||||
// برای سورت بر اساس اشخاص
|
||||
if (empty($search)) {
|
||||
$queryBuilder->leftJoin('d.hesabdariRows', 'hr_person')
|
||||
->leftJoin('hr_person.person', 'p')
|
||||
->groupBy('d.id, d.date, d.code, d.des, d.amount, p.nikename')
|
||||
->orderBy('p.nikename', $sortDirection);
|
||||
->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':
|
||||
// سورت بر اساس طرف حسابها (بانک، صندوق، تنخواه)
|
||||
|
@ -1765,8 +1883,8 @@ class PersonsController extends AbstractController
|
|||
->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, ba.name, cd.name, s.name')
|
||||
->orderBy('COALESCE(ba.name, cd.name, s.name)', $sortDirection);
|
||||
->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');
|
||||
|
@ -1916,10 +2034,14 @@ class PersonsController extends AbstractController
|
|||
$queryBuilder->orderBy('d.des', $sortDirection);
|
||||
break;
|
||||
case 'persons':
|
||||
// برای سورت بر اساس اشخاص
|
||||
if (empty($search)) {
|
||||
$queryBuilder->leftJoin('d.hesabdariRows', 'hr_person')
|
||||
->leftJoin('hr_person.person', 'p')
|
||||
->groupBy('d.id, d.date, d.code, d.des, d.amount, p.nikename')
|
||||
->orderBy('p.nikename', $sortDirection);
|
||||
->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':
|
||||
// سورت بر اساس طرف حسابها (بانک، صندوق، تنخواه)
|
||||
|
@ -1927,8 +2049,8 @@ class PersonsController extends AbstractController
|
|||
->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, ba.name, cd.name, s.name')
|
||||
->orderBy('COALESCE(ba.name, cd.name, s.name)', $sortDirection);
|
||||
->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');
|
||||
|
@ -1942,8 +2064,67 @@ class PersonsController extends AbstractController
|
|||
->setParameter('ids', $ids);
|
||||
}
|
||||
|
||||
// دریافت تعداد کل رکوردها
|
||||
$totalItems = $queryBuilder->select('COUNT(d.id)')
|
||||
// دریافت تعداد کل رکوردها - ایجاد کوئری جدید بدون 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 (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()
|
||||
->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