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;
}
}