diff --git a/src/components/AttachmentModal.js b/src/components/AttachmentModal.js
index 1cc12fca24ae..b8bfb4c36122 100755
--- a/src/components/AttachmentModal.js
+++ b/src/components/AttachmentModal.js
@@ -31,11 +31,14 @@ import useWindowDimensions from '../hooks/useWindowDimensions';
import Navigation from '../libs/Navigation/Navigation';
import ROUTES from '../ROUTES';
import useNativeDriver from '../libs/useNativeDriver';
-import * as ReportUtils from '../libs/ReportUtils';
import * as ReportActionsUtils from '../libs/ReportActionsUtils';
+import * as ReportUtils from '../libs/ReportUtils';
import ONYXKEYS from '../ONYXKEYS';
import * as Policy from '../libs/actions/Policy';
import useNetwork from '../hooks/useNetwork';
+import * as IOU from '../libs/actions/IOU';
+import transactionPropTypes from './transactionPropTypes';
+import * as TransactionUtils from '../libs/TransactionUtils';
/**
* Modal render prop component that exposes modal launching triggers that can be used
@@ -79,6 +82,9 @@ const propTypes = {
/** The report that has this attachment */
report: reportPropTypes,
+ /** The transaction associated with the receipt attachment, if any */
+ transaction: transactionPropTypes,
+
...withLocalizePropTypes,
...windowDimensionsPropTypes,
@@ -97,6 +103,7 @@ const defaultProps = {
allowDownload: false,
headerTitle: null,
report: {},
+ transaction: {},
onModalShow: () => {},
onModalHide: () => {},
onCarouselAttachmentChange: () => {},
@@ -108,6 +115,7 @@ function AttachmentModal(props) {
const [isModalOpen, setIsModalOpen] = useState(props.defaultOpen);
const [shouldLoadAttachment, setShouldLoadAttachment] = useState(false);
const [isAttachmentInvalid, setIsAttachmentInvalid] = useState(false);
+ const [isDeleteReceiptConfirmModalVisible, setIsDeleteReceiptConfirmModalVisible] = useState(false);
const [isAuthTokenRequired, setIsAuthTokenRequired] = useState(props.isAuthTokenRequired);
const [isAttachmentReceipt, setIsAttachmentReceipt] = useState(false);
const [attachmentInvalidReasonTitle, setAttachmentInvalidReasonTitle] = useState('');
@@ -205,12 +213,22 @@ function AttachmentModal(props) {
}, [isModalOpen, isConfirmButtonDisabled, props.onConfirm, file, source]);
/**
- * Close the confirm modal.
+ * Close the confirm modals.
*/
const closeConfirmModal = useCallback(() => {
setIsAttachmentInvalid(false);
+ setIsDeleteReceiptConfirmModalVisible(false);
}, []);
+ /**
+ * Detach the receipt and close the modal.
+ */
+ const deleteAndCloseModal = useCallback(() => {
+ IOU.detachReceipt(props.transaction.transactionID, props.report.reportID);
+ setIsDeleteReceiptConfirmModalVisible(false);
+ Navigation.dismissModal(props.report.reportID);
+ }, [props.transaction, props.report]);
+
/**
* @param {Object} _file
* @returns {Boolean}
@@ -358,9 +376,18 @@ function AttachmentModal(props) {
text: props.translate('common.download'),
onSelected: () => downloadAttachment(source),
});
+ if (TransactionUtils.hasReceipt(props.transaction) && !TransactionUtils.isReceiptBeingScanned(props.transaction)) {
+ menuItems.push({
+ icon: Expensicons.Trashcan,
+ text: props.translate('receipt.deleteReceipt'),
+ onSelected: () => {
+ setIsDeleteReceiptConfirmModalVisible(true);
+ },
+ });
+ }
return menuItems;
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [isAttachmentReceipt, props.parentReport, props.parentReportActions, props.policy]);
+ }, [isAttachmentReceipt, props.parentReport, props.parentReportActions, props.policy, props.transaction]);
return (
<>
@@ -442,18 +469,30 @@ function AttachmentModal(props) {
)}
)}
+ {isAttachmentReceipt ? (
+
+ ) : (
+
+ )}
-
-
{props.children &&
props.children({
displayFileInModal: validateAndDisplayFileToUpload,
@@ -470,6 +509,16 @@ export default compose(
withWindowDimensions,
withLocalize,
withOnyx({
+ transaction: {
+ key: ({report}) => {
+ if (!report) {
+ return undefined;
+ }
+ const parentReportAction = ReportActionsUtils.getReportAction(report.parentReportID, report.parentReportActionID);
+ const transactionID = lodashGet(parentReportAction, ['originalMessage', 'IOUTransactionID'], 0);
+ return `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`;
+ },
+ },
parentReport: {
key: ({report}) => `${ONYXKEYS.COLLECTION.REPORT}${report ? report.parentReportID : '0'}`,
},
diff --git a/src/languages/en.ts b/src/languages/en.ts
index 85e897db58ec..1128e364eb94 100755
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -506,6 +506,8 @@ export default {
flash: 'flash',
shutter: 'shutter',
gallery: 'gallery',
+ deleteReceipt: 'Delete receipt',
+ deleteConfirmation: 'Are you sure you want to delete this receipt?',
addReceipt: 'Add receipt',
},
iou: {
diff --git a/src/languages/es.ts b/src/languages/es.ts
index 548c2caa3721..cc7e94d6e520 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -498,6 +498,8 @@ export default {
flash: 'flash',
shutter: 'obturador',
gallery: 'galería',
+ deleteReceipt: 'Eliminar recibo',
+ deleteConfirmation: '¿Estás seguro de que quieres borrar este recibo?',
addReceipt: 'Añadir recibo',
},
iou: {
diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js
index 68e782010982..bc6ee9be4e0b 100644
--- a/src/libs/actions/IOU.js
+++ b/src/libs/actions/IOU.js
@@ -2431,6 +2431,29 @@ function payMoneyRequest(paymentType, chatReport, iouReport) {
Navigation.dismissModal(chatReport.reportID);
}
+function detachReceipt(transactionID) {
+ const transaction = allTransactions[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`] || {};
+ const newTransaction = {...transaction, filename: '', receipt: {}};
+
+ const optimisticData = [
+ {
+ onyxMethod: Onyx.METHOD.SET,
+ key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`,
+ value: newTransaction,
+ },
+ ];
+
+ const failureData = [
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`,
+ value: transaction,
+ },
+ ];
+
+ API.write('DetachReceipt', {transactionID}, {optimisticData, failureData});
+}
+
/**
* @param {String} transactionID
* @param {Object} receipt
@@ -2663,5 +2686,6 @@ export {
navigateToNextPage,
updateDistanceRequest,
replaceReceipt,
+ detachReceipt,
getIOUReportID,
};