-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
support for offline tax tracking #40443
Changes from all commits
7574fc9
1ed12df
1c16b1a
8dce58a
228c477
a0ac9ba
7b79f15
3ba09e8
59a57b0
1e8a4a4
3cd43a4
31d6d0d
b2829fc
d87b8cc
e9a2ebd
26e108f
7855c95
36e731f
f66df7b
7c29f96
6330d7d
cdeb5bd
8e08bb9
dd6f0a6
042bf2e
45fd4f5
5365262
57425e4
930b070
eec7b89
9d0b843
dc13632
16b32c6
2fd6906
2850e39
da28145
2213bc0
f157b2d
9be9960
381fd11
f23a397
f2f529d
fc15227
1341be5
a5d2386
bdb39b5
521c669
9ef5ee5
f8d31a6
a584cf0
e262453
2e2da04
3522c4e
2ae2836
1a0a317
1c99e0f
05f0784
7872da9
799182f
98f3180
483f5d3
dab26d8
ffe1a80
61f31e1
7e7bcc0
3011f30
aed16c7
9518d73
b27f215
072d10d
1b41f8c
57882de
25c2003
18bc37c
f9a745c
5e6336c
c25eca1
79bee2b
843d33c
e93b1de
bf0ba54
a5768f8
398e421
0102a3f
4305c13
876ee9a
e7e8886
764a76d
09bbe46
81e53e8
25178e9
0ca3634
1184706
b5824e8
923a2ab
0a27694
144746d
52e8cc7
bade846
ea26dc9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -181,9 +181,11 @@ type MoneyRequestConfirmationListProps = MoneyRequestConfirmationListOnyxProps & | |
action?: IOUAction; | ||
}; | ||
|
||
const getTaxAmount = (transaction: OnyxEntry<OnyxTypes.Transaction>, defaultTaxValue: string) => { | ||
const percentage = (transaction?.taxRate ? transaction?.taxRate?.data?.value : defaultTaxValue) ?? ''; | ||
return TransactionUtils.calculateTaxAmount(percentage, transaction?.amount ?? 0); | ||
const getTaxAmount = (transaction: OnyxEntry<OnyxTypes.Transaction>, policy: OnyxEntry<OnyxTypes.Policy>) => { | ||
const defaultTaxCode = TransactionUtils.getDefaultTaxCode(policy, transaction) ?? ''; | ||
|
||
const taxPercentage = TransactionUtils.getTaxValue(policy, transaction, transaction?.taxCode ?? defaultTaxCode) ?? ''; | ||
return TransactionUtils.calculateTaxAmount(taxPercentage, transaction?.amount ?? 0); | ||
}; | ||
|
||
function MoneyRequestConfirmationList({ | ||
|
@@ -317,9 +319,10 @@ function MoneyRequestConfirmationList({ | |
isDistanceRequest ? currency : iouCurrencyCode, | ||
); | ||
const formattedTaxAmount = CurrencyUtils.convertToDisplayString(transaction?.taxAmount, iouCurrencyCode); | ||
const taxRateTitle = taxRates && transaction ? TransactionUtils.getDefaultTaxName(taxRates, transaction) : ''; | ||
const taxRateTitle = TransactionUtils.getTaxName(policy, transaction); | ||
|
||
const previousTransactionAmount = usePrevious(transaction?.amount); | ||
const previousTransactionCurrency = usePrevious(transaction?.currency); | ||
|
||
const isFocused = useIsFocused(); | ||
const [formError, debouncedFormError, setFormError] = useDebouncedState(''); | ||
|
@@ -373,15 +376,15 @@ function MoneyRequestConfirmationList({ | |
|
||
// Calculate and set tax amount in transaction draft | ||
useEffect(() => { | ||
const taxAmount = getTaxAmount(transaction, taxRates?.defaultValue ?? '').toString(); | ||
const taxAmount = getTaxAmount(transaction, policy).toString(); | ||
const amountInSmallestCurrencyUnits = CurrencyUtils.convertToBackendAmount(Number.parseFloat(taxAmount)); | ||
|
||
if (transaction?.taxAmount && previousTransactionAmount === transaction?.amount) { | ||
if (transaction?.taxAmount && previousTransactionAmount === transaction?.amount && previousTransactionCurrency === transaction?.currency) { | ||
return IOU.setMoneyRequestTaxAmount(transaction?.transactionID, transaction?.taxAmount, true); | ||
} | ||
Comment on lines
+382
to
384
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is this block doing here? is it here in case the currency didn't change? if |
||
|
||
IOU.setMoneyRequestTaxAmount(transactionID, amountInSmallestCurrencyUnits, true); | ||
}, [taxRates?.defaultValue, transaction, transactionID, previousTransactionAmount]); | ||
}, [policy, transaction, transactionID, previousTransactionAmount, previousTransactionCurrency]); | ||
|
||
// If completing a split expense fails, set didConfirm to false to allow the user to edit the fields again | ||
if (isEditingSplitBill && didConfirm) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,7 @@ import Onyx from 'react-native-onyx'; | |
import type {ValueOf} from 'type-fest'; | ||
import CONST from '@src/CONST'; | ||
import ONYXKEYS from '@src/ONYXKEYS'; | ||
import type {RecentWaypoint, Report, TaxRate, TaxRates, TaxRatesWithDefault, Transaction, TransactionViolation} from '@src/types/onyx'; | ||
import type {Policy, RecentWaypoint, Report, TaxRate, TaxRates, Transaction, TransactionViolation} from '@src/types/onyx'; | ||
import type {Comment, Receipt, TransactionChanges, TransactionPendingFieldsKey, Waypoint, WaypointCollection} from '@src/types/onyx/Transaction'; | ||
import {isEmptyObject} from '@src/types/utils/EmptyObject'; | ||
import type {IOURequestType} from './actions/IOU'; | ||
|
@@ -96,6 +96,8 @@ function buildOptimisticTransaction( | |
existingTransactionID: string | null = null, | ||
category = '', | ||
tag = '', | ||
taxCode = '', | ||
taxAmount = 0, | ||
billable = false, | ||
pendingFields: Partial<{[K in TransactionPendingFieldsKey]: ValueOf<typeof CONST.RED_BRICK_ROAD_PENDING_ACTION>}> | undefined = undefined, | ||
reimbursable = true, | ||
|
@@ -126,6 +128,8 @@ function buildOptimisticTransaction( | |
filename, | ||
category, | ||
tag, | ||
taxCode, | ||
taxAmount, | ||
Comment on lines
+131
to
+132
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is causing the deploy blocker: #42114 (comment) |
||
billable, | ||
reimbursable, | ||
}; | ||
|
@@ -651,29 +655,69 @@ function getRateID(transaction: OnyxEntry<Transaction>): string | undefined { | |
} | ||
|
||
/** | ||
* Gets the default tax name | ||
* Gets the tax code based on selected currency. | ||
* Returns policy default tax rate if transaction is in policy default currency, otherwise returns foreign default tax rate | ||
*/ | ||
function getDefaultTaxName(taxRates: TaxRatesWithDefault, transaction?: Transaction) { | ||
const defaultTaxKey = taxRates.defaultExternalID; | ||
const defaultTaxName = | ||
(defaultTaxKey && `${taxRates.taxes[defaultTaxKey]?.name} (${taxRates.taxes[defaultTaxKey]?.value}) ${CONST.DOT_SEPARATOR} ${Localize.translateLocal('common.default')}`) || ''; | ||
return transaction?.taxRate?.text ?? defaultTaxName; | ||
function getDefaultTaxCode(policy: OnyxEntry<Policy>, transaction: OnyxEntry<Transaction>) { | ||
const defaultExternalID = policy?.taxRates?.defaultExternalID; | ||
const foreignTaxDefault = policy?.taxRates?.foreignTaxDefault; | ||
return policy?.outputCurrency === getCurrency(transaction) ? defaultExternalID : foreignTaxDefault; | ||
} | ||
|
||
/** | ||
* Transforms tax rates to a new object format - to add codes and new name with concatenated name and value. | ||
* | ||
* @param policy - The policy which the user has access to and which the report is tied to. | ||
* @returns The transformed tax rates object.g | ||
*/ | ||
function transformedTaxRates(policy: OnyxEntry<Policy> | undefined, transaction?: OnyxEntry<Transaction>): Record<string, TaxRate> { | ||
const taxRates = policy?.taxRates; | ||
const defaultExternalID = taxRates?.defaultExternalID; | ||
|
||
const defaultTaxCode = () => { | ||
if (!transaction) { | ||
return defaultExternalID; | ||
} | ||
|
||
return policy && getDefaultTaxCode(policy, transaction); | ||
}; | ||
Comment on lines
+677
to
+683
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @teneeto Why did we wrap this code in a function? Why didn't we just do something like:
Are you expecting that |
||
|
||
const getModifiedName = (data: TaxRate, code: string) => | ||
`${data.name} (${data.value})${defaultTaxCode() === code ? ` ${CONST.DOT_SEPARATOR} ${Localize.translateLocal('common.default')}` : ''}`; | ||
const taxes = Object.fromEntries(Object.entries(taxRates?.taxes ?? {}).map(([code, data]) => [code, {...data, code, modifiedName: getModifiedName(data, code), name: data.name}])); | ||
return taxes; | ||
} | ||
|
||
/** | ||
* Gets the tax value of a selected tax | ||
*/ | ||
function getTaxValue(policy: OnyxEntry<Policy>, transaction: OnyxEntry<Transaction>, taxCode: string) { | ||
return Object.values(transformedTaxRates(policy, transaction)).find((taxRate) => taxRate.code === taxCode)?.value; | ||
} | ||
|
||
/** | ||
* Gets the tax name for Workspace Taxes Settings | ||
*/ | ||
function getWorkspaceTaxesSettingsName(policy: OnyxEntry<Policy>, taxCode: string) { | ||
return Object.values(transformedTaxRates(policy)).find((taxRate) => taxRate.code === taxCode)?.modifiedName; | ||
} | ||
|
||
/** | ||
* Gets the tax name | ||
*/ | ||
function getTaxName(taxes: TaxRates, transactionTaxCode: string) { | ||
const taxName = taxes[transactionTaxCode]?.name ?? ''; | ||
const taxValue = taxes[transactionTaxCode]?.value ?? ''; | ||
return transactionTaxCode && taxName && taxValue ? `${taxName} (${taxValue})` : ''; | ||
function getTaxName(policy: OnyxEntry<Policy>, transaction: OnyxEntry<Transaction>) { | ||
const defaultTaxCode = getDefaultTaxCode(policy, transaction); | ||
return Object.values(transformedTaxRates(policy, transaction)).find((taxRate) => taxRate.code === (transaction?.taxCode ?? defaultTaxCode))?.modifiedName; | ||
} | ||
|
||
export { | ||
buildOptimisticTransaction, | ||
calculateTaxAmount, | ||
getWorkspaceTaxesSettingsName, | ||
getDefaultTaxCode, | ||
transformedTaxRates, | ||
getTaxValue, | ||
getTaxName, | ||
getDefaultTaxName, | ||
getEnabledTaxRateCount, | ||
getUpdatedTransaction, | ||
getDescription, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the
currency
differs from the currenttransaction currency
, thetaxCode
should have also changed to the default (i.e. local or foreign based on the newly updated currency) tax rate. And, the tax amount should also have been recomputed. Missing these changes here resulted in issue #42049.