commonUtil = $commonUtil; $this->ppUtil = $ppUtil; $this->moduleUtil = $moduleUtil; } protected function authorizeModule() { $business_id = request()->session()->get('user.business_id'); if (! (auth()->user()->can('superadmin') || $this->moduleUtil->hasThePermissionInSubscription($business_id, 'professional_project_module'))) { abort(403, 'Unauthorized action.'); } if (! auth()->user()->can('professionalproject.access')) { abort(403, 'Unauthorized action.'); } } public function index() { $this->authorizeModule(); $business_id = request()->session()->get('user.business_id'); $is_admin = $this->commonUtil->is_admin(auth()->user(), $business_id); $user_id = auth()->user()->id; $statuses = PpProject::statusDropdown(); $view = request()->get('view', 'list'); if (request()->ajax()) { $query = PpProject::with(['customer', 'members', 'lead']) ->where('business_id', $business_id) ->where('is_archived', false); if (! $is_admin) { $query->where(function ($q) use ($user_id) { $q->where('lead_id', $user_id) ->orWhereHas('members', fn ($m) => $m->where('user_id', $user_id)); }); } if (request()->filled('status')) { $query->where('status', request()->get('status')); } if (request()->filled('filter_category')) { $filter = request()->get('filter_category'); if ($filter === 'uncategorized') { $query->uncategorized(); } elseif ($filter !== 'all' && is_numeric($filter)) { $query->inCategory((int) $filter); } } if (request()->filled('filter_category') && is_numeric(request()->get('filter_category'))) { $cat_id = (int) request()->get('filter_category'); if (PpProjectCategory::forBusiness($business_id)->where('parent_id', $cat_id)->exists()) { $bridge = app(\Modules\ManagementTools\Utils\ProfessionalProjectBridge::class); $browse = $bridge->getCategoryBrowseData($business_id, $cat_id, $user_id, $is_admin, $view); $browse['link_mode'] = 'pp'; return view('professionalproject::category.partials.subcategories_browser', $browse)->render(); } } if ($view === 'kanban') { $projects = $query->get()->groupBy('status'); $sorted = []; foreach ($statuses as $key => $label) { $sorted[$key] = $projects->get($key, collect()); } return view('professionalproject::project.partials.kanban') ->with(compact('sorted', 'statuses', 'is_admin')) ->render(); } $projects = $query->latest()->paginate(15); return view('professionalproject::project.partials.list') ->with(compact('projects', 'is_admin')) ->render(); } return view('professionalproject::project.index') ->with(compact('statuses', 'view')) ->with([ 'filter_category' => request()->get('filter_category'), 'root_categories' => PpProjectCategory::forBusiness($business_id)->roots()->orderBy('position')->orderBy('name')->get(), 'active_category' => request()->filled('filter_category') && is_numeric(request()->get('filter_category')) ? PpProjectCategory::forBusiness($business_id)->find(request()->get('filter_category')) : null, 'category_breadcrumb' => request()->filled('filter_category') && is_numeric(request()->get('filter_category')) ? PpProjectCategory::breadcrumb($business_id, (int) request()->get('filter_category')) : collect(), ]); } protected function formData($business_id, $project = null) { $exclude_id = $project ? $project->id : null; $projects = PpProject::projectDropdown($business_id); if ($exclude_id) { $projects = $projects->except($exclude_id); } return [ 'users' => User::forDropdown($business_id, false), 'customers' => Contact::customersDropdown($business_id, false), 'statuses' => PpProject::statusDropdown(), 'projects' => $projects, 'categories' => PpProjectCategory::dropdown($business_id), 'categories_with_members' => PpProjectCategory::forBusiness($business_id) ->with('members') ->orderBy('position') ->orderBy('name') ->get(), 'project' => $project, ]; } protected function syncProjectRelations(PpProject $project, Request $request) { $members = array_filter((array) $request->input('user_id', [])); $manager_id = $request->input('manager_id') ?: $request->input('lead_id'); if (empty($members)) { $members = [auth()->id()]; } if ($manager_id && ! in_array($manager_id, $members)) { $members[] = $manager_id; } $project->members()->sync($members); $project->categories()->sync($request->input('category_id', [])); $project->supervisors()->sync($request->input('supervisor_id', [])); $parent_ids = array_filter((array) $request->input('parent_id', [])); $project->parents()->sync($parent_ids); $project->update(['parent_id' => ! empty($parent_ids) ? (int) reset($parent_ids) : null]); } public function create() { $this->authorizeModule(); if (! auth()->user()->can('professionalproject.create_project')) { abort(403, 'Unauthorized action.'); } $business_id = request()->session()->get('user.business_id'); return view('professionalproject::project.create') ->with($this->formData($business_id)); } public function store(Request $request) { $this->authorizeModule(); if (! auth()->user()->can('professionalproject.create_project')) { abort(403, 'Unauthorized action.'); } try { $business_id = $request->session()->get('user.business_id'); $manager_id = $request->input('manager_id') ?: auth()->user()->id; $input = $request->only(['name', 'description', 'contact_id', 'status', 'difficulty']); $input['business_id'] = $business_id; $input['created_by'] = auth()->user()->id; $input['manager_id'] = $manager_id; $input['lead_id'] = $manager_id; $input['start_date'] = $this->commonUtil->uf_date($request->input('start_date'), true); $input['end_date'] = $this->commonUtil->uf_date($request->input('end_date'), true); $input['progress_manual'] = ! empty($request->input('progress_manual')); $input['progress'] = $request->input('progress', 0); $input['is_locked'] = ! empty($request->input('is_locked')); $project = PpProject::create($input); $this->syncProjectRelations($project, $request); $this->ppUtil->ensureUncategorisedMilestone($business_id, $project->id, auth()->user()->id); $this->ppUtil->ensureTaskStatuses($business_id, auth()->user()->id); $output = ['success' => true, 'msg' => __('lang_v1.success')]; } catch (\Exception $e) { \Log::emergency('File:'.$e->getFile().'Line:'.$e->getLine().'Message:'.$e->getMessage()); $output = ['success' => false, 'msg' => __('messages.something_went_wrong')]; } return redirect()->action([self::class, 'show'], $project->id)->with('status', $output); } public function show($id) { $this->authorizeModule(); $business_id = request()->session()->get('user.business_id'); $project = PpProject::with(['customer', 'members', 'lead', 'milestones', 'tasks.status', 'tasks.assignees']) ->where('business_id', $business_id) ->findOrFail($id); if (! $this->ppUtil->canAccessProject(auth()->user(), $business_id, $id)) { abort(403, 'Unauthorized action.'); } $tab = request()->get('tab', 'overview'); $can_manage = $this->ppUtil->canManageProject(auth()->user(), $business_id, $id); $statuses = PpProject::statusDropdown(); $task_statuses = PpTaskStatus::where('business_id', $business_id)->orderBy('position')->get(); $milestones = PpMilestone::withCount('tasks')->where('project_id', $id)->orderBy('position')->get(); $users = User::forDropdown($business_id, false); return view('professionalproject::project.show') ->with(compact('project', 'tab', 'can_manage', 'statuses', 'task_statuses', 'milestones', 'users')); } public function edit($id) { $this->authorizeModule(); if (! auth()->user()->can('professionalproject.edit_project')) { abort(403, 'Unauthorized action.'); } $business_id = request()->session()->get('user.business_id'); $project = PpProject::with(['categories', 'members', 'supervisors', 'parents']) ->where('business_id', $business_id) ->findOrFail($id); if (! $this->ppUtil->canManageProject(auth()->user(), $business_id, $id)) { abort(403, 'Unauthorized action.'); } return view('professionalproject::project.edit') ->with($this->formData($business_id, $project)); } public function update(Request $request, $id) { $this->authorizeModule(); if (! auth()->user()->can('professionalproject.edit_project')) { abort(403, 'Unauthorized action.'); } $business_id = $request->session()->get('user.business_id'); $project = PpProject::where('business_id', $business_id)->findOrFail($id); if (! $this->ppUtil->canManageProject(auth()->user(), $business_id, $id)) { abort(403, 'Unauthorized action.'); } try { $manager_id = $request->input('manager_id') ?: $project->lead_id; $input = $request->only(['name', 'description', 'contact_id', 'status', 'difficulty', 'progress']); $input['manager_id'] = $manager_id; $input['lead_id'] = $manager_id; $input['start_date'] = $this->commonUtil->uf_date($request->input('start_date'), true); $input['end_date'] = $this->commonUtil->uf_date($request->input('end_date'), true); $input['progress_manual'] = ! empty($request->input('progress_manual')); $input['is_locked'] = ! empty($request->input('is_locked')); $project->update($input); $this->syncProjectRelations($project, $request); if (! $project->progress_manual) { $project->recalculateProgress(); } $output = ['success' => true, 'msg' => __('lang_v1.success')]; } catch (\Exception $e) { \Log::emergency('File:'.$e->getFile().'Line:'.$e->getLine().'Message:'.$e->getMessage()); $output = ['success' => false, 'msg' => __('messages.something_went_wrong')]; } if ($request->ajax()) { return $output; } return redirect()->action([self::class, 'show'], $id)->with('status', $output); } public function destroy($id) { $this->authorizeModule(); if (! auth()->user()->can('professionalproject.delete_project')) { abort(403, 'Unauthorized action.'); } $business_id = request()->session()->get('user.business_id'); $project = PpProject::where('business_id', $business_id)->findOrFail($id); try { $project->delete(); $output = ['success' => true, 'msg' => __('lang_v1.success')]; } catch (\Exception $e) { $output = ['success' => false, 'msg' => __('messages.something_went_wrong')]; } return $output; } public function postStatus(Request $request, $id) { $this->authorizeModule(); $business_id = $request->session()->get('user.business_id'); $project = PpProject::where('business_id', $business_id)->findOrFail($id); if (! $this->ppUtil->canManageProject(auth()->user(), $business_id, $id)) { abort(403, 'Unauthorized action.'); } $project->update(['status' => $request->input('status')]); return ['success' => true, 'msg' => __('lang_v1.success')]; } public function archive($id) { $this->authorizeModule(); $business_id = request()->session()->get('user.business_id'); $project = PpProject::where('business_id', $business_id)->findOrFail($id); if (! $this->ppUtil->canManageProject(auth()->user(), $business_id, $id)) { abort(403, 'Unauthorized action.'); } $project->update(['is_archived' => true]); return ['success' => true, 'msg' => __('professionalproject::lang.project_archived')]; } }