Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/libs/API/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,7 @@ const WRITE_COMMANDS = {
UPDATE_NETSUITE_APPROVAL_ACCOUNT: 'UpdateNetSuiteApprovalAccount',
UPDATE_NETSUITE_CUSTOM_FORM_ID_OPTIONS_REIMBURSABLE: 'UpdateNetSuiteCustomFormIDOptionsReimbursable',
UPDATE_NETSUITE_CUSTOM_FORM_ID_OPTIONS_NON_REIMBURSABLE: 'UpdateNetSuiteCustomFormIDOptionsNonReimbursable',
UPDATE_NETSUITE_TOKENS: 'UpdateNetSuiteTokens',
REQUEST_EXPENSIFY_CARD_LIMIT_INCREASE: 'RequestExpensifyCardLimitIncrease',
CONNECT_POLICY_TO_SAGE_INTACCT: 'ConnectPolicyToSageIntacct',
COPY_EXISTING_POLICY_CONNECTION: 'CopyExistingPolicyConnection',
Expand Down Expand Up @@ -1045,6 +1046,7 @@ type WriteCommandParameters = {
[WRITE_COMMANDS.UPDATE_NETSUITE_APPROVAL_ACCOUNT]: Parameters.UpdateNetSuiteGenericTypeParams<'value', string>;
[WRITE_COMMANDS.UPDATE_NETSUITE_CUSTOM_FORM_ID_OPTIONS_REIMBURSABLE]: Parameters.UpdateNetSuiteCustomFormIDParams;
[WRITE_COMMANDS.UPDATE_NETSUITE_CUSTOM_FORM_ID_OPTIONS_NON_REIMBURSABLE]: Parameters.UpdateNetSuiteCustomFormIDParams;
[WRITE_COMMANDS.UPDATE_NETSUITE_TOKENS]: Parameters.ConnectPolicyToNetSuiteParams;
[WRITE_COMMANDS.UPDATE_SAGE_INTACCT_ENTITY]: Parameters.UpdateSageIntacctGenericTypeParams<'entity', string>;
[WRITE_COMMANDS.UPDATE_SAGE_INTACCT_BILLABLE]: Parameters.UpdateSageIntacctGenericTypeParams<'enabled', boolean>;
[WRITE_COMMANDS.UPDATE_SAGE_INTACCT_DEPARTMENT_MAPPING]: Parameters.UpdateSageIntacctGenericTypeParams<'mapping', SageIntacctMappingValue>;
Expand Down
17 changes: 15 additions & 2 deletions src/libs/actions/connections/NetSuiteCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ type SubsidiaryParam = {
subsidiary: string;
};

function connectPolicyToNetSuite(policyID: string, credentials: Omit<ConnectPolicyToNetSuiteParams, 'policyID'>) {
function writeNetSuiteCredentials(
command: typeof WRITE_COMMANDS.CONNECT_POLICY_TO_NETSUITE | typeof WRITE_COMMANDS.UPDATE_NETSUITE_TOKENS,
policyID: string,
credentials: Omit<ConnectPolicyToNetSuiteParams, 'policyID'>,
) {
const optimisticData: Array<OnyxUpdate<typeof ONYXKEYS.COLLECTION.POLICY_CONNECTION_SYNC_PROGRESS>> = [
{
onyxMethod: Onyx.METHOD.MERGE,
Expand All @@ -34,7 +38,15 @@ function connectPolicyToNetSuite(policyID: string, credentials: Omit<ConnectPoli
policyID,
...credentials,
};
API.write(WRITE_COMMANDS.CONNECT_POLICY_TO_NETSUITE, parameters, {optimisticData});
API.write(command, parameters, {optimisticData});
}

function connectPolicyToNetSuite(policyID: string, credentials: Omit<ConnectPolicyToNetSuiteParams, 'policyID'>) {
writeNetSuiteCredentials(WRITE_COMMANDS.CONNECT_POLICY_TO_NETSUITE, policyID, credentials);
}

function updateNetSuiteTokens(policyID: string, credentials: Omit<ConnectPolicyToNetSuiteParams, 'policyID'>) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ CONSISTENCY-3 (docs)

The updateNetSuiteTokens function body is an exact duplicate of connectPolicyToNetSuite (lines 21-37) -- identical signature, identical optimistic data construction, identical parameter assembly. The only difference is the write command (UPDATE_NETSUITE_TOKENS vs CONNECT_POLICY_TO_NETSUITE).

Extract the shared logic into a helper that accepts the command as a parameter:

function writeNetSuiteCredentials(
    command: typeof WRITE_COMMANDS.CONNECT_POLICY_TO_NETSUITE | typeof WRITE_COMMANDS.UPDATE_NETSUITE_TOKENS,
    policyID: string,
    credentials: Omit<ConnectPolicyToNetSuiteParams, 'policyID'>,
) {
    const optimisticData: Array<OnyxUpdate<typeof ONYXKEYS.COLLECTION.POLICY_CONNECTION_SYNC_PROGRESS>> = [
        {
            onyxMethod: Onyx.METHOD.MERGE,
            key: `${ONYXKEYS.COLLECTION.POLICY_CONNECTION_SYNC_PROGRESS}${policyID}`,
            value: {
                stageInProgress: CONST.POLICY.CONNECTIONS.SYNC_STAGE_NAME.NETSUITE_SYNC_CONNECTION,
                connectionName: CONST.POLICY.CONNECTIONS.NAME.NETSUITE,
                timestamp: new Date().toISOString(),
            },
        },
    ];
    const parameters: ConnectPolicyToNetSuiteParams = {
        policyID,
        ...credentials,
    };
    API.write(command, parameters, {optimisticData});
}

function connectPolicyToNetSuite(policyID: string, credentials: Omit<ConnectPolicyToNetSuiteParams, 'policyID'>) {
    writeNetSuiteCredentials(WRITE_COMMANDS.CONNECT_POLICY_TO_NETSUITE, policyID, credentials);
}

function updateNetSuiteTokens(policyID: string, credentials: Omit<ConnectPolicyToNetSuiteParams, 'policyID'>) {
    writeNetSuiteCredentials(WRITE_COMMANDS.UPDATE_NETSUITE_TOKENS, policyID, credentials);
}

Please rate this suggestion with 👍 or 👎 to help us improve! Reactions are used to monitor reviewer efficiency.

@truph01 truph01 Mar 5, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@imgyf Could you explain about it, such as why you 👎?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@truph01 after looking through the comment again, it's actually valid so I've fixed it in the latest commit.

writeNetSuiteCredentials(WRITE_COMMANDS.UPDATE_NETSUITE_TOKENS, policyID, credentials);
}

function createPendingFields<TSettingName extends keyof Connections['netsuite']['options']['config']>(
Expand Down Expand Up @@ -1038,6 +1050,7 @@ function updateNetSuiteCustomFormIDOptions(

export {
connectPolicyToNetSuite,
updateNetSuiteTokens,
updateNetSuiteSubsidiary,
updateNetSuiteSyncTaxConfiguration,
updateNetSuiteExporter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import Text from '@components/Text';
import TextInput from '@components/TextInput';
import useAutoFocusInput from '@hooks/useAutoFocusInput';
import useLocalize from '@hooks/useLocalize';
import usePolicy from '@hooks/usePolicy';
import useThemeStyles from '@hooks/useThemeStyles';
import {connectPolicyToNetSuite} from '@libs/actions/connections/NetSuiteCommands';
import {isAuthenticationError} from '@libs/actions/connections';
import {connectPolicyToNetSuite, updateNetSuiteTokens} from '@libs/actions/connections/NetSuiteCommands';
import {isMobileSafari} from '@libs/Browser';
import {addErrorMessage} from '@libs/ErrorUtils';
import Parser from '@libs/Parser';
Expand All @@ -21,6 +23,7 @@ import INPUT_IDS from '@src/types/form/NetSuiteTokenInputForm';
function NetSuiteTokenInputForm({onNext, policyID}: CustomSubPageTokenInputProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const policy = usePolicy(policyID);
const {inputCallbackRef} = useAutoFocusInput();

const formInputs = Object.values(INPUT_IDS);
Expand All @@ -46,10 +49,14 @@ function NetSuiteTokenInputForm({onNext, policyID}: CustomSubPageTokenInputProps
return;
}

connectPolicyToNetSuite(policyID, formValues);
if (isAuthenticationError(policy, CONST.POLICY.CONNECTIONS.NAME.NETSUITE)) {
updateNetSuiteTokens(policyID, formValues);
} else {
connectPolicyToNetSuite(policyID, formValues);
}
onNext();
},
[onNext, policyID],
[onNext, policyID, policy],
);

return (
Expand Down
Loading