Skip to content
Draft
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
4 changes: 4 additions & 0 deletions src/libs/API/parameters/CreateDistanceRequestParams.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type {Unit} from '@src/types/onyx/Policy';
import type {Receipt} from '@src/types/onyx/Transaction';

type CreateDistanceRequestParams = {
Expand Down Expand Up @@ -32,6 +33,9 @@ type CreateDistanceRequestParams = {
modifiedDistance?: number;
odometerStart?: number;
odometerEnd?: number;

/** Distance unit the odometer readings were entered in, so the backend can convert them when the rate uses a different unit */
odometerUnit?: Unit;
gpsCoordinates?: string;
distanceRequestType?: string;
customUnitPolicyID?: string;
Expand Down
4 changes: 4 additions & 0 deletions src/libs/API/parameters/TrackExpenseParams.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type CONST from '@src/CONST';
import type {Attendee} from '@src/types/onyx/IOU';
import type {Unit} from '@src/types/onyx/Policy';
import type {Receipt} from '@src/types/onyx/Transaction';

import type {ValueOf} from 'type-fest';
Expand Down Expand Up @@ -47,6 +48,9 @@ type TrackExpenseParams = {
isDistance?: boolean;
odometerStart?: number;
odometerEnd?: number;

/** Distance unit the odometer readings were entered in, so the backend can convert them when the rate uses a different unit */
odometerUnit?: Unit;
};

export default TrackExpenseParams;
4 changes: 4 additions & 0 deletions src/libs/API/parameters/UpdateMoneyRequestParams.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type {TransactionDetails} from '@libs/ReportUtils';

import type {Unit} from '@src/types/onyx/Policy';

type UpdateMoneyRequestParams = Partial<TransactionDetails> & {
reportID?: string;
transactionID?: string;
Expand All @@ -9,6 +11,8 @@ type UpdateMoneyRequestParams = Partial<TransactionDetails> & {
updates?: string;
/** Distance in meters of the map route the user picked, sent when the selected alternate route changes */
selectedRouteDistance?: number;
/** Distance unit the odometer readings were entered in, so the backend can convert them when the rate uses a different unit */
odometerUnit?: Unit;
};

export default UpdateMoneyRequestParams;
2 changes: 2 additions & 0 deletions src/libs/DebugUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1154,6 +1154,7 @@ function validateTransactionDraftProperty(key: keyof Transaction, value: string)
rateAutoUpdated: CONST.RED_BRICK_ROAD_PENDING_ACTION,
odometerStart: CONST.RED_BRICK_ROAD_PENDING_ACTION,
odometerEnd: CONST.RED_BRICK_ROAD_PENDING_ACTION,
odometerUnit: CONST.RED_BRICK_ROAD_PENDING_ACTION,
odometerStartImage: CONST.RED_BRICK_ROAD_PENDING_ACTION,
odometerEndImage: CONST.RED_BRICK_ROAD_PENDING_ACTION,
tripID: CONST.RED_BRICK_ROAD_PENDING_ACTION,
Expand Down Expand Up @@ -1291,6 +1292,7 @@ function validateTransactionDraftProperty(key: keyof Transaction, value: string)
splitsEndDate: 'string',
odometerStart: 'number',
odometerEnd: 'number',
odometerUnit: 'string',
odometerStartImage: 'object',
odometerEndImage: 'object',
tripID: 'string',
Expand Down
34 changes: 33 additions & 1 deletion src/libs/OdometerUtils.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import CONST from '@src/CONST';
import type {Comment} from '@src/types/onyx/Transaction';
import type {FileObject} from '@src/types/utils/Attachment';

import {getMimeTypeFromUri} from './fileDownload/FileUtils';
import getPlatform from './getPlatform';
import {roundToTwoDecimalPlaces} from './NumberUtils';

function getOdometerImageUri(image: FileObject | string | null | undefined): string {
return typeof image === 'string' ? image : (image?.uri ?? '');
Expand Down Expand Up @@ -127,6 +129,36 @@ function shouldInitializeOdometerFromTransaction(state: OdometerResyncState, isE
);
}

export {getOdometerImageUri, getOdometerImageName, getOdometerImageType, getOdometerImageIdentity, isExternalOdometerResync, shouldInitializeOdometerFromTransaction};
/**
* The total distance for the given odometer readings, in the transaction's current distance unit.
*
* Readings stay exactly as entered so they match the odometer photos, but the quantity is converted when the expense moves to
* a workspace with a different distance unit. So when the readings match the saved ones, the saved quantity is returned as is,
* and when they differ, the difference is scaled by the same factor the saved quantity was converted by.
*/
function getOdometerTotalDistance(start: number, end: number, comment: Comment | undefined): number {
const distance = end - start;
const savedStart = comment?.odometerStart;
const savedEnd = comment?.odometerEnd;
const savedQuantity = comment?.customUnit?.quantity;

if (savedStart === undefined || savedEnd === undefined || savedQuantity === undefined || savedQuantity === null || savedEnd <= savedStart) {
return roundToTwoDecimalPlaces(distance);
}
if (start === savedStart && end === savedEnd) {
return savedQuantity;
}
return roundToTwoDecimalPlaces(distance * (savedQuantity / (savedEnd - savedStart)));
}

export {
getOdometerImageUri,
getOdometerImageName,
getOdometerImageType,
getOdometerImageIdentity,
getOdometerTotalDistance,
isExternalOdometerResync,
shouldInitializeOdometerFromTransaction,
};
export type {OdometerResyncState};
export default revokeOdometerImageUri;
6 changes: 6 additions & 0 deletions src/libs/TransactionUtils/buildOptimisticTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import CONST from '@src/CONST';
import type {Policy, Transaction} from '@src/types/onyx';
import type {Attendee, Participant, SplitExpense} from '@src/types/onyx/IOU';
import type {PendingAction} from '@src/types/onyx/OnyxCommon';
import type {Unit} from '@src/types/onyx/Policy';
import type {Comment, Receipt, Routes, TransactionCustomUnit, TransactionPendingFieldsKey, WaypointCollection} from '@src/types/onyx/Transaction';
import {isEmptyObject} from '@src/types/utils/EmptyObject';

Expand Down Expand Up @@ -61,6 +62,7 @@ type TransactionParams = {
waypoints?: WaypointCollection;
odometerStart?: number;
odometerEnd?: number;
odometerUnit?: Unit;
routes?: Routes;
gpsCoordinates?: string;
type?: ValueOf<typeof CONST.TRANSACTION.TYPE>;
Expand Down Expand Up @@ -123,6 +125,7 @@ function buildOptimisticTransaction(params: BuildOptimisticTransactionParams): T
waypoints,
odometerStart,
odometerEnd,
odometerUnit,
routes,
type,
count,
Expand All @@ -141,6 +144,9 @@ function buildOptimisticTransaction(params: BuildOptimisticTransactionParams): T
if (odometerEnd !== undefined) {
commentJSON.odometerEnd = odometerEnd;
}
if (odometerUnit !== undefined) {
commentJSON.odometerUnit = odometerUnit;
}
if (isDemoTransactionParam) {
commentJSON.isDemoTransaction = true;
}
Expand Down
1 change: 1 addition & 0 deletions src/libs/actions/IOU/Duplicate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,7 @@ function buildDuplicateTransactionParams(transaction: OnyxTypes.Transaction, tra
originalTransactionID: undefined,
odometerStart: transaction.comment?.odometerStart ?? undefined,
odometerEnd: transaction.comment?.odometerEnd ?? undefined,
odometerUnit: transaction.comment?.odometerUnit ?? undefined,
receipt: undefined,
source: undefined,
waypoints,
Expand Down
4 changes: 4 additions & 0 deletions src/libs/actions/IOU/MoneyRequestBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ import ONYXKEYS from '@src/ONYXKEYS';
import type * as OnyxTypes from '@src/types/onyx';
import type {Attendee, Participant} from '@src/types/onyx/IOU';
import type {ErrorFields, Errors, PendingAction, PendingFields} from '@src/types/onyx/OnyxCommon';
import type {Unit} from '@src/types/onyx/Policy';
import type {ReportNextStep} from '@src/types/onyx/Report';
import type ReportAction from '@src/types/onyx/ReportAction';
import type {OnyxData} from '@src/types/onyx/Request';
Expand Down Expand Up @@ -151,6 +152,7 @@ type RequestMoneyTransactionParams = Omit<BaseTransactionParams, 'comment'> & {
customUnit?: TransactionCustomUnit;
odometerStart?: number;
odometerEnd?: number;
odometerUnit?: Unit;

/** Transaction type (e.g., 'time' for time tracking expenses) */
type?: ValueOf<typeof CONST.TRANSACTION.TYPE>;
Expand Down Expand Up @@ -1371,6 +1373,7 @@ function getMoneyRequestInformation(moneyRequestInformation: MoneyRequestInforma
waypoints,
odometerStart,
odometerEnd,
odometerUnit,
isSelfDMSplit,
selfDMReportID,
shouldSkipReportHighlightRail,
Expand Down Expand Up @@ -1581,6 +1584,7 @@ function getMoneyRequestInformation(moneyRequestInformation: MoneyRequestInforma
waypoints,
odometerStart,
odometerEnd,
odometerUnit,
},
isDemoTransactionParam: transactionParams.receipt?.isTestDriveReceipt,
});
Expand Down
6 changes: 6 additions & 0 deletions src/libs/actions/IOU/Split.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type * as OnyxTypes from '@src/types/onyx';
import type {Attendee, Participant, Split} from '@src/types/onyx/IOU';
import type {Unit} from '@src/types/onyx/Policy';
import type RecentlyUsedTags from '@src/types/onyx/RecentlyUsedTags';
import type {OnyxData} from '@src/types/onyx/Request';
import type {Receipt, ReceiptSource, SplitShares, TransactionChanges, WaypointCollection} from '@src/types/onyx/Transaction';
Expand Down Expand Up @@ -119,6 +120,7 @@ type DistanceRequestTransactionParams = BaseTransactionParams & {
receipt?: Receipt;
odometerStart?: number;
odometerEnd?: number;
odometerUnit?: Unit;
gpsCoordinates?: string;
distanceRequestType?: string;

Expand Down Expand Up @@ -2110,6 +2112,7 @@ function createDistanceRequest(distanceRequestInformation: CreateDistanceRequest
receipt,
odometerStart,
odometerEnd,
odometerUnit,
isFromGlobalCreate,
gpsCoordinates,
distanceRequestType,
Expand Down Expand Up @@ -2207,6 +2210,7 @@ function createDistanceRequest(distanceRequestInformation: CreateDistanceRequest
attendees: attendees ? JSON.stringify(attendees) : undefined,
odometerStart,
odometerEnd,
odometerUnit,
gpsCoordinates,
distanceRequestType,
selectedRouteDistance,
Expand Down Expand Up @@ -2269,6 +2273,7 @@ function createDistanceRequest(distanceRequestInformation: CreateDistanceRequest
waypoints: validWaypoints,
odometerStart,
odometerEnd,
odometerUnit,
customUnitRateID,
},
shouldGenerateTransactionThreadReport: false,
Expand Down Expand Up @@ -2325,6 +2330,7 @@ function createDistanceRequest(distanceRequestInformation: CreateDistanceRequest
receipt,
odometerStart,
odometerEnd,
odometerUnit,
created,
category,
tag,
Expand Down
8 changes: 7 additions & 1 deletion src/libs/actions/IOU/TrackExpense.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ import type {Route} from '@src/ROUTES';
import ROUTES from '@src/ROUTES';
import type * as OnyxTypes from '@src/types/onyx';
import type {Attendee, Participant} from '@src/types/onyx/IOU';
import type {CreatableWorkspaceType} from '@src/types/onyx/Policy';
import type {CreatableWorkspaceType, Unit} from '@src/types/onyx/Policy';
import type {QuickActionName} from '@src/types/onyx/QuickAction';
import type ReportAction from '@src/types/onyx/ReportAction';
import type {OnyxData} from '@src/types/onyx/Request';
Expand Down Expand Up @@ -178,6 +178,7 @@ type GetTrackExpenseInformationTransactionParams = {
distance?: number;
odometerStart?: number;
odometerEnd?: number;
odometerUnit?: Unit;
gpsCoordinates?: string;
distanceRequestType?: string;
};
Expand Down Expand Up @@ -939,6 +940,7 @@ function getTrackExpenseInformation(params: GetTrackExpenseInformationParams): T
attendees,
odometerStart,
odometerEnd,
odometerUnit,
gpsCoordinates,
} = transactionParams;

Expand Down Expand Up @@ -1161,6 +1163,7 @@ function getTrackExpenseInformation(params: GetTrackExpenseInformationParams): T
attendees,
odometerStart: isOdometerDistanceRequest ? odometerStart : undefined,
odometerEnd: isOdometerDistanceRequest ? odometerEnd : undefined,
odometerUnit: isOdometerDistanceRequest ? odometerUnit : undefined,
gpsCoordinates: isGPSDistanceRequest ? gpsCoordinates : undefined,
},
});
Expand Down Expand Up @@ -2567,6 +2570,7 @@ function trackExpense(params: CreateTrackExpenseParams) {
attendees,
odometerStart,
odometerEnd,
odometerUnit,
isFromGlobalCreate = false,
gpsCoordinates,
distanceRequestType,
Expand Down Expand Up @@ -2687,6 +2691,7 @@ function trackExpense(params: CreateTrackExpenseParams) {
attendees,
odometerStart,
odometerEnd,
odometerUnit,
gpsCoordinates,
},
policyParams: {
Expand Down Expand Up @@ -2979,6 +2984,7 @@ function trackExpense(params: CreateTrackExpenseParams) {
isOdometerDistanceRequestTransactionUtils(transaction),
odometerStart,
odometerEnd,
odometerUnit,
};
if (actionableWhisperReportActionIDParam) {
parameters.actionableWhisperReportActionID = actionableWhisperReportActionIDParam;
Expand Down
6 changes: 6 additions & 0 deletions src/libs/actions/IOU/UpdateMoneyRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import ONYXKEYS from '@src/ONYXKEYS';
import type * as OnyxTypes from '@src/types/onyx';
import type {Attendee} from '@src/types/onyx/IOU';
import type {MerchantRuleSuggestionField} from '@src/types/onyx/MerchantRuleSuggestion';
import type {Unit} from '@src/types/onyx/Policy';
import type RecentlyUsedTags from '@src/types/onyx/RecentlyUsedTags';
import type {OnyxData} from '@src/types/onyx/Request';
import type {SearchResultDataType} from '@src/types/onyx/SearchResults';
Expand Down Expand Up @@ -1181,6 +1182,7 @@ type UpdateMoneyRequestDistanceParams = {
isASAPSubmitBetaEnabled: boolean;
odometerStart?: number;
odometerEnd?: number;
odometerUnit?: Unit;
distanceOriginalPolicy?: OnyxEntry<OnyxTypes.Policy>;
delegateAccountID: number | undefined;
isTrackIntentUser: boolean | undefined;
Expand Down Expand Up @@ -1213,6 +1215,7 @@ function updateMoneyRequestDistance({
isASAPSubmitBetaEnabled,
odometerStart,
odometerEnd,
odometerUnit,
distanceOriginalPolicy,
delegateAccountID,
isTrackIntentUser,
Expand Down Expand Up @@ -1282,6 +1285,9 @@ function updateMoneyRequestDistance({
if (odometerEnd !== undefined) {
params.odometerEnd = odometerEnd;
}
if (odometerUnit !== undefined) {
params.odometerUnit = odometerUnit;
}
const selectedRouteDistance = selectedRouteKey ? transaction?.routes?.[selectedRouteKey]?.distance : undefined;
if (selectedRouteDistance) {
params.selectedRouteDistance = selectedRouteDistance;
Expand Down
2 changes: 2 additions & 0 deletions src/libs/actions/IOU/types/TrackExpenseTransactionParams.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type CONST from '@src/CONST';
import type * as OnyxTypes from '@src/types/onyx';
import type {Attendee} from '@src/types/onyx/IOU';
import type {Unit} from '@src/types/onyx/Policy';
import type {Receipt, WaypointCollection} from '@src/types/onyx/Transaction';

import type {ValueOf} from 'type-fest';
Expand Down Expand Up @@ -41,6 +42,7 @@ type TrackExpenseTransactionParams = {
isLinkedTrackedExpenseReportArchived?: boolean;
odometerStart?: number;
odometerEnd?: number;
odometerUnit?: Unit;
isFromGlobalCreate?: boolean;
gpsCoordinates?: string;
distanceRequestType?: string;
Expand Down
8 changes: 7 additions & 1 deletion src/libs/actions/OdometerTransactionUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import CONST from '@src/CONST';
import type {OdometerImageType} from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {OdometerDraft, Transaction} from '@src/types/onyx';
import type {Unit} from '@src/types/onyx/Policy';
import type {Comment} from '@src/types/onyx/Transaction';
import type {FileObject} from '@src/types/utils/Attachment';

Expand All @@ -24,11 +25,16 @@ type SaveOdometerDraftParams = {
endImage?: FileObject | string | null;
};

function setMoneyRequestOdometerReading(transactionID: string, startReading: number | null, endReading: number | null, isDraft: boolean) {
/**
* Set the odometer readings for a transaction
* @param odometerUnit - The distance unit the readings were entered in. Omit it when clearing the readings.
*/
function setMoneyRequestOdometerReading(transactionID: string, startReading: number | null, endReading: number | null, isDraft: boolean, odometerUnit: Unit | null = null) {
Onyx.merge(`${isDraft ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, {
comment: {
odometerStart: startReading,
odometerEnd: endReading,
odometerUnit,
},
});
}
Expand Down
Loading
Loading