Skip to content
This repository was archived by the owner on May 5, 2021. It is now read-only.

Commit 8dd830b

Browse files
authored
Merge pull request SORMAS-Foundation#3321 from hzi-braunschweig/feature-2890-CampaignDataByJurisdiction
Feature 2890 campaign data by jurisdiction
2 parents 207f823 + 5dd7408 commit 8dd830b

8 files changed

Lines changed: 123 additions & 26 deletions

File tree

sormas-api/src/main/java/de/symeda/sormas/api/i18n/Validations.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,13 @@ public interface Validations {
4747
String importCommunityNotUnique = "importCommunityNotUnique";
4848
String importDistrictAlreadyExists = "importDistrictAlreadyExists";
4949
String importDistrictNotUnique = "importDistrictNotUnique";
50+
String importEntryCommunityNotInUsersJurisdiction = "importEntryCommunityNotInUsersJurisdiction";
51+
String importEntryDistrictNotInUsersJurisdiction = "importEntryDistrictNotInUsersJurisdiction";
5052
String importEntryDoesNotExist = "importEntryDoesNotExist";
5153
String importEntryDoesNotExistDbOrCommunity = "importEntryDoesNotExistDbOrCommunity";
5254
String importEntryDoesNotExistDbOrDistrict = "importEntryDoesNotExistDbOrDistrict";
5355
String importEntryDoesNotExistDbOrRegion = "importEntryDoesNotExistDbOrRegion";
56+
String importEntryRegionNotInUsersJurisdiction = "importEntryRegionNotInUsersJurisdiction";
5457
String importErrorInColumn = "importErrorInColumn";
5558
String importFacilityAlreadyExists = "importFacilityAlreadyExists";
5659
String importFacilityNotUniqueInCommunity = "importFacilityNotUniqueInCommunity";

sormas-api/src/main/java/de/symeda/sormas/api/user/UserDto.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ public class UserDto extends EntityDto {
7272

7373
private Set<UserRole> userRoles;
7474

75-
private AreaReferenceDto area;
7675
private RegionReferenceDto region;
7776
private DistrictReferenceDto district;
7877
// community of community informant
@@ -180,14 +179,6 @@ public void setAssociatedOfficer(UserReferenceDto associatedOfficer) {
180179
this.associatedOfficer = associatedOfficer;
181180
}
182181

183-
public AreaReferenceDto getArea() {
184-
return area;
185-
}
186-
187-
public void setArea(AreaReferenceDto area) {
188-
this.area = area;
189-
}
190-
191182
public RegionReferenceDto getRegion() {
192183
return region;
193184
}

sormas-api/src/main/resources/validations.properties

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ importEntryDoesNotExist = Invalid value %s in column %s; Entry does not exist in
3434
importEntryDoesNotExistDbOrCommunity = Invalid value %s in column %s; Entry does not exist in the database or in the specified community or is archived (Or maybe a wrong facility type was specified)
3535
importEntryDoesNotExistDbOrDistrict = Invalid value %s in column %s; Entry does not exist in the database or in the specified district or is archived (Or maybe a wrong facility type was specified)
3636
importEntryDoesNotExistDbOrRegion = Invalid value %s in column %s; Entry does not exist in the database or in the specified region or is archived
37+
importEntryRegionNotInUsersJurisdiction = Invalid value %s in column %s; Specified region is not within your jurisdiction
38+
importEntryDistrictNotInUsersJurisdiction = Invalid value %s in column %s; Specified district is not within your jurisdiction
39+
importEntryCommunityNotInUsersJurisdiction = Invalid value %s in column %s; Specified community is not within your jurisdiction
3740
importErrorInColumn = The import failed because of an error in column %s
3841
importFacilityNotUniqueInCommunity = Invalid value %s in column %s; Facility name is not unique in the chosen community, make sure there is only one facility with this name belonging to the chosen community in the database
3942
importFacilityNotUniqueInDistrict = Invalid value %s in column %s; Facility name is not unique in the chosen district, make sure there is only one facility with this name belonging to the chosen district in the database or specify a community

sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/data/CampaignFormDataFacadeEjb.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
import de.symeda.sormas.backend.campaign.form.CampaignFormMeta;
6868
import de.symeda.sormas.backend.campaign.form.CampaignFormMetaFacadeEjb;
6969
import de.symeda.sormas.backend.campaign.form.CampaignFormMetaService;
70+
import de.symeda.sormas.backend.common.AbstractAdoService;
7071
import de.symeda.sormas.backend.common.AbstractDomainObject;
7172
import de.symeda.sormas.backend.region.Area;
7273
import de.symeda.sormas.backend.region.Community;
@@ -98,9 +99,6 @@ public class CampaignFormDataFacadeEjb implements CampaignFormDataFacade {
9899
@EJB
99100
private CampaignFormMetaService campaignFormMetaService;
100101

101-
@EJB
102-
private CampaignFormMetaFacadeEjb.CampaignFormMetaFacadeEjbLocal campaignFormMetaFacade;
103-
104102
@EJB
105103
private RegionService regionService;
106104

@@ -239,7 +237,8 @@ public List<CampaignFormDataIndexDto> getIndexList(
239237
communityJoin.get(Community.NAME),
240238
root.get(CampaignFormData.FORM_DATE));
241239

242-
Predicate filter = campaignFormDataService.createCriteriaFilter(criteria, cb, root);
240+
Predicate filter = AbstractAdoService
241+
.and(cb, campaignFormDataService.createCriteriaFilter(criteria, cb, root), campaignFormDataService.createUserFilter(cb, cq, root));
243242
if (filter != null) {
244243
cq.where(filter);
245244
}
@@ -508,7 +507,8 @@ public long count(CampaignFormDataCriteria criteria) {
508507
CriteriaQuery<Long> cq = cb.createQuery(Long.class);
509508
Root<CampaignFormData> root = cq.from(CampaignFormData.class);
510509

511-
Predicate filter = campaignFormDataService.createCriteriaFilter(criteria, cb, root);
510+
Predicate filter = AbstractAdoService
511+
.and(cb, campaignFormDataService.createCriteriaFilter(criteria, cb, root), campaignFormDataService.createUserFilter(cb, cq, root));
512512
if (filter != null) {
513513
cq.where(filter);
514514
}

sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/data/CampaignFormDataService.java

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,16 @@
3434
import javax.persistence.criteria.Root;
3535

3636
import de.symeda.sormas.api.campaign.data.CampaignFormDataCriteria;
37+
import de.symeda.sormas.api.user.JurisdictionLevel;
3738
import de.symeda.sormas.api.utils.DateHelper;
3839
import de.symeda.sormas.backend.campaign.Campaign;
3940
import de.symeda.sormas.backend.campaign.form.CampaignFormMeta;
40-
import de.symeda.sormas.backend.caze.Case;
4141
import de.symeda.sormas.backend.common.AbstractAdoService;
4242
import de.symeda.sormas.backend.common.AbstractDomainObject;
4343
import de.symeda.sormas.backend.region.Community;
4444
import de.symeda.sormas.backend.region.District;
4545
import de.symeda.sormas.backend.region.Region;
46+
import de.symeda.sormas.backend.user.User;
4647

4748
@Stateless
4849
@LocalBean
@@ -80,8 +81,41 @@ public Predicate createCriteriaFilter(CampaignFormDataCriteria criteria, Criteri
8081
}
8182

8283
@Override
83-
public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From<?, CampaignFormData> from) {
84-
return null;
84+
public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From<?, CampaignFormData> campaignPath) {
85+
final User currentUser = getCurrentUser();
86+
if (currentUser == null) {
87+
return null;
88+
}
89+
90+
Predicate filter = null;
91+
92+
final JurisdictionLevel jurisdictionLevel = currentUser.getJurisdictionLevel();
93+
if (jurisdictionLevel != JurisdictionLevel.NATION) {
94+
switch (jurisdictionLevel) {
95+
case REGION:
96+
final Region region = currentUser.getRegion();
97+
if (region != null) {
98+
filter = or(cb, filter, cb.equal(campaignPath.get(CampaignFormData.REGION).get(Region.ID), region.getId()));
99+
}
100+
break;
101+
case DISTRICT:
102+
final District district = currentUser.getDistrict();
103+
if (district != null) {
104+
filter = or(cb, filter, cb.equal(campaignPath.get(CampaignFormData.DISTRICT).get(District.ID), district.getId()));
105+
}
106+
break;
107+
case COMMUNITY:
108+
final Community community = currentUser.getCommunity();
109+
if (community != null) {
110+
filter = or(cb, filter, cb.equal(campaignPath.get(CampaignFormData.COMMUNITY).get(Community.ID), community.getId()));
111+
}
112+
break;
113+
default:
114+
return null;
115+
}
116+
}
117+
118+
return filter;
85119
}
86120

87121
public List<String> getAllActiveUuids() {

sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/campaigndata/CampaignFormDataEditForm.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
import de.symeda.sormas.api.region.AreaReferenceDto;
3636
import de.symeda.sormas.api.region.DistrictReferenceDto;
3737
import de.symeda.sormas.api.region.RegionReferenceDto;
38+
import de.symeda.sormas.api.user.UserDto;
39+
import de.symeda.sormas.ui.UserProvider;
3840
import de.symeda.sormas.ui.utils.AbstractEditForm;
3941
import de.symeda.sormas.ui.utils.CssStyles;
4042
import de.symeda.sormas.ui.utils.FieldHelper;
@@ -92,6 +94,9 @@ protected void addFields() {
9294
addInfrastructureListeners(cbRegion, cbDistrict, cbCommunity);
9395
cbRegion.addItems(FacadeProvider.getRegionFacade().getAllActiveAsReference());
9496

97+
final UserDto currentUser = UserProvider.getCurrent().getUser();
98+
final RegionReferenceDto currentUserRegion = currentUser.getRegion();
99+
95100
if (FacadeProvider.getFeatureConfigurationFacade().isFeatureEnabled(FeatureType.INFRASTRUCTURE_TYPE_AREA)) {
96101
ComboBox cbArea = addCustomField(CampaignFormDataEditForm.AREA, AreaReferenceDto.class, ComboBox.class);
97102
cbArea.setCaption(I18nProperties.getCaption(Captions.CampaignFormData_area));
@@ -116,6 +121,26 @@ protected void addFields() {
116121
cbArea.setValue(FacadeProvider.getRegionFacade().getRegionByUuid(region.getUuid()).getArea());
117122
}
118123
});
124+
if (currentUserRegion != null) {
125+
final AreaReferenceDto area = FacadeProvider.getRegionFacade().getRegionByUuid(currentUserRegion.getUuid()).getArea();
126+
cbArea.setValue(area);
127+
if (currentUserRegion != null) {
128+
cbArea.setEnabled(false);
129+
}
130+
}
131+
}
132+
133+
if (currentUserRegion != null) {
134+
cbRegion.setValue(currentUserRegion);
135+
cbRegion.setEnabled(false);
136+
}
137+
if (currentUser.getDistrict() != null) {
138+
cbDistrict.setValue(currentUser.getDistrict());
139+
cbDistrict.setEnabled(false);
140+
}
141+
if (currentUser.getCommunity() != null) {
142+
cbCommunity.setValue(currentUser.getCommunity());
143+
cbCommunity.setEnabled(false);
119144
}
120145
}
121146

sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/importer/CampaignFormDataImporter.java

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import java.lang.reflect.InvocationTargetException;
88
import java.text.ParseException;
99
import java.util.Arrays;
10-
import java.util.Iterator;
1110
import java.util.LinkedHashMap;
1211
import java.util.LinkedList;
1312
import java.util.List;
@@ -36,7 +35,12 @@
3635
import de.symeda.sormas.api.i18n.Validations;
3736
import de.symeda.sormas.api.region.CommunityReferenceDto;
3837
import de.symeda.sormas.api.region.DistrictReferenceDto;
38+
import de.symeda.sormas.api.region.RegionReferenceDto;
39+
import de.symeda.sormas.api.user.JurisdictionLevel;
40+
import de.symeda.sormas.api.user.UserDto;
41+
import de.symeda.sormas.api.user.UserFacade;
3942
import de.symeda.sormas.api.user.UserReferenceDto;
43+
import de.symeda.sormas.api.user.UserRole;
4044
import de.symeda.sormas.ui.importer.DataImporter;
4145
import de.symeda.sormas.ui.importer.ImportErrorException;
4246
import de.symeda.sormas.ui.importer.ImportLineResult;
@@ -49,6 +53,8 @@ public class CampaignFormDataImporter extends DataImporter {
4953
private String campaignFormMetaUUID;
5054
private CampaignReferenceDto campaignReferenceDto;
5155

56+
private UserFacade userFacade;
57+
5258
public CampaignFormDataImporter(
5359
File inputFile,
5460
boolean hasEntityClassRow,
@@ -58,6 +64,8 @@ public CampaignFormDataImporter(
5864
super(inputFile, hasEntityClassRow, currentUser);
5965
this.campaignFormMetaUUID = campaignUUID;
6066
this.campaignReferenceDto = campaignFormDataDto;
67+
68+
this.userFacade = FacadeProvider.getUserFacade();
6169
}
6270

6371
@Override
@@ -87,31 +95,32 @@ protected ImportLineResult importDataFromCsvLine(
8795
CampaignFormMetaDto campaginMetaDto = FacadeProvider.getCampaignFormMetaFacade().getCampaignFormMetaByUuid(campaignFormMetaUUID);
8896
campaignFormData.setCampaign(campaignReferenceDto);
8997
campaignFormData.setCampaignFormMeta(new CampaignFormMetaReferenceDto(campaignFormMetaUUID, campaginMetaDto.getFormName()));
90-
Map<String,String> invalidEntries = validateFormValues(campaginMetaDto, campaignFormData);
98+
Map<String, String> invalidEntries = validateFormValues(campaginMetaDto, campaignFormData);
9199
if (!invalidEntries.isEmpty()) {
92-
for(String e:invalidEntries.keySet()){
93-
writeImportError(values, I18nProperties.getValidationError(Validations.importWrongDataTypeError,invalidEntries.get(e),e));
100+
for (String e : invalidEntries.keySet()) {
101+
writeImportError(values, I18nProperties.getValidationError(Validations.importWrongDataTypeError, invalidEntries.get(e), e));
94102
}
95103
return ImportLineResult.ERROR;
96-
} else {
104+
} else {
97105
FacadeProvider.getCampaignFormDataFacade().saveCampaignFormData(campaignFormData);
98106
}
99107
} catch (ImportErrorException e) {
108+
writeImportError(values, e.getMessage());
100109
return ImportLineResult.ERROR;
101110
}
102111

103112
return ImportLineResult.SUCCESS;
104113
}
105114

106-
private Map<String,String> validateFormValues(CampaignFormMetaDto campaginMetaDto, CampaignFormDataDto campaignFormData) {
107-
Map<String,String> wrongEntries = new LinkedHashMap<>();
115+
private Map<String, String> validateFormValues(CampaignFormMetaDto campaginMetaDto, CampaignFormDataDto campaignFormData) {
116+
Map<String, String> wrongEntries = new LinkedHashMap<>();
108117
List<CampaignFormElement> formElements = campaginMetaDto.getCampaignFormElements();
109118
Optional<CampaignFormElement> formElementOptional;
110119
for (CampaignFormDataEntry formDataEntry : campaignFormData.getFormValues()) {
111120
formElementOptional = formElements.stream().filter(formElement -> formElement.getId().equals(formDataEntry.getId())).findFirst();
112121
if (formElementOptional.isPresent()) {
113122
if (!isEntryValid(formElementOptional.get(), formDataEntry)) {
114-
wrongEntries.put(formElementOptional.get().getId(),formDataEntry.getValue().toString());
123+
wrongEntries.put(formElementOptional.get().getId(), formDataEntry.getValue().toString());
115124

116125
}
117126
}
@@ -146,6 +155,8 @@ private CampaignFormDataDto insertColumnEntryIntoData(CampaignFormDataDto campai
146155
propertyDescriptor = new PropertyDescriptor(entryHeaderPath[i], currentElement.getClass());
147156
Class<?> propertyType = propertyDescriptor.getPropertyType();
148157
if (!executeDefaultInvokings(propertyDescriptor, currentElement, entry[i], entryHeaderPath)) {
158+
final UserDto currentUserDto = userFacade.getByUuid(currentUser.getUuid());
159+
final JurisdictionLevel jurisdictionLevel = UserRole.getJurisdictionLevel(currentUserDto.getUserRoles());
149160
/*
150161
* if (propertyType.isAssignableFrom(CampaignReferenceDto.class)) {
151162
* CampaignDto campaign = FacadeProvider.getCampaignFacade().getByUuid(entry[i]);
@@ -156,6 +167,13 @@ private CampaignFormDataDto insertColumnEntryIntoData(CampaignFormDataDto campai
156167
* } else
157168
*/
158169
if (propertyType.isAssignableFrom(DistrictReferenceDto.class)) {
170+
if (jurisdictionLevel == JurisdictionLevel.DISTRICT && !currentUserDto.getDistrict().getCaption().equals(entry[i])) {
171+
throw new ImportErrorException(
172+
I18nProperties.getValidationError(
173+
Validations.importEntryDistrictNotInUsersJurisdiction,
174+
entry,
175+
buildEntityProperty(entryHeaderPath)));
176+
}
159177
List<DistrictReferenceDto> district =
160178
FacadeProvider.getDistrictFacade().getByName(entry[i], currentElement.getRegion(), true);
161179
if (district.isEmpty()) {
@@ -172,6 +190,13 @@ private CampaignFormDataDto insertColumnEntryIntoData(CampaignFormDataDto campai
172190
propertyDescriptor.getWriteMethod().invoke(currentElement, district.get(0));
173191
}
174192
} else if (propertyType.isAssignableFrom(CommunityReferenceDto.class)) {
193+
if (jurisdictionLevel == JurisdictionLevel.COMMUNITY && !currentUserDto.getCommunity().getCaption().equals(entry[i])) {
194+
throw new ImportErrorException(
195+
I18nProperties.getValidationError(
196+
Validations.importEntryCommunityNotInUsersJurisdiction,
197+
entry,
198+
buildEntityProperty(entryHeaderPath)));
199+
}
175200
List<CommunityReferenceDto> community =
176201
FacadeProvider.getCommunityFacade().getByName(entry[i], currentElement.getDistrict(), true);
177202
if (community.isEmpty()) {
@@ -213,4 +238,20 @@ private CampaignFormDataDto insertColumnEntryIntoData(CampaignFormDataDto campai
213238
}
214239
return currentElement;
215240
}
241+
242+
@Override
243+
protected boolean executeDefaultInvokings(PropertyDescriptor pd, Object element, String entry, String[] entryHeaderPath)
244+
throws InvocationTargetException, IllegalAccessException, ParseException, ImportErrorException {
245+
final boolean returnBoolean = super.executeDefaultInvokings(pd, element, entry, entryHeaderPath);
246+
final Class<?> propertyType = pd.getPropertyType();
247+
if (propertyType.isAssignableFrom(RegionReferenceDto.class)) {
248+
final UserDto currentUserDto = userFacade.getByUuid(currentUser.getUuid());
249+
final JurisdictionLevel jurisdictionLevel = UserRole.getJurisdictionLevel(currentUserDto.getUserRoles());
250+
if (jurisdictionLevel == JurisdictionLevel.REGION && !currentUserDto.getRegion().getCaption().equals(entry)) {
251+
throw new ImportErrorException(
252+
I18nProperties.getValidationError(Validations.importEntryRegionNotInUsersJurisdiction, entry, buildEntityProperty(entryHeaderPath)));
253+
}
254+
}
255+
return returnBoolean;
256+
}
216257
}

sormas-ui/src/main/java/de/symeda/sormas/ui/dashboard/campaigns/CampaignDashboardFilterLayout.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ private void createCampaignFilter() {
7171

7272
@SuppressWarnings("deprecation")
7373
private void createJurisdictionFilters() {
74-
final AreaReferenceDto userArea = UserProvider.getCurrent().getUser().getArea();
7574
final RegionReferenceDto userRegion = UserProvider.getCurrent().getUser().getRegion();
75+
final AreaReferenceDto userArea = FacadeProvider.getRegionFacade().getRegionByUuid(userRegion.getUuid()).getArea();
7676
final DistrictReferenceDto userDistrict = UserProvider.getCurrent().getUser().getDistrict();
7777

7878
dashboardDataProvider.setArea(userArea);

0 commit comments

Comments
 (0)