Skip to content

Commit

Permalink
Merge branch 'hotfix/1.9.21' of https://github.com/akvo/akvo-flow
Browse files Browse the repository at this point in the history
  • Loading branch information
osg74 committed Jul 26, 2017
2 parents 9cc3e56 + 6e4e4bd commit 94fd189
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 70 deletions.
4 changes: 3 additions & 1 deletion GAE/src/org/akvo/flow/domain/DataUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,10 @@ public static String jsonResponsesToPipeSeparated(String optionResponses) {
List<Map<String, String>> options = jsonStringToList(optionResponses);
if (options != null) {
for (Map<String, String> option : options) {
if (option.get("text") != null) {
if (option.get("text") != null) { //try OPTION answer
pipeSeparated.append("|").append(option.get("text"));
} else if (option.get("name") != null) { //try CASCADE answer
pipeSeparated.append("|").append(option.get("name"));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,6 @@ public class GraphicalSurveySummaryExporter extends SurveySummaryExporter {
// store indices of file columns for lookup when generating responses
private Map<String, Integer> columnIndexMap = new HashMap<>();
// stores the questions whose answers will make up the display name, in order
private List<QuestionDto> displayNamePartList = new ArrayList<>();

@Override
public void export(Map<String, String> criteria, File fileName,
Expand Down Expand Up @@ -478,9 +477,6 @@ protected SummaryModel fetchAndWriteRawData(String surveyId,
}
nameToIdMap.put(q.getKeyId().toString(), q.getText());
}
if (q.getLocaleNameFlag() && q.getKeyId() != null && q.getType() != null) {
displayNamePartList.add(q);
}
}
}

Expand Down Expand Up @@ -620,8 +616,7 @@ private synchronized int writeInstanceData(Sheet sheet, final int startRow,
final Long questionId = Long.valueOf(q);
final QuestionDto questionDto = questionsById.get(questionId);

SortedMap<Long, String> iterationsMap = instanceData.responseMap
.get(questionId);
SortedMap<Long, String> iterationsMap = instanceData.responseMap.get(questionId);

if (iterationsMap == null) {
continue;
Expand Down Expand Up @@ -657,13 +652,11 @@ private synchronized int writeInstanceData(Sheet sheet, final int startRow,
// Question id -> response
Map<String, String> responseMap = new HashMap<>();

for (Entry<Long, SortedMap<Long, String>> entry : instanceData.responseMap
.entrySet()) {
for (Entry<Long, SortedMap<Long, String>> entry : instanceData.responseMap.entrySet()) {
String questionId = entry.getKey().toString();

// Pick the first iteration response since we currently don't
// support Repeatable
// Question Groups
// support Repeatable Question Groups
Collection<String> iterations = entry.getValue().values();
if (!iterations.isEmpty()) {
String response = iterations.iterator().next();
Expand All @@ -677,27 +670,25 @@ private synchronized int writeInstanceData(Sheet sheet, final int startRow,
rollups = formRollupStrings(responseMap);
}
for (Entry<String, String> entry : responseMap.entrySet()) {
//TODO: only OPTION and NUMBER summarizable now. Simple to add CASCADE.
if (!unsummarizable.contains(entry.getKey())) {
String effectiveId = entry.getKey();
if (nameToIdMap.get(effectiveId) != null) {
effectiveId = collapseIdMap.get(nameToIdMap
.get(effectiveId));
effectiveId = collapseIdMap.get(nameToIdMap.get(effectiveId));
}

String[] vals;
if (entry.getValue().startsWith("[")) {
if (entry.getValue().startsWith("[")) { //JSON
try {
List<Map<String, String>> optionNodes = OBJECT_MAPPER
.readValue(
entry.getValue(),
new TypeReference<List<Map<String, String>>>() {
});
List<Map<String, String>> optionNodes = OBJECT_MAPPER.readValue(
entry.getValue(),
new TypeReference<List<Map<String, String>>>() {}
);
List<String> valsList = new ArrayList<>();
for (Map<String, String> optionNode : optionNodes) {
valsList.add(optionNode.get("text"));
valsList.add(optionNode.get("text")); //get "name" for CASCADE
}
vals = valsList
.toArray(new String[valsList.size()]);
vals = valsList.toArray(new String[valsList.size()]);
} catch (IOException e) {
vals = entry.getValue().split("\\|");
}
Expand All @@ -708,10 +699,8 @@ private synchronized int writeInstanceData(Sheet sheet, final int startRow,
synchronized (model) {
for (int i = 0; i < vals.length; i++) {
if (vals[i] != null && vals[i].trim().length() > 0) {
QuestionDto q = questionsById.get(Long
.valueOf(effectiveId));
model.tallyResponse(effectiveId, rollups,
vals[i], q);
QuestionDto q = questionsById.get(Long.valueOf(effectiveId));
model.tallyResponse(effectiveId, rollups, vals[i], q);
}
}
}
Expand Down Expand Up @@ -1295,8 +1284,7 @@ protected Object[] createRawDataHeader(Workbook wb, Sheet sheet,
: getLocalizedText(q.getText(),
q.getTranslationMap())
+ " - " + level;
createCell(row, offset++, levelName,
headerStyle);
createCell(row, offset++, levelName, headerStyle);
}
} else if (QuestionType.CADDISFLY == q.getType()) {
StringBuilder caddisflyFirstResultColumnHeaderPrefix = new StringBuilder();
Expand All @@ -1318,8 +1306,7 @@ protected Object[] createRawDataHeader(Workbook wb, Sheet sheet,
.getCaddisflyResourceUuid().trim());
// get expected results for this test, if it exists
if (cr != null) {
List<CaddisflyResult> crResults = cr
.getResults();
List<CaddisflyResult> crResults = cr.getResults();
// sort results on id value
Collections.sort(crResults);

Expand Down Expand Up @@ -1355,8 +1342,7 @@ protected Object[] createRawDataHeader(Workbook wb, Sheet sheet,
offset++,
"--CADDISFLY--|" + q.getText()
+ "--"
+ IMAGE_LABEL
.get(columnLocale),
+ IMAGE_LABEL.get(columnLocale),
headerStyle);
}

Expand Down Expand Up @@ -1417,8 +1403,9 @@ protected Object[] createRawDataHeader(Workbook wb, Sheet sheet,
}
}
}
if (!(QuestionType.NUMBER == q.getType() || QuestionType.OPTION == q
.getType())) {
//TODO: add cascade
if (!(QuestionType.NUMBER == q.getType()
|| QuestionType.OPTION == q.getType())) {
nonSummarizableList.add(q.getKeyId().toString());
}
}
Expand Down Expand Up @@ -1452,15 +1439,19 @@ private void writeSummaryReport(
String title = sector == null ? SUMMARY_LABEL.get(locale) : sector;
Sheet sheet = null;
int sheetCount = 2;
String curTitle = WorkbookUtil.createSafeSheetName(title);
String curTitle = WorkbookUtil.createSafeSheetName(title); //first try the whole sector name
while (sheet == null) {
sheet = wb.getSheet(curTitle);
if (sheet == null) {
if (sheet == null) { //Name free - use it
sheet = wb.createSheet(curTitle);
} else {
} else { //Name in use, try another. Max is 31 chars.
sheet = null;
curTitle = WorkbookUtil.createSafeSheetName(title + " " + sheetCount);
sheetCount++;
curTitle = WorkbookUtil.createSafeSheetName(
title.substring(0,Math.min(title.length(),27)) + " " + sheetCount
);
if (++sheetCount >= 1000) {
throw new Exception("Could not create unique sheet name after 1000 tries.");
}
}
}
CreationHelper creationHelper = wb.getCreationHelper();
Expand All @@ -1470,14 +1461,13 @@ private void writeSummaryReport(
if (sector == null) {
createCell(row, 0, REPORT_HEADER.get(locale), headerStyle);
} else {
createCell(row, 0, sector + " " + REPORT_HEADER.get(locale),
headerStyle);
createCell(row, 0, sector + " " + REPORT_HEADER.get(locale), headerStyle);
}
for (QuestionGroupDto group : orderedGroupList) {
if (questionMap.get(group) != null) {
for (QuestionDto question : questionMap.get(group)) {
if (!(QuestionType.OPTION == question.getType() || QuestionType.NUMBER == question
.getType())) {
if (!(QuestionType.OPTION == question.getType() //TODO: add cascade
|| QuestionType.NUMBER == question.getType())) {
continue;
} else {
if (summaryModel.getResponseCountsForQuestion(
Expand All @@ -1487,25 +1477,23 @@ private void writeSummaryReport(
}
}
// for both options and numeric, we want a pie chart and
// data table for numeric, we also want descriptive
// statistics
// data table. for numeric, we also want descriptive
// statistics.
int tableTopRow = curRow++;
int tableBottomRow = curRow;
row = getRow(tableTopRow, sheet);
// span the question heading over the data table
sheet.addMergedRegion(new CellRangeAddress(curRow - 1,
curRow - 1, 0, 2));
sheet.addMergedRegion(new CellRangeAddress(curRow - 1, curRow - 1, 0, 2));
createCell(
row,
0,
getLocalizedText(question.getText(),
question.getTranslationMap()), headerStyle);
getLocalizedText(question.getText(), question.getTranslationMap()),
headerStyle);
DescriptiveStats stats = summaryModel
.getDescriptiveStatsForQuestion(
question.getKeyId(), sector);
if (stats != null && stats.getSampleCount() > 0) {
sheet.addMergedRegion(new CellRangeAddress(curRow - 1,
curRow - 1, 4, 5));
sheet.addMergedRegion(new CellRangeAddress(curRow - 1, curRow - 1, 4, 5));
createCell(
row,
4,
Expand All @@ -1519,8 +1507,7 @@ private void writeSummaryReport(

// now create the data table for the option count
Map<String, Long> counts = summaryModel
.getResponseCountsForQuestion(question.getKeyId(),
sector);
.getResponseCountsForQuestion(question.getKeyId(), sector);
int sampleTotal = 0;
List<String> labels = new ArrayList<String>();
List<String> values = new ArrayList<String>();
Expand All @@ -1543,8 +1530,7 @@ private void writeSummaryReport(

for (Map<String, String> optionNode : optionNodes) {
labelTextBuilder.append("|");
labelTextBuilder.append(optionNode
.get("text"));
labelTextBuilder.append(optionNode.get("text"));
}
if (labelTextBuilder.length() > 0) {
labelTextBuilder.deleteCharAt(0);
Expand Down Expand Up @@ -1656,8 +1642,7 @@ private void writeSummaryReport(
if (values != null) {
for (String val : values) {
try {
if (val != null
&& new Double(val.trim()) > 0D) {
if (val != null && new Double(val.trim()) > 0D) {
hasVals = true;
break;
}
Expand All @@ -1670,20 +1655,17 @@ && new Double(val.trim()) > 0D) {
// value
if (hasVals && generateCharts) {
// now insert the graph
int indx = wb
.addPicture(
JFreechartChartUtil
.getPieChart(
labels,
values,
getLocalizedText(
question.getText(),
question.getTranslationMap()),
CHART_WIDTH,
CHART_HEIGHT),
int indx = wb.addPicture(
JFreechartChartUtil.getPieChart(
labels,
values,
getLocalizedText(
question.getText(),
question.getTranslationMap()),
CHART_WIDTH,
CHART_HEIGHT),
Workbook.PICTURE_TYPE_PNG);
ClientAnchor anchor = creationHelper
.createClientAnchor();
ClientAnchor anchor = creationHelper.createClientAnchor();
anchor.setDx1(0);
anchor.setDy1(0);
anchor.setDx2(0);
Expand Down
6 changes: 6 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Akvo Flow Release Notes
----
# 1.9.21.1 Thoroughbred Tamandua hotfix
Date: 26 July 2017

## Resolved issues
* **Reporting fixes** - Comprehensive reports should now work when the regional summary sheets get their names from a cascade question [#2206], and also work for questions that have very long names.

# 1.9.21 Thoroughbred Tamandua
Date: 21 July 2017

Expand Down

0 comments on commit 94fd189

Please sign in to comment.