Skip to content

Commit b1951f7

Browse files
authored
Merge pull request #89393 from Expensify/lucien/fix-submit-approver-rca
[Payment due @Krishna2323] Fix submit approver selection after retract and workflow changes
2 parents 30fd07a + da3beb5 commit b1951f7

6 files changed

Lines changed: 787 additions & 13 deletions

File tree

src/libs/PolicyUtils.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ import {formatMemberForList} from './OptionsListUtils';
5252
import type {MemberForList} from './OptionsListUtils';
5353
import {getAccountIDsByLogins, getLoginByAccountID, getLoginsByAccountIDs, getPersonalDetailByEmail} from './PersonalDetailsUtils';
5454
import {getAllSortedTransactions, getCategory, getTag, getTagArrayFromName} from './TransactionUtils';
55-
import {isPublicDomain} from './ValidationUtils';
55+
import {isPublicDomain, isValidAccountRoute} from './ValidationUtils';
5656

5757
type MemberEmailsToAccountIDs = Record<string, number>;
5858

@@ -1292,6 +1292,31 @@ function getSubmitToAccountID(policy: OnyxEntry<Policy>, expenseReport: OnyxEntr
12921292
return getManagerAccountID(policy, expenseReport);
12931293
}
12941294

1295+
function getSubmitReportManagerAccountID(policy: OnyxEntry<Policy>, expenseReport: OnyxEntry<Report>): number | undefined {
1296+
const ownerAccountID = expenseReport?.ownerAccountID ?? CONST.DEFAULT_NUMBER_ID;
1297+
const existingManagerID = expenseReport?.managerID;
1298+
const approvalRules = policy?.rules?.approvalRules;
1299+
const ruleApprover = !isSubmitAndClose(policy) && approvalRules?.length ? getFirstRuleApprover(approvalRules, expenseReport) : '';
1300+
const submitToAccountID = ruleApprover ? (getAccountIDsByLogins([ruleApprover]).at(0) ?? -1) : getManagerAccountID(policy, expenseReport);
1301+
const isValidSubmitToAccountID = isValidAccountRoute(submitToAccountID);
1302+
const isValidExistingManagerID = isValidAccountRoute(existingManagerID ?? CONST.DEFAULT_NUMBER_ID) && existingManagerID !== ownerAccountID;
1303+
const employeeLogin = getLoginByAccountID(ownerAccountID) ?? '';
1304+
const hasReliablePolicyRoute =
1305+
([CONST.POLICY.APPROVAL_MODE.OPTIONAL, CONST.POLICY.APPROVAL_MODE.BASIC] as Array<ValueOf<typeof CONST.POLICY.APPROVAL_MODE>>).includes(getApprovalWorkflow(policy)) ||
1306+
!!ruleApprover ||
1307+
!!policy?.employeeList?.[employeeLogin];
1308+
1309+
if (hasReliablePolicyRoute && isValidSubmitToAccountID) {
1310+
return submitToAccountID;
1311+
}
1312+
1313+
if (!hasReliablePolicyRoute && isValidExistingManagerID) {
1314+
return existingManagerID;
1315+
}
1316+
1317+
return isValidSubmitToAccountID ? submitToAccountID : existingManagerID;
1318+
}
1319+
12951320
function getManagerAccountEmail(policy: OnyxEntry<Policy>, expenseReport: OnyxEntry<Report>): string {
12961321
const managerAccountID = getManagerAccountID(policy, expenseReport);
12971322
return getLoginsByAccountIDs([managerAccountID]).at(0) ?? '';
@@ -2267,6 +2292,7 @@ export {
22672292
getDefaultChatEnabledPolicy,
22682293
getForwardsToAccount,
22692294
getSubmitToAccountID,
2295+
getSubmitReportManagerAccountID,
22702296
getAllTaxRatesNamesAndKeys as getAllTaxRates,
22712297
getAllTaxRatesNamesAndValues,
22722298
getTagNamesFromTagsLists,

src/libs/actions/IOU/ReportWorkflow.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {getMicroSecondOnyxErrorWithTranslationKey} from '@libs/ErrorUtils';
1616
import Navigation from '@libs/Navigation/Navigation';
1717
import {getIsOffline} from '@libs/NetworkState';
1818
import {buildNextStepNew, buildOptimisticNextStep} from '@libs/NextStepUtils';
19-
import {arePaymentsEnabled, getSubmitToAccountID, hasDynamicExternalWorkflow, isPaidGroupPolicy, isPolicyAdmin, isSubmitAndClose} from '@libs/PolicyUtils';
19+
import {arePaymentsEnabled, getSubmitReportManagerAccountID, hasDynamicExternalWorkflow, isPaidGroupPolicy, isPolicyAdmin, isSubmitAndClose} from '@libs/PolicyUtils';
2020
import {getAllReportActions, getReportActionHtml, getReportActionText, hasPendingDEWApprove, isCreatedAction, isDeletedAction} from '@libs/ReportActionsUtils';
2121
import {
2222
buildOptimisticApprovedReportAction,
@@ -1256,10 +1256,11 @@ function submitReport({
12561256
return;
12571257
}
12581258

1259-
const parentReport = getReportOrDraftReport(expenseReport.parentReportID);
1260-
const isCurrentUserManager = currentUserAccountIDParam === expenseReport.managerID;
12611259
const isSubmitAndClosePolicy = isSubmitAndClose(policy);
12621260
const adminAccountID = policy?.role === CONST.POLICY.ROLE.ADMIN ? currentUserAccountIDParam : undefined;
1261+
const parentReport = getReportOrDraftReport(expenseReport.parentReportID);
1262+
const managerID = getSubmitReportManagerAccountID(policy, expenseReport);
1263+
const isCurrentUserManager = currentUserAccountIDParam === managerID;
12631264
const optimisticSubmittedReportAction = buildOptimisticSubmittedReportAction(
12641265
expenseReport?.total ?? 0,
12651266
expenseReport.currency ?? '',
@@ -1297,9 +1298,6 @@ function submitReport({
12971298
isASAPSubmitBetaEnabled,
12981299
isUnapprove: true,
12991300
});
1300-
const submitToAccountID = getSubmitToAccountID(policy, expenseReport);
1301-
const managerID = submitToAccountID > 0 ? submitToAccountID : expenseReport.managerID;
1302-
13031301
const optimisticData: Array<
13041302
OnyxUpdate<typeof ONYXKEYS.COLLECTION.REPORT_ACTIONS | typeof ONYXKEYS.COLLECTION.REPORT | typeof ONYXKEYS.COLLECTION.NEXT_STEP | typeof ONYXKEYS.COLLECTION.REPORT_METADATA>
13051303
> = [];
@@ -1437,8 +1435,9 @@ function submitReport({
14371435
onyxMethod: Onyx.METHOD.MERGE,
14381436
key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReport.reportID}`,
14391437
value: {
1440-
statusNum: CONST.REPORT.STATUS_NUM.OPEN,
1441-
stateNum: CONST.REPORT.STATE_NUM.OPEN,
1438+
statusNum: expenseReport.statusNum,
1439+
stateNum: expenseReport.stateNum,
1440+
managerID: expenseReport.managerID,
14421441
...(isDEWPolicy
14431442
? {}
14441443
: {

src/libs/actions/Search.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import type {SearchFullscreenNavigatorParamList} from '@libs/Navigation/types';
3030
import enhanceParameters from '@libs/Network/enhanceParameters';
3131
import {rand64} from '@libs/NumberUtils';
3232
import {getActivePaymentType} from '@libs/PaymentUtils';
33-
import {getSubmitToAccountID, getValidConnectedIntegration, isDelayedSubmissionEnabled} from '@libs/PolicyUtils';
33+
import {getSubmitReportManagerAccountID, getValidConnectedIntegration, isDelayedSubmissionEnabled} from '@libs/PolicyUtils';
3434
import type {OptimisticExportIntegrationAction} from '@libs/ReportUtils';
3535
import {
3636
buildOptimisticExportIntegrationAction,
@@ -627,6 +627,7 @@ function search({
627627
}
628628

629629
function submitMoneyRequestOnSearch(hash: number, reportList: Report[], policy: Policy[], currentSearchKey?: SearchKey) {
630+
const firstReport = (reportList.at(0) ?? {}) as Report;
630631
const optimisticData: Array<OnyxUpdate<typeof ONYXKEYS.COLLECTION.RAM_ONLY_REPORT_LOADING_STATE>> = [
631632
{
632633
onyxMethod: Onyx.METHOD.MERGE_COLLECTION,
@@ -669,10 +670,9 @@ function submitMoneyRequestOnSearch(hash: number, reportList: Report[], policy:
669670
},
670671
];
671672

672-
const report = (reportList.at(0) ?? {}) as Report;
673673
const parameters: SubmitReportParams = {
674-
reportID: report.reportID,
675-
managerAccountID: getSubmitToAccountID(policy.at(0), report) ?? report?.managerID,
674+
reportID: firstReport.reportID,
675+
managerAccountID: getSubmitReportManagerAccountID(policy.at(0), firstReport),
676676
reportActionID: rand64(),
677677
};
678678

0 commit comments

Comments
 (0)