@@ -135,21 +135,47 @@ function IOURequestStartPage({
135135 const hasCurrentPolicyPerDiemWithRates = ! isFromGlobalCreate && hasCurrentPolicyPerDiemEnabled && hasPolicyPerDiemRates ;
136136 const hasAnyPolicyPerDiemWithRates = ( iouType === CONST . IOU . TYPE . TRACK || isFromGlobalCreate ) && doesPerDiemPolicyExist ;
137137 const shouldShowPerDiemOption = iouType !== CONST . IOU . TYPE . SPLIT && ( hasCurrentPolicyPerDiemWithRates || hasAnyPolicyPerDiemWithRates ) ;
138+ const shouldShowTimeOption =
139+ ( iouType === CONST . IOU . TYPE . SUBMIT || iouType === CONST . IOU . TYPE . CREATE ) &&
140+ ( ( ! isFromGlobalCreate && hasCurrentPolicyTimeTrackingEnabled ) || ( isFromGlobalCreate && ! ! policiesWithTimeEnabled . length ) ) ;
138141
139- const transactionRequestType = useMemo ( ( ) => {
140- if ( ! transaction ?. iouRequestType ) {
141- if ( shouldUseTab ) {
142- if ( selectedTab === CONST . TAB_REQUEST . PER_DIEM && ! shouldShowPerDiemOption ) {
143- return undefined ;
144- }
145- return selectedTab ;
146- }
142+ // Mirrors the tabs rendered below so a stale persisted selectedTab that isn't valid for this iouType is rejected.
143+ const availableTabs = useMemo < Set < SelectedTabRequest > > ( ( ) => {
144+ if ( ! shouldUseTab ) {
145+ return new Set ( ) ;
146+ }
147+ const tabs = new Set < SelectedTabRequest > ( [ CONST . TAB_REQUEST . MANUAL , CONST . TAB_REQUEST . SCAN ] ) ;
148+ if ( iouType === CONST . IOU . TYPE . SPLIT ) {
149+ tabs . add ( CONST . TAB_REQUEST . DISTANCE ) ;
150+ }
151+ if ( shouldShowPerDiemOption ) {
152+ tabs . add ( CONST . TAB_REQUEST . PER_DIEM ) ;
153+ }
154+ if ( shouldShowTimeOption ) {
155+ tabs . add ( CONST . TAB_REQUEST . TIME ) ;
156+ }
157+ return tabs ;
158+ } , [ shouldUseTab , iouType , shouldShowPerDiemOption , shouldShowTimeOption ] ) ;
159+
160+ // A quick-action deeplink (e.g. iOS home-screen "Scan receipt") bypasses startMoneyRequest
161+ // and leaves the previous flow's draft in place under OPTIMISTIC_TRANSACTION_ID. Detect it
162+ // by comparing the draft's reportID to the URL's so we don't inherit its stale iouRequestType.
163+ const isStaleTransactionDraft = ! ! transaction ?. reportID && transaction . reportID !== reportID ;
147164
165+ const transactionRequestType = useMemo ( ( ) => {
166+ if ( transaction ?. iouRequestType && ! isStaleTransactionDraft ) {
167+ return transaction . iouRequestType ;
168+ }
169+ if ( ! shouldUseTab ) {
148170 return CONST . IOU . REQUEST_TYPE . MANUAL ;
149171 }
150-
151- return transaction . iouRequestType ;
152- } , [ transaction ?. iouRequestType , shouldUseTab , selectedTab , shouldShowPerDiemOption ] ) ;
172+ // selectedTab must be valid for the currently-rendered tab set; otherwise let
173+ // OnyxTabNavigator.onTabSelected initialize from the URL (which is authoritative).
174+ if ( selectedTab && availableTabs . has ( selectedTab ) ) {
175+ return selectedTab ;
176+ }
177+ return undefined ;
178+ } , [ transaction ?. iouRequestType , isStaleTransactionDraft , shouldUseTab , selectedTab , availableTabs ] ) ;
153179
154180 const resetIOUTypeIfChanged = useResetIOUType ( {
155181 reportID,
@@ -204,10 +230,6 @@ function IOURequestStartPage({
204230 } ,
205231 } ,
206232 ) ;
207- const shouldShowTimeOption =
208- ( iouType === CONST . IOU . TYPE . SUBMIT || iouType === CONST . IOU . TYPE . CREATE ) &&
209- ( ( ! isFromGlobalCreate && hasCurrentPolicyTimeTrackingEnabled ) || ( isFromGlobalCreate && ! ! policiesWithTimeEnabled . length ) ) ;
210-
211233 const onBackButtonPress = ( ) => {
212234 navigateBack ( ) ;
213235 return true ;
0 commit comments