Update partner packages, copy, and demo switcher
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled

This commit is contained in:
Codex Agent
2026-01-15 17:33:36 +01:00
parent 2f93271d94
commit ad829ae509
50 changed files with 1335 additions and 411 deletions

View File

@@ -277,13 +277,13 @@ class PackageController extends Controller
'purchased_at' => now(),
]);
} else {
// Reseller subscription
// Partner / reseller Event-Kontingent package
\App\Models\TenantPackage::create([
'tenant_id' => $tenant->id,
'package_id' => $package->id,
'price' => $package->price,
'purchased_at' => now(),
'expires_at' => now()->addYear(),
'expires_at' => null,
'active' => true,
]);
}

View File

@@ -99,6 +99,9 @@ class EventController extends Controller
$requestedPackageId = $isSuperAdmin ? $request->integer('package_id') : null;
unset($validated['package_id']);
$requestedServiceSlug = $request->input('service_package_slug');
$requestedServiceSlug = is_string($requestedServiceSlug) && $requestedServiceSlug !== '' ? $requestedServiceSlug : null;
unset($validated['service_package_slug']);
$tenantPackage = $tenant->tenantPackages()
->with('package')
@@ -116,6 +119,18 @@ class EventController extends Controller
$package = $this->resolveOwnerPackage();
}
$billingTenantPackage = null;
if (! $package) {
$billingTenantPackage = $requestedServiceSlug
? $tenant->getActiveResellerPackageFor($requestedServiceSlug)
: $tenant->getActiveResellerPackage();
if ($billingTenantPackage && $billingTenantPackage->package) {
$package = $billingTenantPackage->package;
$requestedServiceSlug = $requestedServiceSlug ?: $package->included_package_slug;
}
}
if (! $package && $tenantPackage) {
$package = $tenantPackage->package ?? Package::query()->find($tenantPackage->package_id);
}
@@ -126,6 +141,11 @@ class EventController extends Controller
]);
}
$billingIsReseller = $package->isReseller();
$eventServicePackage = $billingIsReseller
? $this->resolveResellerEventPackageForSlug($requestedServiceSlug ?: $package->included_package_slug)
: $package;
$requiresWaiver = $package->isEndcustomer();
$latestPurchase = $requiresWaiver ? $this->resolveLatestPackagePurchase($tenant, $package) : null;
$existingWaiver = $latestPurchase ? data_get($latestPurchase->metadata, 'consents.digital_content_waiver_at') : null;
@@ -161,8 +181,8 @@ class EventController extends Controller
unset($eventData['features']);
}
$settings['branding_allowed'] = $package->branding_allowed !== false;
$settings['watermark_allowed'] = $package->watermark_allowed !== false;
$settings['branding_allowed'] = $eventServicePackage->branding_allowed !== false;
$settings['watermark_allowed'] = $eventServicePackage->watermark_allowed !== false;
$eventData['settings'] = $settings;
@@ -190,21 +210,23 @@ class EventController extends Controller
$eventData = Arr::only($eventData, $allowed);
$event = DB::transaction(function () use ($tenant, $eventData, $package, $isSuperAdmin) {
$event = DB::transaction(function () use ($tenant, $eventData, $eventServicePackage, $billingIsReseller, $isSuperAdmin) {
$event = Event::create($eventData);
EventPackage::create([
'event_id' => $event->id,
'package_id' => $package->id,
'purchased_price' => $package->price,
'package_id' => $eventServicePackage->id,
'purchased_price' => $billingIsReseller ? 0 : $eventServicePackage->price,
'purchased_at' => now(),
'gallery_expires_at' => $package->gallery_days ? now()->addDays($package->gallery_days) : null,
'gallery_expires_at' => $eventServicePackage->gallery_days
? now()->addDays($eventServicePackage->gallery_days)
: null,
]);
if ($package->isReseller() && ! $isSuperAdmin) {
if ($billingIsReseller && ! $isSuperAdmin) {
$note = sprintf('Event #%d created (%s)', $event->id, $event->name);
if (! $tenant->consumeEventAllowance(1, 'event.create', $note)) {
if (! $tenant->consumeEventAllowanceFor($eventServicePackage->slug, 1, 'event.create', $note)) {
throw new HttpException(402, 'Insufficient package allowance.');
}
}
@@ -227,6 +249,47 @@ class EventController extends Controller
], 201);
}
private function resolveResellerDefaultEventPackage(): Package
{
return $this->resolveResellerEventPackageForSlug('standard');
}
private function resolveResellerEventPackageForSlug(?string $slug): Package
{
if (is_string($slug) && $slug !== '') {
$match = Package::query()
->where('type', 'endcustomer')
->where('slug', $slug)
->first();
if ($match) {
return $match;
}
}
$default = Package::query()
->where('type', 'endcustomer')
->where('slug', 'standard')
->first();
if ($default) {
return $default;
}
$fallback = Package::query()
->where('type', 'endcustomer')
->orderBy('price')
->first();
if (! $fallback) {
throw ValidationException::withMessages([
'package_id' => __('Aktuell ist kein Endkunden-Paket verfügbar. Bitte kontaktiere den Support.'),
]);
}
return $fallback;
}
private function resolveLatestPackagePurchase(Tenant $tenant, Package $package): ?PackagePurchase
{
return PackagePurchase::query()

View File

@@ -60,6 +60,7 @@ class TenantPackageController extends Controller
$pkg?->limits ?? [],
$this->buildUsageSnapshot($eventPackage),
[
'included_package_slug' => $pkg?->included_package_slug,
'branding_allowed' => $pkg?->branding_allowed,
'watermark_allowed' => $pkg?->watermark_allowed,
'features' => $pkg?->features ?? [],