Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Receipt Audit Feature / Note type violations. #37813

Merged
merged 52 commits into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
9467b3a
feat: Receipt Audit Feature / Note type violations.
Krishna2323 Mar 6, 2024
8c400c3
added translations.
Krishna2323 Mar 6, 2024
96744d5
extract noticeViolations from transactionViolations.
Krishna2323 Mar 6, 2024
952a4da
Update the dot separator sub-state for the request preview.
Krishna2323 Mar 7, 2024
8438383
Remove redundant code.
Krishna2323 Mar 7, 2024
7f97519
minor fix.
Krishna2323 Mar 7, 2024
cebc960
minor fix.
Krishna2323 Mar 7, 2024
86014ab
hide ReceiptAudit when scan is in progress.
Krishna2323 Mar 7, 2024
3db41da
minor updates.
Krishna2323 Mar 8, 2024
afb1afb
Merge branch 'main' into krishna2323/feat/36288
Krishna2323 Mar 11, 2024
b538331
Update MoneyRequestView.tsx
Krishna2323 Mar 11, 2024
48d1543
fix: translations.
Krishna2323 Mar 12, 2024
77165e7
minor fixes.
Krishna2323 Mar 17, 2024
699bb28
Merge branch 'Expensify:main' into krishna2323/feat/36288
Krishna2323 Mar 19, 2024
25cc0fa
receipt audit design changes.
Krishna2323 Mar 20, 2024
da3ae8c
Receipt audit design updates.
Krishna2323 Mar 22, 2024
f2a59fd
Merge branch 'Expensify:main' into krishna2323/feat/36288
Krishna2323 Mar 25, 2024
fd457cd
show notes violation for only admins and approvers in a paid policy.
Krishna2323 Mar 25, 2024
7a194c9
Merge branch 'krishna2323/feat/36288' of https://github.com/Krishna23…
Krishna2323 Mar 25, 2024
0de547a
Merge branch 'main' into krishna2323/feat/36288
Krishna2323 Mar 29, 2024
b785e1f
show notes violation to everyone.
Krishna2323 Mar 29, 2024
f4e118a
fix: violation messages styles.
Krishna2323 Mar 29, 2024
67d7dc4
Merge branch 'main' into krishna2323/feat/36288
Krishna2323 Mar 31, 2024
80b7eb5
Update MoneyRequestView.tsx
Krishna2323 Mar 31, 2024
bfec360
remove ReceiptAuditHeader condition.
Krishna2323 Mar 31, 2024
d9975d8
Merge branch 'Expensify:main' into krishna2323/feat/36288
Krishna2323 Apr 3, 2024
269163f
Merge branch 'Expensify:main' into krishna2323/feat/36288
Krishna2323 Apr 4, 2024
ae2324e
fix: margins issue.
Krishna2323 Apr 4, 2024
4bb11b5
Merge branch 'Expensify:main' into krishna2323/feat/36288
Krishna2323 Apr 7, 2024
899f12c
Merge branch 'Expensify:main' into krishna2323/feat/36288
Krishna2323 Apr 9, 2024
4225d83
show red dot when review is required.
Krishna2323 Apr 9, 2024
98ef4fb
Merge branch 'Expensify:main' into krishna2323/feat/36288
Krishna2323 Apr 13, 2024
78b79cc
allow admin & approver to update receipt when iou request is open.
Krishna2323 Apr 14, 2024
87270fb
revert: allow admin & approver to update receipt when iou request is …
Krishna2323 Apr 14, 2024
51cb29d
Merge branch 'Expensify:main' into krishna2323/feat/36288
Krishna2323 Apr 18, 2024
cd91773
show empty receipt for admin & approver if not present.
Krishna2323 Apr 18, 2024
ca0650b
revert margin changes.
Krishna2323 Apr 19, 2024
943df82
Merge branch 'main' into krishna2323/feat/36288
Krishna2323 Apr 20, 2024
cd52fee
Merge branch 'Expensify:main' into krishna2323/feat/36288
Krishna2323 Apr 23, 2024
1ae1c5b
show audit status only when receipt is scanned.
Krishna2323 Apr 23, 2024
31f34a8
Merge branch 'main' into krishna2323/feat/36288
Krishna2323 Apr 24, 2024
2c9ab1e
fix: disabled receipt cursor style.
Krishna2323 Apr 24, 2024
8f17210
Merge branch 'Expensify:main' into krishna2323/feat/36288
Krishna2323 Apr 25, 2024
148c2b9
fix: no space between audit message and notes violations.
Krishna2323 Apr 25, 2024
ace1043
fix lint warning.
Krishna2323 Apr 26, 2024
cfbddf1
minor updates according to suggestions.
Krishna2323 Apr 29, 2024
a0a2fc3
second commit: minor updates according to suggestions.
Krishna2323 Apr 29, 2024
812fd14
Merge branch 'Expensify:main' into krishna2323/feat/36288
Krishna2323 Apr 29, 2024
9fbf78e
third commit: minor updates according to suggestions.
Krishna2323 Apr 29, 2024
4081f85
Merge branch 'krishna2323/feat/36288' of https://github.com/Krishna23…
Krishna2323 Apr 29, 2024
e117ef5
fourth commit: minor updates according to suggestions.
Krishna2323 Apr 29, 2024
22e6fcb
5th commit: minor updates according to suggestions.
Krishna2323 Apr 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions src/components/ReceiptAudit.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react';
import {View} from 'react-native';
import useLocalize from '@hooks/useLocalize';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import Icon from './Icon';
import * as Expensicons from './Icon/Expensicons';
import Text from './Text';

