migrate to gtea from bistbucket
This commit is contained in:
@@ -0,0 +1,299 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Modules\RestaurantDelivery\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Modules\RestaurantDelivery\Traits\HasRestaurant;
|
||||
use Modules\RestaurantDelivery\Traits\HasUuid;
|
||||
|
||||
class RiderBonus extends Model
|
||||
{
|
||||
use HasFactory, HasRestaurant, HasUuid, SoftDeletes;
|
||||
|
||||
public const TABLE_NAME = 'restaurant_rider_bonuses';
|
||||
|
||||
protected $table = self::TABLE_NAME;
|
||||
|
||||
protected $fillable = [
|
||||
'rider_id',
|
||||
'restaurant_id',
|
||||
'type',
|
||||
'name',
|
||||
'description',
|
||||
'amount',
|
||||
'currency',
|
||||
'criteria',
|
||||
'criteria_value',
|
||||
'achieved_value',
|
||||
'period_start',
|
||||
'period_end',
|
||||
'status',
|
||||
'awarded_at',
|
||||
'expires_at',
|
||||
'earning_id',
|
||||
'meta',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'amount' => 'decimal:2',
|
||||
'criteria_value' => 'decimal:2',
|
||||
'achieved_value' => 'decimal:2',
|
||||
'period_start' => 'datetime',
|
||||
'period_end' => 'datetime',
|
||||
'awarded_at' => 'datetime',
|
||||
'expires_at' => 'datetime',
|
||||
'meta' => 'array',
|
||||
];
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Relationships
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public function rider(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Rider::class, 'rider_id');
|
||||
}
|
||||
|
||||
public function earning(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(RiderEarning::class, 'earning_id');
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Scopes
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public function scopePending($query)
|
||||
{
|
||||
return $query->where('status', 'pending');
|
||||
}
|
||||
|
||||
public function scopeAwarded($query)
|
||||
{
|
||||
return $query->where('status', 'awarded');
|
||||
}
|
||||
|
||||
public function scopeExpired($query)
|
||||
{
|
||||
return $query->where('status', 'expired');
|
||||
}
|
||||
|
||||
public function scopeForPeriod($query, $start, $end)
|
||||
{
|
||||
return $query->whereBetween('period_start', [$start, $end]);
|
||||
}
|
||||
|
||||
public function scopeOfType($query, string $type)
|
||||
{
|
||||
return $query->where('type', $type);
|
||||
}
|
||||
|
||||
public function scopeActive($query)
|
||||
{
|
||||
return $query->where('status', 'awarded')
|
||||
->where(function ($q) {
|
||||
$q->whereNull('expires_at')
|
||||
->orWhere('expires_at', '>', now());
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Bonus Types
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public static function bonusTypes(): array
|
||||
{
|
||||
return [
|
||||
'peak_hour' => 'Peak Hour Bonus',
|
||||
'rain' => 'Rain/Weather Bonus',
|
||||
'consecutive_delivery' => 'Consecutive Delivery Bonus',
|
||||
'rating' => 'High Rating Bonus',
|
||||
'weekly_target' => 'Weekly Target Bonus',
|
||||
'referral' => 'Referral Bonus',
|
||||
'signup' => 'Signup Bonus',
|
||||
'special' => 'Special Bonus',
|
||||
];
|
||||
}
|
||||
|
||||
public function getTypeLabel(): string
|
||||
{
|
||||
return self::bonusTypes()[$this->type] ?? ucfirst($this->type);
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Status Methods
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public function isPending(): bool
|
||||
{
|
||||
return $this->status === 'pending';
|
||||
}
|
||||
|
||||
public function isAwarded(): bool
|
||||
{
|
||||
return $this->status === 'awarded';
|
||||
}
|
||||
|
||||
public function isExpired(): bool
|
||||
{
|
||||
return $this->status === 'expired';
|
||||
}
|
||||
|
||||
public function isActive(): bool
|
||||
{
|
||||
return $this->isAwarded() && (! $this->expires_at || $this->expires_at > now());
|
||||
}
|
||||
|
||||
/**
|
||||
* Award the bonus to rider.
|
||||
*/
|
||||
public function award(): bool
|
||||
{
|
||||
if (! $this->isPending()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->update([
|
||||
'status' => 'awarded',
|
||||
'awarded_at' => now(),
|
||||
]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark bonus as expired.
|
||||
*/
|
||||
public function markExpired(): bool
|
||||
{
|
||||
if (! $this->isPending()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->update([
|
||||
'status' => 'expired',
|
||||
]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Factory Methods
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a peak hour bonus.
|
||||
*/
|
||||
public static function createPeakHourBonus(Rider $rider, float $amount): self
|
||||
{
|
||||
return static::create([
|
||||
'rider_id' => $rider->id,
|
||||
'restaurant_id' => getUserRestaurantId(),
|
||||
'type' => 'peak_hour',
|
||||
'name' => 'Peak Hour Bonus',
|
||||
'description' => 'Bonus for delivering during peak hours',
|
||||
'amount' => $amount,
|
||||
'currency' => config('restaurant-delivery.pricing.currency', 'BDT'),
|
||||
'status' => 'pending',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a weather bonus.
|
||||
*/
|
||||
public static function createWeatherBonus(Rider $rider, float $amount, string $condition = 'rain'): self
|
||||
{
|
||||
return static::create([
|
||||
'rider_id' => $rider->id,
|
||||
'restaurant_id' => getUserRestaurantId(),
|
||||
'type' => 'rain',
|
||||
'name' => ucfirst($condition).' Bonus',
|
||||
'description' => "Bonus for delivering during {$condition}",
|
||||
'amount' => $amount,
|
||||
'currency' => config('restaurant-delivery.pricing.currency', 'BDT'),
|
||||
'status' => 'pending',
|
||||
'meta' => ['weather_condition' => $condition],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a consecutive delivery bonus.
|
||||
*/
|
||||
public static function createConsecutiveBonus(Rider $rider, float $amount, int $deliveryCount): self
|
||||
{
|
||||
return static::create([
|
||||
'rider_id' => $rider->id,
|
||||
'restaurant_id' => getUserRestaurantId(),
|
||||
'type' => 'consecutive_delivery',
|
||||
'name' => 'Consecutive Delivery Bonus',
|
||||
'description' => "Bonus for {$deliveryCount} consecutive deliveries",
|
||||
'amount' => $amount,
|
||||
'currency' => config('restaurant-delivery.pricing.currency', 'BDT'),
|
||||
'criteria' => 'consecutive_deliveries',
|
||||
'criteria_value' => $deliveryCount,
|
||||
'achieved_value' => $deliveryCount,
|
||||
'status' => 'pending',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a weekly target bonus.
|
||||
*/
|
||||
public static function createWeeklyTargetBonus(
|
||||
Rider $rider,
|
||||
float $amount,
|
||||
int $targetDeliveries,
|
||||
int $achievedDeliveries
|
||||
): self {
|
||||
return static::create([
|
||||
'rider_id' => $rider->id,
|
||||
'restaurant_id' => getUserRestaurantId(),
|
||||
'type' => 'weekly_target',
|
||||
'name' => 'Weekly Target Bonus',
|
||||
'description' => "Bonus for completing {$targetDeliveries} deliveries in a week",
|
||||
'amount' => $amount,
|
||||
'currency' => config('restaurant-delivery.pricing.currency', 'BDT'),
|
||||
'criteria' => 'weekly_deliveries',
|
||||
'criteria_value' => $targetDeliveries,
|
||||
'achieved_value' => $achievedDeliveries,
|
||||
'period_start' => now()->startOfWeek(),
|
||||
'period_end' => now()->endOfWeek(),
|
||||
'status' => 'pending',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a rating bonus.
|
||||
*/
|
||||
public static function createRatingBonus(Rider $rider, float $amount, float $rating): self
|
||||
{
|
||||
return static::create([
|
||||
'rider_id' => $rider->id,
|
||||
'restaurant_id' => getUserRestaurantId(),
|
||||
'type' => 'rating',
|
||||
'name' => 'High Rating Bonus',
|
||||
'description' => "Bonus for maintaining {$rating}+ rating",
|
||||
'amount' => $amount,
|
||||
'currency' => config('restaurant-delivery.pricing.currency', 'BDT'),
|
||||
'criteria' => 'min_rating',
|
||||
'criteria_value' => $rating,
|
||||
'achieved_value' => $rider->rating,
|
||||
'status' => 'pending',
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user