From 5360ba43d1320eba8e8330c99ece20c156492700 Mon Sep 17 00:00:00 2001 From: Thibault Degivry Date: Tue, 21 Nov 2017 14:23:07 +0100 Subject: [PATCH 1/4] Adding missing count check for unavailable ContactModels Change-Id: If29d75928e1a14b1deeb9a99d73d9a48facfeb1f --- .../server/handler/GetAvailableStatusForModelHandler.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/org/sigmah/server/handler/GetAvailableStatusForModelHandler.java b/src/main/java/org/sigmah/server/handler/GetAvailableStatusForModelHandler.java index cee4026b1..1aba0881e 100644 --- a/src/main/java/org/sigmah/server/handler/GetAvailableStatusForModelHandler.java +++ b/src/main/java/org/sigmah/server/handler/GetAvailableStatusForModelHandler.java @@ -150,6 +150,10 @@ private TypedQuery buildCountQuery(final ModelType modelType, final Inte query = em().createQuery("SELECT COUNT(o) FROM OrgUnit o WHERE o.orgUnitModel.id = :modelId", Number.class); break; + case ContactModel: + query = em().createQuery("SELECT COUNT(c) FROM Contact c WHERE c.contactModel.id = :modelId", Number.class); + break; + default: throw new UnsupportedOperationException("Invalid model type."); } From 7122462cfdb57550ffd6c997259d41994f7ceb6e Mon Sep 17 00:00:00 2001 From: Thibault Degivry Date: Mon, 27 Nov 2017 13:43:09 +0100 Subject: [PATCH 2/4] Add export to contact lists (button + mechanism) (refs #634) Change-Id: I55d6dcef43671b010bd8adcf9c1fc04950e24016 --- .../sigmah/client/page/RequestParameter.java | 5 +- .../contact/ContactDetailsPresenter.java | 10 +- .../orgunit/OrgUnitDetailsPresenter.java | 53 ++++--- .../project/ProjectDetailsPresenter.java | 51 ++++--- .../project/dashboard/PhasesPresenter.java | 69 +++++---- .../sigmah/server/servlet/ExportServlet.java | 27 +++- .../servlet/exporter/ContactListExporter.java | 140 ++++++++++++++++++ .../utils/ContactsSynthesisUtils.java | 59 ++++++-- .../servlet/exporter/utils/ExporterUtil.java | 37 +++++ .../dto/element/ContactListElementDTO.java | 63 ++++++-- .../shared/servlet/ServletConstants.java | 12 ++ 11 files changed, 415 insertions(+), 111 deletions(-) create mode 100644 src/main/java/org/sigmah/server/servlet/exporter/ContactListExporter.java diff --git a/src/main/java/org/sigmah/client/page/RequestParameter.java b/src/main/java/org/sigmah/client/page/RequestParameter.java index 3f43d0814..0230cbb0d 100644 --- a/src/main/java/org/sigmah/client/page/RequestParameter.java +++ b/src/main/java/org/sigmah/client/page/RequestParameter.java @@ -65,7 +65,10 @@ public enum RequestParameter { CLOSE_CURRENT_TAB, CONTACT_ID, ELEMENTS, - PROJECT_ID; + PROJECT_ID, + CONTACT_LIST_ID, + LAYOUT_GROUP_ID, + ITERATION_ID; // If the parameter is part of the tab uniqueness logic. private final boolean unique; diff --git a/src/main/java/org/sigmah/client/ui/presenter/contact/ContactDetailsPresenter.java b/src/main/java/org/sigmah/client/ui/presenter/contact/ContactDetailsPresenter.java index 1e6ae8b1b..f705a88ae 100644 --- a/src/main/java/org/sigmah/client/ui/presenter/contact/ContactDetailsPresenter.java +++ b/src/main/java/org/sigmah/client/ui/presenter/contact/ContactDetailsPresenter.java @@ -95,6 +95,7 @@ import org.sigmah.shared.command.result.VoidResult; import org.sigmah.shared.dto.ContactDTO; import org.sigmah.shared.dto.country.CountryDTO; +import org.sigmah.shared.dto.element.ContactListElementDTO; import org.sigmah.shared.dto.element.DefaultContactFlexibleElementDTO; import org.sigmah.shared.dto.element.FlexibleElementContainer; import org.sigmah.shared.dto.element.FlexibleElementDTO; @@ -426,7 +427,7 @@ public void addIterationTabItem(int iterationId, IterableGroupItem tab) { } @Override - public FieldSet createGroupLayoutFieldSet(FlexibleElementContainer container, LayoutGroupDTO groupLayout, DispatchQueue queue, final Integer iterationId, final IterableGroupPanel tabPanel, final IterableGroupItem tabItem) { + public FieldSet createGroupLayoutFieldSet(FlexibleElementContainer container, final LayoutGroupDTO groupLayout, DispatchQueue queue, final Integer iterationId, final IterableGroupPanel tabPanel, final IterableGroupItem tabItem) { final ContactDTO contact = (ContactDTO)container; // Creates the fieldset and positions it. @@ -496,6 +497,13 @@ public void onCommandSuccess(final ValueResult valueResult) { } elementDTO.setTabPanel(tabPanel); + if (elementDTO instanceof ContactListElementDTO) { + ContactListElementDTO contactListElement = (ContactListElementDTO)elementDTO; + contactListElement.setPageManager(injector.getPageManager()); + contactListElement.setLayoutGroupId(groupLayout.getId()); + contactListElement.setIterationId(iterationId); + } + // Generates element component (with the value). elementDTO.init(); final Component elementComponent = elementDTO.getElementComponent(valueResult); diff --git a/src/main/java/org/sigmah/client/ui/presenter/orgunit/OrgUnitDetailsPresenter.java b/src/main/java/org/sigmah/client/ui/presenter/orgunit/OrgUnitDetailsPresenter.java index 726f2a173..25a96e7ec 100644 --- a/src/main/java/org/sigmah/client/ui/presenter/orgunit/OrgUnitDetailsPresenter.java +++ b/src/main/java/org/sigmah/client/ui/presenter/orgunit/OrgUnitDetailsPresenter.java @@ -28,10 +28,26 @@ import java.util.List; import java.util.Map; +import com.allen_sauer.gwt.log.client.Log; +import com.extjs.gxt.ui.client.event.ButtonEvent; +import com.extjs.gxt.ui.client.event.Events; +import com.extjs.gxt.ui.client.event.Listener; +import com.extjs.gxt.ui.client.widget.Component; +import com.extjs.gxt.ui.client.widget.ContentPanel; +import com.extjs.gxt.ui.client.widget.Label; import com.extjs.gxt.ui.client.widget.Layout; +import com.extjs.gxt.ui.client.widget.form.FieldSet; +import com.extjs.gxt.ui.client.widget.layout.FormData; +import com.google.gwt.user.client.ui.Grid; +import com.google.gwt.user.client.ui.Widget; +import com.google.inject.ImplementedBy; +import com.google.inject.Inject; +import com.google.inject.Singleton; +import org.sigmah.client.computation.ComputationTriggerManager; import org.sigmah.client.dispatch.CommandResultHandler; import org.sigmah.client.dispatch.DispatchQueue; import org.sigmah.client.dispatch.monitor.LoadingMask; +import org.sigmah.client.event.UpdateEvent; import org.sigmah.client.i18n.I18N; import org.sigmah.client.inject.Injector; import org.sigmah.client.page.Page; @@ -46,7 +62,6 @@ import org.sigmah.client.ui.widget.layout.Layouts; import org.sigmah.client.util.ClientUtils; import org.sigmah.client.util.profiler.Profiler; -import org.sigmah.offline.status.ApplicationState; import org.sigmah.shared.command.GetLayoutGroupIterations; import org.sigmah.shared.command.GetValue; import org.sigmah.shared.command.UpdateLayoutGroupIterations; @@ -58,6 +73,7 @@ import org.sigmah.shared.dto.OrgUnitDetailsDTO; import org.sigmah.shared.dto.element.BudgetElementDTO; import org.sigmah.shared.dto.element.BudgetSubFieldDTO; +import org.sigmah.shared.dto.element.ContactListElementDTO; import org.sigmah.shared.dto.element.DefaultFlexibleElementDTO; import org.sigmah.shared.dto.element.FlexibleElementContainer; import org.sigmah.shared.dto.element.FlexibleElementDTO; @@ -77,23 +93,6 @@ import org.sigmah.shared.util.ProfileUtils; import org.sigmah.shared.util.ValueResultUtils; -import com.allen_sauer.gwt.log.client.Log; -import com.extjs.gxt.ui.client.event.ButtonEvent; -import com.extjs.gxt.ui.client.event.Events; -import com.extjs.gxt.ui.client.event.Listener; -import com.extjs.gxt.ui.client.widget.Component; -import com.extjs.gxt.ui.client.widget.ContentPanel; -import com.extjs.gxt.ui.client.widget.Label; -import com.extjs.gxt.ui.client.widget.form.FieldSet; -import com.extjs.gxt.ui.client.widget.layout.FormData; -import com.google.gwt.user.client.ui.Grid; -import com.google.gwt.user.client.ui.Widget; -import com.google.inject.ImplementedBy; -import com.google.inject.Inject; -import com.google.inject.Singleton; -import org.sigmah.client.computation.ComputationTriggerManager; -import org.sigmah.client.event.UpdateEvent; - /** * OrgUnit Details Presenter. */ @@ -340,7 +339,7 @@ public void addIterationTabItem(int iterationId, IterableGroupItem tab) { } @Override - public FieldSet createGroupLayoutFieldSet(FlexibleElementContainer container, LayoutGroupDTO groupLayout, + public FieldSet createGroupLayoutFieldSet(FlexibleElementContainer container, final LayoutGroupDTO groupLayout, DispatchQueue queue, final Integer iterationId, final IterableGroupPanel tabPanel, final IterableGroupItem tabItem) { final OrgUnitDTO orgUnit = (OrgUnitDTO) container; @@ -375,7 +374,7 @@ public FieldSet createGroupLayoutFieldSet(FlexibleElementContainer container, La getValue = new GetValue(orgUnit.getId(), elementDTO.getId(), elementDTO.getEntityName(), null, iterationId); - queue.add(getValue, new ElementCommandResultHandler(elementDTO, fieldSet, orgUnit, tabPanel, tabItem), + queue.add(getValue, new ElementCommandResultHandler(elementDTO, fieldSet, orgUnit, tabPanel, tabItem, groupLayout, iterationId), new LoadingMask(view.getContentOrgUnitDetailsPanel())); } @@ -394,14 +393,19 @@ private class ElementCommandResultHandler extends CommandResultHandler. + * #L% + */ + + +import java.io.OutputStream; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; + +import com.google.inject.Injector; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.odftoolkit.simple.SpreadsheetDocument; +import org.sigmah.client.page.RequestParameter; +import org.sigmah.server.servlet.base.ServletExecutionContext; +import org.sigmah.server.servlet.exporter.base.Exporter; +import org.sigmah.server.servlet.exporter.data.ProjectSynthesisData; +import org.sigmah.server.servlet.exporter.template.ExportTemplate; +import org.sigmah.server.servlet.exporter.utils.ContactsSynthesisCalcTemplate; +import org.sigmah.server.servlet.exporter.utils.ContactsSynthesisExcelTemplate; +import org.sigmah.server.servlet.exporter.utils.ContactsSynthesisUtils; +import org.sigmah.server.servlet.exporter.utils.ExportConstants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ContactListExporter extends Exporter { + + /** + * Logger. + */ + private static final Logger LOG = LoggerFactory.getLogger(ContactListExporter.class); + + public ContactListExporter(final Injector injector, final HttpServletRequest req, ServletExecutionContext context) throws Exception { + super(injector, req, context); + } + + @Override + public String getFileName() { + SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); + return localize("contactList") + "_" + format.format(new Date()) + getExtention(); + } + + @Override + public void export(OutputStream output) throws Exception { + // The container id. + final String containerIdString = requireParameter(RequestParameter.ID); + Integer containerId; + try { + containerId = Integer.parseInt(containerIdString); + } catch (NumberFormatException e) { + LOG.error("[export] The id '" + containerIdString + "' is invalid.", e); + throw new Exception("The id '" + containerIdString + "' is invalid.", e); + } + // The layout group id. + final String layoutGroupIdString = requireParameter(RequestParameter.LAYOUT_GROUP_ID); + Integer layoutGroupId; + try { + layoutGroupId = Integer.parseInt(layoutGroupIdString); + } catch (NumberFormatException e) { + LOG.error("[export] The id '" + layoutGroupIdString + "' is invalid.", e); + throw new Exception("The id '" + layoutGroupIdString + "' is invalid.", e); + } + // The iteration id (can be null). + final String iterationIdString = requireParameter(RequestParameter.ITERATION_ID); + Integer iterationId; + try { + iterationId = Integer.parseInt(iterationIdString); + } catch (NumberFormatException e) { + LOG.error("[export] The id '" + iterationIdString + "' is invalid.", e); + throw new Exception("The id '" + iterationIdString + "' is invalid.", e); + } + if (iterationId == -1) { + iterationId = null; + } + // The contact list id (can be null). + final String contactListIdString = requireParameter(RequestParameter.CONTACT_LIST_ID); + Integer contactListId; + try { + contactListId = Integer.parseInt(contactListIdString); + } catch (NumberFormatException e) { + LOG.error("[export] The id '" + contactListIdString + "' is invalid.", e); + throw new Exception("The id '" + contactListIdString + "' is invalid.", e); + } + + try { + // data + List contactSheetDatas = ContactsSynthesisUtils.createContactListData(containerId, layoutGroupId, contactListId, iterationId, this, getI18ntranslator(), getLanguage()); + + ExportTemplate template; + switch (exportFormat) { + + case XLS: { + final HSSFWorkbook wb = new HSSFWorkbook(); + template = new ContactsSynthesisExcelTemplate(contactSheetDatas, wb, ExportConstants.CONTACT_SHEET_PREFIX); + ((ContactsSynthesisExcelTemplate) template).generate(); + } + break; + + case ODS: { + final SpreadsheetDocument doc = SpreadsheetDocument.newSpreadsheetDocument(); + template = new ContactsSynthesisCalcTemplate(contactSheetDatas, doc, ExportConstants.CONTACT_SHEET_PREFIX); + ((ContactsSynthesisCalcTemplate)template).generate(); + } + break; + + default: + LOG.error("[export] The export format '" + exportFormat + "' is unknown."); + throw new ServletException("The export format '" + exportFormat + "' is unknown."); + } + template.write(output); + + } catch (Throwable e) { + LOG.error("[export] Error during the workbook writing.", e); + throw new Exception("Error during the workbook writing.", e); + } + } +} diff --git a/src/main/java/org/sigmah/server/servlet/exporter/utils/ContactsSynthesisUtils.java b/src/main/java/org/sigmah/server/servlet/exporter/utils/ContactsSynthesisUtils.java index 2c3826739..2eb2eee86 100644 --- a/src/main/java/org/sigmah/server/servlet/exporter/utils/ContactsSynthesisUtils.java +++ b/src/main/java/org/sigmah/server/servlet/exporter/utils/ContactsSynthesisUtils.java @@ -125,6 +125,33 @@ public static List createProjectContactListData(final Integer return sheets; } + /** + * only used for direct contact list export + */ + public static List createContactListData(final Integer projectId, final Integer layoutGroupId, + final Integer contactListId, final Integer iterationId, + final Exporter exporter, final I18nServer i18nTranslator, + final Language language) throws Throwable { + + final List sheets = new ArrayList<>(); + + final ProjectDTO project = exporter.execute(new GetProject(projectId, null)); + + for (LayoutGroupDTO layoutGroup : project.getProjectModel().getProjectDetails().getLayout().getGroups()) { + + if (layoutGroup.getId().equals(layoutGroupId)) { + for (LayoutConstraintDTO constraint : layoutGroup.getConstraints()) { + if (constraint.getFlexibleElementDTO().getId().equals(contactListId) && constraint.getFlexibleElementDTO() instanceof ContactListElementDTO) { + sheets.add(createContactListSimpleTab(projectId, layoutGroup, (ContactListElementDTO)constraint.getFlexibleElementDTO(), + iterationId, exporter, i18nTranslator, language, false)); + } + } + } + } + + return sheets; + } + public static ContactSheetData createContactListTab(final Integer projectId, final LayoutGroupDTO layoutGroup, final ContactListElementDTO contactListElement, final Exporter exporter, final I18nServer i18nTranslator, final Language language) throws Throwable { @@ -132,7 +159,7 @@ public static ContactSheetData createContactListTab(final Integer projectId, fin if (layoutGroup.getHasIterations()) { return createContactListTabWithIterations(projectId, layoutGroup, contactListElement, exporter, i18nTranslator, language); } else { - return createContactListSimpleTab(projectId, layoutGroup, contactListElement, exporter, i18nTranslator, language); + return createContactListSimpleTab(projectId, layoutGroup, contactListElement, -1, exporter, i18nTranslator, language, true); } } @@ -166,7 +193,7 @@ public static ContactSheetData createContactListTabWithIterations(final Integer try { ValueResult iterationValueResult = exporter.execute(new GetValue(projectId, element.getId(), element.getEntityName(), null, iteration.getId())); - if (element == contactListElement) { + if (element.equals(contactListElement)) { Set contactIds = new HashSet(ValueResultUtils.splitValuesAsInteger(iterationValueResult.getValueObject())); if (!contactIds.isEmpty()) { contacts = exporter.execute(new GetContacts(contactIds)).getList(); @@ -175,7 +202,7 @@ public static ContactSheetData createContactListTabWithIterations(final Integer if (isFirst) { iterationHeaders.add(new ExportStringCell(ExporterUtil.getFlexibleElementLabel(element, i18nTranslator, language))); } - iterationValues.add(valueResultToDataCell(element, iterationValueResult, i18nTranslator, language)); + iterationValues.add(valueResultToDataCell(element, iterationValueResult, i18nTranslator, language, true, exporter)); } } catch(Exception e) { // no value found in database : empty cells @@ -226,32 +253,29 @@ public static ContactSheetData createContactListTabWithIterations(final Integer } public static ContactSheetData createContactListSimpleTab(final Integer projectId, final LayoutGroupDTO layoutGroup, - final ContactListElementDTO contactListElement, final Exporter exporter, - final I18nServer i18nTranslator, final Language language) throws Throwable { + final ContactListElementDTO contactListElement, final Integer iterationId, + final Exporter exporter, final I18nServer i18nTranslator, + final Language language, final boolean withLinks) throws Throwable { ContactSheetData result = new ContactSheetData(contactListElement.getLabel()); boolean isFirst = true; - List iterationHeaders = new ArrayList<>(); List values = new ArrayList<>(); List contacts = null; for (LayoutConstraintDTO constraint : layoutGroup.getConstraints()) { FlexibleElementDTO element = constraint.getFlexibleElementDTO(); - ValueResult valueResult = exporter.execute(new GetValue(projectId, element.getId(), "element." + element.getClass().getSimpleName(), null, null)); + ValueResult valueResult = exporter.execute(new GetValue(projectId, element.getId(), "element." + element.getClass().getSimpleName(), null, iterationId)); - if (element == contactListElement) { + if (element.equals(contactListElement)) { Set contactIds = new HashSet(ValueResultUtils.splitValuesAsInteger(valueResult.getValueObject())); if (!contactIds.isEmpty()) { contacts = exporter.execute(new GetContacts(contactIds)).getList(); } } else { - if (isFirst) { - iterationHeaders.add(new ExportStringCell(ExporterUtil.getFlexibleElementLabel(element, i18nTranslator, language))); - } - values.add(valueResultToDataCell(element, valueResult, i18nTranslator, language)); + values.add(valueResultToDataCell(element, valueResult, i18nTranslator, language, withLinks, exporter)); } } @@ -286,8 +310,6 @@ public static ContactSheetData createContactListSimpleTab(final Integer projectI isFirst = false; } - result.addHeaders(iterationHeaders); - return result; } @@ -428,7 +450,8 @@ public static List createRelationsByElementData(final Integer } private static ExportDataCell valueResultToDataCell(final FlexibleElementDTO element, final ValueResult valueResult, - final I18nServer i18nTranslator, final Language language) { + final I18nServer i18nTranslator, final Language language, + final boolean withLinks, final Exporter exporter) { ExportDataCell val = null; String elementName = element.getEntityName(); @@ -443,7 +466,11 @@ private static ExportDataCell valueResultToDataCell(final FlexibleElementDTO ele } else /* CHOICE */if (elementName.equals("element.QuestionElement")) { val = new ExportStringCell(getChoiceValue(valueResult, (QuestionElementDTO) element)); } else /* CONTACT_LIST */if (elementName.equals("element.ContactListElement")) { - val = new ExportLinkCell(String.valueOf(ExporterUtil.getContactListCount(valueResult)), ExportConstants.CONTACT_SHEET_PREFIX + element.getLabel()); + if (withLinks) { + val = new ExportLinkCell(String.valueOf(ExporterUtil.getContactListCount(valueResult)), ExportConstants.CONTACT_SHEET_PREFIX + element.getLabel()); + } else { + val = new ExportStringCell(ExporterUtil.getContactListFormatedValue(valueResult, exporter)); + } } return val; diff --git a/src/main/java/org/sigmah/server/servlet/exporter/utils/ExporterUtil.java b/src/main/java/org/sigmah/server/servlet/exporter/utils/ExporterUtil.java index d008bbfd9..953961a5d 100644 --- a/src/main/java/org/sigmah/server/servlet/exporter/utils/ExporterUtil.java +++ b/src/main/java/org/sigmah/server/servlet/exporter/utils/ExporterUtil.java @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.Date; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -54,6 +55,7 @@ import org.sigmah.server.domain.layout.LayoutConstraint; import org.sigmah.server.domain.layout.LayoutGroup; import org.sigmah.server.i18n.I18nServer; +import org.sigmah.server.servlet.exporter.base.Exporter; import org.sigmah.server.servlet.exporter.data.BaseSynthesisData; import org.sigmah.server.servlet.exporter.data.ExportData; import org.sigmah.server.servlet.exporter.data.cells.ExportDataCell; @@ -63,12 +65,15 @@ import org.sigmah.server.servlet.exporter.data.columns.GlobalExportFlexibleElementColumn; import org.sigmah.server.servlet.exporter.data.columns.GlobalExportIterativeGroupColumn; import org.sigmah.shared.Language; +import org.sigmah.shared.command.GetContacts; import org.sigmah.shared.command.GetValue; import org.sigmah.shared.command.result.ValueResult; import org.sigmah.shared.computation.value.ComputationError; import org.sigmah.shared.computation.value.ComputedValue; import org.sigmah.shared.computation.value.ComputedValues; import org.sigmah.shared.dispatch.CommandException; +import org.sigmah.shared.dispatch.DispatchException; +import org.sigmah.shared.dto.ContactDTO; import org.sigmah.shared.dto.element.BudgetElementDTO; import org.sigmah.shared.dto.element.BudgetRatioElementDTO; import org.sigmah.shared.dto.element.CheckboxElementDTO; @@ -572,6 +577,38 @@ public static ValueLabel getTripletPair(final FlexibleElement element, final Val return new ValueLabel(element.getLabel(), value, lines); } + public static String getContactListFormatedValue(final ValueResult valueResult, final Exporter exporter) { + + String value = null; + int lines = 1; + + if (valueResult != null && valueResult.isValueDefined()) { + + // Retrieving list values from database. + final List contacts; + try { + contacts = exporter.execute(new GetContacts(new HashSet(ValueResultUtils.splitValuesAsInteger(valueResult.getValueObject())))).getList(); + } catch (DispatchException e) { + return null; + } + + final StringBuilder builder = new StringBuilder(); + for (final ContactDTO contact : contacts) { + builder.append(" - ") + .append(contact.getFullName()) + .append("\n"); + lines++; + } + + if (lines > 1) { + value = builder.substring(0, builder.length() - 1); + lines--; + } + } + + return value; + } + @Deprecated public static ValueLabel getContactListPair(final FlexibleElement element, final ValueResult valueResult, final EntityManager entityManager) { diff --git a/src/main/java/org/sigmah/shared/dto/element/ContactListElementDTO.java b/src/main/java/org/sigmah/shared/dto/element/ContactListElementDTO.java index c4aefb072..c6e3db385 100644 --- a/src/main/java/org/sigmah/shared/dto/element/ContactListElementDTO.java +++ b/src/main/java/org/sigmah/shared/dto/element/ContactListElementDTO.java @@ -21,11 +21,14 @@ * #L% */ -import com.google.gwt.event.dom.client.ClickEvent; -import com.google.gwt.event.dom.client.ClickHandler; -import com.google.gwt.user.client.rpc.AsyncCallback; -import com.google.gwt.user.client.ui.Anchor; -import com.google.gwt.user.client.ui.Image; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import com.allen_sauer.gwt.log.client.Log; import com.extjs.gxt.ui.client.Style.HorizontalAlignment; import com.extjs.gxt.ui.client.event.ButtonEvent; import com.extjs.gxt.ui.client.event.EventType; @@ -49,14 +52,11 @@ import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer; import com.extjs.gxt.ui.client.widget.layout.FitLayout; import com.extjs.gxt.ui.client.widget.toolbar.ToolBar; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.ui.Anchor; +import com.google.gwt.user.client.ui.Image; import org.sigmah.client.dispatch.CommandResultHandler; import org.sigmah.client.dispatch.DispatchQueue; import org.sigmah.client.dispatch.monitor.LoadingMask; @@ -64,6 +64,7 @@ import org.sigmah.client.event.handler.OfflineHandler; import org.sigmah.client.i18n.I18N; import org.sigmah.client.page.Page; +import org.sigmah.client.page.PageManager; import org.sigmah.client.page.RequestParameter; import org.sigmah.client.ui.res.icon.IconImageBundle; import org.sigmah.client.ui.widget.FlexibleGrid; @@ -73,6 +74,7 @@ import org.sigmah.client.ui.widget.form.FormPanel; import org.sigmah.client.ui.widget.form.Forms; import org.sigmah.client.ui.widget.form.ListComboBox; +import org.sigmah.client.util.ClientUtils; import org.sigmah.client.util.profiler.Profiler; import org.sigmah.client.util.profiler.Scenario; import org.sigmah.offline.status.ApplicationState; @@ -97,10 +99,10 @@ import org.sigmah.shared.dto.orgunit.OrgUnitDTO; import org.sigmah.shared.dto.referential.ContactModelType; import org.sigmah.shared.dto.referential.ValueEventChangeType; +import org.sigmah.shared.servlet.ServletConstants; +import org.sigmah.shared.servlet.ServletUrlBuilder; import org.sigmah.shared.util.ValueResultUtils; -import com.allen_sauer.gwt.log.client.Log; - public class ContactListElementDTO extends FlexibleElementDTO { private static final long serialVersionUID = 646913359144175456L; @@ -114,6 +116,10 @@ public class ContactListElementDTO extends FlexibleElementDTO { private static final String STYLE_CONTACT_GRID_NAME = "contact-grid-name"; + protected transient PageManager pageManager; + protected transient Integer layoutGroupId; + protected transient Integer iterationId; + private static class OrgUnitSelectionChangedListener extends SelectionChangedListener { private final AdapterField secondaryOrgUnitsFieldAdapter; @@ -295,6 +301,21 @@ public void componentSelected(ButtonEvent ce) { } })); + actionsToolBar.add(Forms.button(I18N.CONSTANTS.exportAll(), IconImageBundle.ICONS.excel(), + new SelectionListener() { + @Override + public void componentSelected(ButtonEvent buttonEvent) { + final ServletUrlBuilder urlBuilder = new ServletUrlBuilder(authenticationProvider, pageManager, ServletConstants.Servlet.EXPORT, ServletConstants.ServletMethod.EXPORT_CONTACT_LIST); + + urlBuilder.addParameter(RequestParameter.ID, currentContainerDTO.getId()); + urlBuilder.addParameter(RequestParameter.LAYOUT_GROUP_ID, layoutGroupId); + urlBuilder.addParameter(RequestParameter.ITERATION_ID, iterationId!=null?iterationId:-1); + urlBuilder.addParameter(RequestParameter.CONTACT_LIST_ID, getId()); + + ClientUtils.launchDownload(urlBuilder.toString()); + } + })); + final Label offlineLabel = new Label(I18N.CONSTANTS.sigmahContactsOfflineUnavailable()); actionsToolBar.add(offlineLabel); @@ -711,6 +732,18 @@ public void setCheckboxElement(CheckboxElementDTO checkboxElement) { set(CHECKBOX_ELEMENT, checkboxElement); } + public void setPageManager(PageManager pageManager) { + this.pageManager = pageManager; + } + + public void setLayoutGroupId(Integer layoutGroupId) { + this.layoutGroupId = layoutGroupId; + } + + public void setIterationId(Integer iterationId) { + this.iterationId = iterationId; + } + @Override public String getEntityName() { diff --git a/src/main/java/org/sigmah/shared/servlet/ServletConstants.java b/src/main/java/org/sigmah/shared/servlet/ServletConstants.java index f9c7f7bbe..0a04bee51 100644 --- a/src/main/java/org/sigmah/shared/servlet/ServletConstants.java +++ b/src/main/java/org/sigmah/shared/servlet/ServletConstants.java @@ -321,6 +321,18 @@ public static enum ServletMethod { */ EXPORT_CONTACT_GLOBAL("exportContactGlobal"), + /** + *

Global Export Contacts.

+ *

+ * Expected request parameter(s): + *

    + *
  • {@link RequestParameter#ID} : Container id.
  • + *
  • {@link RequestParameter#ITERATION_ID} : Iteration id.
  • + *
  • {@link RequestParameter#CONTACT_LIST_ID} : ContactList field id.
  • + *
+ */ + EXPORT_CONTACT_LIST("exportContactList"), + /** *

Model Gategory Export.

*

From 0f8351f0d2665d87a1ac574cde30c27687774ddd Mon Sep 17 00:00:00 2001 From: Thibault Degivry Date: Wed, 29 Nov 2017 15:31:42 +0100 Subject: [PATCH 3/4] Add import to contact lists (button + mechanism) (refs #634) Change-Id: Ie22a1e7a9090c49644c30c31dc0129d3bb788760 --- .../ContactListImportResultPopup.java | 101 +++++++++++ .../GetContactImportationSchemesHandler.java | 65 +++++++ .../server/inject/CommandHandlerModule.java | 3 + .../command/GetContactImportationSchemes.java | 88 ++++++++++ .../dto/element/ContactListElementDTO.java | 158 +++++++++++++++++- .../sigmah/client/i18n/UIConstants.properties | 2 + 6 files changed, 409 insertions(+), 8 deletions(-) create mode 100644 src/main/java/org/sigmah/client/ui/view/importation/ContactListImportResultPopup.java create mode 100644 src/main/java/org/sigmah/server/handler/GetContactImportationSchemesHandler.java create mode 100644 src/main/java/org/sigmah/shared/command/GetContactImportationSchemes.java diff --git a/src/main/java/org/sigmah/client/ui/view/importation/ContactListImportResultPopup.java b/src/main/java/org/sigmah/client/ui/view/importation/ContactListImportResultPopup.java new file mode 100644 index 000000000..5e2744f2d --- /dev/null +++ b/src/main/java/org/sigmah/client/ui/view/importation/ContactListImportResultPopup.java @@ -0,0 +1,101 @@ +package org.sigmah.client.ui.view.importation; + +/* + * #%L + * Sigmah + * %% + * Copyright (C) 2010 - 2016 URD + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +import java.util.Arrays; +import java.util.List; + +import com.extjs.gxt.ui.client.event.ButtonEvent; +import com.extjs.gxt.ui.client.event.SelectionListener; +import com.extjs.gxt.ui.client.store.ListStore; +import com.extjs.gxt.ui.client.widget.grid.ColumnConfig; +import com.extjs.gxt.ui.client.widget.grid.ColumnModel; +import com.extjs.gxt.ui.client.widget.grid.Grid; +import org.sigmah.client.i18n.I18N; +import org.sigmah.client.ui.widget.button.Button; +import org.sigmah.client.ui.widget.form.Forms; +import org.sigmah.client.ui.widget.layout.Layouts; +import org.sigmah.client.ui.widget.popup.PopupWidget; +import org.sigmah.shared.dto.ContactDTO; + +/** + * Popup displaying a short report about an automated import. + * + * @author Raphaƫl Calabro (raphael.calabro@netapsys.fr) + */ +public class ContactListImportResultPopup extends PopupWidget { + + private Grid grid; + private Button closeButton; + + public ContactListImportResultPopup() { + super(true, Layouts.fitLayout()); + setWidth("700px"); + setHeight("500px"); + initialize(); + } + + public ContactListImportResultPopup(List contacts) { + this(); + grid.getStore().add(contacts); + } + + /** + * Creates the inner components of the popup. + */ + public void initialize() { + setTitle(I18N.CONSTANTS.ignoredImportedContacts()); + + // Building the grid. + grid = new Grid(new ListStore(), createColumnModel()); + + // Creating the OK button. + closeButton = Forms.button(I18N.CONSTANTS.ok(), new SelectionListener() { + @Override + public void componentSelected(ButtonEvent buttonEvent) { + hide(); + } + }); + + // Preparing the popup. + setContent(grid); + addButton(closeButton); + } + + /** + * Creates the column model. + */ + private ColumnModel createColumnModel() { + + // Project code column. + final ColumnConfig projectNameColumnConfig = new ColumnConfig(ContactDTO.NAME, I18N.CONSTANTS.contactName(), 325); + + // Project title column. + final ColumnConfig projectFirstNameColumnConfig = new ColumnConfig(ContactDTO.FIRSTNAME, I18N.CONSTANTS.contactFirstName(), 325); + + // Creating the column model. + return new ColumnModel(Arrays.asList( + projectNameColumnConfig, + projectFirstNameColumnConfig)); + } +} diff --git a/src/main/java/org/sigmah/server/handler/GetContactImportationSchemesHandler.java b/src/main/java/org/sigmah/server/handler/GetContactImportationSchemesHandler.java new file mode 100644 index 000000000..55cf0cc97 --- /dev/null +++ b/src/main/java/org/sigmah/server/handler/GetContactImportationSchemesHandler.java @@ -0,0 +1,65 @@ +package org.sigmah.server.handler; + +/* + * #%L + * Sigmah + * %% + * Copyright (C) 2010 - 2016 URD + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.TypedQuery; + +import org.sigmah.server.dispatch.impl.UserDispatch.UserExecutionContext; +import org.sigmah.server.domain.importation.ImportationScheme; +import org.sigmah.server.handler.base.AbstractCommandHandler; +import org.sigmah.shared.command.GetContactImportationSchemes; +import org.sigmah.shared.command.GetImportationSchemes; +import org.sigmah.shared.command.result.ListResult; +import org.sigmah.shared.dispatch.CommandException; +import org.sigmah.shared.dto.importation.ImportationSchemeDTO; + +/** + * {@link GetContactImportationSchemes} command execution. + * + * @author Guerline Jean-Baptiste (gjbaptiste@ideia.fr) (v1.3) + * @author Maxime Lombard (mlombard@ideia.fr) (v2.0) + */ +public class GetContactImportationSchemesHandler extends AbstractCommandHandler> { + + /** + * {@inheritDoc} + */ + @Override + public ListResult execute(final GetContactImportationSchemes cmd, final UserExecutionContext context) throws CommandException { + + final TypedQuery query; + + if (cmd.getContactModelIds() != null && !cmd.getContactModelIds().isEmpty()) { + query = + em().createQuery("SELECT sm.importationScheme FROM ImportationSchemeModel sm WHERE sm.contactModel.id IN :projectModelIds", ImportationScheme.class); + query.setParameter("projectModelIds", cmd.getContactModelIds()); + } else { + query = em().createQuery("SELECT sm.importationScheme FROM ImportationSchemeModel sm WHERE sm.contactModel.id IS NOT NULL", ImportationScheme.class); + } + + return new ListResult(mapper().mapCollection(query.getResultList(), ImportationSchemeDTO.class)); + } +} diff --git a/src/main/java/org/sigmah/server/inject/CommandHandlerModule.java b/src/main/java/org/sigmah/server/inject/CommandHandlerModule.java index 0435d0c7b..3440adf7e 100644 --- a/src/main/java/org/sigmah/server/inject/CommandHandlerModule.java +++ b/src/main/java/org/sigmah/server/inject/CommandHandlerModule.java @@ -57,6 +57,7 @@ import org.sigmah.server.handler.GetContactDuplicatedPropertiesHandler; import org.sigmah.server.handler.GetContactHandler; import org.sigmah.server.handler.GetContactHistoryHandler; +import org.sigmah.server.handler.GetContactImportationSchemesHandler; import org.sigmah.server.handler.GetContactModelCopyHandler; import org.sigmah.server.handler.GetContactModelHandler; import org.sigmah.server.handler.GetContactModelsHandler; @@ -186,6 +187,7 @@ import org.sigmah.shared.command.GetContactByNameOrEmail; import org.sigmah.shared.command.GetContactDuplicatedProperties; import org.sigmah.shared.command.GetContactHistory; +import org.sigmah.shared.command.GetContactImportationSchemes; import org.sigmah.shared.command.GetContactModel; import org.sigmah.shared.command.GetContactModelCopy; import org.sigmah.shared.command.GetContactModels; @@ -352,6 +354,7 @@ protected void configureHandlers() { bindHandler(GetHistory.class, GetHistoryHandler.class); bindHandler(GetImportationSchemeModels.class, GetImportationSchemeModelsHandler.class); bindHandler(GetImportationSchemes.class, GetImportationSchemesHandler.class); + bindHandler(GetContactImportationSchemes.class, GetContactImportationSchemesHandler.class); bindHandler(GetImportInformation.class, GetImportInformationHandler.class); bindHandler(GetIndicatorDataSources.class, GetIndicatorDataSourcesHandler.class); bindHandler(GetIndicators.class, GetIndicatorsHandler.class); diff --git a/src/main/java/org/sigmah/shared/command/GetContactImportationSchemes.java b/src/main/java/org/sigmah/shared/command/GetContactImportationSchemes.java new file mode 100644 index 000000000..76d4f87fd --- /dev/null +++ b/src/main/java/org/sigmah/shared/command/GetContactImportationSchemes.java @@ -0,0 +1,88 @@ +package org.sigmah.shared.command; + +/* + * #%L + * Sigmah + * %% + * Copyright (C) 2010 - 2016 URD + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +import java.util.Set; + +import org.sigmah.shared.command.base.AbstractCommand; +import org.sigmah.shared.command.result.ListResult; +import org.sigmah.shared.dto.importation.ImportationSchemeDTO; + +/** + * @author Denis Colliot (dcolliot@ideia.fr) + */ +public class GetContactImportationSchemes extends AbstractCommand> { + + private Integer schemaId; + + private Set contactModelIds; + + private Boolean excludeExistent = false; + + public GetContactImportationSchemes() { + // Serialization. + } + + public GetContactImportationSchemes(Set contactModelIds) { + this.contactModelIds = contactModelIds; + } + + public Integer getSchemaId() { + return schemaId; + } + + public void setSchemaId(Integer schemaId) { + this.schemaId = schemaId; + } + + /** + * @return the excludeExistent + */ + public Boolean getExcludeExistent() { + return excludeExistent; + } + + /** + * @param excludeExistent + * the excludeExistent to set + */ + public void setExcludeExistent(Boolean excludeExistent) { + this.excludeExistent = excludeExistent; + } + + /** + * @return the contactModelIds + */ + public Set getContactModelIds() { + return contactModelIds; + } + + /** + * @param contactModelIds + * the contactModelIds to set + */ + public void setContactModelId(Set contactModelIds) { + this.contactModelIds = contactModelIds; + } + +} diff --git a/src/main/java/org/sigmah/shared/dto/element/ContactListElementDTO.java b/src/main/java/org/sigmah/shared/dto/element/ContactListElementDTO.java index c6e3db385..5ca85a9e4 100644 --- a/src/main/java/org/sigmah/shared/dto/element/ContactListElementDTO.java +++ b/src/main/java/org/sigmah/shared/dto/element/ContactListElementDTO.java @@ -30,8 +30,12 @@ import com.allen_sauer.gwt.log.client.Log; import com.extjs.gxt.ui.client.Style.HorizontalAlignment; +import com.extjs.gxt.ui.client.data.BaseModelData; +import com.extjs.gxt.ui.client.event.BaseEvent; import com.extjs.gxt.ui.client.event.ButtonEvent; import com.extjs.gxt.ui.client.event.EventType; +import com.extjs.gxt.ui.client.event.Events; +import com.extjs.gxt.ui.client.event.FormEvent; import com.extjs.gxt.ui.client.event.Listener; import com.extjs.gxt.ui.client.event.SelectionChangedEvent; import com.extjs.gxt.ui.client.event.SelectionChangedListener; @@ -45,6 +49,8 @@ import com.extjs.gxt.ui.client.widget.Window; import com.extjs.gxt.ui.client.widget.form.AdapterField; import com.extjs.gxt.ui.client.widget.form.ComboBox; +import com.extjs.gxt.ui.client.widget.form.FileUploadField; +import com.extjs.gxt.ui.client.widget.form.FormPanel; import com.extjs.gxt.ui.client.widget.form.TextField; import com.extjs.gxt.ui.client.widget.grid.ColumnConfig; import com.extjs.gxt.ui.client.widget.grid.ColumnData; @@ -54,6 +60,7 @@ import com.extjs.gxt.ui.client.widget.toolbar.ToolBar; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.http.client.Response; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.Image; @@ -66,23 +73,28 @@ import org.sigmah.client.page.Page; import org.sigmah.client.page.PageManager; import org.sigmah.client.page.RequestParameter; +import org.sigmah.client.ui.notif.N10N; import org.sigmah.client.ui.res.icon.IconImageBundle; +import org.sigmah.client.ui.view.importation.ContactListImportResultPopup; import org.sigmah.client.ui.widget.FlexibleGrid; import org.sigmah.client.ui.widget.HistoryTokenText; +import org.sigmah.client.ui.widget.button.Button; import org.sigmah.client.ui.widget.contact.ContactPicker; import org.sigmah.client.ui.widget.contact.DedupeContactDialog; -import org.sigmah.client.ui.widget.form.FormPanel; import org.sigmah.client.ui.widget.form.Forms; import org.sigmah.client.ui.widget.form.ListComboBox; import org.sigmah.client.util.ClientUtils; import org.sigmah.client.util.profiler.Profiler; import org.sigmah.client.util.profiler.Scenario; +import org.sigmah.offline.fileapi.Blob; import org.sigmah.offline.status.ApplicationState; import org.sigmah.offline.sync.SuccessCallback; +import org.sigmah.shared.command.AutomatedImport; import org.sigmah.shared.command.CheckContactDuplication; import org.sigmah.shared.command.CreateEntity; import org.sigmah.shared.command.DedupeContact; import org.sigmah.shared.command.GetContactDuplicatedProperties; +import org.sigmah.shared.command.GetContactImportationSchemes; import org.sigmah.shared.command.GetContactModels; import org.sigmah.shared.command.GetContacts; import org.sigmah.shared.command.GetOrgUnits; @@ -96,9 +108,11 @@ import org.sigmah.shared.dto.element.event.ValueEvent; import org.sigmah.shared.dto.history.HistoryTokenDTO; import org.sigmah.shared.dto.history.HistoryTokenListDTO; +import org.sigmah.shared.dto.importation.ImportationSchemeDTO; import org.sigmah.shared.dto.orgunit.OrgUnitDTO; import org.sigmah.shared.dto.referential.ContactModelType; import org.sigmah.shared.dto.referential.ValueEventChangeType; +import org.sigmah.shared.dto.value.FileUploadUtils; import org.sigmah.shared.servlet.ServletConstants; import org.sigmah.shared.servlet.ServletUrlBuilder; import org.sigmah.shared.util.ValueResultUtils; @@ -316,6 +330,14 @@ public void componentSelected(ButtonEvent buttonEvent) { } })); + actionsToolBar.add(Forms.button(I18N.CONSTANTS.importContact(), IconImageBundle.ICONS.excel(), + new SelectionListener() { + @Override + public void componentSelected(ButtonEvent buttonEvent) { + showContactListImporter(store); + } + })); + final Label offlineLabel = new Label(I18N.CONSTANTS.sigmahContactsOfflineUnavailable()); actionsToolBar.add(offlineLabel); @@ -364,7 +386,7 @@ private ColumnConfig[] getColumnModel(boolean enabled) { typeColumn.setRenderer(new GridCellRenderer() { @Override public Object render(final ContactDTO model, final String property, final ColumnData config, final int rowIndex, final int colIndex, - final ListStore store, final Grid grid) { + final ListStore store, final Grid grid) { ContactModelType type = model.get(property); @@ -384,7 +406,7 @@ public Object render(final ContactDTO model, final String property, final Column @Override public Object render(final ContactDTO model, final String property, final ColumnData config, final int rowIndex, final int colIndex, - final ListStore store, final Grid grid) { + final ListStore store, final Grid grid) { final Anchor nameLink = new Anchor((String) model.get(property)); @@ -423,7 +445,7 @@ public void onClick(ClickEvent event) { if (!enabled) { return new ColumnConfig[] { - typeColumn, nameColumn, firstnameColumn, emailColumn, idColumn + typeColumn, nameColumn, firstnameColumn, emailColumn, idColumn }; } @@ -437,7 +459,7 @@ public void onClick(ClickEvent event) { @Override public Object render(final ContactDTO model, String property, ColumnData config, int rowIndex, int colIndex, final ListStore store, - Grid grid) { + Grid grid) { final Image image = IconImageBundle.ICONS.deleteIcon().createImage(); image.setTitle(I18N.CONSTANTS.remove()); @@ -455,7 +477,7 @@ public void onClick(final ClickEvent event) { }); return new ColumnConfig[] { - typeColumn, nameColumn, firstnameColumn, emailColumn, idColumn, removeColumn + typeColumn, nameColumn, firstnameColumn, emailColumn, idColumn, removeColumn }; } @@ -507,6 +529,126 @@ public void componentSelected(ButtonEvent ce) { window.show(); } + private void showContactListImporter(final ListStore store) { + // Window + final Window window = new Window(); + window.setPlain(true); + window.setModal(true); + window.setBlinkModal(true); + window.setLayout(new FitLayout()); + window.setSize(350, 180); + window.setHeadingHtml(I18N.CONSTANTS.importContact()); + + // Scheme field + final ComboBox schemeField = Forms.combobox(I18N.CONSTANTS.adminImportationScheme(), true, ImportationSchemeDTO.ID, ImportationSchemeDTO.NAME); + schemeField.setName(FileUploadUtils.DOCUMENT_ID); + + dispatch.execute(new GetContactImportationSchemes(getAllowedModelIds()), new CommandResultHandler>() { + @Override + protected void onCommandSuccess(ListResult result) { + schemeField.getStore().add(result.getList()); + } + }); + + // File field + final FileUploadField fileField = Forms.upload(I18N.CONSTANTS.adminFileImport()); + fileField.setName(FileUploadUtils.DOCUMENT_CONTENT); + + // Button + final Button importButton = Forms.button(I18N.CONSTANTS.IMPORT_BUTTON(), IconImageBundle.ICONS.add()); + + schemeField.addListener(Events.Select, new Listener() { + @Override + public void handleEvent(BaseEvent be) { + importButton.setEnabled(schemeField.getValue() != null); + } + }); + + // Form + final FormPanel form = Forms.panel(); + form.add(schemeField); + form.add(fileField); + form.getButtonBar().add(importButton); + + form.setEncoding(FormPanel.Encoding.MULTIPART); + form.setMethod(FormPanel.Method.POST); + + importButton.addSelectionListener(new SelectionListener() { + @Override + public void componentSelected(ButtonEvent ce) { + if (form.isValid()) { + ServletUrlBuilder servletUrlBuilder = new ServletUrlBuilder(authenticationProvider, pageManager, ServletConstants.Servlet.IMPORT, ServletConstants.ServletMethod.IMPORT_STORE_FILE); + form.setAction(servletUrlBuilder.toString()); + form.submit(); + } else { + N10N.warn(I18N.CONSTANTS.createFormIncomplete()); + } + }}); + + form.addListener(Events.Submit, new Listener() { + @Override + public void handleEvent(FormEvent be) { + submitContactListImport(be.getResultHtml(), Blob.getBlobFromInputFileElement(fileField.getFileInput()).getName(), schemeField.getValue(), importButton, store, window); + } + }); + + window.add(form); + window.show(); + } + + private void submitContactListImport(String result, String fileName, ImportationSchemeDTO scheme, final Button button, final ListStore store, final Window window) { + switch (ServletConstants.getErrorCode(result)) { + case Response.SC_OK: + dispatch.execute(new AutomatedImport(result, fileName, scheme, false, false, false), + new AsyncCallback>() { + @Override + public void onSuccess(ListResult results) { + computeImportResults(results, store, window); + } + @Override + public void onFailure(Throwable throwable) { + Log.error("Error while importing contacts", throwable); + } + }, button, new LoadingMask(window)); + break; + default: + N10N.error(I18N.CONSTANTS.createFormIncomplete(), I18N.MESSAGES.importFormIncompleteDetails("")); + break; + } + } + + private void computeImportResults(ListResult results, final ListStore store, final Window window) { + Set contactIds = new HashSet(results.getSize()); + for (BaseModelData baseModelData : results.getList()) { + contactIds.add((Integer) baseModelData.get("id")); + } + dispatch.execute(new GetContacts(contactIds), + new AsyncCallback>() { + @Override + public void onSuccess(ListResult contactDTOListResult) { + List exclusions = new ArrayList(); + for (ContactDTO contact : contactDTOListResult.getList()) { + if (store.contains(contact) || + (getAllowedType() != null && !getAllowedType().equals(contact.getContactModel().getType())) || + (!getAllowedModelIds().isEmpty() && !getAllowedModelIds().contains(contact.getContactModel().getId()))) { + exclusions.add(contact); + } else { + store.add(contact); + } + } + if (!exclusions.isEmpty()) { + ContactListImportResultPopup a = new ContactListImportResultPopup(exclusions); + a.show(); + } + window.hide(); + } + @Override + public void onFailure(Throwable throwable) { + Log.error("Error while adding contacts", throwable); + } + }, new LoadingMask(window)); + } + private void showContactCreator(final ListStore store) { final Window window = new Window(); window.setPlain(true); @@ -558,8 +700,8 @@ public void componentSelected(ButtonEvent event) { } handleContactCreation(store, contactModelComboBox.getValue(), emailField.getValue(), - firstNameField.getValue(), familyNameField.getValue(), organizationNameField.getValue(), - mainOrgUnitComboBox.getValue(), secondaryOrgUnitsComboBox.getListStore().getModels()); + firstNameField.getValue(), familyNameField.getValue(), organizationNameField.getValue(), + mainOrgUnitComboBox.getValue(), secondaryOrgUnitsComboBox.getListStore().getModels()); window.hide(); } }); diff --git a/src/main/resources/org/sigmah/client/i18n/UIConstants.properties b/src/main/resources/org/sigmah/client/i18n/UIConstants.properties index 9b023506c..7bee228f8 100644 --- a/src/main/resources/org/sigmah/client/i18n/UIConstants.properties +++ b/src/main/resources/org/sigmah/client/i18n/UIConstants.properties @@ -1999,4 +1999,6 @@ contactPermanentId=Contact Id contactFullName=Contact Name iterationName=Iteration Name +ignoredImportedContacts=Ignored imported contacts + seeIterationDetails=See details From 780ff4cdee51a696ba72f0639ccb7d0dab61df89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Tavin?= Date: Wed, 6 Dec 2017 10:22:27 +0100 Subject: [PATCH 4/4] Codacy fixes Change-Id: Iccd49fa73838bca4f3308be137e7317c1b704073 --- .../contact/ContactDetailsPresenter.java | 210 ++++++++++-------- .../project/ProjectDetailsPresenter.java | 1 - .../ContactListImportResultPopup.java | 3 +- .../GetContactImportationSchemesHandler.java | 4 - .../servlet/exporter/ContactListExporter.java | 1 - 5 files changed, 117 insertions(+), 102 deletions(-) diff --git a/src/main/java/org/sigmah/client/ui/presenter/contact/ContactDetailsPresenter.java b/src/main/java/org/sigmah/client/ui/presenter/contact/ContactDetailsPresenter.java index f705a88ae..f51e81558 100644 --- a/src/main/java/org/sigmah/client/ui/presenter/contact/ContactDetailsPresenter.java +++ b/src/main/java/org/sigmah/client/ui/presenter/contact/ContactDetailsPresenter.java @@ -462,100 +462,7 @@ public FieldSet createGroupLayoutFieldSet(FlexibleElementContainer container, fi // -- // Remote call to ask for this element value. - queue.add(new GetValue(contact.getId(), elementDTO.getId(), elementDTO.getEntityName(), null, iterationId), new CommandResultHandler() { - - @Override - public void onCommandFailure(final Throwable throwable) { - if (Log.isErrorEnabled()) { - Log.error("Error, element value not loaded.", throwable); - } - throw new RuntimeException(throwable); - } - - @Override - public void onCommandSuccess(final ValueResult valueResult) { - - if (Log.isDebugEnabled()) { - Log.debug("Element value(s) object : " + valueResult); - } - - // -- - // -- ELEMENT COMPONENT - // -- - - // Configures the flexible element for the current application state before generating its component. - elementDTO.setService(dispatch); - elementDTO.setAuthenticationProvider(injector.getAuthenticationProvider()); - elementDTO.setEventBus(eventBus); - elementDTO.setCache(injector.getClientCache()); - elementDTO.setCurrentContainerDTO(contact); - elementDTO.setTransfertManager(injector.getTransfertManager()); - elementDTO.assignValue(valueResult); - elementDTO.setImageProvider(imageProvider); - if (elementDTO instanceof DefaultContactFlexibleElementDTO) { - ((DefaultContactFlexibleElementDTO) elementDTO).setFormPanel(formPanel); - } - elementDTO.setTabPanel(tabPanel); - - if (elementDTO instanceof ContactListElementDTO) { - ContactListElementDTO contactListElement = (ContactListElementDTO)elementDTO; - contactListElement.setPageManager(injector.getPageManager()); - contactListElement.setLayoutGroupId(groupLayout.getId()); - contactListElement.setIterationId(iterationId); - } - - // Generates element component (with the value). - elementDTO.init(); - final Component elementComponent = elementDTO.getElementComponent(valueResult); - - // Component width. - final FormData formData; - if (elementDTO.getPreferredWidth() == 0) { - formData = new FormData("100%"); - } else { - formData = new FormData(elementDTO.getPreferredWidth(), -1); - } - - if (elementComponent != null) { - fieldSet.add(elementComponent, formData); - } - fieldSet.layout(); - - // -- - // -- ELEMENT HANDLERS - // -- - - // Adds a value change handler if this element is a dependency of a ComputationElementDTO. - Integer iterationId = tabItem == null ? null : tabItem.getIterationId(); - computationTriggerManager.listenToValueChangesOfElement(elementDTO, elementComponent, valueChanges, iterationId); - - // Adds a value change handler to this element. - elementDTO.addValueHandler(new ValueHandler() { - - @Override - public void onValueChange(final ValueEvent event) { - - if(tabPanel != null) { - event.setIterationId(tabPanel.getCurrentIterationId()); - } - - // TODO: Find linked computation fields if any and recompute the value. - - // Stores the change to be saved later. - valueChanges.add(event); - - // Enables the save action. - view.getSaveButton().enable(); - } - }); - - if(elementDTO.getValidates() && tabItem != null) { - tabItem.setElementValidity(elementDTO, elementDTO.isCorrectRequiredValue(valueResult)); - tabItem.refreshTitle(); - elementDTO.addRequiredValueHandler(new RequiredValueHandlerImpl(elementDTO)); - } - } - }, new LoadingMask(view.getDetailsContainer())); + queue.add(new GetValue(contact.getId(), elementDTO.getId(), elementDTO.getEntityName(), null, iterationId), new GetValueResultCommandResultHandler(elementDTO, contact, tabPanel, groupLayout, iterationId, fieldSet, tabItem), new LoadingMask(view.getDetailsContainer())); } fieldSet.setCollapsible(false); @@ -876,4 +783,119 @@ public void onExportContact(final boolean characteristicsField, final boolean al public boolean hasValueChanged() { return !valueChanges.isEmpty() || !iterationChanges.isEmpty(); } + + private class GetValueResultCommandResultHandler extends CommandResultHandler { + + private final FlexibleElementDTO elementDTO; + private final ContactDTO contact; + private final IterableGroupPanel tabPanel; + private final LayoutGroupDTO groupLayout; + private final Integer iterationId; + private final FieldSet fieldSet; + private final IterableGroupItem tabItem; + + public GetValueResultCommandResultHandler(FlexibleElementDTO elementDTO, ContactDTO contact, IterableGroupPanel tabPanel, LayoutGroupDTO groupLayout, Integer iterationId, FieldSet fieldSet, IterableGroupItem tabItem) { + this.elementDTO = elementDTO; + this.contact = contact; + this.tabPanel = tabPanel; + this.groupLayout = groupLayout; + this.iterationId = iterationId; + this.fieldSet = fieldSet; + this.tabItem = tabItem; + } + + @Override + public void onCommandFailure(final Throwable throwable) { + if (Log.isErrorEnabled()) { + Log.error("Error, element value not loaded.", throwable); + } + throw new RuntimeException(throwable); + } + + @Override + public void onCommandSuccess(final ValueResult valueResult) { + + if (Log.isDebugEnabled()) { + Log.debug("Element value(s) object : " + valueResult); + } + + // -- + // -- ELEMENT COMPONENT + // -- + + // Configures the flexible element for the current application state before generating its component. + elementDTO.setService(dispatch); + elementDTO.setAuthenticationProvider(injector.getAuthenticationProvider()); + elementDTO.setEventBus(eventBus); + elementDTO.setCache(injector.getClientCache()); + elementDTO.setCurrentContainerDTO(contact); + elementDTO.setTransfertManager(injector.getTransfertManager()); + elementDTO.assignValue(valueResult); + elementDTO.setImageProvider(imageProvider); + if (elementDTO instanceof DefaultContactFlexibleElementDTO) { + ((DefaultContactFlexibleElementDTO) elementDTO).setFormPanel(formPanel); + } + elementDTO.setTabPanel(tabPanel); + + if (elementDTO instanceof ContactListElementDTO) { + ContactListElementDTO contactListElement = (ContactListElementDTO) elementDTO; + contactListElement.setPageManager(injector.getPageManager()); + contactListElement.setLayoutGroupId(groupLayout.getId()); + contactListElement.setIterationId(iterationId); + } + + // Generates element component (with the value). + elementDTO.init(); + final Component elementComponent = elementDTO.getElementComponent(valueResult); + + // Component width. + final FormData formData; + if (elementDTO.getPreferredWidth() == 0) { + formData = new FormData("100%"); + } else { + formData = new FormData(elementDTO.getPreferredWidth(), -1); + } + + if (elementComponent != null) { + fieldSet.add(elementComponent, formData); + } + fieldSet.layout(); + + // -- + // -- ELEMENT HANDLERS + // -- + + // Adds a value change handler if this element is a dependency of a ComputationElementDTO. + Integer iterationId = tabItem == null ? null : tabItem.getIterationId(); + computationTriggerManager.listenToValueChangesOfElement(elementDTO, elementComponent, valueChanges, iterationId); + + // Adds a value change handler to this element. + elementDTO.addValueHandler(new ValueChangeHandler()); + + if(elementDTO.getValidates() && tabItem != null) { + tabItem.setElementValidity(elementDTO, elementDTO.isCorrectRequiredValue(valueResult)); + tabItem.refreshTitle(); + elementDTO.addRequiredValueHandler(new RequiredValueHandlerImpl(elementDTO)); + } + } + + private class ValueChangeHandler implements ValueHandler { + + @Override + public void onValueChange(final ValueEvent event) { + + if(tabPanel != null) { + event.setIterationId(tabPanel.getCurrentIterationId()); + } + + // TODO: Find linked computation fields if any and recompute the value. + + // Stores the change to be saved later. + valueChanges.add(event); + + // Enables the save action. + view.getSaveButton().enable(); + } + } + } } diff --git a/src/main/java/org/sigmah/client/ui/presenter/project/ProjectDetailsPresenter.java b/src/main/java/org/sigmah/client/ui/presenter/project/ProjectDetailsPresenter.java index efc529915..6082ae511 100644 --- a/src/main/java/org/sigmah/client/ui/presenter/project/ProjectDetailsPresenter.java +++ b/src/main/java/org/sigmah/client/ui/presenter/project/ProjectDetailsPresenter.java @@ -61,7 +61,6 @@ import org.sigmah.client.ui.widget.layout.Layouts; import org.sigmah.client.util.ClientUtils; import org.sigmah.client.util.profiler.Profiler; -import org.sigmah.server.domain.layout.LayoutGroup; import org.sigmah.shared.command.GetLayoutGroupIterations; import org.sigmah.shared.command.GetOrgUnit; import org.sigmah.shared.command.GetValue; diff --git a/src/main/java/org/sigmah/client/ui/view/importation/ContactListImportResultPopup.java b/src/main/java/org/sigmah/client/ui/view/importation/ContactListImportResultPopup.java index 5e2744f2d..41ed4ae31 100644 --- a/src/main/java/org/sigmah/client/ui/view/importation/ContactListImportResultPopup.java +++ b/src/main/java/org/sigmah/client/ui/view/importation/ContactListImportResultPopup.java @@ -46,7 +46,6 @@ public class ContactListImportResultPopup extends PopupWidget { private Grid grid; - private Button closeButton; public ContactListImportResultPopup() { super(true, Layouts.fitLayout()); @@ -70,7 +69,7 @@ public void initialize() { grid = new Grid(new ListStore(), createColumnModel()); // Creating the OK button. - closeButton = Forms.button(I18N.CONSTANTS.ok(), new SelectionListener() { + Button closeButton = Forms.button(I18N.CONSTANTS.ok(), new SelectionListener() { @Override public void componentSelected(ButtonEvent buttonEvent) { hide(); diff --git a/src/main/java/org/sigmah/server/handler/GetContactImportationSchemesHandler.java b/src/main/java/org/sigmah/server/handler/GetContactImportationSchemesHandler.java index 55cf0cc97..21d0eafcd 100644 --- a/src/main/java/org/sigmah/server/handler/GetContactImportationSchemesHandler.java +++ b/src/main/java/org/sigmah/server/handler/GetContactImportationSchemesHandler.java @@ -22,16 +22,12 @@ * #L% */ -import java.util.ArrayList; -import java.util.List; - import javax.persistence.TypedQuery; import org.sigmah.server.dispatch.impl.UserDispatch.UserExecutionContext; import org.sigmah.server.domain.importation.ImportationScheme; import org.sigmah.server.handler.base.AbstractCommandHandler; import org.sigmah.shared.command.GetContactImportationSchemes; -import org.sigmah.shared.command.GetImportationSchemes; import org.sigmah.shared.command.result.ListResult; import org.sigmah.shared.dispatch.CommandException; import org.sigmah.shared.dto.importation.ImportationSchemeDTO; diff --git a/src/main/java/org/sigmah/server/servlet/exporter/ContactListExporter.java b/src/main/java/org/sigmah/server/servlet/exporter/ContactListExporter.java index 5c226acff..a75bf94a5 100644 --- a/src/main/java/org/sigmah/server/servlet/exporter/ContactListExporter.java +++ b/src/main/java/org/sigmah/server/servlet/exporter/ContactListExporter.java @@ -37,7 +37,6 @@ import org.sigmah.client.page.RequestParameter; import org.sigmah.server.servlet.base.ServletExecutionContext; import org.sigmah.server.servlet.exporter.base.Exporter; -import org.sigmah.server.servlet.exporter.data.ProjectSynthesisData; import org.sigmah.server.servlet.exporter.template.ExportTemplate; import org.sigmah.server.servlet.exporter.utils.ContactsSynthesisCalcTemplate; import org.sigmah.server.servlet.exporter.utils.ContactsSynthesisExcelTemplate;