'array', 'settings' => 'array', 'features' => 'array', 'last_activity_at' => 'datetime', 'event_credits_balance' => 'integer', 'subscription_tier' => 'string', 'subscription_expires_at' => 'datetime', 'total_revenue' => 'decimal:2', ]; public function events(): HasMany { return $this->hasMany(Event::class); } public function photos(): HasManyThrough { return $this->hasManyThrough( Photo::class, Event::class, 'tenant_id', // Foreign key on events table... 'event_id', // Foreign key on photos table... 'id', // Local key on tenants table... 'id' // Local key on events table... ); } public function purchases(): HasMany { return $this->hasMany(PurchaseHistory::class); } public function eventPurchases(): HasMany { return $this->hasMany(EventPurchase::class); } public function creditsLedger(): HasMany { return $this->hasMany(EventCreditsLedger::class); } public function activeSubscription(): Attribute { return Attribute::make( get: fn () => $this->subscription_expires_at && $this->subscription_expires_at->isFuture(), ); } public function decrementCredits(int $amount, string $reason = 'event_create', ?string $note = null, ?int $relatedPurchaseId = null): bool { if ($this->event_credits_balance < $amount) { return false; } return DB::transaction(function () use ($amount, $reason, $note, $relatedPurchaseId) { EventCreditsLedger::create([ 'tenant_id' => $this->id, 'delta' => -$amount, 'reason' => $reason, 'related_purchase_id' => $relatedPurchaseId, 'note' => $note, ]); return $this->decrement('event_credits_balance', $amount); }); } public function incrementCredits(int $amount, string $reason = 'manual_adjust', ?string $note = null, ?int $relatedPurchaseId = null): bool { return DB::transaction(function () use ($amount, $reason, $note, $relatedPurchaseId) { EventCreditsLedger::create([ 'tenant_id' => $this->id, 'delta' => $amount, 'reason' => $reason, 'related_purchase_id' => $relatedPurchaseId, 'note' => $note, ]); return $this->increment('event_credits_balance', $amount); }); } }