357 lines
14 KiB
PHP
357 lines
14 KiB
PHP
<?php
|
|
|
|
namespace Modules\ProfessionalProject\Http\Controllers;
|
|
|
|
use App\Contact;
|
|
use App\User;
|
|
use App\Utils\ModuleUtil;
|
|
use App\Utils\Util;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Routing\Controller;
|
|
use Modules\ProfessionalProject\Entities\PpMilestone;
|
|
use Modules\ProfessionalProject\Entities\PpProject;
|
|
use Modules\ProfessionalProject\Entities\PpProjectCategory;
|
|
use Modules\ProfessionalProject\Entities\PpTask;
|
|
use Modules\ProfessionalProject\Entities\PpTaskStatus;
|
|
use Modules\ProfessionalProject\Utils\ProfessionalProjectUtil;
|
|
|
|
class ProjectController extends Controller
|
|
{
|
|
protected $commonUtil;
|
|
protected $ppUtil;
|
|
protected $moduleUtil;
|
|
|
|
public function __construct(Util $commonUtil, ProfessionalProjectUtil $ppUtil, ModuleUtil $moduleUtil)
|
|
{
|
|
$this->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')];
|
|
}
|
|
}
|