package org.sigmah.server.servlet.exporter.utils; /* * #%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 * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.sigmah.server.i18n.I18nServer; import org.sigmah.server.servlet.exporter.base.Exporter; import org.sigmah.server.servlet.exporter.data.LogFrameExportData; import org.sigmah.server.servlet.exporter.data.cells.ExportDataCell; import org.sigmah.server.servlet.exporter.data.cells.ExportLinkCell; import org.sigmah.server.servlet.exporter.data.cells.ExportStringCell; import org.sigmah.shared.Language; import org.sigmah.shared.command.GetContactRelationships; import org.sigmah.shared.command.GetContacts; import org.sigmah.shared.command.GetLayoutGroupIterations; import org.sigmah.shared.command.GetProject; import org.sigmah.shared.command.GetValue; import org.sigmah.shared.command.result.ContactRelationship; import org.sigmah.shared.command.result.ListResult; import org.sigmah.shared.command.result.ValueResult; import org.sigmah.shared.dto.ContactDTO; import org.sigmah.shared.dto.ProjectDTO; import org.sigmah.shared.dto.element.ContactListElementDTO; import org.sigmah.shared.dto.element.DefaultContactFlexibleElementDTO; import org.sigmah.shared.dto.element.FlexibleElementDTO; import org.sigmah.shared.dto.element.QuestionChoiceElementDTO; import org.sigmah.shared.dto.element.QuestionElementDTO; import org.sigmah.shared.dto.element.TextAreaElementDTO; import org.sigmah.shared.dto.layout.LayoutConstraintDTO; import org.sigmah.shared.dto.layout.LayoutGroupDTO; import org.sigmah.shared.dto.layout.LayoutGroupIterationDTO; import org.sigmah.shared.dto.orgunit.OrgUnitDTO; import org.sigmah.shared.dto.referential.TextAreaType; import org.sigmah.shared.dto.value.ListableValue; import org.sigmah.shared.dto.value.TripletValueDTO; import org.sigmah.shared.util.ValueResultUtils; public class ContactsSynthesisUtils { public static class ContactSheetData { private final String title; private final List<ExportDataCell> headers = new ArrayList<>(); private final List<List<ExportDataCell>> lines = new ArrayList<>(); public ContactSheetData(String title) { this.title = title; } public void addHeader(ExportDataCell header) { headers.add(header); } public void addHeaders(List<ExportDataCell> headers) { this.headers.addAll(headers); } public void addLine(List<ExportDataCell> line) { lines.add(line); } public List<ExportDataCell> getHeaders() { return headers; } public List<List<ExportDataCell>> getLines() { return lines; } public String getTitle() { return title; } } public static List<ContactSheetData> createProjectContactListData(final Integer projectId, final Exporter exporter, final I18nServer i18nTranslator, final Language language) throws Throwable { final List<ContactSheetData> sheets = new ArrayList<>(); final ProjectDTO project = exporter.execute(new GetProject(projectId, null)); for (LayoutGroupDTO group : project.getProjectModel().getProjectDetails().getLayout().getGroups()) { for (LayoutConstraintDTO constraint : group.getConstraints()) { if (constraint.getFlexibleElementDTO() instanceof ContactListElementDTO) { sheets.add(createContactListTab(projectId, group, (ContactListElementDTO)constraint.getFlexibleElementDTO(), exporter, i18nTranslator, language)); } } } 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 { if (layoutGroup.getHasIterations()) { return createContactListTabWithIterations(projectId, layoutGroup, contactListElement, exporter, i18nTranslator, language); } else { return createContactListSimpleTab(projectId, layoutGroup, contactListElement, exporter, i18nTranslator, language); } } public static ContactSheetData createContactListTabWithIterations(final Integer projectId, final LayoutGroupDTO layoutGroup, final ContactListElementDTO contactListElement, final Exporter exporter, final I18nServer i18nTranslator, final Language language) throws Throwable { ContactSheetData result = new ContactSheetData(contactListElement.getLabel()); ListResult<LayoutGroupIterationDTO> iterations = exporter.execute(new GetLayoutGroupIterations(layoutGroup.getId(), projectId, -1)); boolean isFirst = true; List<ExportDataCell> iterationHeaders = new ArrayList<>(); iterationHeaders.add(new ExportStringCell(i18nTranslator.t(language, "iterationName"))); for (LayoutGroupIterationDTO iteration : iterations.getList()) { List<ExportDataCell> iterationValues = new ArrayList<>(); List<ContactDTO> contacts = null; iterationValues.add(new ExportStringCell(iteration.getName())); for (LayoutConstraintDTO constraint : layoutGroup.getConstraints()) { FlexibleElementDTO element = constraint.getFlexibleElementDTO(); try { ValueResult iterationValueResult = exporter.execute(new GetValue(projectId, element.getId(), element.getEntityName(), null, iteration.getId())); if (element == contactListElement) { Set<Integer> contactIds = new HashSet(ValueResultUtils.splitValuesAsInteger(iterationValueResult.getValueObject())); if (!contactIds.isEmpty()) { contacts = exporter.execute(new GetContacts(contactIds)).getList(); } } else { if (isFirst) { iterationHeaders.add(new ExportStringCell(ExporterUtil.getFlexibleElementLabel(element, i18nTranslator, language))); } iterationValues.add(valueResultToDataCell(element, iterationValueResult, i18nTranslator, language)); } } catch(Exception e) { // no value found in database : empty cells iterationValues.add(new ExportStringCell("")); } } if (contacts == null || contacts.isEmpty()) { continue; } for (ContactDTO contact : contacts) { List<ExportDataCell> line = new ArrayList<>(); for (LayoutGroupDTO group : contact.getContactModel().getDetails().getLayout().getGroups()) { if (group.getHasIterations()) { // no default element in iterative groups continue; } for(LayoutConstraintDTO constraint : group.getConstraints()) { FlexibleElementDTO element = constraint.getFlexibleElementDTO(); if (constraint.getFlexibleElementDTO() instanceof DefaultContactFlexibleElementDTO) { if (isFirst) { result.addHeader(new ExportStringCell(ExporterUtil.getFlexibleElementLabel(element, i18nTranslator, language))); } try { line.add(defaultValueToDataCell(element, contact)); } catch(Exception e) { // no value found in database : empty cells line.add(new ExportStringCell("")); } } } } line.addAll(iterationValues); result.addLine(line); isFirst = false; } } result.addHeaders(iterationHeaders); return result; } public static ContactSheetData createContactListSimpleTab(final Integer projectId, final LayoutGroupDTO layoutGroup, final ContactListElementDTO contactListElement, final Exporter exporter, final I18nServer i18nTranslator, final Language language) throws Throwable { ContactSheetData result = new ContactSheetData(contactListElement.getLabel()); boolean isFirst = true; List<ExportDataCell> iterationHeaders = new ArrayList<>(); List<ExportDataCell> values = new ArrayList<>(); List<ContactDTO> contacts = null; for (LayoutConstraintDTO constraint : layoutGroup.getConstraints()) { FlexibleElementDTO element = constraint.getFlexibleElementDTO(); ValueResult valueResult = exporter.execute(new GetValue(projectId, element.getId(), "element." + element.getClass().getSimpleName(), -1, null)); if (element == contactListElement) { Set<Integer> 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)); } } if (contacts == null || contacts.isEmpty()) { return result; } for (ContactDTO contact : contacts) { List<ExportDataCell> line = new ArrayList<>(); for (LayoutGroupDTO group : contact.getContactModel().getDetails().getLayout().getGroups()) { if (group.getHasIterations()) { // no default element in iterative groups continue; } for(LayoutConstraintDTO constraint : group.getConstraints()) { FlexibleElementDTO element = constraint.getFlexibleElementDTO(); if (constraint.getFlexibleElementDTO() instanceof DefaultContactFlexibleElementDTO) { if (isFirst) { result.addHeader(new ExportStringCell(ExporterUtil.getFlexibleElementLabel(element, i18nTranslator, language))); } line.add(defaultValueToDataCell(element, contact)); } } } line.addAll(values); result.addLine(line); isFirst = false; } result.addHeaders(iterationHeaders); return result; } public static ContactSheetData createAllRelationsData(final Integer contactId, final Exporter exporter, final I18nServer i18nTranslator, final Language language) throws Throwable { final ListResult<ContactRelationship> contacts = exporter.execute(new GetContactRelationships(contactId)); if (contacts == null || contacts.isEmpty()) { return null; } final ContactSheetData sheet = new ContactSheetData(i18nTranslator.t(language, "relationships")); sheet.addHeader(new ExportStringCell(i18nTranslator.t(language, "contactRelationshipElementLabel"))); sheet.addHeader(new ExportStringCell(i18nTranslator.t(language, "contactRelationshipGroupTitle"))); sheet.addHeader(new ExportStringCell(i18nTranslator.t(language, "contactRelationshipType"))); sheet.addHeader(new ExportStringCell(i18nTranslator.t(language, "contactRelationshipName"))); sheet.addHeader(new ExportStringCell(i18nTranslator.t(language, "contactRelationshipMember"))); for (ContactRelationship relationship : contacts.getList()) { List<ExportDataCell> line = new ArrayList<>(); line.add(new ExportStringCell(relationship.getFieldName())); line.add(new ExportStringCell(relationship.getGroupName())); line.add(new ExportStringCell(relationship.getFormattedType())); line.add(new ExportStringCell(relationship.getName())); String isMember = relationship.getDirection() == ContactRelationship.Direction.INBOUND ? i18nTranslator.t(language, "yes"):i18nTranslator.t(language, "no"); line.add(new ExportStringCell(isMember)); sheet.addLine(line); } return sheet; } public static List<ContactSheetData> createFrameworkRelationsData(final Integer contactId, final Exporter exporter, final I18nServer i18nTranslator, final Language language) throws Throwable { // TODO : export relationships linked to available frameworks return null; } public static List<ContactSheetData> createRelationsByElementData(final Integer contactId, final Exporter exporter, final I18nServer i18nTranslator, final Language language) throws Throwable { final ListResult<ContactRelationship> contacts = exporter.execute(new GetContactRelationships(contactId)); if (contacts == null || contacts.isEmpty()) { return null; } List<ContactSheetData> sheets = new ArrayList<>(); Map<String, List<ContactRelationship>> relationshipsByElement = new HashMap<>(); for (ContactRelationship relationship : contacts.getList()) { String sheetName = (relationship.getFieldName() + "_" + relationship.getGroupName()).toLowerCase(); List<ContactRelationship> relationships = relationshipsByElement.get(sheetName); if (relationships == null) { relationships = new ArrayList<>(); relationshipsByElement.put(sheetName, relationships); } relationships.add(relationship); } for (String element : relationshipsByElement.keySet()) { final ContactSheetData sheet = new ContactSheetData(element); sheet.addHeader(new ExportStringCell(i18nTranslator.t(language, "contactRelationshipGroupTitle"))); sheet.addHeader(new ExportStringCell(i18nTranslator.t(language, "contactRelationshipType"))); sheet.addHeader(new ExportStringCell(i18nTranslator.t(language, "contactRelationshipName"))); sheet.addHeader(new ExportStringCell(i18nTranslator.t(language, "contactRelationshipMember"))); for (ContactRelationship relationship : relationshipsByElement.get(element)) { List<ExportDataCell> line = new ArrayList<>(); line.add(new ExportStringCell(relationship.getGroupName())); line.add(new ExportStringCell(relationship.getFormattedType())); line.add(new ExportStringCell(relationship.getName())); String isMember = relationship.getDirection() == ContactRelationship.Direction.INBOUND ? i18nTranslator.t(language, "yes"):i18nTranslator.t(language, "no"); line.add(new ExportStringCell(isMember)); sheet.addLine(line); } sheets.add(sheet); } return sheets; } private static ExportDataCell valueResultToDataCell(final FlexibleElementDTO element, final ValueResult valueResult, final I18nServer i18nTranslator, final Language language) { ExportDataCell val = null; String elementName = element.getEntityName(); /* CHECKBOX */ if (elementName.equals("element.CheckboxElement")) { val = new ExportStringCell(getCheckboxElementValue(valueResult, element, i18nTranslator, language)); } else /* TEXT AREA */if (elementName.equals("element.TextAreaElement")) { val = new ExportStringCell(getTextAreaElementValue(valueResult, element)); } else /* TRIPLET */if (elementName.equals("element.TripletsListElement")) { val = new ExportStringCell(getTripletValue(valueResult)); } 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()); } return val; } private static ExportDataCell defaultValueToDataCell(final FlexibleElementDTO element, final ContactDTO contact) { return new ExportStringCell(getDefElementValue(element, contact)); } public static String getDefElementValue(final FlexibleElementDTO element, final ContactDTO contact) { Object value = null; final DefaultContactFlexibleElementDTO defaultElement = (DefaultContactFlexibleElementDTO) element; switch (defaultElement.getType()) { case FAMILY_NAME: { value = contact.getName(); } break; case FIRST_NAME: { value = contact.getFirstname(); } break; case ORGANIZATION_NAME: { value = contact.getOrganizationName(); } break; case MAIN_ORG_UNIT: { OrgUnitDTO orgUnit = contact.getMainOrgUnit(); if (orgUnit != null) { value = orgUnit.getName() + " - " + orgUnit.getFullName(); } } break; case SECONDARY_ORG_UNITS: { List<OrgUnitDTO> orgUnits; orgUnits = contact.getSecondaryOrgUnits(); String val = ""; if (orgUnits != null) { for (OrgUnitDTO unit : orgUnits) { val += unit.getName() + " - " + unit.getFullName() + "\n"; } } if (!val.isEmpty()) { value = val.substring(0, val.length() - 1); } } break; case CREATION_DATE: { value = contact.getDateCreated(); } break; case LOGIN: { value = contact.getLogin(); } break; case EMAIL_ADDRESS: { value = contact.getEmail(); } break; case PHONE_NUMBER: { value = contact.getPhoneNumber(); } break; case POSTAL_ADDRESS: { value = contact.getPostalAddress(); } break; case PHOTO: { value = contact.getPhoto(); } break; case COUNTRY: { value = contact.getCountry() != null ? contact.getCountry().getName() : null; } break; case DIRECT_MEMBERSHIP: { ContactDTO orgUnit = contact.getParent(); if (orgUnit != null) { value = orgUnit.getFullName(); } } break; case TOP_MEMBERSHIP: { ContactDTO orgUnit = contact.getRoot(); if (orgUnit != null) { value = orgUnit.getFullName(); } } break; default: break; } String result; if (value == null) { result = null; } else if (value instanceof String) { result = (String) value; } else if (value instanceof Double) { Double d = (Double) value; result = LogFrameExportData.AGGR_AVG_FORMATTER.format(d.doubleValue()); } else if (value instanceof Long) { Long l = (Long) value; result = LogFrameExportData.AGGR_SUM_FORMATTER.format(l.longValue()); } else { // date result = ExportConstants.EXPORT_DATE_FORMAT.format((Date) value); } return result; } private static String getCheckboxElementValue(final ValueResult valueResult, final FlexibleElementDTO element, final I18nServer i18nTranslator, final Language language) { String value = i18nTranslator.t(language, "no"); if (valueResult != null && valueResult.getValueObject() != null) { if (valueResult.getValueObject().equalsIgnoreCase("true")) value = i18nTranslator.t(language, "yes"); } return value; } private static String getTextAreaElementValue(final ValueResult valueResult, final FlexibleElementDTO element) { String value = null; final TextAreaElementDTO textAreaElement = (TextAreaElementDTO) element; if (valueResult != null && valueResult.isValueDefined()) { String strValue = valueResult.getValueObject(); final TextAreaType type = TextAreaType.fromCode(textAreaElement.getType()); if (type != null) { switch (type) { case NUMBER: if (textAreaElement.getIsDecimal()) { value = LogFrameExportData.AGGR_AVG_FORMATTER.format(Double.parseDouble(strValue)); } else { value = LogFrameExportData.AGGR_SUM_FORMATTER.format(Long.parseLong(strValue)); } break; case DATE: value = ExportConstants.EXPORT_DATE_FORMAT.format((Date) new Date(Long.parseLong(strValue))); break; default: value = strValue; break; } } else { value = strValue; } } return value; } private static String getTripletValue(final ValueResult valueResult) { String value = ""; if (valueResult != null && valueResult.isValueDefined()) { value = formatTripletValues(valueResult.getValuesObject()); } return value; } private static String formatTripletValues(List<ListableValue> list) { int lines = list.size() + 1; final StringBuilder builder = new StringBuilder(); for (ListableValue s : list) { final TripletValueDTO tripletValue = (TripletValueDTO) s; builder.append(" - "); builder.append(tripletValue.getCode()); builder.append(" - "); builder.append(tripletValue.getName()); builder.append(" : "); builder.append(tripletValue.getPeriod()); builder.append("\n"); } String value = null; if (lines > 1) { value = builder.substring(0, builder.length() - 1); } return value; } private static String getChoiceValue(final ValueResult valueResult, final QuestionElementDTO element) { String valueLabels = ""; if (valueResult != null && valueResult.isValueDefined()) { if (element.getMultiple()) { final ExportConstants.MultiItemText item = formatMultipleChoices(element.getChoices(), valueResult.getValueObject()); valueLabels = item.text; final List<Integer> selectedChoicesIds = new ArrayList<>(); for (Integer id : ValueResultUtils.splitValuesAsInteger(valueResult.getValueObject())) { for (QuestionChoiceElementDTO choice : element.getChoices()) { if (id.equals(choice.getId())) { if (choice.getCategoryElement() != null) { id = choice.getCategoryElement().getId(); } break; } } selectedChoicesIds.add(id); } } else { final String idChoice = valueResult.getValueObject(); for (QuestionChoiceElementDTO choice : element.getChoices()) { if (idChoice.equals(String.valueOf(choice.getId()))) { if (choice.getCategoryElement() != null) { valueLabels = choice.getCategoryElement().getLabel(); } else { valueLabels = choice.getLabel(); } break; } } } } return valueLabels; } public static ExportConstants.MultiItemText formatMultipleChoices(List<QuestionChoiceElementDTO> list, String values) { final List<Integer> selectedChoicesId = ValueResultUtils.splitValuesAsInteger(values); final StringBuffer builder = new StringBuffer(); int lines = 1; for (final QuestionChoiceElementDTO choice : list) { for (final Integer id : selectedChoicesId) { if (id.equals(choice.getId())) { builder.append(" - "); if (choice.getCategoryElement() != null) { builder.append(choice.getCategoryElement().getLabel()); } else { builder.append(choice.getLabel()); } builder.append("\n"); lines++; } } } String value = null; if (lines > 1) { value = builder.substring(0, builder.length() - 1); lines--; } return new ExportConstants.MultiItemText(value, lines); } }