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
8 changes: 4 additions & 4 deletions src/hooks/useGetExpensifyCardFromReportAction.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import {useCardList, useWorkspaceCardList} from '@components/OnyxListItemProvider';
import {getPolicy, getWorkspaceAccountID, isPolicyAdmin} from '@libs/PolicyUtils';
import {getWorkspaceAccountID, isPolicyAdmin} from '@libs/PolicyUtils';
import {getOriginalMessage, isCardIssuedAction} from '@libs/ReportActionsUtils';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {Card, ReportAction} from '@src/types/onyx';
import usePolicy from './usePolicy';

function useGetExpensifyCardFromReportAction({reportAction, policyID}: {reportAction?: ReportAction; policyID?: string}): Card | undefined {
const allUserCards = useCardList();
const workspaceAccountID = getWorkspaceAccountID(policyID);
const allExpensifyCards = useWorkspaceCardList();
const policy = usePolicy(policyID);
const expensifyCards = allExpensifyCards?.[`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${CONST.EXPENSIFY_CARD.BANK}`] ?? {};

const cardIssuedActionOriginalMessage = isCardIssuedAction(reportAction) ? getOriginalMessage(reportAction) : undefined;

const cardID = cardIssuedActionOriginalMessage?.cardID ?? CONST.DEFAULT_NUMBER_ID;
// This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850
// eslint-disable-next-line @typescript-eslint/no-deprecated
return isPolicyAdmin(getPolicy(policyID)) ? expensifyCards?.[cardID] : allUserCards?.[cardID];
return isPolicyAdmin(policy) ? expensifyCards?.[cardID] : allUserCards?.[cardID];
}

export default useGetExpensifyCardFromReportAction;
13 changes: 7 additions & 6 deletions src/libs/actions/Policy/Category.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import getIsNarrowLayout from '@libs/getIsNarrowLayout';
import Log from '@libs/Log';
import enhanceParameters from '@libs/Network/enhanceParameters';
import {hasEnabledOptions} from '@libs/OptionsListUtils';
import {getPolicy, goBackWhenEnableFeature} from '@libs/PolicyUtils';
import {goBackWhenEnableFeature} from '@libs/PolicyUtils';
import {pushTransactionViolationsOnyxData} from '@libs/ReportUtils';
import {getFinishOnboardingTaskOnyxData} from '@userActions/Task';
import CONST from '@src/CONST';
Expand Down Expand Up @@ -1451,10 +1451,11 @@ function setPolicyCategoryApprover(policyID: string, categoryName: string, appro
API.write(WRITE_COMMANDS.SET_POLICY_CATEGORY_APPROVER, parameters, onyxData);
}

