120 lines
4.1 KiB
PHP
120 lines
4.1 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api\V1\Qr;
|
|
|
|
use App\Http\Controllers\Api\V1\ApiController;
|
|
use App\Http\Resources\QrCodeResource;
|
|
use App\Models\Household;
|
|
use App\Models\QrCode;
|
|
use App\Services\Qr\QrAllocator;
|
|
use App\States\QrCode\Active;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
|
|
class MyQrCodeController extends ApiController
|
|
{
|
|
public function index(Request $request): JsonResponse
|
|
{
|
|
$request->validate([
|
|
'status' => ['nullable', 'in:unassigned,allocated,active,used,expired,voided'],
|
|
'per_page' => ['nullable', 'integer', 'min:1', 'max:100'],
|
|
]);
|
|
|
|
$household = Household::where('head_user_id', $request->user()->id)->first();
|
|
if (! $household) {
|
|
return $this->ok([], 'No household yet');
|
|
}
|
|
|
|
$perPage = (int) $request->input('per_page', 50);
|
|
|
|
$codes = QrCode::query()
|
|
->where('assigned_to_household_id', $household->id)
|
|
->when($request->filled('status'), fn ($q) => $q->where('status', $request->string('status')))
|
|
->orderByDesc('id')
|
|
->paginate($perPage);
|
|
|
|
return $this->ok(
|
|
QrCodeResource::collection($codes),
|
|
null,
|
|
[
|
|
'page' => $codes->currentPage(),
|
|
'per_page' => $codes->perPage(),
|
|
'total' => $codes->total(),
|
|
],
|
|
);
|
|
}
|
|
|
|
public function balance(Request $request): JsonResponse
|
|
{
|
|
$household = Household::where('head_user_id', $request->user()->id)->first();
|
|
if (! $household) {
|
|
return $this->ok([
|
|
'active' => 0, 'allocated' => 0, 'used' => 0, 'expired' => 0,
|
|
'low_balance' => false,
|
|
]);
|
|
}
|
|
|
|
$counts = QrCode::query()
|
|
->where('assigned_to_household_id', $household->id)
|
|
->selectRaw('status, COUNT(*) as count')
|
|
->groupBy('status')
|
|
->pluck('count', 'status')
|
|
->all();
|
|
|
|
$active = (int) ($counts['active'] ?? 0);
|
|
$threshold = (int) config('qr.low_balance_threshold', 5);
|
|
|
|
return $this->ok([
|
|
'active' => $active,
|
|
'allocated' => (int) ($counts['allocated'] ?? 0),
|
|
'used' => (int) ($counts['used'] ?? 0),
|
|
'expired' => (int) ($counts['expired'] ?? 0),
|
|
'low_balance' => $active <= $threshold,
|
|
'low_balance_threshold' => $threshold,
|
|
]);
|
|
}
|
|
|
|
public function activate(Request $request, QrCode $qrCode, QrAllocator $allocator): JsonResponse
|
|
{
|
|
$request->validate([
|
|
'activate_batch' => ['nullable', 'boolean'],
|
|
]);
|
|
|
|
$household = Household::where('head_user_id', $request->user()->id)->first();
|
|
if (! $household) {
|
|
return $this->forbidden('You must have an active household');
|
|
}
|
|
|
|
$activateBatch = $request->boolean('activate_batch');
|
|
|
|
if ($activateBatch) {
|
|
// Activate the whole batch
|
|
if (! $qrCode->batch_id) {
|
|
return $this->fail('This QR code does not belong to a batch', null, 422);
|
|
}
|
|
|
|
$activatedCount = $allocator->activateBatch($qrCode, $household);
|
|
if ($activatedCount === 0) {
|
|
return $this->fail('No unactivated codes found in this batch, or you do not have permission to activate this batch', null, 422);
|
|
}
|
|
|
|
return $this->ok(['activated_count' => $activatedCount], "Successfully activated $activatedCount QR codes in the batch");
|
|
}
|
|
|
|
// Single code activation
|
|
if ($qrCode->assigned_to_household_id !== $household->id) {
|
|
return $this->forbidden('This code is not assigned to your household');
|
|
}
|
|
|
|
if ($qrCode->status instanceof Active) {
|
|
return $this->ok(new QrCodeResource($qrCode), 'Code already active');
|
|
}
|
|
|
|
if (! $allocator->activate($qrCode)) {
|
|
return $this->fail('Code cannot be activated from its current state', null, 422);
|
|
}
|
|
|
|
return $this->ok(new QrCodeResource($qrCode->fresh()), 'Code activated');
|
|
}
|
|
}
|