Spamworldpro Mini Shell
Spamworldpro


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/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/corals/ts.corals.io/corals-api/Corals/modules/Timesheet/Services/ChartService.php
<?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,
        ];
    }
}

Spamworldpro Mini