From a1788370de8b83cdd45c066c05abbf79cc4388ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Stan=C4=9Bk?= Date: Wed, 27 Dec 2017 22:47:43 +0100 Subject: [PATCH] uprava podakci --- .../forms/SubeventForm.php | 2 +- .../ProgramAttendeesGridControl.php | 1 + .../components/ApplicationsGridControl.php | 43 ++++++++++----- .../components/UsersGridControl.php | 22 +++----- app/ApiModule/services/ScheduleService.php | 6 +- .../components/ApplicationContentControl.php | 18 +++++- .../components/ApplicationsGridControl.php | 30 +++++++--- .../templates/application_content.latte | 19 ++++--- app/WebModule/forms/ApplicationForm.php | 2 +- app/lang/admin.cs_CZ.neon | 8 ++- app/model/Program/Program.php | 2 +- app/model/Structure/Subevent.php | 3 +- app/model/User/Application/Application.php | 55 ++++++++++++++++--- .../User/Application/RolesApplication.php | 32 ----------- .../User/Application/SubeventsApplication.php | 32 ----------- app/model/User/User.php | 34 +++++++----- app/model/User/UserRepository.php | 7 +-- app/services/ApplicationService.php | 22 ++++---- app/services/ExcelExportService.php | 11 ++-- app/services/PdfExportService.php | 2 +- app/services/ProgramService.php | 7 +-- migrations/Version20171227203925.php | 30 ++++++++++ 22 files changed, 218 insertions(+), 170 deletions(-) create mode 100644 migrations/Version20171227203925.php diff --git a/app/AdminModule/ConfigurationModule/forms/SubeventForm.php b/app/AdminModule/ConfigurationModule/forms/SubeventForm.php index fdbfb2b46..2ad65719d 100644 --- a/app/AdminModule/ConfigurationModule/forms/SubeventForm.php +++ b/app/AdminModule/ConfigurationModule/forms/SubeventForm.php @@ -61,7 +61,7 @@ public function create($id) ->setAttribute('title', $form->getTranslator()->translate('admin.configuration.subevents_capacity_note')); $form->addText('fee', 'admin.configuration.subevents_fee') - ->addCondition(Form::FILLED) + ->addRule(Form::FILLED, 'admin.configuration.subevents_fee_empty') ->addRule(Form::INTEGER, 'admin.configuration.subevents_fee_format'); if ($this->subevent) { diff --git a/app/AdminModule/ProgramModule/components/ProgramAttendeesGridControl.php b/app/AdminModule/ProgramModule/components/ProgramAttendeesGridControl.php index 139961236..88a9ed4f6 100644 --- a/app/AdminModule/ProgramModule/components/ProgramAttendeesGridControl.php +++ b/app/AdminModule/ProgramModule/components/ProgramAttendeesGridControl.php @@ -127,6 +127,7 @@ public function createComponentProgramAttendeesGrid($name) ->innerJoin('a.subevents', 's') ->where('per.name = :permission') ->andWhere('s.id = :sid') + ->andWhere('a.validTo IS NULL') ->andWhere('(a.state = \'' . ApplicationState::PAID . '\' OR a.state = \'' . ApplicationState::PAID_FREE . '\' OR a.state = \'' . ApplicationState::WAITING_FOR_PAYMENT . '\')') ->setParameter('pid', $program->getId()) diff --git a/app/AdminModule/components/ApplicationsGridControl.php b/app/AdminModule/components/ApplicationsGridControl.php index 48841b1d5..ea4b91f7f 100644 --- a/app/AdminModule/components/ApplicationsGridControl.php +++ b/app/AdminModule/components/ApplicationsGridControl.php @@ -185,8 +185,7 @@ public function createComponentApplicationsGrid($name) $container->addMultiSelect('subevents', '', $this->subeventRepository->getSubeventsOptionsWithCapacity() ) - ->setAttribute('class', 'datagrid-multiselect') - ->addRule(Form::FILLED, 'admin.users.users_applications_subevents_empty'); + ->setAttribute('class', 'datagrid-multiselect'); $container->addText('variableSymbol', 'admin.users.users_variable_symbol') ->addRule(Form::FILLED, 'admin.users.users_applications_variable_symbol_empty') @@ -205,10 +204,10 @@ public function createComponentApplicationsGrid($name) $container->addDatePicker('maturityDate', 'admin.users.users_maturity_date'); }; - $grid->getInlineEdit()->onSetDefaults[] = function ($container, $item) { + $grid->getInlineEdit()->onSetDefaults[] = function ($container, Application $item) { $container->setDefaults([ 'subevents' => $this->subeventRepository->findSubeventsIds($item->getSubevents()), - 'variableSymbol' => $item->getVariableSymbol(), + 'variableSymbol' => $item->getVariableSymbolText(), 'paymentMethod' => $item->getPaymentMethod(), 'paymentDate' => $item->getPaymentDate(), 'incomeProofPrintedDate' => $item->getIncomeProofPrintedDate(), @@ -261,13 +260,15 @@ public function add($values) { $selectedSubevents = $this->subeventRepository->findSubeventsByIds($values['subevents']); + $p = $this->getPresenter(); + if (!$this->validators->validateSubeventsCapacities($selectedSubevents, $this->user)) { - $this->getPresenter()->flashMessage('admin.users.users_applications_subevents_occupied', 'danger'); + $p->flashMessage('admin.users.users_applications_subevents_occupied', 'danger'); $this->redirect('this'); } if (!$this->validators->validateSubeventsRegistered($selectedSubevents, $this->user)) { - $this->getPresenter()->flashMessage('admin.users.users_applications_subevents_registered', 'danger'); + $p->flashMessage('admin.users.users_applications_subevents_registered', 'danger'); $this->redirect('this'); } @@ -275,7 +276,7 @@ public function add($values) $this->applicationService->addSubeventsApplication($this->user, $selectedSubevents, $loggedUser); - $this->getPresenter()->flashMessage('admin.users.users_applications_saved', 'success'); + $p->flashMessage('admin.users.users_applications_saved', 'success'); $this->redirect('this'); } @@ -293,25 +294,41 @@ public function edit($id, $values) $selectedSubevents = $this->subeventRepository->findSubeventsByIds($values['subevents']); + $p = $this->getPresenter(); + + if ($application->getType() == Application::ROLES) { + if (!$selectedSubevents->isEmpty()) { + $p->flashMessage('admin.users.users_applications_subevents_not_empty', 'danger'); + $this->redirect('this'); + } + } else { + if ($selectedSubevents->isEmpty()) { + $p->flashMessage('admin.users.users_applications_subevents_empty', 'danger'); + $this->redirect('this'); + } + } + if (!$this->validators->validateSubeventsCapacities($selectedSubevents, $this->user)) { - $this->getPresenter()->flashMessage('admin.users.users_applications_subevents_occupied', 'danger'); + $p->flashMessage('admin.users.users_applications_subevents_occupied', 'danger'); $this->redirect('this'); } if (!$this->validators->validateSubeventsRegistered($selectedSubevents, $this->user, $application)) { - $this->getPresenter()->flashMessage('admin.users.users_applications_subevents_registered', 'danger'); + $p->flashMessage('admin.users.users_applications_subevents_registered', 'danger'); $this->redirect('this'); } $loggedUser = $this->userRepository->findById($this->getPresenter()->user->id); $this->applicationRepository->getEntityManager()->transactional(function ($em) use ($application, $selectedSubevents, $values, $loggedUser) { - $this->applicationService->updateSubeventsApplication($application, $selectedSubevents, $loggedUser); - $this->applicationService->updatePayment($application, $values['variableSymbol'], $values['paymentMethod'], - $values['paymentDate'], $values['incomeProofPrintedDate'], $values['maturityDate'], $loggedUser); + if ($application->getType() == Application::SUBEVENTS) + $this->applicationService->updateSubeventsApplication($application, $selectedSubevents, $loggedUser); + $this->applicationService->updatePayment($application, $values['variableSymbol'], + $values['paymentMethod'] ?: NULL, $values['paymentDate'], + $values['incomeProofPrintedDate'], $values['maturityDate'], $loggedUser); }); - $this->getPresenter()->flashMessage('admin.users.users_applications_saved', 'success'); + $p->flashMessage('admin.users.users_applications_saved', 'success'); $this->redirect('this'); } diff --git a/app/AdminModule/components/UsersGridControl.php b/app/AdminModule/components/UsersGridControl.php index 9f9a5a3df..0fb89025d 100644 --- a/app/AdminModule/components/UsersGridControl.php +++ b/app/AdminModule/components/UsersGridControl.php @@ -17,6 +17,7 @@ use App\Model\Settings\Settings; use App\Model\Settings\SettingsRepository; use App\Model\Structure\SubeventRepository; +use App\Model\User\Application; use App\Model\User\ApplicationRepository; use App\Model\User\User; use App\Model\User\UserRepository; @@ -180,22 +181,22 @@ public function createComponentUsersGrid($name) ->onSelect[] = [$this, 'groupMarkAttended']; $grid->addGroupAction('admin.users.users_group_action_mark_paid_today', $this->preparePaymentMethodOptionsWithoutEmpty()) - ->onSelect[] = [$this, 'groupMarkPaidToday']; //TODO kontrola + ->onSelect[] = [$this, 'groupMarkPaidToday']; $grid->addGroupAction('admin.users.users_group_action_generate_payment_proofs') - ->onSelect[] = [$this, 'groupGeneratePaymentProofs']; //TODO kontrola + ->onSelect[] = [$this, 'groupGeneratePaymentProofs']; $grid->addGroupAction('admin.users.users_group_action_export_users') - ->onSelect[] = [$this, 'groupExportUsers']; //TODO kontrola + ->onSelect[] = [$this, 'groupExportUsers']; $grid->addGroupAction('admin.users.users_group_action_export_subevents_and_categories') - ->onSelect[] = [$this, 'groupExportSubeventsAndCategories']; //TODO kontrola + ->onSelect[] = [$this, 'groupExportSubeventsAndCategories']; $grid->addGroupAction('admin.users.users_group_action_export_roles') - ->onSelect[] = [$this, 'groupExportRoles']; //TODO kontrola + ->onSelect[] = [$this, 'groupExportRoles']; $grid->addGroupAction('admin.users.users_group_action_export_schedules') - ->onSelect[] = [$this, 'groupExportSchedules']; //TODO kontrola + ->onSelect[] = [$this, 'groupExportSchedules']; $grid->addColumnText('displayName', 'admin.users.users_name') @@ -281,14 +282,9 @@ public function createComponentUsersGrid($name) return $this->userService->getPaymentMethodText($row); }); - $grid->addColumnDateTime('lastPaymentDate', 'admin.users.users_last_payment_date'); //TODO kontrola + $grid->addColumnDateTime('lastPaymentDate', 'admin.users.users_last_payment_date'); - $grid->addColumnDateTime('firstApplicationDate', 'admin.users.users_first_application_date') - ->setSortable() - ->setSortableCallback(function ($qb, $sort) { //TODO kontrola - $qb->leftJoin('u.applications', 'aFirstApplicationDate', Expr\Join::WITH, 'aFirstApplicationDate.first = true') - ->orderBy('aFirstApplicationDate.applicationDate', $sort['firstApplicationDate']); - }) + $grid->addColumnDateTime('rolesApplicationDate', 'admin.users.users_roles_application_date') ->setFormat('j. n. Y H:i'); $columnAttended = $grid->addColumnStatus('attended', 'admin.users.users_attended'); diff --git a/app/ApiModule/services/ScheduleService.php b/app/ApiModule/services/ScheduleService.php index f654583a4..14b285576 100644 --- a/app/ApiModule/services/ScheduleService.php +++ b/app/ApiModule/services/ScheduleService.php @@ -110,7 +110,7 @@ public function getProgramsAdmin() */ public function getProgramsWeb() { - $programs = $this->programRepository->findUserAllowed($this->user); + $programs = $this->programService->getUserAllowedPrograms($this->user); $programDetailDTOs = []; foreach ($programs as $program) { $programDetailDTO = $this->convertProgramToProgramDetailDTO($program); @@ -295,7 +295,7 @@ public function attendProgram($programId) $responseDTO->setMessage($this->translator->translate('common.api.schedule_program_already_registered')); elseif ($program->getCapacity() !== NULL && $program->getCapacity() <= $program->getAttendeesCount()) $responseDTO->setMessage($this->translator->translate('common.api.schedule_program_no_vacancies')); - elseif (!(new ArrayCollection($this->programRepository->findUserAllowed($this->user)))->contains($program)) + elseif (!($this->programService->getUserAllowedPrograms($this->user))->contains($program)) $responseDTO->setMessage($this->translator->translate('common.api.schedule_program_category_not_allowed')); elseif (count( array_intersect($this->programRepository->findBlockedProgramsIdsByProgram($program), @@ -396,7 +396,7 @@ private function convertBlockToBlockDetailDTO(Block $block) $blockDetailDTO->setDescription($block->getDescription()); $blockDetailDTO->setProgramsCount($block->getProgramsCount()); $blockDetailDTO->setUserAttends($block->isAttendee($this->user)); - $blockDetailDTO->setUserAllowed($block->isAllowed($this->user)); //TODO kontrola povolení zapisování před zaplacením + $blockDetailDTO->setUserAllowed($block->isAllowed($this->user)); return $blockDetailDTO; } diff --git a/app/WebModule/components/ApplicationContentControl.php b/app/WebModule/components/ApplicationContentControl.php index 817ede16e..30b306ecb 100644 --- a/app/WebModule/components/ApplicationContentControl.php +++ b/app/WebModule/components/ApplicationContentControl.php @@ -82,15 +82,27 @@ public function render($content) $template->guestRole = $user->isInRole($this->roleRepository->findBySystemName(Role::GUEST)->getName()); $template->testRole = Role::TEST; + $explicitSubeventsExists = $this->subeventRepository->explicitSubeventsExists(); + if ($user->isLoggedIn()) { + $dbuser = $this->userRepository->findById($user->id); + $userHasFixedFeeRole = $dbuser->hasFixedFeeRole(); + $template->unapprovedRole = $user->isInRole($this->roleRepository->findBySystemName(Role::UNAPPROVED)->getName()); $template->nonregisteredRole = $user->isInRole($this->roleRepository->findBySystemName(Role::NONREGISTERED)->getName()); $template->bankAccount = $this->settingsRepository->getValue(Settings::ACCOUNT_NUMBER); - $template->subeventsExists = $this->subeventRepository->explicitSubeventsExists(); - $template->dbuser = $this->userRepository->findById($user->id); + $template->dbuser = $dbuser; + $template->userHasFixedFeeRole = $userHasFixedFeeRole; + + $template->usersApplications = $explicitSubeventsExists && $userHasFixedFeeRole + ? $dbuser->getNotCanceledApplications() + : ($explicitSubeventsExists + ? $dbuser->getNotCanceledSubeventsApplications() + : $dbuser->getNotCanceledRolesApplications() + ); } - $template->explicitSubeventsExists = $this->subeventRepository->explicitSubeventsExists(); + $template->explicitSubeventsExists = $explicitSubeventsExists; $template->rolesWithSubevents = json_encode($this->roleRepository->findRolesIds($this->roleRepository->findAllWithSubevents())); $template->render(); diff --git a/app/WebModule/components/ApplicationsGridControl.php b/app/WebModule/components/ApplicationsGridControl.php index 6fa6cec9f..be02d0cbb 100644 --- a/app/WebModule/components/ApplicationsGridControl.php +++ b/app/WebModule/components/ApplicationsGridControl.php @@ -17,6 +17,7 @@ use App\Model\User\ApplicationRepository; use App\Model\User\RolesApplicationRepository; use App\Model\User\SubeventsApplication; +use App\Model\User\SubeventsApplicationRepository; use App\Model\User\User; use App\Model\User\UserRepository; use App\Services\ApplicationService; @@ -88,6 +89,9 @@ class ApplicationsGridControl extends Control /** @var RolesApplicationRepository */ private $rolesApplicationRepository; + /** @var SubeventsApplicationRepository */ + private $subeventsApplicationRepository; + /** * ApplicationsGridControl constructor. @@ -112,7 +116,8 @@ public function __construct(Translator $translator, ApplicationRepository $appli SettingsRepository $settingsRepository, Authenticator $authenticator, PdfExportService $pdfExportService, ProgramService $programService, UserService $userService, Validators $validators, - RolesApplicationRepository $rolesApplicationRepository) + RolesApplicationRepository $rolesApplicationRepository, + SubeventsApplicationRepository $subeventsApplicationRepository) { parent::__construct(); @@ -131,6 +136,7 @@ public function __construct(Translator $translator, ApplicationRepository $appli $this->userService = $userService; $this->validators = $validators; $this->rolesApplicationRepository = $rolesApplicationRepository; + $this->subeventsApplicationRepository = $subeventsApplicationRepository; } /** @@ -264,8 +270,10 @@ public function add($values) foreach ($selectedSubevents as $subevent) $selectedAndUsersSubevents->add($subevent); + $p = $this->getPresenter(); + if (!$this->validators->validateSubeventsCapacities($selectedSubevents, $this->user)) { - $this->getPresenter()->flashMessage('web.profile.applications_subevents_capacity_occupied', 'danger'); + $p->flashMessage('web.profile.applications_subevents_capacity_occupied', 'danger'); $this->redirect('this'); } @@ -274,21 +282,21 @@ public function add($values) $message = $this->translator->translate('web.profile.applications_incompatible_subevents_selected', NULL, ['subevent' => $subevent->getName(), 'incompatibleSubevents' => $subevent->getIncompatibleSubeventsText()] ); - $this->getPresenter()->flashMessage($message, 'danger'); + $p->flashMessage($message, 'danger'); $this->redirect('this'); } if (!$this->validators->validateSubeventsRequired($selectedAndUsersSubevents, $subevent)) { $message = $this->translator->translate('web.profile.applications_required_subevents_not_selected', NULL, ['subevent' => $subevent->getName(), 'requiredSubevents' => $subevent->getRequiredSubeventsTransitiveText()] ); - $this->getPresenter()->flashMessage($message, 'danger'); + $p->flashMessage($message, 'danger'); $this->redirect('this'); } } $this->applicationService->addSubeventsApplication($this->user, $selectedSubevents, $this->user); - $this->getPresenter()->flashMessage('web.profile.applications_add_subevents_successful', 'success'); + $p->flashMessage('web.profile.applications_add_subevents_successful', 'success'); $this->redirect('this'); } @@ -308,9 +316,13 @@ public function edit($id, $values) $selectedAndUsersSubevents = clone $this->user->getSubevents(); foreach ($selectedSubevents as $subevent) $selectedAndUsersSubevents->add($subevent); + foreach ($application->getSubevents() as $subevent) + $selectedAndUsersSubevents->removeElement($subevent); + + $p = $this->getPresenter(); if (!$this->validators->validateSubeventsCapacities($selectedSubevents, $this->user)) { - $this->getPresenter()->flashMessage('web.profile.applications_subevents_capacity_occupied', 'danger'); + $p->flashMessage('web.profile.applications_subevents_capacity_occupied', 'danger'); $this->redirect('this'); } @@ -319,21 +331,21 @@ public function edit($id, $values) $message = $this->translator->translate('web.profile.applications_incompatible_subevents_selected', NULL, ['subevent' => $subevent->getName(), 'incompatibleSubevents' => $subevent->getIncompatibleSubeventsText()] ); - $this->getPresenter()->flashMessage($message, 'danger'); + $p->flashMessage($message, 'danger'); $this->redirect('this'); } if (!$this->validators->validateSubeventsRequired($selectedAndUsersSubevents, $subevent)) { $message = $this->translator->translate('web.profile.applications_required_subevents_not_selected', NULL, ['subevent' => $subevent->getName(), 'requiredSubevents' => $subevent->getRequiredSubeventsTransitiveText()] ); - $this->getPresenter()->flashMessage($message, 'danger'); + $p->flashMessage($message, 'danger'); $this->redirect('this'); } } $this->applicationService->updateSubeventsApplication($application, $selectedSubevents, $this->user); - $this->getPresenter()->flashMessage('web.profile.applications_edit_successful', 'success'); + $p->flashMessage('web.profile.applications_edit_successful', 'success'); $this->redirect('this'); } diff --git a/app/WebModule/components/templates/application_content.latte b/app/WebModule/components/templates/application_content.latte index 7fcc2093f..3bde460ec 100644 --- a/app/WebModule/components/templates/application_content.latte +++ b/app/WebModule/components/templates/application_content.latte @@ -71,13 +71,14 @@

- {*TODO tabulka s přehledem cen*} - - {if $subeventsExists} + {if $userHasFixedFeeRole} + + {/if} + {if $explicitSubeventsExists} {/if} @@ -87,18 +88,18 @@ - {foreach $dbuser->getNotCanceledApplications() as $application} + {foreach $usersApplications as $application} - - {if $subeventsExists} + {if $userHasFixedFeeRole} + + {/if} + {if $explicitSubeventsExists} {/if} - {**} + {/foreach} diff --git a/app/WebModule/forms/ApplicationForm.php b/app/WebModule/forms/ApplicationForm.php index 0cd43873c..0309394a0 100644 --- a/app/WebModule/forms/ApplicationForm.php +++ b/app/WebModule/forms/ApplicationForm.php @@ -370,7 +370,7 @@ private function addSubeventsSelect(Form $form) //generovani chybovych hlasek pro vsechny kombinace podakci foreach ($this->subeventRepository->findAllExplicitOrderedByName() as $subevent) { - if (!$subevent->getIncompatibleSubevents()-isEmpty()) { + if (!$subevent->getIncompatibleSubevents()->isEmpty()) { $subeventsSelect->addRule([$this, 'validateSubeventsIncompatible'], $form->getTranslator()->translate('web.application_content.incompatible_subevents_selected', NULL, ['subevent' => $subevent->getName(), 'incompatibleSubevents' => $subevent->getIncompatibleSubeventsText()] diff --git a/app/lang/admin.cs_CZ.neon b/app/lang/admin.cs_CZ.neon index 1f61ad6c3..cec0dc70d 100644 --- a/app/lang/admin.cs_CZ.neon +++ b/app/lang/admin.cs_CZ.neon @@ -303,7 +303,7 @@ users: users_fee_remaining: "Zbývá doplatit" users_payment_method: "Platební metoda" users_variable_symbol: "Variabilní symbol" - users_first_application_date: "Datum první přihlášky" + users_roles_application_date: "Datum přihlášení" users_last_payment_date: "Datum poslední platby" users_payment_date: "Zaplaceno dne" users_income_proof_printed_date: "Doklad vytištěn" @@ -329,7 +329,7 @@ users: users_group_action_generate_payment_proofs: "Vygenerovat doklady o zaplacení" users_group_action_export_users: "Vyexportovat seznam uživatelů" users_group_action_export_subevents_and_categories: "Vyexportovat seznam uživatelů s podakcemi a programy podle kategorií" - users_group_action_export_roles: "Vyexportovat seznam s rolemi" + users_group_action_export_roles: "Vyexportovat seznam uživatelů s rolemi" users_group_action_export_schedules: "Vyexportovat harmonogramy" users_group_action_change_roles: "Nastavit role" users_group_action_changed_roles: "Vybraným uživatelům byly úspěšně nastaveny role." @@ -351,6 +351,7 @@ users: users_applications_roles: "Role" users_applications_subevents: "Podakce" users_applications_subevents_empty: "Musí být vybrána alespoň jedna podakce." + users_applications_subevents_not_empty: "Nesmí být vybrána žádná podakce." users_applications_subevents_occupied: "Všechna místa na některé podakci jsou obsazena." users_applications_subevents_registered: "Na některou ze zvolených podakcí je uživatel již přihlášen." users_applications_fee: "Cena" @@ -504,8 +505,9 @@ configuration: subevents_heading: "Podakce" subevents_name: "Název" subevents_name_empty: "Zadejte název." - subevents_implicit: "Skrytá" + subevents_implicit: "Systémová" subevents_fee: "Cena" + subevents_fee_empty: "Zadejte cenu." subevents_fee_format: "Zadejte číslo." subevents_capacity: "Kapacita" subevents_capacity_format: "Zadejte číslo." diff --git a/app/model/Program/Program.php b/app/model/Program/Program.php index fbc335dd0..1b81a10db 100644 --- a/app/model/Program/Program.php +++ b/app/model/Program/Program.php @@ -104,7 +104,7 @@ public function setAttendees(Collection $attendees) /** * @param $user */ - public function addAttendee($user) + public function addAttendee(User $user) { if (!$this->attendees->contains($user)) { $this->attendees->add($user); diff --git a/app/model/Structure/Subevent.php b/app/model/Structure/Subevent.php index 8e7d4edc6..28faa223d 100644 --- a/app/model/Structure/Subevent.php +++ b/app/model/Structure/Subevent.php @@ -3,6 +3,7 @@ namespace App\Model\Structure; use App\Model\ACL\Role; +use App\Model\Enums\ApplicationState; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Criteria; @@ -37,7 +38,7 @@ class Subevent /** * Přihlášky. - * @ORM\ManyToMany(targetEntity="\App\Model\User\Application", mappedBy="subevents", cascade={"persist"}) + * @ORM\ManyToMany(targetEntity="\App\Model\User\SubeventsApplication", mappedBy="subevents", cascade={"persist"}) * @var Collection */ protected $applications; diff --git a/app/model/User/Application/Application.php b/app/model/User/Application/Application.php index a74771add..240c7e052 100644 --- a/app/model/User/Application/Application.php +++ b/app/model/User/Application/Application.php @@ -2,7 +2,9 @@ namespace App\Model\User; +use App\Model\ACL\Role; use App\Model\Enums\ApplicationState; +use App\Model\Structure\Subevent; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; @@ -55,6 +57,20 @@ abstract class Application */ protected $user; + /** + * Role. + * @ORM\ManyToMany(targetEntity="\App\Model\ACL\Role") + * @var Collection + */ + protected $roles; + + /** + * Podakce. + * @ORM\ManyToMany(targetEntity="\App\Model\Structure\Subevent", inversedBy="applications", cascade={"persist"}) + * @var Collection + */ + protected $subevents; + /** * Poplatek. * @ORM\Column(type="integer") @@ -131,6 +147,15 @@ abstract class Application */ protected $validTo; + /** + * Application constructor. + */ + public function __construct() + { + $this->roles = new ArrayCollection(); + $this->subevents = new ArrayCollection(); + } + /** * @return int @@ -180,24 +205,38 @@ public function setUser($user) $this->user = $user; } + /** + * @return Collection + */ public function getRoles(): Collection { - return new ArrayCollection(); + return $this->roles; } - public function getRolesText(): ?string + /** + * Vrací názvy rolí oddělené čárkou. + * @return string + */ + public function getRolesText() : string { - return NULL; + return implode(', ', $this->roles->map(function (Role $role) {return $role->getName();})->toArray()); } + /** + * @return Collection + */ public function getSubevents(): Collection { - return new ArrayCollection(); + return $this->subevents; } - public function getSubeventsText(): ?string + /** + * Vrací názvy podakcí oddělené čárkou. + * @return string + */ + public function getSubeventsText() : string { - return NULL; + return implode(', ', $this->subevents->map(function (Subevent $subevent) {return $subevent->getName();})->toArray()); } /** @@ -362,7 +401,7 @@ public function setState($state) /** * @return User */ - public function getCreatedBy(): User + public function getCreatedBy(): ?User { return $this->createdBy; } @@ -370,7 +409,7 @@ public function getCreatedBy(): User /** * @param User $createdBy */ - public function setCreatedBy(User $createdBy) + public function setCreatedBy(?User $createdBy) { $this->createdBy = $createdBy; } diff --git a/app/model/User/Application/RolesApplication.php b/app/model/User/Application/RolesApplication.php index a79e9fc73..e668b3265 100644 --- a/app/model/User/Application/RolesApplication.php +++ b/app/model/User/Application/RolesApplication.php @@ -19,29 +19,6 @@ class RolesApplication extends Application { protected $type = Application::ROLES; - /** - * Role. - * @ORM\ManyToMany(targetEntity="\App\Model\ACL\Role") - * @var Collection - */ - protected $roles; - - - /** - * RolesApplication constructor. - */ - public function __construct() - { - $this->subevents = new ArrayCollection(); - } - - /** - * @return Collection - */ - public function getRoles(): Collection - { - return $this->roles; - } /** * @param Collection $roles @@ -50,13 +27,4 @@ public function setRoles(Collection $roles): void { $this->roles = $roles; } - - /** - * Vrací názvy rolí oddělené čárkou. - * @return string - */ - public function getRolesText(): ?string - { - return implode(', ', $this->roles->map(function (Role $role) {return $role->getName();})->toArray()); - } } diff --git a/app/model/User/Application/SubeventsApplication.php b/app/model/User/Application/SubeventsApplication.php index 6724bd1cd..9c286953c 100644 --- a/app/model/User/Application/SubeventsApplication.php +++ b/app/model/User/Application/SubeventsApplication.php @@ -19,29 +19,6 @@ class SubeventsApplication extends Application { protected $type = Application::SUBEVENTS; - /** - * Podakce. - * @ORM\ManyToMany(targetEntity="\App\Model\Structure\Subevent", inversedBy="applications", cascade={"persist"}) - * @var Collection - */ - protected $subevents; - - - /** - * SubeventsApplication constructor. - */ - public function __construct() - { - $this->subevents = new ArrayCollection(); - } - - /** - * @return Collection - */ - public function getSubevents(): Collection - { - return $this->subevents; - } /** * @param Collection $subevents @@ -50,13 +27,4 @@ public function setSubevents(Collection $subevents): void { $this->subevents = $subevents; } - - /** - * Vrací názvy podakcí oddělené čárkou. - * @return string - */ - public function getSubeventsText(): ?string - { - return implode(', ', $this->subevents->map(function (Subevent $subevent) {return $subevent->getName();})->toArray()); - } } diff --git a/app/model/User/User.php b/app/model/User/User.php index ce6956938..c46dd7918 100644 --- a/app/model/User/User.php +++ b/app/model/User/User.php @@ -486,6 +486,17 @@ public function getNotCanceledApplications(): Collection }); } + /** + * Vrátí nezrušené přihlášky na rolí. + * @return Collection|RolesApplication[] + */ + public function getNotCanceledRolesApplications(): Collection + { + return $this->getNotCanceledApplications()->filter(function (Application $application) { + return $application->getType() == Application::ROLES; + }); + } + /** * Vrátí nezrušené přihlášky na podakce. * @return Collection|SubeventsApplication[] @@ -614,7 +625,6 @@ public function addProgram(Program $program) { if (!$this->programs->contains($program)) { $this->programs->add($program); - $program->addAttendee($this); } } @@ -634,11 +644,9 @@ public function removeProgram(Program $program) */ public function hasProgramBlock(Block $block) { - $criteria = Criteria::create()->where( - Criteria::expr()->eq('block_id', $block->getId()) - ); - - return !$this->programs->matching($criteria)->isEmpty(); + return !$this->programs->filter(function (Program $program) use ($block) { + return $program->getBlock() === $block; + }); } /** @@ -1244,24 +1252,22 @@ public function hasFixedFeeRole(): bool public function hasPaidSubevent(Subevent $subevent) { foreach ($this->getPaidAndFreeApplications() as $application) - if ($application->getType() == Application::SUBEVENTS && $application->getSubevents->contains($subevent)) + if ($application->getType() == Application::SUBEVENTS && $application->getSubevents()->contains($subevent)) return TRUE; return FALSE; } /** - * Vrací datum první přihlášky. + * Vrací datum přihlášení. * @return \DateTime|null */ - public function getFirstApplicationDate() + public function getRolesApplicationDate() { - $minDate = NULL; - foreach ($this->getValidApplications() as $application) { - if ($minDate === NULL || $minDate > $application->getApplicationDate()) - $minDate = $application->getApplicationDate(); + foreach ($this->getNotCanceledRolesApplications() as $application) { + return $application->getApplicationDate(); } - return $minDate; + return NULL; } /** diff --git a/app/model/User/UserRepository.php b/app/model/User/UserRepository.php index cecb5d5b7..1d2572f10 100644 --- a/app/model/User/UserRepository.php +++ b/app/model/User/UserRepository.php @@ -147,9 +147,9 @@ public function findAllWithWaitingForPaymentApplication(): Collection /** * Vrací uživatele, kteří se mohou na program přihlásit. * @param $program - * @return array + * @return Collection|User[] */ - public function findProgramAllowed(Program $program) + public function findProgramAllowed(Program $program): Collection { $qb = $this->createQueryBuilder('u') ->leftJoin('u.programs', 'p', 'WITH', 'p.id = :pid') @@ -172,8 +172,7 @@ public function findProgramAllowed(Program $program) ->setParameter('cid', $program->getBlock()->getCategory()->getId()); } - return $qb->getQuery() - ->getResult(); + return new ArrayCollection($qb->getQuery()->getResult()); } /** diff --git a/app/services/ApplicationService.php b/app/services/ApplicationService.php index dc88edf9b..af9cb060e 100644 --- a/app/services/ApplicationService.php +++ b/app/services/ApplicationService.php @@ -164,7 +164,7 @@ public function register(User $user, Collection $roles, Collection $subevents, U * @return bool * @throws \Throwable */ - public function updateRoles(User $user, Collection $roles, User $createdBy, bool $approve = FALSE): void + public function updateRoles(User $user, Collection $roles, ?User $createdBy, bool $approve = FALSE): void { $oldRoles = clone $user->getRoles(); @@ -245,7 +245,7 @@ public function updateRoles(User $user, Collection $roles, User $createdBy, bool * @param User $createdBy * @throws \Throwable */ - public function cancelRegistration(User $user, string $state, User $createdBy): void + public function cancelRegistration(User $user, string $state, ?User $createdBy): void { $this->applicationRepository->getEntityManager()->transactional(function ($em) use ($user, $state, $createdBy) { $user->setApproved(TRUE); @@ -306,8 +306,8 @@ public function updateSubeventsApplication(SubeventsApplication $application, Co //pokud se podakce nezmenily, nic se neprovede if ($subevents->count() == $oldSubevents->count()) { - $subeventsArray = $subevents->map(function (Role $role) {return $role->getId();})->toArray(); - $oldSubeventsArray = $oldSubevents->map(function (Role $role) {return $role->getId();})->toArray(); + $subeventsArray = $subevents->map(function (Subevent $subevent) {return $subevent->getId();})->toArray(); + $oldSubeventsArray = $oldSubevents->map(function (Subevent $subevent) {return $subevent->getId();})->toArray(); if (array_diff($subeventsArray, $oldSubeventsArray) === array_diff($oldSubeventsArray, $subeventsArray)) return; @@ -344,7 +344,7 @@ public function updateSubeventsApplication(SubeventsApplication $application, Co * @param User $createdBy * @throws \Throwable */ - public function cancelSubeventsApplication(SubeventsApplication $application, string $state, User $createdBy): void + public function cancelSubeventsApplication(SubeventsApplication $application, string $state, ?User $createdBy): void { $this->applicationRepository->getEntityManager()->transactional(function ($em) use ($application, $state, $createdBy) { $user = $application->getUser(); @@ -380,8 +380,8 @@ public function cancelSubeventsApplication(SubeventsApplication $application, st * @param User $createdBy * @throws \Throwable */ - public function updatePayment(Application $application, string $variableSymbol, string $paymentMethod, - \DateTime $paymentDate, \DateTime $incomeProofPrintedDate, \DateTime $maturityDate, + public function updatePayment(Application $application, string $variableSymbol, ?string $paymentMethod, + ?\DateTime $paymentDate, ?\DateTime $incomeProofPrintedDate, ?\DateTime $maturityDate, User $createdBy): void { $oldVariableSymbol = $application->getVariableSymbolText(); @@ -430,7 +430,7 @@ public function updatePayment(Application $application, string $variableSymbol, }); if ($paymentDate !== NULL && $oldPaymentDate === NULL) { - $this->mailService->sendMailFromTemplate($this->user, '', Template::PAYMENT_CONFIRMED, [ + $this->mailService->sendMailFromTemplate($application->getUser(), '', Template::PAYMENT_CONFIRMED, [ TemplateVariable::SEMINAR_NAME => $this->settingsRepository->getValue(Settings::SEMINAR_NAME), TemplateVariable::APPLICATION_SUBEVENTS => $application->getSubeventsText() ]); @@ -585,13 +585,13 @@ private function countSubeventsFee(Collection $roles, Collection $subevents) foreach ($subevents as $subevent) { $fee += $subevent->getFee(); } - return $fee; + break; } } - //TODO sleva + $discount = $this->discountService->countDiscount($this->subeventRepository->findSubeventsIds($subevents)); - return $fee; + return $fee - $discount; } /** diff --git a/app/services/ExcelExportService.php b/app/services/ExcelExportService.php index 13b5881cd..1242fe864 100644 --- a/app/services/ExcelExportService.php +++ b/app/services/ExcelExportService.php @@ -421,17 +421,15 @@ public function exportUsersList($users, $filename) $sheet->setCellValueByColumnAndRow($column++, $row, $user->getLastPaymentDate() !== NULL ? $user->getLastPaymentDate()->format("j. n. Y") : ''); - $sheet->setCellValueByColumnAndRow($column++, $row, $user->getFirstApplicationDate() !== NULL ? $user->getFirstApplicationDate()->format("j. n. Y") : ''); + $sheet->setCellValueByColumnAndRow($column++, $row, $user->getRolesApplicationDate() !== NULL ? $user->getRolesApplicationDate()->format("j. n. Y") : ''); $sheet->setCellValueByColumnAndRow($column++, $row, $user->isAttended() ? $this->translator->translate('common.export.common.yes') : $this->translator->translate('common.export.common.no') ); - $sheet->setCellValueByColumnAndRow($column++, $row, - ($user->isAllowed(Resource::PROGRAM, Permission::CHOOSE_PROGRAMS) && $user->isApproved()) - ? implode(', ', $this->programService->getUnregisteredUserMandatoryBlocksNames($user)) - : '' + $sheet->setCellValueByColumnAndRow($column++, $row, $user->isAllowedRegisterPrograms() + ? $this->programService->getUnregisteredUserMandatoryBlocksNamesText($user) : '' ); foreach ($this->customInputRepository->findAllOrderedByPosition() as $customInput) { @@ -522,8 +520,7 @@ public function exportUsersSubeventsAndCategories($users, $filename) $column = 0; $sheet->getCellByColumnAndRow($column++, $row) - ->setValueExplicit($user->getFirstApplication() ? $user->getFirstApplication()->getVariableSymbol() : '', - PHPExcel_Cell_DataType::TYPE_STRING); + ->setValueExplicit($user->getVariableSymbolsText(), PHPExcel_Cell_DataType::TYPE_STRING); $sheet->setCellValueByColumnAndRow($column++, $row, $user->getFirstName()); diff --git a/app/services/PdfExportService.php b/app/services/PdfExportService.php index de1a47711..d1c07a1e0 100644 --- a/app/services/PdfExportService.php +++ b/app/services/PdfExportService.php @@ -119,7 +119,7 @@ public function generateUsersPaymentProof(User $user, $filename, User $createdBy */ private function prepareUsersPaymentProof(User $user, User $createdBy) { - foreach ($user->getApplications() as $application) { + foreach ($user->getNotCanceledApplications() as $application) { $this->prepareApplicationsPaymentProof($application, $createdBy); } } diff --git a/app/services/ProgramService.php b/app/services/ProgramService.php index 7bb6a6a1b..0747f3f23 100644 --- a/app/services/ProgramService.php +++ b/app/services/ProgramService.php @@ -95,17 +95,16 @@ public function updateUserPrograms(User $user) public function updateUsersPrograms($users) { foreach ($users as $user) { - $oldUsersPrograms = $user->getPrograms(); + $oldUsersPrograms = clone $user->getPrograms(); $userAllowedPrograms = $this->getUserAllowedPrograms($user); - $newUsersPrograms = new ArrayCollection(); + $user->getPrograms()->clear(); foreach ($userAllowedPrograms as $userAllowedProgram) { if ($userAllowedProgram->getBlock()->getMandatory() == 2 || $oldUsersPrograms->contains($userAllowedProgram)) - $newUsersPrograms->add($userAllowedProgram); + $user->addProgram($userAllowedProgram); } - $user->setPrograms($newUsersPrograms); $this->userRepository->save($user); } } diff --git a/migrations/Version20171227203925.php b/migrations/Version20171227203925.php new file mode 100644 index 000000000..84ea1bb80 --- /dev/null +++ b/migrations/Version20171227203925.php @@ -0,0 +1,30 @@ +abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.'); + + $this->addSql('CREATE TABLE application_role (application_id INT NOT NULL, role_id INT NOT NULL, INDEX IDX_A085E2E23E030ACD (application_id), INDEX IDX_A085E2E2D60322AC (role_id), PRIMARY KEY(application_id, role_id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB'); + $this->addSql('CREATE TABLE application_subevent (application_id INT NOT NULL, subevent_id INT NOT NULL, INDEX IDX_FE263A6E3E030ACD (application_id), INDEX IDX_FE263A6E7A675502 (subevent_id), PRIMARY KEY(application_id, subevent_id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB'); + $this->addSql('ALTER TABLE application_role ADD CONSTRAINT FK_A085E2E23E030ACD FOREIGN KEY (application_id) REFERENCES application (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE application_role ADD CONSTRAINT FK_A085E2E2D60322AC FOREIGN KEY (role_id) REFERENCES role (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE application_subevent ADD CONSTRAINT FK_FE263A6E3E030ACD FOREIGN KEY (application_id) REFERENCES application (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE application_subevent ADD CONSTRAINT FK_FE263A6E7A675502 FOREIGN KEY (subevent_id) REFERENCES subevent (id) ON DELETE CASCADE'); + $this->addSql('DROP TABLE roles_application_role'); + $this->addSql('DROP TABLE subevents_application_subevent'); + } + + public function down(Schema $schema) + { + } +}
{_web.application_content.application_date}{_web.application_content.application_roles}{_web.application_content.application_roles}{_web.application_content.application_subevents}{_web.application_content.application_fee}
{$application->getApplicationDate()->format('j. n. Y')} - - {$application->getRolesText()}{$application->getSubeventsText()}{$application->getFee()} {$application->getVariableSymbolText()}{$application->getMaturityDate()->format('j. n. Y')}{$application->getMaturityDate() ? $application->getMaturityDate()->format('j. n. Y') : ""} {_'common.application_state.'.$application->getState()}