HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/SBogers10/hours.komma.pro/app/Komma/HoursService.php
<?php


namespace App\Komma;


use App\Komma\Users\User;
use Carbon\Carbon;
use App\Komma\Projects\Project;
use App\Komma\Projects\ProjectService;
use App\Komma\Expenses\ExpenseService;
use App\Komma\Hours\HourService;
use App\Komma\Settings\AbsenceTypes\AbsenceType;
use App\Komma\Settings\ExpenseTypes\ExpenseType;
use Illuminate\Support\Facades\Auth;

class HoursService
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    private $hourService;
    private $expenseService;
    private $projectService;

    public function __construct(HourService $hourService, ExpenseService $expenseService, ProjectService $projectService)
    {
        $this->hourService = $hourService;
        $this->expenseService = $expenseService;
        $this->projectService = $projectService;
    }

    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Http\Response
     */
    public function home($request)
    {
        // Session is used so the date, view and user are retained while interacting with the hour write view
        $date = $request->filled('date') ? $request->get('date') : (\Session::has('date') ? \Session::get('date') : Carbon::today()->format('d-m-Y') );
        $view = $request->filled('view') ? $request->get('view') : (\Session::has('view') ? \Session::get('view') : "");
        $user = Auth::user()->can('write_by_other_user') ? $request->filled('user') ? $request->get('user') : (\Session::has('user') ? \Session::get('user') : Auth::id()) : Auth::id();

        // forget the session variables so they do not overwrite any changes coming from the frontend in the next request
        \Session::forget('date');
        \Session::forget('view');
        \Session::forget('user');


        // get all the hours, absences and expenses for this month
        if (!$currentMonth = $this->hourService->getMonth($date, $user)) ;
        if (!$absenceMonth = $this->hourService->getAbsenceMonth($date, $user)) ;
        if (!$expenses = $this->expenseService->getExpense($date, $user)) ;

        // get the projects for the project select
        $projects = $this->projectService->action('list', "");
        $projects = $projects->sortBy('name');

        // get the types for the expenses and absences
        $expenseTypes = ExpenseType::with(['ExpenseUnit'])->where('id', '!=', 'Kilometervergoeding')->get();
        $absenceTypes = AbsenceType::select('id', 'name')->get();

        // get the users for the users select (admin only)
        $users = User::select('id', 'name')->get();

        // filter the hours for this month for the relevant view
        $hours = $this->getDayHours($currentMonth, $date);
        $absenceHours = $this->getDayHours($absenceMonth, $date);
        $flexHours = $this->getFlexDayHours($absenceMonth, $date);

        // used in the user dashboard/statistics banner in the hours view
        $currentWeek = $this->getWeekHours($currentMonth, $date);
        $currentInternalWeek = $this->getInternalWeekHours($currentMonth, $date);
        $currentFactWeek = $currentWeek->filter(function ($item) { return $item->Task->Subproject->billable == 1 && $item->exceed_subproject == 0; });
        $currentNotFactWeek = $currentWeek->filter(function ($item) { return $item->Task->Subproject->billable == 0 && $item->exceed_subproject == 0; });
        $currentExceedsWeek = $currentWeek->filter(function ($item) { return $item->exceed_subproject == 1; });
        $currentAbsenceWeek = $this->getWeekHours($absenceMonth, $date);

        //make results array
        $results = [
            'date' => $date,
            'view' => $view,
            'weekCollection' => $this->createWeekCalendar($date, $currentWeek, $currentAbsenceWeek),
            'monthCollection' => $this->createMonthCalendar($date, $currentMonth, $absenceMonth),
            'currentMonth' => $currentMonth,
            'absenceMonth' => $absenceMonth,
            'expenses' => $expenses,
            'projects' => $projects,
            'expenseType' => $expenseTypes,
            'absenceType' => $absenceTypes,
            'users' => $users,
            'user' => $user,
            'hours' => $hours,
            'absenceHours' => $absenceHours,
            'flexHours' => $flexHours,
            'sumHours' => $this->sumCollection($hours,
                $absenceHours->filter(function ($item) {
                    return $item->not_in_weektotal < 1;
                }),
                $flexHours),
            'sumExpense' => $this->sumExpense($expenses),
            'currentWeek' => $currentWeek,
            'currentInternalWeek' => $this->sumSingleCollection($currentInternalWeek),
            'currentFactWeek' => $this->sumSingleCollection($currentFactWeek),
            'currentNotFactWeek' => $this->sumSingleCollection($currentNotFactWeek),
            'currentExceedsWeek' => $this->sumSingleCollection($currentExceedsWeek),
            'currentAbsenceWeek' => $currentAbsenceWeek,
            'sumWeek' => $this->sumCollection($currentWeek,
                $currentAbsenceWeek->filter(function ($item) {
                    return $item->not_in_weektotal< 1;
                })
            ),
        ];
        //return all results in array
        return $results;
    }



    protected function sumSingleCollection($collection)
    {
        $total = [];
        // Check if we have hours
        if (!empty($collection)) {
            // Loop through hours
            foreach ($collection as $item) {
                $total[] = $item->value;
            }
        }

        return $total;
    }

    /**
     * Put all hours in an array
     *
     * @param $hours
     * @return array
     */
    protected function sumCollection($collection, $absenceCollection, $flexCollection = null)
    {
        $sumTotal = $this->sumSingleCollection($collection);
        $sumAbsenceTotal = $this->sumSingleCollection($absenceCollection);
        $sumFlexTotal = !empty($flexCollection) ? $this->sumSingleCollection($flexCollection) : null;

        //compact all hours of day
        return compact('sumTotal', 'sumAbsenceTotal', 'sumFlexTotal');
    }


    /**
     * @param $expenses
     * @return number
     */
    protected function sumExpense($expenses)
    {
        // Create empty array
        $sumExpense = [];

        //loop through expenses
        foreach ($expenses as $expense) {
            $sumExpense[] = $expense->value * $expense->ExpenseType->costs;
        }
        return array_sum($sumExpense);
    }

    /**
     * @param $monthCollection
     * @param $date
     * @return mixed
     */
    protected function getDayHours($monthCollection, $date)
    {
        $carbonDate = Carbon::parse($date);
        $hoursCollection = $monthCollection->filter(function ($item) use ($carbonDate) {
            $itemDate = Carbon::parse($item->date);
            $flex = empty($item->not_in_weektotal) ? -1 : $item->not_in_weektotal;
            return $carbonDate->isSameDay($itemDate) && $flex < 1;
        });
        return $hoursCollection;
    }

    /**
     * @param $monthCollection
     * @param $date
     * @return mixed
     */
    protected function getFlexDayHours($monthCollection, $date)
    {
        $carbonDate = Carbon::parse($date);
        $hoursCollection = $monthCollection->filter(function ($item) use ($carbonDate) {
            $itemDate = Carbon::parse($item->date);
            return $carbonDate->isSameDay($itemDate) && $item->not_in_weektotal == 1;
        });
        return $hoursCollection;
    }

    /**
     * @param $monthCollection
     * @param $date
     * @return mixed
     */
    protected function getWeekHours($monthCollection, $date)
    {
        $currentWeekCollection = $monthCollection->filter(function ($item) use ($date) {
            return $item->date >= $this->getWeekDays($date)['startOfWeek'] && $item->date < $this->getWeekDays($date)['endOfWeek'];
        });

        return $currentWeekCollection;
    }

    /**
     * @param $monthCollection
     * @param $date
     * @return mixed
     */
    protected function getInternalWeekHours($monthCollection, $date)
    {
        $currentWeekCollection = $monthCollection->filter(function ($item) use ($date) {
            return ($item->date >= $this->getWeekDays($date)['startOfWeek']) && $item->date < $this->getWeekDays($date)['endOfWeek'] && ($item->Task->Subproject->Project->internal == 1);
        });

        return $currentWeekCollection;
    }

    /**
     * @param $date
     * @return array
     */
    protected function getWeekDays($date)
    {
        $startOfWeek = Carbon::parse($date)->startOfWeek()->toDateString();
        $endOfWeek = Carbon::parse($date)->endOfWeek()->toDateTimeString();

        return compact('startOfWeek', 'endOfWeek');
    }


    /**
     * @param $date
     * @param $currentMonth
     * @param $internMonth
     * @return array
     */
    protected function createMonthCalendar($date, $currentMonth, $internMonth)
    {
        $days = [];
        $selectedDay = Carbon::parse($date, 'UTC');
        $tempDate = Carbon::parse($date, 'UTC')->startOfMonth()->startOfWeek();
        $endDate = Carbon::parse($date, 'UTC')->endOfMonth()->endOfWeek();

        while ($tempDate->lessThan($endDate)) {

            for ($i = 0; $i < 7; $i++) {
                //create empty arrays
                $allHourByDay = [];
                $allInternHourByDay = [];
                $selected = null;
                $today = null;

                //get hours
                $hourByDay = $currentMonth->where('date', $tempDate->toDateString() . ' 00:00:00')->all();
                $internHourByDay = $internMonth->where('date', $tempDate->toDateString() . ' 00:00:00')->all();

                //loop trough hours
                foreach ($hourByDay as $value) {
                    $allHourByDay[] = $value->value;
                }
                //loop trough intern hours
                foreach ($internHourByDay as $value) {
                    //if is not_in_weektotal
                    if ($value->not_in_weektotal == 0) {
                        $allInternHourByDay[] = $value->value;
                    }
                }

                if ($tempDate->equalTo($selectedDay)) {
                    $selected = true;
                }
                if ($tempDate->isToday()) {
                    $today = true;
                }

                $days[] = ['day' => $tempDate->format('d-m-Y'), 'value' => array_sum($allHourByDay) + array_sum($allInternHourByDay), 'selected' => $selected, 'today' => $today];
                $tempDate->addDay();
            }
        }

        return $days;
    }


    /**
     * @param $date
     * @param $currentWeek
     * @param $currentInternWeek
     * @return array
     */
    protected function createWeekCalendar($date, $currentWeek, $currentInternWeek)
    {
        //create empty array
        $days = [];
        //get date
        $tempDate = \Carbon\Carbon::parse($date)->startOfWeek();

        //create 7 days
        for ($i = 0; $i < 7; $i++) {
            //today false
            $today = null;
            //if today
            if ($tempDate->toDateString() == Carbon::today()->toDateString()) {
                //today true
                $today = true;
            }
            //put day info in array
            $days[] = ['day' => $tempDate->formatLocalized('%A'), 'date' => $tempDate->format('d-m-Y'), 'today' => $today];
            //get hours
            $hourByDay = $currentWeek->where('date', $tempDate->toDateString() . ' 00:00:00')->all();
            $internHourByDay = $currentInternWeek->where('date', $tempDate->toDateString() . ' 00:00:00')->all();

            //put hours in day
            $days[$i] += ['hours' => $hourByDay];
            $days[$i] += ['internHours' => $internHourByDay];

            //next day
            $tempDate->addDay();
        }

        //return array
        return $days;
    }
}