Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,235 changes: 1,098 additions & 137 deletions amp/TEMPLATE/reamp/package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion amp/TEMPLATE/reamp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"author": "Alexei Savca",
"license": "inherit",
"devDependencies": {
"amp-ui": "github:devgateway/amp-ui#develop",
"amp-ui": "github:devgateway/amp-ui#add-missing-me-fields-to-preview-and-api",
"babel-core": "^6.26.3",
"babel-jest": "^6.0.1",
"babel-loader": "^6.3.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,108 @@ private static void addExtraFieldsToActivity(Map<String, Object> activityFields,
.findFirst();

addActualIndicatorValues(indicatorsObject, projectId);
addDisaggregationValues(indicatorsObject);
resolveIndicatorActivityLocations(indicatorsObject);
}
}

/**
* Replaces each indicator's {@code activity_location} value (an AmpActivityLocation PK)
* with the inner AmpCategoryValueLocations id so the frontend can hydrate it to a location name
* via the standard locations id-values pipeline
*/
private static void resolveIndicatorActivityLocations(Optional<Object> indicatorsObject) {
indicatorsObject.ifPresent(indicators -> {
if (!(indicators instanceof ArrayList)) {
return;
}
List<Map<String, Object>> indicatorsList = (ArrayList<Map<String, Object>>) indicators;
for (Map<String, Object> indicator : indicatorsList) {
Object rawLocId = indicator.get("activity_location");
if (rawLocId == null) {
continue;
}
Long ampActivityLocationId = (rawLocId instanceof Long)
? (Long) rawLocId : Long.valueOf(rawLocId.toString());
try {
AmpActivityLocation aal = (AmpActivityLocation)
PersistenceManager.getSession().get(AmpActivityLocation.class, ampActivityLocationId);
if (aal != null && aal.getLocation() != null) {
indicator.put("activity_location", aal.getLocation().getId());
}
} catch (Exception e) {
logger.error("Failed to resolve AmpActivityLocation id=" + ampActivityLocationId
+ " to inner location", e);
}
}
});
}

private static void addDisaggregationValues(Optional<Object> indicatorsObject) {
indicatorsObject.ifPresent(indicators -> {
if (indicators instanceof ArrayList) {
List<Map<String, Object>> indicatorsList = (ArrayList<Map<String, Object>>) indicators;
for (Map<String, Object> indicator : indicatorsList) {
Long indicatorId = (Long) indicator.get("indicator");
if (indicatorId == null) {
continue;
}
AmpIndicator ampIndicator;
try {
ampIndicator = IndicatorUtil.getIndicator(indicatorId);
} catch (DgException e) {
logger.error("Failed to load AmpIndicator id=" + indicatorId + " for disaggregation values", e);
continue;
}
if (ampIndicator == null || ampIndicator.getDisaggregationValues() == null) {
indicator.put("disaggregation_values", Collections.emptyList());
continue;
}
List<Map<String, Object>> disaggList = new ArrayList<>();
for (AmpIndicatorDisaggregationValue dv : ampIndicator.getDisaggregationValues()) {
Map<String, Object> dvMap = new LinkedHashMap<>();
dvMap.put("id", dv.getId());
dvMap.put("parent_category",
dv.getParentCategory() != null ? dv.getParentCategory().getId() : null);
dvMap.put("parent_category_name",
dv.getParentCategory() != null ? dv.getParentCategory().getValue() : null);
dvMap.put("child_category",
dv.getChildCategory() != null ? dv.getChildCategory().getId() : null);
dvMap.put("child_category_name",
dv.getChildCategory() != null ? dv.getChildCategory().getValue() : null);
dvMap.put("base_value", serializeGlobalValue(dv.getBaseValue()));
dvMap.put("target_value", serializeGlobalValue(dv.getTargetValue()));
List<Map<String, Object>> actualValues = new ArrayList<>();
if (dv.getActualValues() != null) {
for (AmpIndicatorGlobalValue av : dv.getActualValues()) {
actualValues.add(serializeGlobalValue(av));
}
}
dvMap.put("actual_values", actualValues);
disaggList.add(dvMap);
}
indicator.put("disaggregation_values", disaggList);
}
}
});
}

