Files
Verde-Web/app/Http/Controllers/Api/V1/Admin/BulkActionController.php

157 lines
5.3 KiB
PHP

<?php
namespace App\Http\Controllers\Api\V1\Admin;
use App\Events\HouseholdVerified;
use App\Http\Controllers\Api\V1\ApiController;
use App\Models\Household;
use App\Models\QrCode;
use App\Models\User;
use App\States\QrCode\Voided;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class BulkActionController extends ApiController
{
/**
* Approve N pending households in one shot. Per-id outcome reported
* back so the UI can show what worked and what didn't.
*/
public function approveHouseholds(Request $request): JsonResponse
{
$data = $request->validate([
'household_ids' => ['required', 'array', 'min:1', 'max:200'],
'household_ids.*' => ['string', 'exists:households,uuid'],
]);
$admin = $request->user();
$results = [];
foreach ($data['household_ids'] as $uuid) {
$h = Household::where('uuid', $uuid)->first();
if (! $h) {
$results[] = ['id' => $uuid, 'ok' => false, 'reason' => 'not_found'];
continue;
}
if ($h->verification_status === Household::VERIFICATION_APPROVED) {
$results[] = ['id' => $uuid, 'ok' => false, 'reason' => 'already_approved'];
continue;
}
if (! $h->proof_of_residency_path) {
$results[] = ['id' => $uuid, 'ok' => false, 'reason' => 'no_proof'];
continue;
}
DB::transaction(function () use ($h, $admin) {
$h->markVerified($admin);
});
HouseholdVerified::dispatch($h->fresh(), $admin);
$results[] = ['id' => $uuid, 'ok' => true];
}
$okCount = collect($results)->where('ok', true)->count();
return $this->ok([
'approved' => $okCount,
'rejected' => count($results) - $okCount,
'results' => $results,
], "Approved {$okCount} of ".count($results).' households');
}
public function suspendUsers(Request $request): JsonResponse
{
$data = $request->validate([
'user_ids' => ['required', 'array', 'min:1', 'max:200'],
'user_ids.*' => ['string', 'exists:users,uuid'],
]);
$results = [];
foreach ($data['user_ids'] as $uuid) {
$u = User::where('uuid', $uuid)->first();
if (! $u) {
$results[] = ['id' => $uuid, 'ok' => false, 'reason' => 'not_found'];
continue;
}
if ($u->role === User::ROLE_ADMIN) {
$results[] = ['id' => $uuid, 'ok' => false, 'reason' => 'admin_protected'];
continue;
}
$u->forceFill(['status' => User::STATUS_SUSPENDED])->save();
$results[] = ['id' => $uuid, 'ok' => true];
}
$okCount = collect($results)->where('ok', true)->count();
return $this->ok(['suspended' => $okCount, 'results' => $results], "Suspended {$okCount} users");
}
public function activateUsers(Request $request): JsonResponse
{
$data = $request->validate([
'user_ids' => ['required', 'array', 'min:1', 'max:200'],
'user_ids.*' => ['string', 'exists:users,uuid'],
]);
$results = [];
foreach ($data['user_ids'] as $uuid) {
$u = User::where('uuid', $uuid)->first();
if (! $u) {
$results[] = ['id' => $uuid, 'ok' => false, 'reason' => 'not_found'];
continue;
}
$u->forceFill(['status' => User::STATUS_ACTIVE])->save();
$results[] = ['id' => $uuid, 'ok' => true];
}
$okCount = collect($results)->where('ok', true)->count();
return $this->ok(['activated' => $okCount, 'results' => $results], "Activated {$okCount} users");
}
public function voidQrCodes(Request $request): JsonResponse
{
$data = $request->validate([
'serials' => ['required', 'array', 'min:1', 'max:500'],
'serials.*' => ['string'],
'reason' => ['required', 'string', 'min:3', 'max:500'],
]);
$admin = $request->user();
$results = [];
foreach ($data['serials'] as $serial) {
$code = QrCode::where('serial', $serial)->first();
if (! $code) {
$results[] = ['serial' => $serial, 'ok' => false, 'reason' => 'not_found'];
continue;
}
if (! $code->status->canTransitionTo(Voided::class)) {
$results[] = ['serial' => $serial, 'ok' => false, 'reason' => 'cannot_void_from_'.(string) $code->status];
continue;
}
$code->status->transitionTo(Voided::class);
$code->forceFill([
'metadata' => array_merge($code->metadata ?? [], [
'voided_at' => now()->toIso8601String(),
'voided_by_admin_id' => $admin->id,
'void_reason' => $data['reason'],
]),
])->save();
$results[] = ['serial' => $serial, 'ok' => true];
}
$okCount = collect($results)->where('ok', true)->count();
return $this->ok(['voided' => $okCount, 'results' => $results], "Voided {$okCount} codes");
}
}