137 lines
4.4 KiB
PHP
137 lines
4.4 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Tenant;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Resources\Tenant\CreditLedgerResource;
|
|
use App\Http\Resources\Tenant\EventPurchaseResource;
|
|
use App\Models\EventCreditsLedger;
|
|
use App\Models\EventPurchase;
|
|
use App\Models\Tenant;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Symfony\Component\HttpKernel\Exception\HttpException;
|
|
|
|
class CreditController extends Controller
|
|
{
|
|
public function balance(Request $request): JsonResponse
|
|
{
|
|
$tenant = $this->resolveTenant($request);
|
|
|
|
return response()->json([
|
|
'balance' => $tenant->event_credits_balance,
|
|
'free_event_granted_at' => $tenant->free_event_granted_at,
|
|
]);
|
|
}
|
|
|
|
public function ledger(Request $request)
|
|
{
|
|
$tenant = $this->resolveTenant($request);
|
|
|
|
$ledgers = EventCreditsLedger::where('tenant_id', $tenant->id)
|
|
->orderByDesc('created_at')
|
|
->paginate(20);
|
|
|
|
return CreditLedgerResource::collection($ledgers);
|
|
}
|
|
|
|
public function history(Request $request)
|
|
{
|
|
$tenant = $this->resolveTenant($request);
|
|
|
|
$purchases = EventPurchase::where('tenant_id', $tenant->id)
|
|
->orderByDesc('purchased_at')
|
|
->paginate(20);
|
|
|
|
return EventPurchaseResource::collection($purchases);
|
|
}
|
|
|
|
public function purchase(Request $request): JsonResponse
|
|
{
|
|
$tenant = $this->resolveTenant($request);
|
|
|
|
$data = $request->validate([
|
|
'package_id' => ['required', 'string', 'max:255'],
|
|
'credits_added' => ['required', 'integer', 'min:1'],
|
|
'platform' => ['nullable', 'string', 'max:32'],
|
|
'transaction_id' => ['nullable', 'string', 'max:255'],
|
|
'subscription_active' => ['sometimes', 'boolean'],
|
|
]);
|
|
|
|
$purchase = EventPurchase::create([
|
|
'tenant_id' => $tenant->id,
|
|
'events_purchased' => $data['credits_added'],
|
|
'amount' => 0,
|
|
'currency' => 'EUR',
|
|
'provider' => $data['platform'] ?? 'tenant-app',
|
|
'external_receipt_id' => $data['transaction_id'] ?? null,
|
|
'status' => 'completed',
|
|
'purchased_at' => now(),
|
|
]);
|
|
|
|
$note = 'Package: '.$data['package_id'];
|
|
$incremented = $tenant->incrementCredits($data['credits_added'], 'purchase', $note, $purchase->id);
|
|
|
|
if (! $incremented) {
|
|
throw new HttpException(500, 'Unable to record credit purchase');
|
|
}
|
|
|
|
if (array_key_exists('subscription_active', $data)) {
|
|
$tenant->update([
|
|
'subscription_tier' => $data['subscription_active'] ? 'pro' : $tenant->subscription_tier,
|
|
]);
|
|
}
|
|
|
|
$tenant->refresh();
|
|
|
|
return response()->json([
|
|
'message' => 'Purchase recorded',
|
|
'balance' => $tenant->event_credits_balance,
|
|
'subscription_active' => (bool) ($data['subscription_active'] ?? false),
|
|
], 201);
|
|
}
|
|
|
|
public function sync(Request $request): JsonResponse
|
|
{
|
|
$tenant = $this->resolveTenant($request);
|
|
|
|
$data = $request->validate([
|
|
'balance' => ['nullable', 'integer', 'min:0'],
|
|
'subscription_active' => ['sometimes', 'boolean'],
|
|
'last_sync' => ['nullable', 'date'],
|
|
]);
|
|
|
|
if (array_key_exists('subscription_active', $data)) {
|
|
$tenant->update([
|
|
'subscription_tier' => $data['subscription_active'] ? 'pro' : ($tenant->subscription_tier ?? 'free'),
|
|
]);
|
|
}
|
|
|
|
// Server remains source of truth for balance; echo current state back to client
|
|
return response()->json([
|
|
'balance' => $tenant->event_credits_balance,
|
|
'subscription_active' => (bool) ($tenant->active_subscription ?? false),
|
|
'server_time' => now()->toIso8601String(),
|
|
]);
|
|
}
|
|
|
|
private function resolveTenant(Request $request): Tenant
|
|
{
|
|
$user = $request->user();
|
|
if ($user && isset($user->tenant) && $user->tenant instanceof Tenant) {
|
|
return $user->tenant;
|
|
}
|
|
|
|
$tenantId = $request->attributes->get('tenant_id');
|
|
if (! $tenantId && $user && isset($user->tenant_id)) {
|
|
$tenantId = $user->tenant_id;
|
|
}
|
|
|
|
if (! $tenantId) {
|
|
throw new HttpException(401, 'Unauthenticated');
|
|
}
|
|
|
|
return Tenant::findOrFail($tenantId);
|
|
}
|
|
}
|