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.List; import java.util.Map; import java.util.Set; import javax.persistence.EntityManager; import javax.persistence.NoResultException; import javax.persistence.TypedQuery; import org.sigmah.client.util.NumberUtils; import org.sigmah.server.dispatch.CommandHandler; import org.sigmah.server.domain.Contact; import org.sigmah.server.domain.Country; import org.sigmah.server.domain.OrgUnit; import org.sigmah.server.domain.Project; import org.sigmah.server.domain.User; import org.sigmah.server.domain.base.EntityId; import org.sigmah.server.domain.category.CategoryType; import org.sigmah.server.domain.element.BudgetElement; import org.sigmah.server.domain.element.BudgetRatioElement; import org.sigmah.server.domain.element.ContactListElement; import org.sigmah.server.domain.element.DefaultContactFlexibleElement; import org.sigmah.server.domain.element.DefaultFlexibleElement; import org.sigmah.server.domain.element.FlexibleElement; import org.sigmah.server.domain.element.QuestionChoiceElement; import org.sigmah.server.domain.element.QuestionElement; import org.sigmah.server.domain.element.TextAreaElement; import org.sigmah.server.domain.layout.Layout; 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.data.BaseSynthesisData; import org.sigmah.server.servlet.exporter.data.ExportData; 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.server.servlet.exporter.data.columns.GlobalExportDataColumn; 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.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.dto.element.BudgetElementDTO; import org.sigmah.shared.dto.element.BudgetRatioElementDTO; import org.sigmah.shared.dto.element.CheckboxElementDTO; import org.sigmah.shared.dto.element.ContactListElementDTO; import org.sigmah.shared.dto.element.DefaultContactFlexibleElementDTO; import org.sigmah.shared.dto.element.DefaultFlexibleElementDTO; import org.sigmah.shared.dto.element.FlexibleElementDTO; import org.sigmah.shared.dto.element.MessageElementDTO; import org.sigmah.shared.dto.element.QuestionElementDTO; import org.sigmah.shared.dto.element.TextAreaElementDTO; import org.sigmah.shared.dto.element.TripletsListElementDTO; import org.sigmah.shared.dto.layout.LayoutGroupIterationDTO; import org.sigmah.shared.dto.referential.DefaultContactFlexibleElementType; import org.sigmah.shared.dto.referential.DefaultFlexibleElementType; 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; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Utility class for exporters. * * @author sherzod * @author Raphaƫl Calabro (raphael.calabro@netapsys.fr) */ public final class ExporterUtil { /** * Logger. */ private static final Logger LOGGER = LoggerFactory.getLogger(ExporterUtil.class); // ------------------------------------------------------------------------- // LABELS // ------------------------------------------------------------------------- /** * Gets the label of the flexible element. * * @param fleDTO * @param i18nTranslator * @param language * @return The flexible element i18n label. */ public static String getFlexibleElementLabel(FlexibleElementDTO fleDTO, I18nServer i18nTranslator, final Language language) { String fleName = null; if (fleDTO.getLabel() != null) { fleName = fleDTO.getLabel(); } else if (fleDTO instanceof DefaultFlexibleElementDTO) { fleName = getFlexibleElementLabel(((DefaultFlexibleElementDTO) fleDTO).getType(), i18nTranslator, language); } else if (fleDTO instanceof DefaultContactFlexibleElementDTO) { fleName = getDefaultContactFlexibleElementLabel(((DefaultContactFlexibleElementDTO) fleDTO).getType(), i18nTranslator, language); } return fleName; } /** * Gets the label of the flexible element. * * @param fle * @param i18nTranslator * @param language * @return The flexible element i18n label. */ public static String getFlexibleElementLabel(FlexibleElement fle, I18nServer i18nTranslator, final Language language) { String fleName = null; if (fle.getLabel() != null) { fleName = fle.getLabel(); } else if (fle instanceof DefaultFlexibleElement) { fleName = getFlexibleElementLabel(((DefaultFlexibleElement) fle).getType(), i18nTranslator, language); } else if (fle instanceof DefaultContactFlexibleElement) { fleName = getDefaultContactFlexibleElementLabel(((DefaultContactFlexibleElement) fle).getType(), i18nTranslator, language); } return fleName; } /** * Gets the label of the default flexible element type * * @param type * @param i18nTranslator * @param language * @return The default flexible element i18n label. */ public static String getFlexibleElementLabel(DefaultFlexibleElementType type, I18nServer i18nTranslator, final Language language) { String fleName = null; switch (type) { case BUDGET: fleName = i18nTranslator.t(language, "projectBudget"); break; case CODE: fleName = i18nTranslator.t(language, "projectName"); break; case COUNTRY: fleName = i18nTranslator.t(language, "projectCountry"); break; case END_DATE: fleName = i18nTranslator.t(language, "projectEndDate"); break; case MANAGER: fleName = i18nTranslator.t(language, "projectManager"); break; case ORG_UNIT: fleName = i18nTranslator.t(language, "orgunit"); break; case OWNER: fleName = i18nTranslator.t(language, "projectOwner"); break; case START_DATE: fleName = i18nTranslator.t(language, "projectStartDate"); break; case TITLE: fleName = i18nTranslator.t(language, "projectFullName"); break; default: break; } return fleName; } /** * Gets the label of the default contact flexible element type * * @param type * @param i18nTranslator * @param language * @return The default contact flexible element i18n label. */ public static String getDefaultContactFlexibleElementLabel(DefaultContactFlexibleElementType type, I18nServer i18nTranslator, final Language language) { String fleName = null; switch (type) { case FAMILY_NAME: fleName = i18nTranslator.t(language, "contactFamilyName"); break; case FIRST_NAME: fleName = i18nTranslator.t(language, "contactFirstName"); break; case ORGANIZATION_NAME: fleName = i18nTranslator.t(language, "contactOrganizationName"); break; case MAIN_ORG_UNIT: fleName = i18nTranslator.t(language, "contactMainOrgUnit"); break; case SECONDARY_ORG_UNITS: fleName = i18nTranslator.t(language, "contactSecondaryOrgUnits"); break; case CREATION_DATE: fleName = i18nTranslator.t(language, "contactCreationDate"); break; case LOGIN: fleName = i18nTranslator.t(language, "contactLogin"); break; case EMAIL_ADDRESS: fleName = i18nTranslator.t(language, "contactEmailAddress"); break; case PHONE_NUMBER: fleName = i18nTranslator.t(language, "contactPhoneNumber"); break; case POSTAL_ADDRESS: fleName = i18nTranslator.t(language, "contactPostalAddress"); break; case PHOTO: fleName = i18nTranslator.t(language, "contactPhoto"); break; case COUNTRY: fleName = i18nTranslator.t(language, "contactCountry"); break; case DIRECT_MEMBERSHIP: fleName = i18nTranslator.t(language, "contactDirectMembership"); break; case TOP_MEMBERSHIP: fleName = i18nTranslator.t(language, "contactTopMembership"); break; default: break; } return fleName; } // ------------------------------------------------------------------------- // FORMATS // ------------------------------------------------------------------------- public static ExportConstants.MultiItemText formatMultipleChoices(List<QuestionChoiceElement> list, String values) { final List<Integer> selectedChoicesId = ValueResultUtils.splitValuesAsInteger(values); final StringBuffer builder = new StringBuffer(); int lines = 1; for (final QuestionChoiceElement 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); } public static ExportConstants.MultiItemText 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() - 2); lines--; } return new ExportConstants.MultiItemText(value, lines); } /** * Removes tags from the given html string. * * @param html * HTML string to clear of its formatting. * @return The text value contained in the given html string. */ public static String clearHtmlFormatting(final String html) { String text = html; if (text != null && text.length() > 0) { text = text.replaceAll("<br>", " "); text = text.replaceAll("<[^>]+>|\\n", ""); text = text.trim().replaceAll(" +", " "); } return text; } // ------------------------------------------------------------------------- // TITLES & VALUES // ------------------------------------------------------------------------- public static void addBudgetTitles(final List<ExportDataCell> titles, final FlexibleElement element, final I18nServer i18nTranslator, final Language language) { String budgetLabel = ExporterUtil.getFlexibleElementLabel(element, i18nTranslator, language); titles.add(new ExportStringCell(budgetLabel + " " + i18nTranslator.t(language, "spentBudget"))); titles.add(new ExportStringCell(budgetLabel + " " + i18nTranslator.t(language, "plannedBudget"))); titles.add(new ExportStringCell(budgetLabel + " " + i18nTranslator.t(language, "consumptionRatioBudget"))); } public static void addBudgetValues(final List<ExportDataCell> values, final ValueResult valueResult, final FlexibleElement element, final I18nServer i18nTranslator, final Language language) { BudgetElement budgetElement = (BudgetElement) element; BudgetValues budget = new BudgetValues(budgetElement, valueResult); values.add(new ExportStringCell(String.valueOf(budget.getSpent()))); values.add(new ExportStringCell(String.valueOf(budget.getPlanned()))); values.add(new ExportStringCell(String.valueOf(budget.getRatio()))); } public static void addChoiceTitles(final List<ExportDataCell> titles, final Set<CategoryType> categories, final FlexibleElement element, final I18nServer i18nTranslator, final Language language) { final QuestionElement questionElement = (QuestionElement) element; String choiceLabel = ExporterUtil.getFlexibleElementLabel(element, i18nTranslator, language); titles.add(new ExportStringCell(choiceLabel)); if (questionElement.getCategoryType() != null) { titles.add(new ExportStringCell(choiceLabel + " (" + questionElement.getCategoryType().getLabel() + ") " + i18nTranslator.t(language, "categoryId"))); categories.add(((QuestionElement) element).getCategoryType()); } } public static void addChoiceValues(final List<ExportDataCell> values, final ValueResult valueResult, final FlexibleElement element) { ChoiceValue choiceValue = new ChoiceValue((QuestionElement) element, valueResult); values.add(new ExportStringCell(choiceValue.getValueLabels())); if (((QuestionElement)element).getCategoryType() != null) { values.add(new ExportStringCell(choiceValue.getValueIds())); } } /** * Add the columns titles for a {@link ContactListElement}. * * @param titles * List of cells. * @param element * Contact list element. * @param i18nTranslator * Translator. * @param language * Language of the user. */ public static void addContactListTitles(final List<ExportDataCell> titles, final FlexibleElement element, final I18nServer i18nTranslator, final Language language) { titles.add(new ExportStringCell(element.getLabel())); titles.add(new ExportStringCell(element.getLabel() + " [" + i18nTranslator.t(language, "contactListExportIds") + ']')); } /** * Add the values for a {@link ContactListElement}. * * @param values * Values to add. * @param element * Contact list element. * @param valueResult * Value in the database. * @param entityManager * Entity manager to query the database. */ public static void addContactListValues(final List<ExportDataCell> values, final FlexibleElement element, final ValueResult valueResult, final EntityManager entityManager) { final StringBuilder namesBuilder = new StringBuilder(); final StringBuilder idsBuilder = new StringBuilder(); if (valueResult != null && valueResult.isValueDefined()) { // Retrieving list values from database. final TypedQuery<Contact> query = entityManager.createQuery("SELECT c FROM Contact c WHERE c.id IN (:idList)", Contact.class); query.setParameter("idList", ValueResultUtils.splitValuesAsInteger(valueResult.getValueObject())); final List<Contact> contacts = query.getResultList(); for (final Contact contact : contacts) { namesBuilder.append(" - ") .append(contact.getFullName()) .append("\n"); idsBuilder.append(contact.getId()).append(','); } if (namesBuilder.length() > 0) { namesBuilder.setLength(namesBuilder.length() - 1); idsBuilder.setLength(idsBuilder.length() - 1); } } values.add(new ExportStringCell(namesBuilder.toString())); values.add(new ExportStringCell(idsBuilder.toString())); } // ------------------------------------------------------------------------- // VALUE RESULTS // ------------------------------------------------------------------------- public static ValueResult getValueResult(final FlexibleElement element, final EntityId<Integer> container, final CommandHandler<GetValue, ValueResult> handler) { return getValueResult(element, null, container, handler); } public static ValueResult getValueResult(final FlexibleElement element, final Integer iterationId, final EntityId<Integer> container, final CommandHandler<GetValue, ValueResult> handler) { final String elementName = "element." + element.getClass().getSimpleName(); final GetValue command = new GetValue(container.getId(), element.getId(), elementName, null, iterationId); try { return handler.execute(command, null); } catch (CommandException e) { LOGGER.error("Failed to get the value of element '" + element.getId() + "' of container '" + container.getId() + "'.", e); return null; } } // ------------------------------------------------------------------------- // PAIRS // ------------------------------------------------------------------------- /** * Returns the label/value pair for the given element. * * @param element * Flexible element. * @param container * Container of the flexible element (can be a <code>Project</code> or an <code>OrgUnit</code>). * @param em * Instance of the entity manager. * @param handler * Handler of the <code>GetValue</code> command. * @param i18nTranslator * Translator for localized strings. * @param language * Language of the export. * @param data * Export data. * @return The label/value pair for the given element. */ public static ValueLabel getPair(final FlexibleElement element, final EntityId<Integer> container, final EntityManager em, final CommandHandler<GetValue, ValueResult> handler, final I18nServer i18nTranslator, final Language language, final ExportData data) { final String elementName = "element." + element.getClass().getSimpleName(); final GetValue command = new GetValue(container.getId(), element.getId(), elementName, null); final ValueResult valueResult; try { valueResult = handler.execute(command, null); } catch (CommandException e) { LOGGER.error("Failed to get the value of element '" + element.getId() + "' of container '" + container.getId() + "'.", e); return null; } return getPair(valueResult, element, container, em, i18nTranslator, language, data); } /** * Returns the label/value pair for the given element. * * @param valueResult * Value of the given flexible element. * @param element * Flexible element. * @param container * Container of the flexible element (can be a <code>Project</code> or an <code>OrgUnit</code>). * @param em * Instance of the entity manager. * @param i18nTranslator * Translator for localized strings. * @param language * Language of the export. * @param data * Export data. * @return The label/value pair for the given element. */ public static ValueLabel getPair(final ValueResult valueResult, final FlexibleElement element, final EntityId<Integer> container, final EntityManager em, final I18nServer i18nTranslator, final Language language, final ExportData data) { final String elementName = "element." + element.getClass().getSimpleName(); final ValueLabel pair; /* DEF FLEXIBLE & BUDGET ELEMENT */ if (elementName.equals(DefaultFlexibleElementDTO.ENTITY_NAME) || elementName.equals(BudgetElementDTO.ENTITY_NAME)) { if (container instanceof Project) { pair = getDefElementPair(valueResult, element, (Project)container, em, i18nTranslator, language); } else if (container instanceof OrgUnit) { pair = getDefElementPair(valueResult, element, (OrgUnit)container, em, i18nTranslator, language); } else { throw new UnsupportedOperationException("Container of DefaultFlexibleElement should be either Project or OrgUnit, received: " + container.getClass()); } } /* CONTACT DEF FLEXIBLE */ else if (elementName.equals(DefaultContactFlexibleElementDTO.ENTITY_NAME)) { pair = ExporterUtil.getDefElementPair(valueResult, element, (Contact)container, em, i18nTranslator, language); } /* BUDGET RATIO */ else if (elementName.equals(BudgetRatioElementDTO.ENTITY_NAME)) { pair = getBudgetRatioElementPair(element, container.getId(), em); } /* CHECKBOX */ else if (elementName.equals(CheckboxElementDTO.ENTITY_NAME)) { pair = getCheckboxElementPair(valueResult, element, i18nTranslator, language); } /* TEXT AREA */ else if (elementName.equals(TextAreaElementDTO.ENTITY_NAME)) { pair = getTextAreaElementPair(valueResult, element); } /* TRIPLET */ else if (elementName.equals(TripletsListElementDTO.ENTITY_NAME)) { pair = getTripletPair(element, valueResult); } /* CHOICE */ else if (elementName.equals(QuestionElementDTO.ENTITY_NAME)) { pair = getChoicePair(element, valueResult); } /* CONTACT LIST */ else if (elementName.equals(ContactListElementDTO.ENTITY_NAME)) { pair = ExporterUtil.getContactListPair(element, valueResult, em); } /* MESSAGE */ else if (elementName.equals(MessageElementDTO.ENTITY_NAME)) { pair = new ValueLabel(data.getLocalizedVersion("flexibleElementMessage"), clearHtmlFormatting(element.getLabel())); pair.setMessage(true); } else { pair = null; } return pair; } public static ValueLabel getTripletPair(final FlexibleElement element, final ValueResult valueResult) { String value = null; int lines = 1; if (valueResult != null && valueResult.isValueDefined()) { final ExportConstants.MultiItemText item = formatTripletValues(valueResult.getValuesObject()); value = item.text; lines = item.lineCount; } return new ValueLabel(element.getLabel(), value, lines); } @Deprecated public static ValueLabel getContactListPair(final FlexibleElement element, final ValueResult valueResult, final EntityManager entityManager) { String value = null; int lines = 1; if (valueResult != null && valueResult.isValueDefined()) { // Retrieving list values from database. final TypedQuery<Contact> query = entityManager.createQuery("SELECT c FROM Contact c WHERE c.id IN (:idList)", Contact.class); query.setParameter("idList", ValueResultUtils.splitValuesAsInteger(valueResult.getValueObject())); final List<Contact> contacts = query.getResultList(); final StringBuilder builder = new StringBuilder(); for (final Contact contact : contacts) { builder.append(" - ") .append(contact.getFullName()) .append("\n"); lines++; } if (lines > 1) { value = builder.substring(0, builder.length() - 1); lines--; } } return new ValueLabel(element.getLabel(), value, lines); } public static ValueLabel getChoicePair(final FlexibleElement element, final ValueResult valueResult) { String value = null; int lines = 1; if (valueResult != null && valueResult.isValueDefined()) { final QuestionElement questionElement = (QuestionElement) element; final Boolean multiple = questionElement.getMultiple(); if (multiple != null && multiple) { final ExportConstants.MultiItemText item = formatMultipleChoices(questionElement.getChoices(), valueResult.getValueObject()); value = item.text; lines = item.lineCount; } else { final String idChoice = valueResult.getValueObject(); for (final QuestionChoiceElement choice : questionElement.getChoices()) { if (idChoice.equals(String.valueOf(choice.getId()))) { if (choice.getCategoryElement() != null) { value = choice.getCategoryElement().getLabel(); } else { value = choice.getLabel(); } break; } } } } return new ValueLabel(element.getLabel(), value, lines); } public static ValueLabel getTextAreaElementPair(final ValueResult valueResult, final FlexibleElement element) { Object value = null; final TextAreaElement textAreaElement = (TextAreaElement) 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 = Double.parseDouble(strValue); } else { value = (long) Double.parseDouble(strValue); } break; case DATE: value = new Date(Long.parseLong(strValue)); break; default: value = strValue; break; } } else { value = strValue; } } return new ValueLabel(element.getLabel(), value); } public static ValueLabel getCheckboxElementPair(final ValueResult valueResult, final FlexibleElement 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 new ValueLabel(element.getLabel(), value); } public static ValueLabel getDefElementPair(final ValueResult valueResult, final FlexibleElement element, final Object object, final Class<?> clazz, final EntityManager entityManager, final I18nServer i18nTranslator, final Language language) { if (clazz.equals(Project.class)) { return getDefElementPair(valueResult, element, (Project) object, entityManager, i18nTranslator, language); } else if (clazz.equals(OrgUnit.class)) { return getDefElementPair(valueResult, element, (OrgUnit) object, entityManager, i18nTranslator, language); } else if (clazz.equals(Contact.class)) { return getDefElementPair(valueResult, element, (Contact) object, entityManager, i18nTranslator, language); } else { throw new UnsupportedOperationException("Unsupported container type: " + clazz); } } public static ValueLabel getDefElementPair(final ValueResult valueResult, final FlexibleElement element, final Project project, final EntityManager entityManager, final I18nServer i18nTranslator, final Language language) { Object value = null; String label = ExporterUtil.getFlexibleElementLabel(element, i18nTranslator, language); final DefaultFlexibleElement defaultElement = (DefaultFlexibleElement) element; boolean hasValue = valueResult != null && valueResult.isValueDefined(); switch (defaultElement.getType()) { case CODE: { if (hasValue) { value = valueResult.getValueObject(); } else { value = project.getName(); } } break; case TITLE: { if (hasValue) { value = valueResult.getValueObject(); } else { value = project.getFullName(); } } break; case START_DATE: { if (hasValue) { value = new Date(Long.parseLong(valueResult.getValueObject())); } else { value = project.getStartDate(); } } break; case END_DATE: { if (hasValue) { value = new Date(Long.parseLong(valueResult.getValueObject())); } else { value = ""; if (project.getEndDate() != null) value = project.getEndDate(); } } break; case BUDGET: { BudgetElement budgetElement = (BudgetElement) element; // BUGFIX #732: Inverted plannedBudget and spentBudget. Double plannedBudget = 0d; Double spentBudget = 0d; if (hasValue) { final Map<Integer, String> values = ValueResultUtils.splitMapElements(valueResult.getValueObject()); if (budgetElement.getRatioDividend() != null) { if (values.get(budgetElement.getRatioDividend().getId()) != null) { spentBudget = Double.valueOf(values.get(budgetElement.getRatioDividend().getId())); } } if (budgetElement.getRatioDivisor() != null) { if (values.get(budgetElement.getRatioDivisor().getId()) != null) { plannedBudget = Double.valueOf(values.get(budgetElement.getRatioDivisor().getId())); } } } value = spentBudget + " / " + plannedBudget; } break; case COUNTRY: { if (hasValue) { int countryId = Integer.parseInt(valueResult.getValueObject()); value = entityManager.find(Country.class, countryId).getName(); } else { value = project.getCountry().getName(); } } break; case OWNER: { if (hasValue) { value = valueResult.getValueObject(); } else { value = getUserName(project.getOwner()); } } break; case MANAGER: { if (hasValue) { int userId = Integer.parseInt(valueResult.getValueObject()); value = getUserName(entityManager.find(User.class, userId)); } else { value = getUserName(project.getManager()); } } break; case ORG_UNIT: { int orgUnitId = -1; if (hasValue) { orgUnitId = Integer.parseInt(valueResult.getValueObject()); } else { orgUnitId = project.getOrgUnit().getId(); } OrgUnit orgUnit = entityManager.find(OrgUnit.class, orgUnitId); if (orgUnit != null) value = orgUnit.getName() + " - " + orgUnit.getFullName(); } break; } return new ValueLabel(label, value); } public static ValueLabel getDefElementPair(final ValueResult valueResult, final FlexibleElement element, final OrgUnit orgUnit, final EntityManager entityManager, final I18nServer i18nTranslator, final Language language) { Object value = null; String label = ExporterUtil.getFlexibleElementLabel(element, i18nTranslator, language); final DefaultFlexibleElement defaultElement = (DefaultFlexibleElement) element; boolean hasValue = valueResult != null && valueResult.isValueDefined(); switch (defaultElement.getType()) { case CODE: { if (hasValue) { value = valueResult.getValueObject(); } else { value = orgUnit.getName(); } } break; case TITLE: { if (hasValue) { value = valueResult.getValueObject(); } else { value = orgUnit.getFullName(); } } break; case COUNTRY: { if (hasValue) { int countryId = Integer.parseInt(valueResult.getValueObject()); value = entityManager.find(Country.class, countryId).getName(); } else { value = orgUnit.getOfficeLocationCountry() != null ? orgUnit.getOfficeLocationCountry().getName() : null; } } break; case MANAGER: { if (hasValue) { int userId = Integer.parseInt(valueResult.getValueObject()); value = getUserName(entityManager.find(User.class, userId)); } else { value = ""; } } break; case ORG_UNIT: { OrgUnit parentOrgUnit = orgUnit.getParentOrgUnit(); if (parentOrgUnit == null) parentOrgUnit = orgUnit; value = parentOrgUnit.getName() + " - " + parentOrgUnit.getFullName(); } break; default: break; } return new ValueLabel(label, value); } public static ValueLabel getDefElementPair(final ValueResult valueResult, final FlexibleElement element, final Contact contact, final EntityManager entityManager, final I18nServer i18nTranslator, final Language language) { Object value = null; String label = ExporterUtil.getFlexibleElementLabel(element, i18nTranslator, language); final DefaultContactFlexibleElement defaultElement = (DefaultContactFlexibleElement) element; boolean hasValue = valueResult != null && valueResult.isValueDefined(); switch (defaultElement.getType()) { case FAMILY_NAME: { if (hasValue) { value = valueResult.getValueObject(); } else { value = contact.getName(); } } break; case FIRST_NAME: { if (hasValue) { value = valueResult.getValueObject(); } else { value = contact.getFirstname(); } } break; case ORGANIZATION_NAME: { if (hasValue) { value = valueResult.getValueObject(); } else { value = contact.getName(); } } break; case MAIN_ORG_UNIT: { int orgUnitId = -1; if (hasValue) { orgUnitId = Integer.parseInt(valueResult.getValueObject()); } else { orgUnitId = contact.getMainOrgUnit().getId(); } OrgUnit orgUnit = entityManager.find(OrgUnit.class, orgUnitId); if (orgUnit != null) { value = orgUnit.getName() + " - " + orgUnit.getFullName(); } } break; case SECONDARY_ORG_UNITS: { List<OrgUnit> orgUnits = new ArrayList<>(); if (hasValue) { List<Integer> orgUnitsIds = ValueResultUtils.splitValuesAsInteger(valueResult.getValueObject()); for (Integer id : orgUnitsIds) { OrgUnit unit = entityManager.find(OrgUnit.class, id); if (unit != null) orgUnits.add(unit); } } else { orgUnits = contact.getSecondaryOrgUnits(); } String val = ""; for (OrgUnit unit : orgUnits) { val += unit.getName() + " - " + unit.getFullName() + "\n"; } if (!val.isEmpty()) { value = val.substring(0, val.length() - 1); } } break; case CREATION_DATE: { if (hasValue) { value = new Date(Long.parseLong(valueResult.getValueObject())); } else { value = contact.getDateCreated(); } } break; case LOGIN: { if (hasValue) { value = valueResult.getValueObject(); } else { value = contact.getLogin(); } } break; case EMAIL_ADDRESS: { if (hasValue) { value = valueResult.getValueObject(); } else { value = contact.getEmail(); } } break; case PHONE_NUMBER: { if (hasValue) { value = valueResult.getValueObject(); } else { value = contact.getPhoneNumber(); } } break; case POSTAL_ADDRESS: { if (hasValue) { value = valueResult.getValueObject(); } else { value = contact.getPostalAddress(); } } break; case PHOTO: { if (hasValue) { value = valueResult.getValueObject(); } else { value = contact.getPhoto(); } } break; case COUNTRY: { if (hasValue) { int countryId = Integer.parseInt(valueResult.getValueObject()); value = entityManager.find(Country.class, countryId).getName(); } else { value = contact.getCountry() != null ? contact.getCountry().getName() : null; } } break; case DIRECT_MEMBERSHIP: { int orgUnitId = -1; if (hasValue) { orgUnitId = Integer.parseInt(valueResult.getValueObject()); } else { if (contact.getParent() != null) { orgUnitId = contact.getParent().getId(); } } OrgUnit orgUnit = entityManager.find(OrgUnit.class, orgUnitId); if (orgUnit != null) { value = orgUnit.getName() + " - " + orgUnit.getFullName(); } } break; case TOP_MEMBERSHIP: { int orgUnitId = -1; if (hasValue) { orgUnitId = Integer.parseInt(valueResult.getValueObject()); } else { if (contact.getRoot() != null) { orgUnitId = contact.getRoot().getId(); } } OrgUnit orgUnit = entityManager.find(OrgUnit.class, orgUnitId); if (orgUnit != null) { value = orgUnit.getName() + " - " + orgUnit.getFullName(); } } break; default: break; } return new ValueLabel(label, value); } /** * Get the label/value pair of the given budget ratio element. * * @param element * Budget ratio element. * @param containerId * Identifier of the parent container. * @param em * Entity manager to use. * @return The <code>ValueLabel</code> containing the label of the element and its value. */ public static ValueLabel getBudgetRatioElementPair(final FlexibleElement element, final Integer containerId, final EntityManager em) { final BudgetRatioElement budgetRatioElement = (BudgetRatioElement) element; final TypedQuery<String> valueQuery = em.createQuery("SELECT v.value FROM Value v WHERE v.containerId = :containerId AND v.element = :element", String.class); valueQuery.setParameter("containerId", containerId); final ComputedValue spentBudget = getElementValue(budgetRatioElement.getSpentBudget(), valueQuery); final ComputedValue plannedBudget = getElementValue(budgetRatioElement.getPlannedBudget(), valueQuery); final Double value = plannedBudget.divide(spentBudget).get(); return new ValueLabel(budgetRatioElement.getLabel(), NumberUtils.truncateDouble(value)); } // ------------------------------------------------------------------------- // ITERATIONS // ------------------------------------------------------------------------- /** * Returns the list of cells to export for the given iteration. * * @param iteration * Current iteration. * @param constraints * Layout constraints of the given iteration. * @param container * Instance of the container. * @param em * Instance of the entity manager. * @param i18nTranslator * Translator of strings. * @param language * Language of the current user. * @param data * General export data. * @return A list of <code>ExportDataCell</code> for the given iteration (never <code>null</code>). */ public static List<ExportDataCell> getCellsForIteration(final LayoutGroupIterationDTO iteration, final List<LayoutConstraint> constraints, final EntityId<Integer> container, final EntityManager em, final I18nServer i18nTranslator, final Language language, final BaseSynthesisData data) { final List<ExportDataCell> cells = new ArrayList<>(); for(final LayoutConstraint constraint : constraints) { final FlexibleElement element = constraint.getElement(); try { final ExportDataCell cell; if (data.isWithContacts() && element instanceof ContactListElement) { final ValueResult iterationValueResult = getValueResult(element, iteration.getId(), container, data.getHandler()); cell = new ExportLinkCell(String.valueOf(ExporterUtil.getContactListCount(iterationValueResult)), ExportConstants.CONTACT_SHEET_PREFIX + element.getLabel()); } else { final ValueLabel pair = getPair(element, container, em, data.getHandler(), i18nTranslator, language, data); final String value = pair.toValueString(); cell = new ExportStringCell(value != null ? value : ""); } cells.add(cell); } catch (final Exception e) { LOGGER.warn("No value found for the element #" + element.getId() + " (" + element.getLabel() + ")", e); cells.add(new ExportStringCell("")); } } return cells; } // ------------------------------------------------------------------------- // OTHERS // ------------------------------------------------------------------------- /** * Find the value of the given element with the given query. * * @param element * Element to search. * @param valueQuery * Query to use. * @return The value of the given element as a <code>ComputedValue</code> or {@link ComputationError#NO_VALUE} if no value was found. */ private static ComputedValue getElementValue(final FlexibleElement element, final TypedQuery<String> valueQuery) { if (element != null) { valueQuery.setParameter("element", element); try { return ComputedValues.from(valueQuery.getSingleResult(), false); } catch (NoResultException e) { // Ignored. } } return ComputationError.NO_VALUE; } public static Integer getContactListCount(final ValueResult valueResult) { if (valueResult != null && valueResult.isValueDefined()) { return ValueResultUtils.splitValuesAsInteger(valueResult.getValueObject()).size(); } return 0; } private static String getUserName(User u) { String name = ""; if (u != null) name = u.getFirstName() != null ? u.getFirstName() + " " + u.getName() : u.getName(); return name; } public static void fillElementList(final List<GlobalExportDataColumn> elements, final Layout layout) { for (final LayoutGroup group : layout.getGroups()) { if(group.getHasIterations()) { elements.add(new GlobalExportIterativeGroupColumn(group)); continue; } for (final LayoutConstraint constraint : group.getConstraints()) { final FlexibleElement element = constraint.getElement(); if (element.isGloballyExportable()) elements.add(new GlobalExportFlexibleElementColumn(element)); } } } }