From 2af05150f9f3e4746e5871e0caa221990b1615c5 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Tue, 22 Oct 2024 01:23:28 +0700 Subject: [PATCH 1/9] update getSubmitToAccountID with category and tag approver --- src/libs/Permissions.ts | 1 + src/libs/PolicyUtils.ts | 32 ++++++++++++++++++++++++++++---- src/libs/ReportUtils.ts | 11 ++++++----- src/libs/actions/IOU.ts | 9 ++++----- 4 files changed, 39 insertions(+), 14 deletions(-) diff --git a/src/libs/Permissions.ts b/src/libs/Permissions.ts index 24de2e612208..47fa860af63c 100644 --- a/src/libs/Permissions.ts +++ b/src/libs/Permissions.ts @@ -4,6 +4,7 @@ import type {IOUType} from '@src/CONST'; import type Beta from '@src/types/onyx/Beta'; function canUseAllBetas(betas: OnyxEntry): boolean { + return true; return !!betas?.includes(CONST.BETAS.ALL); } diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 3e0ae7cba291..5f703bc27879 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -8,7 +8,7 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import INPUT_IDS from '@src/types/form/NetSuiteCustomFieldForm'; -import type {OnyxInputOrEntry, Policy, PolicyCategories, PolicyEmployeeList, PolicyTagLists, PolicyTags, TaxRate} from '@src/types/onyx'; +import type {OnyxInputOrEntry, Policy, PolicyCategories, PolicyEmployeeList, PolicyTagLists, PolicyTags, Report, TaxRate} from '@src/types/onyx'; import type {CardFeedData} from '@src/types/onyx/CardFeeds'; import type {ErrorFields, PendingAction, PendingFields} from '@src/types/onyx/OnyxCommon'; import type { @@ -31,10 +31,13 @@ import type { import type PolicyEmployee from '@src/types/onyx/PolicyEmployee'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import {hasSynchronizationErrorMessage} from './actions/connections'; +import {getCategoryApproverRule} from './CategoryUtils'; import * as Localize from './Localize'; import Navigation from './Navigation/Navigation'; import * as NetworkStore from './Network/NetworkStore'; import {getAccountIDsByLogins, getLoginsByAccountIDs, getPersonalDetailByEmail} from './PersonalDetailsUtils'; +import {getTransactionDetails} from './ReportUtils'; +import {getAllReportTransactions} from './TransactionUtils'; type MemberEmailsToAccountIDs = Record; @@ -514,10 +517,31 @@ function getDefaultApprover(policy: OnyxEntry): string { /** * Returns the accountID to whom the given employeeAccountID submits reports to in the given Policy. */ -function getSubmitToAccountID(policy: OnyxEntry, employeeAccountID: number): number { +function getSubmitToAccountID(policy: OnyxEntry, expenseReport: OnyxEntry): number { + const employeeAccountID = expenseReport?.ownerAccountID ?? -1; const employeeLogin = getLoginsByAccountIDs([employeeAccountID]).at(0) ?? ''; const defaultApprover = getDefaultApprover(policy); + let categoryAppover; + let tagApprover; + const allTransactions = getAllReportTransactions(expenseReport?.reportID).sort((transA, transB) => (transA.created < transB.created ? -1 : 1)); + + for (let i = 0; i < allTransactions.length; i++) { + const {tag = '', category = ''} = getTransactionDetails(allTransactions.at(i)) ?? {}; + categoryAppover = getCategoryApproverRule(policy?.rules?.approvalRules ?? [], category)?.approver; + if (categoryAppover) { + return getAccountIDsByLogins([categoryAppover]).at(0) ?? -1; + } + + if (!tagApprover && getTagApproverRule(policy?.id ?? '-1', tag)?.approver) { + tagApprover = getTagApproverRule(policy?.id ?? '-1', tag)?.approver; + } + } + + if (tagApprover) { + return getAccountIDsByLogins([tagApprover]).at(0) ?? -1; + } + // For policy using the optional or basic workflow, the manager is the policy default approver. if (([CONST.POLICY.APPROVAL_MODE.OPTIONAL, CONST.POLICY.APPROVAL_MODE.BASIC] as Array>).includes(getApprovalWorkflow(policy))) { return getAccountIDsByLogins([defaultApprover]).at(0) ?? -1; @@ -531,8 +555,8 @@ function getSubmitToAccountID(policy: OnyxEntry, employeeAccountID: numb return getAccountIDsByLogins([employee.submitsTo ?? defaultApprover]).at(0) ?? -1; } -function getSubmitToEmail(policy: OnyxEntry, employeeAccountID: number): string { - const submitToAccountID = getSubmitToAccountID(policy, employeeAccountID); +function getSubmitToEmail(policy: OnyxEntry, expenseReport: OnyxEntry): string { + const submitToAccountID = getSubmitToAccountID(policy, expenseReport); return getLoginsByAccountIDs([submitToAccountID]).at(0) ?? ''; } diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 1ef60b626ac7..306ef147cbd9 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -3081,7 +3081,7 @@ function canEditMoneyRequest(reportAction: OnyxInputOrEntry, approverAcco function isAllowedToSubmitDraftExpenseReport(report: OnyxEntry): boolean { const policy = getPolicy(report?.policyID); - const submitToAccountID = PolicyUtils.getSubmitToAccountID(policy, report?.ownerAccountID ?? -1); + const submitToAccountID = PolicyUtils.getSubmitToAccountID(policy, report); return isAllowedToApproveExpenseReport(report, submitToAccountID); } @@ -8256,15 +8256,16 @@ function isExported(reportActions: OnyxEntry) { return Object.values(reportActions).some((action) => ReportActionsUtils.isExportIntegrationAction(action)); } -function getApprovalChain(policy: OnyxEntry, employeeAccountID: number, reportTotal: number): string[] { +function getApprovalChain(policy: OnyxEntry, expenseReport: OnyxEntry): string[] { const approvalChain: string[] = []; + const reportTotal = expenseReport?.total ?? 0; // If the policy is not on advanced approval mode, we should not use the approval chain even if it exists. if (!PolicyUtils.isControlOnAdvancedApprovalMode(policy)) { return approvalChain; } - let nextApproverEmail = PolicyUtils.getSubmitToEmail(policy, employeeAccountID); + let nextApproverEmail = PolicyUtils.getSubmitToEmail(policy, expenseReport); while (nextApproverEmail && !approvalChain.includes(nextApproverEmail)) { approvalChain.push(nextApproverEmail); diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 0d9a4887bd1d..94e29948e266 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -7080,10 +7080,9 @@ function isLastApprover(approvalChain: string[]): boolean { } function getNextApproverAccountID(report: OnyxEntry) { - const ownerAccountID = report?.ownerAccountID ?? -1; const policy = PolicyUtils.getPolicy(report?.policyID); - const approvalChain = ReportUtils.getApprovalChain(policy, ownerAccountID, report?.total ?? 0); - const submitToAccountID = PolicyUtils.getSubmitToAccountID(policy, ownerAccountID); + const approvalChain = ReportUtils.getApprovalChain(policy, report); + const submitToAccountID = PolicyUtils.getSubmitToAccountID(policy, report); if (approvalChain.length === 0) { return submitToAccountID; @@ -7111,7 +7110,7 @@ function approveMoneyRequest(expenseReport: OnyxEntry, full?: } const optimisticApprovedReportAction = ReportUtils.buildOptimisticApprovedReportAction(total, expenseReport?.currency ?? '', expenseReport?.reportID ?? '-1'); - const approvalChain = ReportUtils.getApprovalChain(PolicyUtils.getPolicy(expenseReport?.policyID), expenseReport?.ownerAccountID ?? -1, expenseReport?.total ?? 0); + const approvalChain = ReportUtils.getApprovalChain(PolicyUtils.getPolicy(expenseReport?.policyID), expenseReport); const predictedNextStatus = isLastApprover(approvalChain) ? CONST.REPORT.STATUS_NUM.APPROVED : CONST.REPORT.STATUS_NUM.SUBMITTED; const predictedNextState = isLastApprover(approvalChain) ? CONST.REPORT.STATE_NUM.APPROVED : CONST.REPORT.STATE_NUM.SUBMITTED; @@ -7472,7 +7471,7 @@ function submitReport(expenseReport: OnyxTypes.Report) { const parameters: SubmitReportParams = { reportID: expenseReport.reportID, - managerAccountID: PolicyUtils.getSubmitToAccountID(policy, expenseReport.ownerAccountID ?? -1) ?? expenseReport.managerID, + managerAccountID: PolicyUtils.getSubmitToAccountID(policy, expenseReport) ?? expenseReport.managerID, reportActionID: optimisticSubmittedReportAction.reportActionID, }; From c93c19da35dd88874dfb14aef9d795f811c6747a Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Tue, 22 Oct 2024 01:38:11 +0700 Subject: [PATCH 2/9] revert change --- src/libs/Permissions.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/Permissions.ts b/src/libs/Permissions.ts index 47fa860af63c..24de2e612208 100644 --- a/src/libs/Permissions.ts +++ b/src/libs/Permissions.ts @@ -4,7 +4,6 @@ import type {IOUType} from '@src/CONST'; import type Beta from '@src/types/onyx/Beta'; function canUseAllBetas(betas: OnyxEntry): boolean { - return true; return !!betas?.includes(CONST.BETAS.ALL); } From 7d36a2bdfe2ec300a2a3f2ef2e4714a2b0bae97b Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Tue, 22 Oct 2024 02:02:31 +0700 Subject: [PATCH 3/9] fix lint --- ios/Podfile.lock | 31 +++++++++---------------------- src/libs/PolicyUtils.ts | 7 ++++--- 2 files changed, 13 insertions(+), 25 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 1242ab7a5a39..68266651661a 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1606,29 +1606,16 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - react-native-config (1.5.3): - - react-native-config/App (= 1.5.3) - - react-native-config/App (1.5.3): - - DoubleConversion - - glog - - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - react-native-config (1.5.0): + - react-native-config/App (= 1.5.0) + - react-native-config/App (1.5.0): + - RCT-Folly - RCTRequired - RCTTypeSafety - - React-Core - - React-debug - - React-Fabric - - React-featureflags - - React-graphics - - React-ImageManager - - React-NativeModulesApple + - React + - React-Codegen - React-RCTFabric - - React-rendererdebug - - React-utils - - ReactCodegen - - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - Yoga - react-native-document-picker (9.3.1): - DoubleConversion - glog @@ -1700,7 +1687,7 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - react-native-keyboard-controller (1.14.1): + - react-native-keyboard-controller (1.14.0): - DoubleConversion - glog - hermes-engine @@ -3186,12 +3173,12 @@ SPEC CHECKSUMS: react-native-airship: e10f6823d8da49bbcb2db4bdb16ff954188afccc react-native-blob-util: 221c61c98ae507b758472ac4d2d489119d1a6c44 react-native-cameraroll: 478a0c1fcdd39f08f6ac272b7ed06e92b2c7c129 - react-native-config: 742a9e0a378a78d0eaff1fb3477d8c0ae222eb51 + react-native-config: 5ce986133b07fc258828b20b9506de0e683efc1c react-native-document-picker: e9d83c149bdd72dc01cf8dcb8df0389c6bd5fddb react-native-geolocation: b9bd12beaf0ebca61a01514517ca8455bd26fa06 react-native-image-picker: f8a13ff106bcc7eb00c71ce11fdc36aac2a44440 react-native-key-command: aae312752fcdfaa2240be9a015fc41ce54087546 - react-native-keyboard-controller: 902c07f41a415b632583b384427a71770a8b02a3 + react-native-keyboard-controller: 17d5830f2bd6c6cad44682eb2cc13f9078eff985 react-native-launch-arguments: 5f41e0abf88a15e3c5309b8875d6fd5ac43df49d react-native-netinfo: fb5112b1fa754975485884ae85a3fb6a684f49d5 react-native-pager-view: 94195f1bf32e7f78359fa20057c97e632364a08b diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 5f703bc27879..e49fc2ae41d4 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -36,8 +36,7 @@ import * as Localize from './Localize'; import Navigation from './Navigation/Navigation'; import * as NetworkStore from './Network/NetworkStore'; import {getAccountIDsByLogins, getLoginsByAccountIDs, getPersonalDetailByEmail} from './PersonalDetailsUtils'; -import {getTransactionDetails} from './ReportUtils'; -import {getAllReportTransactions} from './TransactionUtils'; +import {getAllReportTransactions, getCategory, getTag} from './TransactionUtils'; type MemberEmailsToAccountIDs = Record; @@ -527,7 +526,9 @@ function getSubmitToAccountID(policy: OnyxEntry, expenseReport: OnyxEntr const allTransactions = getAllReportTransactions(expenseReport?.reportID).sort((transA, transB) => (transA.created < transB.created ? -1 : 1)); for (let i = 0; i < allTransactions.length; i++) { - const {tag = '', category = ''} = getTransactionDetails(allTransactions.at(i)) ?? {}; + const transaction = allTransactions.at(i); + const tag = getTag(transaction); + const category = getCategory(transaction); categoryAppover = getCategoryApproverRule(policy?.rules?.approvalRules ?? [], category)?.approver; if (categoryAppover) { return getAccountIDsByLogins([categoryAppover]).at(0) ?? -1; From 3682b9f4fd89b755fcb9a9383f0bbd62b2014bc9 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Tue, 22 Oct 2024 02:04:04 +0700 Subject: [PATCH 4/9] revert pod file --- ios/Podfile.lock | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 68266651661a..1242ab7a5a39 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1606,16 +1606,29 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - react-native-config (1.5.0): - - react-native-config/App (= 1.5.0) - - react-native-config/App (1.5.0): - - RCT-Folly + - react-native-config (1.5.3): + - react-native-config/App (= 1.5.3) + - react-native-config/App (1.5.3): + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2024.01.01.00) - RCTRequired - RCTTypeSafety - - React - - React-Codegen + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-NativeModulesApple - React-RCTFabric + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core + - Yoga - react-native-document-picker (9.3.1): - DoubleConversion - glog @@ -1687,7 +1700,7 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - react-native-keyboard-controller (1.14.0): + - react-native-keyboard-controller (1.14.1): - DoubleConversion - glog - hermes-engine @@ -3173,12 +3186,12 @@ SPEC CHECKSUMS: react-native-airship: e10f6823d8da49bbcb2db4bdb16ff954188afccc react-native-blob-util: 221c61c98ae507b758472ac4d2d489119d1a6c44 react-native-cameraroll: 478a0c1fcdd39f08f6ac272b7ed06e92b2c7c129 - react-native-config: 5ce986133b07fc258828b20b9506de0e683efc1c + react-native-config: 742a9e0a378a78d0eaff1fb3477d8c0ae222eb51 react-native-document-picker: e9d83c149bdd72dc01cf8dcb8df0389c6bd5fddb react-native-geolocation: b9bd12beaf0ebca61a01514517ca8455bd26fa06 react-native-image-picker: f8a13ff106bcc7eb00c71ce11fdc36aac2a44440 react-native-key-command: aae312752fcdfaa2240be9a015fc41ce54087546 - react-native-keyboard-controller: 17d5830f2bd6c6cad44682eb2cc13f9078eff985 + react-native-keyboard-controller: 902c07f41a415b632583b384427a71770a8b02a3 react-native-launch-arguments: 5f41e0abf88a15e3c5309b8875d6fd5ac43df49d react-native-netinfo: fb5112b1fa754975485884ae85a3fb6a684f49d5 react-native-pager-view: 94195f1bf32e7f78359fa20057c97e632364a08b From b75c05605b0db964dba8a8b3f88e83ca854aa190 Mon Sep 17 00:00:00 2001 From: nkdengineer <161821005+nkdengineer@users.noreply.github.com> Date: Fri, 25 Oct 2024 02:17:26 +0700 Subject: [PATCH 5/9] Update src/libs/PolicyUtils.ts Co-authored-by: Alex Beaman --- src/libs/PolicyUtils.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 1547c4ddda02..35fb0d6b69eb 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -531,6 +531,8 @@ function getSubmitToAccountID(policy: OnyxEntry, expenseReport: OnyxEntr let tagApprover; const allTransactions = getAllReportTransactions(expenseReport?.reportID).sort((transA, transB) => (transA.created < transB.created ? -1 : 1)); + // Before submitting to their `submitsTo` (in a policy on Advanced Approvals), submit to category/tag approvers. + // Category approvers are prioritized, then tag approvers. for (let i = 0; i < allTransactions.length; i++) { const transaction = allTransactions.at(i); const tag = getTag(transaction); From de7e6a67957292ffbc1171c65c347b572c6a10f1 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Fri, 25 Oct 2024 02:24:36 +0700 Subject: [PATCH 6/9] update comment --- src/libs/PolicyUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 35fb0d6b69eb..2e7efd6afc71 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -520,7 +520,7 @@ function getDefaultApprover(policy: OnyxEntry): string { } /** - * Returns the accountID to whom the given employeeAccountID submits reports to in the given Policy. + * Returns the accountID to whom the given expenseReport submits reports to in the given Policy. */ function getSubmitToAccountID(policy: OnyxEntry, expenseReport: OnyxEntry): number { const employeeAccountID = expenseReport?.ownerAccountID ?? -1; From 4dbb1a42c10838a35c649bbff05fe71e393ddec3 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Sat, 26 Oct 2024 00:33:29 +0700 Subject: [PATCH 7/9] fix test --- src/libs/PolicyUtils.ts | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 2e7efd6afc71..d353ebcd1df4 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -37,6 +37,7 @@ import Navigation from './Navigation/Navigation'; import * as NetworkStore from './Network/NetworkStore'; import {getAccountIDsByLogins, getLoginsByAccountIDs, getPersonalDetailByEmail} from './PersonalDetailsUtils'; import {getAllReportTransactions, getCategory, getTag} from './TransactionUtils'; +import { isExpenseReport } from './ReportUtils'; type MemberEmailsToAccountIDs = Record; @@ -527,28 +528,30 @@ function getSubmitToAccountID(policy: OnyxEntry, expenseReport: OnyxEntr const employeeLogin = getLoginsByAccountIDs([employeeAccountID]).at(0) ?? ''; const defaultApprover = getDefaultApprover(policy); - let categoryAppover; - let tagApprover; - const allTransactions = getAllReportTransactions(expenseReport?.reportID).sort((transA, transB) => (transA.created < transB.created ? -1 : 1)); - - // Before submitting to their `submitsTo` (in a policy on Advanced Approvals), submit to category/tag approvers. - // Category approvers are prioritized, then tag approvers. - for (let i = 0; i < allTransactions.length; i++) { - const transaction = allTransactions.at(i); - const tag = getTag(transaction); - const category = getCategory(transaction); - categoryAppover = getCategoryApproverRule(policy?.rules?.approvalRules ?? [], category)?.approver; - if (categoryAppover) { - return getAccountIDsByLogins([categoryAppover]).at(0) ?? -1; - } + if (isExpenseReport(expenseReport)) { + let categoryAppover; + let tagApprover; + const allTransactions = getAllReportTransactions(expenseReport?.reportID).sort((transA, transB) => (transA.created < transB.created ? -1 : 1)); + + // Before submitting to their `submitsTo` (in a policy on Advanced Approvals), submit to category/tag approvers. + // Category approvers are prioritized, then tag approvers. + for (let i = 0; i < allTransactions.length; i++) { + const transaction = allTransactions.at(i); + const tag = getTag(transaction); + const category = getCategory(transaction); + categoryAppover = getCategoryApproverRule(policy?.rules?.approvalRules ?? [], category)?.approver; + if (categoryAppover) { + return getAccountIDsByLogins([categoryAppover]).at(0) ?? -1; + } - if (!tagApprover && getTagApproverRule(policy?.id ?? '-1', tag)?.approver) { - tagApprover = getTagApproverRule(policy?.id ?? '-1', tag)?.approver; + if (!tagApprover && getTagApproverRule(policy?.id ?? '-1', tag)?.approver) { + tagApprover = getTagApproverRule(policy?.id ?? '-1', tag)?.approver; + } } - } - if (tagApprover) { - return getAccountIDsByLogins([tagApprover]).at(0) ?? -1; + if (tagApprover) { + return getAccountIDsByLogins([tagApprover]).at(0) ?? -1; + } } // For policy using the optional or basic workflow, the manager is the policy default approver. From 9a789f34db26e28bdf4eb81d445e37a44c27f074 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Sat, 26 Oct 2024 00:45:20 +0700 Subject: [PATCH 8/9] fix test --- src/libs/PolicyUtils.ts | 2 +- src/libs/ReportUtils.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index d353ebcd1df4..96ca8c503eca 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -36,8 +36,8 @@ import * as Localize from './Localize'; import Navigation from './Navigation/Navigation'; import * as NetworkStore from './Network/NetworkStore'; import {getAccountIDsByLogins, getLoginsByAccountIDs, getPersonalDetailByEmail} from './PersonalDetailsUtils'; +import {isExpenseReport} from './ReportUtils'; import {getAllReportTransactions, getCategory, getTag} from './TransactionUtils'; -import { isExpenseReport } from './ReportUtils'; type MemberEmailsToAccountIDs = Record; diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 2a8546a2d915..298ac5721217 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -1295,7 +1295,7 @@ function isAwaitingFirstLevelApproval(report: OnyxEntry): boolean { return false; } - const submitsToAccountID = PolicyUtils.getSubmitToAccountID(getPolicy(report.policyID), report.ownerAccountID ?? -1); + const submitsToAccountID = PolicyUtils.getSubmitToAccountID(getPolicy(report.policyID), report); return isProcessingReport(report) && submitsToAccountID === report.managerID; } From 62c0db1b506e4819600e40a0d7bdf1c4faab4021 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Sat, 26 Oct 2024 00:47:56 +0700 Subject: [PATCH 9/9] fix cycle dependen --- src/libs/PolicyUtils.ts | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 96ca8c503eca..2e7efd6afc71 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -36,7 +36,6 @@ import * as Localize from './Localize'; import Navigation from './Navigation/Navigation'; import * as NetworkStore from './Network/NetworkStore'; import {getAccountIDsByLogins, getLoginsByAccountIDs, getPersonalDetailByEmail} from './PersonalDetailsUtils'; -import {isExpenseReport} from './ReportUtils'; import {getAllReportTransactions, getCategory, getTag} from './TransactionUtils'; type MemberEmailsToAccountIDs = Record; @@ -528,32 +527,30 @@ function getSubmitToAccountID(policy: OnyxEntry, expenseReport: OnyxEntr const employeeLogin = getLoginsByAccountIDs([employeeAccountID]).at(0) ?? ''; const defaultApprover = getDefaultApprover(policy); - if (isExpenseReport(expenseReport)) { - let categoryAppover; - let tagApprover; - const allTransactions = getAllReportTransactions(expenseReport?.reportID).sort((transA, transB) => (transA.created < transB.created ? -1 : 1)); - - // Before submitting to their `submitsTo` (in a policy on Advanced Approvals), submit to category/tag approvers. - // Category approvers are prioritized, then tag approvers. - for (let i = 0; i < allTransactions.length; i++) { - const transaction = allTransactions.at(i); - const tag = getTag(transaction); - const category = getCategory(transaction); - categoryAppover = getCategoryApproverRule(policy?.rules?.approvalRules ?? [], category)?.approver; - if (categoryAppover) { - return getAccountIDsByLogins([categoryAppover]).at(0) ?? -1; - } - - if (!tagApprover && getTagApproverRule(policy?.id ?? '-1', tag)?.approver) { - tagApprover = getTagApproverRule(policy?.id ?? '-1', tag)?.approver; - } + let categoryAppover; + let tagApprover; + const allTransactions = getAllReportTransactions(expenseReport?.reportID).sort((transA, transB) => (transA.created < transB.created ? -1 : 1)); + + // Before submitting to their `submitsTo` (in a policy on Advanced Approvals), submit to category/tag approvers. + // Category approvers are prioritized, then tag approvers. + for (let i = 0; i < allTransactions.length; i++) { + const transaction = allTransactions.at(i); + const tag = getTag(transaction); + const category = getCategory(transaction); + categoryAppover = getCategoryApproverRule(policy?.rules?.approvalRules ?? [], category)?.approver; + if (categoryAppover) { + return getAccountIDsByLogins([categoryAppover]).at(0) ?? -1; } - if (tagApprover) { - return getAccountIDsByLogins([tagApprover]).at(0) ?? -1; + if (!tagApprover && getTagApproverRule(policy?.id ?? '-1', tag)?.approver) { + tagApprover = getTagApproverRule(policy?.id ?? '-1', tag)?.approver; } } + if (tagApprover) { + return getAccountIDsByLogins([tagApprover]).at(0) ?? -1; + } + // For policy using the optional or basic workflow, the manager is the policy default approver. if (([CONST.POLICY.APPROVAL_MODE.OPTIONAL, CONST.POLICY.APPROVAL_MODE.BASIC] as Array>).includes(getApprovalWorkflow(policy))) { return getAccountIDsByLogins([defaultApprover]).at(0) ?? -1;