diff --git a/src/libs/PerDiemRequestUtils.ts b/src/libs/PerDiemRequestUtils.ts index 5c5b3bbabed4..71a950998980 100644 --- a/src/libs/PerDiemRequestUtils.ts +++ b/src/libs/PerDiemRequestUtils.ts @@ -1,4 +1,4 @@ -import {addDays, differenceInDays, differenceInMinutes, format, startOfDay} from 'date-fns'; +import {addDays, differenceInDays, differenceInMinutes, format, isSameDay, startOfDay} from 'date-fns'; import lodashSortBy from 'lodash/sortBy'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; @@ -258,6 +258,16 @@ function getTimeDifferenceIntervals(transaction: OnyxEntry) { const customUnitRateDate = transaction?.comment?.customUnit?.attributes?.dates ?? {start: '', end: ''}; const startDate = new Date(customUnitRateDate.start); const endDate = new Date(customUnitRateDate.end); + + if (isSameDay(startDate, endDate)) { + const hourDiff = differenceInMinutes(endDate, startDate) / 60; + return { + firstDay: hourDiff, + tripDays: 0, + lastDay: undefined, + }; + } + const firstDayDiff = differenceInMinutes(startOfDay(addDays(startDate, 1)), startDate); const tripDaysDiff = differenceInDays(startOfDay(endDate), startOfDay(addDays(startDate, 1))); const lastDayDiff = differenceInMinutes(endDate, startOfDay(endDate)); diff --git a/tests/unit/getTimeDifferenceIntervalsTest.ts b/tests/unit/getTimeDifferenceIntervalsTest.ts new file mode 100644 index 000000000000..72dce3bb2058 --- /dev/null +++ b/tests/unit/getTimeDifferenceIntervalsTest.ts @@ -0,0 +1,82 @@ +import {addDays, differenceInDays, differenceInMinutes, startOfDay} from 'date-fns'; +import type {OnyxEntry} from 'react-native-onyx'; +import {getTimeDifferenceIntervals} from '@libs/PerDiemRequestUtils'; +import type Transaction from '@src/types/onyx/Transaction'; + +describe('getTimeDifferenceIntervals', () => { + const createMockTransaction = (startDate: string, endDate: string): OnyxEntry => + ({ + comment: { + customUnit: { + attributes: { + dates: { + start: startDate, + end: endDate, + }, + }, + }, + }, + } as OnyxEntry); + + it('calculates hours for same-day transactions', () => { + // Given a transaction that starts and ends on the same day + const startDate = '2024-03-20T09:00:00Z'; + const endDate = '2024-03-20T17:00:00Z'; + const transaction = createMockTransaction(startDate, endDate); + + const result = getTimeDifferenceIntervals(transaction); + + // When we calculate the time difference intervals + const expectedHours = differenceInMinutes(new Date(endDate), new Date(startDate)) / 60; + + // Then we should get the correct number of hours for a single day, there should be no trip days and no last day + expect(result).toEqual({ + firstDay: expectedHours, + tripDays: 0, + lastDay: undefined, + }); + }); + + it('calculates hours spanning two days', () => { + // Given a transaction that spans across two days + const startDate = '2024-03-20T14:00:00Z'; + const endDate = '2024-03-21T16:00:00Z'; + const transaction = createMockTransaction(startDate, endDate); + + const result = getTimeDifferenceIntervals(transaction); + + // When we calculate the time difference intervals + const startDateTime = new Date(startDate); + const firstDayDiff = differenceInMinutes(startOfDay(addDays(startDateTime, 1)), startDateTime); + const lastDayDiff = differenceInMinutes(new Date(endDate), startOfDay(new Date(endDate))); + + // Then we should get the correct split of hours, there should be no trip days + expect(result).toEqual({ + firstDay: firstDayDiff / 60, + tripDays: 0, + lastDay: lastDayDiff / 60, + }); + }); + + it('calculates hours for multi-day trips', () => { + // Given a transaction that spans multiple days + const startDate = '2024-03-20T16:00:00Z'; + const endDate = '2024-03-23T14:00:00Z'; + const transaction = createMockTransaction(startDate, endDate); + + const result = getTimeDifferenceIntervals(transaction); + + // When we calculate the time difference intervals + const startDateTime = new Date(startDate); + const firstDayDiff = differenceInMinutes(startOfDay(addDays(startDateTime, 1)), startDateTime); + const tripDaysDiff = differenceInDays(startOfDay(new Date(endDate)), startOfDay(addDays(startDateTime, 1))); + const lastDayDiff = differenceInMinutes(new Date(endDate), startOfDay(new Date(endDate))); + + // Then we should get the correct hours split, there should be trip days and last day + expect(result).toEqual({ + firstDay: firstDayDiff / 60, + tripDays: tripDaysDiff, + lastDay: lastDayDiff / 60, + }); + }); +});