| Version 3 (modified by , 17 months ago) ( diff ) |
|---|
Напреден апликативен развој
Во последната верзија апликацијата имплементирани се следните сценарија (сите од прототипот и дополнителни):
| ID | UseCase |
|---|---|
| 1 | Прегледува избирачки список |
| 2 | Ажурира избирачки список |
| 3 | Прегледува изборни единици |
| 4 | Ажурира изборни единици |
| 5 | Прегледува гласачки места |
| 6 | Aжурира гласачки места |
| 7 | Креира инстанца од избори |
| 8 | Пријавува учество на партија и кандидати |
| 9 | Назначува членови на комисија |
| 10 | Гласа онлајн |
| 11 | Доделува идентификациски код за гласање со физичко присуство |
| 12 | Гласа со физичко присуство |
| 13 | Прегледува вкупна излезност |
| 14 | Прегледува статистики од излезност по критериуми |
| 15 | Прегледува вкунпи резултати од избори со кандидат |
| 16 | Прегледува вкунпи резултати од избори со кандидатски листи |
| 16 | Прегледува статистики од резултати од избори по критериуми |
| 17 | Поднесува приговор |
| 18 | Одлучува по приговорот |
| 19 | Пријавува учество на кандидатски листи |
Назначува членови на комисија
Администраторот пристапува на адреса /admin/committee каде му се отвора страница на која се прикажани сите комисии и формулар за внесување податоци за нова комисија. За ова е одговорен следниот контролер:
@GetMapping("admin/committee")
public String showCommittee(Model m) {
m.addAttribute("realizations", electionRealizationService.findAll());
m.addAttribute("committeeMembers", committeeMemberService.findAll());
m.addAttribute("pollingStations", addressService.findAllPollingStations());
m.addAttribute("committees", committeeService.findAll());
m.addAttribute("committeeForm", new Committee());
m.addAttribute("replaceTemplate", "add_comitee");
return "admin";
}
По внесување на податоците и клик на копчето „Запиши“ се праќа POST барање до контролерот кој ги обработува.
@PostMapping("/admin/committee")
public String addCommittee(
@RequestParam(required = false) Long id,
@RequestParam Long electionRealization,
@RequestParam Long pollingStation,
@RequestParam List<Long> membersId
) {
committeeService.update(id, pollingStation, electionRealization, membersId);
return "redirect:/admin/committee";
}
Контролерот повикува функција од committeeService за додавање и ажурирање на комисии каде се креира нова инстанца од објектот Committee, и за истиот се полнат добиентите податоци од формуларот. Дополнително, се додаваат и членовите на комисијата кои се во many-to-many релација со комисијата. Оттаму се повикува функцијата save од committeeRepository кој наследува од JpaRepository. Таа служи за зачувување на новиот објект во базата. За да се обезбеди интегритет и конзистентност на податоците, методот е анотиран со @Transactional, односно функцијата успешно ќе заврши ако и само ако успешно се запишат и комисијата и членовите.
@Transactional
@Override
public Committee update(Long id, Long pollingStationId, Long electionRealizationId, List<Long> membersId) {
Committee committee;
if (id != null){
committee = findById(id);
} else {
committee = new Committee();
}
committee.setPollingStation(addressService.findPollingStationById(pollingStationId));
committee.setElectionRealization(electionRealizationService. findById(electionRealizationId));
committeeRepository.save(committee);
membersId.forEach(memberId -> addMemberToCommittee(committee.getId(), memberId));
return committeeRepository.save(committee);
}
Истава имплементација, преточена во SQL прашалникот кој се извршува позадински би изгледала вака:
DO $$
DECLARE
new_kom_id BIGINT;
BEGIN
INSERT INTO komisii (im_id, ri_id) VALUES (1, 1)
RETURNING kom_id INTO new_kom_id;
INSERT INTO se_clenovi_na (g_id, kom_id) VALUES (20, new_kom_id);
INSERT INTO se_clenovi_na (g_id, kom_id) VALUES (21, new_kom_id);
INSERT INTO se_clenovi_na (g_id, kom_id) VALUES (22, new_kom_id);
INSERT INTO se_clenovi_na (g_id, kom_id) VALUES (23, new_kom_id);
INSERT INTO se_clenovi_na (g_id, kom_id) VALUES (24, new_kom_id);
COMMIT;
END $$;
Доделува идентификациски код за гласање со физичко присуство
Корисниците со улога членови на комисија, можат да се најават на системот и пристапат на адресата /admin/electionRealizationInterface, при што добиваат преглед на избирачкиот список од реализацијата којашто се одржува на деновите на најава, за гласачкото место во кое се одговорни. Дополнително, на крајот на редот достапна е акцијата „Гласај“ со што можат да генерираат идентификациски код за гласање доколку гласачот сака да го оствари правото на глас со физичко присуство. Контролерот кој ја опслужува оваа акција е следен:
@GetMapping("/admin/electionRealizationInterface")
public String showElectionRealization(Model m, Principal p, Authentication authentication) {
UserProfile userProfile = (UserProfile) authentication.getPrincipal();
m.addAttribute("realization", committeeService.findElectionRealizationByCitizen(userProfile.getCitizen().getId()));
m.addAttribute("citizens", committeeService.getCitizens(userProfile.getCitizen().getId()));
m.addAttribute("replaceTemplate","election_realization_interface");
return "index";
}
За да се избегнат било какви манипулации и приказ на информации кои не треба да се достапни за најавениот корисник, неговиот идентитет се утврдува директно на серверска страна, од најавениот корисник. Дополнително во сервисите се процесираат реализацијата и избирачкиот список кој треба да го гледа корисникот.
@Override
public List<Citizen> getCitizens(Long committeeId) {
CommitteeMember committeeMember = committeeMemberRepository.findById(committeeId).orElseThrow(RuntimeException::new);
Committee committee = committeeRepository.findCommitteeByMembersContainsAndElectionRealization_DateIsAfter(committeeMember, LocalDate.now().minusDays(1));
PollingStation pollingStation = committee.getPollingStation();
return citizenRepository.findAllByAddress_PollingStation(pollingStation.getId()).stream().filter(x -> x instanceof Citizen).toList();
}
Во committeeService-от се пронаѓа членот на комисија кој го претставува корисничкиот профил, комисијата во која е член, како и избирачкиот список за гласачкото местоо за кое е одговорна. Во програмската имплементација, ова се прави со повик на соодветни методи од Spring Data JPA, а во SQL би изгледало вака:
select *
from komisii k
join se_clenovi_na ck on k.kom_id = ck.kom_id
join realizacii_na_izbori ri on ri.ri_id = k.ri_id
where ck.g_id = 1 and ri.ri_id = 1 and ri.ri_datum = CURRENT_DATE
limit 1
Attachments (9)
- komisii_1.png (65.0 KB ) - added by 17 months ago.
- komisii_2.png (155.6 KB ) - added by 17 months ago.
- kod.png (36.8 KB ) - added by 17 months ago.
- kod.2.png (36.8 KB ) - added by 17 months ago.
- glas_kod.png (18.7 KB ) - added by 17 months ago.
- izleznost.png (120.0 KB ) - added by 17 months ago.
- rezultati.png (115.3 KB ) - added by 17 months ago.
- kandidatska_lista.png (77.0 KB ) - added by 17 months ago.
- kandidatska_lista_2.png (81.4 KB ) - added by 17 months ago.
Download all attachments as: .zip
