Skip to content

Commit

Permalink
Merge pull request #56295 from Shahidullah-Muffakir/fix/55449-time-su…
Browse files Browse the repository at this point in the history
…mmary-for-per-diem-same-day

Correct per diem time calculation for same-day expenses
  • Loading branch information
lakchote authored Feb 4, 2025
2 parents e36d812 + 40f1c51 commit df3db1d
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 1 deletion.
12 changes: 11 additions & 1 deletion src/libs/PerDiemRequestUtils.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -258,6 +258,16 @@ function getTimeDifferenceIntervals(transaction: OnyxEntry<Transaction>) {
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));
Expand Down
82 changes: 82 additions & 0 deletions tests/unit/getTimeDifferenceIntervalsTest.ts
Original file line number Diff line number Diff line change
@@ -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<Transaction> =>
({
comment: {
customUnit: {
attributes: {
dates: {
start: startDate,
end: endDate,
},
},
},
},
} as OnyxEntry<Transaction>);

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,
});
});
});

0 comments on commit df3db1d

Please sign in to comment.