@@ -12,7 +12,14 @@ import useNetwork from '@hooks/useNetwork';
1212import useOnyx from '@hooks/useOnyx' ;
1313import usePolicy from '@hooks/usePolicy' ;
1414import useThemeStyles from '@hooks/useThemeStyles' ;
15- import { detachReceipt , navigateToStartStepIfScanFileCannotBeRead , removeMoneyRequestOdometerImage , replaceReceipt , setMoneyRequestReceipt } from '@libs/actions/IOU' ;
15+ import {
16+ detachReceipt ,
17+ navigateToStartStepIfScanFileCannotBeRead ,
18+ removeMoneyRequestOdometerImage ,
19+ replaceReceipt ,
20+ setMoneyRequestOdometerImage ,
21+ setMoneyRequestReceipt ,
22+ } from '@libs/actions/IOU' ;
1623import { openReport } from '@libs/actions/Report' ;
1724import cropOrRotateImage from '@libs/cropOrRotateImage' ;
1825import fetchImage from '@libs/fetchImage' ;
@@ -22,7 +29,16 @@ import Navigation from '@libs/Navigation/Navigation';
2229import { getThumbnailAndImageURIs } from '@libs/ReceiptUtils' ;
2330import { getReportAction , isTrackExpenseAction } from '@libs/ReportActionsUtils' ;
2431import { canEditFieldOfMoneyRequest , isMoneyRequestReport , isTrackExpenseReport } from '@libs/ReportUtils' ;
25- import { getRequestType , hasEReceipt , hasMissingSmartscanFields , hasReceipt , hasReceiptSource , isOdometerDistanceRequest , isReceiptBeingScanned } from '@libs/TransactionUtils' ;
32+ import {
33+ getRequestType ,
34+ hasEReceipt ,
35+ hasMissingSmartscanFields ,
36+ hasOdometerImageSource ,
37+ hasReceipt ,
38+ hasReceiptSource ,
39+ isOdometerDistanceRequest ,
40+ isReceiptBeingScanned ,
41+ } from '@libs/TransactionUtils' ;
2642import tryResolveUrlFromApiRoot from '@libs/tryResolveUrlFromApiRoot' ;
2743import type { AttachmentModalBaseContentProps , ThreeDotsMenuItemFactory } from '@pages/media/AttachmentModalScreen/AttachmentModalBaseContent/types' ;
2844import AttachmentModalContainer from '@pages/media/AttachmentModalScreen/AttachmentModalContainer' ;
@@ -90,6 +106,9 @@ function TransactionReceiptModalContent({navigation, route}: AttachmentModalScre
90106 odometerImage = imageType === CONST . IOU . ODOMETER_IMAGE_TYPE . START ? transaction ?. comment ?. odometerStartImage : transaction ?. comment ?. odometerEndImage ;
91107 }
92108 const odometerFile = typeof odometerImage !== 'string' ? odometerImage : undefined ;
109+ const odometerFilename = odometerFile ?. name ?? ( typeof odometerImage === 'string' ? odometerImage . split ( '/' ) . pop ( ) : undefined ) ;
110+ const odometerUriExtension = odometerFilename ?. split ( '.' ) . pop ( ) ?. toLowerCase ( ) ;
111+ const odometerFileType = ( odometerFile as Partial < File > ) ?. type ?? ( odometerUriExtension ? `image/${ odometerUriExtension } ` : CONST . IMAGE_FILE_FORMAT . JPEG ) ;
93112 const [ odometerImageSource , setOdometerImageSource ] = useState < string | undefined > ( undefined ) ;
94113
95114 useEffect ( ( ) => {
@@ -131,13 +150,15 @@ function TransactionReceiptModalContent({navigation, route}: AttachmentModalScre
131150 const canDeleteReceipt = canEditFieldOfMoneyRequest ( parentReportAction , CONST . EDIT_REQUEST_FIELD . RECEIPT , true ) ;
132151
133152 const receiptFilename = transaction ?. receipt ?. filename ;
134- const isImage = ! ! receiptFilename && Str . isImage ( receiptFilename ) ;
135153 const isStitchedOdometerReceipt = isOdometerDistanceRequest ( transaction ) && ! imageType ;
136154
137155 const shouldShowReplaceReceiptButton = ( ( canEditReceipt && ! readonly ) || isDraftTransaction ) && ! transaction ?. receipt ?. isTestDriveReceipt && ! isStitchedOdometerReceipt ;
138156 const shouldShowDeleteReceiptButton = canDeleteReceipt && ! readonly && ! isDraftTransaction && ! transaction ?. receipt ?. isTestDriveReceipt ;
139157
140158 const isEReceipt = transaction && ! hasReceiptSource ( transaction ) && hasEReceipt ( transaction ) ;
159+ const fileName = ( isOdometerImage ? odometerFilename : receiptFilename ) ?? '' ;
160+ const isImage = ! ! fileName && Str . isImage ( fileName ) ;
161+ const fileType = isOdometerImage ? odometerFileType : ( transaction ?. receipt ?. type ?? CONST . IMAGE_FILE_FORMAT . JPEG ) ;
141162 const isTrackExpenseActionValue = isTrackExpenseAction ( parentReportAction ) ;
142163 const iouType = useMemo ( ( ) => iouTypeParam ?? ( isTrackExpenseActionValue ? CONST . IOU . TYPE . TRACK : CONST . IOU . TYPE . SUBMIT ) , [ isTrackExpenseActionValue , iouTypeParam ] ) ;
143164
@@ -261,13 +282,11 @@ function TransactionReceiptModalContent({navigation, route}: AttachmentModalScre
261282 return ;
262283 }
263284
264- const receiptType = transaction ?. receipt ?. type ?? CONST . IMAGE_FILE_FORMAT . JPEG ;
265-
266285 setIsRotating ( true ) ;
267286 cropOrRotateImage ( sourceUri as string , [ { rotate : - 90 } ] , {
268287 compress : 1 ,
269- name : receiptFilename ,
270- type : receiptType ,
288+ name : fileName ,
289+ type : fileType ,
271290 } )
272291 . then ( ( rotatedImage ) => {
273292 if ( ! rotatedImage ) {
@@ -284,8 +303,10 @@ function TransactionReceiptModalContent({navigation, route}: AttachmentModalScre
284303 const file = rotatedImage as File ;
285304 const rotatedFilename = file . name ?? receiptFilename ;
286305
287- if ( isDraftTransaction ) {
288- setMoneyRequestReceipt ( transaction . transactionID , imageUriResult , rotatedFilename , isDraftTransaction , receiptType ) ;
306+ if ( isOdometerImage ) {
307+ setMoneyRequestOdometerImage ( transaction . transactionID , imageType , file , isDraftTransaction ) ;
308+ } else if ( isDraftTransaction ) {
309+ setMoneyRequestReceipt ( transaction . transactionID , imageUriResult , rotatedFilename , isDraftTransaction , fileType ) ;
289310 } else {
290311 replaceReceipt ( {
291312 transactionID : transaction . transactionID ,
@@ -302,17 +323,17 @@ function TransactionReceiptModalContent({navigation, route}: AttachmentModalScre
302323 . catch ( ( ) => {
303324 setIsRotating ( false ) ;
304325 } ) ;
305- } , [ transaction ?. transactionID , isDraftTransaction , sourceUri , isImage , receiptFilename , policyCategories , transaction ?. receipt , policy ] ) ;
326+ } , [ transaction ?. transactionID , isDraftTransaction , isOdometerImage , imageType , sourceUri , isImage , receiptFilename , fileName , fileType , policyCategories , transaction ?. receipt , policy ] ) ;
306327
307328 const shouldShowRotateAndCropReceiptButton = useMemo (
308329 ( ) =>
309330 shouldShowReplaceReceiptButton &&
310331 transaction &&
311- hasReceiptSource ( transaction ) &&
332+ ( hasReceiptSource ( transaction ) || ( isOdometerImage && hasOdometerImageSource ( transaction , imageType ) ) ) &&
312333 ! isEReceipt &&
313334 ! transaction ?. receipt ?. isTestDriveReceipt &&
314- ( receiptFilename ? Str . isImage ( receiptFilename ) : false ) ,
315- [ shouldShowReplaceReceiptButton , transaction , isEReceipt , receiptFilename ] ,
335+ isImage ,
336+ [ shouldShowReplaceReceiptButton , transaction , isEReceipt , isOdometerImage , imageType , isImage ] ,
316337 ) ;
317338
318339 const enterCropMode = useCallback ( ( ) => {
@@ -335,8 +356,6 @@ function TransactionReceiptModalContent({navigation, route}: AttachmentModalScre
335356 return ;
336357 }
337358
338- const receiptType = transaction ?. receipt ?. type ?? CONST . IMAGE_FILE_FORMAT . JPEG ;
339-
340359 setIsCropSaving ( true ) ;
341360 cropOrRotateImage (
342361 sourceUri as string ,
@@ -352,8 +371,8 @@ function TransactionReceiptModalContent({navigation, route}: AttachmentModalScre
352371 ] ,
353372 {
354373 compress : 1 ,
355- name : receiptFilename ,
356- type : receiptType ,
374+ name : fileName ,
375+ type : fileType ,
357376 } ,
358377 )
359378 . then ( ( croppedImage ) => {
@@ -371,8 +390,10 @@ function TransactionReceiptModalContent({navigation, route}: AttachmentModalScre
371390 const file = croppedImage as File ;
372391 const croppedFilename = file . name ?? receiptFilename ;
373392
374- if ( isDraftTransaction ) {
375- setMoneyRequestReceipt ( transaction . transactionID , imageUriResult , croppedFilename , isDraftTransaction , receiptType ) ;
393+ if ( isOdometerImage ) {
394+ setMoneyRequestOdometerImage ( transaction . transactionID , imageType , file , isDraftTransaction ) ;
395+ } else if ( isDraftTransaction ) {
396+ setMoneyRequestReceipt ( transaction . transactionID , imageUriResult , croppedFilename , isDraftTransaction , fileType ) ;
376397 } else {
377398 replaceReceipt ( {
378399 transactionID : transaction . transactionID ,
@@ -388,7 +409,21 @@ function TransactionReceiptModalContent({navigation, route}: AttachmentModalScre
388409 . catch ( ( ) => {
389410 setIsCropSaving ( false ) ;
390411 } ) ;
391- } , [ transaction ?. transactionID , isDraftTransaction , sourceUri , isImage , cropRect , receiptFilename , policyCategories , transaction ?. receipt ?. type , policy , exitCropMode ] ) ;
412+ } , [
413+ transaction ?. transactionID ,
414+ isDraftTransaction ,
415+ isOdometerImage ,
416+ imageType ,
417+ sourceUri ,
418+ isImage ,
419+ cropRect ,
420+ receiptFilename ,
421+ fileName ,
422+ fileType ,
423+ policyCategories ,
424+ policy ,
425+ exitCropMode ,
426+ ] ) ;
392427
393428 const threeDotsMenuItems : ThreeDotsMenuItemFactory = useCallback (
394429 ( { file, source : innerSource , isLocalSource} ) => {
0 commit comments