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

Attach receipt #27224

Merged
merged 36 commits into from
Sep 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
f7c72f1
add three dot menu to confirmation page
luacmartins Sep 12, 2023
5ca20ac
add attachment picker support
luacmartins Sep 12, 2023
513c5fc
fix dropdown position anchor
luacmartins Sep 12, 2023
37d9bc2
add logic to select receipt file
luacmartins Sep 12, 2023
05a4da1
use only add receipt option
luacmartins Sep 12, 2023
2875666
create edit receipt route, navigator
luacmartins Sep 12, 2023
ef7fb9e
create edit receipt page, navigate to edit page
luacmartins Sep 12, 2023
0ab130c
update logic in navigateToNextPage
luacmartins Sep 12, 2023
63e92ee
update native implementation
luacmartins Sep 13, 2023
2ba6f18
use correct optimistic receipt state
luacmartins Sep 13, 2023
4cf4ffd
pass receipt state to API
luacmartins Sep 13, 2023
b3df1cb
rm attachmentpicker
luacmartins Sep 13, 2023
c85695b
fix condition to display threeDotMenu
luacmartins Sep 13, 2023
d38feb4
add receipt state
luacmartins Sep 13, 2023
abd801c
update whisper logic
luacmartins Sep 13, 2023
db82a3e
add safe object access
luacmartins Sep 13, 2023
0836a75
add attach option to transaction thread
luacmartins Sep 13, 2023
1650f19
resolve conflicts
luacmartins Sep 13, 2023
698a17a
fix style
luacmartins Sep 13, 2023
492c4a5
fix whisper for report preview
luacmartins Sep 13, 2023
dcf2bb6
fix undefined variable
luacmartins Sep 13, 2023
076f7c8
fix tests
luacmartins Sep 13, 2023
ba0232c
add useCallback dependency
luacmartins Sep 13, 2023
9fdd47f
resolve conflicts
luacmartins Sep 14, 2023
7bcf78a
resolve conflicts
luacmartins Sep 20, 2023
3f5b814
pass missing param, add comment
luacmartins Sep 20, 2023
fabdca5
fix propTypes
luacmartins Sep 20, 2023
8cc320d
fix crash
luacmartins Sep 20, 2023
56a6d2d
fix style
luacmartins Sep 20, 2023
d6c18c8
only allow attaching receipts to dms
luacmartins Sep 21, 2023
fcc5441
address comments
luacmartins Sep 21, 2023
2c9910c
use receipt instead of transaction
luacmartins Sep 21, 2023
ccd13d3
use ioutype
luacmartins Sep 21, 2023
a9c157f
resolve conflicts
luacmartins Sep 25, 2023
3e75e28
resolve conflicts again
luacmartins Sep 25, 2023
32221ae
fix route conflicts
luacmartins Sep 25, 2023
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
1 change: 1 addition & 0 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ export default {
MONEY_REQUEST_TAG: { route: ':iouType/new/tag/:reportID?', getRoute: (iouType: string, reportID = '') => `${iouType}/new/tag/${reportID}`},
MONEY_REQUEST_MERCHANT: { route: ':iouType/new/merchant/:reportID?', getRoute: (iouType: string, reportID = '') => `${iouType}/new/merchant/${reportID}`},
MONEY_REQUEST_WAYPOINT: { route: ':iouType/new/waypoint/:waypointIndex', getRoute: (iouType: string, waypointIndex: number) => `${iouType}/new/waypoint/${waypointIndex}`},
MONEY_REQUEST_RECEIPT: { route: ':iouType/new/receipt/:reportID?', getRoute: (iouType: string, reportID = '') => `${iouType}/new/receipt/${reportID}`},
MONEY_REQUEST_ADDRESS: { route: ':iouType/new/address/:reportID?', getRoute: (iouType: string, reportID = '') => `${iouType}/new/address/${reportID}`},
MONEY_REQUEST_DISTANCE_TAB: { route: ':iouType/new/:reportID?/distance', getRoute: (iouType: string, reportID = '') => `${iouType}/new/${reportID}/distance`},
MONEY_REQUEST_MANUAL_TAB: ':iouType/new/:reportID?/manual',
Expand Down
10 changes: 10 additions & 0 deletions src/components/MoneyRequestHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import participantPropTypes from './participantPropTypes';
import styles from '../styles/styles';
import Navigation from '../libs/Navigation/Navigation';
import ROUTES from '../ROUTES';
import CONST from '../CONST';
import ONYXKEYS from '../ONYXKEYS';
import * as IOU from '../libs/actions/IOU';
import ConfirmModal from './ConfirmModal';
Expand Down Expand Up @@ -85,6 +86,15 @@ function MoneyRequestHeader({session, parentReport, report, parentReportAction,
shouldShowPinButton={false}
shouldShowThreeDotsButton={isActionOwner && !isSettled}
threeDotsMenuItems={[
...(TransactionUtils.hasReceipt(transaction)
? []
: [
{
icon: Expensicons.Receipt,
text: translate('receipt.addReceipt'),
onSelected: () => Navigation.navigate(ROUTES.EDIT_REQUEST.getRoute(report.reportID, CONST.EDIT_REQUEST_FIELD.RECEIPT)),
},
]),
{
icon: Expensicons.Trashcan,
text: translate('reportActionContextMenu.deleteAction', {action: parentReportAction}),
Expand Down
1 change: 1 addition & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@ export default {
flash: 'flash',
shutter: 'shutter',
gallery: 'gallery',
addReceipt: 'Add receipt',
},
iou: {
amount: 'Amount',
Expand Down
1 change: 1 addition & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,7 @@ export default {
flash: 'flash',
shutter: 'obturador',
gallery: 'galería',
addReceipt: 'Añadir recibo',
},
iou: {
amount: 'Importe',
Expand Down
1 change: 1 addition & 0 deletions src/libs/Navigation/AppNavigator/ModalStackNavigators.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ const MoneyRequestModalStackNavigator = createModalStackNavigator({
IOU_Send_Add_Debit_Card: () => require('../../../pages/settings/Wallet/AddDebitCardPage').default,
IOU_Send_Enable_Payments: () => require('../../../pages/EnablePayments/EnablePaymentsPage').default,
Money_Request_Waypoint: () => require('../../../pages/iou/WaypointEditorPage').default,
Money_Request_Receipt: () => require('../../../pages/EditRequestReceiptPage').default,
Money_Request_Address: () => require('../../../pages/iou/DistanceRequestPage').default,
});

Expand Down
1 change: 1 addition & 0 deletions src/libs/Navigation/linkingConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ export default {
Money_Request_Tag: ROUTES.MONEY_REQUEST_TAG.route,
Money_Request_Merchant: ROUTES.MONEY_REQUEST_MERCHANT.route,
Money_Request_Waypoint: ROUTES.MONEY_REQUEST_WAYPOINT.route,
Money_Request_Receipt: ROUTES.MONEY_REQUEST_RECEIPT.route,
Money_Request_Address: ROUTES.MONEY_REQUEST_ADDRESS.route,
IOU_Send_Enable_Payments: ROUTES.IOU_SEND_ENABLE_PAYMENTS,
IOU_Send_Add_Bank_Account: ROUTES.IOU_SEND_ADD_BANK_ACCOUNT,
Expand Down
5 changes: 3 additions & 2 deletions src/libs/ReportUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2230,7 +2230,7 @@ function buildOptimisticIOUReportAction(
created: DateUtils.getDBTime(),
pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
receipt,
whisperedToAccountIDs: !_.isEmpty(receipt) ? [currentUserAccountID] : [],
whisperedToAccountIDs: _.contains([CONST.IOU.RECEIPT_STATE.SCANREADY, CONST.IOU.RECEIPT_STATE.SCANNING], receipt.state) ? [currentUserAccountID] : [],
};
}
/**
Expand Down Expand Up @@ -2283,6 +2283,7 @@ function buildOptimisticApprovedReportAction(amount, currency, expenseReportID)
*/
function buildOptimisticReportPreview(chatReport, iouReport, comment = '', transaction = undefined) {
const hasReceipt = TransactionUtils.hasReceipt(transaction);
const isReceiptBeingScanned = hasReceipt && TransactionUtils.isReceiptBeingScanned(transaction);
const message = getReportPreviewMessage(iouReport);
return {
reportActionID: NumberUtils.rand64(),
Expand All @@ -2307,7 +2308,7 @@ function buildOptimisticReportPreview(chatReport, iouReport, comment = '', trans
childMoneyRequestCount: 1,
childLastMoneyRequestComment: comment,
childLastReceiptTransactionIDs: hasReceipt ? transaction.transactionID : '',
whisperedToAccountIDs: hasReceipt ? [currentUserAccountID] : [],
whisperedToAccountIDs: isReceiptBeingScanned ? [currentUserAccountID] : [],
};
}

Expand Down
10 changes: 9 additions & 1 deletion src/libs/actions/IOU.js
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,7 @@ function requestMoney(
createdIOUReportActionID,
reportPreviewReportActionID: reportPreviewAction.reportActionID,
receipt,
receiptState: lodashGet(receipt, 'state'),
Copy link
Contributor

Choose a reason for hiding this comment

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

BE: This is redundant. We are sending duplicate data, receipt already have state, the backend should extract it from there instead of us having to send it again separately.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yea, I was trying to avoid that too, but our backend seems to strip away any custom properties from files. Since we were losing this data, I ended up having to send this as a separate param.

category,
tag,
billable,
Expand Down Expand Up @@ -2086,8 +2087,9 @@ function createEmptyTransaction() {
* @param {String} iouType
* @param {String} reportID
* @param {Object} report
* @param {String} path
*/
function navigateToNextPage(iou, iouType, reportID, report) {
function navigateToNextPage(iou, iouType, reportID, report, path = '') {
const moneyRequestID = `${iouType}${reportID}`;
const shouldReset = iou.id !== moneyRequestID;

Expand All @@ -2097,6 +2099,12 @@ function navigateToNextPage(iou, iouType, reportID, report) {
resetMoneyRequestInfo(moneyRequestID);
}

// If we're adding a receipt, that means the user came from the confirmation page and we need to navigate back to it.
if (path.slice(1) === ROUTES.MONEY_REQUEST_RECEIPT.getRoute(iouType, reportID)) {
Navigation.navigate(ROUTES.MONEY_REQUEST_CONFIRMATION.getRoute(iouType, reportID));
return;
}

// If a request is initiated on a report, skip the participants selection step and navigate to the confirmation page.
if (report.reportID) {
// If the report is iou or expense report, we should get the chat report to set participant for request money
Expand Down
7 changes: 6 additions & 1 deletion src/pages/EditRequestReceiptPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ const propTypes = {
}).isRequired,

/** The id of the transaction we're editing */
transactionID: PropTypes.string.isRequired,
transactionID: PropTypes.string,
};

const defaultProps = {
transactionID: '',
};

function EditRequestReceiptPage({route, transactionID}) {
Expand Down Expand Up @@ -49,6 +53,7 @@ function EditRequestReceiptPage({route, transactionID}) {
}

EditRequestReceiptPage.propTypes = propTypes;
EditRequestReceiptPage.defaultProps = defaultProps;
EditRequestReceiptPage.displayName = 'EditRequestReceiptPage';

export default EditRequestReceiptPage;
5 changes: 4 additions & 1 deletion src/pages/iou/ReceiptSelector/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ const propTypes = {
/** The report ID of the IOU */
reportID: PropTypes.string,
}),

/** The current route path */
path: PropTypes.string,
}).isRequired,

/** Holds data related to Money Request view state, rather than the underlying Money Request data. */
Expand Down Expand Up @@ -124,7 +127,7 @@ function ReceiptSelector(props) {
return;
}

IOU.navigateToNextPage(iou, iouType, reportID, report);
IOU.navigateToNextPage(iou, iouType, reportID, report, props.route.path);
};

return (
Expand Down
9 changes: 6 additions & 3 deletions src/pages/iou/ReceiptSelector/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ const propTypes = {
/** The report ID of the IOU */
reportID: PropTypes.string,
}),

/** The current route path */
path: PropTypes.string,
}).isRequired,

/** The report on which the request is initiated on */
Expand Down Expand Up @@ -220,13 +223,13 @@ function ReceiptSelector({route, report, iou, transactionID, isInTabNavigator})
return;
}

IOU.navigateToNextPage(iou, iouType, reportID, report);
IOU.navigateToNextPage(iou, iouType, reportID, report, route.path);
})
.catch((error) => {
showCameraAlert();
Log.warn('Error taking photo', error);
});
}, [flash, iouType, iou, report, reportID, translate, transactionID]);
}, [flash, iouType, iou, report, reportID, translate, transactionID, route.path]);

