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