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);
$this->ppUtil->ensureTaskStatuses($business_id, auth()->user()->id);
$view = request()->get('view', 'kanban');
$project_id = request()->get('project_id');
$statuses = PpTaskStatus::where('business_id', $business_id)->orderBy('position')->get();
$projects = PpProject::projectDropdown($business_id, $is_admin ? null : auth()->user()->id);
$priorities = PpTask::priorityDropdown();
if (request()->ajax()) {
if ($view === 'kanban') {
$boards = [];
foreach ($statuses as $status) {
$query = PpTask::with(['assignees', 'project', 'milestone'])
->where('business_id', $business_id)
->where('status_id', $status->id);
if ($project_id) {
$query->where('project_id', $project_id);
}
if (! $is_admin && ! $project_id) {
$query->whereHas('assignees', fn ($q) => $q->where('user_id', auth()->user()->id));
}
$boards[$status->id] = $query->orderBy('position')->get();
}
return view('professionalproject::task.partials.kanban')
->with(compact('boards', 'statuses', 'priorities'))
->render();
}
$query = PpTask::with(['assignees', 'project', 'status', 'milestone'])
->where('business_id', $business_id);
if ($project_id) {
$query->where('project_id', $project_id);
}
return DataTables::of($query)
->addColumn('action', function ($row) {
$html = '';
if (auth()->user()->can('professionalproject.edit_task')) {
$html .= ' ';
}
if (auth()->user()->can('professionalproject.delete_task')) {
$html .= '';
}
return $html;
})
->editColumn('priority', function ($row) {
$colors = PpTask::priorityColors();
return ''.PpTask::priorityDropdown()[$row->priority].'';
})
->editColumn('status_id', function ($row) {
return $row->status ? $row->status->title : '';
})
->rawColumns(['action', 'priority'])
->make(true);
}
return view('professionalproject::task.index')
->with(compact('view', 'statuses', 'projects', 'project_id', 'priorities'));
}
public function create()
{
$this->authorizeModule();
if (! auth()->user()->can('professionalproject.create_task')) {
abort(403, 'Unauthorized action.');
}
$business_id = request()->session()->get('user.business_id');
$project_id = request()->get('project_id');
$projects = PpProject::projectDropdown($business_id);
$users = User::forDropdown($business_id, false);
$statuses = PpTaskStatus::where('business_id', $business_id)->orderBy('position')->pluck('title', 'id');
$priorities = PpTask::priorityDropdown();
$milestones = $project_id
? \Modules\ProfessionalProject\Entities\PpMilestone::where('project_id', $project_id)->pluck('title', 'id')
: collect();
return view('professionalproject::task.create')
->with(compact('projects', 'users', 'statuses', 'priorities', 'project_id', 'milestones'));
}
public function store(Request $request)
{
$this->authorizeModule();
if (! auth()->user()->can('professionalproject.create_task')) {
abort(403, 'Unauthorized action.');
}
try {
$business_id = $request->session()->get('user.business_id');
$project_id = $request->input('project_id');
$status_id = $request->input('status_id') ?: $this->ppUtil->getDefaultTaskStatusId($business_id);
$milestone_id = $request->input('milestone_id');
if (empty($milestone_id)) {
$milestone = $this->ppUtil->ensureUncategorisedMilestone($business_id, $project_id, auth()->user()->id);
$milestone_id = $milestone->id;
}
$task = PpTask::create([
'business_id' => $business_id,
'project_id' => $project_id,
'milestone_id' => $milestone_id,
'title' => $request->input('title'),
'description' => $request->input('description'),
'status_id' => $status_id,
'priority' => $request->input('priority', 'normal'),
'start_date' => $this->commonUtil->uf_date($request->input('start_date'), true),
'due_date' => $this->commonUtil->uf_date($request->input('due_date'), true),
'duration' => $request->input('duration', 1),
'position' => $this->ppUtil->getNextKanbanPosition($status_id),
'sortorder' => (PpTask::where('project_id', $project_id)->max('sortorder') ?? 0) + 1,
'created_by' => auth()->user()->id,
]);
$task->assignees()->sync($request->input('user_id', []));
$this->ppUtil->notifyUsersAboutAssignedTask(
$request->input('user_id', []),
$task,
$request->user()->user_full_name ?? $request->user()->username
);
$project = PpProject::find($project_id);
if ($project) {
$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()->back()->with('status', $output);
}
public function edit($id)
{
$this->authorizeModule();
if (! auth()->user()->can('professionalproject.edit_task')) {
abort(403, 'Unauthorized action.');
}
$business_id = request()->session()->get('user.business_id');
$task = PpTask::with('assignees')->where('business_id', $business_id)->findOrFail($id);
$projects = PpProject::projectDropdown($business_id);
$users = User::forDropdown($business_id, false);
$statuses = PpTaskStatus::where('business_id', $business_id)->orderBy('position')->pluck('title', 'id');
$priorities = PpTask::priorityDropdown();
$milestones = \Modules\ProfessionalProject\Entities\PpMilestone::where('project_id', $task->project_id)->pluck('title', 'id');
$project_tasks = PpTask::where('project_id', $task->project_id)->where('id', '!=', $id)->pluck('title', 'id');
$dependencies = PpTaskDependency::with('blocker')->where('task_id', $id)->get();
return view('professionalproject::task.edit')
->with(compact('task', 'projects', 'users', 'statuses', 'priorities', 'milestones', 'project_tasks', 'dependencies'));
}
public function update(Request $request, $id)
{
$this->authorizeModule();
if (! auth()->user()->can('professionalproject.edit_task')) {
abort(403, 'Unauthorized action.');
}
$business_id = $request->session()->get('user.business_id');
$task = PpTask::where('business_id', $business_id)->findOrFail($id);
try {
$new_status_id = $request->input('status_id', $task->status_id);
$new_status = PpTaskStatus::find($new_status_id);
if ($new_status && $new_status->is_completed && $this->ppUtil->hasActiveCannotCompleteDependencies($id)) {
return ['success' => false, 'msg' => __('professionalproject::lang.dependency_blocks_complete')];
}
$task->update([
'title' => $request->input('title'),
'description' => $request->input('description'),
'project_id' => $request->input('project_id'),
'milestone_id' => $request->input('milestone_id'),
'status_id' => $new_status_id,
'priority' => $request->input('priority', 'normal'),
'start_date' => $this->commonUtil->uf_date($request->input('start_date'), true),
'due_date' => $this->commonUtil->uf_date($request->input('due_date'), true),
'duration' => $request->input('duration', $task->duration),
'progress' => $request->input('progress', $task->progress),
]);
$syncResult = $task->assignees()->sync($request->input('user_id', []));
$attached = $syncResult['attached'] ?? [];
if (! empty($attached)) {
$this->ppUtil->notifyUsersAboutAssignedTask(
$attached,
$task,
$request->user()->user_full_name ?? $request->user()->username
);
}
if ($new_status && $new_status->is_completed) {
$this->ppUtil->fulfillDependenciesForTask($task->id);
}
$task->project->recalculateProgress();
$output = ['success' => true, 'msg' => __('lang_v1.success')];
} catch (\Exception $e) {
$output = ['success' => false, 'msg' => __('messages.something_went_wrong')];
}
if ($request->ajax()) {
return $output;
}
return redirect()->back()->with('status', $output);
}
public function destroy($id)
{
$this->authorizeModule();
if (! auth()->user()->can('professionalproject.delete_task')) {
abort(403, 'Unauthorized action.');
}
$business_id = request()->session()->get('user.business_id');
$task = PpTask::where('business_id', $business_id)->findOrFail($id);
$project = $task->project;
try {
$task->delete();
if ($project) {
$project->recalculateProgress();
}
$output = ['success' => true, 'msg' => __('lang_v1.success')];
} catch (\Exception $e) {
$output = ['success' => false, 'msg' => __('messages.something_went_wrong')];
}
return $output;
}
public function updateKanbanPosition(Request $request)
{
$this->authorizeModule();
$business_id = $request->session()->get('user.business_id');
$task = PpTask::where('business_id', $business_id)->findOrFail($request->input('task_id'));
$new_status_id = $request->input('status_id');
$new_status = PpTaskStatus::find($new_status_id);
if ($new_status && $new_status->is_completed && $this->ppUtil->hasActiveCannotCompleteDependencies($task->id)) {
return ['success' => false, 'msg' => __('professionalproject::lang.dependency_blocks_complete')];
}
$task->update([
'status_id' => $new_status_id,
'position' => $request->input('position', $this->ppUtil->getNextKanbanPosition($new_status_id)),
]);
if ($new_status && $new_status->is_completed) {
$this->ppUtil->fulfillDependenciesForTask($task->id);
}
$task->project->recalculateProgress();
return ['success' => true, 'msg' => __('lang_v1.success')];
}
public function storeDependency(Request $request)
{
$this->authorizeModule();
$business_id = $request->session()->get('user.business_id');
PpTaskDependency::create([
'task_id' => $request->input('task_id'),
'blocker_task_id' => $request->input('blocker_task_id'),
'project_id' => $request->input('project_id'),
'dependency_type' => $request->input('dependency_type', 'cannot_start'),
'status' => 'active',
'created_by' => auth()->user()->id,
]);
return ['success' => true, 'msg' => __('lang_v1.success')];
}
public function destroyDependency($id)
{
$this->authorizeModule();
PpTaskDependency::findOrFail($id)->delete();
return ['success' => true, 'msg' => __('lang_v1.success')];
}
public function getMilestonesByProject($project_id)
{
$milestones = \Modules\ProfessionalProject\Entities\PpMilestone::where('project_id', $project_id)->pluck('title', 'id');
return $milestones;
}
}