diff --git a/app/Http/Controllers/ScheduleController.php b/app/Http/Controllers/ScheduleController.php
index 953e9f7865ffe3be6cd62623f0fa2ab57794f733..b2ca9d7c0434ac4ab0f8412f5523bb6f5cbaed0f 100644
--- a/app/Http/Controllers/ScheduleController.php
+++ b/app/Http/Controllers/ScheduleController.php
@@ -3,20 +3,51 @@
 namespace App\Http\Controllers;
 
 use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Auth;
 use App\Schedule;
 use App\Http\Requests;
 
 class ScheduleController extends Controller
 {
+    protected $user_roles = [];
+
     public function __construct()
     {
         $this->middleware('auth');
-        $this->middleware('scheduler');        
+        $this->middleware('sched', ['only' => [
+            'index',
+            'show',
+        ]]);
+        $this->middleware('sched.edit', ['except' => [
+            'index',
+            'show',
+        ]]);
+        $this->user_roles = Auth::user()->roles()->get()->toArray();
+    }
+
+    public function has_role($role_name)
+    {
+        foreach ($this->user_roles as $role) 
+        {
+            if ($role['name'] == $role_name)
+            {
+                return true;
+            }
+        }
+
+        return false;
     }
     
     public function index()
     {
-        return Schedule::all();
+        if ($this->has_role('all_schedule'))
+        {
+            return Schedule::all();
+        } 
+        else 
+        {
+            return Schedule::where('id_user', Auth::user()->id)->get();
+        }
     }
 
     public function store()
diff --git a/app/Http/Controllers/TpsController.php b/app/Http/Controllers/TpsController.php
index afe211cb181277300f360f2deda8fdb195273eef..79cafb915c450df1de63d3bae71c7f2b966385e9 100644
--- a/app/Http/Controllers/TpsController.php
+++ b/app/Http/Controllers/TpsController.php
@@ -3,15 +3,41 @@
 namespace App\Http\Controllers;
 
 use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Auth;
 use App\Tps;
 use App\Http\Requests;
 
 class TpsController extends Controller
 {
+    protected $user_roles = [];
+
     public function __construct()
     {
         $this->middleware('auth');
-        $this->middleware('manager');
+        $this->middleware('tps', ['except' => [
+            'index',
+            'store',
+            'create',
+        ]]);
+        $this->middleware('tps.admin', ['only' => [
+            'index',
+            'store',
+            'create',
+        ]]);
+        $this->user_roles = Auth::user()->roles()->get()->toArray();
+    }
+
+    public function has_role($role_name)
+    {
+        foreach ($this->user_roles as $role) 
+        {
+            if ($role['name'] == $role_name)
+            {
+                return true;
+            }
+        }
+
+        return false;
     }
     
     public function index()
diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php
index b7097e8e76e8b3d9a37e945e4dec941a9b887222..6d39631fa3c560521489c87cf19ad68640af5c24 100644
--- a/app/Http/Controllers/UserController.php
+++ b/app/Http/Controllers/UserController.php
@@ -3,15 +3,41 @@
 namespace App\Http\Controllers;
 
 use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Auth;
 use App\User;
 use App\Http\Requests;
 
 class UserController extends Controller
 {
+    protected $user_roles = [];
+
     public function __construct()
     {
         $this->middleware('auth');
-        $this->middleware('user');
+        $this->middleware('user', ['except' => [
+            'index',
+            'store',
+            'create',
+        ]]);
+        $this->middleware('user.admin', ['only' => [
+            'index',
+            'store',
+            'create',
+        ]]);
+        $this->user_roles = Auth::user()->roles()->get()->toArray();
+    }
+
+    public function has_role($role_name)
+    {
+        foreach ($this->user_roles as $role) 
+        {
+            if ($role['name'] == $role_name)
+            {
+                return true;
+            }
+        }
+
+        return false;
     }
     
     public function index()
diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php
index 1a7967180260757238b72837318357808d0256de..dc48d9011c308646492125bb6c67a9fb24c75344 100644
--- a/app/Http/Kernel.php
+++ b/app/Http/Kernel.php
@@ -48,8 +48,11 @@ class Kernel extends HttpKernel
         'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
         'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
         'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
-        'user' => \App\Http\Middleware\AuthorizedUser::class,
-        'manager' => \App\Http\Middleware\AuthorizedManager::class,
-        'scheduler' => \App\Http\Middleware\AuthorizedScheduler::class,
+        'user' => \App\Http\Middleware\CurrentUser::class,
+        'user.admin' => \App\Http\Middleware\AllUser::class,
+        'tps' => \App\Http\Middleware\CurrentTps::class,
+        'tps.admin' => \App\Http\Middleware\AllTps::class,
+        'sched' => \App\Http\Middleware\ReadSched::class,
+        'sched.edit' => \App\Http\Middleware\EditSched::class,
     ];
 }
diff --git a/app/Http/Middleware/AllTps.php b/app/Http/Middleware/AllTps.php
new file mode 100644
index 0000000000000000000000000000000000000000..260aa56a20867343055261a3c80fdf616b56da7f
--- /dev/null
+++ b/app/Http/Middleware/AllTps.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Closure;
+use Illuminate\Support\Facades\Auth;
+
+class AllTps
+{
+    /**
+     * Handle an incoming request.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \Closure  $next
+     * @return mixed
+     */
+    public function handle($request, Closure $next)
+    {
+        $user = Auth::user();
+        $param = $request->route()->parameters();
+        $isAdmin = false;
+
+        /* Find admin role */
+        foreach ($user->roles as $role) 
+        {
+            if ($role->name == 'all_tps')
+            {
+                $isAdmin = true;
+                break;
+            }
+        }
+
+        /* Bypassing admin */
+        if ($isAdmin) 
+        {
+            return $next($request);
+        }
+
+        return response('Unauthorized', 403);
+    }
+}
diff --git a/app/Http/Middleware/AllUser.php b/app/Http/Middleware/AllUser.php
new file mode 100644
index 0000000000000000000000000000000000000000..e29e6b4ba21578843047bf2d08aea9e9486089fd
--- /dev/null
+++ b/app/Http/Middleware/AllUser.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Closure;
+use Illuminate\Support\Facades\Auth;
+
+class AllUser
+{
+    /**
+     * Handle an incoming request.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \Closure  $next
+     * @return mixed
+     */
+    public function handle($request, Closure $next)
+    {
+        $user = Auth::user();
+        $param = $request->route()->parameters();
+        $isAdmin = false;
+
+        /* Find admin role */
+        foreach ($user->roles as $role) 
+        {
+            if ($role->name == 'all_user')
+            {
+                $isAdmin = true;
+                break;
+            }
+        }
+
+        /* Bypassing admin */
+        if ($isAdmin) 
+        {
+            return $next($request);
+        }
+
+        return response('Unauthorized', 403);
+    }
+}
diff --git a/app/Http/Middleware/AuthorizedManager.php b/app/Http/Middleware/AuthorizedManager.php
deleted file mode 100644
index e4f943e0b28f38e099b7ff539507b8715ec36de3..0000000000000000000000000000000000000000
--- a/app/Http/Middleware/AuthorizedManager.php
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-
-namespace App\Http\Middleware;
-
-use Closure;
-use Illuminate\Support\Facades\Auth;
-use App\Tps;
-
-class AuthorizedManager
-{
-    /**
-     * Handle an incoming request.
-     *
-     * @param  \Illuminate\Http\Request  $request
-     * @param  \Closure  $next
-     * @return mixed
-     */
-    public function handle($request, Closure $next)
-    {
-        $user = Auth::user();
-        $role = $user->role();
-        $param = $request->route()->parameters();
-        $tps_id = !$param ? null : $param['tps'];
-        $tps = Tps::find($tps_id);
-        $mgr_id = !$tps ? null : $tps->id_manager;
-
-        if (!$tps_id) 
-        {
-            if ($role == 'admin')
-            {
-                return $next($request);
-            }
-            else
-            {
-                return redirect('/')->with('error', 'Not authorized');
-            }
-        }
-        else if ($mgr_id && $user->id == $mgr_id)
-        {
-            return $next($request);
-        }
-
-        return redirect('/')->with('error', 'Not authorized');
-    }
-}
diff --git a/app/Http/Middleware/AuthorizedScheduler.php b/app/Http/Middleware/AuthorizedScheduler.php
deleted file mode 100644
index 42d4a6ec4015a8815651ed5178d375f1b66e1597..0000000000000000000000000000000000000000
--- a/app/Http/Middleware/AuthorizedScheduler.php
+++ /dev/null
@@ -1,44 +0,0 @@
-<?php
-
-namespace App\Http\Middleware;
-
-use Closure;
-use Illuminate\Support\Facades\Auth;
-
-class AuthorizedScheduler
-{
-    /**
-     * Handle an incoming request.
-     *
-     * @param  \Illuminate\Http\Request  $request
-     * @param  \Closure  $next
-     * @return mixed
-     */
-    public function handle($request, Closure $next)
-    {
-        $user = Auth::user();
-        $role = $user->role();
-        $param = $request->route()->parameters();
-        $tps_id = $request->input('id_tps');
-        $tps = !$tps_id ? null : Tps::find($tps_id);
-        $mgr_id = !$tps ? null : $tps->id_manager;
-
-        if (!$tps_id)
-        {
-            if ($role == 'admin')
-            {
-                return $next($request);
-            }
-            else
-            {
-                return redirect('/')->with('error', 'Not authorized');
-            }
-        }
-        else if ($mgr_id && $user->id == $mgr_id)
-        {
-            return $next($request);
-        }
-
-        return redirect('/')->with('error', 'Not authorized');
-    }
-}
diff --git a/app/Http/Middleware/AuthorizedUser.php b/app/Http/Middleware/AuthorizedUser.php
deleted file mode 100644
index b19481a98df3f0266ce87f722feb3db4669d0fe3..0000000000000000000000000000000000000000
--- a/app/Http/Middleware/AuthorizedUser.php
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-
-namespace App\Http\Middleware;
-
-use Closure;
-use Illuminate\Support\Facades\Auth;
-
-class AuthorizedUser
-{
-    /**
-     * Handle an incoming request.
-     *
-     * @param  \Illuminate\Http\Request  $request
-     * @param  \Closure  $next
-     * @return mixed
-     */
-    public function handle($request, Closure $next)
-    {
-        $user = Auth::user();
-        $role = $user->role();
-        $id = !$request->route()->parameters() ? null : 
-                $request->route()->parameters()['user'];
-
-        if (!$id) 
-        {
-            if ($role == 'admin')
-            {
-                return $next($request);
-            }
-            else
-            {
-                return redirect('/')->with('error', 'Not authorized');
-            }
-        }
-        else if ($user->id == $id)
-        {
-            return $next($request);
-        }
-
-        return redirect('/')->with('error', 'Not authorized');
-    }
-}
diff --git a/app/Http/Middleware/CurrentTps.php b/app/Http/Middleware/CurrentTps.php
new file mode 100644
index 0000000000000000000000000000000000000000..968d970bd124da069161e5b39b19624dd50b62ff
--- /dev/null
+++ b/app/Http/Middleware/CurrentTps.php
@@ -0,0 +1,52 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Closure;
+use Illuminate\Support\Facades\Auth;
+use App\Tps;
+
+class CurrentTps
+{
+    /**
+     * Handle an incoming request.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \Closure  $next
+     * @return mixed
+     */
+    public function handle($request, Closure $next)
+    {
+        $user = Auth::user();
+        $param = $request->route()->parameters();
+        $isAdmin = false;
+        $isAuthorizedUser = false;
+
+        /* Find user roles */
+        foreach ($user->roles as $role) 
+        {
+            if ($isAdmin && $isAuthorizedUser) break;
+
+            $isAdmin = $isAdmin || ($role->name == 'all_tps');
+            $isAuthorizedUser = $isAuthorizedUser || ($role->name == 'current_tps');
+        }
+
+        /* Bypassing admin */
+        if ($isAdmin) 
+        {
+            return $next($request);
+        }
+
+        $tps = Tps::find($param['tps']);
+        $id_mgr = ($tps ? $tps->id_manager : null);
+        $isAuthorizedUser &= ($id_mgr && $id_mgr == $user->id);
+        
+        /* User id match */
+        if ($isAuthorizedUser)        
+        {
+            return $next($request);
+        }
+
+        return response('Unauthorized', 403);
+    }
+}
diff --git a/app/Http/Middleware/CurrentUser.php b/app/Http/Middleware/CurrentUser.php
new file mode 100644
index 0000000000000000000000000000000000000000..8675bc354555f804656618be78e2195b612fdb91
--- /dev/null
+++ b/app/Http/Middleware/CurrentUser.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Closure;
+use Illuminate\Support\Facades\Auth;
+
+class CurrentUser
+{
+    /**
+     * Handle an incoming request.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \Closure  $next
+     * @return mixed
+     */
+    public function handle($request, Closure $next)
+    {
+        $user = Auth::user();
+        $param = $request->route()->parameters();
+        $isAdmin = false;
+        $isAuthorizedUser = false;
+
+        /* Find user roles */
+        foreach ($user->roles as $role) 
+        {
+            if ($isAdmin && $isAuthorizedUser) break;
+
+            $isAdmin = $isAdmin || ($role->name == 'all_user');
+            $isAuthorizedUser = $isAuthorizedUser || ($role->name == 'current_user');
+        }
+
+        /* Bypassing admin */
+        if ($isAdmin) 
+        {
+            return $next($request);
+        }
+
+        $isAuthorizedUser &= ($param && $param['user'] == $user->id);
+        
+        /* User id match */
+        if ($isAuthorizedUser)        
+        {
+            return $next($request);
+        }
+
+        return response('Unauthorized', 403);
+    }
+}
diff --git a/app/Http/Middleware/EditSched.php b/app/Http/Middleware/EditSched.php
new file mode 100644
index 0000000000000000000000000000000000000000..bb988791d6b3824ffee81c368813a42cbfb8e9b9
--- /dev/null
+++ b/app/Http/Middleware/EditSched.php
@@ -0,0 +1,52 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Closure;
+use Illuminate\Support\Facades\Auth;
+
+class EditSched
+{
+    /**
+     * Handle an incoming request.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \Closure  $next
+     * @return mixed
+     */
+    public function handle($request, Closure $next)
+    {
+        $user = Auth::user();
+        $param = $request->route()->parameters();
+        $isAdmin = false;
+        $isAuthorizedUser = false;
+
+        /* Find user roles */
+        foreach ($user->roles as $role) 
+        {
+            if ($isAdmin && $isAuthorizedUser) break;
+
+            $isAdmin = $isAdmin || ($role->name == 'all_schedule');
+            $isAuthorizedUser = $isAuthorizedUser || ($role->name == 'edit_schedule');
+        }
+
+        /* Bypassing admin */
+        if ($isAdmin) 
+        {
+            return $next($request);
+        }
+
+        // schedule null means create new schedule which requires only admin
+        $schedule = $param ? Schedule::find($param->has('schedule')) : null;             
+        $id_user = ($schedule ? $schedule->id_user : null);
+        $isAuthorizedUser = $isAuthorizedUser && ($id_user && $id_user == $user->id);   
+        
+        /* User id match */
+        if ($isAuthorizedUser)        
+        {
+            return $next($request);
+        }
+
+        return response('Unauthorized', 403);
+    }
+}
diff --git a/app/Http/Middleware/ReadSched.php b/app/Http/Middleware/ReadSched.php
new file mode 100644
index 0000000000000000000000000000000000000000..04ccbed022073381a983e273fc6ad9ab9d9ed075
--- /dev/null
+++ b/app/Http/Middleware/ReadSched.php
@@ -0,0 +1,53 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Closure;
+use Illuminate\Support\Facades\Auth;
+use App\Schedule;
+
+class ReadSched
+{
+    /**
+     * Handle an incoming request.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \Closure  $next
+     * @return mixed
+     */
+    public function handle($request, Closure $next)
+    {
+        $user = Auth::user();
+        $param = $request->route()->parameters();
+        $isAdmin = false;
+        $isAuthorizedUser = false;
+
+        /* Find user roles */
+        foreach ($user->roles as $role) 
+        {
+            if ($isAdmin && $isAuthorizedUser) break;
+
+            $isAdmin = $isAdmin || ($role->name == 'all_schedule');
+            $isAuthorizedUser = $isAuthorizedUser || ($role->name == 'read_schedule');
+        }
+
+        /* Bypassing admin */
+        if ($isAdmin) 
+        {
+            return $next($request);
+        }
+
+        // schedule null means get all schedule of current user
+        $schedule = $param ? Schedule::find($param->has('schedule')) : null;
+        $id_user = ($schedule ? $schedule->id_user : null);     
+        $isAuthorizedUser = $isAuthorizedUser && (!$id_user || $id_user == $user->id);      
+        
+        /* Param null or user id match */
+        if ($isAuthorizedUser)        
+        {
+            return $next($request);
+        }
+
+        return response('Unauthorized', 403);
+    }
+}
diff --git a/app/Role.php b/app/Role.php
index 666c5a0c075a6f29e486a57316a5eb002321d18d..bb9c9323fafe1fb813e3d0c87585ba27e46e9a96 100644
--- a/app/Role.php
+++ b/app/Role.php
@@ -8,6 +8,6 @@ class Role extends Model
 {
     public function users()
     {
-        return $this->hasMany('App\User', 'role_id');
+        return $this->belongsToMany('App\User');
     }
 }
diff --git a/app/Schedule.php b/app/Schedule.php
index 434ea30b635bef4039e03ff9651d249fbb0fb927..37f2fa6807ebb6708c4278b440f68269461ff011 100644
--- a/app/Schedule.php
+++ b/app/Schedule.php
@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
 
 class Schedule extends Model
 {
-    public function users()
+    public function user()
     {
         return $this->belongsTo('App\User');
     }
diff --git a/app/User.php b/app/User.php
index 6f4666a775923a2c5fa1a5c7717f72efa7ef3e99..c129335df5ee75e0df052ff6bf78e0d34491fd35 100644
--- a/app/User.php
+++ b/app/User.php
@@ -24,10 +24,9 @@ class User extends Authenticatable
         'password', 'remember_token',
     ];
 
-    public function role()
+    public function roles()
     {
-        // $this->belongsTo('App\Role');
-        return Role::find($this->role_id)->name;
+        return $this->belongsToMany('App\Role', 'users_roles', 'id_user', 'id_role');
     }
 
     public function schedule()
diff --git a/database/migrations/2016_03_31_095953_create_users_table.php b/database/migrations/2016_03_31_095953_create_users_table.php
index b31ed011ad62cc787ebbcc58afa52b106d997f33..fa960d652ed6344f8713bf697b1bf98ce44a273f 100644
--- a/database/migrations/2016_03_31_095953_create_users_table.php
+++ b/database/migrations/2016_03_31_095953_create_users_table.php
@@ -18,7 +18,6 @@ class CreateUsersTable extends Migration
             $table->string('name');
             $table->string('email')->unique();
             $table->string('password');
-            $table->integer('role_id')->unsigned();
             $table->rememberToken();
             $table->timestamps();
         }); 
