Skip to content

Commit 048b574

Browse files
inimagaOSBotify
authored andcommitted
Merge pull request #76153 from Expensify/arosiclair-revert-73676
Revert "Merge pull request #73676 from mkzie2/mkzie2-issue/70286" (cherry picked from commit 24c9140) (cherry-picked to staging by arosiclair)
1 parent 7f1a5fa commit 048b574

File tree

8 files changed

+131
-199
lines changed

8 files changed

+131
-199
lines changed

src/libs/WorkflowUtils.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -262,11 +262,10 @@ function convertApprovalWorkflowToPolicyEmployees({
262262
continue;
263263
}
264264

265-
const previousPendingAction = previousEmployeeList[approver.email]?.pendingAction;
266265
updatedEmployeeList[approver.email] = {
267266
email: approver.email,
268267
forwardsTo,
269-
pendingAction: previousPendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE ? previousPendingAction : pendingAction,
268+
pendingAction,
270269
pendingFields: {
271270
forwardsTo: pendingAction,
272271
},
@@ -282,11 +281,10 @@ function convertApprovalWorkflowToPolicyEmployees({
282281
continue;
283282
}
284283

285-
const previousPendingAction = previousEmployeeList[email]?.pendingAction;
286284
updatedEmployeeList[email] = {
287285
...(updatedEmployeeList[email] ? updatedEmployeeList[email] : {email}),
288286
submitsTo,
289-
pendingAction: previousPendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE ? previousPendingAction : pendingAction,
287+
pendingAction,
290288
pendingFields: {
291289
submitsTo: pendingAction,
292290
},
@@ -297,11 +295,10 @@ function convertApprovalWorkflowToPolicyEmployees({
297295
// which will set the submitsTo field to the default approver email on backend.
298296
if (membersToRemove) {
299297
for (const {email} of membersToRemove) {
300-
const previousPendingAction = previousEmployeeList[email]?.pendingAction;
301298
updatedEmployeeList[email] = {
302299
...(updatedEmployeeList[email] ? updatedEmployeeList[email] : {email}),
303300
submitsTo: defaultApprover,
304-
pendingAction: previousPendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE ? previousPendingAction : pendingAction,
301+
pendingAction,
305302
};
306303
}
307304
}
@@ -310,11 +307,10 @@ function convertApprovalWorkflowToPolicyEmployees({
310307
// which will reset the forwardsTo on the backend.
311308
if (approversToRemove) {
312309
for (const {email} of approversToRemove) {
313-
const previousPendingAction = previousEmployeeList[email]?.pendingAction;
314310
updatedEmployeeList[email] = {
315311
...(updatedEmployeeList[email] ? updatedEmployeeList[email] : {email}),
316312
forwardsTo: '',
317-
pendingAction: previousPendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE ? previousPendingAction : pendingAction,
313+
pendingAction,
318314
};
319315
}
320316
}

src/libs/actions/Policy/Member.ts

Lines changed: 29 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -24,31 +24,17 @@ import * as PhoneNumber from '@libs/PhoneNumber';
2424
import {getDefaultApprover, isUserPolicyAdmin} from '@libs/PolicyUtils';
2525
import * as ReportActionsUtils from '@libs/ReportActionsUtils';
2626
import * as ReportUtils from '@libs/ReportUtils';
27-
import {updateWorkflowDataOnApproverRemoval} from '@libs/WorkflowUtils';
2827
import * as FormActions from '@userActions/FormActions';
29-
import {getRemoveApprovalWorkflowOnyxData, getUpdateApprovalWorkflowOnyxData} from '@userActions/Workflow';
3028
import CONST from '@src/CONST';
3129
import ONYXKEYS from '@src/ONYXKEYS';
32-
import type {
33-
ImportedSpreadsheetMemberData,
34-
InvitedEmailsToAccountIDs,
35-
PersonalDetails,
36-
PersonalDetailsList,
37-
Policy,
38-
PolicyEmployee,
39-
PolicyOwnershipChangeChecks,
40-
Report,
41-
ReportAction,
42-
ReportActions,
43-
} from '@src/types/onyx';
44-
import type ApprovalWorkflow from '@src/types/onyx/ApprovalWorkflow';
30+
import type {ImportedSpreadsheetMemberData, InvitedEmailsToAccountIDs, Policy, PolicyEmployee, PolicyOwnershipChangeChecks, Report, ReportAction, ReportActions} from '@src/types/onyx';
4531
import type {PendingAction} from '@src/types/onyx/OnyxCommon';
4632
import type {JoinWorkspaceResolution} from '@src/types/onyx/OriginalMessage';
4733
import type {ApprovalRule} from '@src/types/onyx/Policy';
4834
import type {NotificationPreference, Participant} from '@src/types/onyx/Report';
4935
import type {OnyxData} from '@src/types/onyx/Request';
5036
import {isEmptyObject} from '@src/types/utils/EmptyObject';
51-
import {createPolicyExpenseChats, getSetPolicyPreventSelfApprovalOnyxData} from './Policy';
37+
import {createPolicyExpenseChats} from './Policy';
5238

5339
type OnyxDataReturnType = {
5440
optimisticData: OnyxUpdate[];
@@ -409,13 +395,7 @@ function resetAccountingPreferredExporter(policyID: string, loginList: string[])
409395
* Remove the passed members from the policy employeeList
410396
* Please see https://github.com/Expensify/App/blob/main/README.md#Security for more details
411397
*/
412-
function removeMembers(
413-
policyID: string,
414-
selectedMemberEmails: string[],
415-
policyMemberEmailsToAccountIDs: Record<string, number>,
416-
approvalWorkflows: ApprovalWorkflow[],
417-
allPersonalDetails: OnyxEntry<PersonalDetailsList>,
418-
) {
398+
function removeMembers(policyID: string, selectedMemberEmails: string[], policyMemberEmailsToAccountIDs: Record<string, number>) {
419399
if (selectedMemberEmails.length === 0) {
420400
return;
421401
}
@@ -427,46 +407,6 @@ function removeMembers(
427407
// eslint-disable-next-line @typescript-eslint/no-deprecated
428408
const policy = getPolicy(policyID);
429409

430-
const optimisticData: OnyxUpdate[] = [];
431-
const successData: OnyxUpdate[] = [];
432-
const failureData: OnyxUpdate[] = [];
433-
434-
// Update approval workflows after member removal
435-
// Check if any of the account IDs are approvers
436-
const hasApprovers = selectedMemberEmails.some((selectedMemberEmail) => isApprover(policy, selectedMemberEmail));
437-
const ownerDetails = allPersonalDetails?.[policy?.ownerAccountID ?? CONST.DEFAULT_NUMBER_ID] ?? ({} as PersonalDetails);
438-
439-
if (hasApprovers) {
440-
const ownerEmail = ownerDetails.login;
441-
// eslint-disable-next-line unicorn/no-array-for-each
442-
accountIDs.forEach((accountID) => {
443-
const removedApprover = allPersonalDetails?.[accountID];
444-
if (!removedApprover?.login || !ownerEmail) {
445-
return;
446-
}
447-
const updatedWorkflows = updateWorkflowDataOnApproverRemoval({
448-
approvalWorkflows,
449-
removedApprover,
450-
ownerDetails,
451-
});
452-
// eslint-disable-next-line unicorn/no-array-for-each
453-
updatedWorkflows.forEach((workflow) => {
454-
if (workflow?.removeApprovalWorkflow) {
455-
const {removeApprovalWorkflow, ...updatedWorkflow} = workflow;
456-
const onyxDataForRemoveApprovalWorkflow = getRemoveApprovalWorkflowOnyxData(updatedWorkflow, policy);
457-
optimisticData.push(...(onyxDataForRemoveApprovalWorkflow.optimisticData ?? []));
458-
successData.push(...(onyxDataForRemoveApprovalWorkflow.successData ?? []));
459-
failureData.push(...(onyxDataForRemoveApprovalWorkflow.failureData ?? []));
460-
} else {
461-
const onyxDataForUpdateApprovalWorkflow = getUpdateApprovalWorkflowOnyxData(workflow, [], [], policy);
462-
optimisticData.push(...(onyxDataForUpdateApprovalWorkflow.optimisticData ?? []));
463-
successData.push(...(onyxDataForUpdateApprovalWorkflow.successData ?? []));
464-
failureData.push(...(onyxDataForUpdateApprovalWorkflow.failureData ?? []));
465-
}
466-
});
467-
});
468-
}
469-
470410
const workspaceChats = ReportUtils.getWorkspaceChats(policyID, accountIDs);
471411
const optimisticClosedReportActions = workspaceChats.map(() =>
472412
ReportUtils.buildOptimisticClosedReportAction(sessionEmail, policy?.name ?? '', CONST.REPORT.ARCHIVE_REASON.REMOVED_FROM_POLICY),
@@ -537,32 +477,38 @@ function removeMembers(
537477
const approvalRules: ApprovalRule[] = policy?.rules?.approvalRules ?? [];
538478
const optimisticApprovalRules = approvalRules.filter((rule) => !selectedMemberEmails.includes(rule?.approver ?? ''));
539479

540-
optimisticData.push({
541-
onyxMethod: Onyx.METHOD.MERGE,
542-
key: policyKey,
543-
value: {
544-
employeeList: optimisticMembersState,
545-
approver: selectedMemberEmails.includes(policy?.approver ?? '') ? policy?.owner : policy?.approver,
546-
rules: {
547-
...(policy?.rules ?? {}),
548-
approvalRules: optimisticApprovalRules,
480+
const optimisticData: OnyxUpdate[] = [
481+
{
482+
onyxMethod: Onyx.METHOD.MERGE,
483+
key: policyKey,
484+
value: {
485+
employeeList: optimisticMembersState,
486+
approver: selectedMemberEmails.includes(policy?.approver ?? '') ? policy?.owner : policy?.approver,
487+
rules: {
488+
...(policy?.rules ?? {}),
489+
approvalRules: optimisticApprovalRules,
490+
},
549491
},
550492
},
551-
});
493+
];
552494
optimisticData.push(...announceRoomMembers.optimisticData, ...adminRoomMembers.optimisticData, ...preferredExporterOnyxData.optimisticData);
553495

554-
successData.push({
555-
onyxMethod: Onyx.METHOD.MERGE,
556-
key: policyKey,
557-
value: {employeeList: successMembersState},
558-
});
496+
const successData: OnyxUpdate[] = [
497+
{
498+
onyxMethod: Onyx.METHOD.MERGE,
499+
key: policyKey,
500+
value: {employeeList: successMembersState},
501+
},
502+
];
559503
successData.push(...announceRoomMembers.successData, ...adminRoomMembers.successData, ...preferredExporterOnyxData.successData);
560504

561-
failureData.push({
562-
onyxMethod: Onyx.METHOD.MERGE,
563-
key: policyKey,
564-
value: {employeeList: failureMembersState, approver: policy?.approver, rules: policy?.rules},
565-
});
505+
const failureData: OnyxUpdate[] = [
506+
{
507+
onyxMethod: Onyx.METHOD.MERGE,
508+
key: policyKey,
509+
value: {employeeList: failureMembersState, approver: policy?.approver, rules: policy?.rules},
510+
},
511+
];
566512
failureData.push(...announceRoomMembers.failureData, ...adminRoomMembers.failureData, ...preferredExporterOnyxData.failureData);
567513

568514
const pendingChatMembers = ReportUtils.getPendingChatMembers(accountIDs, [], CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE);
@@ -701,16 +647,6 @@ function removeMembers(
701647
policyID,
702648
};
703649

704-
// Update "Prevent Self Approvals" after member removal
705-
const previousEmployeesCount = Object.values(policy?.employeeList ?? {}).filter((employee) => employee.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE).length;
706-
const remainingEmployeeCount = previousEmployeesCount - accountIDs.length;
707-
if (remainingEmployeeCount === 1 && policy?.preventSelfApproval) {
708-
const onyxDataForSetPolicyPreventSelfApproval = getSetPolicyPreventSelfApprovalOnyxData(policyID, false);
709-
optimisticData.push(...(onyxDataForSetPolicyPreventSelfApproval.optimisticData ?? []));
710-
successData.push(...(onyxDataForSetPolicyPreventSelfApproval.successData ?? []));
711-
failureData.push(...(onyxDataForSetPolicyPreventSelfApproval.failureData ?? []));
712-
}
713-
714650
API.write(WRITE_COMMANDS.DELETE_MEMBERS_FROM_WORKSPACE, params, {optimisticData, successData, failureData});
715651
}
716652

src/libs/actions/Policy/Policy.ts

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5680,13 +5680,18 @@ function setPolicyPreventMemberCreatedTitle(policyID: string, enforced: boolean)
56805680
});
56815681
}
56825682

5683-
function getSetPolicyPreventSelfApprovalOnyxData(policyID: string, preventSelfApproval: boolean): OnyxData {
5683+
/**
5684+
* Call the API to enable or disable self approvals for the reports
5685+
* @param policyID - id of the policy to apply the naming pattern to
5686+
* @param preventSelfApproval - flag whether to prevent workspace members from approving their own expense reports
5687+
*/
5688+
function setPolicyPreventSelfApproval(policyID: string, preventSelfApproval: boolean) {
56845689
// This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850
56855690
// eslint-disable-next-line @typescript-eslint/no-deprecated
56865691
const policy = getPolicy(policyID);
56875692

56885693
if (preventSelfApproval === policy?.preventSelfApproval) {
5689-
return {};
5694+
return;
56905695
}
56915696

56925697
const optimisticData: OnyxUpdate[] = [
@@ -5731,25 +5736,6 @@ function getSetPolicyPreventSelfApprovalOnyxData(policyID: string, preventSelfAp
57315736
},
57325737
];
57335738

5734-
return {optimisticData, failureData, successData};
5735-
}
5736-
5737-
/**
5738-
* Call the API to enable or disable self approvals for the reports
5739-
* @param policyID - id of the policy to apply the naming pattern to
5740-
* @param preventSelfApproval - flag whether to prevent workspace members from approving their own expense reports
5741-
*/
5742-
function setPolicyPreventSelfApproval(policyID: string, preventSelfApproval: boolean) {
5743-
// This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850
5744-
// eslint-disable-next-line @typescript-eslint/no-deprecated
5745-
const policy = getPolicy(policyID);
5746-
5747-
if (preventSelfApproval === policy?.preventSelfApproval) {
5748-
return;
5749-
}
5750-
5751-
const {optimisticData, failureData, successData} = getSetPolicyPreventSelfApprovalOnyxData(policyID, preventSelfApproval);
5752-
57535739
const parameters: SetPolicyPreventSelfApprovalParams = {
57545740
preventSelfApproval,
57555741
policyID,
@@ -6550,5 +6536,4 @@ export {
65506536
clearPolicyTitleFieldError,
65516537
inviteWorkspaceEmployeesToUber,
65526538
setWorkspaceConfirmationCurrency,
6553-
getSetPolicyPreventSelfApprovalOnyxData,
65546539
};

src/libs/actions/Workflow.ts

Lines changed: 6 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import ONYXKEYS from '@src/ONYXKEYS';
1212
import type {ApprovalWorkflowOnyx, PersonalDetailsList, Policy} from '@src/types/onyx';
1313
import type {Approver, Member} from '@src/types/onyx/ApprovalWorkflow';
1414
import type ApprovalWorkflow from '@src/types/onyx/ApprovalWorkflow';
15-
import type {OnyxData} from '@src/types/onyx/Request';
1615
import {isEmptyObject} from '@src/types/utils/EmptyObject';
1716

1817
type SetApprovalWorkflowApproverParams = {
@@ -83,9 +82,9 @@ function createApprovalWorkflow(approvalWorkflow: ApprovalWorkflow, policy: Onyx
8382
API.write(WRITE_COMMANDS.CREATE_WORKSPACE_APPROVAL, parameters, {optimisticData, failureData, successData});
8483
}
8584

86-
function getUpdateApprovalWorkflowOnyxData(approvalWorkflow: ApprovalWorkflow, membersToRemove: Member[], approversToRemove: Approver[], policy: OnyxEntry<Policy>): OnyxData {
85+
function updateApprovalWorkflow(approvalWorkflow: ApprovalWorkflow, membersToRemove: Member[], approversToRemove: Approver[], policy: OnyxEntry<Policy>) {
8786
if (!policy) {
88-
return {};
87+
return;
8988
}
9089

9190
const previousDefaultApprover = getDefaultApprover(policy);
@@ -102,7 +101,7 @@ function getUpdateApprovalWorkflowOnyxData(approvalWorkflow: ApprovalWorkflow, m
102101

103102
// If there are no changes to the employees list, we can exit early
104103
if (isEmptyObject(updatedEmployees) && !newDefaultApprover) {
105-
return {};
104+
return;
106105
}
107106

108107
const optimisticData: OnyxUpdate[] = [
@@ -143,33 +142,6 @@ function getUpdateApprovalWorkflowOnyxData(approvalWorkflow: ApprovalWorkflow, m
143142
},
144143
];
145144

146-
return {optimisticData, failureData, successData};
147-
}
148-
149-
function updateApprovalWorkflow(approvalWorkflow: ApprovalWorkflow, membersToRemove: Member[], approversToRemove: Approver[], policy: OnyxEntry<Policy>) {
150-
if (!policy) {
151-
return;
152-
}
153-
154-
const previousDefaultApprover = getDefaultApprover(policy);
155-
const newDefaultApprover = approvalWorkflow.isDefault ? approvalWorkflow.approvers.at(0)?.email : undefined;
156-
const previousEmployeeList = Object.fromEntries(Object.entries(policy.employeeList ?? {}).map(([key, value]) => [key, {...value, pendingAction: null}]));
157-
const updatedEmployees = convertApprovalWorkflowToPolicyEmployees({
158-
previousEmployeeList,
159-
approvalWorkflow,
160-
type: CONST.APPROVAL_WORKFLOW.TYPE.UPDATE,
161-
membersToRemove,
162-
approversToRemove,
163-
defaultApprover: newDefaultApprover ?? previousDefaultApprover ?? '',
164-
});
165-
166-
// If there are no changes to the employees list, we can exit early
167-
if (isEmptyObject(updatedEmployees) && !newDefaultApprover) {
168-
return;
169-
}
170-
171-
const {optimisticData, failureData, successData} = getUpdateApprovalWorkflowOnyxData(approvalWorkflow, membersToRemove, approversToRemove, policy);
172-
173145
const parameters: UpdateWorkspaceApprovalParams = {
174146
policyID: policy.id,
175147
employees: JSON.stringify(Object.values(updatedEmployees)),
@@ -178,12 +150,12 @@ function updateApprovalWorkflow(approvalWorkflow: ApprovalWorkflow, membersToRem
178150
API.write(WRITE_COMMANDS.UPDATE_WORKSPACE_APPROVAL, parameters, {optimisticData, failureData, successData});
179151
}
180152

181-
function getRemoveApprovalWorkflowOnyxData(approvalWorkflow: ApprovalWorkflow, policy: OnyxEntry<Policy>): OnyxData {
153+
function removeApprovalWorkflow(approvalWorkflow: ApprovalWorkflow, policy: OnyxEntry<Policy>) {
182154
if (!policy) {
183-
return {};
155+
return;
184156
}
185157

186-
const previousEmployeeList = policy.employeeList ?? {};
158+
const previousEmployeeList = Object.fromEntries(Object.entries(policy.employeeList ?? {}).map(([key, value]) => [key, {...value, pendingAction: null}]));
187159
const updatedEmployees = convertApprovalWorkflowToPolicyEmployees({previousEmployeeList, approvalWorkflow, type: CONST.APPROVAL_WORKFLOW.TYPE.REMOVE});
188160
const updatedEmployeeList = {...previousEmployeeList, ...updatedEmployees};
189161

@@ -228,19 +200,6 @@ function getRemoveApprovalWorkflowOnyxData(approvalWorkflow: ApprovalWorkflow, p
228200
},
229201
];
230202

231-
return {optimisticData, failureData, successData};
232-
}
233-
234-
function removeApprovalWorkflow(approvalWorkflow: ApprovalWorkflow, policy: OnyxEntry<Policy>) {
235-
if (!policy) {
236-
return;
237-
}
238-
239-
const previousEmployeeList = Object.fromEntries(Object.entries(policy.employeeList ?? {}).map(([key, value]) => [key, {...value, pendingAction: null}]));
240-
const updatedEmployees = convertApprovalWorkflowToPolicyEmployees({previousEmployeeList, approvalWorkflow, type: CONST.APPROVAL_WORKFLOW.TYPE.REMOVE});
241-
242-
const {optimisticData, failureData, successData} = getRemoveApprovalWorkflowOnyxData(approvalWorkflow, policy);
243-
244203
const parameters: RemoveWorkspaceApprovalParams = {policyID: policy.id, employees: JSON.stringify(Object.values(updatedEmployees))};
245204
API.write(WRITE_COMMANDS.REMOVE_WORKSPACE_APPROVAL, parameters, {optimisticData, failureData, successData});
246205
}
@@ -363,6 +322,4 @@ export {
363322
clearApprovalWorkflowApprovers,
364323
clearApprovalWorkflow,
365324
validateApprovalWorkflow,
366-
getRemoveApprovalWorkflowOnyxData,
367-
getUpdateApprovalWorkflowOnyxData,
368325
};

0 commit comments

Comments
 (0)