122 lines
3.9 KiB
PHP
122 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,
|
|
];
|
|
}
|
|
}
|