Skip to content

Commit

Permalink
Merge branch 'release/2.2.0.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
Inigo Lopez de Heredia committed Nov 11, 2015
2 parents 79b6a05 + 2bb9d8c commit bb08a56
Show file tree
Hide file tree
Showing 14 changed files with 162 additions and 61 deletions.
9 changes: 9 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
Akvo FLOW app release notes
===========================

# ver 2.2.0.2
Date: 11 November 2015

Resolved issues
---------------
* Fix backwards compatibility in cascade questions [#371]
* Fix datapoint name generation in cascade questions [#373]
* Display form version [#365]

# ver 2.2.0.1
Date: 23 October 2015

Expand Down
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.akvo.flow"
android:versionCode="1"
android:versionName="2.2.0.1" >
android:versionName="2.2.0.2" >

<uses-sdk
android:minSdkVersion="10"
Expand Down
30 changes: 22 additions & 8 deletions app/src/main/java/org/akvo/flow/activity/FormActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
Expand Down Expand Up @@ -127,7 +128,9 @@ protected void onCreate(Bundle savedInstanceState) {
}

// Set the survey name as Activity title
setTitle(mSurvey.getName());
getSupportActionBar().setTitle(mSurvey.getName());
getSupportActionBar().setSubtitle("v " + getVersion());

mPager = (ViewPager)findViewById(R.id.pager);
mAdapter = new SurveyTabAdapter(this, getSupportActionBar(), mPager, this, this);
mPager.setAdapter(mAdapter);
Expand Down Expand Up @@ -199,6 +202,21 @@ private void loadSurvey(String surveyId) {
}
}

private double getVersion() {
double version = 0.0;
Cursor c = mDatabase.getFormInstance(mSurveyInstanceId);
if (c.moveToFirst()) {
version = c.getDouble(SurveyDbAdapter.FormInstanceQuery.VERSION);
}
c.close();

if (version == 0.0) {
version = mSurvey.getVersion();// Default to current value
}

return version;
}

/**
* Load state for the current survey instance
*/
Expand Down Expand Up @@ -263,18 +281,14 @@ private void saveRecordMetaData() {
boolean first = true;
for (String questionId : localeNameQuestions) {
QuestionResponse questionResponse = mDatabase.getResponse(mSurveyInstanceId, questionId);
String answer = questionResponse != null ? questionResponse.getValue() : null;
String answer = questionResponse != null ? questionResponse.getDatapointNameValue() : null;

if (!TextUtils.isEmpty(answer)) {
answer = answer.replaceAll("\\s+", " ");// Trim line breaks, multiple spaces, etc
answer = answer.replaceAll("\\s*\\|\\s*", " - ");// Replace pipes with hyphens

if (!first) {
builder.append(" - ");
} else {
first = false;
}
builder.append(answer.trim());
builder.append(answer);
first = false;
}
}
// Make sure the value is not larger than 500 chars
Expand Down
8 changes: 5 additions & 3 deletions app/src/main/java/org/akvo/flow/activity/RecordActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.akvo.flow.app.FlowApp;
import org.akvo.flow.dao.SurveyDbAdapter;
import org.akvo.flow.dao.SurveyDbAdapter.SurveyInstanceStatus;
import org.akvo.flow.domain.Survey;
import org.akvo.flow.domain.SurveyGroup;
import org.akvo.flow.domain.SurveyedLocale;
import org.akvo.flow.domain.User;
Expand Down Expand Up @@ -138,16 +139,17 @@ public void onSurveyClick(final String surveyId) {
Toast.makeText(this, R.string.pleasewaitforbootstrap, Toast.LENGTH_LONG).show();
return;
}
if (!mDatabase.getSurvey(surveyId).isHelpDownloaded()) {
Survey survey = mDatabase.getSurvey(surveyId);
if (!survey.isHelpDownloaded()) {
Toast.makeText(this, R.string.error_missing_cascade, Toast.LENGTH_LONG).show();
return;
}

// Check if there are saved (non-submitted) responses for this Survey, and take the 1st one
long[] instances = mDatabase.getSurveyInstances(mRecord.getId(), surveyId,
long[] instances = mDatabase.getFormInstances(mRecord.getId(), surveyId,
SurveyInstanceStatus.SAVED);
long instance = instances.length > 0 ? instances[0]
: mDatabase.createSurveyRespondent(surveyId, mUser, mRecord.getId());
: mDatabase.createSurveyRespondent(surveyId, survey.getVersion(), mUser, mRecord.getId());

Intent i = new Intent(this, FormActivity.class);
i.putExtra(ConstantUtil.USER_ID_KEY, mUser.getId());
Expand Down
8 changes: 4 additions & 4 deletions app/src/main/java/org/akvo/flow/activity/SurveyActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -293,13 +293,13 @@ public void onRecordSelected(String surveyedLocaleId) {
final String formId = registrationForm.getId();
long formInstanceId;
boolean readOnly = false;
Cursor c = mDatabase.getSurveyInstances(surveyedLocaleId);
Cursor c = mDatabase.getFormInstances(surveyedLocaleId);
if (c.moveToFirst()) {
formInstanceId = c.getLong(c.getColumnIndexOrThrow(SurveyDbAdapter.SurveyInstanceColumns._ID));
int status = c.getInt(c.getColumnIndexOrThrow(SurveyDbAdapter.SurveyInstanceColumns.STATUS));
formInstanceId = c.getLong(SurveyDbAdapter.FormInstanceQuery._ID);
int status = c.getInt(SurveyDbAdapter.FormInstanceQuery.STATUS);
readOnly = status != SurveyDbAdapter.SurveyInstanceStatus.SAVED;
} else {
formInstanceId = mDatabase.createSurveyRespondent(formId, user, surveyedLocaleId);
formInstanceId = mDatabase.createSurveyRespondent(formId, registrationForm.getVersion(), user, surveyedLocaleId);
}
c.close();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public SurveyInstanceLoader(Context context, SurveyDbAdapter db, String surveye

@Override
public Cursor loadData(SurveyDbAdapter database) {
return database.getSurveyInstances(mSurveyedLocaleId);
return database.getFormInstances(mSurveyedLocaleId);
}

}
22 changes: 9 additions & 13 deletions app/src/main/java/org/akvo/flow/dao/CascadeDB.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014 Stichting Akvo (Akvo Foundation)
* Copyright (C) 2014-2015 Stichting Akvo (Akvo Foundation)
*
* This file is part of Akvo FLOW.
*
Expand Down Expand Up @@ -38,14 +38,6 @@ public interface NodeColumns {
String PARENT = "parent";
}

public interface NodeQuery {
String[] PROJECTION = new String[]{NodeColumns.ID, NodeColumns.NAME, NodeColumns.CODE};

int ID = 0;
int NAME = 1;
int CODE = 2;
}

private DatabaseHelper mHelper;
public SQLiteDatabase mDatabase;

Expand Down Expand Up @@ -73,17 +65,21 @@ public boolean isOpen() {
}

public List<Node> getValues(long parent) {
Cursor c = mDatabase.query(TABLE_NODE, NodeQuery.PROJECTION,
// For backwards compatibility, we'll query all columns, and check if the code exist.
Cursor c = mDatabase.query(TABLE_NODE, null,
NodeColumns.PARENT + "=?",
new String[]{String.valueOf(parent)},
null, null, NodeColumns.NAME);

final List<Node> result = new ArrayList<Node>();
final List<Node> result = new ArrayList<>();
if (c != null) {
if (c.moveToFirst()) {
final int codeCol = c.getColumnIndex(NodeColumns.CODE);
do {
result.add(new Node(c.getLong(NodeQuery.ID), c.getString(NodeQuery.NAME),
c.getString(NodeQuery.CODE)));
Long id = c.getLong(c.getColumnIndex(NodeColumns.ID));
String name = c.getString(c.getColumnIndex(NodeColumns.NAME));
String code = codeCol > -1 ? c.getString(codeCol) : null;
result.add(new Node(id, name, code));
} while (c.moveToNext());
}
c.close();
Expand Down
67 changes: 53 additions & 14 deletions app/src/main/java/org/akvo/flow/dao/SurveyDbAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ public interface SurveyInstanceColumns {
String STATUS = "status";// Denormalized value. See 'SurveyInstanceStatus'
String DURATION = "duration";
String SUBMITTER = "submitter";// Submitter name. Added in DB version 79
String VERSION = "version";
}

public interface TransmissionColumns {
Expand Down Expand Up @@ -212,7 +213,8 @@ public interface TransmissionStatus {
private static final int VER_LAUNCH = 78;// App refactor version. Start from scratch
private static final int VER_FORM_SUBMITTER = 79;
private static final int VER_FORM_DEL_CHECK = 80;
private static final int DATABASE_VERSION = VER_FORM_DEL_CHECK;
private static final int VER_FORM_VERSION = 81;
private static final int DATABASE_VERSION = VER_FORM_VERSION;

private final Context context;

Expand Down Expand Up @@ -275,6 +277,7 @@ public void onCreate(SQLiteDatabase db) {
+ SurveyInstanceColumns.SYNC_DATE + " INTEGER,"
+ SurveyInstanceColumns.DURATION + " INTEGER NOT NULL DEFAULT 0,"
+ SurveyInstanceColumns.SUBMITTER + " TEXT,"
+ SurveyInstanceColumns.VERSION + " REAL,"
+ "UNIQUE (" + SurveyInstanceColumns.UUID + ") ON CONFLICT REPLACE)");

db.execSQL("CREATE TABLE " + Tables.RESPONSE + " ("
Expand Down Expand Up @@ -340,6 +343,9 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
case VER_FORM_SUBMITTER:
db.execSQL("ALTER TABLE " + Tables.TRANSMISSION
+ " ADD COLUMN " + TransmissionColumns.SURVEY_ID + " TEXT");
case VER_FORM_DEL_CHECK:
db.execSQL("ALTER TABLE " + Tables.SURVEY_INSTANCE
+ " ADD COLUMN " + SurveyInstanceColumns.VERSION + " REAL");
version = DATABASE_VERSION;
}

Expand Down Expand Up @@ -738,11 +744,12 @@ public QuestionResponse createOrUpdateSurveyResponse(QuestionResponse resp) {
/**
* creates a new unsubmitted survey instance
*/
public long createSurveyRespondent(String surveyId, User user, String surveyedLocaleId) {
public long createSurveyRespondent(String surveyId, double version, User user, String surveyedLocaleId) {
final long time = System.currentTimeMillis();

ContentValues initialValues = new ContentValues();
initialValues.put(SurveyInstanceColumns.SURVEY_ID, surveyId);
initialValues.put(SurveyInstanceColumns.VERSION, version);
initialValues.put(SurveyInstanceColumns.USER_ID, user.getId());
initialValues.put(SurveyInstanceColumns.STATUS, SurveyInstanceStatus.SAVED);
initialValues.put(SurveyInstanceColumns.UUID, PlatformUtil.uuid());
Expand Down Expand Up @@ -1392,24 +1399,24 @@ public void deleteSurvey(String surveyId) {
ContentValues updatedValues = new ContentValues();
updatedValues.put(SurveyColumns.DELETED, 1);
database.update(Tables.SURVEY, updatedValues, SurveyColumns.SURVEY_ID + " = ?",
new String[] { surveyId });
new String[]{surveyId});
}

public Cursor getFormInstance(long formInstanceId) {
return database.query(Tables.SURVEY_INSTANCE_JOIN_SURVEY,
FormInstanceQuery.PROJECTION,
Tables.SURVEY_INSTANCE + "." + SurveyInstanceColumns._ID + "= ?",
new String[] { String.valueOf(formInstanceId) },
null, null, null);
}

/**
* Get all the SurveyInstances for a particular data point. Registration form will be at the top
* of the list, all other forms will be ordered by submission date (desc).
*/
public Cursor getSurveyInstances(String recordId) {
public Cursor getFormInstances(String recordId) {
return database.query(Tables.SURVEY_INSTANCE_JOIN_SURVEY,
new String[] {
Tables.SURVEY_INSTANCE + "." + SurveyInstanceColumns._ID,
Tables.SURVEY_INSTANCE + "." + SurveyInstanceColumns.SURVEY_ID,
SurveyColumns.NAME, SurveyInstanceColumns.SAVED_DATE,
SurveyInstanceColumns.USER_ID, SurveyInstanceColumns.SUBMITTED_DATE,
SurveyInstanceColumns.UUID, SurveyInstanceColumns.STATUS,
SurveyInstanceColumns.SYNC_DATE, SurveyInstanceColumns.EXPORTED_DATE,
SurveyInstanceColumns.RECORD_ID, SurveyInstanceColumns.SUBMITTER,
},
FormInstanceQuery.PROJECTION,
Tables.SURVEY_INSTANCE + "." + SurveyInstanceColumns.RECORD_ID + "= ?",
new String[] { recordId },
null, null,
Expand All @@ -1421,7 +1428,7 @@ public Cursor getSurveyInstances(String recordId) {
* Get SurveyInstances with a particular status.
* If the recordId is not null, results will be filtered by Record.
*/
public long[] getSurveyInstances(String recordId, String surveyId, int status) {
public long[] getFormInstances(String recordId, String surveyId, int status) {
String where = Tables.SURVEY_INSTANCE + "." + SurveyInstanceColumns.SURVEY_ID + "= ?" +
" AND " + SurveyInstanceColumns.STATUS + "= ?" +
" AND " + SurveyInstanceColumns.RECORD_ID + "= ?";
Expand Down Expand Up @@ -1769,4 +1776,36 @@ public interface RecordQuery {
int LAST_MODIFIED = 6;
}

public interface FormInstanceQuery {
String[] PROJECTION = {
Tables.SURVEY_INSTANCE + "." + SurveyInstanceColumns._ID,
Tables.SURVEY_INSTANCE + "." + SurveyInstanceColumns.SURVEY_ID,
Tables.SURVEY_INSTANCE + "." + SurveyInstanceColumns.VERSION,
SurveyColumns.NAME,
SurveyInstanceColumns.SAVED_DATE,
SurveyInstanceColumns.USER_ID,
SurveyInstanceColumns.SUBMITTED_DATE,
SurveyInstanceColumns.UUID,
SurveyInstanceColumns.STATUS,
SurveyInstanceColumns.SYNC_DATE,
SurveyInstanceColumns.EXPORTED_DATE,
SurveyInstanceColumns.RECORD_ID,
SurveyInstanceColumns.SUBMITTER,
};

int _ID = 0;
int SURVEY_ID = 1;
int VERSION = 2;
int NAME = 3;
int SAVED_DATE = 4;
int USER_ID = 5;
int SUBMITTED_DATE = 6;
int UUID = 7;
int STATUS = 8;
int SYNC_DATE = 9;
int EXPORTED_DATE = 10;
int RECORD_ID = 11;
int SUBMITTER = 12;
}

}
44 changes: 43 additions & 1 deletion app/src/main/java/org/akvo/flow/domain/QuestionResponse.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2010-2012 Stichting Akvo (Akvo Foundation)
* Copyright (C) 2010-2015 Stichting Akvo (Akvo Foundation)
*
* This file is part of Akvo FLOW.
*
Expand All @@ -16,6 +16,8 @@

package org.akvo.flow.domain;

import org.akvo.flow.domain.response.value.CascadeValue;
import org.akvo.flow.ui.view.CascadeQuestionView;
import org.akvo.flow.util.ConstantUtil;

public class QuestionResponse {
Expand Down Expand Up @@ -161,4 +163,44 @@ public boolean hasValue() {
}
return hasVal;
}

/**
* Build a human-readable representation of the response.
* Based on the response type, this means handling and parsing each value in a different way.
*/
public String getDatapointNameValue() {
if (type == null || value == null) {
return "";
}

String name;
switch (type) {
case ConstantUtil.CASCADE_RESPONSE_TYPE:
name = getCascadeDatapointName();
break;
default:
name = value;
break;
}

name = name.replaceAll("\\s+", " ");// Trim line breaks, multiple spaces, etc
name = name.replaceAll("\\s*\\|\\s*", " - ");// Replace pipes with hyphens

return name.trim();
}

private String getCascadeDatapointName() {
StringBuilder builder = new StringBuilder();
boolean first = true;
for (CascadeValue cv : CascadeQuestionView.loadValues(value)) {
if (!first) {
builder.append(" - ");
}
builder.append(cv.getName());
first = false;
}

return builder.toString();
}

}
Loading

0 comments on commit bb08a56

Please sign in to comment.