diff --git a/app/AdminModule/UsersModule/Components/PatrolsGridControl.php b/app/AdminModule/UsersModule/Components/PatrolsGridControl.php index 367a4fa66..c998cddc4 100644 --- a/app/AdminModule/UsersModule/Components/PatrolsGridControl.php +++ b/app/AdminModule/UsersModule/Components/PatrolsGridControl.php @@ -8,9 +8,13 @@ use App\Model\User\Patrol; use App\Model\User\Repositories\PatrolRepository; use App\Services\CommandBus; +use App\Services\ExcelExportService; use App\Utils\Helpers; +use Exception; use Nette\Application\AbortException; use Nette\Application\UI\Control; +use Nette\Http\Session; +use Nette\Http\SessionSection; use Nette\Localization\Translator; use Nette\Utils\Html; use Throwable; @@ -19,18 +23,22 @@ use Ublaboo\DataGrid\Exception\DataGridException; use function count; -use function date; /** * Komponenta pro zobrazení datagridu družin. */ class PatrolsGridControl extends Control { + private SessionSection $sessionSection; + public function __construct( private CommandBus $commandBus, private Translator $translator, - private PatrolRepository $patrolRepository + private PatrolRepository $patrolRepository, + private ExcelExportService $excelExportService, + private Session $session ) { + $this->sessionSection = $session->getSection('srs'); } /** @@ -59,9 +67,8 @@ public function createComponentPatrolsGrid(string $name): DataGrid $grid->setItemsPerPageList([25, 50, 100, 250, 500]); $grid->setStrictSessionFilterValues(false); - $stamp = date(Helpers::DATE_FORMAT); - $grid->addExportCsv('admin.common.export_all', 'NSJ2023 Druziny ' . $stamp . '.csv'); - $grid->addExportCsvFiltered('admin.common.export_filter', 'NSJ2023 Druziny fi ' . $stamp . '.csv'); + $grid->addGroupAction('Export seznamu družin') + ->onSelect[] = [$this, 'groupExportPatrols']; $grid->addColumnText('name', 'Název') ->setSortable() @@ -112,4 +119,34 @@ public function handleDelete(int $id): void $p->flashMessage('Družina byla úspěšně odstraněna.', 'success'); $p->redirect('this'); } + + /** + * Hromadně vyexportuje seznam družin. + * + * @param int[] $ids + * + * @throws AbortException + */ + public function groupExportPatrols(array $ids): void + { + $this->sessionSection->patrolIds = $ids; + $this->redirect('exportpatrols'); + } + + /** + * Zpracuje export seznamu družin. + * + * @throws AbortException + * @throws Exception + */ + public function handleExportPatrols(): void + { + $ids = $this->session->getSection('srs')->patrolIds; + + $patrols = $this->patrolRepository->findPatrolsByIds($ids); + + $response = $this->excelExportService->exportPatrolsList($patrols, 'seznam-druzin.xlsx'); + + $this->getPresenter()->sendResponse($response); + } } diff --git a/app/AdminModule/UsersModule/Components/TroopsGridControl.php b/app/AdminModule/UsersModule/Components/TroopsGridControl.php index c71b7760d..ce4f71e96 100644 --- a/app/AdminModule/UsersModule/Components/TroopsGridControl.php +++ b/app/AdminModule/UsersModule/Components/TroopsGridControl.php @@ -9,10 +9,14 @@ use App\Model\User\Repositories\TroopRepository; use App\Model\User\Troop; use App\Services\CommandBus; +use App\Services\ExcelExportService; use App\Utils\Helpers; use Doctrine\ORM\QueryBuilder; +use Exception; use Nette\Application\AbortException; use Nette\Application\UI\Control; +use Nette\Http\Session; +use Nette\Http\SessionSection; use Nette\Localization\Translator; use Nette\Utils\Html; use Throwable; @@ -21,18 +25,22 @@ use Ublaboo\DataGrid\Exception\DataGridException; use function count; -use function date; /** * Komponenta pro zobrazení datagridu družin. */ class TroopsGridControl extends Control { + private SessionSection $sessionSection; + public function __construct( private CommandBus $commandBus, private Translator $translator, - private TroopRepository $troopRepository + private TroopRepository $troopRepository, + private ExcelExportService $excelExportService, + private Session $session ) { + $this->sessionSection = $session->getSection('srs'); } /** @@ -61,9 +69,8 @@ public function createComponentPatrolsGrid(string $name): DataGrid $grid->setItemsPerPageList([25, 50, 100, 250, 500]); $grid->setStrictSessionFilterValues(false); - $stamp = date(Helpers::DATE_FORMAT); - $grid->addExportCsv('admin.common.export_all', 'NSJ2023 Skupiny ' . $stamp . '.csv'); - $grid->addExportCsvFiltered('admin.common.export_filter', 'NSJ2023 Skupiny fi ' . $stamp . '.csv'); + $grid->addGroupAction('Export seznamu skupin') + ->onSelect[] = [$this, 'groupExportTroops']; $grid->addColumnText('name', 'Název') ->setSortable() @@ -180,4 +187,34 @@ public function handleGeneratePaymentProof(int $id): void { $this->presenter->redirect(':Export:TroopIncomeProof:troop', ['id' => $id]); } + + /** + * Hromadně vyexportuje seznam skupin. + * + * @param int[] $ids + * + * @throws AbortException + */ + public function groupExportTroops(array $ids): void + { + $this->sessionSection->troopIds = $ids; + $this->redirect('exporttroops'); + } + + /** + * Zpracuje export seznamu skupin. + * + * @throws AbortException + * @throws Exception + */ + public function handleExportTroops(): void + { + $ids = $this->session->getSection('srs')->troopIds; + + $troops = $this->troopRepository->findTroopsByIds($ids); + + $response = $this->excelExportService->exportTroopsList($troops, 'seznam-skupin.xlsx'); + + $this->getPresenter()->sendResponse($response); + } } diff --git a/app/Model/User/Repositories/PatrolRepository.php b/app/Model/User/Repositories/PatrolRepository.php index 2c18d0a6c..f7b8be640 100644 --- a/app/Model/User/Repositories/PatrolRepository.php +++ b/app/Model/User/Repositories/PatrolRepository.php @@ -6,6 +6,8 @@ use App\Model\Infrastructure\Repositories\AbstractRepository; use App\Model\User\Patrol; +use Doctrine\Common\Collections\Collection; +use Doctrine\Common\Collections\Criteria; use Doctrine\ORM\EntityManagerInterface; /** @@ -28,6 +30,19 @@ public function findByTroopAndNotConfirmed(int $troopId): ?Patrol return $this->getRepository()->findOneBy(['troop' => $troopId, 'confirmed' => false]); } + /** + * @param int[] $ids + * + * @return Collection + */ + public function findPatrolsByIds(array $ids): Collection + { + $criteria = Criteria::create() + ->where(Criteria::expr()->in('id', $ids)); + + return $this->getRepository()->matching($criteria); + } + public function save(Patrol $patrol): void { $this->em->persist($patrol); diff --git a/app/Services/ExcelExportService.php b/app/Services/ExcelExportService.php index dafbcf619..7104e6e23 100644 --- a/app/Services/ExcelExportService.php +++ b/app/Services/ExcelExportService.php @@ -14,7 +14,9 @@ use App\Model\Program\Repositories\ProgramRepository; use App\Model\Program\Room; use App\Model\Structure\Repositories\SubeventRepository; +use App\Model\User\Patrol; use App\Model\User\Queries\UserAttendsProgramsQuery; +use App\Model\User\Troop; use App\Model\User\User; use App\Utils\Helpers; use Doctrine\Common\Collections\ArrayCollection; @@ -518,6 +520,172 @@ public function exportUsersSubeventsAndCategories(Collection $users, string $fil return new ExcelResponse($this->spreadsheet, $filename); } + /** + * @param Collection $patrols + * + * @throws Exception + */ + public function exportPatrolsList(Collection $patrols, string $filename): ExcelResponse + { + $sheet = $this->spreadsheet->getSheet(0); + + $row = 1; + $column = 1; + + $sheet->setCellValue([$column, $row], $this->translator->translate('Název')); + $sheet->getStyle([$column, $row])->getFont()->setBold(true); + $sheet->getColumnDimensionByColumn($column)->setAutoSize(false); + $sheet->getColumnDimensionByColumn($column++)->setWidth(20); + + $sheet->setCellValue([$column, $row], $this->translator->translate('Skupina')); + $sheet->getStyle([$column, $row])->getFont()->setBold(true); + $sheet->getColumnDimensionByColumn($column)->setAutoSize(false); + $sheet->getColumnDimensionByColumn($column++)->setWidth(15); + + $sheet->setCellValue([$column, $row], $this->translator->translate('Datum založení')); + $sheet->getStyle([$column, $row])->getFont()->setBold(true); + $sheet->getColumnDimensionByColumn($column)->setAutoSize(false); + $sheet->getColumnDimensionByColumn($column++)->setWidth(20); + + $sheet->setCellValue([$column, $row], $this->translator->translate('Počet osob')); + $sheet->getStyle([$column, $row])->getFont()->setBold(true); + $sheet->getColumnDimensionByColumn($column)->setAutoSize(false); + $sheet->getColumnDimensionByColumn($column++)->setWidth(15); + + foreach ($patrols as $patrol) { + $row++; + $column = 1; + + $sheet->setCellValue([$column++, $row], $patrol->getName()); + + $sheet->setCellValue([$column++, $row], $patrol->getTroop()->getName()); + + $sheet->setCellValue([$column++, $row], $patrol->getTroop()->getApplicationDate() !== null ? $patrol->getTroop()->getApplicationDate()->format(Helpers::DATETIME_FORMAT) : ''); + + $sheet->setCellValue([$column++, $row], $patrol->getUsersRoles()->count()); + } + + return new ExcelResponse($this->spreadsheet, $filename); + } + + /** + * @param Collection $troops + * + * @throws Exception + */ + public function exportTroopsList(Collection $troops, string $filename): ExcelResponse + { + $sheet = $this->spreadsheet->getSheet(0); + + $row = 1; + $column = 1; + + $sheet->setCellValue([$column, $row], $this->translator->translate('Název')); + $sheet->getStyle([$column, $row])->getFont()->setBold(true); + $sheet->getColumnDimensionByColumn($column)->setAutoSize(false); + $sheet->getColumnDimensionByColumn($column++)->setWidth(20); + + $sheet->setCellValue([$column, $row], $this->translator->translate('Stav')); + $sheet->getStyle([$column, $row])->getFont()->setBold(true); + $sheet->getColumnDimensionByColumn($column)->setAutoSize(false); + $sheet->getColumnDimensionByColumn($column++)->setWidth(20); + + $sheet->setCellValue([$column, $row], $this->translator->translate('Variabilní symbol')); + $sheet->getStyle([$column, $row])->getFont()->setBold(true); + $sheet->getColumnDimensionByColumn($column)->setAutoSize(false); + $sheet->getColumnDimensionByColumn($column++)->setWidth(20); + + $sheet->setCellValue([$column, $row], $this->translator->translate('Vedoucí')); + $sheet->getStyle([$column, $row])->getFont()->setBold(true); + $sheet->getColumnDimensionByColumn($column)->setAutoSize(false); + $sheet->getColumnDimensionByColumn($column++)->setWidth(30); + + $sheet->setCellValue([$column, $row], $this->translator->translate('E-mail vedoucího')); + $sheet->getStyle([$column, $row])->getFont()->setBold(true); + $sheet->getColumnDimensionByColumn($column)->setAutoSize(false); + $sheet->getColumnDimensionByColumn($column++)->setWidth(30); + + $sheet->setCellValue([$column, $row], $this->translator->translate('Datum založení')); + $sheet->getStyle([$column, $row])->getFont()->setBold(true); + $sheet->getColumnDimensionByColumn($column)->setAutoSize(false); + $sheet->getColumnDimensionByColumn($column++)->setWidth(20); + + $sheet->setCellValue([$column, $row], $this->translator->translate('Cena')); + $sheet->getStyle([$column, $row])->getFont()->setBold(true); + $sheet->getColumnDimensionByColumn($column)->setAutoSize(false); + $sheet->getColumnDimensionByColumn($column++)->setWidth(10); + + $sheet->setCellValue([$column, $row], $this->translator->translate('Datum splatnosti')); + $sheet->getStyle([$column, $row])->getFont()->setBold(true); + $sheet->getColumnDimensionByColumn($column)->setAutoSize(false); + $sheet->getColumnDimensionByColumn($column++)->setWidth(20); + + $sheet->setCellValue([$column, $row], $this->translator->translate('Datum platby')); + $sheet->getStyle([$column, $row])->getFont()->setBold(true); + $sheet->getColumnDimensionByColumn($column)->setAutoSize(false); + $sheet->getColumnDimensionByColumn($column++)->setWidth(20); + + $sheet->setCellValue([$column, $row], $this->translator->translate('Kód jamoddílu')); + $sheet->getStyle([$column, $row])->getFont()->setBold(true); + $sheet->getColumnDimensionByColumn($column)->setAutoSize(false); + $sheet->getColumnDimensionByColumn($column++)->setWidth(30); + + $sheet->setCellValue([$column, $row], $this->translator->translate('Počet osob')); + $sheet->getStyle([$column, $row])->getFont()->setBold(true); + $sheet->getColumnDimensionByColumn($column)->setAutoSize(false); + $sheet->getColumnDimensionByColumn($column++)->setWidth(15); + + $sheet->setCellValue([$column, $row], $this->translator->translate('Počet rádců')); + $sheet->getStyle([$column, $row])->getFont()->setBold(true); + $sheet->getColumnDimensionByColumn($column)->setAutoSize(false); + $sheet->getColumnDimensionByColumn($column++)->setWidth(15); + + $sheet->setCellValue([$column, $row], $this->translator->translate('Počet dospělých')); + $sheet->getStyle([$column, $row])->getFont()->setBold(true); + $sheet->getColumnDimensionByColumn($column)->setAutoSize(false); + $sheet->getColumnDimensionByColumn($column++)->setWidth(15); + + $sheet->setCellValue([$column, $row], $this->translator->translate('Počet družin')); + $sheet->getStyle([$column, $row])->getFont()->setBold(true); + $sheet->getColumnDimensionByColumn($column)->setAutoSize(false); + $sheet->getColumnDimensionByColumn($column++)->setWidth(15); + + foreach ($troops as $troop) { + $row++; + $column = 1; + + $sheet->setCellValue([$column++, $row], $troop->getName()); + + $sheet->setCellValue([$column++, $row], $this->translator->translate('common.application_state.' . $troop->getState())); + + $sheet->setCellValue([$column++, $row], $troop->getVariableSymbolText()); + + $sheet->setCellValue([$column++, $row], $troop->getLeader()->getDisplayName()); + + $sheet->setCellValue([$column++, $row], $troop->getLeader()->getEmail()); + + $sheet->setCellValue([$column++, $row], $troop->getApplicationDate() !== null ? $troop->getApplicationDate()->format(Helpers::DATETIME_FORMAT) : ''); + + $sheet->setCellValue([$column++, $row], $troop->getFee()); + + $sheet->setCellValue([$column++, $row], $troop->getMaturityDate() !== null ? $troop->getMaturityDate()->format(Helpers::DATE_FORMAT) : ''); + + $sheet->setCellValue([$column++, $row], $troop->getPaymentDate() !== null ? $troop->getPaymentDate()->format(Helpers::DATE_FORMAT) : ''); + + $sheet->setCellValue([$column++, $row], $troop->getPairingCode()); + + $sheet->setCellValue([$column++, $row], $troop->countUsersInRoles([Role::PATROL_LEADER, Role::LEADER, Role::ESCORT, Role::ATTENDEE])); + + $sheet->setCellValue([$column++, $row], $troop->countUsersInRoles([Role::PATROL_LEADER])); + + $sheet->setCellValue([$column++, $row], $troop->countUsersInRoles([Role::LEADER, Role::ESCORT])); + + $sheet->setCellValue([$column++, $row], $troop->getConfirmedPatrols()->count()); + } + + return new ExcelResponse($this->spreadsheet, $filename); + } + /** * @param Collection $blocks *