![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/ts.corals.io/corals-api/Corals/modules/Timesheet/Services/ |
<?php namespace Corals\Modules\Timesheet\Services; use Carbon\Carbon; use Corals\Foundation\Services\BaseServiceClass; use Corals\Modules\Timesheet\Models\Entry; use Corals\Settings\Facades\Settings; use Corals\User\Models\User; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Query\JoinClause; use Illuminate\Support\Str; class ChartService extends BaseServiceClass { /** * @param string $model * @return array */ public function getChartsDataFor(string $model) { $chartModelHandlerMethodName = sprintf("get%sChartData", Str::studly($model)); if (!method_exists($this, $chartModelHandlerMethodName)) { return []; } return $this->{$chartModelHandlerMethodName}(); } /** * @return array */ public function getEntriesChartData() { $days = $this->getBaseQuery(); $days = $days->get()->toArray(); return $this->getDataForChartJS($days, 'entries'); } /** * @return array */ public function getActivityChartData() { $days = $this->getBaseQuery()->when(request('activity_id'), function ($query, $activityId) { $query->where('timesheet_entries.activity_id', $activityId); })->get()->toArray(); return $this->getDataForChartJS($days, 'activity'); } /** * @return array */ public function getUserChartData() { $userId = request('user_id'); $days = $this->getBaseQuery()->when($userId, function ($query, $userId) { $query->where('timesheet_entries.user_id', $userId); })->get()->toArray(); return $this->getDataForChartJS($days, 'user', $userId); } /** * @return array */ public function getProjectChartData() { $days = $this->getBaseQuery()->when(request('project_id'), function ($query, $projectId) { $query->where('timesheet_entries.project_id', $projectId); })->when(request('user_id'), function ($query, $userId) { $query->where('timesheet_entries.user_id', $userId); })->get()->toArray(); return $this->getDataForChartJS($days, 'project'); } /** * @return array */ public function getClientChartData() { $days = $this->getBaseQuery() ->join('timesheet_projects', 'timesheet_entries.project_id', 'timesheet_projects.id') ->when(request('client_id'), function ($query, $clientId) { $query->where('timesheet_projects.client_id', $clientId); })->get() ->toArray(); return $this->getDataForChartJS($days, 'client'); } /** * @return \Illuminate\Database\Eloquent\Builder */ protected function getBaseQuery(): Builder { $start_end_date = $this->getDateRange(); if (isset(request()->year) && !request('from_date') && !request('to_date')) { if (isset(request()->month) && request()->month != 'all') { $dateOfYear = Carbon::createFromDate(request()->year, request()->month); $start_end_date = [$dateOfYear->copy()->startOfMonth(), $dateOfYear->copy()->endOfMonth()]; } else { $dateOfYear = Carbon::createFromDate(request()->year, 1); $start_end_date = [$dateOfYear->copy()->startOfYear(), $dateOfYear->copy()->endOfYear()]; } } return Entry::query() ->whereBetween('timesheet_entries.spent_at', $start_end_date) ->selectRaw("spent_at,DATE_FORMAT(spent_at,'%a, %d %b') as label , ((SUM(ifNull(timesheet_entries.hours*60,0)) + SUM(ifNull(timesheet_entries.minutes,0)))/60) as total_hours, ((SUM(ifNull(timesheet_entries.evaluation_hours*60,0)) + SUM(ifNull(timesheet_entries.evaluation_minutes,0)))/60) as total_evaluation_hours") ->groupBy("timesheet_entries.spent_at"); } /** * @param $days * @param $startPeriod * @return null */ protected function getTargetDate($days, $startPeriod) { $targetDay = null; foreach ($days as $day) { if ($day['spent_at'] == $startPeriod->toDateString()) { $targetDay = $day; break; } } return $targetDay; } /** * @param Carbon $period * @return array */ protected function getChartDayPlaceholder(Carbon $period) { return [ 'spent_at' => $period->toDateString(), 'label' => $period->format('D, d M'), 'total_hours' => 0, 'total_evaluation_hours' => 0 ]; } protected function getExpectedWorkingDays() { [$startPeriod, $endPeriod] = $this->getDateRange(); $working_days = Settings::get('working_days'); $number_of_working_days = 0; while ($startPeriod->lte($endPeriod)) { if (in_array($startPeriod->shortDayName, $working_days)) { $number_of_working_days++; } $startPeriod->addDay(); } return $number_of_working_days; } /** * @param $days * @return array */ protected function getDataForChartJS($days, $chartFor, $arg = null) { [$startPeriod, $endPeriod] = $this->getDateRange(); if (isset(request()->year) && !request('from_date') && !request('to_date')) { if (isset(request()->month) && request()->month != 'all') { $dateOfYear = Carbon::createFromDate(request()->year, request()->month); $startPeriod = $dateOfYear->copy()->startOfMonth(); $endPeriod = $dateOfYear->copy()->endOfMonth(); } else { $dateOfYear = Carbon::createFromDate(request()->year, 1); $startPeriod = $dateOfYear->copy()->startOfYear(); $endPeriod = $dateOfYear->copy()->endOfYear(); } } $working_days = Settings::get('working_days'); $periodTotalHours = 0; $periodTotalEvaluationHours = 0; $generationType = 'days'; $diffInDays = $startPeriod->diffInDays($endPeriod->copy()->addDay()); if ($diffInDays > 60) { $generationType = 'months'; } elseif ($diffInDays >= 30) { $generationType = 'weeks'; } while ($startPeriod->lt($endPeriod)) { switch ($generationType) { case 'days': $targetDay = $this->getTargetDay($startPeriod, $working_days, $days); $dayTotalHours = data_get($targetDay, 'total_hours'); $dayEvaluationHours = data_get($targetDay, 'total_evaluation_hours'); if ($dayTotalHours || $dayEvaluationHours) { $periodTotalHours += $dayTotalHours; $periodTotalEvaluationHours += $dayEvaluationHours; $labels[] = data_get($targetDay, 'label'); $hours[] = $dayTotalHours; $evaluationHours[] = $dayEvaluationHours; } $startPeriod->addDay(); break; case 'months': $startMonth = $startPeriod->copy(); $endMonth = $startPeriod->copy()->endOfMonth(); if ($endPeriod < $endMonth) { $endMonth = $endPeriod->copy(); } $result = $this->getTotalAndEvaluationHours($startMonth, $endMonth, $working_days, $days); $periodTotalHours += $result['totalHours']; $periodTotalEvaluationHours += $result['evaluationHours']; $labels[] = $endMonth->format('M'); $hours[] = $result['totalHours']; $evaluationHours[] = $result['evaluationHours']; $startPeriod = $result['startDate']; break; case 'weeks': $startWeek = $startPeriod->copy(); $endWeek = $startPeriod->copy() ->endOfWeek((Settings::get('timesheet_start_of_week', Carbon::MONDAY)) - 1); if ($endPeriod < $endWeek) { $endWeek = $endPeriod->copy(); } $result = $this->getTotalAndEvaluationHours($startWeek, $endWeek, $working_days, $days); $periodTotalHours += $result['totalHours']; $periodTotalEvaluationHours += $result['evaluationHours']; $labels[] = $startPeriod->copy()->format('d M') . '-' . $endWeek->format('d M'); $hours[] = $result['totalHours']; $evaluationHours[] = $result['evaluationHours']; $startPeriod = $result['startDate']; break; } } if ($chartFor == 'user') { if ($arg) { $user = User::find($arg); } if (isset($user) && $user->employee_type = 'part_time') { $workingHours = $periodTotalHours; } else { $expectedWorkingHours = $this->getExpectedWorkingDays() * Settings::get('total_working_hours_per_day', 8); $workingHours = max($expectedWorkingHours, $periodTotalHours); } } else { $workingHours = $periodTotalHours; } $dataSets = [ [ 'label' => 'Total Hours', 'fill' => false, 'borderColor' => '#808080', 'data' => $hours ?? [], ], ]; if (Settings::get('evaluation_enabled')) { $evaluationPercentage = $workingHours ? round(($periodTotalEvaluationHours / $workingHours) * 100) . '%' : 'N/A'; $evaluationPercentage = min($evaluationPercentage, 100); $dataSets[] = [ 'label' => 'Evaluation Hours', 'fill' => false, 'borderColor' => '#0d9903', 'data' => $evaluationHours ?? [], ]; } else { $evaluationPercentage = 'N/A'; } return [ 'labels' => $labels ?? [], 'evaluation_percentage' => $evaluationPercentage, 'datasets' => $dataSets, ]; } public function baseActivitiesQuery($column_name, $model_id): array { $result = Entry::query() ->where("timesheet_entries.$column_name", '=', $model_id) ->whereBetween('timesheet_entries.spent_at', $this->getDateRange()) ->join('timesheet_activities', function (JoinClause $joinActivitiesTable) { $joinActivitiesTable->on('timesheet_entries.activity_id', 'timesheet_activities.id'); })->selectRaw('timesheet_activities.is_limited,timesheet_activities.title, (SUM(ifNull(timesheet_entries.hours*60,0)) + SUM(ifNull(timesheet_entries.minutes,0)))/60 as total_hours, (SUM(ifNull(timesheet_entries.evaluation_hours * 60,0)) + SUM(ifNull(timesheet_entries.evaluation_minutes,0)))/60 as total_evaluation_hours' )->groupBy('timesheet_activities.id') ->get(); $withLimitedActivities = request('is_limited'); $data = []; $labels = []; if ($withLimitedActivities) { $result = $result->partition->is_limited; $data[] = round($result[1]->sum->total_hours / Settings::get('total_working_hours_per_day', 8), 1); $labels[] = 'Other'; } foreach ($withLimitedActivities ? $result[0] : $result as $limitedActivity) { $labels[] = $limitedActivity->title; $data[] = round($limitedActivity->total_hours / Settings::get('total_working_hours_per_day', 8), 1); } return [ 'labels' => $labels ?? [], 'datasets' => [ [ 'backgroundColor' => [ 'rgb(255, 99, 132)', 'rgb(54, 162, 235)', 'rgb(255, 205, 86)', '#5e4548', '#8dd3c7', '#1f78b4', '#ffffb3', '#b2df8a', '#bebada', '#33a02c', '#fb9a99', '#80b1d3', '#e31a1c', '#fdb462', '#fdbf6f' ], 'data' => $data ?? [], ], ] ]; } /** * @return array */ public function getLimitedActivitiesChartData() { $result = $this->baseActivitiesQuery('user_id', request('user_id')); return [ 'expectedWorkingDays' => $this->getExpectedWorkingDays(), 'labels' => $result['labels'], 'datasets' => $result['datasets'] ]; } /** * @return array */ public function getProjectActivitiesChartData() { $result = $this->baseActivitiesQuery('project_id', request('project_id')); return [ 'labels' => $result['labels'], 'datasets' => $result['datasets'] ]; } /** * @return array */ protected function getDateRange() { $fromDate = request('from_date'); if ($fromDate) { $fromDate = Carbon::parse($fromDate); } else { $fromDate = now()->startOfMonth(); } $toDate = request('to_date'); if ($toDate) { $toDate = Carbon::parse($toDate); } else { $toDate = now(); } return [ $fromDate, $toDate ]; } public function getTargetDay($startPeriod, $working_days, $days) { $targetDay = null; if (in_array($startPeriod->shortDayName, $working_days)) { if (!($targetDay = $this->getTargetDate($days, $startPeriod))) { $targetDay = $this->getChartDayPlaceholder($startPeriod); } } return $targetDay; } protected function getTotalAndEvaluationHours($startDate, $endDate, $working_days, $days) { $totalHours = 0; $evaluationHours = 0; while ($startDate->lt($endDate)) { $targetDay = $this->getTargetDay($startDate, $working_days, $days); $dayTotalHours = data_get($targetDay, 'total_hours'); $dayEvaluationHours = data_get($targetDay, 'total_evaluation_hours'); if ($dayTotalHours || $dayEvaluationHours) { $totalHours += $dayTotalHours; $evaluationHours += $dayEvaluationHours; } $startDate->addDay(); } return [ 'totalHours' => $totalHours, 'evaluationHours' => $evaluationHours, 'startDate' => $startDate, ]; } }