Skip to content

Commit

Permalink
Feature: VIP
Browse files Browse the repository at this point in the history
  • Loading branch information
MilesChou committed Jul 9, 2023
1 parent a681d7a commit f18b03e
Show file tree
Hide file tree
Showing 11 changed files with 326 additions and 176 deletions.
26 changes: 26 additions & 0 deletions app/Console/Commands/VipActivate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace App\Console\Commands;

use App\Models\User;
use Illuminate\Console\Command;
use Laravel\Pennant\FeatureManager;

class VipActivate extends Command
{
protected $signature = 'app:vip:activate {emails*}';

protected $description = 'Activate VIP permission';

public function handle(User $userModel, FeatureManager $feature): int
{
$users = $userModel->newQuery()
->select('id', 'email')
->whereIn('email', $this->argument('emails'))
->get();

$feature->for($users)->activate('vip');

return self::SUCCESS;
}
}
26 changes: 26 additions & 0 deletions app/Console/Commands/VipDeactivate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace App\Console\Commands;

use App\Models\User;
use Illuminate\Console\Command;
use Laravel\Pennant\FeatureManager;

class VipDeactivate extends Command
{
protected $signature = 'app:vip:deactivate {emails*}';

protected $description = 'Deactivate VIP permission';

public function handle(User $userModel, FeatureManager $feature): int
{
$users = $userModel->newQuery()
->select('id', 'email')
->whereIn('email', $this->argument('emails'))
->get();

$feature->for($users)->deactivate('vip');

return self::SUCCESS;
}
}
36 changes: 36 additions & 0 deletions app/Console/Commands/VipStatus.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace App\Console\Commands;

use App\Models\User;
use Illuminate\Console\Command;
use Laravel\Pennant\Feature;

class VipStatus extends Command
{
protected $signature = 'app:vip:status {emails*}';

protected $description = 'Inspect VIP status';

public function handle(User $userModel): int
{
$emails = $this->argument('emails');

$users = $userModel->newQuery()
->select('id', 'email')
->whereIn('email', $emails)
->get();

Feature::for($users)->load('vip');

$status = $users->map(function (User $user) {
$user['vip'] = $user->features()->active('vip') ? 'ON' : 'OFF';

return $user->toArray();
});

$this->table(['ID', 'Email', 'status'], $status->toArray());

return self::SUCCESS;
}
}
20 changes: 20 additions & 0 deletions app/Features/Vip.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace App\Features;

use Illuminate\Support\Lottery;

class Vip
{
public readonly string $name;

public function __construct()
{
$this->name = 'vip';
}

public function resolve(mixed $scope): bool
{
return false;
}
}
24 changes: 21 additions & 3 deletions app/Http/Controllers/User/Order.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,27 @@
namespace App\Http\Controllers\User;

use App\Models\Cart;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redirect;
use Laravel\Pennant\Feature;
use RealRashid\SweetAlert\Facades\Alert;

class Order
{
public function store(Request $request): RedirectResponse
public function __invoke(Request $request): RedirectResponse
{
$cart = Cart::findOrFail($request->cart_id)->with('product')->first();

/** @var User $user */
$user = Auth::user();

$order = new \App\Models\Order();
$order->user_id = Auth::user()->getAuthIdentifier();
$order->user_id = $user->getAuthIdentifier();
$order->product_id = $cart->product->id;
$order->quantity = $request->quantity;

Expand All @@ -29,7 +35,19 @@ public function store(Request $request): RedirectResponse
} else {
$totalPrice = $cart->product->price;
}
$order->price = $totalPrice;

$isVip = Feature::for($user)->active('vip');

if ($isVip) {
$order->price = (int)$totalPrice * 0.9;
} else {
$order->price = $totalPrice;
}

Log::info('VIP User order', [
'user' => $user->email,
'vip' => $isVip,
]);

if ($order->save()) {
//cart delete
Expand Down
4 changes: 3 additions & 1 deletion app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Pennant\Concerns\HasFeatures;
use Spatie\Permission\Traits\HasRoles;

/**
Expand All @@ -27,8 +28,9 @@
class User extends Authenticatable
{
use HasFactory;
use Notifiable;
use HasFeatures;
use HasRoles;
use Notifiable;

/**
* The attributes that are mass assignable.
Expand Down
Loading

0 comments on commit f18b03e

Please sign in to comment.