CameraPermission.getCameraPermissionStatus().then((permissionStatus) => {
setPermissions(permissionStatus);
Expand Down Expand Up @@ -295,7 +298,7 @@ function ReceiptSelector({route, report, iou, transactionID, isInTabNavigator})
return;
}

IOU.navigateToNextPage(iou, iouType, reportID, report);
IOU.navigateToNextPage(iou, iouType, reportID, report, route.path);
})
.catch(() => {
Log.info('User did not select an image from gallery');
Expand Down
18 changes: 16 additions & 2 deletions src/pages/iou/steps/MoneyRequestConfirmPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import useNetwork from '../../../hooks/useNetwork';
import useWindowDimensions from '../../../hooks/useWindowDimensions';
import * as StyleUtils from '../../../styles/StyleUtils';
import {iouPropTypes, iouDefaultProps} from '../propTypes';
import * as Expensicons from '../../../components/Icon/Expensicons';

const propTypes = {
/** React Navigation route */
Expand Down Expand Up @@ -61,7 +62,7 @@ const defaultProps = {

function MoneyRequestConfirmPage(props) {
const {isOffline} = useNetwork();
const {windowHeight} = useWindowDimensions();
const {windowHeight, windowWidth} = useWindowDimensions();
const prevMoneyRequestId = useRef(props.iou.id);
const iouType = useRef(lodashGet(props.route, 'params.iouType', ''));
const isDistanceRequest = MoneyRequestUtils.isDistanceRequest(iouType.current, props.selectedTab);
Expand All @@ -74,6 +75,7 @@ function MoneyRequestConfirmPage(props) {
}),
[props.iou.participants, props.personalDetails],
);
const isManualRequestDM = props.selectedTab === CONST.TAB.MANUAL && iouType.current === CONST.IOU.MONEY_REQUEST_TYPE.REQUEST;

useEffect(() => {
const policyExpenseChat = _.find(participants, (participant) => participant.isPolicyExpenseChat);
Expand Down Expand Up @@ -214,7 +216,9 @@ function MoneyRequestConfirmPage(props) {
}

if (props.iou.receiptPath && props.iou.receiptSource) {
FileUtils.readFileAsync(props.iou.receiptPath, props.iou.receiptSource).then((receipt) => {
FileUtils.readFileAsync(props.iou.receiptPath, props.iou.receiptSource).then((file) => {
const receipt = file;
receipt.state = file && isManualRequestDM ? CONST.IOU.RECEIPT_STATE.OPEN : CONST.IOU.RECEIPT_STATE.SCANREADY;
requestMoney(selectedParticipants, trimmedComment, receipt);
});
return;
Expand All @@ -238,6 +242,7 @@ function MoneyRequestConfirmPage(props) {
isDistanceRequest,
requestMoney,
createDistanceRequest,
isManualRequestDM,
],
);

Expand Down Expand Up @@ -286,6 +291,15 @@ function MoneyRequestConfirmPage(props) {
<HeaderWithBackButton
title={headerTitle()}
onBackButtonPress={navigateBack}
shouldShowThreeDotsButton={isManualRequestDM}
threeDotsAnchorPosition={styles.threeDotsPopoverOffsetNoCloseButton(windowWidth)}
threeDotsMenuItems={[
{
icon: Expensicons.Receipt,
text: props.translate('receipt.addReceipt'),
onSelected: () => Navigation.navigate(ROUTES.MONEY_REQUEST_RECEIPT.getRoute(iouType.current, reportID.current)),
},
]}
/>
{/*
* The MoneyRequestConfirmationList component uses a SectionList which uses a VirtualizedList internally.
Expand Down