feat: add referral_code
This commit is contained in:
@@ -140,6 +140,85 @@ public function subscribeUser(Request $request, $identifier)
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List users who reached the referral invite target (کد معرف) and have
|
||||||
|
* not yet been granted their free-month subscription.
|
||||||
|
*/
|
||||||
|
public function pendingReferralRewards(Request $request)
|
||||||
|
{
|
||||||
|
$target = User::REFERRAL_SUBSCRIPTION_TARGET;
|
||||||
|
|
||||||
|
$users = User::withCount('referrals')
|
||||||
|
->whereNull('referral_subscription_granted_at')
|
||||||
|
->having('referrals_count', '>=', $target)
|
||||||
|
->orderByDesc('referrals_count')
|
||||||
|
->get(['id', 'uuid', 'first_name', 'last_name', 'email', 'mobile', 'referral_code']);
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'subscription_target' => $target,
|
||||||
|
'data' => $users->map(fn ($u) => [
|
||||||
|
'id' => $u->id,
|
||||||
|
'uuid' => $u->uuid,
|
||||||
|
'name' => trim($u->first_name . ' ' . $u->last_name),
|
||||||
|
'email' => $u->email,
|
||||||
|
'mobile' => $u->mobile,
|
||||||
|
'referral_code' => $u->referral_code,
|
||||||
|
'successful_invites' => $u->referrals_count,
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grant the free-month subscription to a user who reached the referral
|
||||||
|
* invite target. Defaults to the meditation package's monthly product,
|
||||||
|
* overridable via product_id. Marks the grant so it happens only once.
|
||||||
|
*/
|
||||||
|
public function fulfillReferralReward(Request $request, $userId)
|
||||||
|
{
|
||||||
|
$data = $request->validate([
|
||||||
|
'product_id' => 'integer|nullable',
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!$user = User::find($userId)) {
|
||||||
|
return response()->json(['message' => 'user not found'], 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($user->referral_subscription_granted_at) {
|
||||||
|
return response()->json(['message' => 'referral subscription already granted'], 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($user->referrals()->count() < User::REFERRAL_SUBSCRIPTION_TARGET) {
|
||||||
|
return response()->json(['message' => 'user has not reached the referral target yet'], 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resolve which monthly product to grant
|
||||||
|
if (!empty($data['product_id'])) {
|
||||||
|
$product = Product::where('id', $data['product_id'])->first();
|
||||||
|
} else {
|
||||||
|
$package = PackageName::where('name', User::REFERRAL_PACKAGE_NAME)->first();
|
||||||
|
$product = $package
|
||||||
|
? Product::where('package_name_id', $package->id)
|
||||||
|
->where('type', Product::TYPES['monthly'])
|
||||||
|
->first()
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$product) {
|
||||||
|
return response()->json(['message' => 'monthly product not found'], 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
$product->buy($user);
|
||||||
|
|
||||||
|
$user->referral_subscription_granted_at = now();
|
||||||
|
$user->save();
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'referral subscription granted',
|
||||||
|
'user_id' => $user->id,
|
||||||
|
'product_id' => $product->id,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
public function unsubscribeUser(Request $request, $identifier)
|
public function unsubscribeUser(Request $request, $identifier)
|
||||||
{
|
{
|
||||||
$data = $request->validate([
|
$data = $request->validate([
|
||||||
|
|||||||
@@ -638,6 +638,10 @@ public function status(Request $request)
|
|||||||
->first();
|
->first();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Expose the referrer's uuid so downstream apps can resolve the
|
||||||
|
// referral relationship (کد معرف) against their own local user.
|
||||||
|
$user['referrer_uuid'] = $user->referred_by ? optional($user->referrer)->uuid : null;
|
||||||
|
|
||||||
return $user;
|
return $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,9 +20,16 @@ class User extends Authenticatable
|
|||||||
'male' => 1,
|
'male' => 1,
|
||||||
'female' => 2,
|
'female' => 2,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Referral program (کد معرف): successful invites needed for a free month,
|
||||||
|
// and the app whose monthly product is granted as the reward.
|
||||||
|
const REFERRAL_SUBSCRIPTION_TARGET = 10;
|
||||||
|
const REFERRAL_PACKAGE_NAME = 'com.approagency.meditation';
|
||||||
|
|
||||||
protected $guarded = [];
|
protected $guarded = [];
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'mobile_verified_at' => 'datetime',
|
'mobile_verified_at' => 'datetime',
|
||||||
|
'referral_subscription_granted_at' => 'datetime',
|
||||||
];
|
];
|
||||||
protected $hidden = [
|
protected $hidden = [
|
||||||
'password',
|
'password',
|
||||||
|
|||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('users', function (Blueprint $table) {
|
||||||
|
// When the referral free-month subscription was granted (null = not yet).
|
||||||
|
if (!Schema::hasColumn('users', 'referral_subscription_granted_at')) {
|
||||||
|
$table->timestamp('referral_subscription_granted_at')->nullable()->after('referred_by');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('users', function (Blueprint $table) {
|
||||||
|
if (Schema::hasColumn('users', 'referral_subscription_granted_at')) {
|
||||||
|
$table->dropColumn('referral_subscription_granted_at');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -95,6 +95,9 @@
|
|||||||
Route::get('/users/{mobile}/status-v1', 'getUserStatusV1');
|
Route::get('/users/{mobile}/status-v1', 'getUserStatusV1');
|
||||||
Route::put('/users/{mobile}/status', 'subscribeUser');
|
Route::put('/users/{mobile}/status', 'subscribeUser');
|
||||||
Route::delete('/users/{mobile}/status', 'unsubscribeUser');
|
Route::delete('/users/{mobile}/status', 'unsubscribeUser');
|
||||||
|
// Referral free-month rewards (کد معرف)
|
||||||
|
Route::get('/referral-rewards', 'pendingReferralRewards');
|
||||||
|
Route::post('/referral-rewards/{user}/fulfill', 'fulfillReferralReward');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
///promotions
|
///promotions
|
||||||
|
|||||||
Reference in New Issue
Block a user