To address the issue of excluding weekends from the calculation, we need to ensure that the logic correctly handles the difference in days and hours while excluding weekends. The provided code has a good start, but there are a few improvements and corrections we can make to ensure it works as expected.
Here's a revised version of the helper function:
if (!function_exists('getTimeInReceiptStatusLessWeekends')) {
function getTimeInReceiptStatusLessWeekends(Receipt $receipt): string
{
// Assuming Receipt has a relationship to Activity
$activity = $receipt->activities()->latest()->first(); // Get the latest activity
if (!$activity) {
return 'No activity found'; // Handle cases where no activity is found
}
// Get the next activity (status change)
$nextActivity = Activity::where('subject_type', $activity->subject_type)
->where('subject_id', $activity->subject_id)
->where('created_at', '>', $activity->created_at)
->orderBy('created_at', 'asc')
->first();
// Determine end time for the current status
$endTime = $nextActivity ? new Carbon($nextActivity->created_at) : Carbon::now();
// Start time is the creation time of the activity
$startTime = new Carbon($activity->created_at);
// Calculate the duration excluding weekends
$totalDays = $startTime->diffInDaysFiltered(function (Carbon $date) {
return !$date->isWeekend(); // Exclude weekends
}, $endTime);
// Calculate the total hours excluding weekends
$totalHours = $startTime->diffFiltered(CarbonInterval::hour(), function (Carbon $date) {
return !$date->isWeekend(); // Exclude weekends
}, $endTime);
// Calculate the remaining hours after full days
$remainingHours = $totalHours % 24;
// If you want to return the result in a human-readable format (days and hours)
$duration = CarbonInterval::days($totalDays)
->hours($remainingHours)
->forHumans(['parts' => 2]);
return $duration;
}
}
Explanation:
- Fetching Activities: The function fetches the latest activity and the next activity to determine the time range.
- End Time Calculation: If there is no next activity, the end time is set to the current time.
-
Duration Calculation:
-
diffInDaysFilteredis used to calculate the total number of days excluding weekends. -
diffFilteredwithCarbonInterval::hour()is used to calculate the total number of hours excluding weekends.
-
- Remaining Hours: The remaining hours after full days are calculated using the modulus operator.
- Human-Readable Format: The duration is formatted into a human-readable string showing days and hours.
This should correctly calculate the duration excluding weekends and return the result in a human-readable format.