MIFOSX-237: ensure big decimal entries are compared correctly and only transactions with changes are audited.
This commit is contained in:
+14
-10
@@ -8435,10 +8435,7 @@ Request Body:
|
||||
<div class="method-description">
|
||||
<h4>Delete Entry(s) in Data Table</h4>
|
||||
<p>
|
||||
Deletes the entry (if it exists) for data tables that are one to
|
||||
one with the application table. <br> Deletes the entries (if
|
||||
they exist) for data tables that are one to many with the
|
||||
application table.
|
||||
Deletes the entry (if it exists) for data tables that are one-to-one with the application table. <br> Deletes the entries (if they exist) for data tables that are one-to-many with the application table.
|
||||
</p>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
@@ -8446,14 +8443,17 @@ Request Body:
|
||||
DELETE https://DomainName/api/v1/datatables/{datatable}/{apptableId}
|
||||
</code>
|
||||
<code class="method-request">
|
||||
DELETE datatables/Additional Client Fields Data/1
|
||||
DELETE datatables/extra_client_details/1
|
||||
|
||||
Content-Type: application/json
|
||||
|
||||
Request Body:
|
||||
{}
|
||||
</code>
|
||||
<code class="method-response">{ "resourceId": 1 } </code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"resourceId": 1
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -8461,7 +8461,7 @@ Request Body:
|
||||
class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Delete Entry in Data Table (One to Many)</h4>
|
||||
<h4>Delete Entry in Datatable (One to Many)</h4>
|
||||
<p>Deletes the entry (if it exists) for data tables that are
|
||||
one to many with the application table.</p>
|
||||
</div>
|
||||
@@ -8470,13 +8470,17 @@ Request Body:
|
||||
DELETE https://DomainName/api/v1/datatables/{datatable}/{apptableId}/{datatableId}
|
||||
</code>
|
||||
<code class="method-request">
|
||||
DELETE datatables/Extra Family Details Data/1/2
|
||||
DELETE datatables/extra_family_details/1/2
|
||||
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{}
|
||||
</code>
|
||||
<code class="method-response">{ "resourceId": 1 } </code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"resourceId": 1
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end of datatables api docs -->
|
||||
|
||||
+3
-3
@@ -23,8 +23,8 @@ public class CommandWrapper {
|
||||
private final Long datatableId;
|
||||
private final Long codeId;
|
||||
private final String transactionId;
|
||||
private String supportedEntityType;
|
||||
private Long supportedEntityId;
|
||||
private final String supportedEntityType;
|
||||
private final Long supportedEntityId;
|
||||
|
||||
public static CommandWrapper wrap(final String actionName, final String enityName, final Long resourceId) {
|
||||
return new CommandWrapper(null, actionName, enityName, resourceId);
|
||||
@@ -163,7 +163,7 @@ public class CommandWrapper {
|
||||
|| (isUpdateOperation() && this.entityId != null);
|
||||
}
|
||||
|
||||
private boolean isUpdateOperation() {
|
||||
public boolean isUpdateOperation() {
|
||||
return this.actionName.equalsIgnoreCase("UPDATE");
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -77,7 +77,7 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
|
||||
commandSourceResult.updateJsonTo(changesOnlyJson);
|
||||
}
|
||||
|
||||
if (!result.hasChanges() && wrapper.isUpdate()) {
|
||||
if (!result.hasChanges() && wrapper.isUpdateOperation()) {
|
||||
commandSourceResult.updateJsonTo(null);
|
||||
}
|
||||
|
||||
|
||||
+18
-9
@@ -79,7 +79,6 @@ public class DatatablesApiResource {
|
||||
this.readWriteNonCoreDataService.registerDatatable(datatable, apptable);
|
||||
|
||||
final CommandProcessingResult result = new CommandProcessingResultBuilder().withResourceIdAsString(datatable).build();
|
||||
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
|
||||
@@ -151,8 +150,10 @@ public class DatatablesApiResource {
|
||||
public String createDatatableEntry(@PathParam("datatable") final String datatable, @PathParam("apptableId") final Long apptableId,
|
||||
final String apiRequestBodyAsJson) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().createDatatable(datatable, apptableId, null)
|
||||
.withJson(apiRequestBodyAsJson).build();
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder() //
|
||||
.createDatatable(datatable, apptableId, null) //
|
||||
.withJson(apiRequestBodyAsJson) //
|
||||
.build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
@@ -166,8 +167,10 @@ public class DatatablesApiResource {
|
||||
public String updateDatatableEntryOnetoOne(@PathParam("datatable") final String datatable,
|
||||
@PathParam("apptableId") final Long apptableId, final String apiRequestBodyAsJson) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateDatatable(datatable, apptableId, null)
|
||||
.withJson(apiRequestBodyAsJson).build();
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder() //
|
||||
.updateDatatable(datatable, apptableId, null) //
|
||||
.withJson(apiRequestBodyAsJson) //
|
||||
.build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
@@ -182,8 +185,10 @@ public class DatatablesApiResource {
|
||||
@PathParam("apptableId") final Long apptableId, @PathParam("datatableId") final Long datatableId,
|
||||
final String apiRequestBodyAsJson) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateDatatable(datatable, apptableId, datatableId)
|
||||
.withJson(apiRequestBodyAsJson).build();
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder() //
|
||||
.updateDatatable(datatable, apptableId, datatableId) //
|
||||
.withJson(apiRequestBodyAsJson) //
|
||||
.build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
@@ -196,7 +201,9 @@ public class DatatablesApiResource {
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String deleteDatatableEntries(@PathParam("datatable") final String datatable, @PathParam("apptableId") final Long apptableId) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteDatatable(datatable, apptableId, null).build();
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder() //
|
||||
.deleteDatatable(datatable, apptableId, null) //
|
||||
.build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
@@ -210,7 +217,9 @@ public class DatatablesApiResource {
|
||||
public String deleteDatatableEntries(@PathParam("datatable") final String datatable, @PathParam("apptableId") final Long apptableId,
|
||||
@PathParam("datatableId") final Long datatableId) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteDatatable(datatable, apptableId, datatableId).build();
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder() //
|
||||
.deleteDatatable(datatable, apptableId, datatableId) //
|
||||
.build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
|
||||
+25
-1
@@ -11,7 +11,7 @@ import java.util.List;
|
||||
/**
|
||||
* Immutable data object for generic resultset data.
|
||||
*/
|
||||
public class GenericResultsetData {
|
||||
public final class GenericResultsetData {
|
||||
|
||||
private final List<ResultsetColumnHeaderData> columnHeaders;
|
||||
private final List<ResultsetRowData> data;
|
||||
@@ -28,4 +28,28 @@ public class GenericResultsetData {
|
||||
public List<ResultsetRowData> getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public String getColTypeOfColumnNamed(final String columnName) {
|
||||
|
||||
String colType = null;
|
||||
for (ResultsetColumnHeaderData columnHeader : this.columnHeaders) {
|
||||
if (columnHeader.isNamed(columnName)) {
|
||||
colType = columnHeader.getColumnType();
|
||||
}
|
||||
}
|
||||
|
||||
return colType;
|
||||
}
|
||||
|
||||
public boolean hasNoEntries() {
|
||||
return this.data.isEmpty();
|
||||
}
|
||||
|
||||
public boolean hasEntries() {
|
||||
return !hasNoEntries();
|
||||
}
|
||||
|
||||
public boolean hasMoreThanOneEntry() {
|
||||
return this.data.size() > 1;
|
||||
}
|
||||
}
|
||||
+4
@@ -80,6 +80,10 @@ public final class ResultsetColumnHeaderData {
|
||||
this.columnDisplayType = displayType;
|
||||
}
|
||||
|
||||
public boolean isNamed(final String columnName) {
|
||||
return this.columnName.equalsIgnoreCase(columnName);
|
||||
}
|
||||
|
||||
private boolean isAnyText() {
|
||||
return isText() || isTinyText() || isMediumText() || isLongText();
|
||||
}
|
||||
|
||||
+4
-1
@@ -30,6 +30,9 @@ public class DeleteOneToOneDatatableEntryCommandHandler implements NewCommandSou
|
||||
|
||||
this.writePlatformService.deleteDatatableEntries(command.entityName(), command.getApptableId());
|
||||
|
||||
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(command.getApptableId()).build();
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
.withEntityId(command.getApptableId()) //
|
||||
.build();
|
||||
}
|
||||
}
|
||||
+33
-30
@@ -242,29 +242,26 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
@Override
|
||||
public Map<String, Object> updateDatatableEntryOneToOne(final String datatable, final Long appTableId, final JsonCommand command) {
|
||||
|
||||
GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable, appTableId, null, null);
|
||||
final GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable, appTableId, null, null);
|
||||
|
||||
if (grs.getData().size() == 0) throw new DatatableNotFoundException(datatable, appTableId);
|
||||
if (grs.hasNoEntries()) { throw new DatatableNotFoundException(datatable, appTableId); }
|
||||
|
||||
if (grs.getData().size() > 1)
|
||||
throw new PlatformDataIntegrityException("error.msg.attempting.multiple.update", "Application Table: " + datatable
|
||||
+ " Foreign Key Id: " + appTableId);
|
||||
if (grs.hasMoreThanOneEntry()) { throw new PlatformDataIntegrityException("error.msg.attempting.multiple.update",
|
||||
"Application table: " + datatable + " Foreign key id: " + appTableId); }
|
||||
|
||||
String fkName = getFKField(queryForApplicationTableName(datatable));
|
||||
final String fkName = getFKField(queryForApplicationTableName(datatable));
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
|
||||
Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(typeOfMap, command.json());
|
||||
|
||||
final Map<String, Object> changes = getAffectedAndChangedColumns(grs, dataParams, fkName);
|
||||
|
||||
if (changes.size() == 0) return changes;
|
||||
if (!changes.isEmpty()) {
|
||||
final String updateOneToOneDatatableSql = getUpdateSql(datatable, fkName, appTableId, changes);
|
||||
|
||||
final String sql = getUpdateSql(datatable, fkName, appTableId, changes);
|
||||
|
||||
if (StringUtils.isNotBlank(sql)) {
|
||||
this.jdbcTemplate.update(sql);
|
||||
} else {
|
||||
logger.info("No Changes");
|
||||
if (StringUtils.isNotBlank(updateOneToOneDatatableSql)) {
|
||||
this.jdbcTemplate.update(updateOneToOneDatatableSql);
|
||||
}
|
||||
}
|
||||
|
||||
return changes;
|
||||
@@ -301,9 +298,10 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
|
||||
final String appTable = getWithinScopeApplicationTableName(datatable, appTableId);
|
||||
|
||||
final String sql = getDeleteEntriesSql(datatable, getFKField(appTable), appTableId);
|
||||
final String deleteOneToOneEntrySql = getDeleteEntriesSql(datatable, getFKField(appTable), appTableId);
|
||||
|
||||
this.jdbcTemplate.update(sql);
|
||||
int rowsDeleted = this.jdbcTemplate.update(deleteOneToOneEntrySql);
|
||||
if (rowsDeleted < 1) { throw new DatatableNotFoundException(datatable, appTableId); }
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -334,9 +332,11 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
sql = sql + "select * from `" + datatable + "` where id = " + id;
|
||||
}
|
||||
|
||||
if (order != null) sql = sql + " order by " + order;
|
||||
if (order != null) {
|
||||
sql = sql + " order by " + order;
|
||||
}
|
||||
|
||||
List<ResultsetRowData> result = fillDatatableResultSetDataRows(sql);
|
||||
final List<ResultsetRowData> result = fillDatatableResultSetDataRows(sql);
|
||||
|
||||
return new GenericResultsetData(columnHeaders, result);
|
||||
}
|
||||
@@ -513,13 +513,13 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
private Map<String, Object> getAffectedAndChangedColumns(final GenericResultsetData grs, final Map<String, String> queryParams,
|
||||
final String fkName) {
|
||||
|
||||
Map<String, String> affectedColumns = getAffectedColumns(grs.getColumnHeaders(), queryParams, fkName);
|
||||
Map<String, Object> affectedAndChangedColumns = new HashMap<String, Object>();
|
||||
String columnValue;
|
||||
final Map<String, String> affectedColumns = getAffectedColumns(grs.getColumnHeaders(), queryParams, fkName);
|
||||
final Map<String, Object> affectedAndChangedColumns = new HashMap<String, Object>();
|
||||
|
||||
for (String key : affectedColumns.keySet()) {
|
||||
columnValue = affectedColumns.get(key);
|
||||
if (columnChanged(key, columnValue, grs)) {
|
||||
for (final String key : affectedColumns.keySet()) {
|
||||
final String columnValue = affectedColumns.get(key);
|
||||
final String colType = grs.getColTypeOfColumnNamed(key);
|
||||
if (columnChanged(key, columnValue, colType, grs)) {
|
||||
affectedAndChangedColumns.put(key, columnValue);
|
||||
}
|
||||
}
|
||||
@@ -527,7 +527,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
return affectedAndChangedColumns;
|
||||
}
|
||||
|
||||
private boolean columnChanged(final String key, final String keyValue, final GenericResultsetData grs) {
|
||||
private boolean columnChanged(final String key, final String keyValue, final String colType, final GenericResultsetData grs) {
|
||||
|
||||
List<String> columnValues = grs.getData().get(0).getRow();
|
||||
|
||||
@@ -537,12 +537,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
if (key.equals(grs.getColumnHeaders().get(i).getColumnName())) {
|
||||
columnValue = columnValues.get(i);
|
||||
|
||||
if (notTheSame(columnValue, keyValue)) {
|
||||
// logger.info("Difference - Column: " + key +
|
||||
// "- Current Value: " + columnValue + " New Value: " +
|
||||
// keyValue);
|
||||
if (notTheSame(columnValue, keyValue, colType)) {
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -691,13 +687,20 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
|
||||
}
|
||||
|
||||
private boolean notTheSame(final String currValue, final String pValue) {
|
||||
private boolean notTheSame(final String currValue, final String pValue, final String colType) {
|
||||
if (StringUtils.isEmpty(currValue) && StringUtils.isEmpty(pValue)) return false;
|
||||
|
||||
if (StringUtils.isEmpty(currValue)) return true;
|
||||
|
||||
if (StringUtils.isEmpty(pValue)) return true;
|
||||
|
||||
if ("DECIMAL".equalsIgnoreCase(colType)) {
|
||||
final BigDecimal currentDecimal = BigDecimal.valueOf(Double.valueOf(currValue));
|
||||
final BigDecimal newDecimal = BigDecimal.valueOf(Double.valueOf(pValue));
|
||||
|
||||
return currentDecimal.compareTo(newDecimal) != 0;
|
||||
}
|
||||
|
||||
if (currValue.equals(pValue)) return false;
|
||||
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user