File: D:/HostingSpaces/SBogers10/hours.komma.pro/app/Komma/Projects/ProjectController.php
<?php
namespace App\Komma\Projects;
use App\Http\Controllers\Controller;
use App\Komma\Users\User;
use Carbon\Carbon;
use App\Komma\Cache\CacheService;
use App\Komma\Companies\Company;
use App\Komma\Messages\MessageController;
use App\Komma\Notifications\NotificationService;
use App\Komma\ProjectWorkers\ProjectWorker;
use App\Komma\Settings\ProjectTemplates\ProjectTemplate;
use App\Komma\Settings\TaskTemplates\TaskTemplate;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Session;
class ProjectController extends Controller
{
private $projectService;
private $messageController;
private $cacheService;
private $notificationService;
public function __construct(ProjectService $projectService, MessageController $messageController, CacheService $cacheService, NotificationService $notificationService)
{
$this->middleware('auth');
$this->projectService = $projectService;
$this->messageController = $messageController;
$this->cacheService = $cacheService;
$this->notificationService = $notificationService;
}
/**
* @param Request $request
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index(Request $request)
{
session()->forget(['date', 'view', 'user']);
// Show flash messages only once
\Session::push('flash.old', 'flash_notification.message');
\Session::push('flash.old', 'flash_notification.level');
//get params
$action = !empty($request->action) ? $request->action : "active";
$search = !empty($request->search) ? $request->search : "";
//load projects by action
if (!$projects = $this->projectService->action($action, $search)) ;
//get first date
$firstProject = Project::select('created_at')->orderBy('created_at')->first();
if(isset($firstProject)) $firstDate = Carbon::parse($firstProject->created_at)->format('d-m-Y');
else $firstDate = null;
//get filter params
$begin = !empty($request->begin) ? $request->begin : $firstDate;
$end = !empty($request->end) ? $request->end : Carbon::today()->format('d-m-Y');
$user = !empty($request->user) ? $request->user : "";
//filter projects
foreach ($projects as $index => $project) {
//filter project
$projects[$index] = $this->projectService->filterProjectHours($project, $begin, $end, $user, false)['project'];
}
//get budgets
$budgets = $this->projectService->getBudgetsProjects($projects);
//get count values
$badgeCounter = (object)$this->projectService->getCountProjects($projects);
//get users for select box
$users = User::select('name')->get();
//return
return view('projects.index', compact('projects', 'action', 'budgets', 'begin', 'end', 'user', 'users', 'badgeCounter'));
}
/**
* @param $id
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function show($id)
{
session()->forget(['date', 'view', 'user']);
// Load project with all relations
$project = $this->projectService->eagerLoadProject($id);
$this->authorize('view', $project);
//get first date
$firstDate = $this->projectService->getFirstDateProject($project);
$firstDate = !empty($firstDate[0]) ? $firstDate[0] : $project->created_at->format('d-m-Y');
//get begin and end date
$begin = \Request::filled('begin') ? \Request::get('begin') : $firstDate;
$end = \Request::filled('end') ? \Request::get('end') : Carbon::today()->endOfDay()->format('d-m-Y');
$user = \Request::filled('user') ? \Request::get('user') : "";
//filter hours by begin and end date
$data = $this->projectService->filterProjectHours($project, $begin, $end, $user, true);
$project = $data['project'];
$workers = $data['workers'];
// Load data
$allData = (object)$this->projectService->createAllData($project);
$budgets = (object)$this->projectService->getBudgets($project);
$subprojectHours = $this->projectService->allSubprojectHours($project);
$sumExpense = (object)$this->projectService->sumExpenses($project);
$billableBudget = $project->Subprojects->where('billable', 1)->sum('budget');
$weightedAverageHourlyRate = $this->projectService->weightedAverageHourlyRate($project);
if(!empty($project->Subprojects)) {
$project->Subprojects = $project->Subprojects->sortBy('name');
}
//return
return view('projects.show', compact('project', 'budgets', 'subprojectHours', 'sumExpense', 'billableBudget', 'allData', 'begin', 'end', 'user', 'workers', 'weightedAverageHourlyRate'));
}
/**
* @param $id
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function recalculate($id)
{
// Load project with all relations
$project = $this->projectService->eagerLoadProject($id);
if( !$this->projectService->recalculateProject($project) ){
return back();
}
$budgets = (object)$this->projectService->getBudgets($project);
$this->projectService->lockHours($project, Carbon::now(), $budgets->projectHours['actualRate']);
$project->calculated = 1;
$project->save();
$this->notificationService->archivedNotification($project);
//return
return redirect('/projecten/' . $id);
}
/**
* @param $project
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function edit($project)
{
$project = Project::find($project);
$users = User::whereNotIn('email', ['stef@komma.pro'])->orderBy('name', 'asc')->get();
if(!empty($project->excluded_users)) {
$project->excluded_users = explode(',', $project->excluded_users);
}
return view('projects.edit', compact('project', 'users'));
}
/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function create(Request $request)
{
$cache = Cache::has('createProject') ? Cache::pull('createProject') : "";
$outputBudgetSetting = Cache::has('outputMakeProject') ? Cache::pull('outputMakeProject') : "";
$outputNewBudgetSetting = Cache::has('newOutputMakeProject') ? Cache::pull('newOutputMakeProject') : "";
$outputSelectBudgetSetting = Cache::has('outputSelectMakeProject') ? Cache::pull('outputSelectMakeProject') : "";
$company = $this->cacheService->fillSelectBox("company", $cache);
$project = $this->cacheService->fillSelectBox("project", $cache);
$projectManager = $this->cacheService->fillSelectBox("projectManager", $cache);
$companies = Company::orderBy('name', 'asc')->get();
$projectOwners = User::whereNotIn('email', ['stef@komma.pro'])->orderBy('name', 'asc')->get();
$users = User::orderBy('name', 'asc')->get();
$projectTemplates = ProjectTemplate::orderBy('name', 'asc')->where('status','=', 1)->where('name','!=', 'Import')->get();
$taskTemplates = TaskTemplate::orderBy('name', 'asc')->get();
$ref = \Request::filled('ref') ? \Request::get('ref') : 'projecten';
return view('projects.create', compact('projectTemplates', 'taskTemplates', 'company', 'ref', 'users', 'projectOwners', 'companies', 'cache', 'project', 'projectManager', 'outputBudgetSetting', 'outputNewBudgetSetting', 'outputSelectBudgetSetting'));
}
/**
* @param Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function store(Request $request)
{
$this->validate($request, [
'company' => 'required',
'project' => 'required',
'name' => 'required|unique:projects',
'internal' => 'required',
'projectManager' => 'required',
'hourlyRate' => [
'required',
function ($attribute, $value, $fail) {
if ($value === '0' && request()->billable === "1") {
$fail('Bij een facaturabel project moet de uurprijs hoger dan 0 zijn!');
}
if ($value !== '0' && request()->internal === "1") {
$fail('Bij een intern project moet de uurprijs 0 zijn!');
}
},
],
]);
// extra check to prevent duplicate projects
$importProject = $this->projectService->checkIfExist($request);
if (empty($importProject)) {
$project = $this->projectService->storeProject($request);
} else {
$project = $importProject;
}
// Find redirect route
$redirectRoute = 'projecten';
if ($request->filled('ref')) {
$ref = $request->get('ref');
$redirectRoute = str_replace('-', '/', $ref . '?project=' . $project->id);
}
Cache::forget('outputMakeProject');
Cache::forget('newOutputMakeProject');
Cache::forget('outputSelectMakeProject');
if($request->ajax()) {
return $project->id;
} else {
return redirect('/' . $redirectRoute);
}
}
/**
* @param Request $request
* @param $project
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function update(Request $request, $project)
{
$this->validate($request, [
'name' => 'required',
'internal' => 'required',
'projectManager' => 'required',
'hourlyRate' => [
'required',
function ($attribute, $value, $fail) {
if ($value === '0' && request()->internal === "0") {
$fail('Bij een niet-intern project moet de uurprijs hoger dan 0 zijn!');
}
if ($value !== '0' && request()->internal === "1") {
$fail('Bij een intern project moet de uurprijs 0 zijn!');
}
},
],
]);
\DB::transaction(function () use ($request, $project) {
//update project
$project = Project::find($project);
$project->name = $request->name;
$project->hourly_rate = $request->hourlyRate;
$project->billable = !$request->internal;
$project->internal = $request->internal;
$project->reserved = $request->reserved;
$project->excluded_users = !empty($request->excluded_users) ? implode(",",$request->excluded_users) : null;
$project->create_every_x_months = !empty($request->monthly_project) && !empty($request->xMonths) ? $request->xMonths : null;
$project->save();
//update project owner
$projectWorker = ProjectWorker::find($request->projectWorker);
$projectWorker->user_id = $request->projectManager;
$projectWorker->save();
//message + activity
$subject = Project::find($project->id);
$value = "Project";
$this->messageController->changed($value, $subject);
});
return redirect('/projecten/' . $project);
}
/**
* @param Request $request
* @param $project
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function activate(Request $request, $project)
{
\DB::transaction(function () use ($request, $project) {
$project = $this->projectService->eagerLoadProject($project);
$project->archived = '0';
$project->calculated = '0';
$project->save();
$this->projectService->lockHours($project, null);
//message + activity
$subject = Project::find($project->id);
$value = "Project";
$this->messageController->activated($value, $subject);
$this->notificationService->archivedNotification($project);
});
return redirect('/projecten');
}
/**
* @param Request $request
* @param $project
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function archive(Request $request, $project)
{
$project = $this->projectService->eagerLoadProject($project);
$emptySubprojects = $this->projectService->findNotFilledSubprojects($project);
if (!empty($emptySubprojects)) {
\Session::flash('message', 'Onder de deelprojecten ' . rtrim($emptySubprojects, ", ") . ' zijn geen uren ingeboekt!');
return redirect('/projecten/' . $project->id);
}
if (!empty($this->projectService->allExpensesAreBilled($project))) {
\Session::flash('message', 'Er zijn nog niet gefactureerde onkosten!');
return redirect('/projecten/' . $project->id);
}
\DB::transaction(function () use ($request, $project) {
$project->name = explode(' (', $project->name)[0] . Carbon::today()->format(' (d-m-Y)');
$project->archived = '1';
$project->save();
$this->projectService->lockHours($project, Carbon::now());
//message + activity
$subject = Project::find($project->id);
$value = "Project";
$this->messageController->archived($value, $subject);
$this->notificationService->archivedNotification($project);
});
return redirect('/projecten/' . $project->id);
}
/**
* @param $project
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function destroy($project)
{
//get full project
$project = $this->projectService->eagerLoadProject($project);
//check if is has hours
if (!empty($this->projectService->ifHasHours($project))) {
\Session::flash('message', 'Er zijn uren in dit project geschreven!');
return redirect('/projecten/'.$project->id);
}
//check if is has expenses
if (!empty($this->projectService->ifHasExpenses($project))) {
\Session::flash('message', 'Er zijn onkosten in dit project geschreven!');
return redirect('/projecten/'.$project->id);
}
\DB::transaction(function () use ($project) {
//change name
$project->name = explode(' (', $project->name)[0] . Carbon::today()->format(' (d-m-Y)');
//$project->ProjectWorkers()->delete();
//save
$project->save();
//delete
$project->delete();
//message + activity
$value = "Project";
$this->messageController->destroyed($value, $project);
});
//return
return redirect('/projecten');
}
/**
* @param $project
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function restore($project)
{
\DB::transaction(function () use ($project) {
Project::withTrashed()->find($project)->restore();
ProjectWorker::withTrashed()->where('project_id', $project)->restore();
//message + activity
$subject = Project::find($project);
$value = "Project";
$this->messageController->recovered($value, $subject);
});
return redirect('/projecten');
}
public function getProjects(){
$projects = $this->projectService->action('list', "");
$projects = $projects->sortBy('name');
return response()->json(['projects' => $projects]);
}
public function checkDuplicateProject(Request $request){
if($request->internal == "1" && $request->hourlyRate != "0"){
abort(404, "Bij een intern project moet de uurprijs 0 zijn!", ['pjax-error-test' => "Bij een intern project moet de uurprijs 0 zijn!"]);
}
if($request->internal == "0" && $request->hourlyRate == "0") {
abort(404, "Bij een niet-intern project moet de uurprijs hoger dan 0 zijn!", ['pjax-error-test' => "Bij een niet-intern project moet de uurprijs hoger dan 0 zijn!"]);
}
return response()->json(['foundProject' => !empty($this->projectService->checkIfExist($request))]);
}
public function getSubprojectsForProject(Request $request) {
$foundSubprojects = $this->projectService->getProjectSubprojectsByID($request->id);
if(!empty($foundSubprojects)) {
$foundSubprojects = $foundSubprojects->sortBy('name');
return response()->json(['subprojects' => $foundSubprojects->values()->all()]);
} else {
return response('No Subprojects found.', 404);
}
}
public function getProgressBarForProject(Request $request){
return response($this->projectService->getProjectProgressBarByID($request->id));
}
public function storeProjectBilledAmount(Request $request){
$this->projectService->storeProjectBilledAmount($request->id, $request->amount);
return redirect('/projecten/'.$request->id);
}
}