UnitAccountPayableService.php 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. <?php
  2. namespace App\Services;
  3. use App\Models\UnitAccountPayable;
  4. use Carbon\Carbon;
  5. use Illuminate\Database\Eloquent\Collection;
  6. use Illuminate\Validation\ValidationException;
  7. /**
  8. * Contas a Pagar da unidade.
  9. *
  10. * Registros com origin='tbr' são criados automaticamente quando a matriz gera a
  11. * cobrança do TBR (espelho da dívida). Registros avulsos usam origin='manual'.
  12. * A baixa é manual (Asaas não cobra a unidade de si mesma).
  13. */
  14. class UnitAccountPayableService
  15. {
  16. public function list(int $unitId, array $filters = []): Collection
  17. {
  18. return UnitAccountPayable::with('franchiseeAccountReceive')
  19. ->where('unit_id', $unitId)
  20. ->when(
  21. isset($filters['status']),
  22. fn ($q) => $q->where('status', $filters['status']),
  23. )
  24. ->when(
  25. isset($filters['origin']),
  26. fn ($q) => $q->where('origin', $filters['origin']),
  27. )
  28. ->orderBy('due_date')
  29. ->get();
  30. }
  31. public function findForUnit(int $id, int $unitId): ?UnitAccountPayable
  32. {
  33. return UnitAccountPayable::where('id', $id)
  34. ->where('unit_id', $unitId)
  35. ->first();
  36. }
  37. public function createManual(int $unitId, array $data): UnitAccountPayable
  38. {
  39. return UnitAccountPayable::create([
  40. 'unit_id' => $unitId,
  41. 'origin' => UnitAccountPayable::ORIGIN_MANUAL,
  42. 'history' => $data['history'],
  43. 'value' => $data['value'],
  44. 'due_date' => $data['due_date'],
  45. 'obs' => $data['obs'] ?? null,
  46. 'paid_value' => 0,
  47. 'discount' => 0,
  48. 'fine' => 0,
  49. 'status' => 'pending',
  50. ]);
  51. }
  52. /**
  53. * Baixa manual: marca a conta como paga.
  54. */
  55. public function settle(UnitAccountPayable $payable, array $data): UnitAccountPayable
  56. {
  57. if ($payable->status === 'paid') {
  58. throw ValidationException::withMessages([
  59. 'status' => 'Esta conta já está paga.',
  60. ]);
  61. }
  62. if ($payable->status === 'cancelled') {
  63. throw ValidationException::withMessages([
  64. 'status' => 'Esta conta está cancelada e não pode receber baixa.',
  65. ]);
  66. }
  67. $discount = isset($data['discount']) ? (float) $data['discount'] : (float) $payable->discount;
  68. $fine = isset($data['fine']) ? (float) $data['fine'] : (float) $payable->fine;
  69. $paidValue = isset($data['paid_value'])
  70. ? (float) $data['paid_value']
  71. : round((float) $payable->value - $discount + $fine, 2);
  72. $payable->update([
  73. 'status' => 'paid',
  74. 'discount' => $discount,
  75. 'fine' => $fine,
  76. 'paid_value' => $paidValue,
  77. 'payment_date' => $data['payment_date'] ?? Carbon::today()->format('Y-m-d'),
  78. ]);
  79. return $payable->fresh();
  80. }
  81. /**
  82. * Reabre uma conta paga (estorno da baixa manual).
  83. */
  84. public function reopen(UnitAccountPayable $payable): UnitAccountPayable
  85. {
  86. throw ValidationException::withMessages([
  87. 'status' => 'Uma conta paga não pode voltar para um status anterior.',
  88. ]);
  89. }
  90. }