Skip to content

Commit

Permalink
feat: HR dashboard for timesheets (#512)
Browse files Browse the repository at this point in the history
  • Loading branch information
djaiss committed Jan 25, 2021
1 parent c2c12d3 commit 6d21621
Show file tree
Hide file tree
Showing 36 changed files with 2,243 additions and 245 deletions.
22 changes: 21 additions & 1 deletion app/Helpers/TimeHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class TimeHelper
*/
public static function convertToHoursAndMinutes(int $minutes = null): array
{
if (! $minutes) {
if (! $minutes || $minutes == 0) {
return [
'hours' => 0,
'minutes' => 0,
Expand All @@ -31,4 +31,24 @@ public static function convertToHoursAndMinutes(int $minutes = null): array
'minutes' => $minutes,
];
}

/**
* Gets a sentence representing the time given in the array.
*
* @param array $duration
* @return string
*/
public static function durationInHumanFormat(array $duration): string
{
$minutes = $duration['minutes'] == 0 ? '00' : $duration['minutes'];

$time = trans('app.duration', [
'hours' => $duration['hours'],
'minutes' => $minutes,
]);

$time = str_replace(' ', '', $time);

return $time;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public function index(): Response
'dashboard_view' => 'expenses',
'is_manager' => $employee->directReports->count() > 0,
'can_manage_expenses' => $employee->can_manage_expenses,
'can_manage_hr' => $employee->permission_level <= config('officelife.permission_level.hr'),
];

return Inertia::render('Dashboard/Expenses/Index', [
Expand Down
43 changes: 39 additions & 4 deletions app/Http/Controllers/Company/Dashboard/DashboardHRController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,53 @@

namespace App\Http\Controllers\Company\Dashboard;

use Inertia\Inertia;
use Illuminate\Http\Request;
use App\Models\Company\Company;
use App\Helpers\InstanceHelper;
use App\Helpers\NotificationHelper;
use App\Http\Controllers\Controller;
use App\Jobs\UpdateDashboardPreference;
use App\Http\ViewHelpers\Dashboard\DashboardHRViewHelper;

class DashboardHRController extends Controller
{
/**
* Company details.
* Index of the HR tab on the dashboard.
*
* @param Request $request
* @return mixed
*/
public function index(Request $request): void
public function index(Request $request)
{
$company = InstanceHelper::getLoggedCompany();
$employee = InstanceHelper::getLoggedEmployee();

// is this person HR?
if ($employee->permission_level > config('officelife.permission_level.hr')) {
return redirect('home');
}

UpdateDashboardPreference::dispatch([
'employee_id' => $employee->id,
'company_id' => $company->id,
'view' => 'hr',
])->onQueue('low');

$employeeInformation = [
'id' => $employee->id,
'dashboard_view' => 'hr',
'is_manager' => true,
'can_manage_expenses' => $employee->can_manage_expenses,
'can_manage_hr' => $employee->permission_level <= config('officelife.permission_level.hr'),
];

$employeesWithoutManagersWithPendingTimesheets = DashboardHRViewHelper::employeesWithoutManagersWithPendingTimesheets($company);
$statisticsAboutTimesheets = DashboardHRViewHelper::statisticsAboutTimesheets($company);

return Inertia::render('Dashboard/HR/Index', [
'employee' => $employeeInformation,
'notifications' => NotificationHelper::getNotifications($employee),
'employeesWithoutManagersWithPendingTimesheets' => $employeesWithoutManagersWithPendingTimesheets,
'statisticsAboutTimesheets' => $statisticsAboutTimesheets,
]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
<?php

namespace App\Http\Controllers\Company\Dashboard;

use Inertia\Inertia;
use Inertia\Response;
use Illuminate\Http\Request;
use App\Helpers\InstanceHelper;
use App\Models\Company\Company;
use App\Models\Company\Employee;
use App\Models\Company\Timesheet;
use Illuminate\Http\JsonResponse;
use App\Helpers\NotificationHelper;
use App\Http\Controllers\Controller;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use App\Services\Company\Employee\Timesheet\RejectTimesheet;
use App\Services\Company\Employee\Timesheet\ApproveTimesheet;
use App\Http\ViewHelpers\Dashboard\DashboardTimesheetViewHelper;
use App\Http\ViewHelpers\Dashboard\HR\DashboardHRTimesheetViewHelper;

class DashboardHRTimesheetController extends Controller
{
/**
* Show the list of timesheets to validate.
*
* @return mixed
*/
public function index()
{
$company = InstanceHelper::getLoggedCompany();
$employee = InstanceHelper::getLoggedEmployee();

// is this person HR?
if ($employee->permission_level > config('officelife.permission_level.hr')) {
return redirect('home');
}

$employees = DashboardHRTimesheetViewHelper::timesheetApprovalsForEmployeesWithoutManagers($company);

return Inertia::render('Dashboard/HR/Timesheets/Index', [
'employee' => [
'id' => $employee->id,
],
'notifications' => NotificationHelper::getNotifications($employee),
'employees' => $employees,
]);
}

/**
* Show the timesheet to validate.
*
* @param Request $request
* @param int $companyId
* @param int $timesheetId
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|Response
*/
public function show(Request $request, int $companyId, int $timesheetId)
{
$company = InstanceHelper::getLoggedCompany();
$employee = InstanceHelper::getLoggedEmployee();

$timesheet = $this->canAccess($company, $timesheetId, $employee);

$timesheetInformation = DashboardTimesheetViewHelper::show($timesheet);
$daysInHeader = DashboardTimesheetViewHelper::daysHeader($timesheet);
$approverInformation = DashboardTimesheetViewHelper::approverInformation($timesheet);

return Inertia::render('Dashboard/HR/Timesheets/Show', [
'employee' => [
'id' => $employee->id,
'name' => $employee->name,
],
'daysHeader' => $daysInHeader,
'timesheet' => $timesheetInformation,
'approverInformation' => $approverInformation,
'notifications' => NotificationHelper::getNotifications($employee),
]);
}

/**
* Approve the timesheet.
*
* @param Request $request
* @param int $companyId
* @param int $timesheetId
* @return JsonResponse
*/
public function approve(Request $request, int $companyId, int $timesheetId): JsonResponse
{
$company = InstanceHelper::getLoggedCompany();
$employee = InstanceHelper::getLoggedEmployee();

$timesheet = $this->canAccess($company, $timesheetId, $employee);

$data = [
'company_id' => $company->id,
'author_id' => $employee->id,
'employee_id' => $timesheet->employee->id,
'timesheet_id' => $timesheetId,
];

$timesheet = (new ApproveTimesheet)->execute($data);

return response()->json([
'data' => $timesheet->id,
], 201);
}

/**
* Reject the timesheet.
*
* @param Request $request
* @param int $companyId
* @param int $timesheetId
* @return JsonResponse
*/
public function reject(Request $request, int $companyId, int $timesheetId): JsonResponse
{
$company = InstanceHelper::getLoggedCompany();
$employee = InstanceHelper::getLoggedEmployee();

$timesheet = $this->canAccess($company, $timesheetId, $employee);

$data = [
'company_id' => $company->id,
'author_id' => $employee->id,
'employee_id' => $timesheet->employee->id,
'timesheet_id' => $timesheetId,
];

$timesheet = (new RejectTimesheet)->execute($data);

return response()->json([
'data' => $timesheet->id,
], 201);
}

/**
* Check that the current employee has access to this method.
* @param Company $company
* @param int $timesheetId
* @param Employee $employee
* @return mixed
*/
private function canAccess(Company $company, int $timesheetId, Employee $employee)
{
try {
$timesheet = Timesheet::where('company_id', $company->id)
->findOrFail($timesheetId);
} catch (ModelNotFoundException $e) {
return redirect('home');
}

if ($timesheet->status !== Timesheet::READY_TO_SUBMIT) {
return redirect('home');
}

// is this person HR?
if ($employee->permission_level > config('officelife.permission_level.hr')) {
return redirect('home');
}

return $timesheet;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,20 +57,21 @@ public function index()
'dashboard_view' => 'manager',
'is_manager' => true,
'can_manage_expenses' => $employee->can_manage_expenses,
'can_manage_hr' => $employee->permission_level <= config('officelife.permission_level.hr'),
];

$pendingExpenses = DashboardManagerViewHelper::pendingExpenses($employee, $directReports);
$oneOnOnes = DashboardManagerViewHelper::oneOnOnes($employee, $directReports);
$contractRenewals = DashboardManagerViewHelper::contractRenewals($employee, $directReports);
$timesheetApprovals = DashboardManagerViewHelper::timesheetApprovals($employee, $directReports);
$timesheetsStats = DashboardManagerViewHelper::employeesWithTimesheetsToApprove($employee, $directReports);

return Inertia::render('Dashboard/Manager/Index', [
'employee' => $employeeInformation,
'notifications' => NotificationHelper::getNotifications($employee),
'pendingExpenses' => $pendingExpenses,
'oneOnOnes' => $oneOnOnes,
'contractRenewals' => $contractRenewals,
'timesheetApprovals' => $timesheetApprovals,
'timesheetsStats' => $timesheetsStats,
'defaultCompanyCurrency' => $company->currency,
]);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,89 @@

namespace App\Http\Controllers\Company\Dashboard;

use Inertia\Inertia;
use Inertia\Response;
use Illuminate\Http\Request;
use App\Helpers\InstanceHelper;
use App\Models\Company\Company;
use App\Models\Company\Employee;
use App\Models\Company\Timesheet;
use Illuminate\Http\JsonResponse;
use App\Helpers\NotificationHelper;
use App\Http\Controllers\Controller;
use App\Models\Company\DirectReport;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use App\Services\Company\Employee\Timesheet\RejectTimesheet;
use App\Services\Company\Employee\Timesheet\ApproveTimesheet;
use App\Http\ViewHelpers\Dashboard\DashboardTimesheetViewHelper;
use App\Http\ViewHelpers\Dashboard\Manager\DashboardManagerTimesheetViewHelper;

class DashboardTimesheetManagerController extends Controller
class DashboardManagerTimesheetController extends Controller
{
/**
* Show the list of timesheets to validate.
*
* @return mixed
*/
public function index()
{
$company = InstanceHelper::getLoggedCompany();
$employee = InstanceHelper::getLoggedEmployee();

// is the user a manager?
$directReports = DirectReport::where('company_id', $company->id)
->where('manager_id', $employee->id)
->with('directReport')
->with('directReport.timesheets')
->get();

if ($directReports->count() == 0) {
return redirect('home');
}

$timesheetApprovals = DashboardManagerTimesheetViewHelper::timesheetApprovals($employee, $directReports);

return Inertia::render('Dashboard/Manager/Timesheets/Index', [
'employee' => [
'id' => $employee->id,
],
'notifications' => NotificationHelper::getNotifications($employee),
'directReports' => $timesheetApprovals,
]);
}

/**
* Show the timesheet to validate.
*
* @param Request $request
* @param int $companyId
* @param int $timesheetId
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|Response
*/
public function show(Request $request, int $companyId, int $timesheetId)
{
$company = InstanceHelper::getLoggedCompany();
$employee = InstanceHelper::getLoggedEmployee();

$timesheet = $this->canAccess($company, $timesheetId, $employee);

$timesheetInformation = DashboardTimesheetViewHelper::show($timesheet);
$daysInHeader = DashboardTimesheetViewHelper::daysHeader($timesheet);
$approverInformation = DashboardTimesheetViewHelper::approverInformation($timesheet);

return Inertia::render('Dashboard/Manager/Timesheets/Show', [
'employee' => [
'id' => $employee->id,
'name' => $employee->name,
],
'daysHeader' => $daysInHeader,
'timesheet' => $timesheetInformation,
'approverInformation' => $approverInformation,
'notifications' => NotificationHelper::getNotifications($employee),
]);
}

/**
* Approve the timesheet.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public function index(): Response
'is_manager' => $employee->directReports->count() > 0,
'has_worked_from_home_today' => WorkFromHomeHelper::hasWorkedFromHomeOnDate($employee, Carbon::now()),
'question' => DashboardMeViewHelper::question($employee),
'can_manage_hr' => $employee->permission_level <= config('officelife.permission_level.hr'),
];

$defaultCompanyCurrency = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public function index(Request $request, int $companyId, int $teamId = null, $req
'dashboard_view' => 'team',
'can_manage_expenses' => $employee->can_manage_expenses,
'is_manager' => $employee->directReports->count() > 0,
'can_manage_hr' => $employee->permission_level <= config('officelife.permission_level.hr'),
];

UpdateDashboardPreference::dispatch([
Expand Down

0 comments on commit 6d21621

Please sign in to comment.