'integer', 'invoice_id' => 'integer', 'amount' => 'decimal:2', 'created_by' => 'integer', 'due_date' => 'date', ]; /* |-------------------------------------------------------------------------- | Relationships |-------------------------------------------------------------------------- */ public function parent() { return $this->belongsTo(User::class, 'parent_id'); } public function invoice() { return $this->belongsTo(Invoice::class, 'invoice_id'); } public function creator() { return $this->belongsTo(User::class, 'created_by'); } /* |-------------------------------------------------------------------------- | Custom Query Scopes (CI equivalent of byParentTerm) |-------------------------------------------------------------------------- */ public function scopeByParentTerm(Builder $query, int $parentId, string $year, string $semester, ?string $status = null) { $query->where('parent_id', $parentId) ->where('school_year', $year) ->where('semester', $semester); if ($status !== null) { $query->where('status', $status); } return $query->orderBy('id', 'DESC'); } /* |-------------------------------------------------------------------------- | Custom Methods |-------------------------------------------------------------------------- */ public function markApplied($ids, int $invoiceId): bool { $ids = is_array($ids) ? $ids : [$ids]; if (empty($ids)) { return true; } $ids = array_map('intval', $ids); return $this->whereIn('id', $ids) ->update([ 'status' => 'applied', 'invoice_id' => $invoiceId ]) >= 0; } /* |-------------------------------------------------------------------------- | Pagination Search (CI paginate alternative) |-------------------------------------------------------------------------- */ public function listAllForTerm( string $schoolYear, string $semester, ?string $status = null, ?string $q = null, int $perPage = 50, bool $fallbackToYear = true ) { $build = function (?string $semesterFilter) use ($schoolYear, $status, $q) { $query = self::query() ->select('additional_charges.*') ->selectRaw("CONCAT(COALESCE(users.lastname,''), ', ', COALESCE(users.firstname,'')) AS parent_name") ->selectRaw('invoices.invoice_number') ->leftJoin('users', 'users.id', '=', 'additional_charges.parent_id') ->leftJoin('invoices', 'invoices.id', '=', 'additional_charges.invoice_id') ->where('additional_charges.school_year', $schoolYear); if ($semesterFilter !== null && $semesterFilter !== '') { $query->where('additional_charges.semester', $semesterFilter); } if (!empty($status)) { $query->where('additional_charges.status', $status); } if (!empty($q)) { $query->where(function ($sub) use ($q) { $sub->where('additional_charges.title', 'like', "%$q%") ->orWhere('additional_charges.description', 'like', "%$q%") ->orWhere('users.firstname', 'like', "%$q%") ->orWhere('users.lastname', 'like', "%$q%") ->orWhere('invoices.invoice_number', 'like', "%$q%"); }); } return $query; }; $result = $build($semester) ->orderBy('additional_charges.id', 'DESC') ->paginate($perPage); if ($fallbackToYear && $result->count() === 0 && $semester !== '') { $result = $build(null) ->orderBy('additional_charges.id', 'DESC') ->paginate($perPage); } return $result; } }