src/Controller/ApiV2/Residents/PollController.php line 194

  1. <?php
  2. namespace App\Controller\ApiV2\Residents;
  3. use App\Controller\ApiV2\AbstractController;
  4. use App\Entity\Flat;
  5. use App\Entity\MoneyLog;
  6. use App\Entity\Poll;
  7. use App\Exception\FormException;
  8. use App\Form\ApiV2\PollOptionIdType;
  9. use App\Repository\BuildingRepository;
  10. use App\Repository\FlatRepository;
  11. use App\Repository\PollOptionRepository;
  12. use App\Repository\PollRepository;
  13. use App\Security\Voter\DTO\FlatPoll;
  14. use App\Security\Voter\FlatPollVoter;
  15. use App\Security\Voter\FlatVoter;
  16. use App\Services\PollService;
  17. use App\Services\SendGrid\SendBillsSendGridService;
  18. use Doctrine\ORM\NonUniqueResultException;
  19. use Doctrine\ORM\NoResultException;
  20. use FOS\RestBundle\Controller\Annotations as Rest;
  21. use Psr\Container\ContainerExceptionInterface;
  22. use Psr\Container\NotFoundExceptionInterface;
  23. use Symfony\Component\HttpFoundation\Request;
  24. use Symfony\Component\HttpFoundation\Response;
  25. use Symfony\Component\HttpFoundation\StreamedResponse;
  26. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  27. class PollController extends AbstractController
  28. {
  29. private FlatRepository $flatRepository;
  30. private PollService $pollService;
  31. private PollRepository $pollRepository;
  32. private PollOptionRepository $pollOptionRepository;
  33. private SendBillsSendGridService $sendBillsSendGridService;
  34. private string $sendGridMailFromName;
  35. private string $pollsFilesDirectory;
  36. /**
  37. * @param BuildingRepository $buildingRepository
  38. * @param FlatRepository $flatRepository
  39. * @param PollRepository $pollRepository
  40. * @param PollOptionRepository $pollOptionRepository
  41. * @param PollService $pollService
  42. * @param SendBillsSendGridService $sendBillsSendGridService
  43. * @param string $sendGridMailFromName
  44. * @param string $pollsFilesDirectory
  45. */
  46. public function __construct(
  47. BuildingRepository $buildingRepository,
  48. FlatRepository $flatRepository,
  49. PollRepository $pollRepository,
  50. PollOptionRepository $pollOptionRepository,
  51. PollService $pollService,
  52. SendBillsSendGridService $sendBillsSendGridService,
  53. string $sendGridMailFromName,
  54. string $pollsFilesDirectory
  55. ) {
  56. parent::__construct($buildingRepository);
  57. $this->flatRepository = $flatRepository;
  58. $this->pollService = $pollService;
  59. $this->pollRepository = $pollRepository;
  60. $this->pollOptionRepository = $pollOptionRepository;
  61. $this->sendBillsSendGridService = $sendBillsSendGridService;
  62. $this->sendGridMailFromName = $sendGridMailFromName;
  63. $this->pollsFilesDirectory = $pollsFilesDirectory;
  64. }
  65. /**
  66. * @param Request $request
  67. * @param int $id
  68. * @return array<string, mixed>
  69. * @throws NoResultException
  70. * @throws NonUniqueResultException
  71. */
  72. #[Rest\Get('/', name: 'residents_flats_polls_index')]
  73. public function index(Request $request, int $id): array
  74. {
  75. $status = $request->query->get('status') ?? 'active';
  76. $flat = $this->flatRepository->find($id);
  77. $this->isFlatAccessible($flat);
  78. $queryOptions = $this->getListOptions($request);
  79. if ($status === 'active') {
  80. return $this->pollService->getActiveBuildingPolls($flat->getBuilding(), $queryOptions);
  81. }
  82. return $this->pollService->getFinishedBuildingPolls($flat->getBuilding(), $queryOptions);
  83. }
  84. /**
  85. * @param int $id
  86. * @param int $pollId
  87. * @return array<string, mixed>
  88. * @throws NonUniqueResultException
  89. */
  90. #[Rest\Get('/{pollId}', name: 'residents_flats_polls_show')]
  91. public function show(int $id, int $pollId): array
  92. {
  93. $flat = $this->flatRepository->find($id);
  94. /** @var Poll $poll */
  95. $poll = $this->pollRepository->find($pollId);
  96. $this->isPollAccessible($flat, $poll);
  97. return [
  98. 'data' => $this->pollRepository->getPollWithFlatVotes($poll->getId())
  99. ];
  100. }
  101. /**
  102. * @param Request $request
  103. * @param int $id
  104. * @param int $pollId
  105. * @return array<string, mixed>
  106. */
  107. #[Rest\Post('/{pollId}/options', name: 'residents_flats_polls_vote')]
  108. public function vote(Request $request, int $id, int $pollId): array
  109. {
  110. $flat = $this->flatRepository->find($id);
  111. /** @var Poll $poll */
  112. $poll = $this->pollRepository->find($pollId);
  113. $this->isPollAccessible($flat, $poll);
  114. try {
  115. $pollVoteData = $this->validateForm($request, PollOptionIdType::class, null, [
  116. 'optionTypes' => $this->pollService->getAllPollOptionIdsForPoll($poll)
  117. ]);
  118. $pollOption = $this->pollOptionRepository->find($pollVoteData['option_type']);
  119. $hasVotedForSameOption = $flat->getVotedOptions()->contains($pollOption);
  120. foreach ($poll->getPollOptions() as $option) {
  121. if ($flat->getVotedOptions()->contains($option)) {
  122. $flat->removePollOption($option);
  123. }
  124. }
  125. if (!$hasVotedForSameOption) {
  126. $flat->addPollOption($pollOption);
  127. }
  128. $subject = sprintf("eGlasanje za zgradu %s", $flat->getBuilding()->getAddress());
  129. $text = sprintf(
  130. "Poštovani, <br><br>
  131. Vlasnik stana <b>%s</b>, broj stana <b>%s</b>, dana <b>%s</b> glasao/la je <b>%s</b> po pitanju:<br>
  132. <b>%s</b><br><br>
  133. Glasanje je započeto dana <b>%s</b>, a zaršava se dana <b>%s</b> <br>
  134. Ova potvrda predstavlja pisani trag u skladu sa Zakonom o stanovanju i održavanju zgrada<br>
  135. (Sl. glasnik RS, br. 104/2016 i 9/2020).<br><br><hr>
  136. <i>Ovim potvrđujem da je glasanje sprovedeno elektronskim putem preko aplikacije Troškovi,<br>
  137. koja omogućava validno e-glasanje u skladu sa važećim zakonskim propisima.</i>",
  138. sprintf('%s %s', $flat->getOwnerLastname(), $flat->getOwnerName()),
  139. $flat->getDisplayFlatId(),
  140. date("d.m.Y."),
  141. $pollOption->getDescription(),
  142. $poll->getDescription(),
  143. $poll->getStartsAt()->format('d.m.Y.'),
  144. $poll->getEndsAt()->format('d.m.Y.')
  145. );
  146. // $this->sendBillsSendGridService->sendEmail(
  147. // $subject,
  148. // [$flat->getUser()->getEmail()],
  149. // $this->sendGridMailFromName,
  150. // $text,
  151. // [],
  152. // null,
  153. // null,
  154. // null,
  155. // null,
  156. // true,
  157. // );
  158. $this->flatRepository->save($flat);
  159. return [
  160. 'data' => $pollOption
  161. ];
  162. } catch (FormException $exception) {
  163. return $exception->getFormError();
  164. }
  165. }
  166. /**
  167. * @param Flat|null $flat
  168. */
  169. private function isFlatAccessible(?Flat $flat): void
  170. {
  171. if (!$flat) {
  172. throw $this->createNotFoundException('Stan nije pronađen.');
  173. }
  174. $this->denyAccessUnlessGranted(FlatVoter::FLAT_BELONGS_TO_RESIDENT, $flat);
  175. }
  176. /**
  177. * @param Flat $flat
  178. * @param Poll|null $poll
  179. */
  180. private function isPollAccessible(Flat $flat, ?Poll $poll): void
  181. {
  182. $this->isFlatAccessible($flat);
  183. if (!$poll) {
  184. throw $this->createNotFoundException('Elektronsko glasanje nije pronađeno.');
  185. }
  186. $this->denyAccessUnlessGranted(
  187. FlatPollVoter::FLAT_AND_POLL_BELONG_TO_SAME_BUILDING,
  188. new FlatPoll($flat, $poll)
  189. );
  190. }
  191. /**
  192. * @param int $id
  193. * @param int $pollId
  194. * @return Response
  195. */
  196. #[Rest\Get('/pdf/{pollId}', name: 'resident_poll_pdf')]
  197. public function getPollPdf(int $id, int $pollId): Response
  198. {
  199. $flat = $this->flatRepository->find($id);
  200. $this->denyAccessUnlessGranted(FlatVoter::FLAT_BELONGS_TO_RESIDENT, $flat);
  201. if (!$flat) {
  202. throw $this->createNotFoundException('Stan nije pronađen.');
  203. }
  204. /** @var Poll $poll */
  205. $poll = $this->pollRepository->find($pollId);
  206. $this->isPollAccessible($flat, $poll);
  207. $filePath = sprintf("%s%s", $this->pollsFilesDirectory, $poll->getFile());
  208. $fileContent = file_get_contents($filePath);
  209. return new Response($fileContent, 200, [
  210. 'Content-Type' => 'application/pdf',
  211. 'Content-Disposition' => sprintf("%s.pdf", md5($pollId))
  212. ]);
  213. }
  214. }