Skip to content

Commit

Permalink
reset preferred exporter when admin is removed
Browse files Browse the repository at this point in the history
  • Loading branch information
FitseTLT committed Feb 25, 2025
1 parent 9abc56b commit dae7718
Show file tree
Hide file tree
Showing 2 changed files with 186 additions and 46 deletions.
139 changes: 138 additions & 1 deletion src/libs/actions/Policy/Member.ts
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,127 @@ function removeOptimisticRoomMembers(

return roomMembers;
}
/** This function will reset the preferred exporter to the owner of the workspace
* if the current preferred exporter is removed from the admin role.
*/
function resetAccountingPreferredExporter(policyID: string, loginList: string[]) {
const policy = getPolicy(policyID);
const owner = ReportUtils.getPersonalDetailsForAccountID(policy?.ownerAccountID).login ?? '';
const optimisticData: OnyxUpdate[] = [];
const successData: OnyxUpdate[] = [];
const failureData: OnyxUpdate[] = [];
const policyKey = `${ONYXKEYS.COLLECTION.POLICY}${policyID}` as const;

if (policy?.connections?.xero?.config.export.exporter && loginList.includes(policy?.connections?.xero?.config.export.exporter)) {
optimisticData.push({
onyxMethod: Onyx.METHOD.MERGE,
key: policyKey,
value: {
connections: {xero: {config: {export: {exporter: owner}, pendingFields: {exporter: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}}}},
},
});
successData.push({
onyxMethod: Onyx.METHOD.MERGE,
key: policyKey,
value: {
connections: {xero: {config: {pendingFields: {exporter: null}}}},
},
});
failureData.push({
onyxMethod: Onyx.METHOD.MERGE,
key: policyKey,
value: {connections: {xero: {config: {export: {exporter: policy?.connections?.xero?.config.export.exporter}, pendingFields: {exporter: null}}}}},
});
} else if (policy?.connections?.netsuite?.options.config.exporter && loginList.includes(policy?.connections?.netsuite?.options.config.exporter)) {
optimisticData.push({
onyxMethod: Onyx.METHOD.MERGE,
key: policyKey,
value: {
connections: {netsuite: {options: {config: {exporter: owner, pendingFields: {exporter: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}}}}},
},
});
successData.push({
onyxMethod: Onyx.METHOD.MERGE,
key: policyKey,
value: {
connections: {netsuite: {options: {config: {pendingFields: {exporter: null}}}}},
},
});
failureData.push({
onyxMethod: Onyx.METHOD.MERGE,
key: policyKey,
value: {connections: {netsuite: {options: {config: {exporter: policy?.connections?.netsuite?.options.config.exporter, pendingFields: {exporter: null}}}}}},
});
} else if (policy?.connections?.quickbooksOnline?.config.export.exporter && loginList.includes(policy?.connections?.quickbooksOnline?.config.export.exporter)) {
optimisticData.push({
onyxMethod: Onyx.METHOD.MERGE,
key: policyKey,
value: {
connections: {quickbooksOnline: {config: {export: {exporter: owner}, pendingFields: {export: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}}}},
},
});
successData.push({
onyxMethod: Onyx.METHOD.MERGE,
key: policyKey,
value: {
connections: {quickbooksOnline: {config: {pendingFields: {export: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}}}},
},
});
failureData.push({
onyxMethod: Onyx.METHOD.MERGE,
key: policyKey,
value: {
connections: {
quickbooksOnline: {
config: {export: {exporter: policy?.connections?.quickbooksOnline?.config.export.exporter}, pendingFields: {export: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}},
},
},
},
});
} else if (policy?.connections?.intacct?.config.export.exporter && loginList.includes(policy?.connections?.intacct?.config.export.exporter)) {
optimisticData.push({
onyxMethod: Onyx.METHOD.MERGE,
key: policyKey,
value: {
connections: {intacct: {config: {export: {exporter: owner}, pendingFields: {exporter: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}}}},
},
});
successData.push({
onyxMethod: Onyx.METHOD.MERGE,
key: policyKey,
value: {
connections: {intacct: {config: {pendingFields: {exporter: null}}}},
},
});
failureData.push({
onyxMethod: Onyx.METHOD.MERGE,
key: policyKey,
value: {connections: {intacct: {config: {export: {exporter: policy?.connections?.intacct?.config.export.exporter}, pendingFields: {exporter: null}}}}},
});
} else if (policy?.connections?.quickbooksDesktop?.config.export.exporter && loginList.includes(policy?.connections?.quickbooksDesktop?.config.export.exporter)) {
optimisticData.push({
onyxMethod: Onyx.METHOD.MERGE,
key: policyKey,
value: {
connections: {quickbooksDesktop: {config: {export: {exporter: owner}, pendingFields: {exporter: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}}}},
},
});
successData.push({
onyxMethod: Onyx.METHOD.MERGE,
key: policyKey,
value: {
connections: {quickbooksDesktop: {config: {pendingFields: {exporter: null}}}},
},
});
failureData.push({
onyxMethod: Onyx.METHOD.MERGE,
key: policyKey,
value: {connections: {quickbooksDesktop: {config: {export: {exporter: policy?.connections?.quickbooksDesktop?.config.export.exporter}, pendingFields: {exporter: null}}}}},
});
}

return {optimisticData, successData, failureData};
}

