diff --git a/src/main/java/org/commcare/core/network/CommCareNetworkServiceGenerator.java b/src/main/java/org/commcare/core/network/CommCareNetworkServiceGenerator.java index 17e0ae88ef..2568c511ad 100644 --- a/src/main/java/org/commcare/core/network/CommCareNetworkServiceGenerator.java +++ b/src/main/java/org/commcare/core/network/CommCareNetworkServiceGenerator.java @@ -140,6 +140,10 @@ public static CommCareNetworkService createNoAuthCommCareNetworkService() { return createCommCareNetworkService(null, false, true, ImmutableMultimap.of()); } + public static CommCareNetworkService createNoAuthCommCareNetworkService(Multimap params) { + return createCommCareNetworkService(null, false, true, params); + } + private static boolean isValidRedirect(HttpUrl url, HttpUrl newUrl) { // unless it's https, don't worry about it if (!url.scheme().equals("https")) { diff --git a/src/main/java/org/commcare/session/RemoteQuerySessionManager.java b/src/main/java/org/commcare/session/RemoteQuerySessionManager.java index 43f9483f67..baf2dd153c 100644 --- a/src/main/java/org/commcare/session/RemoteQuerySessionManager.java +++ b/src/main/java/org/commcare/session/RemoteQuerySessionManager.java @@ -1,5 +1,7 @@ package org.commcare.session; +import static org.commcare.suite.model.QueryPrompt.INPUT_TYPE_DATERANGE; + import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Multimap; @@ -11,6 +13,7 @@ import org.commcare.suite.model.QueryPrompt; import org.commcare.suite.model.RemoteQueryDatum; import org.commcare.suite.model.SessionDatum; +import org.commcare.util.DateRangeUtils; import org.javarosa.core.model.ItemsetBinding; import org.javarosa.core.model.condition.EvaluationContext; import org.javarosa.core.model.instance.ExternalDataInstance; @@ -19,6 +22,7 @@ import org.javarosa.core.model.instance.TreeReference; import org.javarosa.core.model.instance.utils.TreeUtilities; import org.javarosa.core.model.utils.ItemSetUtils; +import org.javarosa.core.services.Logger; import org.javarosa.core.util.OrderedHashtable; import org.javarosa.model.xform.XPathReference; import org.javarosa.xml.util.InvalidStructureException; @@ -31,6 +35,7 @@ import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.text.ParseException; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; @@ -74,8 +79,15 @@ private void initUserAnswers() throws XPathException { QueryPrompt prompt = queryPrompts.get(promptId); if (isPromptSupported(prompt) && prompt.getDefaultValueExpr() != null) { - userAnswers.put(prompt.getKey(), - FunctionUtils.toString(prompt.getDefaultValueExpr().eval(evaluationContext))); + String value = FunctionUtils.toString(prompt.getDefaultValueExpr().eval(evaluationContext)); + if(INPUT_TYPE_DATERANGE.equals(prompt.getInput())){ + try { + value = DateRangeUtils.formatDateRangeAnswer(value); + } catch (ParseException e) { + Logger.exception("Error parsing default date range " + value + " for " + promptId, e); + } + } + userAnswers.put(prompt.getKey(), value); } } } diff --git a/src/main/java/org/commcare/util/DateRangeUtils.java b/src/main/java/org/commcare/util/DateRangeUtils.java new file mode 100644 index 0000000000..0d528f3ddd --- /dev/null +++ b/src/main/java/org/commcare/util/DateRangeUtils.java @@ -0,0 +1,81 @@ +package org.commcare.util; + +import org.commcare.modern.util.Pair; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +import javax.annotation.Nullable; + +public class DateRangeUtils { + + // Changing this will require changing this format on ES end as well + public static final String DATE_RANGE_ANSWER_PREFIX = "__range__"; + public static final String DATE_RANGE_ANSWER_DELIMITER = "__"; + public static final String DATE_RANGE_ANSWER_HUMAN_READABLE_DELIMITER = " to "; + private static final String DATE_FORMAT = "yyyy-MM-dd"; + + /** + * @param humanReadableDateRange human readable fomat for date range as 'startDate to endDate' + * @return a Pair of start time and end time that can be supplied to MaterialDatePicker to set a date range, + * @throws ParseException if the given humanReadableDateRange is not in 'yyyy-mm-dd to yyyy-mm-dd' format + */ + @Nullable + public static Pair parseHumanReadableDate(String humanReadableDateRange) throws ParseException { + if (humanReadableDateRange.contains(DATE_RANGE_ANSWER_HUMAN_READABLE_DELIMITER)) { + String[] humanReadableDateRangeSplit = humanReadableDateRange.split(DATE_RANGE_ANSWER_HUMAN_READABLE_DELIMITER); + if (humanReadableDateRangeSplit.length == 2) { + SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT, Locale.US); + Date startDate = sdf.parse(humanReadableDateRangeSplit[0]); + Date endDate = sdf.parse(humanReadableDateRangeSplit[1]); + return new Pair<>(getTimeFromDateOffsettingTz(startDate), getTimeFromDateOffsettingTz(endDate)); + } + } + throw new ParseException("Argument " + humanReadableDateRange + " should be formatted as 'yyyy-mm-dd to yyyy-mm-dd'", 0); + } + + private static Long getTimeFromDateOffsettingTz(Date date) { + return date.getTime() - date.getTimezoneOffset() * 60 * 1000; + } + + /** + * Formats __range__startDate__endDate as 'startDate to EndDate' + * + * @param dateRangeAnswer A date range value in form of '__range__startDate__endDate' + * @return human readable format 'startDate to EndDate' for given dateRangeAnswer + */ + public static String getHumanReadableDateRange(String dateRangeAnswer) { + if (dateRangeAnswer != null && dateRangeAnswer.startsWith(DATE_RANGE_ANSWER_PREFIX)) { + String[] dateRangeSplit = dateRangeAnswer.split(DATE_RANGE_ANSWER_DELIMITER); + if (dateRangeSplit.length == 4) { + return getHumanReadableDateRange(dateRangeSplit[2], dateRangeSplit[3]); + } + } + return dateRangeAnswer; + } + + + // Formats as 'startDate to endDate' + public static String getHumanReadableDateRange(String startDate, String endDate) { + return startDate + DATE_RANGE_ANSWER_HUMAN_READABLE_DELIMITER + endDate; + } + + // Formats as '__range__startDate__endDate' + public static String formatDateRangeAnswer(String startDate, String endDate) { + return DATE_RANGE_ANSWER_PREFIX + startDate + DATE_RANGE_ANSWER_DELIMITER + endDate; + } + + public static String formatDateRangeAnswer(String humanReadableDateRange) throws ParseException { + Pair selection = DateRangeUtils.parseHumanReadableDate(humanReadableDateRange); + String startDate = DateRangeUtils.getDateFromTime(selection.first); + String endDate = DateRangeUtils.getDateFromTime(selection.second); + return DATE_RANGE_ANSWER_PREFIX + startDate + DATE_RANGE_ANSWER_DELIMITER + endDate; + } + + // Convers given time as yyyy-mm-dd + public static String getDateFromTime(Long time) { + return new SimpleDateFormat(DATE_FORMAT, Locale.US).format(new Date(time)); + } +} diff --git a/src/main/java/org/commcare/util/LogTypes.java b/src/main/java/org/commcare/util/LogTypes.java index 9bd387fb8a..1b5c34bb41 100644 --- a/src/main/java/org/commcare/util/LogTypes.java +++ b/src/main/java/org/commcare/util/LogTypes.java @@ -113,4 +113,7 @@ public class LogTypes { * Logs related to Firebase Cloud Messaging */ public static final String TYPE_FCM = "fcm"; + + public static final String TYPE_MEDIA_EVENT = "media-event"; + } diff --git a/src/test/java/org/commcare/util/DateRangeUtilsTest.java b/src/test/java/org/commcare/util/DateRangeUtilsTest.java new file mode 100644 index 0000000000..e46ac253b1 --- /dev/null +++ b/src/test/java/org/commcare/util/DateRangeUtilsTest.java @@ -0,0 +1,18 @@ +package org.commcare.util; + +import junit.framework.TestCase; + +import org.junit.Test; + +import java.text.ParseException; + +public class DateRangeUtilsTest extends TestCase { + + @Test + public void testDateConversion() throws ParseException { + String dateRange = "2020-02-15 to 2021-03-18"; + String formattedDateRange = DateRangeUtils.formatDateRangeAnswer(dateRange); + assertEquals("__range__2020-02-15__2021-03-18", formattedDateRange); + assertEquals(dateRange, DateRangeUtils.getHumanReadableDateRange(formattedDateRange)); + } +}