| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- <?php
- namespace App\Services;
- use App\Models\StudentContractInstallment;
- use Carbon\Carbon;
- use Illuminate\Database\Eloquent\Collection;
- use Illuminate\Validation\ValidationException;
- /**
- * Contas a Receber da unidade.
- *
- * Decisão de modelagem (A): as parcelas de contrato de aluno
- * (student_contract_installments) SÃO a Contas a Receber de alunos da unidade.
- * A baixa é manual aqui; quando houver Asaas na unidade, a baixa também chega
- * pelo webhook (ramo STU_).
- */
- class UnitReceivableService
- {
- public function list(int $unitId, array $filters = []): Collection
- {
- return StudentContractInstallment::with(['student'])
- ->where('unit_id', $unitId)
- ->when(
- isset($filters['status']),
- fn ($q) => $q->where('status', $filters['status']),
- )
- ->when(
- isset($filters['student_id']),
- fn ($q) => $q->where('student_id', $filters['student_id']),
- )
- ->when(
- isset($filters['type']),
- fn ($q) => $q->where('type', $filters['type']),
- )
- ->orderBy('due_date')
- ->orderBy('installment_number')
- ->get();
- }
- public function findForUnit(int $id, int $unitId): ?StudentContractInstallment
- {
- return StudentContractInstallment::where('id', $id)
- ->where('unit_id', $unitId)
- ->first();
- }
- /**
- * Baixa manual: marca a parcela como paga.
- */
- public function settle(StudentContractInstallment $installment, array $data): StudentContractInstallment
- {
- if ($installment->status === 'paid') {
- throw ValidationException::withMessages([
- 'status' => 'Esta parcela já está paga.',
- ]);
- }
- if ($installment->status === 'cancelled') {
- throw ValidationException::withMessages([
- 'status' => 'Esta parcela está cancelada e não pode receber baixa.',
- ]);
- }
- $discount = isset($data['discount']) ? (float) $data['discount'] : (float) $installment->discount;
- $fine = isset($data['fine']) ? (float) $data['fine'] : (float) $installment->fine;
- $paidValue = isset($data['paid_value'])
- ? (float) $data['paid_value']
- : round((float) $installment->value - $discount + $fine, 2);
- $installment->update([
- 'status' => 'paid',
- 'discount' => $discount,
- 'fine' => $fine,
- 'paid_value' => $paidValue,
- 'payment_date' => $data['payment_date'] ?? Carbon::today()->format('Y-m-d'),
- ]);
- return $installment->fresh(['student']);
- }
- /**
- * Reabre uma parcela paga (estorno da baixa manual).
- */
- public function reopen(StudentContractInstallment $installment): StudentContractInstallment
- {
- if ($installment->status !== 'paid') {
- throw ValidationException::withMessages([
- 'status' => 'Só é possível reabrir parcelas que estão pagas.',
- ]);
- }
- $installment->update([
- 'status' => 'pending',
- 'paid_value' => 0,
- 'payment_date' => null,
- ]);
- return $installment->fresh(['student']);
- }
- }
|