/**
* Remove the passed members from the policy employeeList
Expand Down Expand Up @@ -430,6 +551,14 @@ function removeMembers(accountIDs: number[], policyID: string) {
];
failureData.push(...announceRoomMembers.onyxFailureData, ...adminRoomMembers.onyxFailureData);

const previousAdminLogins = emailList.filter((login) => policy?.employeeList?.[login]?.role === CONST.POLICY.ROLE.ADMIN);
if (previousAdminLogins.length) {
const preferredExporterOnyxData = resetAccountingPreferredExporter(policyID, previousAdminLogins);
optimisticData.push(...preferredExporterOnyxData.optimisticData);
successData.push(...preferredExporterOnyxData.successData);
failureData.push(...preferredExporterOnyxData.failureData);
}

const pendingChatMembers = ReportUtils.getPendingChatMembers(accountIDs, [], CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE);

workspaceChats.forEach((report) => {
Expand Down Expand Up @@ -529,7 +658,7 @@ function removeMembers(accountIDs: number[], policyID: string) {
}

function updateWorkspaceMembersRole(policyID: string, accountIDs: number[], newRole: ValueOf<typeof CONST.POLICY.ROLE>) {
const previousEmployeeList = {...allPolicies?.[policyID]?.employeeList};
const previousEmployeeList = {...allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]?.employeeList};
const memberRoles: WorkspaceMembersRoleData[] = accountIDs.reduce((result: WorkspaceMembersRoleData[], accountID: number) => {
if (!allPersonalDetails?.[accountID]?.login) {
return result;
Expand Down Expand Up @@ -589,6 +718,14 @@ function updateWorkspaceMembersRole(policyID: string, accountIDs: number[], newR
},
];

if (newRole !== CONST.POLICY.ROLE.ADMIN) {
const previousAdminLogins = memberRoles.filter((member) => previousEmployeeList[member.email]?.role === CONST.POLICY.ROLE.ADMIN).map((member) => member.email);
const preferredExporterOnyxData = resetAccountingPreferredExporter(policyID, previousAdminLogins);
optimisticData.push(...preferredExporterOnyxData.optimisticData);
successData.push(...preferredExporterOnyxData.successData);
failureData.push(...preferredExporterOnyxData.failureData);
}

const adminRoom = ReportUtils.getAllPolicyReports(policyID).find(ReportUtils.isAdminRoom);
if (adminRoom) {
const failureDataParticipants: Record<number, Participant | null> = {...adminRoom.participants};
Expand Down
93 changes: 48 additions & 45 deletions src/types/onyx/Policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1373,67 +1373,70 @@ type QBDConnectionData = {
/**
* User configuration for the QuickBooks Desktop accounting integration.
*/
type QBDConnectionConfig = OnyxCommon.OnyxValueWithOfflineFeedback<{
/** API provider */
apiProvider: string;
type QBDConnectionConfig = OnyxCommon.OnyxValueWithOfflineFeedback<
{
/** API provider */
apiProvider: string;

/** Configuration of automatic synchronization from QuickBooks Desktop to the app */
autoSync: {
/** Job ID of the synchronization */
jobID: string;
/** Configuration of automatic synchronization from QuickBooks Desktop to the app */
autoSync: {
/** Job ID of the synchronization */
jobID: string;

/** Whether changes made in QuickBooks Desktop should be reflected into the app automatically */
enabled: boolean;
};
/** Whether changes made in QuickBooks Desktop should be reflected into the app automatically */
enabled: boolean;
};

/** Whether a check to be printed */
markChecksToBePrinted: boolean;
/** Whether a check to be printed */
markChecksToBePrinted: boolean;

/** Determines if a vendor should be automatically created */
shouldAutoCreateVendor: boolean;
/** Determines if a vendor should be automatically created */
shouldAutoCreateVendor: boolean;

/** Whether items is imported */
importItems: boolean;
/** Whether items is imported */
importItems: boolean;

/** Configuration of the export */
export: {
/** E-mail of the exporter */
exporter: string;
/** Configuration of the export */
export: {
/** E-mail of the exporter */
exporter: string;

/** Defines how reimbursable expenses are exported */
reimbursable: QBDReimbursableExportAccountType;
/** Defines how reimbursable expenses are exported */
reimbursable: QBDReimbursableExportAccountType;

/** Account that receives the reimbursable expenses */
reimbursableAccount: string;
/** Account that receives the reimbursable expenses */
reimbursableAccount: string;

/** Export date type */
exportDate: ValueOf<typeof CONST.QUICKBOOKS_EXPORT_DATE>;
/** Export date type */
exportDate: ValueOf<typeof CONST.QUICKBOOKS_EXPORT_DATE>;

/** Defines how non-reimbursable expenses are exported */
nonReimbursable: QBDNonReimbursableExportAccountType;
/** Defines how non-reimbursable expenses are exported */
nonReimbursable: QBDNonReimbursableExportAccountType;

/** Account that receives the non reimbursable expenses */
nonReimbursableAccount: string;
/** Account that receives the non reimbursable expenses */
nonReimbursableAccount: string;

/** Default vendor of non reimbursable bill */
nonReimbursableBillDefaultVendor: string;
};
/** Default vendor of non reimbursable bill */
nonReimbursableBillDefaultVendor: string;
};

/** Configuration of import settings from QuickBooks Desktop to the app */
mappings: {
/** How QuickBooks Desktop classes displayed as */
classes: IntegrationEntityMap;
/** Configuration of import settings from QuickBooks Desktop to the app */
mappings: {
/** How QuickBooks Desktop classes displayed as */
classes: IntegrationEntityMap;

/** How QuickBooks Desktop customers displayed as */
customers: IntegrationEntityMap;
};
/** How QuickBooks Desktop customers displayed as */
customers: IntegrationEntityMap;
};

/** Whether new categories are enabled in chart of accounts */
enableNewCategories: boolean;
/** Whether new categories are enabled in chart of accounts */
enableNewCategories: boolean;

/** Collections of form field errors */
errorFields?: OnyxCommon.ErrorFields;
}>;
/** Collections of form field errors */
errorFields?: OnyxCommon.ErrorFields;
},
'exporter'
>;

/** State of integration connection */
type Connection<ConnectionData, ConnectionConfig> = {
Expand Down

0 comments on commit dae7718

Please sign in to comment.