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

}