export default function ReceiptAudit({notes = []}: {notes?: string[]}) {
const styles = useThemeStyles();
const theme = useTheme();
const {translate} = useLocalize();

const issuesFoundText = notes.length > 0 ? translate('iou.receiptIssuesFound', notes.length) : translate('iou.receiptNoIssuesFound');
return (
<View style={[styles.mt1, styles.mb2, styles.ph5]}>
<View style={[styles.flexRow, styles.alignItemsCenter, styles.gap2]}>
<View style={[styles.receiptAuditTitleContainer, {backgroundColor: notes.length ? theme.danger : theme.success}]}>
<Icon
width={18}
height={18}
src={notes.length > 0 ? Expensicons.Receipt : Expensicons.Checkmark}
fill={theme.white}
/>
<Text style={[styles.textLabel, styles.textStrong, styles.textWhite]}>{notes.length > 0 ? translate('iou.receiptAudit') : translate('iou.receiptVerified')}</Text>
</View>
<Text style={[styles.textLabel, styles.textSupporting]}>{issuesFoundText}</Text>
</View>
<View style={[styles.mt2, styles.gap1]}>{notes.length > 0 && notes.map((message) => <Text style={[styles.textLabelError]}>{message}</Text>)}</View>
</View>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ function MoneyRequestPreviewContent({
const hasReceipt = TransactionUtils.hasReceipt(transaction);
const isScanning = hasReceipt && TransactionUtils.isReceiptBeingScanned(transaction);
const hasViolations = TransactionUtils.hasViolation(transaction?.transactionID ?? '', transactionViolations);
const hasNoteTypeViolations = TransactionUtils.hasNoteTypeViolation(transaction?.transactionID ?? '', transactionViolations);
Krishna2323 marked this conversation as resolved.
Show resolved Hide resolved
const hasFieldErrors = TransactionUtils.hasMissingSmartscanFields(transaction);
const shouldShowRBR = hasViolations || hasFieldErrors;
const isDistanceRequest = TransactionUtils.isDistanceRequest(transaction);
Expand Down Expand Up @@ -159,6 +160,8 @@ function MoneyRequestPreviewContent({
const isTooLong = violations.filter((v) => v.type === 'violation').length > 1 || violationMessage.length > 15;
message += ` • ${isTooLong ? translate('violations.reviewRequired') : violationMessage}`;
}
} else if (hasNoteTypeViolations && transaction && !ReportUtils.isReportApproved(iouReport) && !ReportUtils.isSettled(iouReport?.reportID)) {
Krishna2323 marked this conversation as resolved.
Show resolved Hide resolved
message += ` • ${translate('violations.reviewRequired')}`;
} else if (ReportUtils.isPaidGroupPolicyExpenseReport(iouReport) && ReportUtils.isReportApproved(iouReport) && !ReportUtils.isSettled(iouReport?.reportID)) {
message += ` • ${translate('iou.approved')}`;
} else if (iouReport?.isWaitingOnBankAccount) {
Expand Down
7 changes: 6 additions & 1 deletion src/components/ReportActionItem/MoneyRequestView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import ConfirmedRoute from '@components/ConfirmedRoute';
import * as Expensicons from '@components/Icon/Expensicons';
import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription';
import OfflineWithFeedback from '@components/OfflineWithFeedback';
import ReceiptAudit from '@components/ReceiptAudit';
import ReceiptEmptyState from '@components/ReceiptEmptyState';
import SpacerView from '@components/SpacerView';
import Switch from '@components/Switch';
Expand Down Expand Up @@ -127,6 +128,8 @@ function MoneyRequestView({
const canEditDate = ReportUtils.canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.DATE);
const canEditReceipt = ReportUtils.canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.RECEIPT);
const canEditDistance = ReportUtils.canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.DISTANCE);
const hasReceipt = TransactionUtils.hasReceipt(transaction);
const isReceiptBeingScanned = hasReceipt && TransactionUtils.isReceiptBeingScanned(transaction);

// A flag for verifying that the current report is a sub-report of a workspace chat
// if the policy of the report is either Collect or Control, then this report must be tied to workspace chat
Expand All @@ -148,6 +151,8 @@ function MoneyRequestView({
(field: ViolationField, data?: OnyxTypes.TransactionViolation['data']): boolean => !!canUseViolations && getViolationsForField(field, data).length > 0,
[canUseViolations, getViolationsForField],
);
const noteTypeViolations = transactionViolations?.filter((violation) => violation.type === 'note').map((v) => ViolationsUtils.getViolationTranslation(v, translate));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Krishna2323 Is the violation type 'note' for such violations? What type do we use for violation messages? Can we reuse the existing method for violation messages? If you have any confusion, please do raise it on the issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sobitneupane, I guess we need to pass array of strings to ReceiptAudit component so we need to extract like this. The type for violation messages is violation.

return Boolean(transactionViolations?.[ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS + transactionID]?.some((violation: TransactionViolation) => violation.type === 'violation'));

@JmillsExpensify can you pls confirm if the type for note type violation is note?

Copy link
Contributor

@sobitneupane sobitneupane Mar 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Krishna2323 type for such violation is "notice"

[
    {
        "type": "notice",
        "name": "modifiedAmount",
        "data": null
    },
    {
        "type": "notice",
        "name": "modifiedDate",
        "data": null
    }
]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated!

const shouldShowNotesViolations = !isReceiptBeingScanned && canUseViolations && hasReceipt;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Krishna2323 If there is no receipt in the request, I believe we do raise note type violation. hasNoteTypeViolation will return true in MoneyRequestPreviewContext resulting Review Required sub-state but we don't show any receipt audit message because hasReceipt is false. This would create discrepancy.

Copy link
Contributor Author

@Krishna2323 Krishna2323 Mar 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be resolved with the linked commit.

And this also:

@Krishna2323 Have you considered #36288 (comment) comments? We would want this feature only for admin/approver in paid workspace

Receipt Audit is only a feature for paid workspaces, so Collect and Control.

Commit: fd457cd


let amountDescription = `${translate('iou.amount')}`;

Expand Down Expand Up @@ -189,7 +194,6 @@ function MoneyRequestView({
}
}

const hasReceipt = TransactionUtils.hasReceipt(transaction);
let receiptURIs;
const hasErrors = canEdit && TransactionUtils.hasMissingSmartscanFields(transaction);
if (hasReceipt) {
Expand Down Expand Up @@ -285,6 +289,7 @@ function MoneyRequestView({
}
/>
)}
{shouldShowNotesViolations && <ReceiptAudit notes={noteTypeViolations} />}
{canUseViolations && <ViolationMessages violations={getViolationsForField('receipt')} />}
<OfflineWithFeedback pendingAction={getPendingFieldAction('amount')}>
<MenuItemWithTopDescription
Expand Down
4 changes: 4 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,10 @@ export default {
posted: 'Posted',
deleteReceipt: 'Delete receipt',
routePending: 'Route pending...',
receiptAudit: 'Receipt Audit',
receiptVerified: 'Receipt Verified',
receiptNoIssuesFound: 'No issues Found',
receiptIssuesFound: (count: number) => `${count} Issue(s) Found`,
Krishna2323 marked this conversation as resolved.
Show resolved Hide resolved
receiptScanning: 'Scan in progress…',
receiptMissingDetails: 'Receipt missing details',
receiptStatusTitle: 'Scanning…',
Expand Down
4 changes: 4 additions & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,10 @@ export default {
posted: 'Contabilizado',
deleteReceipt: 'Eliminar recibo',
routePending: 'Ruta pendiente...',
receiptAudit: 'Auditoría de recibos',
receiptVerified: 'Recibo verificado',
receiptNoIssuesFound: 'No se encontraron problemas',
receiptIssuesFound: (count: number) => `Se encontró ${count} problema(s)`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Krishna2323 Did we verify if it is the correct translation? We can ask for the correct translations in slack channel.

receiptScanning: 'Escaneo en curso…',
receiptMissingDetails: 'Recibo con campos vacíos',
receiptStatusTitle: 'Escaneando…',
Expand Down
8 changes: 8 additions & 0 deletions src/libs/TransactionUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,13 @@ function hasViolation(transactionID: string, transactionViolations: OnyxCollecti
return Boolean(transactionViolations?.[ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS + transactionID]?.some((violation: TransactionViolation) => violation.type === 'violation'));
}

/**
* Checks if any violations for the provided transaction are of type 'note'
Krishna2323 marked this conversation as resolved.
Show resolved Hide resolved
*/
function hasNoteTypeViolation(transactionID: string, transactionViolations: OnyxCollection<TransactionViolation[]>): boolean {
Krishna2323 marked this conversation as resolved.
Show resolved Hide resolved
return Boolean(transactionViolations?.[ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS + transactionID]?.some((violation: TransactionViolation) => violation.type === 'note'));
}

function getTransactionViolations(transactionID: string, transactionViolations: OnyxCollection<TransactionViolation[]>): TransactionViolation[] | null {
return transactionViolations?.[ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS + transactionID] ?? null;
}
Expand Down Expand Up @@ -663,6 +670,7 @@ export {
waypointHasValidAddress,
getRecentTransactions,
hasViolation,
hasNoteTypeViolation,
};

export type {TransactionChanges};
13 changes: 13 additions & 0 deletions src/styles/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4197,6 +4197,19 @@ const styles = (theme: ThemeColors) =>
borderWidth: 1,
},

receiptAuditTitleContainer: {
flexDirection: 'row',
gap: 4,
padding: 4,
paddingHorizontal: 8,
height: variables.inputHeightSmall,
borderRadius: variables.componentBorderRadiusSmall,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: theme.border,
},

mapViewContainer: {
...flex.flex1,
minHeight: 300,
Expand Down
Loading