Check for required fields

This commit is contained in:
2023-03-30 11:55:36 -05:00
parent f6f2cb7070
commit a9e793dfb8
2 changed files with 111 additions and 3 deletions

View File

@ -25,6 +25,7 @@ package com.kingsrook.qqq.backend.core.actions.tables;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import com.kingsrook.qqq.backend.core.actions.ActionHelper;
import com.kingsrook.qqq.backend.core.actions.audits.DMLAuditAction;
@ -48,6 +49,7 @@ import com.kingsrook.qqq.backend.core.model.actions.tables.update.UpdateInput;
import com.kingsrook.qqq.backend.core.model.actions.tables.update.UpdateOutput;
import com.kingsrook.qqq.backend.core.model.data.QRecord;
import com.kingsrook.qqq.backend.core.model.metadata.audits.AuditLevel;
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.joins.JoinOn;
import com.kingsrook.qqq.backend.core.model.metadata.joins.QJoinMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.tables.Association;
@ -83,10 +85,19 @@ public class UpdateAction
QBackendModuleDispatcher qBackendModuleDispatcher = new QBackendModuleDispatcher();
QBackendModuleInterface qModule = qBackendModuleDispatcher.getQBackendModule(updateInput.getBackend());
validateRequiredFields(updateInput);
// todo pre-customization - just get to modify the request?
UpdateOutput updateResult = qModule.getUpdateInterface().execute(updateInput);
UpdateOutput updateOutput = qModule.getUpdateInterface().execute(updateInput);
// todo post-customization - can do whatever w/ the result if you want
List<String> errors = updateOutput.getRecords().stream().flatMap(r -> r.getErrors().stream()).toList();
if(CollectionUtils.nullSafeHasContents(errors))
{
LOG.warn("Errors in updateAction", logPair("tableName", updateInput.getTableName()), logPair("errorCount", errors.size()), errors.size() < 10 ? logPair("errors", errors) : logPair("first10Errors", errors.subList(0, 10)));
}
manageAssociations(updateInput);
if(updateInput.getOmitDmlAudit())
@ -95,10 +106,43 @@ public class UpdateAction
}
else
{
new DMLAuditAction().execute(new DMLAuditInput().withTableActionInput(updateInput).withRecordList(updateResult.getRecords()).withOldRecordList(oldRecordList));
new DMLAuditAction().execute(new DMLAuditInput().withTableActionInput(updateInput).withRecordList(updateOutput.getRecords()).withOldRecordList(oldRecordList));
}
return updateResult;
return updateOutput;
}
/*******************************************************************************
**
*******************************************************************************/
private void validateRequiredFields(UpdateInput updateInput)
{
QTableMetaData table = updateInput.getTable();
Set<QFieldMetaData> requiredFields = table.getFields().values().stream()
.filter(f -> f.getIsRequired())
.collect(Collectors.toSet());
if(!requiredFields.isEmpty())
{
for(QRecord record : updateInput.getRecords())
{
for(QFieldMetaData requiredField : requiredFields)
{
/////////////////////////////////////////////////////////////////////////////////////////////
// only consider fields that were set in the record to be updated (e.g., "patch" semantic) //
/////////////////////////////////////////////////////////////////////////////////////////////
if(record.getValues().containsKey(requiredField.getName()))
{
if(record.getValue(requiredField.getName()) == null || (requiredField.getType().isStringLike() && record.getValueString(requiredField.getName()).trim().equals("")))
{
record.addError("Missing value in required field: " + requiredField.getLabel());
}
}
}
}
}
}

View File

@ -22,12 +22,14 @@
package com.kingsrook.qqq.backend.core.actions.tables;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import com.kingsrook.qqq.backend.core.BaseTest;
import com.kingsrook.qqq.backend.core.context.QContext;
import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertInput;
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertOutput;
import com.kingsrook.qqq.backend.core.model.actions.tables.update.UpdateInput;
import com.kingsrook.qqq.backend.core.model.actions.tables.update.UpdateOutput;
import com.kingsrook.qqq.backend.core.model.data.QRecord;
@ -333,4 +335,66 @@ class UpdateActionTest extends BaseTest
));
new InsertAction().execute(insertInput);
}
/*******************************************************************************
**
*******************************************************************************/
@Test
void testRequiredFields() throws QException
{
QInstance qInstance = QContext.getQInstance();
qInstance.getTable(TestUtils.TABLE_NAME_ORDER).getField("orderNo").setIsRequired(true);
QContext.getQSession().withSecurityKeyValue(TestUtils.SECURITY_KEY_TYPE_STORE_ALL_ACCESS, true);
///////////////////////////////////////////////////
// insert records that we'll later try to update //
///////////////////////////////////////////////////
InsertInput insertInput = new InsertInput();
insertInput.setTableName(TestUtils.TABLE_NAME_ORDER);
insertInput.setRecords(List.of(
new QRecord().withValue("id", 1).withValue("storeId", 999).withValue("orderNo", "ORD1"),
new QRecord().withValue("id", 2).withValue("storeId", 999).withValue("orderNo", "ORD2"),
new QRecord().withValue("id", 3).withValue("storeId", 999).withValue("orderNo", "ORD3"),
new QRecord().withValue("id", 4).withValue("storeId", 999).withValue("orderNo", "ORD4")
));
InsertOutput insertOutput = new InsertAction().execute(insertInput);
//////////////////////////////////////////////////
// do our update that we'll test the results of //
//////////////////////////////////////////////////
UpdateInput updateInput = new UpdateInput();
updateInput.setTableName(TestUtils.TABLE_NAME_ORDER);
updateInput.setRecords(List.of(
new QRecord().withValue("id", 1).withValue("orderNo", null),
new QRecord().withValue("id", 2).withValue("total", new BigDecimal("3.50")),
new QRecord().withValue("id", 3).withValue("orderNo", "ORD3B"),
new QRecord().withValue("id", 4).withValue("orderNo", " ")
));
UpdateOutput updateOutput = new UpdateAction().execute(updateInput);
////////////////////////////////////////////////////////////////
// 1st record tried to set a null orderNo - assert it errored //
////////////////////////////////////////////////////////////////
assertEquals(1, updateOutput.getRecords().get(0).getErrors().size());
assertEquals("Missing value in required field: Order No", updateOutput.getRecords().get(0).getErrors().get(0));
////////////////////////////////////////////////////////////////
// 2nd record didn't try to change orderNo, so should be fine //
////////////////////////////////////////////////////////////////
assertEquals(0, updateOutput.getRecords().get(1).getErrors().size());
///////////////////////////////////////////////////////////////////
// 3rd record should have actually set a new order no - no error //
///////////////////////////////////////////////////////////////////
assertEquals(0, updateOutput.getRecords().get(2).getErrors().size());
///////////////////////////////////////////////////////////////////////
// 4th record tried to set orderNo to all spaces - assert it errored //
///////////////////////////////////////////////////////////////////////
assertEquals(1, updateOutput.getRecords().get(3).getErrors().size());
assertEquals("Missing value in required field: Order No", updateOutput.getRecords().get(3).getErrors().get(0));
}
}