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

Commit 66e8323

Browse files
MateStrysewskebarnabartha
andauthored
Feature 3068 campaign form data columns validation (SORMAS-Foundation#3615)
* SORMAS-Foundation#3068 - validate imported campaign form data column exists in corresponding campaign form meta * SORMAS-Foundation#3068 - Refactored import error message generation, changed file names * SORMAS-Foundation#3068 - Refactoring, more validation fixes Co-authored-by: barnabartha <[email protected]>
1 parent f954732 commit 66e8323

16 files changed

Lines changed: 401 additions & 231 deletions

File tree

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public interface Validations {
2323
String campaignFormDependingOnValuesMissing = "campaignFormDependingOnValuesMissing";
2424
String campaignFormElementDuplicateId = "campaignFormElementDuplicateId";
2525
String campaignFormElementIdRequired = "campaignFormElementIdRequired";
26+
String campaignFormElementNotExisting = "campaignFormElementNotExisting";
2627
String campaignFormElementTypeRequired = "campaignFormElementTypeRequired";
2728
String campaignFormInvalidIdInListElements = "campaignFormInvalidIdInListElements";
2829
String campaignFormTranslationCaptionRequired = "campaignFormTranslationCaptionRequired";

sormas-api/src/main/java/de/symeda/sormas/api/utils/DataHelper.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,4 +387,8 @@ public static String valueToString(Object value) {
387387
return value.toString();
388388
}
389389
}
390+
391+
public static String sanitizeFileName(String fileName) {
392+
return fileName.replaceAll("[^a-zA-Z0-9._-]", "");
393+
}
390394
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ contactFollowUpUntilDate = The follow-up until date must at least be on the day
100100
emptyOverwrittenFollowUpUntilDate = The follow-up until date cannot be overwritten with an empty value.
101101
textTooLong = The text you entered is too long. Maximum allowed length is %d
102102
contactWithoutInfrastructureData = A contact needs either a source case or a responsible region and district.
103+
campaignFormElementNotExisting = Column %s does not exist in form meta definition.
103104
campaignFormUnsupportedType = The type %s of element %s is not supported in campaign forms.
104105
campaignFormUnsupportedStyle = The style %s of element %s is not supported in campaign forms.
105106
campaignFormDependingOnNotFound = The campaign form does not contain a field with the ID %s that was specified in the dependingOn attribute of element %s.

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

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@
2222
import java.util.Objects;
2323
import java.util.function.Consumer;
2424

25-
import javax.naming.NamingException;
26-
2725
import org.vaadin.hene.popupbutton.PopupButton;
2826

2927
import com.vaadin.icons.VaadinIcons;
@@ -56,7 +54,7 @@
5654
import de.symeda.sormas.ui.UserProvider;
5755
import de.symeda.sormas.ui.ViewModelProviders;
5856
import de.symeda.sormas.ui.campaign.AbstractCampaignView;
59-
import de.symeda.sormas.ui.campaign.importer.CampaignImportLayout;
57+
import de.symeda.sormas.ui.campaign.importer.CampaignFormDataImportLayout;
6058
import de.symeda.sormas.ui.utils.ButtonHelper;
6159
import de.symeda.sormas.ui.utils.CssStyles;
6260
import de.symeda.sormas.ui.utils.GridExportStreamResource;
@@ -143,11 +141,8 @@ public CampaignDataView() {
143141
addHeaderComponent(exportPopupButton);
144142

145143
{
146-
StreamResource streamResource = new GridExportStreamResource(
147-
grid,
148-
"sormas_campaign_data",
149-
createFileNameWithCurrentDate("sormas_campaign_data_", ".csv"),
150-
EDIT_BTN_ID);
144+
StreamResource streamResource =
145+
new GridExportStreamResource(grid, "campaign_data", createFileNameWithCurrentDate("campaign_data_", ".csv"), EDIT_BTN_ID);
151146
addExportButton(streamResource, exportPopupButton, exportLayout, VaadinIcons.TABLE, Captions.export, Strings.infoBasicExport);
152147
}
153148
}
@@ -197,18 +192,18 @@ public CampaignDataView() {
197192
}
198193

199194
private void createImportLayout(VerticalLayout importFormLayout) {
195+
200196
for (CampaignFormMetaReferenceDto campaignForm : FacadeProvider.getCampaignFormMetaFacade()
201197
.getCampaignFormMetasAsReferencesByCampaign(campaignCombo.getValue().getUuid())) {
202198

203199
Button campaignFormButton = ButtonHelper.createButton(campaignForm.toString(), e -> {
204-
Window popupWindow = null;
205200
try {
206-
popupWindow = VaadinUiUtil.showPopupWindow(new CampaignImportLayout(campaignForm.getUuid(), filterForm.getValue().getCampaign()));
207-
} catch (IOException | NamingException ioException) {
201+
Window popupWindow = VaadinUiUtil.showPopupWindow(new CampaignFormDataImportLayout(campaignForm, campaignCombo.getValue()));
202+
popupWindow.setCaption(I18nProperties.getString(Strings.headingImportCampaign));
203+
popupWindow.addCloseListener(c -> grid.reload());
204+
} catch (IOException ioException) {
208205
ioException.printStackTrace();
209206
}
210-
popupWindow.setCaption(I18nProperties.getString(Strings.headingImportCampaign));
211-
212207
});
213208
campaignFormButton.setWidth(100, Unit.PERCENTAGE);
214209
importFormLayout.addComponent(campaignFormButton);
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package de.symeda.sormas.ui.campaign.importer;
2+
3+
import java.io.IOException;
4+
5+
import com.opencsv.exceptions.CsvValidationException;
6+
import com.vaadin.server.Page;
7+
import com.vaadin.ui.Notification;
8+
9+
import de.symeda.sormas.api.FacadeProvider;
10+
import de.symeda.sormas.api.campaign.CampaignReferenceDto;
11+
import de.symeda.sormas.api.campaign.form.CampaignFormMetaReferenceDto;
12+
import de.symeda.sormas.api.i18n.I18nProperties;
13+
import de.symeda.sormas.api.i18n.Strings;
14+
import de.symeda.sormas.api.importexport.ImportFacade;
15+
import de.symeda.sormas.api.utils.DataHelper;
16+
import de.symeda.sormas.ui.importer.AbstractImportLayout;
17+
import de.symeda.sormas.ui.importer.ImportReceiver;
18+
19+
public class CampaignFormDataImportLayout extends AbstractImportLayout {
20+
21+
private static final long serialVersionUID = 4380218570798586587L;
22+
23+
public CampaignFormDataImportLayout(CampaignFormMetaReferenceDto campaignForm, CampaignReferenceDto campaignReferenceDto) throws IOException {
24+
super();
25+
26+
ImportFacade importFacade = FacadeProvider.getImportFacade();
27+
importFacade.generateCampaignFormImportTemplateFile(campaignForm.getUuid());
28+
29+
String templateFileName = DataHelper.sanitizeFileName(campaignReferenceDto.getCaption().replaceAll(" ", "_")) + "_"
30+
+ DataHelper.sanitizeFileName(campaignForm.getCaption().replaceAll(" ", "_")) + ".csv";
31+
addDownloadImportTemplateComponent(1, importFacade.getCampaignFormImportTemplateFilePath(), templateFileName);
32+
addImportCsvComponent(2, new ImportReceiver("_campaign_data_import_", file -> {
33+
resetDownloadErrorReportButton();
34+
35+
try {
36+
CampaignFormDataImporter importer =
37+
new CampaignFormDataImporter(file, false, currentUser, campaignForm.getUuid(), campaignReferenceDto);
38+
importer.startImport(this::extendDownloadErrorReportButton, currentUI, false);
39+
} catch (IOException | CsvValidationException e) {
40+
new Notification(
41+
I18nProperties.getString(Strings.headingImportFailed),
42+
I18nProperties.getString(Strings.messageImportFailed),
43+
Notification.Type.ERROR_MESSAGE,
44+
false).show(Page.getCurrent());
45+
}
46+
}));
47+
addDownloadErrorReportComponent(3);
48+
}
49+
50+
protected void addDownloadImportTemplateComponent(int step, String templateFilePath, String templateFileName) {
51+
super.addDownloadImportTemplateComponent(step, templateFilePath, templateFileName);
52+
}
53+
54+
}

0 commit comments

Comments
 (0)