function setPolicyCategoryTax(policyID: string, categoryName: string, taxID: string) {
// This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850
// eslint-disable-next-line @typescript-eslint/no-deprecated
const policy = getPolicy(policyID);
function setPolicyCategoryTax(policy: OnyxEntry<Policy>, categoryName: string, taxID: string) {
if (!policy?.id) {
return;
}
const policyID = policy.id;
const expenseRules = policy?.rules?.expenseRules ?? [];
const updatedExpenseRules: ExpenseRule[] = lodashCloneDeep(expenseRules);
const existingCategoryExpenseRule = updatedExpenseRules.find((rule) => rule.applyWhen.some((when) => when.value === categoryName));
Expand All @@ -1470,7 +1471,7 @@ function setPolicyCategoryTax(policyID: string, categoryName: string, taxID: str
applyWhen: [
{
condition: CONST.POLICY.RULE_CONDITIONS.MATCHES,
field: 'category',
field: CONST.POLICY.FIELDS.CATEGORY,
value: categoryName,
},
],
Expand Down
9 changes: 5 additions & 4 deletions src/libs/actions/Policy/Tag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
import type {OnyxData} from '@src/types/onyx/Request';

let allPolicyTags: OnyxCollection<PolicyTagLists> = {};
Onyx.connect({

Check warning on line 39 in src/libs/actions/Policy/Tag.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.POLICY_TAGS,
waitForCollectionCallback: true,
callback: (value) => {
Expand Down Expand Up @@ -1164,10 +1164,11 @@
API.write(WRITE_COMMANDS.UPDATE_POLICY_TAG_GL_CODE, parameters, onyxData);
}

function setPolicyTagApprover(policyID: string, tag: string, approver: string) {
// This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850
// eslint-disable-next-line @typescript-eslint/no-deprecated
const policy = PolicyUtils.getPolicy(policyID);
function setPolicyTagApprover(policy: OnyxEntry<Policy>, tag: string, approver: string) {
if (!policy?.id) {
return;
}
const policyID = policy.id;
const prevApprovalRules = policy?.rules?.approvalRules ?? [];
const approverRuleToUpdate = PolicyUtils.getTagApproverRule(policyID, tag);
const filteredApprovalRules = approverRuleToUpdate ? prevApprovalRules.filter((rule) => rule.id !== approverRuleToUpdate.id) : prevApprovalRules;
Expand Down
5 changes: 1 addition & 4 deletions src/libs/actions/TeachersUnite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {WRITE_COMMANDS} from '@libs/API/types';
import {getMicroSecondOnyxErrorWithTranslationKey} from '@libs/ErrorUtils';
import Navigation from '@libs/Navigation/Navigation';
import {addSMSDomainIfPhoneNumber} from '@libs/PhoneNumber';
import {getPolicy} from '@libs/PolicyUtils';
import {buildOptimisticChatReport, buildOptimisticCreatedReportAction} from '@libs/ReportUtils';
import type {OptimisticCreatedReportAction} from '@libs/ReportUtils';
import CONST from '@src/CONST';
Expand Down Expand Up @@ -118,9 +117,7 @@ function addSchoolPrincipal(
name: policyName,
role: CONST.POLICY.ROLE.USER,
owner: sessionEmail,
// This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850
// eslint-disable-next-line @typescript-eslint/no-deprecated
outputCurrency: getPolicy(policyID)?.outputCurrency ?? localCurrencyCode ?? CONST.CURRENCY.USD,
outputCurrency: localCurrencyCode ?? CONST.CURRENCY.USD,
employeeList: {
[sessionEmail]: {
role: CONST.POLICY.ROLE.USER,
Expand Down
7 changes: 3 additions & 4 deletions src/pages/TransactionDuplicate/ReviewTaxCode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton';
import ScreenWrapper from '@components/ScreenWrapper';
import useLocalize from '@hooks/useLocalize';
import useOnyx from '@hooks/useOnyx';
import usePolicy from '@hooks/usePolicy';
import useReviewDuplicatesNavigation from '@hooks/useReviewDuplicatesNavigation';
import useTransactionsByID from '@hooks/useTransactionsByID';
import {setReviewDuplicatesKey} from '@libs/actions/Transaction';
import {convertToBackendAmount} from '@libs/CurrencyUtils';
import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID';
import type {PlatformStackRouteProp} from '@libs/Navigation/PlatformStackNavigation/types';
import type {TransactionDuplicateNavigatorParamList} from '@libs/Navigation/types';
import {getPolicy, getTaxByID} from '@libs/PolicyUtils';
import {getTaxByID} from '@libs/PolicyUtils';
import {calculateTaxAmount, compareDuplicateTransactionFields, getAmount, getDefaultTaxCode, getTaxValue, getTransactionID} from '@libs/TransactionUtils';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
Expand All @@ -25,9 +26,7 @@ function ReviewTaxRate() {
const {translate} = useLocalize();
const [reviewDuplicates] = useOnyx(ONYXKEYS.REVIEW_DUPLICATES, {canBeMissing: true});
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reviewDuplicates?.reportID ?? route.params.threadReportID}`, {canBeMissing: true});
// This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850
// eslint-disable-next-line @typescript-eslint/no-deprecated
const policy = getPolicy(report?.policyID);
const policy = usePolicy(report?.policyID);
const transactionID = getTransactionID(route.params.threadReportID);
const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${getNonEmptyStringOnyxID(transactionID)}`, {canBeMissing: true});
const [transactionViolations] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`, {
Expand Down
8 changes: 3 additions & 5 deletions src/pages/home/report/SystemChatReportFooterMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
import useLocalize from '@hooks/useLocalize';
import useOnyx from '@hooks/useOnyx';
import useThemeStyles from '@hooks/useThemeStyles';
import {getPolicy, shouldShowPolicy} from '@libs/PolicyUtils';
import {shouldShowPolicy} from '@libs/PolicyUtils';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
Expand All @@ -25,12 +25,10 @@ function SystemChatReportFooterMessage() {

const adminChatReportID = useMemo(() => {
const adminPolicy = activePolicyID
? // This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850
// eslint-disable-next-line @typescript-eslint/no-deprecated
getPolicy(activePolicyID)
? policies?.[`${ONYXKEYS.COLLECTION.POLICY}${activePolicyID}`]
: Object.values(policies ?? {}).find((policy) => shouldShowPolicy(policy, false, currentUserLogin) && policy?.role === CONST.POLICY.ROLE.ADMIN && policy?.chatReportIDAdmins);

return String(adminPolicy?.chatReportIDAdmins ?? -1);
return adminPolicy?.chatReportIDAdmins ?? CONST.DEFAULT_NUMBER_ID;
}, [activePolicyID, policies, currentUserLogin]);

const [adminChatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${adminChatReportID}`, {canBeMissing: true});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import * as Expensicons from '@components/Icon/Expensicons';

Check warning on line 3 in src/pages/iou/request/step/IOURequestStepPerDiemWorkspace.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

'@components/Icon/Expensicons' import is restricted from being used by a pattern. Direct imports from Icon/Expensicons are deprecated. Please use lazy loading hooks instead. Use `useMemoizedLazyExpensifyIcons` from @hooks/useLazyAsset. See docs/LAZY_ICONS_AND_ILLUSTRATIONS.md for details

Check warning on line 3 in src/pages/iou/request/step/IOURequestStepPerDiemWorkspace.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

'@components/Icon/Expensicons' import is restricted from being used. Direct imports from @components/Icon/Expensicons are deprecated. Please use lazy loading hooks instead. Use `useMemoizedLazyExpensifyIcons` from @hooks/useLazyAsset. See docs/LAZY_ICONS_AND_ILLUSTRATIONS.md for details
import SearchBar from '@components/SearchBar';
import SelectionList from '@components/SelectionList';
import type {ListItem} from '@components/SelectionList/ListItem/types';
Expand All @@ -12,7 +12,7 @@
import useSearchResults from '@hooks/useSearchResults';
import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@libs/Navigation/Navigation';
import {getActivePoliciesWithExpenseChatAndPerDiemEnabled, getPerDiemCustomUnit, getPolicy, sortWorkspacesBySelected} from '@libs/PolicyUtils';
import {getActivePoliciesWithExpenseChatAndPerDiemEnabled, getPerDiemCustomUnit, sortWorkspacesBySelected} from '@libs/PolicyUtils';
import {getDefaultWorkspaceAvatar, getPolicyExpenseChat} from '@libs/ReportUtils';
import tokenizedSearch from '@libs/tokenizedSearch';
import {setCustomUnitID, setMoneyRequestCategory, setMoneyRequestParticipants} from '@userActions/IOU';
Expand Down Expand Up @@ -92,9 +92,7 @@
if (!policyExpenseReportID) {
return;
}
// This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850
// eslint-disable-next-line @typescript-eslint/no-deprecated
const selectedPolicy = getPolicy(item.value, allPolicies);
const selectedPolicy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${item.value}`];
const perDiemUnit = getPerDiemCustomUnit(selectedPolicy);
setMoneyRequestParticipants(transactionID, [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ function CategoryDefaultTaxRatePage({
return;
}

setPolicyCategoryTax(policyID, categoryName, item.keyForList);
setPolicyCategoryTax(policy, categoryName, item.keyForList);
Navigation.setNavigationActionToMicrotaskQueue(() => Navigation.goBack(ROUTES.WORKSPACE_CATEGORY_SETTINGS.getRoute(policyID, categoryName)));
},
[policyID, categoryName, selectedTaxRate],
[policyID, policy, categoryName, selectedTaxRate],
);

return (
Expand Down
6 changes: 2 additions & 4 deletions src/pages/workspace/members/WorkspaceMemberNewCardPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {useCompanyCardFeedIcons} from '@hooks/useCompanyCardIcons';
import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset';
import useLocalize from '@hooks/useLocalize';
import useOnyx from '@hooks/useOnyx';
import usePolicy from '@hooks/usePolicy';
import useThemeIllustrations from '@hooks/useThemeIllustrations';
import useThemeStyles from '@hooks/useThemeStyles';
import {
Expand All @@ -31,7 +32,6 @@ import {
} from '@libs/CardUtils';
import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
import type {SettingsNavigatorParamList} from '@libs/Navigation/types';
import {getPolicy} from '@libs/PolicyUtils';
import Navigation from '@navigation/Navigation';
import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
import type {WithPolicyAndFullscreenLoadingProps} from '@pages/workspace/withPolicyAndFullscreenLoading';
Expand All @@ -58,9 +58,7 @@ type WorkspaceMemberNewCardPageProps = WithPolicyAndFullscreenLoadingProps & Pla

function WorkspaceMemberNewCardPage({route, personalDetails}: WorkspaceMemberNewCardPageProps) {
const {policyID} = route.params;
// This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850
// eslint-disable-next-line @typescript-eslint/no-deprecated
const policy = getPolicy(policyID);
const policy = usePolicy(policyID);
const workspaceAccountID = policy?.workspaceAccountID ?? CONST.DEFAULT_NUMBER_ID;

const {translate} = useLocalize();
Expand Down
2 changes: 1 addition & 1 deletion src/pages/workspace/tags/TagApproverPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ function TagApproverPage({route}: TagApproverPageProps) {
policyID={policyID}
selectedApprover={tagApprover ?? ''}
setApprover={(email) => {
setPolicyTagApprover(policyID, tagName, email);
setPolicyTagApprover(policy, tagName, email);
Navigation.setNavigationActionToMicrotaskQueue(goBack);
}}
/>
Expand Down
103 changes: 103 additions & 0 deletions tests/actions/PolicyCategoryTest.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import {act, renderHook} from '@testing-library/react-native';
import Onyx from 'react-native-onyx';
import OnyxUtils from 'react-native-onyx/dist/OnyxUtils';
import OnyxListItemProvider from '@components/OnyxListItemProvider';
import usePolicyData from '@hooks/usePolicyData';
import {
createPolicyCategory,
deleteWorkspaceCategories,
enablePolicyCategories,
renamePolicyCategory,
setPolicyCategoryTax,
setWorkspaceCategoryEnabled,
setWorkspaceRequiresCategory,
} from '@libs/actions/Policy/Category';
Expand Down Expand Up @@ -394,4 +396,105 @@ describe('actions/PolicyCategory', () => {
});
});
});

describe('SetPolicyCategoryTax', () => {
it('should set expense rule when category expense rule is not present', async () => {
// Given a policy
const fakePolicy = createRandomPolicy(0);
fakePolicy.areCategoriesEnabled = true;
const categoryName = 'Fake category';
const fakePolicyCategories = {
[categoryName]: {
name: categoryName,
enabled: false,
// eslint-disable-next-line @typescript-eslint/naming-convention
'GL Code': '',
unencodedName: categoryName,
externalID: '',
areCommentsRequired: false,
origin: '',
},
};

mockFetch.pause();

await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, fakePolicy);
await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${fakePolicy.id}`, fakePolicyCategories);

setPolicyCategoryTax(fakePolicy, categoryName, 'VAT');
await waitForBatchedUpdates();

// Then the approval rule should be created with the tag name
const updatedPolicy = await OnyxUtils.get(`${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`);

expect(updatedPolicy?.rules?.expenseRules).toHaveLength(1);
expect(updatedPolicy?.rules?.expenseRules?.[0]?.applyWhen?.[0]?.value).toBe(categoryName);
expect(updatedPolicy?.rules?.expenseRules?.[0]?.applyWhen?.[0]?.condition).toBe(CONST.POLICY.RULE_CONDITIONS.MATCHES);
expect(updatedPolicy?.rules?.expenseRules?.[0]?.applyWhen?.[0]?.field).toBe(CONST.POLICY.FIELDS.CATEGORY);
expect(updatedPolicy?.rules?.expenseRules?.[0].tax.field_id_TAX.externalID).toBe('VAT');

mockFetch.resume();
await waitForBatchedUpdates();
});

it('should update expense rule when category expense rule is present', async () => {
// Given a policy with approval rules that reference a tag
const fakePolicy = createRandomPolicy(0);
fakePolicy.areCategoriesEnabled = true;
const categoryName = 'Fake category';
const fakePolicyCategories = {
[categoryName]: {
name: categoryName,
enabled: false,
// eslint-disable-next-line @typescript-eslint/naming-convention
'GL Code': '',
unencodedName: categoryName,
externalID: '',
areCommentsRequired: false,
origin: '',
},
};

// Create expense rule that uses the tag
fakePolicy.rules = {
expenseRules: [
{
tax: {
// eslint-disable-next-line @typescript-eslint/naming-convention
field_id_TAX: {
externalID: 'GST',
},
},
applyWhen: [
{
condition: CONST.POLICY.RULE_CONDITIONS.MATCHES,
field: CONST.POLICY.FIELDS.CATEGORY,
value: categoryName,
},
],
},
],
};

mockFetch.pause();

await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, fakePolicy);
await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${fakePolicy.id}`, fakePolicyCategories);

setPolicyCategoryTax(fakePolicy, categoryName, 'VAT');
await waitForBatchedUpdates();

// Then the approval rule should be created with the tag name
const updatedPolicy = await OnyxUtils.get(`${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`);

expect(updatedPolicy?.rules?.expenseRules).toHaveLength(1);
expect(updatedPolicy?.rules?.expenseRules?.[0]?.applyWhen?.[0]?.value).toBe(categoryName);
expect(updatedPolicy?.rules?.expenseRules?.[0]?.applyWhen?.[0]?.condition).toBe(CONST.POLICY.RULE_CONDITIONS.MATCHES);
expect(updatedPolicy?.rules?.expenseRules?.[0]?.applyWhen?.[0]?.field).toBe(CONST.POLICY.FIELDS.CATEGORY);
expect(updatedPolicy?.rules?.expenseRules?.[0].tax.field_id_TAX.externalID).toBe('VAT');

mockFetch.resume();
await waitForBatchedUpdates();
});
});
});
Loading
Loading