Commit e212f31b authored by OlegPahhomov's avatar OlegPahhomov

Merge branch 'dashboard-roles' into 'master'

SA0140-547, SA0140-548, SA0140-549 | Dashboard roles

See merge request statistics-estonia/juhtimislauad/dashboard-backend!5
parents de04b3d1 0af609bb
......@@ -46,7 +46,7 @@ public class DashboardAdminController {
}
@GetMapping(path = "/{dashboardId}")
@Secured(RoleString.ADMIN)
// @Secured(RoleString.ADMIN)
public Response<DashboardAdminResponse> findById(@PathVariable Long dashboardId) {
return of(dashboardAdminService.findById(dashboardId));
}
......
package ee.stat.dashboard.controller.element;
import ee.stat.dashboard.controller.Response;
import ee.stat.dashboard.model.widget.back.enums.Language;
import ee.stat.dashboard.service.element.ClassifierService;
import ee.stat.dashboard.service.element.dto.ClassifierResponse;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import static ee.stat.dashboard.controller.Response.of;
@RestController
@RequestMapping("/classifier")
@AllArgsConstructor
public class ClassifierController {
private ClassifierService classifierService;
@GetMapping("roles")
public Response<List<ClassifierResponse>> findAll(@RequestParam(defaultValue = "et") String language) {
return of(classifierService.getRoles(Language.getValue(language)));
}
}
package ee.stat.dashboard.controller.element.dto;
package ee.stat.dashboard.controller.element;
import ee.stat.dashboard.controller.Response;
import ee.stat.dashboard.controller.element.ElementStrategy;
import ee.stat.dashboard.controller.element.dto.ElementStrategy;
import ee.stat.dashboard.model.classifier.ClassifierCode;
import ee.stat.dashboard.model.widget.back.enums.Language;
import ee.stat.dashboard.service.element.ElementService;
import ee.stat.dashboard.service.element.dto.ElementResponse;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import static ee.stat.dashboard.controller.Response.of;
import static org.apache.commons.lang3.BooleanUtils.isTrue;
import static org.apache.commons.collections4.CollectionUtils.isNotEmpty;
@RestController
@RequestMapping("/element")
......@@ -23,17 +26,17 @@ public class ElementController {
private ElementService elementService;
@GetMapping
public Response findAll(@RequestParam ClassifierCode clfCode,
@RequestParam(defaultValue = "et") String language,
@RequestParam(required = false) Integer level,
@RequestParam(required = false) String elementCode,
@RequestParam(required = false) Boolean connections
public Response<List<ElementResponse>> findAll(@RequestParam ClassifierCode clfCode,
@RequestParam(defaultValue = "et") String language,
@RequestParam(required = false) List<Integer> level,
@RequestParam(required = false) Long parentId,
@RequestParam(required = false) String elementCode,
@RequestParam(defaultValue = "FLAT") ElementStrategy elementStrategy
) {
if (level == null && elementCode == null) {
return of(elementService.findAll(clfCode, Language.getValue(language)));
if (isNotEmpty(level) || parentId != null || elementCode != null) {
return of(elementService.findAll(clfCode, Language.getValue(language), level, parentId, elementCode, elementStrategy));
}
ElementStrategy strategy = isTrue(connections) ? ElementStrategy.LOAD_CHILDREN : ElementStrategy.LIGHTWEIGHT;
return of(elementService.findAll(clfCode, Language.getValue(language), level, elementCode, strategy));
return of(elementService.findAll(clfCode, Language.getValue(language)));
}
}
package ee.stat.dashboard.controller.element;
public enum ElementStrategy {
LOAD_CHILDREN, LIGHTWEIGHT
}
package ee.stat.dashboard.controller.element.dto;
public enum ElementStrategy {
TREE, FLAT;
public boolean isFlat(){
return this == FLAT;
}
}
package ee.stat.dashboard.controller.publics;
import ee.stat.dashboard.config.security.RoleString;
import ee.stat.dashboard.config.security.StatUser;
import ee.stat.dashboard.controller.Response;
import ee.stat.dashboard.controller.user.UserSessionHolder;
import ee.stat.dashboard.model.widget.back.enums.Language;
import ee.stat.dashboard.service.dashboard.RoleDashboardService;
import ee.stat.dashboard.service.dashboard.DashboardSaveService;
import ee.stat.dashboard.service.dashboard.DashboardService;
import ee.stat.dashboard.service.dashboard.MyDashboardService;
import ee.stat.dashboard.service.dashboard.dto.DashboardResponse;
import ee.stat.dashboard.service.dashboard.dto.RoleDashboardResponse;
import ee.stat.dashboard.service.dashboard.dto.UserDashboardDto;
import ee.stat.dashboard.service.dashboard.dto.UserWidgetsDto;
import lombok.AllArgsConstructor;
import org.springframework.security.access.annotation.Secured;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import static ee.stat.dashboard.controller.Response.of;
@RestController
@RequestMapping("/v2/dashboard")
@AllArgsConstructor
public class DashboardV2Controller {
private RoleDashboardService roleDashboardService;
private DashboardService dashboardService;
private MyDashboardService myDashboardService;
private DashboardSaveService dashboardSaveService;
@GetMapping
public Response<List<RoleDashboardResponse>> findAll(@RequestParam(defaultValue = "et") String language) {
return of(roleDashboardService.findAll(Language.getValue(language)));
}
@GetMapping(path = "/{dashboardId}")
public Response<DashboardResponse> findById(@PathVariable Long dashboardId,
@RequestParam(defaultValue = "et") String language) {
StatUser user = UserSessionHolder.getLoggedInUser();
return of(dashboardService.findById(dashboardId, Language.getValue(language), user));
}
@GetMapping(path = "/me")
@Secured(RoleString.USER)
public Response<DashboardResponse> myDashboard(@RequestParam(defaultValue = "et") String language) {
StatUser user = UserSessionHolder.getLoggedInUserOrThrow("user");
return of(myDashboardService.findMyDashboard(Language.getValue(language), user));
}
@PatchMapping(path = "/{dashboardId}/region")
@Secured(RoleString.USER)
public Response<DashboardResponse> saveSelectedRegion(@PathVariable Long dashboardId,
@RequestBody UserDashboardDto preferences) {
StatUser user = UserSessionHolder.getLoggedInUserOrThrow(dashboardId);
Long savedDashboard = dashboardSaveService.saveRegion(dashboardId, preferences, user);
return of(dashboardService.findById(savedDashboard, Language.getValue(preferences.getLanguage()), user));
}
@PatchMapping(path = "/{dashboardId}/widgets")
@Secured(RoleString.USER)
public Response<DashboardResponse> saveSelectedWidgets(@PathVariable Long dashboardId,
@RequestBody UserWidgetsDto preferences) {
StatUser user = UserSessionHolder.getLoggedInUserOrThrow(dashboardId);
Long savedDashboard = dashboardSaveService.saveWidgetsAndSetVisited(dashboardId, preferences, user);
return of(dashboardService.findById(savedDashboard, Language.getValue(preferences.getLanguage()), user));
}
}
package ee.stat.dashboard.model.classifier;
import ee.stat.dashboard.model.widget.back.enums.Language;
import lombok.Getter;
import lombok.Setter;
......@@ -20,6 +21,11 @@ public class Classifier {
private Long id;
@Enumerated(EnumType.STRING)
private ClassifierCode code;
private String name;
private String description;
private String nameEt;
private String nameEn;
private Integer orderNr;
public String getName(Language lang) {
return lang.isEt() ? nameEt : nameEn;
}
}
package ee.stat.dashboard.model.classifier;
import java.util.Arrays;
import java.util.List;
public enum ClassifierCode {
EHAK
EHAK,
GOV,
BUSINESS;
public static List<ClassifierCode> getRoleClassifiers(){
return Arrays.asList(GOV, EHAK, BUSINESS);
};
}
package ee.stat.dashboard.model.classifier;
import ee.stat.dashboard.model.dashboard.Dashboard;
public enum DashboardRule {
ONE_DASHBOARD, DASHBOARDS, SUB_DASHBOARDS;
public boolean isDashboards(){
return this == DASHBOARDS;
}
public boolean isSubDashboards(){
return this == SUB_DASHBOARDS;
}
public boolean isOneDashboards(){
return this == ONE_DASHBOARD;
}
}
package ee.stat.dashboard.model.classifier;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.time.LocalDateTime;
@Getter
@Setter
@Entity
public class RoleDashboard {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long dashboard;
private Long roleElement;
private Long roleClassifier;
@Enumerated(EnumType.STRING)
private DashboardRule dashboardRule;
private LocalDateTime createdAt;
}
package ee.stat.dashboard.repository;
import ee.stat.dashboard.model.classifier.Classifier;
import ee.stat.dashboard.model.classifier.ClassifierCode;
import ee.stat.dashboard.model.classifier.Element;
import ee.stat.dashboard.repository.custom.ElementCustomRepository;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface ClassifierRepository extends JpaRepository<Classifier, Long> {
Classifier findByCode(ClassifierCode code);
List<Classifier> findByCodeInOrderByOrderNr(List<ClassifierCode> code);
}
......@@ -4,7 +4,7 @@ import ee.stat.dashboard.model.process.Process;
import ee.stat.dashboard.model.process.enums.ProcessCode;
import org.springframework.data.jpa.repository.JpaRepository;
public interface ProcessRepository extends JpaRepository<ee.stat.dashboard.model.process.Process, Long> {
public interface ProcessRepository extends JpaRepository<Process, Long> {
Process findByCode(ProcessCode code);
}
package ee.stat.dashboard.repository;
import ee.stat.dashboard.model.classifier.RoleDashboard;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface RoleDashboardRepository extends JpaRepository<RoleDashboard, Long> {
List<RoleDashboard> findByRoleClassifier(Long roleClassifier);
List<RoleDashboard> findByRoleElement(Long roleElement);
List<RoleDashboard> findByDashboard(Long dashboard);
void deleteByDashboard(Long dashboard);
}
......@@ -2,6 +2,8 @@ package ee.stat.dashboard.repository.custom;
import ee.stat.dashboard.model.classifier.ClassifierCode;
import ee.stat.dashboard.model.classifier.Element;
import ee.stat.dashboard.model.widget.back.enums.Language;
import ee.stat.dashboard.service.element.dto.RoleStrategy;
import java.util.List;
......@@ -19,6 +21,8 @@ public interface ElementCustomRepository {
List<Element> findAllByClfCode(ClassifierCode code);
List<Element> findAllByClfCodeAndRoleOrderByName(ClassifierCode code, RoleStrategy role, Language language);
List<Element> findAllByClfCodeAndElCode(ClassifierCode code, String elementCode);
List<Element> findAllByClfCodeAndLevel(ClassifierCode code, Integer level);
......
......@@ -2,6 +2,8 @@ package ee.stat.dashboard.repository.custom;
import ee.stat.dashboard.model.classifier.ClassifierCode;
import ee.stat.dashboard.model.classifier.Element;
import ee.stat.dashboard.model.widget.back.enums.Language;
import ee.stat.dashboard.service.element.dto.RoleStrategy;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
......@@ -45,6 +47,20 @@ public class ElementCustomRepositoryImpl implements ElementCustomRepository {
.getResultList();
}
@Override
public List<Element> findAllByClfCodeAndRoleOrderByName(ClassifierCode code, RoleStrategy role, Language language) {
String roleExistsCondition = role.hasDashboard() ? "and rd.id is not null \n" : "and rd.id is null \n";
String order = language.isEt() ? "order by e.name_et asc \n" : "order by e.name_en asc \n";
String select = "SELECT e.*\n" +
"from Element e\n" +
" join Classifier c on c.id = e.classifier\n" +
" left join role_dashboard rd on e.id = rd.role_element\n" +
"where c.code = :code\n";
return entityManager.createNativeQuery(select + roleExistsCondition + order, Element.class)
.setParameter("code", code.name())
.getResultList();
}
@Override
public List<Element> findAllByClfCodeAndElCode(ClassifierCode code, String elementCode) {
return entityManager.createNativeQuery("" +
......
......@@ -34,6 +34,7 @@ public class DashboardAdminSaveService {
private DashboardDomainService dashboardDomainService;
private DashboardParentService dashboardParentService;
private DashboardRegionService dashboardRegionService;
private RoleDashboardAdminService roleDashboardAdminService;
private DashboardRepository dashboardRepository;
private DashboardCacheManager dashboardCacheManager;
......@@ -75,6 +76,7 @@ public class DashboardAdminSaveService {
private Dashboard saveOrUpdate(DashboardAdminResponse dashboard, Dashboard dbDashboard, ValidationStrategy saving) {
Dashboard saved = dashboardRepository.save(dbDashboard);
dashboard.setId(saved.getId());
roleDashboardAdminService.saveRole(dashboard);
dashboardRegionService.updateRegions(dashboard);
dashboardDomainService.updateDomains(dashboard, saving);
dashboardParentService.updateParent(dashboard);
......
......@@ -6,6 +6,7 @@ import ee.stat.dashboard.model.dashboard.DashboardUserType;
import ee.stat.dashboard.repository.DashboardRepository;
import ee.stat.dashboard.service.admin.dashboard.DashboardAdminConverter;
import ee.stat.dashboard.service.admin.dashboard.dto.DashboardAdminResponse;
import ee.stat.dashboard.service.admin.dto.RoleResponse;
import ee.stat.dashboard.service.admin.dto.StatPage;
import ee.stat.dashboard.util.ErrorCode;
import ee.stat.dashboard.util.StatBadRequestException;
......@@ -29,6 +30,7 @@ import static org.apache.commons.collections4.CollectionUtils.isNotEmpty;
public class DashboardAdminService {
private DomainAdminService domainAdminService;
private RoleDashboardAdminService roleDashboardAdminService;
private DashboardAdminConverter dashboardAdminConverter;
private DashboardRepository dashboardRepository;
......@@ -73,6 +75,11 @@ public class DashboardAdminService {
}
DashboardAdminResponse dto = dashboardAdminConverter.mapWRegionsWChildrenWParent(dashboard);
dto.setElements(domainAdminService.loadDomainsAndWidgets(dashboard.getId()));
RoleResponse role = roleDashboardAdminService.getRole(dashboard.getId());
if (role != null){
dto.setMainRole(role.getMainRole());
dto.setSubRole(role.getSubRole());
}
return dto;
}
......
package ee.stat.dashboard.service.admin;
import ee.stat.dashboard.model.classifier.Classifier;
import ee.stat.dashboard.model.classifier.ClassifierCode;
import ee.stat.dashboard.model.classifier.DashboardRule;
import ee.stat.dashboard.model.classifier.Element;
import ee.stat.dashboard.model.classifier.RoleDashboard;
import ee.stat.dashboard.repository.RoleDashboardRepository;
import ee.stat.dashboard.service.admin.dashboard.ElementAdminService;
import ee.stat.dashboard.service.admin.dashboard.dto.DashboardAdminResponse;
import ee.stat.dashboard.service.admin.dto.RoleResponse;
import ee.stat.dashboard.service.element.ClassifierServiceCache;
import ee.stat.dashboard.service.element.ElementServiceCache;
import ee.stat.dashboard.util.StatListUtil;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
import static org.apache.commons.collections4.CollectionUtils.isEmpty;
@Service
@AllArgsConstructor
public class RoleDashboardAdminService {
private RoleDashboardRepository roleDashboardRepository;
private ElementServiceCache elementServiceCache;
private ClassifierServiceCache classifierServiceCache;
private ElementAdminService elementAdminService;
public RoleResponse getRole(Long dashboardId) {
List<RoleDashboard> roleDashboards = roleDashboardRepository.findByDashboard(dashboardId);
if (isEmpty(roleDashboards)) {
return null;
}
RoleDashboard roleDashboard = StatListUtil.first(roleDashboards);
if (roleDashboard.getRoleElement() != null) {
Element element = elementServiceCache.findById(roleDashboard.getRoleElement()).orElseThrow(RuntimeException::new);
return new RoleResponse(elementAdminService.mapMainData(element.getClassifier()), elementAdminService.mapMainData(element));
}
if (roleDashboard.getRoleClassifier() != null) {
Classifier classifier = classifierServiceCache.findById(roleDashboard.getRoleClassifier()).orElseThrow(RuntimeException::new);
return new RoleResponse(elementAdminService.mapMainData(classifier));
}
throw new UnsupportedOperationException("unknown situation");
}
public void saveRole(DashboardAdminResponse dashboard) {
if (dashboard.getMainRole() != null) {
List<RoleDashboard> byDashboard = roleDashboardRepository.findByDashboard(dashboard.getId());
RoleDashboard existingRoleDashboard = StatListUtil.firstOrNull(byDashboard);
if (dashboard.getMainRole().getCode() == ClassifierCode.EHAK) {
updateClassifier(dashboard, existingRoleDashboard);
} else {
updateElement(dashboard, existingRoleDashboard);
}
}
}
private void updateElement(DashboardAdminResponse dashboard, RoleDashboard existingRoleDashboard) {
RoleDashboard newRoleDashboard = updateCommon(dashboard, existingRoleDashboard);
Element element = elementServiceCache.findById(dashboard.getSubRole().getId()).orElseThrow(RuntimeException::new);
newRoleDashboard.setRoleElement(dashboard.getSubRole().getId());
newRoleDashboard.setDashboardRule(clfToRule(element.getClassifier().getCode()));
roleDashboardRepository.save(newRoleDashboard);
}
private void updateClassifier(DashboardAdminResponse dashboard, RoleDashboard existingRoleDashboard) {
RoleDashboard newRoleDashboard = updateCommon(dashboard, existingRoleDashboard);
Classifier classifier = classifierServiceCache.findById(dashboard.getMainRole().getId()).orElseThrow(RuntimeException::new);
newRoleDashboard.setRoleClassifier(dashboard.getMainRole().getId());
newRoleDashboard.setDashboardRule(clfToRule(classifier.getCode()));
roleDashboardRepository.save(newRoleDashboard);
}
private RoleDashboard updateCommon(DashboardAdminResponse dashboard, RoleDashboard existingRoleDashboard) {
RoleDashboard newRoleDashboard = new RoleDashboard();
newRoleDashboard.setId(existingRoleDashboard != null ? existingRoleDashboard.getId() : null);
newRoleDashboard.setDashboard(dashboard.getId());
newRoleDashboard.setCreatedAt(existingRoleDashboard != null ? existingRoleDashboard.getCreatedAt() : LocalDateTime.now());
return newRoleDashboard;
}
private DashboardRule clfToRule(ClassifierCode code) {
if (code == ClassifierCode.EHAK) {
return DashboardRule.ONE_DASHBOARD;
} else if (code == ClassifierCode.BUSINESS) {
return DashboardRule.DASHBOARDS;
} else if (code == ClassifierCode.GOV) {
return DashboardRule.SUB_DASHBOARDS;
}
throw new UnsupportedOperationException("unknown clf: " + code.name());
}
}
......@@ -10,6 +10,7 @@ import ee.stat.dashboard.repository.DashboardRepository;
import ee.stat.dashboard.repository.DashboardWidgetRepository;
import ee.stat.dashboard.repository.DomainConnectionRepository;
import ee.stat.dashboard.repository.DomainRepository;
import ee.stat.dashboard.repository.RoleDashboardRepository;
import ee.stat.dashboard.repository.WidgetDomainRepository;
import ee.stat.dashboard.service.admin.widget.UserWidgetDeleteService;
import lombok.AllArgsConstructor;
......@@ -34,6 +35,7 @@ public class DashboardDeleteService {
private WidgetDomainRepository widgetDomainRepository;
private DomainConnectionRepository domainConnectionRepository;
private DomainRepository domainRepository;
private RoleDashboardRepository roleDashboardRepository;
public void delete(Dashboard dashboard) {
dashboardConnectionRepository.deleteByToId(dashboard.getId());
......@@ -42,6 +44,8 @@ public class DashboardDeleteService {
widgetDomainRepository.deleteByDashboard(dashboard.getId());
dashboardWidgetRepository.deleteByDashboard(dashboard.getId());
roleDashboardRepository.deleteByDashboard(dashboard.getId());
List<Domain> domains = domainRepository.findByDashboard(dashboard.getId());
if (isNotEmpty(domains)) {
domainConnectionRepository.deleteByToIdIn(domainIds(domains));
......
......@@ -8,6 +8,7 @@ import ee.stat.dashboard.service.admin.dashboard.dto.DashboardAdminResponse;
import ee.stat.dashboard.service.admin.dashboard.dto.ElementAdminResponse;
import ee.stat.dashboard.service.admin.dto.ValidationStrategy;
import ee.stat.dashboard.service.element.ElementServiceCache;
import ee.stat.dashboard.util.StatBadRequestException;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
......@@ -16,6 +17,8 @@ import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import static ee.stat.dashboard.util.ErrorCode.dashboard_admin_ehak_role_must_have_no_subrole;
import static ee.stat.dashboard.util.ErrorCode.dashboard_admin_role_must_have_subrole;
import static ee.stat.dashboard.util.ResponseUtil.badRequest;
import static org.apache.commons.collections4.CollectionUtils.isEmpty;
import static org.apache.commons.collections4.CollectionUtils.isNotEmpty;
......@@ -43,6 +46,14 @@ public class DashboardValidator {
if (dashboard.getType().isRegional()) {
validateRegions(dashboard);
}
if (dashboard.getMainRole() != null) {
if (dashboard.getMainRole().getCode() == ClassifierCode.EHAK && dashboard.getSubRole() != null) {
throw new StatBadRequestException(dashboard_admin_ehak_role_must_have_no_subrole);
}
if (dashboard.getMainRole().getCode() != ClassifierCode.EHAK && dashboard.getSubRole() == null) {
throw new StatBadRequestException(dashboard_admin_role_must_have_subrole);
}
}
}
private void validateRegions(DashboardAdminResponse dashboard) {
......@@ -97,4 +108,4 @@ public class DashboardValidator {
}
}
}
}
\ No newline at end of file
}