Implement package limit notification system
This commit is contained in:
@@ -5,7 +5,6 @@ namespace App\Models;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class EventPackage extends Model
|
||||
{
|
||||
@@ -27,6 +26,8 @@ class EventPackage extends Model
|
||||
'purchased_price' => 'decimal:2',
|
||||
'purchased_at' => 'datetime',
|
||||
'gallery_expires_at' => 'datetime',
|
||||
'gallery_warning_sent_at' => 'datetime',
|
||||
'gallery_expired_notified_at' => 'datetime',
|
||||
'used_photos' => 'integer',
|
||||
'used_guests' => 'integer',
|
||||
];
|
||||
@@ -48,33 +49,37 @@ class EventPackage extends Model
|
||||
|
||||
public function canUploadPhoto(): bool
|
||||
{
|
||||
if (!$this->isActive()) {
|
||||
if (! $this->isActive()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$maxPhotos = $this->package->max_photos ?? 0;
|
||||
|
||||
return $this->used_photos < $maxPhotos;
|
||||
}
|
||||
|
||||
public function canAddGuest(): bool
|
||||
{
|
||||
if (!$this->isActive()) {
|
||||
if (! $this->isActive()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$maxGuests = $this->package->max_guests ?? 0;
|
||||
|
||||
return $this->used_guests < $maxGuests;
|
||||
}
|
||||
|
||||
public function getRemainingPhotosAttribute(): int
|
||||
{
|
||||
$max = $this->package->max_photos ?? 0;
|
||||
|
||||
return max(0, $max - $this->used_photos);
|
||||
}
|
||||
|
||||
public function getRemainingGuestsAttribute(): int
|
||||
{
|
||||
$max = $this->package->max_guests ?? 0;
|
||||
|
||||
return max(0, $max - $this->used_guests);
|
||||
}
|
||||
|
||||
@@ -83,13 +88,13 @@ class EventPackage extends Model
|
||||
parent::boot();
|
||||
|
||||
static::creating(function ($eventPackage) {
|
||||
if (!$eventPackage->purchased_at) {
|
||||
if (! $eventPackage->purchased_at) {
|
||||
$eventPackage->purchased_at = now();
|
||||
}
|
||||
if (!$eventPackage->gallery_expires_at && $eventPackage->package) {
|
||||
if (! $eventPackage->gallery_expires_at && $eventPackage->package) {
|
||||
$days = $eventPackage->package->gallery_days ?? 30;
|
||||
$eventPackage->gallery_expires_at = now()->addDays($days);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,30 +5,31 @@ namespace App\Models;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use App\Models\TenantPackage;
|
||||
use App\Models\EventCreditsLedger;
|
||||
|
||||
class Tenant extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'tenants';
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
protected $casts = [
|
||||
'features' => 'array',
|
||||
'settings' => 'array',
|
||||
'notification_preferences' => 'array',
|
||||
'last_activity_at' => 'datetime',
|
||||
'total_revenue' => 'decimal:2',
|
||||
'settings_updated_at' => 'datetime',
|
||||
'subscription_expires_at' => 'datetime',
|
||||
'credit_warning_sent_at' => 'datetime',
|
||||
'credit_warning_threshold' => 'integer',
|
||||
];
|
||||
|
||||
public function events(): HasMany
|
||||
@@ -83,6 +84,7 @@ class Tenant extends Model
|
||||
}
|
||||
|
||||
$package->increment('used_events', $amount);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -90,6 +92,7 @@ class Tenant extends Model
|
||||
{
|
||||
if (is_string($value)) {
|
||||
$this->attributes['settings'] = $value;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -105,6 +108,22 @@ class Tenant extends Model
|
||||
$balance = (int) ($this->event_credits_balance ?? 0) + $amount;
|
||||
$this->forceFill(['event_credits_balance' => $balance])->save();
|
||||
|
||||
$maxThreshold = collect(config('package-limits.credit_thresholds', []))
|
||||
->filter(fn ($value) => is_numeric($value) && $value >= 0)
|
||||
->map(fn ($value) => (int) $value)
|
||||
->max();
|
||||
|
||||
if (
|
||||
$maxThreshold !== null
|
||||
&& $balance > $maxThreshold
|
||||
&& ($this->credit_warning_sent_at !== null || $this->credit_warning_threshold !== null)
|
||||
) {
|
||||
$this->forceFill([
|
||||
'credit_warning_sent_at' => null,
|
||||
'credit_warning_threshold' => null,
|
||||
])->save();
|
||||
}
|
||||
|
||||
EventCreditsLedger::create([
|
||||
'tenant_id' => $this->id,
|
||||
'delta' => $amount,
|
||||
@@ -134,6 +153,12 @@ class Tenant extends Model
|
||||
$balance = $current - $amount;
|
||||
$this->forceFill(['event_credits_balance' => $balance])->save();
|
||||
|
||||
app(\App\Services\Packages\TenantUsageTracker::class)->recordCreditBalance(
|
||||
$this,
|
||||
$current,
|
||||
$balance
|
||||
);
|
||||
|
||||
EventCreditsLedger::create([
|
||||
'tenant_id' => $this->id,
|
||||
'delta' => -$amount,
|
||||
@@ -166,7 +191,15 @@ class Tenant extends Model
|
||||
{
|
||||
$package = $this->getActiveResellerPackage();
|
||||
if ($package && $package->canCreateEvent()) {
|
||||
$previousUsed = (int) $package->used_events;
|
||||
$package->increment('used_events', $amount);
|
||||
$package->refresh();
|
||||
|
||||
app(\App\Services\Packages\TenantUsageTracker::class)->recordEventUsage(
|
||||
$package,
|
||||
$previousUsed,
|
||||
$amount
|
||||
);
|
||||
|
||||
Log::info('Tenant package usage recorded', [
|
||||
'tenant_id' => $this->id,
|
||||
|
||||
@@ -30,6 +30,11 @@ class TenantPackage extends Model
|
||||
'expires_at' => 'datetime',
|
||||
'used_events' => 'integer',
|
||||
'active' => 'boolean',
|
||||
'event_warning_sent_at' => 'datetime',
|
||||
'event_warning_threshold' => 'float',
|
||||
'event_limit_notified_at' => 'datetime',
|
||||
'expiry_warning_sent_at' => 'datetime',
|
||||
'expired_notified_at' => 'datetime',
|
||||
];
|
||||
|
||||
public function tenant(): BelongsTo
|
||||
|
||||
Reference in New Issue
Block a user