Files
alrahma_sunday_school_api/app/Services/Reimbursements/ReimbursementBatchAssignmentService.php
T
2026-06-09 01:25:14 -04:00

120 lines
3.9 KiB
PHP

<?php
namespace App\Services\Reimbursements;
use App\Models\ReimbursementBatch;
use App\Models\ReimbursementBatchItem;
use Illuminate\Support\Facades\Log;
use RuntimeException;
class ReimbursementBatchAssignmentService
{
public function __construct(private ReimbursementLookupService $lookupService) {}
public function updateAssignment(
int $expenseId,
int $batchId,
?int $adminId,
?int $reimbursementId,
string $schoolYear,
string $semester
): array {
if ($expenseId <= 0) {
throw new RuntimeException('Invalid expense id.');
}
$now = now();
$activeItem = ReimbursementBatchItem::query()
->where('expense_id', $expenseId)
->whereNull('unassigned_at')
->first();
if ($batchId <= 0) {
if ($activeItem) {
$activeItem->update(['unassigned_at' => $now]);
if (! $reimbursementId && ! empty($activeItem->reimbursement_id)) {
$reimbursementId = (int) $activeItem->reimbursement_id;
}
}
return [
'batch_id' => 0,
'admin_id' => null,
'reimbursement_id' => $reimbursementId,
];
}
$batch = ReimbursementBatch::query()->find($batchId);
if (! $batch || strtolower((string) $batch->status) !== ReimbursementBatch::STATUS_OPEN) {
throw new RuntimeException('Batch not found or already closed.');
}
$currentAdmin = $activeItem ? (int) ($activeItem->admin_id ?? 0) : null;
$activeSameBatch = $activeItem && (int) ($activeItem->batch_id ?? 0) === $batchId;
if ($activeSameBatch && ($currentAdmin === ($adminId ?? 0))) {
return [
'batch_id' => $batchId,
'admin_id' => $adminId,
'reimbursement_id' => $activeItem->reimbursement_id ?? null,
];
}
if ($activeSameBatch) {
if (! $reimbursementId) {
$reimbursementId = $activeItem->reimbursement_id
? (int) $activeItem->reimbursement_id
: $this->lookupService->findReimbursementIdForExpense($expenseId);
}
$activeItem->update([
'admin_id' => $adminId,
'assigned_at' => $now,
'reimbursement_id' => $reimbursementId,
'unassigned_at' => $adminId === null ? $now : null,
]);
return [
'batch_id' => $batchId,
'admin_id' => $adminId,
'reimbursement_id' => $reimbursementId,
];
}
if ($activeItem) {
$activeItem->update(['unassigned_at' => $now]);
if (! $reimbursementId && ! empty($activeItem->reimbursement_id)) {
$reimbursementId = (int) $activeItem->reimbursement_id;
}
}
if (! $reimbursementId) {
$reimbursementId = $this->lookupService->findReimbursementIdForExpense($expenseId);
}
try {
ReimbursementBatchItem::query()->create([
'batch_id' => $batchId,
'expense_id' => $expenseId,
'reimbursement_id' => $reimbursementId,
'admin_id' => $adminId,
'assigned_at' => $now,
'school_year' => $schoolYear,
'semester' => $semester,
]);
} catch (\Throwable $e) {
Log::error('Failed to assign expense to batch: '.$e->getMessage(), [
'expense_id' => $expenseId,
'batch_id' => $batchId,
]);
throw new RuntimeException('Unable to update batch assignment right now.');
}
return [
'batch_id' => $batchId,
'admin_id' => $adminId,
'reimbursement_id' => $reimbursementId,
];
}
}