fix
This commit is contained in:
parent
f4c6bcade1
commit
588d93c4a2
@ -4,7 +4,8 @@
|
||||
"type": "library",
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^8.2"
|
||||
"php": "^8.2",
|
||||
"google/apiclient": "^2.15.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@ -23,7 +24,11 @@
|
||||
"aliases": {
|
||||
"Subscription": "IICN\\Subscription\\Subscription"
|
||||
}
|
||||
}
|
||||
},
|
||||
"google/apiclient-services": [
|
||||
"Drive",
|
||||
"YouTube"
|
||||
]
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^10.5.5",
|
||||
@ -33,5 +38,8 @@
|
||||
"psr-4": {
|
||||
"IICN\\Subscription\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"pre-autoload-dump": "Google\\Task\\Composer::cleanup"
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,25 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'user_model' => \App\Models\User::class,
|
||||
'coupon_conditions' => [
|
||||
|
||||
],
|
||||
|
||||
'guard' => null,
|
||||
|
||||
'enumerations' => [
|
||||
'subscription_ability_types' => ['istikhara', 'thematicـquran'],
|
||||
|
||||
'subscription_types' => ['premium', 'freemium', 'packages'],
|
||||
],
|
||||
|
||||
'google' => [
|
||||
'application_name' => '',
|
||||
|
||||
'app_key' => '',
|
||||
|
||||
'package_name' => '',
|
||||
],
|
||||
|
||||
'response_class' => null
|
||||
];
|
||||
|
@ -17,8 +17,8 @@ return new class extends Migration
|
||||
$table->integer('duration_day')->default(-1);
|
||||
$table->unsignedInteger('price')->default(0);
|
||||
$table->unsignedInteger('discount_percent')->default(0);
|
||||
$table->string('sku_code');
|
||||
$table->string('type')->default('subscription');
|
||||
$table->string('sku_code')->unique();
|
||||
$table->string('type');
|
||||
$table->integer('count')->default(0)->comment("just for show to Front");
|
||||
$table->json('description')->nullable();
|
||||
$table->timestamps();
|
||||
|
@ -17,7 +17,7 @@ return new class extends Migration
|
||||
$table->string('name');
|
||||
$table->string('type');
|
||||
$table->unsignedInteger('count')->default(999999);
|
||||
$table->unsignedInteger('subscription_id')->nullable();
|
||||
$table->unsignedInteger('subscription_id')->index();
|
||||
$table->string('description')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
@ -13,9 +13,10 @@ return new class extends Migration
|
||||
{
|
||||
Schema::create('subscription_logs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('subscription_ability_id');
|
||||
$table->unsignedBigInteger('user_id');
|
||||
$table->enum('type', ['used', 'rollback', 'new']);
|
||||
$table->unsignedBigInteger('subscription_user_id')->index();
|
||||
$table->unsignedBigInteger('user_id')->index();
|
||||
$table->json('new');
|
||||
$table->json('old');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('subscription_coupons', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('code')->index();
|
||||
$table->unsignedBigInteger('user_id')->nullable()->index();
|
||||
$table->unsignedBigInteger('subscription_id')->index();
|
||||
$table->unsignedBigInteger('count')->default(0);
|
||||
$table->timestamp('expiry_at');
|
||||
$table->integer('duration_day')->default(-1);
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('subscription_coupons');
|
||||
}
|
||||
};
|
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('subscription_transactions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('user_id')->index();
|
||||
$table->unsignedBigInteger('subscription_user_id')->nullable()->index();
|
||||
$table->unsignedBigInteger('price')->default(0);
|
||||
$table->unsignedBigInteger('subscription_coupon_id')->nullable()->index();
|
||||
$table->enum('status', [
|
||||
\IICN\Subscription\Constants\Status::INIT,
|
||||
\IICN\Subscription\Constants\Status::SUCCESS,
|
||||
\IICN\Subscription\Constants\Status::FAILED,
|
||||
])->default(\IICN\Subscription\Constants\Status::INIT);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('subscription_transactions');
|
||||
}
|
||||
};
|
@ -1,81 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace IICN\Subscription\Concerns;
|
||||
|
||||
trait AllowsCoupons
|
||||
{
|
||||
/**
|
||||
* The coupon ID being applied.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $couponId;
|
||||
|
||||
/**
|
||||
* The promotion code ID being applied.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $promotionCodeId;
|
||||
|
||||
/**
|
||||
* Determines if user redeemable promotion codes are available in Stripe Checkout.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $allowPromotionCodes = false;
|
||||
|
||||
/**
|
||||
* The coupon ID to be applied.
|
||||
*
|
||||
* @param string $couponId
|
||||
* @return $this
|
||||
*/
|
||||
public function withCoupon($couponId)
|
||||
{
|
||||
$this->couponId = $couponId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The promotion code ID to apply.
|
||||
*
|
||||
* @param string $promotionCodeId
|
||||
* @return $this
|
||||
*/
|
||||
public function withPromotionCode($promotionCodeId)
|
||||
{
|
||||
$this->promotionCodeId = $promotionCodeId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables user redeemable promotion codes for a Stripe Checkout session.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function allowPromotionCodes()
|
||||
{
|
||||
$this->allowPromotionCodes = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the discounts for a Stripe Checkout session.
|
||||
*
|
||||
* @return array[]|null
|
||||
*/
|
||||
protected function checkoutDiscounts()
|
||||
{
|
||||
if ($this->couponId) {
|
||||
return [['coupon' => $this->couponId]];
|
||||
}
|
||||
|
||||
if ($this->promotionCodeId) {
|
||||
return [['promotion_code' => $this->promotionCodeId]];
|
||||
}
|
||||
}
|
||||
}
|
@ -30,6 +30,13 @@ trait ManagesSubscriptions
|
||||
return $subscription->getActiveWithCount($type);
|
||||
}
|
||||
|
||||
public function getSubscriptionTypes(): array
|
||||
{
|
||||
$subscription = new Subscription($this);
|
||||
|
||||
return $subscription->getSubscriptionTypes();
|
||||
}
|
||||
|
||||
public function activeSubscriptionsWithType(string $type): BelongsToMany
|
||||
{
|
||||
return $this->activeSubscriptions()->whereHas('subscriptionAbilities', function ($query) use ($type) {
|
||||
|
10
src/Constants/Status.php
Normal file
10
src/Constants/Status.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace IICN\Subscription\Constants;
|
||||
|
||||
class Status
|
||||
{
|
||||
const SUCCESS = 'success';
|
||||
const FAILED = 'failed';
|
||||
const INIT = 'int';
|
||||
}
|
13
src/CouponConditionInterface.php
Normal file
13
src/CouponConditionInterface.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace IICN\Subscription;
|
||||
|
||||
|
||||
use IICN\Subscription\Models\SubscriptionCoupon;
|
||||
|
||||
interface CouponConditionInterface
|
||||
{
|
||||
public function handle(SubscriptionCoupon $subscriptionCoupon): bool;
|
||||
|
||||
public function failedMessage(): string;
|
||||
}
|
18
src/Http/Controllers/Subscription/Index.php
Normal file
18
src/Http/Controllers/Subscription/Index.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace IICN\Subscription\Http\Controllers\Subscription;
|
||||
|
||||
use IICN\Subscription\Http\Controllers\Controller;
|
||||
use IICN\Subscription\Http\Resources\SubscriptionResources;
|
||||
use IICN\Subscription\Models\Subscription;
|
||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||
|
||||
class Index extends Controller
|
||||
{
|
||||
public function __invoke(): AnonymousResourceCollection
|
||||
{
|
||||
$subscriptions = Subscription::query()->get();
|
||||
|
||||
return SubscriptionResources::collection($subscriptions);
|
||||
}
|
||||
}
|
18
src/Http/Controllers/Subscription/IndexByType.php
Normal file
18
src/Http/Controllers/Subscription/IndexByType.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace IICN\Subscription\Http\Controllers\Subscription;
|
||||
|
||||
use IICN\Subscription\Http\Controllers\Controller;
|
||||
use IICN\Subscription\Http\Resources\SubscriptionResources;
|
||||
use IICN\Subscription\Models\Subscription;
|
||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||
|
||||
class IndexByType extends Controller
|
||||
{
|
||||
public function __invoke(string $type): AnonymousResourceCollection
|
||||
{
|
||||
$subscriptions = Subscription::query()->with('subscriptionAbilities')->where('type', $type)->get();
|
||||
|
||||
return SubscriptionResources::collection($subscriptions);
|
||||
}
|
||||
}
|
57
src/Http/Controllers/Subscription/VerifyPurchase.php
Normal file
57
src/Http/Controllers/Subscription/VerifyPurchase.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace IICN\Subscription\Http\Controllers\Subscription;
|
||||
|
||||
use IICN\Subscription\Constants\Status;
|
||||
use IICN\Subscription\Http\Controllers\Controller;
|
||||
use IICN\Subscription\Models\Subscription;
|
||||
use IICN\Subscription\Models\SubscriptionTransaction;
|
||||
use IICN\Subscription\Models\SubscriptionUser;
|
||||
use IICN\Subscription\Services\Playstore\Playstore;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class VerifyPurchase extends Controller
|
||||
{
|
||||
public function __invoke(Subscription $subscription, Request $request)
|
||||
{
|
||||
$playstore = new Playstore();
|
||||
|
||||
$result = $playstore->verifyPurchase($subscription->sku_code, $request->purechaseToken);
|
||||
|
||||
if (!$result) {
|
||||
SubscriptionTransaction::query()->create([
|
||||
'user_id' => \IICN\Subscription\Subscription::getSubscriptionableId(),
|
||||
'status' => Status::FAILED,
|
||||
]);
|
||||
return false;
|
||||
}
|
||||
|
||||
DB::beginTransaction();
|
||||
|
||||
$result = \IICN\Subscription\Subscription::create($subscription->id);
|
||||
|
||||
if (!$result) {
|
||||
DB::rollBack();
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = SubscriptionTransaction::query()->create([
|
||||
'user_id' => \IICN\Subscription\Subscription::getSubscriptionableId(),
|
||||
'subscription_user_id' => SubscriptionUser::query()->where([
|
||||
'subscription_id' => $subscription->id,
|
||||
'user_id' => \IICN\Subscription\Subscription::getSubscriptionableId(),
|
||||
])->latest('id')->first()?->id,
|
||||
'status' => Status::SUCCESS,
|
||||
]);
|
||||
|
||||
if (!$result) {
|
||||
DB::rollBack();
|
||||
return false;
|
||||
}
|
||||
|
||||
DB::commit();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace IICN\Subscription\Http\Controllers\SubscriptionCoupon;
|
||||
|
||||
use IICN\Subscription\Constants\Status;
|
||||
use IICN\Subscription\Http\Controllers\Controller;
|
||||
use IICN\Subscription\Http\Requests\StoreWithSubscriptionCouponRequest;
|
||||
use IICN\Subscription\Models\SubscriptionCoupon;
|
||||
use IICN\Subscription\Models\SubscriptionUser;
|
||||
use IICN\Subscription\Subscription;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class StoreWithSubscriptionCoupon extends Controller
|
||||
{
|
||||
public function __invoke(StoreWithSubscriptionCouponRequest $request)
|
||||
{
|
||||
$subscriptionCoupon = SubscriptionCoupon::query()->find($request->validated('subscription_coupon_id'));
|
||||
|
||||
DB::beginTransaction();
|
||||
|
||||
$result = Subscription::create($subscriptionCoupon->subscription_id, $subscriptionCoupon->duration_day);
|
||||
|
||||
if (!$result) {
|
||||
DB::rollBack();
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = $subscriptionCoupon->subscriptionTransactions()->create([
|
||||
'user_id' => Subscription::getSubscriptionableId(),
|
||||
'subscription_user_id' => SubscriptionUser::query()->where([
|
||||
'subscription_id' => $subscriptionCoupon->subscription_id,
|
||||
'user_id' => Subscription::getSubscriptionableId(),
|
||||
])->latest('id')->first()?->id,
|
||||
'status' => Status::SUCCESS,
|
||||
]);
|
||||
|
||||
if (!$result) {
|
||||
DB::rollBack();
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = $subscriptionCoupon->update(['count' => $subscriptionCoupon->count - 1]);
|
||||
|
||||
if (!$result) {
|
||||
DB::rollBack();
|
||||
return false;
|
||||
}
|
||||
|
||||
DB::commit();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -11,7 +11,8 @@ class Test extends Controller
|
||||
public function __invoke()
|
||||
{
|
||||
Auth::loginUsingId(1);
|
||||
return Subscription::canUse('Istikhara');
|
||||
// return Subscription::create(1);
|
||||
return Subscription::getSubscriptionTypes();
|
||||
return $user->useSubscription("Istikhara");
|
||||
$user->newSubscription(1);
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ class ValidateSubscription
|
||||
if (Subscription::canUse($type)) {
|
||||
return $next($request);
|
||||
} else {
|
||||
abort(403);
|
||||
abort(403, 'You do not have access to this Ability');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
66
src/Http/Requests/StoreWithSubscriptionCouponRequest.php
Normal file
66
src/Http/Requests/StoreWithSubscriptionCouponRequest.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace IICN\Subscription\Http\Requests;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use IICN\Subscription\CouponConditionInterface;
|
||||
use IICN\Subscription\Models\SubscriptionCoupon;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class StoreWithSubscriptionCouponRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return \Illuminate\Support\Facades\Auth::guard(config('subscription.guard'))->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'code' => 'required|string|max:100',
|
||||
'subscription_coupon_id' => 'required',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function prepareForValidation()
|
||||
{
|
||||
if (!isset($this->code)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$subscriptionCoupon = SubscriptionCoupon::query()
|
||||
->where('code', $this->code)
|
||||
->where('expiry_at', '>=', Carbon::now())
|
||||
->where('count', '>', 0)
|
||||
->first();
|
||||
|
||||
if ($subscriptionCoupon) {
|
||||
$this->merge(['subscription_coupon_id' => $subscriptionCoupon->id]);
|
||||
} else {
|
||||
return throw ValidationException::withMessages(['code' => 'code not found!']);
|
||||
}
|
||||
|
||||
$conditions = config('subscription.coupon_conditions');
|
||||
|
||||
foreach ($conditions as $condition) {
|
||||
if ($condition instanceof CouponConditionInterface) {
|
||||
$classCondition = new $condition();
|
||||
if (!$classCondition->handle($subscriptionCoupon)) {
|
||||
return throw ValidationException::withMessages(['message' => $classCondition->failedMessage()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
22
src/Http/Resources/SubscriptionAbilityResources.php
Normal file
22
src/Http/Resources/SubscriptionAbilityResources.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace IICN\Subscription\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class SubscriptionAbilityResources extends JsonResource
|
||||
{
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'slug' => $this->slug,
|
||||
'name' => $this->name,
|
||||
'type' => $this->type,
|
||||
'count' => $this->count,
|
||||
'subscription_id' => $this->subscription_id,
|
||||
'description' => $this->description,
|
||||
'subscription' => SubscriptionResources::make($this->whenLoaded('subscription')),
|
||||
];
|
||||
}
|
||||
}
|
24
src/Http/Resources/SubscriptionResources.php
Normal file
24
src/Http/Resources/SubscriptionResources.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace IICN\Subscription\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class SubscriptionResources extends JsonResource
|
||||
{
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'title' => $this->title,
|
||||
'duration_day' => $this->duration_day,
|
||||
'price' => $this->price,
|
||||
'discount_percent' => $this->discount_percent,
|
||||
'sku_code' => $this->sku_code,
|
||||
'type' => $this->type,
|
||||
'count' => $this->count,
|
||||
'description' => $this->description,
|
||||
'subscriptionAbilities' => SubscriptionAbilityResources::collection($this->whenLoaded('subscriptionAbilities')),
|
||||
];
|
||||
}
|
||||
}
|
@ -2,9 +2,7 @@
|
||||
|
||||
namespace IICN\Subscription\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
@ -28,23 +26,8 @@ class Subscription extends Model
|
||||
'description',
|
||||
];
|
||||
|
||||
// public function users(): BelongsToMany
|
||||
// {
|
||||
// return $this->belongsToMany(config('subscription.user_model'), 'subscription_user')->with(['created_at', 'expiry_at', 'remaining_number']);
|
||||
// }
|
||||
|
||||
public function subscriptionAbilities(): HasMany
|
||||
{
|
||||
return $this->hasMany(SubscriptionAbility::class);
|
||||
}
|
||||
|
||||
public function activeUsers(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(config('subscription.user_model'), 'subscription_user')
|
||||
->where(function ($query) {
|
||||
$query->wherePivot('expiry_at', '>', Carbon::now())->orWherePivotNull('expiry_at');
|
||||
})
|
||||
->wherePivot('remaining_number', '>', 0)
|
||||
->with(['created_at', 'expiry_at', 'remaining_number']);
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ class SubscriptionAbility extends Model
|
||||
'name',
|
||||
'type',
|
||||
'count',
|
||||
'condition_class',
|
||||
'subscription_id',
|
||||
'description',
|
||||
];
|
||||
|
30
src/Models/SubscriptionCoupon.php
Normal file
30
src/Models/SubscriptionCoupon.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace IICN\Subscription\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class SubscriptionCoupon extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = ['subscription_id', 'user_id', 'count', 'expiry_at', 'duration_day', 'code'];
|
||||
|
||||
public function subscription(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Subscription::class);
|
||||
}
|
||||
|
||||
public function subscriptionTransactions(): HasMany
|
||||
{
|
||||
return $this->hasMany(SubscriptionTransaction::class);
|
||||
}
|
||||
}
|
24
src/Models/SubscriptionLog.php
Normal file
24
src/Models/SubscriptionLog.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace IICN\Subscription\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class SubscriptionLog extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = ['subscription_user_id', 'user_id', 'new', 'old'];
|
||||
|
||||
public function subscriptionUser(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(SubscriptionUser::class);
|
||||
}
|
||||
}
|
35
src/Models/SubscriptionTransaction.php
Normal file
35
src/Models/SubscriptionTransaction.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace IICN\Subscription\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class SubscriptionTransaction extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'price',
|
||||
'subscription_user_id',
|
||||
'subscription_coupon_id',
|
||||
'status'
|
||||
];
|
||||
|
||||
public function subscriptionUser(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(SubscriptionUser::class);
|
||||
}
|
||||
|
||||
public function subscriptionCoupon(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(SubscriptionCoupon::class);
|
||||
}
|
||||
}
|
32
src/Services/Playstore/Playstore.php
Normal file
32
src/Services/Playstore/Playstore.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace IICN\Subscription\Services\Playstore;
|
||||
|
||||
use Google\Client;
|
||||
use Google\Service\AndroidPublisher;
|
||||
|
||||
class Playstore
|
||||
{
|
||||
public $service;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$client = new Client();
|
||||
$client->setApplicationName(config('subscription.google.application_name'));
|
||||
$client->setDeveloperKey(config('subscription.google.app_key'));
|
||||
|
||||
// $client->setAuthConfig('path/to/credentials.json');
|
||||
// $client->setScopes(['https://www.googleapis.com/auth/androidpublisher']);
|
||||
|
||||
$this->service = new AndroidPublisher($client);
|
||||
}
|
||||
|
||||
public function verifyPurchase(string $productId, string $purchaseToken)
|
||||
{
|
||||
$packageName = config('subscription.google.package_name');
|
||||
|
||||
$result = $this->service->purchases_products->get($packageName, $productId, $purchaseToken);
|
||||
|
||||
return $result->getPurchaseState() == 0;
|
||||
}
|
||||
}
|
@ -12,19 +12,20 @@ class Subscription
|
||||
{
|
||||
}
|
||||
|
||||
public function create(int $subscription_id): bool
|
||||
public function create(int $subscription_id, ?int $durationDay = null): bool
|
||||
{
|
||||
$subscription = \IICN\Subscription\Models\Subscription::query()->find($subscription_id);
|
||||
|
||||
if (isset($subscription->id)) {
|
||||
$expiryAt = Carbon::now()->addDays($subscription->duration_day);
|
||||
|
||||
$data = [];
|
||||
$expiryAt = $durationDay ? Carbon::now()->addDays($durationDay) : Carbon::now()->addDays($subscription->duration_day);
|
||||
|
||||
$remainingNumber = [];
|
||||
foreach ($subscription->subscriptionAbilities as $ability) {
|
||||
$data[$ability->type] = $ability->count;
|
||||
$remainingNumber[$ability->type] = $ability->count;
|
||||
}
|
||||
|
||||
$this->model->subscriptions()->attach($subscription_id, ['expiry_at' => $expiryAt, 'remaining_number' => $data]);
|
||||
dd($this->model->subscriptions()->attach($subscription_id, ['expiry_at' => $expiryAt, 'remaining_number' => $remainingNumber]));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -71,4 +72,14 @@ class Subscription
|
||||
{
|
||||
return isset($this->getActiveWithCount($type)[0]);
|
||||
}
|
||||
|
||||
public function getSubscriptionTypes(): array
|
||||
{
|
||||
return array_unique($this->model->activeSubscriptions->pluck('type')->toArray());
|
||||
}
|
||||
|
||||
public function getSubscriptionableId(): int|null|string
|
||||
{
|
||||
return $this->model->id;
|
||||
}
|
||||
}
|
||||
|
@ -4,9 +4,11 @@ namespace IICN\Subscription;
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
/**
|
||||
* @method static \IICN\Subscription\Services\Subscription create(int $subscription_id)
|
||||
* @method static \IICN\Subscription\Services\Subscription create(int $subscription_id, ?int $durationDay = null)
|
||||
* @method static \IICN\Subscription\Services\Subscription used(string $type)
|
||||
* @method static \IICN\Subscription\Services\Subscription canUse(string $type)
|
||||
* @method static \IICN\Subscription\Services\Subscription getSubscriptionTypes()
|
||||
* @method static \IICN\Subscription\Services\Subscription getSubscriptionableId()
|
||||
*
|
||||
* @see \IICN\Subscription\Services\Subscription
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user