Merge pull request #451 from vishwasbabu/mifosx-500

bug fixes for mifosx-519, 516, 361 and 362
This commit is contained in:
Vishwas Babu A J
2013-07-12 06:20:05 -07:00
7 changed files with 49 additions and 35 deletions
+3 -3
View File
@@ -15300,14 +15300,14 @@ No Request Body:
</dd> </dd>
<dt>fromDate</dt> <dt>fromDate</dt>
<dd> <dd>
Date (yyyy-MM-dd)<span>optional</span> Date<span>optional</span>
</dd> </dd>
<dd>Filters for Journal entries whose entry Date <dd>Filters for Journal entries whose entry Date
is greater than or equal to the passed in Date is greater than or equal to the passed in Date
</dd> </dd>
<dt>toDate</dt> <dt>toDate</dt>
<dd> <dd>
Date (yyyy-MM-dd)<span>optional</span> Date <span>optional</span>
</dd> </dd>
<dd>Filters for Journal entries whose entry Date <dd>Filters for Journal entries whose entry Date
is lesser than or equal to the passed in Date is lesser than or equal to the passed in Date
@@ -15322,7 +15322,7 @@ No Request Body:
<br> <br>
<div class=apiClick>journalentries?transactionId=PB37X8Y21EQUY4S</div> <div class=apiClick>journalentries?transactionId=PB37X8Y21EQUY4S</div>
<br> <br>
<div class=apiClick>journalentries?officeId=1&glAccountId=17&manualEntriesOnly=true&fromDate=2012-01-01&toDate=2013-01-01</div> <div class=apiClick>journalentries?officeId=1&manualEntriesOnly=true&fromDate=1 July 2013&toDate=15 July 2013&dateFormat=dd MMMM yyyy&locale=en</div>
<br> <br>
<div class=apiClick>journalentries?fields=officeName,glAccountName,transactionDate</div> <div class=apiClick>journalentries?fields=officeName,glAccountName,transactionDate</div>
<br> <br>
@@ -5,16 +5,13 @@
*/ */
package org.mifosplatform.accounting.journalentry.api; 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.Date;
import java.util.Locale;
import javax.ws.rs.WebApplicationException; 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 * Class for parsing dates sent as query parameters
@@ -23,23 +20,15 @@ import org.apache.commons.lang.StringUtils;
*/ */
public class DateParam { public class DateParam {
private final Date date; private final String dateAsString;
public DateParam(final String dateStr) throws WebApplicationException { public DateParam(final String dateStr) throws WebApplicationException {
if (StringUtils.isEmpty(dateStr)) { this.dateAsString = 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());
}
} }
public Date getDate() { public Date getDate(String parameterName,String dateFormat, String localeAsString) {
return this.date; Locale locale = JsonParserHelper.localeFromString(localeAsString);
LocalDate localDate = JsonParserHelper.convertFrom(dateAsString, parameterName, dateFormat, locale);
return localDate.toDate();
} }
} }
@@ -78,17 +78,18 @@ public class JournalEntriesApiResource {
@QueryParam("fromDate") final DateParam fromDateParam, @QueryParam("toDate") final DateParam toDateParam, @QueryParam("fromDate") final DateParam fromDateParam, @QueryParam("toDate") final DateParam toDateParam,
@QueryParam("transactionId") final String transactionId, @QueryParam("offset") final Integer offset, @QueryParam("transactionId") final String transactionId, @QueryParam("offset") final Integer offset,
@QueryParam("limit") final Integer limit, @QueryParam("orderBy") final String orderBy, @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); this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
Date fromDate = null; Date fromDate = null;
if (fromDateParam != null) { if (fromDateParam != null) {
fromDate = fromDateParam.getDate(); fromDate = fromDateParam.getDate("fromDate", dateFormat, locale);
} }
Date toDate = null; Date toDate = null;
if (toDateParam != null) { if (toDateParam != null) {
toDate = toDateParam.getDate(); toDate = toDateParam.getDate("toDate", dateFormat, locale);
} }
final SearchParameters searchParameters = SearchParameters.forJournalEntries(officeId, offset, limit, orderBy, sortOrder); final SearchParameters searchParameters = SearchParameters.forJournalEntries(officeId, offset, limit, orderBy, sortOrder);
@@ -55,6 +55,7 @@ public class CodeWritePlatformServiceJpaRepositoryImpl implements CodeWritePlatf
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(code.getId()).build(); return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(code.getId()).build();
} catch (DataIntegrityViolationException dve) { } catch (DataIntegrityViolationException dve) {
handleCodeDataIntegrityIssues(command, dve);
return CommandProcessingResult.empty(); return CommandProcessingResult.empty();
} }
} }
@@ -112,9 +113,10 @@ public class CodeWritePlatformServiceJpaRepositoryImpl implements CodeWritePlatf
*/ */
private void handleCodeDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) { private void handleCodeDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) {
Throwable realCause = dve.getMostSpecificCause(); Throwable realCause = dve.getMostSpecificCause();
if (realCause.getMessage().contains("code_name_org")) { if (realCause.getMessage().contains("code_name")) {
final String name = command.stringValueOfParameterNamed("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); logger.error(dve.getMessage(), dve);
@@ -338,7 +338,7 @@ public class JsonParserHelper {
return value; 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) { final Locale clientApplicationLocale) {
if (StringUtils.isBlank(dateFormat) || clientApplicationLocale == null) { 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) { public static Locale localeFromString(final String localeAsString) {
if (StringUtils.isBlank(localeAsString)) { if (StringUtils.isBlank(localeAsString)) {
@@ -162,6 +162,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
public void registerDatatable(final String dataTableName, final String applicationTableName) { public void registerDatatable(final String dataTableName, final String applicationTableName) {
validateAppTable(applicationTableName); validateAppTable(applicationTableName);
assertDataTableExists(dataTableName);
final String registerDatatableSql = "insert into x_registered_table (registered_table_name, application_table_name) values ('" final String registerDatatableSql = "insert into x_registered_table (registered_table_name, application_table_name) values ('"
+ dataTableName + "', '" + applicationTableName + "')"; + dataTableName + "', '" + applicationTableName + "')";
@@ -214,6 +215,17 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
String[] sqlArray = { registerDatatableSql, permissionsSql }; String[] sqlArray = { registerDatatableSql, permissionsSql };
this.jdbcTemplate.batchUpdate(sqlArray); 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) { } catch (DataIntegrityViolationException dve) {
Throwable realCause = dve.getMostSpecificCause(); Throwable realCause = dve.getMostSpecificCause();
// even if duplicate is only due to permission duplicate, okay to // 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( if (realCause.getMessage().contains("Duplicate entry")) { throw new PlatformDataIntegrityException(
"error.msg.datatable.registered", "Datatable `" + dataTableName "error.msg.datatable.registered", "Datatable `" + dataTableName
+ "` is already registered against an application table.", "dataTableName", dataTableName); } + "` is already registered against an application table.", "dataTableName", dataTableName); }
logAsErrorUnexpectedDataIntegrityException(dve); logAsErrorUnexpectedDataIntegrityException(dve);
throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue", throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue",
"Unknown data integrity issue with resource."); "Unknown data integrity issue with resource.");
@@ -296,6 +307,14 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
return new Boolean(isRegisteredDataTable); 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) { private void validateDatatableName(final String name) {
if (name == null || name.isEmpty()) { 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_product_loan")) return;
if (appTable.equalsIgnoreCase("m_savings_product")) 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) { private String mapToActualAppTable(final String appTable) {
@@ -1188,7 +1208,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
} }
if (columnHeader.isDateDisplayType()) { 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) { if (tmpDate == null) {
paramValue = null; paramValue = null;
} else { } else {