- Design Doc
- Implement a new ViolationUtils lib (src/libs/ViolationUtils.js or src/libs/ViolationUtils.ts)
- Add a method
getViolationForField(object transactionViolation, string field) : string
getViolationForField will check transactionViolation and return an an array of strings with the translated copies of the violations for that field, eg
- When field is ‘category’, the method will pull the violations that apply to the category field, and then call translate on the violation names, like
missingCategory and return that
- See code example below
- Add a method
getViolationsOnyxData(Transaction transaction, object transactionViolations, bool policyRequiresTags, object[] policyTags, bool policyRequiresCategories, object[] policyCategories) that calculates the new transaction violations (by adding/removing those that have been addressed with the current user changes), and returns an object that we can save into onyx. The updatedTransactionViolations variable shown in the code snippet below will be set like so:
- If
policyRequiresCategories === true, the transactionViolations array doesn't have one with name: categoryOutOfPolicy and the passed transaction contains a category, and the policyCategories collection doesn’t have that category with its enabled value set to true, then it’ll add the object {‘name’:’categoryOutOfPolicy’, ‘type’: ‘violation’} to updatedTransactionViolations
- If
policyRequiresCategories === true, the passed transaction contains a category that is enabled in the policy, and the onyx data had a missingCategory violation, we’ll clear it from updatedTransactionViolations using _.reject(transactionViolations, e => e.name === 'missingCategory')
- If
policyRequiresTag === true, the transactionViolations array doesn't have one with name: tagOutOfPolicy and the passed transaction contains a tag, and the policyTags collection doesn’t have that tag with its enabled value set to true, then it’ll add the object {‘name’:’categoryOutOfPolicy’, ‘type’: ‘violation’} to updatedTransactionViolations
- If
policyRequiresTag === true, the passed transaction contains a tag that is enabled in the policy, and the onyx data had a missingTag violation, we’ll clear it from updatedTransactionViolations using `_.reject(transactionViolations, e => e.name === 'missingTag')
- Add
const formFields = {merchant: 'merchant', amount: 'amount', category: 'category', ...}
- Add a
const violationField = {missingCategory: 'category', categoryOutOfPolicy: 'category', ...} with a mapping of violation names to the name of the field where the violation is shown (more in code snippet below
- Feel free to add dummy translations to the EN and ES files for now for the violations
function getViolationForField(transactionViolations, field) {
const {translate} = useLocalize();
const fieldViolations = _.filter(transactionViolations, (violation) => violations[violation.name] === field);
return fieldViolations.map(violation => translate(violation.name));
}
// Example object returned by getViolationsOnyxData
{
onyxMethod: Onyx.METHOD.SET,
key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transaction.transactionID}`
value: updatedTransactionViolations
}
const formFields = {
merchant: 'merchant',
amount: 'amount',
category: 'category',
date: 'date',
tag: 'tag',
comment: 'comment',
billable: 'billable',
receipt: 'receipt',
tax: 'tax',
};
const violationFields = {
perDayLimit: formFields.amount,
maxAge: formFields.date,
overLimit: formFields.amount,
overLimitAttendee: formFields.amount,
overCategoryLimit: formFields.amount,
receiptRequired: formFields.receipt,
missingCategory: formFields.category,
categoryOutOfPolicy: formFields.category,
missingTag: formFields.tag,
tagOutOfPolicy: formFields.tag,
missingComment: formFields.comment,
taxRequired: formFields.tax,
taxOutOfPolicy: formFields.tax,
billableExpense: formFields.billable,
};
Example
getViolationForField([{name: 'overLimit', type: 'violation'}], 'amount')
// should return => translate('overLimit')
getViolationForField([{name: 'maxAge', type: 'violation'}], 'amount')
// should return => ''
getViolationForField([{name: 'maxAge', type: 'violation'}], 'date')
// should return => translate('maxAge')
getViolationsOnyxData(
transaction = {category: '', ...},
transactionViolations = [],
policyRequiresTags = false,
policyTags = [],
policyRequiresCategories = true,
policyCategories = [{Entertainment: {name: 'Entertainment', enabled: true}}]
)
// should return
{
onyxMethod: Onyx.METHOD.SET,
key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transaction.transactionID}`,
value: [{name: 'missingCategory', type: 'violation'}],
}
getViolationsOnyxData(
transaction = {tag: '', ...},
transactionViolations = [],
policyRequiresTags = true,
policyTags = [{Entertainment: {name: 'Engineering', enabled: true}}],
policyRequiresCategories = true,
policyCategories = []
)
// should return
{
onyxMethod: Onyx.METHOD.SET,
key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transaction.transactionID}`,
value: [{name: 'missingTag', type: 'violation'}],
}
getViolationForField(object transactionViolation, string field) : stringgetViolationForFieldwill checktransactionViolationand return an an array of strings with the translated copies of the violations for that field, egmissingCategoryand return thatgetViolationsOnyxData(Transaction transaction, object transactionViolations, bool policyRequiresTags, object[] policyTags, bool policyRequiresCategories, object[] policyCategories)that calculates the new transaction violations (by adding/removing those that have been addressed with the current user changes), and returns an object that we can save into onyx. TheupdatedTransactionViolationsvariable shown in the code snippet below will be set like so:policyRequiresCategories === true, the transactionViolations array doesn't have one withname: categoryOutOfPolicyand the passed transaction contains a category, and the policyCategories collection doesn’t have that category with its enabled value set to true, then it’ll add the object{‘name’:’categoryOutOfPolicy’, ‘type’: ‘violation’}toupdatedTransactionViolationspolicyRequiresCategories === true, the passed transaction contains a category that is enabled in the policy, and the onyx data had amissingCategoryviolation, we’ll clear it fromupdatedTransactionViolationsusing_.reject(transactionViolations, e => e.name === 'missingCategory')policyRequiresTag === true, the transactionViolations array doesn't have one withname: tagOutOfPolicyand the passed transaction contains a tag, and the policyTags collection doesn’t have that tag with its enabled value set to true, then it’ll add the object{‘name’:’categoryOutOfPolicy’, ‘type’: ‘violation’}toupdatedTransactionViolationspolicyRequiresTag === true, the passed transaction contains a tag that is enabled in the policy, and the onyx data had amissingTagviolation, we’ll clear it fromupdatedTransactionViolationsusing `_.reject(transactionViolations, e => e.name === 'missingTag')const formFields = {merchant: 'merchant', amount: 'amount', category: 'category', ...}const violationField = {missingCategory: 'category', categoryOutOfPolicy: 'category', ...}with a mapping of violation names to the name of the field where the violation is shown (more in code snippet belowExample