- Wired the checkout wizard for Google “comfort login”: added Socialite controller + dependency, new Google env
hooks in config/services.php/.env.example, and updated wizard steps/controllers to store session payloads, attach packages, and surface localized success/error states. - Retooled payment handling for both Stripe and PayPal, adding richer status management in CheckoutController/ PayPalController, fallback flows in the wizard’s PaymentStep.tsx, and fresh feature tests for intent creation, webhooks, and the wizard CTA. - Introduced a consent-aware Matomo analytics stack: new consent context, cookie-banner UI, useAnalytics/ useCtaExperiment hooks, and MatomoTracker component, then instrumented marketing pages (Home, Packages, Checkout) with localized copy and experiment tracking. - Polished package presentation across marketing UIs by centralizing formatting in PresentsPackages, surfacing localized description tables/placeholders, tuning badges/layouts, and syncing guest/marketing translations. - Expanded docs & reference material (docs/prp/*, TODOs, public gallery overview) and added a Playwright smoke test for the hero CTA while reconciling outstanding checklist items.
This commit is contained in:
@@ -8,8 +8,11 @@ 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\HasOne;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use App\Models\TenantPackage;
|
||||
use App\Models\EventCreditsLedger;
|
||||
|
||||
class Tenant extends Model
|
||||
@@ -55,6 +58,13 @@ class Tenant extends Model
|
||||
return $this->hasMany(TenantPackage::class);
|
||||
}
|
||||
|
||||
public function packages(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Package::class, 'tenant_packages')
|
||||
->withPivot(['price', 'purchased_at', 'expires_at', 'active'])
|
||||
->withTimestamps();
|
||||
}
|
||||
|
||||
public function activeResellerPackage(): HasOne
|
||||
{
|
||||
return $this->hasOne(TenantPackage::class)->where('active', true);
|
||||
@@ -62,18 +72,13 @@ class Tenant extends Model
|
||||
|
||||
public function canCreateEvent(): bool
|
||||
{
|
||||
$package = $this->activeResellerPackage()->first();
|
||||
if (!$package) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $package->canCreateEvent();
|
||||
return $this->hasEventAllowance();
|
||||
}
|
||||
|
||||
public function incrementUsedEvents(int $amount = 1): bool
|
||||
{
|
||||
$package = $this->activeResellerPackage()->first();
|
||||
if (!$package) {
|
||||
$package = $this->getActiveResellerPackage();
|
||||
if (! $package) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -108,6 +113,13 @@ class Tenant extends Model
|
||||
'note' => $note,
|
||||
]);
|
||||
|
||||
Log::info('Tenant credits incremented', [
|
||||
'tenant_id' => $this->id,
|
||||
'delta' => $amount,
|
||||
'reason' => $reason,
|
||||
'purchase_id' => $purchaseId,
|
||||
]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -130,9 +142,54 @@ class Tenant extends Model
|
||||
'note' => $note,
|
||||
]);
|
||||
|
||||
Log::info('Tenant credits decremented', [
|
||||
'tenant_id' => $this->id,
|
||||
'delta' => -$amount,
|
||||
'reason' => $reason,
|
||||
'purchase_id' => $purchaseId,
|
||||
]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function hasEventAllowance(): bool
|
||||
{
|
||||
$package = $this->getActiveResellerPackage();
|
||||
if ($package && $package->canCreateEvent()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (int) ($this->event_credits_balance ?? 0) > 0;
|
||||
}
|
||||
|
||||
public function consumeEventAllowance(int $amount = 1, string $reason = 'event.create', ?string $note = null): bool
|
||||
{
|
||||
$package = $this->getActiveResellerPackage();
|
||||
if ($package && $package->canCreateEvent()) {
|
||||
$package->increment('used_events', $amount);
|
||||
|
||||
Log::info('Tenant package usage recorded', [
|
||||
'tenant_id' => $this->id,
|
||||
'tenant_package_id' => $package->id,
|
||||
'used_events' => $package->used_events,
|
||||
'amount' => $amount,
|
||||
]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->decrementCredits($amount, $reason, $note);
|
||||
}
|
||||
|
||||
public function getActiveResellerPackage(): ?TenantPackage
|
||||
{
|
||||
return $this->activeResellerPackage()
|
||||
->whereHas('package', fn ($query) => $query->where('type', 'reseller'))
|
||||
->where('active', true)
|
||||
->orderByDesc('expires_at')
|
||||
->first();
|
||||
}
|
||||
|
||||
public function activeSubscription(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
|
||||
Reference in New Issue
Block a user