diff --git a/api-docs/apiLive.htm b/api-docs/apiLive.htm
index 6b45552fe..655a097bd 100644
--- a/api-docs/apiLive.htm
+++ b/api-docs/apiLive.htm
@@ -15300,14 +15300,14 @@ No Request Body:
fromDate
- Date (yyyy-MM-dd)optional
+ Dateoptional
Filters for Journal entries whose entry Date
is greater than or equal to the passed in Date
toDate
- Date (yyyy-MM-dd)optional
+ Date optional
Filters for Journal entries whose entry Date
is lesser than or equal to the passed in Date
@@ -15322,7 +15322,7 @@ No Request Body:
journalentries?transactionId=PB37X8Y21EQUY4S
- journalentries?officeId=1&glAccountId=17&manualEntriesOnly=true&fromDate=2012-01-01&toDate=2013-01-01
+ journalentries?officeId=1&manualEntriesOnly=true&fromDate=1 July 2013&toDate=15 July 2013&dateFormat=dd MMMM yyyy&locale=en
journalentries?fields=officeName,glAccountName,transactionDate
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/api/DateParam.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/api/DateParam.java
index 67ba484d9..f0b051754 100755
--- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/api/DateParam.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/api/DateParam.java
@@ -5,16 +5,13 @@
*/
package org.mifosplatform.accounting.journalentry.api;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
import java.util.Date;
+import java.util.Locale;
import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
-import org.apache.commons.lang.StringUtils;
+import org.joda.time.LocalDate;
+import org.mifosplatform.infrastructure.core.serialization.JsonParserHelper;
/**
* Class for parsing dates sent as query parameters
@@ -23,23 +20,15 @@ import org.apache.commons.lang.StringUtils;
*/
public class DateParam {
- private final Date date;
+ private final String dateAsString;
public DateParam(final String dateStr) throws WebApplicationException {
- if (StringUtils.isEmpty(dateStr)) {
- this.date = null;
- return;
- }
- final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
- try {
- this.date = dateFormat.parse(dateStr);
- } catch (final ParseException e) {
- throw new WebApplicationException(Response.status(Status.BAD_REQUEST)
- .entity("Couldn't parse date string: Expected format yyyy-mm-dd " + e.getMessage()).build());
- }
+ this.dateAsString = dateStr;
}
- public Date getDate() {
- return this.date;
+ public Date getDate(String parameterName,String dateFormat, String localeAsString) {
+ Locale locale = JsonParserHelper.localeFromString(localeAsString);
+ LocalDate localDate = JsonParserHelper.convertFrom(dateAsString, parameterName, dateFormat, locale);
+ return localDate.toDate();
}
}
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/api/JournalEntriesApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/api/JournalEntriesApiResource.java
index 79ac08216..6c2217b46 100755
--- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/api/JournalEntriesApiResource.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/api/JournalEntriesApiResource.java
@@ -78,17 +78,18 @@ public class JournalEntriesApiResource {
@QueryParam("fromDate") final DateParam fromDateParam, @QueryParam("toDate") final DateParam toDateParam,
@QueryParam("transactionId") final String transactionId, @QueryParam("offset") final Integer offset,
@QueryParam("limit") final Integer limit, @QueryParam("orderBy") final String orderBy,
- @QueryParam("sortOrder") final String sortOrder) {
+ @QueryParam("sortOrder") final String sortOrder, @QueryParam("locale") final String locale,
+ @QueryParam("dateFormat") final String dateFormat) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
Date fromDate = null;
if (fromDateParam != null) {
- fromDate = fromDateParam.getDate();
+ fromDate = fromDateParam.getDate("fromDate", dateFormat, locale);
}
Date toDate = null;
if (toDateParam != null) {
- toDate = toDateParam.getDate();
+ toDate = toDateParam.getDate("toDate", dateFormat, locale);
}
final SearchParameters searchParameters = SearchParameters.forJournalEntries(officeId, offset, limit, orderBy, sortOrder);
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeWritePlatformServiceJpaRepositoryImpl.java
index 0ec156924..52807c4eb 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeWritePlatformServiceJpaRepositoryImpl.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeWritePlatformServiceJpaRepositoryImpl.java
@@ -49,12 +49,13 @@ public class CodeWritePlatformServiceJpaRepositoryImpl implements CodeWritePlatf
context.authenticatedUser();
this.fromApiJsonDeserializer.validateForCreate(command.json());
-
+
final Code code = Code.fromJson(command);
this.codeRepository.save(code);
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(code.getId()).build();
} catch (DataIntegrityViolationException dve) {
+ handleCodeDataIntegrityIssues(command, dve);
return CommandProcessingResult.empty();
}
}
@@ -65,9 +66,9 @@ public class CodeWritePlatformServiceJpaRepositoryImpl implements CodeWritePlatf
try {
context.authenticatedUser();
-
+
this.fromApiJsonDeserializer.validateForUpdate(command.json());
-
+
final Code code = retrieveCodeBy(codeId);
final Map changes = code.update(command);
@@ -112,9 +113,10 @@ public class CodeWritePlatformServiceJpaRepositoryImpl implements CodeWritePlatf
*/
private void handleCodeDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) {
Throwable realCause = dve.getMostSpecificCause();
- if (realCause.getMessage().contains("code_name_org")) {
+ if (realCause.getMessage().contains("code_name")) {
final String name = command.stringValueOfParameterNamed("name");
- throw new PlatformDataIntegrityException("error.msg.code.duplicate.name", "A code with name '" + name + "' already exists");
+ throw new PlatformDataIntegrityException("error.msg.code.duplicate.name", "A code with name '" + name + "' already exists",
+ "name", name);
}
logger.error(dve.getMessage(), dve);
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/serialization/JsonParserHelper.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/serialization/JsonParserHelper.java
index f3b51db00..50ba29431 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/serialization/JsonParserHelper.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/serialization/JsonParserHelper.java
@@ -338,7 +338,7 @@ public class JsonParserHelper {
return value;
}
- public LocalDate convertFrom(final String dateAsString, final String parameterName, final String dateFormat,
+ public static LocalDate convertFrom(final String dateAsString, final String parameterName, final String dateFormat,
final Locale clientApplicationLocale) {
if (StringUtils.isBlank(dateFormat) || clientApplicationLocale == null) {
@@ -518,6 +518,7 @@ public class JsonParserHelper {
}
}
+ /***TODO: Vishwas move all Locale related code to a separate Utils class***/
public static Locale localeFromString(final String localeAsString) {
if (StringUtils.isBlank(localeAsString)) {
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java
index 4969eaf31..01f908e12 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java
@@ -162,6 +162,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
public void registerDatatable(final String dataTableName, final String applicationTableName) {
validateAppTable(applicationTableName);
+ assertDataTableExists(dataTableName);
final String registerDatatableSql = "insert into x_registered_table (registered_table_name, application_table_name) values ('"
+ dataTableName + "', '" + applicationTableName + "')";
@@ -214,6 +215,17 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
String[] sqlArray = { registerDatatableSql, permissionsSql };
this.jdbcTemplate.batchUpdate(sqlArray);
+ }
+ /***
+ * Strangely, a Hibernate contraint violation exception is thrown
+ ****/
+ catch (ConstraintViolationException cve) {
+ Throwable realCause = cve.getCause();
+ // even if duplicate is only due to permission duplicate, okay to
+ // show duplicate datatable error msg
+ if (realCause.getMessage().contains("Duplicate entry")) { throw new PlatformDataIntegrityException(
+ "error.msg.datatable.registered", "Datatable `" + dataTableName
+ + "` is already registered against an application table.", "dataTableName", dataTableName); }
} catch (DataIntegrityViolationException dve) {
Throwable realCause = dve.getMostSpecificCause();
// even if duplicate is only due to permission duplicate, okay to
@@ -221,7 +233,6 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
if (realCause.getMessage().contains("Duplicate entry")) { throw new PlatformDataIntegrityException(
"error.msg.datatable.registered", "Datatable `" + dataTableName
+ "` is already registered against an application table.", "dataTableName", dataTableName); }
-
logAsErrorUnexpectedDataIntegrityException(dve);
throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue",
"Unknown data integrity issue with resource.");
@@ -296,6 +307,14 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
return new Boolean(isRegisteredDataTable);
}
+ private void assertDataTableExists(String datatableName) {
+ final String sql = "select if((exists (select 1 from information_schema.tables where table_schema = schema() and table_name = ?)) = 1, 'true', 'false')";
+ final String dataTableExistsString = this.jdbcTemplate.queryForObject(sql, String.class, new Object[] { datatableName });
+ final boolean dataTableExists = new Boolean(dataTableExistsString);
+ if (!dataTableExists) { throw new PlatformDataIntegrityException("error.msg.invalid.datatable", "Invalid Data Table: "
+ + datatableName, "name", datatableName); }
+ }
+
private void validateDatatableName(final String name) {
if (name == null || name.isEmpty()) {
@@ -932,7 +951,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
if (appTable.equalsIgnoreCase("m_product_loan")) return;
if (appTable.equalsIgnoreCase("m_savings_product")) return;
- throw new PlatformDataIntegrityException("error.msg.invalid.application.table", "Invalid Application Table: " + appTable);
+ throw new PlatformDataIntegrityException("error.msg.invalid.application.table", "Invalid Application Table: " + appTable, "name",
+ appTable);
}
private String mapToActualAppTable(final String appTable) {
@@ -1188,7 +1208,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
}
if (columnHeader.isDateDisplayType()) {
- final LocalDate tmpDate = helper.convertFrom(paramValue, columnHeader.getColumnName(), dateFormat, clientApplicationLocale);
+ final LocalDate tmpDate = JsonParserHelper.convertFrom(paramValue, columnHeader.getColumnName(), dateFormat,
+ clientApplicationLocale);
if (tmpDate == null) {
paramValue = null;
} else {
diff --git a/mifosng-provider/src/main/pentahoReports/Income Statement.prpt b/mifosng-provider/src/main/pentahoReports/Income Statement.prpt
index f4c88f7a2..464508a77 100644
Binary files a/mifosng-provider/src/main/pentahoReports/Income Statement.prpt and b/mifosng-provider/src/main/pentahoReports/Income Statement.prpt differ