diff --git a/database/migrations/2016_04_02_171120_create_tps_table.php b/database/migrations/2016_04_02_171120_create_tps_table.php
index f36ce53787b9f4af52d1e048223c8d6ea7f89f82..e117aff010dc2a6033261af2a7390d3d6076d856 100644
--- a/database/migrations/2016_04_02_171120_create_tps_table.php
+++ b/database/migrations/2016_04_02_171120_create_tps_table.php
@@ -15,11 +15,20 @@ class CreateTpsTable extends Migration
         Schema::create('tps', function(Blueprint $table)
         {
             $table->increments('id');
+            $table->string('nama');
             $table->integer('capacity_now');
             $table->integer('capacity_full');
             $table->integer('id_manager')->unsigned();
+            $table->boolean('is_full');
             $table->timestamps();
         }); 
+
+        Schema::table('tps', function($table)
+        {
+            $table->foreign('id_manager')
+                ->references('id')
+                ->on('users');
+        });
     }
 
     /**
diff --git a/database/migrations/2016_04_02_172129_create_schedules_table.php b/database/migrations/2016_04_04_055311_create_schedules_table.php
similarity index 68%
rename from database/migrations/2016_04_02_172129_create_schedules_table.php
rename to database/migrations/2016_04_04_055311_create_schedules_table.php
index 2164f9aad863ccacde15bf6ce3a096964ba7d96f..eccf548935dde7c5ff428d133226c2ac03aa3683 100644
--- a/database/migrations/2016_04_02_172129_create_schedules_table.php
+++ b/database/migrations/2016_04_04_055311_create_schedules_table.php
@@ -17,9 +17,20 @@ class CreateSchedulesTable extends Migration
             $table->increments('id');
             $table->integer('id_tps')->unsigned();
             $table->integer('id_user')->unsigned();
+            $table->boolean('is_done');
             $table->timestamp('time');
             $table->timestamps();
         }); 
+
+        Schema::table('schedules', function($table)
+        {
+            $table->foreign('id_tps')
+                ->references('id')
+                ->on('tps');
+            $table->foreign('id_user')
+                ->references('id')
+                ->on('users');
+        });
     }
 
     /**
diff --git a/database/migrations/2016_04_04_063623_create_users_roles_table.php b/database/migrations/2016_04_04_063623_create_users_roles_table.php
new file mode 100644
index 0000000000000000000000000000000000000000..bde414b8c4cde90ff7ed80ad335a7dbd74e37488
--- /dev/null
+++ b/database/migrations/2016_04_04_063623_create_users_roles_table.php
@@ -0,0 +1,43 @@
+<?php
+
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Migrations\Migration;
+
+class CreateUsersRolesTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('users_roles', function(Blueprint $table)
+        {
+            $table->increments('id');
+            $table->integer('id_user')->unsigned();
+            $table->integer('id_role')->unsigned();
+            $table->timestamps();
+        });
+
+        Schema::table('users_roles', function($table)
+        {
+            $table->foreign('id_role')
+                ->references('id')
+                ->on('roles');
+            $table->foreign('id_user')
+                ->references('id')
+                ->on('users');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::drop('users_roles');
+    }
+}