private static Map<String, Object> serializeGlobalValue(AmpIndicatorGlobalValue gv) {
if (gv == null) {
return null;
}
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Map<String, Object> map = new LinkedHashMap<>();
map.put("id", gv.getId());
map.put("original_value", gv.getOriginalValue());
map.put("original_value_date",
gv.getOriginalValueDate() != null ? dateFormat.format(gv.getOriginalValueDate()) : null);
map.put("revised_value", gv.getRevisedValue());
map.put("revised_value_date",
gv.getRevisedValueDate() != null ? dateFormat.format(gv.getRevisedValueDate()) : null);
return map;
}

private static void addActualIndicatorValues(Optional<Object> indicatorsObject, Long projectId){
// Loop through the elements of the ArrayList if present in indicators
indicatorsObject.ifPresent(indicators -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.digijava.kernel.validators.common.RequiredValidator;
import org.digijava.module.aim.annotations.interchange.*;
import org.digijava.module.aim.util.AmpAutoCompleteDisplayable;
import org.digijava.module.aim.util.Identifiable;
import org.digijava.module.aim.util.Output;
import org.digijava.module.aim.util.TreeNodeAware;
import org.jetbrains.annotations.NotNull;
Expand All @@ -20,7 +21,7 @@
*
*/
public class AmpActivityLocation implements Comparable<AmpActivityLocation>, Versionable, Serializable, Cloneable,
TreeNodeAware<AmpCategoryValueLocations> {
TreeNodeAware<AmpCategoryValueLocations>, Identifiable {

//IATI-check: should be exported.
@InterchangeableId
Expand Down Expand Up @@ -58,6 +59,11 @@ public Long getId() {
public void setId(Long id) {
this.id = id;
}

@Override
public Object getIdentifier() {
return id;
}
public AmpActivityVersion getActivity() {
return activity;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,36 @@
package org.digijava.module.aim.dbentity;

import org.digijava.module.aim.annotations.interchange.Interchangeable;
import org.digijava.module.aim.annotations.interchange.InterchangeableBackReference;
import org.digijava.module.aim.annotations.interchange.InterchangeableId;
import org.digijava.module.categorymanager.dbentity.AmpCategoryValue;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import java.io.Serializable;
import java.util.Set;
import java.util.HashSet;

public class AmpIndicatorDisaggregationValue implements Serializable {
@InterchangeableId
@Interchangeable(fieldTitle = "Id")
private Long id;

@Interchangeable(fieldTitle = "Parent Category", importable = true, pickIdOnly = true)
private AmpCategoryValue parentCategory;

@Interchangeable(fieldTitle = "Child Category", importable = true, pickIdOnly = true)
private AmpCategoryValue childCategory;

@Interchangeable(fieldTitle = "Base Value", importable = true)
private AmpIndicatorGlobalValue baseValue;

@Interchangeable(fieldTitle = "Target Value", importable = true)
private AmpIndicatorGlobalValue targetValue;

// changed from List to Set and will be mapped via hbm
@Interchangeable(fieldTitle = "Actual Values", importable = true)
private Set<AmpIndicatorGlobalValue> actualValues; // @OneToMany like mapping in hbm (inverse)

@InterchangeableBackReference
private AmpIndicator indicator;

public AmpIndicatorGlobalValue getBaseValue() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
import io.swagger.annotations.ApiModelProperty;
import org.digijava.kernel.ampapi.endpoints.serializers.LocalizedDateDeserializer;
import org.digijava.kernel.ampapi.endpoints.serializers.LocalizedDateSerializer;
import org.digijava.module.aim.annotations.interchange.Interchangeable;
import org.digijava.module.aim.annotations.interchange.InterchangeableBackReference;
import org.digijava.module.aim.annotations.interchange.InterchangeableId;

import java.io.Serializable;
import java.util.Date;
Expand All @@ -19,10 +22,12 @@ public class AmpIndicatorGlobalValue implements Serializable {
public static final int ACTUAL = 1;
public static final int BASE = 2;
public static final int REVISED = 3;

@InterchangeableId
@Interchangeable(fieldTitle = "Id")
@JsonIgnore
private Long id;


@JsonIgnore
/**
* The type of indicator, see {@link AmpIndicatorValue constants}
Expand All @@ -31,24 +36,29 @@ public class AmpIndicatorGlobalValue implements Serializable {
*/
private int type;

@Interchangeable(fieldTitle = "Original Value", importable = true)
@JsonProperty("originalValue")
private Double originalValue;

@Interchangeable(fieldTitle = "Original Value Date", importable = true)
@JsonSerialize(using = LocalizedDateSerializer.class)
@JsonDeserialize(using = LocalizedDateDeserializer.class)
@JsonProperty("originalValueDate")
@ApiModelProperty(dataType = "java.util.Date", example = "02/02/2023")
private Date originalValueDate;

@Interchangeable(fieldTitle = "Revised Value", importable = true)
@JsonProperty("revisedValue")
private Double revisedValue;

@Interchangeable(fieldTitle = "Revised Value Date", importable = true)
@JsonSerialize(using = LocalizedDateSerializer.class)
@JsonDeserialize(using = LocalizedDateDeserializer.class)
@JsonProperty("revisedValueDate")
@ApiModelProperty(dataType = "java.util.Date", example = "02/02/2023")
private Date revisedValueDate;

@InterchangeableBackReference
@JsonIgnore
private AmpIndicator indicator;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.digijava.module.aim.annotations.interchange.Interchangeable;
import org.digijava.module.aim.annotations.interchange.InterchangeableDiscriminator;
import org.digijava.module.aim.annotations.interchange.InterchangeableId;
import org.digijava.kernel.ampapi.endpoints.common.values.providers.LocationPossibleValuesProvider;
import org.digijava.module.aim.annotations.interchange.PossibleValues;

import java.io.Serializable;
Expand Down Expand Up @@ -48,6 +49,22 @@ public class IndicatorConnection implements Serializable, Comparable<IndicatorTh
// @VersionableCollection(fieldTitle = "Indicator Values")
protected Set<AmpIndicatorValue> values = new HashSet<>();

/**
* Disaggregation values for this indicator connection.
* Transient — not persisted by Hibernate. Populated externally (e.g. via addExtraFieldsToActivity)
*/
@Interchangeable(fieldTitle = "Disaggregation Values", importable = false)
private transient Set<AmpIndicatorDisaggregationValue> disaggregationValues = new HashSet<>();

/**
* Activity location for multi-location instances.
* When an indicator is added per location in a multi-location activity, this links to the specific
* AmpActivityLocation. The activity API replaces this id with the inner location id at export time
* (see ActivityInterchangeUtils.resolveIndicatorActivityLocations).
* Null for single-location activities.
*/
@PossibleValues(LocationPossibleValuesProvider.class)
@Interchangeable(fieldTitle = "Activity Location", importable = true, pickIdOnly = true)
private AmpActivityLocation activityLocation;

public Long getId() {
Expand Down Expand Up @@ -118,4 +135,12 @@ public String getIndicatorLocationKey() {
}
return indicatorLocationKey;
}

public Set<AmpIndicatorDisaggregationValue> getDisaggregationValues() {
return disaggregationValues;
}

public void setDisaggregationValues(Set<AmpIndicatorDisaggregationValue> disaggregationValues) {
this.disaggregationValues = disaggregationValues;
}
}
Loading
Loading