From 3b042182e8df58beaba9b2662743f1770e4f0117 Mon Sep 17 00:00:00 2001 From: jorplaz <429-jorplaz@users.noreply.gitlab.inf.uva.es> Date: Sat, 2 Jul 2022 12:52:04 +0200 Subject: [PATCH] Updated models and seeders --- app/Http/Controllers/AuthController.php | 12 +++- app/Models/Bike.php | 12 ++++ app/Models/ElectricBike.php | 4 ++ app/Models/Reward.php | 7 +++ app/Models/Route.php | 7 +++ app/Models/Stop.php | 30 +++++++++ app/Models/User.php | 7 +++ app/Providers/AppServiceProvider.php | 5 +- composer.json | 3 +- composer.lock | 63 ++++++++++++++++++- .../2022_06_13_151027_create_bikes_table.php | 3 + ..._13_153838_create_electric_bikes_table.php | 3 +- .../2022_06_14_151011_create_routes_table.php | 2 + ...2022_06_15_144408_create_rewards_table.php | 1 + database/seeders/BikeSeeder.php | 19 ++++-- database/seeders/RewardSeeder.php | 15 +++-- database/seeders/UserSeeder.php | 3 +- routes/api.php | 30 ++++++++- 18 files changed, 203 insertions(+), 23 deletions(-) diff --git a/app/Http/Controllers/AuthController.php b/app/Http/Controllers/AuthController.php index 87a0349..1c4a337 100644 --- a/app/Http/Controllers/AuthController.php +++ b/app/Http/Controllers/AuthController.php @@ -2,8 +2,11 @@ namespace App\Http\Controllers; +use App\Models\User; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Validator; +use Laravel\Sanctum\PersonalAccessToken; class AuthController extends Controller { @@ -24,9 +27,12 @@ class AuthController extends Controller ]); } - public function logout() + public function logout(Request $request) { - auth()->user()->tokens()->delete(); - return response()->json(['Token revoked']); + $user = UserController::getUserByToken($request); + if(1 != $user->tokens()->delete()){ + return "false"; + } + return "true"; } } \ No newline at end of file diff --git a/app/Models/Bike.php b/app/Models/Bike.php index 05c406f..75a3e69 100644 --- a/app/Models/Bike.php +++ b/app/Models/Bike.php @@ -6,17 +6,25 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; +use Nanigans\SingleTableInheritance\SingleTableInheritanceTrait; /** * @method static create(array $array) + * @method static find(int $int) + * @property mixed $id + * @property mixed $bikeable_type + * @property mixed|null $stop_id */ class Bike extends Model { use HasFactory; + protected $table = "bikes"; + protected $fillable = [ 'stop_id', 'unlocked', + 'type' ]; public function stop(): BelongsTo{ @@ -26,4 +34,8 @@ class Bike extends Model public function routes(): HasMany{ return $this->hasMany(Route::class); } + + public function bikeable(){ + return $this->morphTo(); + } } diff --git a/app/Models/ElectricBike.php b/app/Models/ElectricBike.php index 8991516..de5833e 100644 --- a/app/Models/ElectricBike.php +++ b/app/Models/ElectricBike.php @@ -14,4 +14,8 @@ class ElectricBike extends Bike 'id', 'battery', ]; + + public function bike(){ + return $this->morphOne(Bike::class, 'bikeable'); + } } diff --git a/app/Models/Reward.php b/app/Models/Reward.php index 3b40b19..e108eb0 100644 --- a/app/Models/Reward.php +++ b/app/Models/Reward.php @@ -8,6 +8,9 @@ use Illuminate\Database\Eloquent\Relations\BelongsToMany; /** * @method static create(array $array) + * @property mixed $redeemed + * @property mixed $total_available + * @property mixed $points */ class Reward extends Model { @@ -18,6 +21,10 @@ class Reward extends Model 'description', 'user_id', 'reward_id', + 'points', + 'total_available', + 'image', + 'redeemed', ]; public function users(): BelongsToMany{ diff --git a/app/Models/Route.php b/app/Models/Route.php index 987300d..d33714c 100644 --- a/app/Models/Route.php +++ b/app/Models/Route.php @@ -6,6 +6,12 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; +/** + * @property mixed $user_id + * @property \Illuminate\Database\Eloquent\HigherOrderBuilderProxy|mixed $initial_stop_id + * @property mixed $bike_id + * @method static find(mixed $id) + */ class Route extends Model { use HasFactory; @@ -17,6 +23,7 @@ class Route extends Model "bike_id", "distance", "duration", + "estimated_duration", "points", ]; diff --git a/app/Models/Stop.php b/app/Models/Stop.php index 2a25676..0b74cb9 100644 --- a/app/Models/Stop.php +++ b/app/Models/Stop.php @@ -5,9 +5,16 @@ namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; +use phpDocumentor\Reflection\Types\Boolean; +use PhpParser\Node\Expr\Cast\Int_; /** * @method static create(array $array) + * @method static find($initial_stop_id) + * @property mixed $lng + * @property mixed $lat + * @property mixed $total_spaces + * @property mixed $id */ class Stop extends Model { @@ -34,4 +41,27 @@ class Stop extends Model public function routesEnd(): HasMany{ return $this->hasMany(Route::class, "final_stop_id"); } + + public function reservations(): HasMany{ + return $this->hasMany(Reservation::class); + } + + public function reserved_pedal_bikes(): int{ + return $this->reservations()->where('bike_type', '=', 'pedal')->count(); + } + public function reserved_electric_bikes(): int{ + return $this->reservations()->where('bike_type', '=', 'electric')->count(); + } + + public function check_availability_bikes(String $type): bool{ + $available = false; + if ($type=="pedal" || $type=="App\Models\Bike"){ + $bikeCount = $this->bikes()->where('bikeable_type', '=', 'App\Models\Bike')->count(); + $available = $bikeCount > $this->reserved_pedal_bikes(); + }else if ($type=="electric" || $type=="App\Models\ElectricBike"){ + $bikeCount = $this->bikes()->where('bikeable_type', '=', 'App\Models\ElectricBike')->count(); + $available = $bikeCount > $this->reserved_electric_bikes(); + } + return $available; + } } diff --git a/app/Models/User.php b/app/Models/User.php index b9cb8ba..4bb40e9 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -13,6 +13,9 @@ use Laravel\Sanctum\HasApiTokens; /** * @method static create(string[] $array) * @method static find(int $id) + * @method static where(string $string, mixed $email) + * @property mixed $points + * @property mixed $id */ class User extends Authenticatable { @@ -55,4 +58,8 @@ class User extends Authenticatable public function rewards(): BelongsToMany{ return $this->belongsToMany(Reward::class, 'user_reward')->withTimestamps(); } + + public function reservations(): HasMany{ + return $this->hasMany(Reservation::class); + } } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 88da5b6..c29e182 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -22,8 +22,11 @@ class AppServiceProvider extends ServiceProvider * * @return void */ - public function boot() + public function boot(\Illuminate\Http\Request $request) { + if (!empty( env('NGROK_URL') ) && $request->server->has('HTTP_X_ORIGINAL_HOST')) { + $this->app['url']->forceRootUrl(env('NGROK_URL')); + } JsonResource::withoutWrapping(); } } diff --git a/composer.json b/composer.json index 0ab4cf7..e112bb1 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,8 @@ "guzzlehttp/guzzle": "^7.2", "laravel/framework": "^9.11", "laravel/sanctum": "^2.15", - "laravel/tinker": "^2.7" + "laravel/tinker": "^2.7", + "nanigans/single-table-inheritance": "~1.0" }, "require-dev": { "fakerphp/faker": "^1.9.1", diff --git a/composer.lock b/composer.lock index 292c550..9ba8178 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "58fa573d0eb02b0bca9c8679dea764c0", + "content-hash": "a6074d6cbd7b2a35b7d18370d948483f", "packages": [ { "name": "brick/math", @@ -1702,6 +1702,67 @@ ], "time": "2022-05-10T09:36:00+00:00" }, + { + "name": "nanigans/single-table-inheritance", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/jonspalmer/single-table-inheritance.git", + "reference": "5fd1dd86ddc5ab66bf9d1260b8de1e58ac5826ff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jonspalmer/single-table-inheritance/zipball/5fd1dd86ddc5ab66bf9d1260b8de1e58ac5826ff", + "reference": "5fd1dd86ddc5ab66bf9d1260b8de1e58ac5826ff", + "shasum": "" + }, + "require": { + "illuminate/database": ">= 5.2", + "illuminate/support": ">= 5.2", + "php": ">= 7.2" + }, + "require-dev": { + "mockery/mockery": "~1.0", + "orchestra/database": "3.8.*|4.*|5.*|6.*", + "orchestra/testbench": "3.8.*|4.*|5.*|6.*", + "phpunit/phpunit": "~8.0|~9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Nanigans\\SingleTableInheritance\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jon Palmer", + "email": "328224+jonspalmer@users.noreply.github.com" + } + ], + "description": "Single Table Inheritance Trait", + "keywords": [ + "eloquent", + "inheritance", + "laravel", + "model", + "single", + "table" + ], + "support": { + "issues": "https://github.com/jonspalmer/single-table-inheritance/issues", + "source": "https://github.com/jonspalmer/single-table-inheritance/tree/v1.0.0" + }, + "time": "2021-04-17T13:10:00+00:00" + }, { "name": "nesbot/carbon", "version": "2.58.0", diff --git a/database/migrations/2022_06_13_151027_create_bikes_table.php b/database/migrations/2022_06_13_151027_create_bikes_table.php index 705aadf..6e16720 100644 --- a/database/migrations/2022_06_13_151027_create_bikes_table.php +++ b/database/migrations/2022_06_13_151027_create_bikes_table.php @@ -16,10 +16,13 @@ return new class extends Migration Schema::create('bikes', function (Blueprint $table) { $table->id(); $table->foreignId('stop_id') + ->nullable() ->index() ->constrained() ->cascadeOnUpdate(); $table->boolean('unlocked'); + $table->unsignedBigInteger('bikeable_id'); + $table->string('bikeable_type'); $table->timestamps(); }); } diff --git a/database/migrations/2022_06_13_153838_create_electric_bikes_table.php b/database/migrations/2022_06_13_153838_create_electric_bikes_table.php index db6b5b7..0946573 100644 --- a/database/migrations/2022_06_13_153838_create_electric_bikes_table.php +++ b/database/migrations/2022_06_13_153838_create_electric_bikes_table.php @@ -17,8 +17,7 @@ return new class extends Migration $table->id(); $table->integer('battery'); $table->timestamps(); - - $table->foreign('id')->references('id')->on('bikes'); + //$table->foreign('id')->references('id')->on('bikes'); }); } diff --git a/database/migrations/2022_06_14_151011_create_routes_table.php b/database/migrations/2022_06_14_151011_create_routes_table.php index 51d6e35..f73d946 100644 --- a/database/migrations/2022_06_14_151011_create_routes_table.php +++ b/database/migrations/2022_06_14_151011_create_routes_table.php @@ -48,6 +48,8 @@ return new class extends Migration ->nullable(); $table->integer('duration') ->nullable(); + $table->integer('estimated_duration') + ->nullable(); $table->integer('points') ->nullable(); diff --git a/database/migrations/2022_06_15_144408_create_rewards_table.php b/database/migrations/2022_06_15_144408_create_rewards_table.php index deebdc1..485b82c 100644 --- a/database/migrations/2022_06_15_144408_create_rewards_table.php +++ b/database/migrations/2022_06_15_144408_create_rewards_table.php @@ -19,6 +19,7 @@ return new class extends Migration $table->string('description'); $table->integer('points'); $table->integer('total_available'); + $table->integer('redeemed')->default(0); $table->string('image')->nullable(); $table->timestamps(); }); diff --git a/database/seeders/BikeSeeder.php b/database/seeders/BikeSeeder.php index 22543e8..b638f24 100644 --- a/database/seeders/BikeSeeder.php +++ b/database/seeders/BikeSeeder.php @@ -18,29 +18,36 @@ class BikeSeeder extends Seeder { $bike = Bike::create([ 'stop_id' => 1, - 'unlocked' => false + 'unlocked' => false, + 'bikeable_id' => 1, + 'bikeable_type' => 'App\Models\ElectricBike', ]); ElectricBike::create([ - 'id' => $bike->id, 'battery' => 60 ]); Bike::create([ 'stop_id' => 1, - 'unlocked' => false + 'unlocked' => false, + 'bikeable_id' => 2, + 'bikeable_type' => 'App\Models\Bike', ]); $bike = Bike::create([ 'stop_id' => 2, - 'unlocked' => false + 'unlocked' => false, + 'bikeable_id' => 2, + 'bikeable_type' => 'App\Models\ElectricBike', ]); ElectricBike::create([ - 'id' => $bike->id, 'battery' => 70 ]); Bike::create([ 'stop_id' => 3, - 'unlocked' => false + 'unlocked' => false, + 'bikeable_id' => 4, + 'bikeable_type' => 'App\Models\Bike', ]); + } } diff --git a/database/seeders/RewardSeeder.php b/database/seeders/RewardSeeder.php index 5472789..e98dbed 100644 --- a/database/seeders/RewardSeeder.php +++ b/database/seeders/RewardSeeder.php @@ -19,33 +19,38 @@ class RewardSeeder extends Seeder 'name' => 'Reward 1', 'description' => 'A short description', 'points' => 100, - 'total_available' => 5 + 'total_available' => 5, + "image"=> "https://images.unsplash.com/photo-1591544940847-e8c860a9464e?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1974&q=80" ]); $reward->users()->sync([1,2]); $reward = Reward::create([ 'name' => 'Reward 2', 'description' => 'A short description 2', 'points' => 200, - 'total_available' => 2 + 'total_available' => 2, + "image"=> "https://images.unsplash.com/photo-1621841957884-1210fe19d66d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2340&q=80" ]); $reward->users()->sync([1]); Reward::create([ 'name' => 'Reward 3', 'description' => 'A short description 3', 'points' => 1000, - 'total_available' => 1 + 'total_available' => 1, + "image" => "https://images.unsplash.com/photo-1565599837634-134bc3aadce8?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1335&q=80" ]); Reward::create([ 'name' => 'Reward 4', 'description' => 'A short description 4', 'points' => 4, - 'total_available' => 10 + 'total_available' => 10, + 'image' => 'https://images.unsplash.com/photo-1617257118084-339d30c49b02?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2340&q=80' ]); Reward::create([ 'name' => 'Reward 5', 'description' => 'A short description 5', 'points' => 500, - 'total_available' => 5 + 'total_available' => 5, + "image"=> "https://images.unsplash.com/photo-1655219282218-6a4a8d91a699?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2340&q=80" ]); } } diff --git a/database/seeders/UserSeeder.php b/database/seeders/UserSeeder.php index 53bc219..81d01bf 100644 --- a/database/seeders/UserSeeder.php +++ b/database/seeders/UserSeeder.php @@ -18,7 +18,8 @@ class UserSeeder extends Seeder User::create([ 'name' => 'Jorge', 'email' => 'jorge@uva.es', - 'password' => '12345678' + 'password' => bcrypt('123456'), + 'points' => 1000 ]); User::create([ 'name' => 'Mario', diff --git a/routes/api.php b/routes/api.php index fd621db..0276c00 100644 --- a/routes/api.php +++ b/routes/api.php @@ -2,8 +2,12 @@ use App\Http\Controllers\AuthController; use App\Http\Controllers\BikeController; +use App\Http\Controllers\RewardController; use App\Http\Controllers\RouteController; use App\Http\Controllers\StopController; +use App\Http\Resources\BikeResource; +use App\Http\Resources\RewardColletion; +use App\Models\Bike; use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; @@ -23,10 +27,30 @@ Route::middleware('auth:sanctum')->get('/user', function (Request $request) { }); Route::post('/login', [AuthController::class, 'login']); -Route::get('/retobici/stops', [StopController::class, 'getAllStops']); +Route::get('/stops', [StopController::class, 'getAllStops']); +Route::get('/rewards', [RewardController::class, 'getAllRewards']); Route::middleware('auth:sanctum')->group(function (){ - Route::post('/retobici/bikes/unlock/{bike}', [BikeController::class, 'unlockBike']); - Route::put('/retobici/routes', [RouteController::class, 'createRoute']); + + Route::post('/stops/{bike}/unlock', [StopController::class, 'unlockBike']); + Route::post('/stops/{stop}/reserve/{type}', [StopController::class, 'reserveBike']); + Route::post('/stops/{stop}/lock', [StopController::class, 'lockBike']); + + Route::put('/routes/{bike}', [RouteController::class, 'createRoute']); + Route::post('/routes/finish', [RouteController::class, 'finishRoute']); + + Route::post('/rewards/{reward}', [RewardController::class, 'obtainReward']); + Route::get('/rewards/redeemed', [RewardController::class, 'getUserRewards']); + Route::get('/rewards/not/redeemed', [RewardController::class, 'getNotRedeemedRewards']); + + Route::post('/logout', [AuthController::class, 'logout']); +}); + +Route::get('/test', function (){ + $stops = \App\Models\Stop::all(); + $remove = $stops->first(); + return $stops->filter(function ($value) use ($remove){ + return $value!=$remove; + }); }); -- GitLab