159 lines
5.1 KiB
PHP
159 lines
5.1 KiB
PHP
<?php
|
||
|
||
namespace Modules\ManagementTools\Utils;
|
||
|
||
use Carbon\Carbon;
|
||
use Illuminate\Support\Collection;
|
||
use Modules\ManagementTools\Entities\MtUserTask;
|
||
use Modules\ManagementTools\Entities\MtUserTimeLine;
|
||
|
||
class TaskReportUtil
|
||
{
|
||
public function __construct(protected ManagementToolsUtil $mtUtil)
|
||
{
|
||
}
|
||
|
||
public function tasksForUserOnDate(int $business_id, int $user_id, string $date): Collection
|
||
{
|
||
return MtUserTask::forBusiness($business_id)
|
||
->whereHas('timeLines', function ($q) use ($user_id, $date) {
|
||
$q->where('user_id', $user_id)
|
||
->whereDate('starts_at', $date);
|
||
})
|
||
->with(['timeLines' => fn ($q) => $q->where('user_id', $user_id)])
|
||
->orderByDesc('id')
|
||
->get();
|
||
}
|
||
|
||
public function tasksForUserInRange(int $business_id, int $user_id, Carbon $start, Carbon $end): Collection
|
||
{
|
||
return MtUserTask::forBusiness($business_id)
|
||
->whereHas('timeLines', function ($q) use ($user_id, $start, $end) {
|
||
$q->where('user_id', $user_id)
|
||
->whereDate('starts_at', '>=', $start->toDateString())
|
||
->whereDate('starts_at', '<=', $end->toDateString());
|
||
})
|
||
->with(['timeLines' => fn ($q) => $q->where('user_id', $user_id)])
|
||
->orderByDesc('id')
|
||
->get();
|
||
}
|
||
|
||
public function calendarTasks(int $business_id, int $user_id, Carbon $start, Carbon $end): Collection
|
||
{
|
||
return MtUserTask::forBusiness($business_id)
|
||
->where('user_id', $user_id)
|
||
->where(function ($q) use ($start, $end) {
|
||
$q->whereBetween('created_at', [$start, $end])
|
||
->orWhereBetween('due_date', [$start->toDateString(), $end->toDateString()]);
|
||
})
|
||
->orderBy('title')
|
||
->get();
|
||
}
|
||
|
||
public function taskWorkMinutes(MtUserTask $task, int $user_id, ?string $date = null): int
|
||
{
|
||
$lines = $task->relationLoaded('timeLines')
|
||
? $task->timeLines->where('user_id', $user_id)
|
||
: $task->timeLines()->where('user_id', $user_id)->get();
|
||
|
||
if ($date) {
|
||
$lines = $lines->filter(fn ($line) => $line->starts_at && $line->starts_at->toDateString() === $date);
|
||
}
|
||
|
||
return (int) $lines->sum(fn ($line) => $line->durationMinutes() ?? 0);
|
||
}
|
||
|
||
public function sumTasksWorkMinutes(Collection $tasks, int $user_id, ?string $date = null): int
|
||
{
|
||
return (int) $tasks->sum(fn ($task) => $this->taskWorkMinutes($task, $user_id, $date));
|
||
}
|
||
|
||
public function userDayWorkMinutes(int $business_id, int $user_id, string $date): int
|
||
{
|
||
$lines = MtUserTimeLine::forBusiness($business_id)
|
||
->where('user_id', $user_id)
|
||
->whereDate('starts_at', $date)
|
||
->get();
|
||
|
||
return (int) $lines->sum(fn ($line) => $line->durationMinutes() ?? 0);
|
||
}
|
||
|
||
public function formatDuration(int $minutes): string
|
||
{
|
||
if ($minutes <= 0) {
|
||
return '۰:۰۰';
|
||
}
|
||
|
||
$formatted = sprintf('%d:%02d', intdiv($minutes, 60), $minutes % 60);
|
||
|
||
return function_exists('persian_number') ? persian_number($formatted) : $formatted;
|
||
}
|
||
|
||
public function formatDurationHtml(int $minutes): string
|
||
{
|
||
$label = $this->formatDuration($minutes);
|
||
|
||
if ($minutes <= 0) {
|
||
return '<span class="text-muted">'.$label.'</span>';
|
||
}
|
||
|
||
return '<span class="label label-success" style="font-size:13px;">'.$label.'</span>';
|
||
}
|
||
|
||
public function latestTimelineForTask(int $business_id, int $user_id, int $task_id, ?string $date = null): ?MtUserTimeLine
|
||
{
|
||
$query = MtUserTimeLine::forBusiness($business_id)
|
||
->where('user_id', $user_id)
|
||
->where('user_task_id', $task_id);
|
||
|
||
if ($date) {
|
||
$query->whereDate('starts_at', $date);
|
||
}
|
||
|
||
return $query->latest('starts_at')->first();
|
||
}
|
||
|
||
public function dayTabDates(): array
|
||
{
|
||
$future = collect();
|
||
for ($i = 0; $i < 7; $i++) {
|
||
$future->push(now()->addDays($i)->format('Y-m-d'));
|
||
}
|
||
|
||
$past = collect();
|
||
for ($i = 1; $i <= 6; $i++) {
|
||
$past->push(now()->subDays($i)->format('Y-m-d'));
|
||
}
|
||
|
||
return [
|
||
'future' => $future,
|
||
'past' => $past->reverse()->values(),
|
||
];
|
||
}
|
||
|
||
public function groupedTasksByTimelineDate(Collection $tasks, int $user_id): Collection
|
||
{
|
||
$grouped = collect();
|
||
|
||
foreach ($tasks as $task) {
|
||
$dates = $task->timeLines
|
||
->where('user_id', $user_id)
|
||
->pluck('starts_at')
|
||
->filter()
|
||
->map(fn ($dt) => $dt->toDateString())
|
||
->unique();
|
||
|
||
foreach ($dates as $date) {
|
||
if (! $grouped->has($date)) {
|
||
$grouped->put($date, collect());
|
||
}
|
||
if (! $grouped->get($date)->contains('id', $task->id)) {
|
||
$grouped->get($date)->push($task);
|
||
}
|
||
}
|
||
}
|
||
|
||
return $grouped->sortKeysDesc();
|
||
}
|
||
}
|