diff --git a/app/Http/Controllers/ActivityTypeController.php b/app/Http/Controllers/ActivityTypeController.php index f9c87beb9..8f3b26818 100644 --- a/app/Http/Controllers/ActivityTypeController.php +++ b/app/Http/Controllers/ActivityTypeController.php @@ -96,6 +96,11 @@ public function update(ActivityType $activityType, UpdateActivityTypeRequest $re */ public function destroy(ActivityType $activityType) { + if ($activityType->timeEntries()->count() > 0) { + return $this->sendError('This activity has more than one time entry, so it can\'t be deleted.'); + } + + $activityType->update(['deleted_by' => getLoggedInUserId()]); $activityType->delete(); return $this->sendSuccess('Activity Type deleted successfully.'); diff --git a/app/Http/Controllers/ClientController.php b/app/Http/Controllers/ClientController.php index dc3228ee1..e8fcf3492 100644 --- a/app/Http/Controllers/ClientController.php +++ b/app/Http/Controllers/ClientController.php @@ -121,7 +121,7 @@ public function update(Client $client, UpdateClientRequest $request) */ public function destroy(Client $client) { - $client->delete(); + $this->clientRepository->delete($client->id); return $this->sendSuccess('Client deleted successfully.'); } diff --git a/app/Http/Controllers/ProjectController.php b/app/Http/Controllers/ProjectController.php index 190832f6b..1fa0ddebe 100644 --- a/app/Http/Controllers/ProjectController.php +++ b/app/Http/Controllers/ProjectController.php @@ -133,7 +133,7 @@ public function update(Project $project, UpdateProjectRequest $request) */ public function destroy(Project $project) { - $project->delete(); + $this->projectRepository->delete($project->id); return $this->sendSuccess('Project deleted successfully.'); } diff --git a/app/Http/Controllers/TagController.php b/app/Http/Controllers/TagController.php index 4dcb790c9..cdbdb5309 100644 --- a/app/Http/Controllers/TagController.php +++ b/app/Http/Controllers/TagController.php @@ -98,6 +98,8 @@ public function update(Tag $tag, UpdateTagRequest $request) */ public function destroy(Tag $tag) { + $tag->deleted_by = getLoggedInUserId(); + $tag->save(); $tag->delete(); return $this->sendSuccess('Tag deleted successfully.'); diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index f4a32ea45..c1395e02d 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -177,6 +177,8 @@ public function update(User $user, UpdateUserRequest $request) */ public function destroy(User $user) { + $user->deleted_by = getLoggedInUserId(); + $user->save(); $user->delete(); return $this->sendSuccess('User deleted successfully.'); diff --git a/app/Models/ActivityType.php b/app/Models/ActivityType.php index dc65484a8..61eeca2c8 100644 --- a/app/Models/ActivityType.php +++ b/app/Models/ActivityType.php @@ -3,6 +3,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\SoftDeletes; /** * App\Models\ActivityType. @@ -26,10 +27,11 @@ */ class ActivityType extends Model { + use SoftDeletes; public $table = 'activity_types'; public $fillable = [ - 'name', + 'name', 'created_by', 'deleted_by', ]; /** @@ -38,8 +40,9 @@ class ActivityType extends Model * @var array */ protected $casts = [ - 'id' => 'integer', - 'name' => 'string', + 'id' => 'integer', + 'name' => 'string', + 'created_by' => 'integer', ]; const ACTIVITY_TYPES = [ @@ -70,4 +73,9 @@ public function createdUser() { return $this->belongsTo(User::class, 'created_by'); } + + public function timeEntries() + { + return $this->hasMany(TimeEntry::class, 'activity_type_id'); + } } diff --git a/app/Models/Client.php b/app/Models/Client.php index f69aef8a3..06b129831 100644 --- a/app/Models/Client.php +++ b/app/Models/Client.php @@ -3,6 +3,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\SoftDeletes; /** * App\Models\Client. @@ -30,6 +31,7 @@ */ class Client extends Model { + use softDeletes; public $table = 'clients'; public $fillable = [ @@ -37,6 +39,7 @@ class Client extends Model 'email', 'website', 'created_by', + 'deleted_by', ]; /** @@ -79,4 +82,12 @@ public function createdUser() { return $this->belongsTo(User::class, 'created_by'); } + + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany + */ + public function projects() + { + return $this->hasMany(Project::class); + } } diff --git a/app/Models/Project.php b/app/Models/Project.php index f4073fc17..bf2ea001a 100644 --- a/app/Models/Project.php +++ b/app/Models/Project.php @@ -3,6 +3,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\SoftDeletes; /** * App\Models\Project. @@ -36,6 +37,7 @@ */ class Project extends Model { + use softDeletes; const TEAM_ARR = ['1' => 'Backend', '2' => 'Frontend', '3' => 'Mobile', '4' => 'QA']; public $table = 'projects'; @@ -46,6 +48,7 @@ class Project extends Model 'description', 'client_id', 'created_by', + 'deleted_by', 'prefix', ]; @@ -111,4 +114,12 @@ public function createdUser() { return $this->belongsTo(User::class, 'created_by'); } + + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany + */ + public function tasks() + { + return $this->hasMany(Task::class); + } } diff --git a/app/Models/Tag.php b/app/Models/Tag.php index c59ba2d1a..48421f835 100644 --- a/app/Models/Tag.php +++ b/app/Models/Tag.php @@ -3,6 +3,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\SoftDeletes; /** * App\Models\Tag. @@ -26,11 +27,13 @@ */ class Tag extends Model { + use softDeletes; public $table = 'tags'; public $fillable = [ 'name', 'created_by', + 'deleted_by', ]; /** @@ -42,6 +45,7 @@ class Tag extends Model 'id' => 'integer', 'name' => 'string', 'created_by' => 'integer', + 'deleted_by' => 'integer', ]; /** diff --git a/app/Models/Task.php b/app/Models/Task.php index f3afdda18..6aa469ac4 100644 --- a/app/Models/Task.php +++ b/app/Models/Task.php @@ -131,7 +131,7 @@ public function tags() */ public function project() { - return $this->belongsTo(Project::class, 'project_id'); + return $this->belongsTo(Project::class, 'project_id')->withTrashed(); } /** @@ -162,6 +162,16 @@ public function timeEntries() return $this->hasMany(TimeEntry::class, 'task_id')->latest(); } + public static function boot() + { + parent::boot(); + + static::deleting(function ($task) { + $task->timeEntries()->update(['deleted_by' => getLoggedInUserId()]); + $task->timeEntries()->delete(); + }); + } + /** * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ diff --git a/app/Models/User.php b/app/Models/User.php index 84bde1672..24b5d7922 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -4,6 +4,7 @@ use App\Notifications\MailResetPasswordNotification; use App\Traits\ImageTrait; +use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Zizaco\Entrust\Traits\EntrustUserTrait; @@ -60,10 +61,16 @@ */ class User extends Authenticatable { - use Notifiable, EntrustUserTrait, ImageTrait; + use Notifiable, ImageTrait, softDeletes, EntrustUserTrait { + SoftDeletes::restore insteadof EntrustUserTrait; + EntrustUserTrait::restore insteadof SoftDeletes; + } use ImageTrait { deleteImage as traitDeleteImage; } + use SoftDeletes { + restore as restoreSoftDeletes; + } public $table = 'users'; const IMAGE_PATH = 'users'; @@ -84,6 +91,7 @@ class User extends Authenticatable 'activation_code', 'is_active', 'image_path', + 'deleted_by', ]; /** @@ -175,7 +183,7 @@ public function getImagePathAttribute($value) return $this->imageUrl(self::IMAGE_PATH.DIRECTORY_SEPARATOR.$value); } - return asset('assets/img/user-avatar.png'); + return getUserImageInitial($this->id, $this->name); } /** diff --git a/app/Queries/TimeEntryDataTable.php b/app/Queries/TimeEntryDataTable.php index 2c43c5bff..09d0b4f86 100644 --- a/app/Queries/TimeEntryDataTable.php +++ b/app/Queries/TimeEntryDataTable.php @@ -31,15 +31,19 @@ function (Builder $q) use ($input) { $q->where('activity_type_id', $input['filter_activity']); }); $query->when(isset($input['filter_project']) && !empty($input['filter_project']), - function (Builder $q) use ($input) { - $filterUserId = (isset($input['filter_user']) && !empty($input['filter_user'])) ? $input['filter_user'] : getLoggedInUser()->id; - $taskIds = Task::whereProjectId($input['filter_project']) - ->where(function ($q) use ($filterUserId) { - $q->whereHas('taskAssignee', function ($q) use ($filterUserId) { - $q->where('user_id', $filterUserId); - }); - })->get()->pluck('id')->toArray(); - $q->whereIn('task_id', $taskIds); + function (Builder $q) use ($input,$user) { + if ($user->can('manage_time_entries')) { + $taskIds = Task::whereProjectId($input['filter_project'])->get()->pluck('id')->toArray(); + $q->whereIn('task_id', $taskIds); + } else { + $taskIds = Task::whereProjectId($input['filter_project']) + ->where(function ($q) { + $q->whereHas('taskAssignee', function ($q) { + $q->where('user_id', getLoggedInUserId()); + }); + })->get()->pluck('id')->toArray(); + $q->whereIn('task_id', $taskIds); + } }); if (!$user->can('manage_time_entries')) { return $query->OfCurrentUser(); diff --git a/app/Repositories/ClientRepository.php b/app/Repositories/ClientRepository.php index 30ce07358..daf80dd19 100644 --- a/app/Repositories/ClientRepository.php +++ b/app/Repositories/ClientRepository.php @@ -3,6 +3,9 @@ namespace App\Repositories; use App\Models\Client; +use App\Models\Project; +use App\Models\Task; +use App\Models\TimeEntry; /** * Class ClientRepository. @@ -47,4 +50,31 @@ public function getClientList() { return Client::orderBy('name')->pluck('name', 'id'); } + + /** + * @param int $clientId + * + * @throws \Exception + * + * @return bool|mixed|void|null + */ + public function delete($clientId) + { + $client = $this->find($clientId); + + $projectIds = Project::where('client_id', '=', $client->id)->get()->pluck('id'); + $taskIds = Task::whereIn('project_id', $projectIds)->get()->pluck('id'); + + TimeEntry::whereIn('task_id', $taskIds)->update(['deleted_by' => getLoggedInUserId()]); + TimeEntry::whereIn('task_id', $taskIds)->delete(); + + Task::whereIn('project_id', $projectIds)->update(['deleted_by' => getLoggedInUserId()]); + Task::whereIn('project_id', $projectIds)->delete(); + + $client->projects()->update(['deleted_by' => getLoggedInUserId()]); + $client->projects()->delete(); + + $client->update(['deleted_by' => getLoggedInUserId()]); + $client->delete(); + } } diff --git a/app/Repositories/ProjectRepository.php b/app/Repositories/ProjectRepository.php index 8947f90a4..f55207124 100644 --- a/app/Repositories/ProjectRepository.php +++ b/app/Repositories/ProjectRepository.php @@ -3,6 +3,8 @@ namespace App\Repositories; use App\Models\Project; +use App\Models\Task; +use App\Models\TimeEntry; use Auth; use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Collection; @@ -88,4 +90,26 @@ public function getProjectsList($clientId = null) return $query->pluck('name', 'id'); } + + /** + * @param int $id + * + * @throws \Exception + * + * @return bool|mixed|void|null + */ + public function delete($id) + { + $project = $this->find($id); + + $taskIds = Task::whereProjectId($project->id)->pluck('id')->toArray(); + TimeEntry::whereIn('task_id', $taskIds)->update(['deleted_by' => getLoggedInUserId()]); + TimeEntry::whereIn('task_id', $taskIds)->delete(); + + $project->tasks()->update(['deleted_by' => getLoggedInUserId()]); + $project->tasks()->delete(); + + $project->update(['deleted_by' => getLoggedInUserId()]); + $project->delete(); + } } diff --git a/app/Repositories/ReportRepository.php b/app/Repositories/ReportRepository.php index a562ddff2..7639a6106 100644 --- a/app/Repositories/ReportRepository.php +++ b/app/Repositories/ReportRepository.php @@ -266,8 +266,6 @@ public function getReport($report) $project = $entry->task->project; $client = $project->client; $duration = $entry->duration; - $projectPrefix = $project->prefix; - $taskNumber = $entry->task->task_number; // prepare client and duration $result[$clientId]['name'] = $client->name; @@ -308,8 +306,7 @@ public function getReport($report) $time = $result[$clientId]['projects'][$project->id]['users'][$entry->user_id]['tasks'][$entry->task_id]['duration'] + $entry->duration; $result[$clientId]['projects'][$project->id]['users'][$entry->user_id]['tasks'][$entry->task_id]['duration'] = $time; $result[$clientId]['projects'][$project->id]['users'][$entry->user_id]['tasks'][$entry->task_id]['time'] = $this->getDurationTime($time); - $result[$clientId]['projects'][$project->id]['users'][$entry->user_id]['tasks'][$entry->task_id]['project_prefix'] = $projectPrefix; - $result[$clientId]['projects'][$project->id]['users'][$entry->user_id]['tasks'][$entry->task_id]['task_number'] = $taskNumber; + $result[$clientId]['projects'][$project->id]['users'][$entry->user_id]['tasks'][$entry->task_id]['task_id'] = $entry->task->id; } return $result; diff --git a/composer.json b/composer.json index 39e157dd9..05e02dac5 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "infyomlabs/infy-tracker", "type": "project", - "version": "1.8.2-alpha", + "version": "1.8.3-alpha", "description": "Create Projects / Tasks, Track Time, Show Daily Reports", "keywords": [ "time", diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php index b7cb1d8af..cb4dc9c0e 100644 --- a/database/migrations/2014_10_12_000000_create_users_table.php +++ b/database/migrations/2014_10_12_000000_create_users_table.php @@ -28,9 +28,7 @@ public function up() $table->timestamps(); // foreign - $table->foreign('created_by')->references('id')->on('users') - ->onDelete('set null') - ->onUpdate('set null'); + $table->foreign('created_by')->references('id')->on('users'); }); } diff --git a/database/migrations/2019_05_02_101439_create_activity_types_table.php b/database/migrations/2019_05_02_101439_create_activity_types_table.php index a32f8f87c..3d21b3a10 100644 --- a/database/migrations/2019_05_02_101439_create_activity_types_table.php +++ b/database/migrations/2019_05_02_101439_create_activity_types_table.php @@ -19,9 +19,7 @@ public function up() $table->timestamps(); // foreign - $table->foreign('created_by')->references('id')->on('users') - ->onDelete('set null') - ->onUpdate('set null'); + $table->foreign('created_by')->references('id')->on('users'); }); } diff --git a/database/migrations/2019_05_02_101619_create_clients_table.php b/database/migrations/2019_05_02_101619_create_clients_table.php index 28138098b..cde1535fe 100644 --- a/database/migrations/2019_05_02_101619_create_clients_table.php +++ b/database/migrations/2019_05_02_101619_create_clients_table.php @@ -21,9 +21,7 @@ public function up() $table->timestamps(); // foreign - $table->foreign('created_by')->references('id')->on('users') - ->onDelete('set null') - ->onUpdate('set null'); + $table->foreign('created_by')->references('id')->on('users'); }); } diff --git a/database/migrations/2019_05_03_043336_create_tags_table.php b/database/migrations/2019_05_03_043336_create_tags_table.php index 37dc00a9d..e0ab4b9b5 100644 --- a/database/migrations/2019_05_03_043336_create_tags_table.php +++ b/database/migrations/2019_05_03_043336_create_tags_table.php @@ -19,9 +19,7 @@ public function up() $table->timestamps(); // foreign - $table->foreign('created_by')->references('id')->on('users') - ->onDelete('set null') - ->onUpdate('set null'); + $table->foreign('created_by')->references('id')->on('users'); }); } diff --git a/database/migrations/2019_05_03_050601_create_projects_table.php b/database/migrations/2019_05_03_050601_create_projects_table.php index 33fef155f..1ad4f2a45 100644 --- a/database/migrations/2019_05_03_050601_create_projects_table.php +++ b/database/migrations/2019_05_03_050601_create_projects_table.php @@ -21,13 +21,9 @@ public function up() $table->timestamps(); //foreign - $table->foreign('client_id')->references('id')->on('clients') - ->onDelete('set null') - ->onUpdate('set null'); + $table->foreign('client_id')->references('id')->on('clients'); - $table->foreign('created_by')->references('id')->on('users') - ->onDelete('set null') - ->onUpdate('set null'); + $table->foreign('created_by')->references('id')->on('users'); }); } diff --git a/database/migrations/2019_05_03_060503_create_tasks_table.php b/database/migrations/2019_05_03_060503_create_tasks_table.php index eefc89783..9c950cb0f 100644 --- a/database/migrations/2019_05_03_060503_create_tasks_table.php +++ b/database/migrations/2019_05_03_060503_create_tasks_table.php @@ -25,18 +25,11 @@ public function up() $table->softDeletes(); // foreign - $table->foreign('deleted_by')->references('id')->on('users') - ->onDelete('set null') - ->onUpdate('set null'); + $table->foreign('deleted_by')->references('id')->on('users'); - $table->foreign('project_id') - ->references('id')->on('projects') - ->onDelete('cascade') - ->onUpdate('cascade'); + $table->foreign('project_id')->references('id')->on('projects'); - $table->foreign('created_by')->references('id')->on('users') - ->onDelete('set null') - ->onUpdate('set null'); + $table->foreign('created_by')->references('id')->on('users'); }); } diff --git a/database/migrations/2019_05_03_072634_create_task_tags_table.php b/database/migrations/2019_05_03_072634_create_task_tags_table.php index 870a8aad8..1687e8e97 100644 --- a/database/migrations/2019_05_03_072634_create_task_tags_table.php +++ b/database/migrations/2019_05_03_072634_create_task_tags_table.php @@ -18,15 +18,9 @@ public function up() $table->unsignedInteger('task_id'); $table->unsignedInteger('tag_id'); - $table->foreign('task_id') - ->references('id')->on('tasks') - ->onUpdate('cascade') - ->onDelete('cascade'); + $table->foreign('task_id')->references('id')->on('tasks'); - $table->foreign('tag_id') - ->references('id')->on('tags') - ->onUpdate('cascade') - ->onDelete('cascade'); + $table->foreign('tag_id')->references('id')->on('tags'); }); } diff --git a/database/migrations/2019_05_03_094616_create_time_entries_table.php b/database/migrations/2019_05_03_094616_create_time_entries_table.php index bb0571c45..28ccb0099 100644 --- a/database/migrations/2019_05_03_094616_create_time_entries_table.php +++ b/database/migrations/2019_05_03_094616_create_time_entries_table.php @@ -26,21 +26,13 @@ public function up() $table->softDeletes(); // foreign - $table->foreign('deleted_by')->references('id')->on('users') - ->onDelete('set null') - ->onUpdate('set null'); + $table->foreign('deleted_by')->references('id')->on('users'); - $table->foreign('task_id')->references('id')->on('tasks') - ->onDelete('cascade') - ->onUpdate('cascade'); + $table->foreign('task_id')->references('id')->on('tasks'); - $table->foreign('activity_type_id')->references('id')->on('activity_types') - ->onDelete('cascade') - ->onUpdate('cascade'); + $table->foreign('activity_type_id')->references('id')->on('activity_types'); - $table->foreign('user_id')->references('id')->on('users') - ->onDelete('cascade') - ->onUpdate('cascade'); + $table->foreign('user_id')->references('id')->on('users'); }); } diff --git a/database/migrations/2019_05_22_115729_create_table_task_assignees.php b/database/migrations/2019_05_22_115729_create_table_task_assignees.php index b2c3432d1..f078aec0b 100644 --- a/database/migrations/2019_05_22_115729_create_table_task_assignees.php +++ b/database/migrations/2019_05_22_115729_create_table_task_assignees.php @@ -18,13 +18,9 @@ public function up() $table->unsignedInteger('user_id'); //foreign - $table->foreign('task_id')->references('id')->on('tasks') - ->onDelete('cascade') - ->onUpdate('cascade'); + $table->foreign('task_id')->references('id')->on('tasks'); - $table->foreign('user_id')->references('id')->on('users') - ->onDelete('cascade') - ->onUpdate('cascade'); + $table->foreign('user_id')->references('id')->on('users'); }); } diff --git a/database/migrations/2019_06_11_062240_create_project_users_table.php b/database/migrations/2019_06_11_062240_create_project_users_table.php index 1db798620..5d93be6d7 100644 --- a/database/migrations/2019_06_11_062240_create_project_users_table.php +++ b/database/migrations/2019_06_11_062240_create_project_users_table.php @@ -19,15 +19,9 @@ public function up() $table->unsignedInteger('user_id'); $table->timestamps(); - $table->foreign('project_id') - ->references('id')->on('projects') - ->onUpdate('cascade') - ->onDelete('cascade'); + $table->foreign('project_id')->references('id')->on('projects'); - $table->foreign('user_id') - ->references('id')->on('users') - ->onUpdate('cascade') - ->onDelete('cascade'); + $table->foreign('user_id')->references('id')->on('users'); }); } diff --git a/database/migrations/2019_06_18_093135_create_table_task_attachment.php b/database/migrations/2019_06_18_093135_create_table_task_attachment.php index 3d1d81ba5..9fa2a15d8 100644 --- a/database/migrations/2019_06_18_093135_create_table_task_attachment.php +++ b/database/migrations/2019_06_18_093135_create_table_task_attachment.php @@ -19,10 +19,7 @@ public function up() $table->string('file')->nullable(); $table->timestamps(); - $table->foreign('task_id') - ->references('id')->on('tasks') - ->onUpdate('cascade') - ->onDelete('cascade'); + $table->foreign('task_id')->references('id')->on('tasks'); }); } diff --git a/database/migrations/2019_07_01_050129_entrust_setup_tables.php b/database/migrations/2019_07_01_050129_entrust_setup_tables.php index c984f5dc0..9d9f516c4 100644 --- a/database/migrations/2019_07_01_050129_entrust_setup_tables.php +++ b/database/migrations/2019_07_01_050129_entrust_setup_tables.php @@ -28,10 +28,8 @@ public function up() $table->integer('user_id')->unsigned(); $table->integer('role_id')->unsigned(); - $table->foreign('user_id')->references('id')->on('users') - ->onUpdate('cascade')->onDelete('cascade'); - $table->foreign('role_id')->references('id')->on('roles') - ->onUpdate('cascade')->onDelete('cascade'); + $table->foreign('user_id')->references('id')->on('users'); + $table->foreign('role_id')->references('id')->on('roles'); $table->primary(['user_id', 'role_id']); }); @@ -50,10 +48,8 @@ public function up() $table->integer('permission_id')->unsigned(); $table->integer('role_id')->unsigned(); - $table->foreign('permission_id')->references('id')->on('permissions') - ->onUpdate('cascade')->onDelete('cascade'); - $table->foreign('role_id')->references('id')->on('roles') - ->onUpdate('cascade')->onDelete('cascade'); + $table->foreign('permission_id')->references('id')->on('permissions'); + $table->foreign('role_id')->references('id')->on('roles'); $table->primary(['permission_id', 'role_id']); }); diff --git a/database/migrations/2019_07_06_121218_create_reports_table.php b/database/migrations/2019_07_06_121218_create_reports_table.php index 877e47ca2..61a58d6d0 100644 --- a/database/migrations/2019_07_06_121218_create_reports_table.php +++ b/database/migrations/2019_07_06_121218_create_reports_table.php @@ -19,10 +19,7 @@ public function up() $table->date('start_date'); $table->date('end_date'); $table->timestamps(); - $table->foreign('owner_id') - ->references('id')->on('users') - ->onDelete('cascade') - ->onUpdate('cascade'); + $table->foreign('owner_id')->references('id')->on('users'); }); } diff --git a/database/migrations/2019_09_05_123722_add_soft_delete_in_all_table.php b/database/migrations/2019_09_05_123722_add_soft_delete_in_all_table.php new file mode 100644 index 000000000..fdc424f5a --- /dev/null +++ b/database/migrations/2019_09_05_123722_add_soft_delete_in_all_table.php @@ -0,0 +1,76 @@ +softDeletes(); + $table->unsignedInteger('deleted_by')->nullable(); + $table->foreign('deleted_by')->references('id')->on('users'); + }); + Schema::table('clients', function (Blueprint $table) { + $table->softDeletes(); + $table->unsignedInteger('deleted_by')->nullable(); + $table->foreign('deleted_by')->references('id')->on('users'); + }); + Schema::table('projects', function (Blueprint $table) { + $table->softDeletes(); + $table->unsignedInteger('deleted_by')->nullable(); + $table->foreign('deleted_by')->references('id')->on('users'); + }); + Schema::table('tags', function (Blueprint $table) { + $table->softDeletes(); + $table->unsignedInteger('deleted_by')->nullable(); + $table->foreign('deleted_by')->references('id')->on('users'); + }); + Schema::table('users', function (Blueprint $table) { + $table->softDeletes(); + $table->unsignedInteger('deleted_by')->nullable(); + $table->foreign('deleted_by')->references('id')->on('users'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('activity_types', function (Blueprint $table) { + $table->dropSoftDeletes(); + $table->dropForeign(['deleted_by']); + $table->dropColumn('deleted_by'); + }); + Schema::table('clients', function (Blueprint $table) { + $table->dropSoftDeletes(); + $table->dropForeign(['deleted_by']); + $table->dropColumn('deleted_by'); + }); + Schema::table('projects', function (Blueprint $table) { + $table->dropSoftDeletes(); + $table->dropForeign(['deleted_by']); + $table->dropColumn('deleted_by'); + }); + Schema::table('tags', function (Blueprint $table) { + $table->dropSoftDeletes(); + $table->dropForeign(['deleted_by']); + $table->dropColumn('deleted_by'); + }); + Schema::table('users', function (Blueprint $table) { + $table->dropSoftDeletes(); + $table->dropForeign(['deleted_by']); + $table->dropColumn('deleted_by'); + }); + } +} diff --git a/database/testing.sqlite b/database/testing.sqlite index 4adddde76..0210bcce6 100644 Binary files a/database/testing.sqlite and b/database/testing.sqlite differ diff --git a/public/images/warning.png b/public/images/warning.png new file mode 100644 index 000000000..1bc555d83 Binary files /dev/null and b/public/images/warning.png differ diff --git a/resources/assets/js/clients/client.js b/resources/assets/js/clients/client.js index 841e1bcce..12700f4e6 100644 --- a/resources/assets/js/clients/client.js +++ b/resources/assets/js/clients/client.js @@ -125,5 +125,8 @@ $(document).on('click', '.edit-btn', function (event) { $(document).on('click', '.delete-btn', function (event) { let clientId = $(event.currentTarget).data('id'); - deleteItem(clientUrl + clientId, '#clients_table', 'Client'); + let alertMessage = '
\n' + + 'Are you sure want to delete this client?
By deleting this client all its project, task and time entries will be deleted.
'; + + deleteItemInputConfirmation(clientUrl + clientId, '#clients_table', 'Client', alertMessage); }); diff --git a/resources/assets/js/custom.js b/resources/assets/js/custom.js index 35922a485..c39c18dea 100644 --- a/resources/assets/js/custom.js +++ b/resources/assets/js/custom.js @@ -52,6 +52,36 @@ $(document).on('click', '.btn-task-delete', function (event) { }, 1000); }); +function deleteItemAjax(url, tableId, header, callFunction = null) { + $.ajax({ + url: url, + type: 'DELETE', + dataType: 'json', + success: function (obj) { + if (obj.success) { + $(tableId).DataTable().ajax.reload(null, false); + } + swal({ + title: 'Deleted!', + text: header + ' has been deleted.', + type: 'success', + timer: 2000 + }); + if (callFunction) { + eval(callFunction); + } + }, + error: function (data) { + swal({ + title: '', + text: data.responseJSON.message, + type: 'error', + timer: 5000 + }); + } + }); +} + window.deleteItem = function (url, tableId, header, callFunction = null) { swal({ title: "Delete !", @@ -66,33 +96,38 @@ window.deleteItem = function (url, tableId, header, callFunction = null) { confirmButtonText: 'Yes' }, function () { - $.ajax({ - url: url, - type: 'DELETE', - dataType: 'json', - success: function (obj) { - if (obj.success) { - $(tableId).DataTable().ajax.reload(null, false); - } - swal({ - title: 'Deleted!', - text: header + ' has been deleted.', - type: 'success', - timer: 2000 - }); - if (callFunction) { - eval(callFunction); - } - }, - error: function (data) { - swal({ - title: '', - text: data.responseJSON.message, - type: 'error', - timer: 5000 - }); - } - }); + deleteItemAjax(url, tableId, header, callFunction = null); + }); +}; + +window.deleteItemInputConfirmation = function (url, tableId, header, alertMessage, callFunction = null) { + swal({ + type: "input", + inputPlaceholder: "Please type \"delete\" to delete this "+header+".", + title: "Delete !", + text: alertMessage, + html: true, + showCancelButton: true, + closeOnConfirm: false, + showLoaderOnConfirm: true, + confirmButtonColor: '#5cb85c', + cancelButtonColor: '#d33', + cancelButtonText: 'No', + confirmButtonText: 'Yes', + imageUrl: "http://infy-tracker/images/warning.png" + }, + function (inputVal) { + if (inputVal===false) { + return false; + } + if (inputVal=='' || inputVal.toLowerCase() != "delete") { + swal.showInputError("Please type \"delete\" to delete this client."); + $(".sa-input-error").css('top','23px!important'); + return false; + } + if(inputVal.toLowerCase() === "delete"){ + deleteItemAjax(url, tableId, header, callFunction = null); + } }); }; diff --git a/resources/assets/js/projects/project.js b/resources/assets/js/projects/project.js index fc5e19cdf..3155ddc92 100644 --- a/resources/assets/js/projects/project.js +++ b/resources/assets/js/projects/project.js @@ -3,9 +3,7 @@ $('#client_id,#edit_client_id').select2({ placeholder: "Select Client" }); -$('#filterClient').select2({ - minimumResultsForSearch: -1 -}); +$('#filterClient').select2(); let tbl = $('#projects_table').DataTable({ processing: true, @@ -41,6 +39,7 @@ let tbl = $('#projects_table').DataTable({ }, { data: 'client.name', + defaultContent: '', name: 'client.name' }, { @@ -152,10 +151,13 @@ $(document).on('click', '.edit-btn', function (event) { $(document).on('click', '.delete-btn', function (event) { let projectId = $(event.currentTarget).data('id'); - deleteItem(projectUrl + projectId, '#projects_table', 'Project'); + let alertMessage = '
\n' + + 'Are you sure want to delete this project?
By deleting this project all its task and time entries will be deleted.
'; + + deleteItemInputConfirmation(projectUrl + projectId, '#projects_table', 'Project', alertMessage); setTimeout(function () { revokerTracker(); - }, 1000) + }, 1000); }); $('#user_ids,#edit_user_ids').select2({ diff --git a/resources/assets/js/task/task.js b/resources/assets/js/task/task.js index 187bb9a1f..79bfafb4c 100644 --- a/resources/assets/js/task/task.js +++ b/resources/assets/js/task/task.js @@ -1,9 +1,9 @@ $(function () { $('#no-record-info-msg').hide(); $('#user-drop-down-body').hide(); - $('#task_users').select2({ width: '100%', placeholder: "All", minimumResultsForSearch: -1 }); - $('#filter_project,#filter_status,#filter_user').select2({ + $('#filter_project,#filter_user').select2(); + $('#filter_status').select2({ minimumResultsForSearch: -1 }); $('#assignTo,#editAssignTo').select2({ @@ -271,132 +271,11 @@ $(document).on('click', '.delete-btn', function (event) { deleteItem(taskUrl + id, '#task_table', 'Task'); }); -// open detail confirmation model -$(document).on('click', '.taskDetails', function (event) { - let id = $(event.currentTarget).data('id'); - startLoader(); - $('#no-record-info-msg').hide(); - $('#taskDetailsTable').hide(); - $('.time-entry-data').hide(); - - $.ajax({ - url: taskUrl + id + '/' + 'users', - type: 'GET', - success: function (result) { - $('#task_users').empty(''); - $('#task_users').attr('data-task_id', id); - const newOption = new Option('All', 0, false, false); - $('#task_users').append(newOption).trigger('change'); - $.each(result, function (key, value) { - const newOption = new Option(value, key + '-' + id, false, false); - $('#task_users').append(newOption); - }); - } - }); - - $.ajax({ - url: taskDetailUrl + '/' + id, - type: 'GET', - success: function (result) { - if (result.success) { - let data = result.data; - drawTaskDetailTable(data); - } - } - }); -}); - -function formatCollapsableRow(data) { - return '
' + data.note + '
'; -} -$(document).on('change', '#task_users', function () { - let taskId = $(this).attr('data-task_id'); - let taskUserId = $(this).val().split('-'); - let userId = 0; - if (taskUserId.length > 1) { - taskId = taskUserId[1]; - userId = taskUserId[0]; - } - let url = taskDetailUrl + '/' + taskId; - if (userId !== 0) { - url = url + '?user_id=' + userId; - } - $.ajax({ - url: url, - type: 'GET', - success: function (result) { - if (result.success) { - let data = result.data; - drawTaskDetailTable(data); - } - } - }); -}); -window.drawTaskDetailTable = function (data) { - if (data.totalDuration === 0) { - $('#no-record-info-msg').show(); - $('.time-entry-data').hide(); - stopLoader(); - return true; - } - - let taskDetailsTable = $('#taskDetailsTable').DataTable({ - destroy: true, - paging: true, - data: data.time_entries, - searching: false, - lengthChange: false, - columns: [ - { - className: 'details-control', - defaultContent: "", - data: null, - orderable: false, - }, - {data: "user.name"}, - {data: "start_time"}, - {data: "end_time"}, - {data: "duration"}, - { - orderable: false, - data: function (data) { - return "" + - ""; - } - } - ], - }); - - $('.time-entry-data').show(); - $('#taskDetailsTable').show(); - $('#user-drop-down-body').show(); - $('#no-record-info-msg').hide(); - stopLoader(); - - $('#taskDetailsTable tbody').off('click', 'tr td.details-control'); - $('#taskDetailsTable tbody').on('click', 'tr td.details-control', function () { - var tr = $(this).closest('tr'); - var row = taskDetailsTable.row(tr); - - if (row.child.isShown()) { - // This row is already open - close it - row.child.hide(); - tr.removeClass('shown'); - } else { - // Open this row - row.child('
' + row.data().note + '
').show(); - tr.addClass('shown'); - } - }); - - $("#taskDetailsTable_wrapper").css('width', "100%"); - $("#total-duration").html("Total duration: " + data.totalDuration + " || " + data.totalDurationMin + " Minutes"); -}; $('#addNewForm').submit(function (event) { event.preventDefault(); - let loadingButton = jQuery(this).find("#btnSave"); + let loadingButton = jQuery(this).find("#btnTaskSave"); loadingButton.button('loading'); let formdata = $(this).serialize(); @@ -425,7 +304,7 @@ $('#addNewForm').submit(function (event) { $('#editForm').submit(function (event) { event.preventDefault(); - let loadingButton = jQuery(this).find("#btnEditSave"); + let loadingButton = jQuery(this).find("#btnTaskEditSave"); loadingButton.button('loading'); let id = $('#tagId').val(); let formdata = $(this).serializeArray(); diff --git a/resources/assets/js/task/task_detail.js b/resources/assets/js/task/task_detail.js index 23df41144..967912d91 100644 --- a/resources/assets/js/task/task_detail.js +++ b/resources/assets/js/task/task_detail.js @@ -90,16 +90,49 @@ $(document).on('click', '.edit-btn', function (event) { $("#editAssignee").val(userIds).trigger('change'); $("#editPriority").val(task.priority).trigger('change'); - loadingButton.button('reset'); - $('#EditModal').modal('show'); + + setTimeout(function () { + $.each(task.task_assignee, function (i, e) { + $("#editAssignee option[value='" + e.id + "']").prop("selected", true).trigger('change'); + }); + loadingButton.button('reset'); + $('#EditModal').modal('show'); + + }, 1500); } + }, + error: function () { + loadingButton.button('reset'); } }); }); +$(document).on('change', '#editProjectId', function (event) { + let projectId = $(this).val(); + loadProjectAssignees(projectId, 'editAssignee') +}); + +function loadProjectAssignees(projectId, selector) { + let url = usersOfProjects + '?projectIds='+projectId; + $('#'+selector).empty(); + $('#'+selector).trigger("change"); + $.ajax({ + url: url, + type: 'GET', + success: function (result) { + const users = result.data; + for (const key in users) { + if (users.hasOwnProperty(key)) { + $('#' + selector).append($('