84 lines
3.1 KiB
PHP
84 lines
3.1 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Refunds;
|
|
|
|
use App\Models\Refund;
|
|
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class RefundQueryService
|
|
{
|
|
public function list(array $filters): array
|
|
{
|
|
$perPage = (int) ($filters['per_page'] ?? 25);
|
|
$page = (int) ($filters['page'] ?? 1);
|
|
$sortBy = (string) ($filters['sort_by'] ?? 'created_at');
|
|
$sortDir = strtolower((string) ($filters['sort_dir'] ?? 'desc')) === 'asc' ? 'asc' : 'desc';
|
|
|
|
$allowedSorts = ['created_at', 'updated_at', 'refund_amount', 'status', 'parent_id', 'invoice_id'];
|
|
if (!in_array($sortBy, $allowedSorts, true)) {
|
|
$sortBy = 'created_at';
|
|
}
|
|
|
|
$query = Refund::query()
|
|
->select([
|
|
'refunds.*',
|
|
DB::raw("CONCAT(COALESCE(parents.lastname, ''), ', ', COALESCE(parents.firstname, '')) AS parent_name"),
|
|
DB::raw("CONCAT(COALESCE(approvers.lastname, ''), ', ', COALESCE(approvers.firstname, '')) AS approved_by_name"),
|
|
])
|
|
->leftJoin('users as parents', 'parents.id', '=', 'refunds.parent_id')
|
|
->leftJoin('users as approvers', 'approvers.id', '=', 'refunds.approved_by');
|
|
|
|
if (!empty($filters['status'])) {
|
|
$query->where('refunds.status', $filters['status']);
|
|
}
|
|
if (!empty($filters['request'])) {
|
|
$query->where('refunds.request', $filters['request']);
|
|
}
|
|
if (!empty($filters['parent_id'])) {
|
|
$query->where('refunds.parent_id', (int) $filters['parent_id']);
|
|
}
|
|
if (!empty($filters['invoice_id'])) {
|
|
$query->where('refunds.invoice_id', (int) $filters['invoice_id']);
|
|
}
|
|
if (!empty($filters['school_year'])) {
|
|
$query->where('refunds.school_year', (string) $filters['school_year']);
|
|
}
|
|
if (!empty($filters['semester'])) {
|
|
$query->where('refunds.semester', (string) $filters['semester']);
|
|
}
|
|
if (!empty($filters['q'])) {
|
|
$term = trim((string) $filters['q']);
|
|
$query->where(function ($where) use ($term) {
|
|
$where->where('refunds.reason', 'like', "%{$term}%")
|
|
->orWhere('refunds.note', 'like', "%{$term}%")
|
|
->orWhere('parents.firstname', 'like', "%{$term}%")
|
|
->orWhere('parents.lastname', 'like', "%{$term}%");
|
|
});
|
|
}
|
|
|
|
$paginator = $query->orderBy('refunds.' . $sortBy, $sortDir)
|
|
->paginate($perPage, ['*'], 'page', $page);
|
|
|
|
return [
|
|
'refunds' => $paginator,
|
|
'pagination' => $this->paginationPayload($paginator),
|
|
];
|
|
}
|
|
|
|
public function find(int $refundId): ?Refund
|
|
{
|
|
return Refund::query()->find($refundId);
|
|
}
|
|
|
|
private function paginationPayload(LengthAwarePaginator $paginator): array
|
|
{
|
|
return [
|
|
'current_page' => $paginator->currentPage(),
|
|
'per_page' => $paginator->perPage(),
|
|
'total' => $paginator->total(),
|
|
'total_pages' => $paginator->lastPage(),
|
|
];
|
|
}
|
|
}
|