Refactor transaction handling and improve shift time logic
Introduced a new `getAllTransactionIds` utility function to better handle filtering of transaction IDs. Replaced outdated `start`/`end` time properties with `checkIn`/`checkOut` objects for shift records, alongside added validation in tests to exclude shifts without punches. Enhanced invoicing tests to ensure flags remain visible even for excluded transactions.
This commit is contained in:
@@ -22,13 +22,12 @@ final class workfeed_shift_time_resolver
|
||||
}
|
||||
|
||||
$actual_start = self::firstDateTimeFromPaths($record, [
|
||||
'checkIn.time',
|
||||
'checkIn',
|
||||
'actualStart',
|
||||
'actualStartTime',
|
||||
'clockIn',
|
||||
'clockInTime',
|
||||
'start',
|
||||
'startTime',
|
||||
'from',
|
||||
'approval.originalStart',
|
||||
]);
|
||||
$scheduled_end = self::firstDateTimeFromPaths($record, [
|
||||
@@ -38,17 +37,14 @@ final class workfeed_shift_time_resolver
|
||||
'to',
|
||||
]);
|
||||
$actual_only_end = self::firstDateTimeFromPaths($record, [
|
||||
'checkOut.time',
|
||||
'checkOut',
|
||||
'actualEnd',
|
||||
'actualEndTime',
|
||||
'clockOut',
|
||||
'clockOutTime',
|
||||
]);
|
||||
$current_end = self::firstDateTimeFromPaths($record, [
|
||||
'end',
|
||||
'endTime',
|
||||
'to',
|
||||
]);
|
||||
$saved_actual_end = $actual_only_end ?? $current_end;
|
||||
$saved_actual_end = $actual_only_end;
|
||||
|
||||
if ($actual_start === null || $scheduled_end === null || $saved_actual_end === null) {
|
||||
return null;
|
||||
|
||||
@@ -23,22 +23,26 @@ it('calculates workfeed employee hours for the hour slot based on overlap', func
|
||||
$shifts = [
|
||||
(object)[
|
||||
'departmentID' => 'dep_1',
|
||||
'start' => '2026-03-24T13:00:00+00:00',
|
||||
'checkIn' => (object)['time' => '2026-03-24T13:00:00+00:00'],
|
||||
'checkOut' => (object)['time' => '2026-03-24T14:00:00+00:00'],
|
||||
'end' => '2026-03-24T14:00:00+00:00',
|
||||
],
|
||||
(object)[
|
||||
'departmentID' => 'dep_1',
|
||||
'start' => '2026-03-24T13:30:00+00:00',
|
||||
'checkIn' => (object)['time' => '2026-03-24T13:30:00+00:00'],
|
||||
'checkOut' => (object)['time' => '2026-03-24T15:00:00+00:00'],
|
||||
'end' => '2026-03-24T15:00:00+00:00',
|
||||
],
|
||||
(object)[
|
||||
'departmentID' => 'dep_other',
|
||||
'start' => '2026-03-24T13:00:00+00:00',
|
||||
'checkIn' => (object)['time' => '2026-03-24T13:00:00+00:00'],
|
||||
'checkOut' => (object)['time' => '2026-03-24T14:00:00+00:00'],
|
||||
'end' => '2026-03-24T14:00:00+00:00',
|
||||
],
|
||||
(object)[
|
||||
'departmentID' => 'dep_1',
|
||||
'start' => '2026-03-24T14:00:00+00:00',
|
||||
'checkIn' => (object)['time' => '2026-03-24T14:00:00+00:00'],
|
||||
'checkOut' => (object)['time' => '2026-03-24T13:00:00+00:00'],
|
||||
'end' => '2026-03-24T13:00:00+00:00',
|
||||
],
|
||||
];
|
||||
@@ -93,12 +97,14 @@ it('calculates workfeed employee hours across multiple departments for one hour
|
||||
$shifts = [
|
||||
(object)[
|
||||
'departmentID' => 'dep_1',
|
||||
'start' => '2026-03-24T13:00:00+00:00',
|
||||
'checkIn' => (object)['time' => '2026-03-24T13:00:00+00:00'],
|
||||
'checkOut' => (object)['time' => '2026-03-24T14:00:00+00:00'],
|
||||
'end' => '2026-03-24T14:00:00+00:00',
|
||||
],
|
||||
(object)[
|
||||
'departmentID' => 'dep_2',
|
||||
'start' => '2026-03-24T13:00:00+00:00',
|
||||
'checkIn' => (object)['time' => '2026-03-24T13:00:00+00:00'],
|
||||
'checkOut' => (object)['time' => '2026-03-24T14:00:00+00:00'],
|
||||
'end' => '2026-03-24T14:00:00+00:00',
|
||||
],
|
||||
];
|
||||
@@ -108,6 +114,25 @@ it('calculates workfeed employee hours across multiple departments for one hour
|
||||
expect($hours)->toBe(2.0);
|
||||
});
|
||||
|
||||
it('does not count shifts without punches when checkIn/checkOut are null', function (): void {
|
||||
$route = new moduleWeatherAPIRoute();
|
||||
$slot = new DateTime('2026-03-24T13:00:00+00:00');
|
||||
|
||||
$shifts = [
|
||||
(object)[
|
||||
'departmentID' => 'dep_1',
|
||||
'checkIn' => null,
|
||||
'checkOut' => null,
|
||||
'start' => '2026-03-24T13:00:00+00:00',
|
||||
'end' => '2026-03-24T14:00:00+00:00',
|
||||
],
|
||||
];
|
||||
|
||||
$hours = weather_route_invoke_private($route, 'calculateWorkfeedEmployeeHoursForHour', [$shifts, 'dep_1', $slot]);
|
||||
|
||||
expect($hours)->toBe(0.0);
|
||||
});
|
||||
|
||||
it('counts overtime minutes when a saved shift end extends past the approved original end', function (): void {
|
||||
$route = new moduleWeatherAPIRoute();
|
||||
$slot = new DateTime('2026-03-23T18:00:00+00:00');
|
||||
|
||||
Reference in New Issue
Block a user