package org.sigmah.shared.dto.element; /* * #%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.HashMap; import java.util.List; import java.util.Map; import org.sigmah.client.i18n.I18N; import org.sigmah.client.ui.widget.HistoryTokenText; import org.sigmah.client.ui.widget.form.Forms; import org.sigmah.client.util.NumberUtils; import org.sigmah.shared.command.result.ValueResult; import org.sigmah.shared.dto.history.HistoryTokenListDTO; import org.sigmah.shared.dto.referential.BudgetSubFieldType; import org.sigmah.shared.util.ProjectUtils; import org.sigmah.shared.util.ValueResultUtils; import com.allen_sauer.gwt.log.client.Log; import com.extjs.gxt.ui.client.event.BaseEvent; 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.event.SelectionListener; import com.extjs.gxt.ui.client.store.ListStore; import com.extjs.gxt.ui.client.widget.Component; import com.extjs.gxt.ui.client.widget.form.Field; import com.extjs.gxt.ui.client.widget.form.FieldSet; import com.extjs.gxt.ui.client.widget.form.LabelField; import org.sigmah.client.ui.res.icon.IconImageBundle; import org.sigmah.shared.dto.ProjectDTO; import org.sigmah.shared.dto.referential.AmendmentState; /** * BudgetElementDTO. * * @author Denis Colliot (dcolliot@ideia.fr) */ @Deprecated public class BudgetElementDTO extends DefaultFlexibleElementDTO { /** * Serial version UID. */ private static final long serialVersionUID = 9066323201865770116L; /** * DTO corresponding entity name. */ public static final String ENTITY_NAME = "element.BudgetElement"; // DTO attributes keys. public static final String RATIO_DIVIDEND = "ratioDividend"; public static final String RATIO_DIVISOR = "ratioDivisor"; public static final String BUDGET_SUB_FIELDS = "budgetSubFields"; /** * {@inheritDoc} */ @Override public String getEntityName() { return ENTITY_NAME; } public List<BudgetSubFieldDTO> getBudgetSubFields() { return get(BUDGET_SUB_FIELDS); } public void setBudgetSubFields(List<BudgetSubFieldDTO> budgetSubFields) { set(BUDGET_SUB_FIELDS, budgetSubFields); } public BudgetSubFieldDTO getRatioDividend() { return get(RATIO_DIVIDEND); } public void setRatioDividend(BudgetSubFieldDTO ratioDividend) { set(RATIO_DIVIDEND, ratioDividend); } public BudgetSubFieldDTO getRatioDivisor() { return get(RATIO_DIVISOR); } public void setRatioDivisor(BudgetSubFieldDTO ratioDivisor) { set(RATIO_DIVISOR, ratioDivisor); } /** * {@inheritDoc} */ @Override protected Component getComponent(ValueResult valueResult, boolean enabled) { if (currentContainerDTO instanceof DefaultFlexibleElementContainer) { container = (DefaultFlexibleElementContainer) currentContainerDTO; } else { throw new IllegalArgumentException( "The flexible elements container isn't an instance of DefaultFlexibleElementContainer. The default flexible element connot be instanciated."); } final Component component; // Creates choices store. final ListStore<BudgetSubFieldDTO> store = new ListStore<BudgetSubFieldDTO>(); store.add(getBudgetSubFields()); final Map<Integer, String> values = ValueResultUtils.splitMapElements(valueResult.getValueObject()); // Spent ratio. final LabelField ratioLabel = Forms.label(I18N.CONSTANTS.adminBudgetRatio()); final Map<BudgetSubFieldDTO, Field<?>> fields = new HashMap<BudgetSubFieldDTO, Field<?>>(); final List<BudgetSubFieldDTO> budgetSubFields = getBudgetSubFields(); final boolean disabledBecauseAmendable = isDisabledBecauseAmendable(); if (enabled || disabledBecauseAmendable) { for (BudgetSubFieldDTO subField : budgetSubFields) { final HistoryWrapper<Number> input = new HistoryWrapper(createNumberField(false)); fields.put(subField, input); input.setFieldLabel(generateBudgetSubFieldLabel(subField)); if (values.get(subField.getId()) != null) { // Sets the value to the fields. input.setValue(Double.valueOf(values.get(subField.getId()))); } else { input.setValue(0); } // Show history. input.getHistoryButton().addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { loadAndShowHistory(input.getHistoryButton()); } }); if(disabledBecauseAmendable && isRatioDivisor(subField)) { input.setEnabled(false); } } // Listener. final Listener<BaseEvent> listener = new Listener<BaseEvent>() { final double minValue = 0.0; @Override public void handleEvent(BaseEvent be) { boolean isValueOn = true; final Map<BudgetSubFieldDTO, String> budgetStringValues = new HashMap<BudgetSubFieldDTO, String>(); for (BudgetSubFieldDTO budgetField : fields.keySet()) { final Field<Number> budgetNumberField = (Field<Number>) fields.get(budgetField); final Double doubleValue; if (budgetNumberField.getValue() != null) { doubleValue = budgetNumberField.getValue().doubleValue(); } else { doubleValue = 0.0; } isValueOn = isValueOn && doubleValue >= minValue; budgetStringValues.put(budgetField, String.valueOf(doubleValue)); } final String rawValue = ValueResultUtils.mergeElements(budgetStringValues); fireEvents(rawValue, isValueOn); } }; for (Field<?> field : fields.values()) { field.addListener(Events.Change, listener); } } else { for (BudgetSubFieldDTO bf : budgetSubFields) { final LabelField budgetLabelField = createLabelField(); fields.put(bf, budgetLabelField); if (bf.getType() != null) { budgetLabelField.setFieldLabel(BudgetSubFieldType.getName(bf.getType())); } else { budgetLabelField.setFieldLabel(bf.getLabel()); } if (values.get(bf.getId()) != null) { // Sets the value to the fields. budgetLabelField.setValue(Double.valueOf(values.get(bf.getId()))); } } } String rationBudgetSubFieldNames = ""; if (getRatioDividend() != null && getRatioDivisor() != null) { rationBudgetSubFieldNames = " (" + generateBudgetSubFieldLabel(getRatioDividend()) + " / " + generateBudgetSubFieldLabel(getRatioDivisor()) + ")"; if (values.get(getRatioDividend().getId()) != null && values.get(getRatioDivisor().getId()) != null) { ratioLabel.setValue(NumberUtils.ratioAsString(Double.valueOf(values.get(getRatioDividend().getId())), Double.valueOf(values.get(getRatioDivisor().getId()))) + rationBudgetSubFieldNames); } else { ratioLabel.setValue(NumberUtils.ratioAsString(0, 0) + rationBudgetSubFieldNames); } } // Fieldset. final FieldSet fieldset = new FieldSet(); fieldset.setCollapsible(true); fieldset.setLayout(Forms.layout(170, null)); for (Field<?> budgetField : fields.values()) { fieldset.add(budgetField); } fieldset.add(ratioLabel); // Sets the field label. setLabel(I18N.CONSTANTS.projectBudget()); if(getAmendable()) { fieldset.setHeadingHtml(getLabel() + " " + IconImageBundle.ICONS.DNABrownGreen().getHTML()); } else { fieldset.setHeadingHtml(getLabel()); } component = fieldset; return component; } @Override protected Component getComponentInBanner(ValueResult valueResult) { if (currentContainerDTO instanceof DefaultFlexibleElementContainer) { container = (DefaultFlexibleElementContainer) currentContainerDTO; } else { throw new IllegalArgumentException( "The flexible elements container isn't an instance of DefaultFlexibleElementContainer. The default flexible element connot be instanciated."); } Map<Integer, String> values = ValueResultUtils.splitMapElements(valueResult.getValueObject()); final LabelField budgetLabelField = createLabelField(); budgetLabelField.setFieldLabel(I18N.CONSTANTS.projectBannerBudget()); final String dividendValue = values.get(getRatioDividend().getId()); final String divisorValue = values.get(getRatioDivisor().getId()); if (dividendValue != null && divisorValue != null) { budgetLabelField.setValue(dividendValue + " / " + divisorValue); } else { budgetLabelField.setValue("0.0 / 0.0"); } final LabelField ratioLabel = Forms.label(I18N.CONSTANTS.adminBudgetRatio()); String rationBudgetSubFieldNames = ""; if (getRatioDividend() != null && getRatioDivisor() != null) { rationBudgetSubFieldNames = " (" + generateBudgetSubFieldLabel(getRatioDividend()) + " / " + generateBudgetSubFieldLabel(getRatioDivisor()) + ")"; } if (values.get(getRatioDividend().getId()) != null && values.get(getRatioDivisor().getId()) != null) { ratioLabel.setValue(NumberUtils.ratioAsString(Double.valueOf(values.get(getRatioDividend().getId())), Double.valueOf(values.get(getRatioDivisor().getId()))) + rationBudgetSubFieldNames); } else { ratioLabel.setValue(NumberUtils.ratioAsString(0, 0) + rationBudgetSubFieldNames); } return budgetLabelField; } private List<String> toLabels(String value) { final Map<Integer, String> budgets = ValueResultUtils.splitMapElements(value); final List<String> stringValues = new ArrayList<String>(); for (BudgetSubFieldDTO budgetField : getBudgetSubFields()) { // BUGFIX #788: Verifying if an entry exists before using it to avoid NullPointerExceptions final String currentBudget = budgets.size() > 0 && budgets.containsKey(budgetField.getId()) ? budgets.get(budgetField.getId()) : "0"; final String label = budgetField.getType() != null ? BudgetSubFieldType.getName(budgetField.getType()) : budgetField.getLabel(); stringValues.add(label + ": " + Double.parseDouble(currentBudget)); } return stringValues; } @Override public Object renderHistoryToken(HistoryTokenListDTO token) { ensureHistorable(); final String value = token.getTokens().get(0).getValue(); if (Log.isDebugEnabled()) { Log.debug("[renderHistoryToken] Case BUDGET ; value to split '" + value + "'."); } return new HistoryTokenText(toLabels(value)); } @Override public String toHTML(String value) { if(value == null || value.length() == 0) { return ""; } final StringBuilder htmlBuilder = new StringBuilder(); for(final String entry : toLabels(value)) { htmlBuilder.append(" -").append(entry).append("<br>"); } return htmlBuilder.toString(); } @Override protected Component getComponentWithValue(ValueResult valueResult, boolean enabled) { return getComponent(valueResult, enabled); } public String generateBudgetSubFieldLabel(BudgetSubFieldDTO bf) { String label = ""; if (bf.getType() != null) { label = BudgetSubFieldType.getName(bf.getType()); } else { label = bf.getLabel(); } return label; } public BudgetSubFieldDTO getPlannedBudget() { for (BudgetSubFieldDTO budgetSubField : getBudgetSubFields()) { if (BudgetSubFieldType.PLANNED.equals(budgetSubField.getType())) { return budgetSubField; } } return null; } private boolean isDisabledBecauseAmendable() { // BUGFIX #794: Checking if this element is amendable before going further. if(currentContainerDTO instanceof ProjectDTO && getAmendable()) { final ProjectDTO project = (ProjectDTO)currentContainerDTO; if(project.getAmendmentState() == AmendmentState.LOCKED && project.getCloseDate() == null) { return ProjectUtils.isProjectEditable(project, auth()); } } return false; } private boolean isRatioDivisor(BudgetSubFieldDTO subField) { final BudgetSubFieldDTO divisor = getRatioDivisor(); return subField != null && divisor != null && subField.getId() != null && subField.getId().equals(divisor.getId()); } }