AppointmentGuideService.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. <?php
  2. namespace App\Services;
  3. use App\Enums\AppointmentStatusEnum;
  4. use App\Models\Appointment;
  5. use App\Models\CompanySetting;
  6. use Barryvdh\DomPDF\Facade\Pdf;
  7. use Barryvdh\DomPDF\PDF as PdfWrapper;
  8. use Carbon\Carbon;
  9. class AppointmentGuideService
  10. {
  11. private const DEFAULT_VALIDITY_DAYS = 30;
  12. public function canIssue(Appointment $appointment): bool
  13. {
  14. return in_array($appointment->status, [
  15. AppointmentStatusEnum::CONFIRMADO,
  16. AppointmentStatusEnum::CONCLUIDO,
  17. ], true)
  18. && $appointment->date !== null
  19. && $appointment->time !== null;
  20. }
  21. public function issue(Appointment $appointment, ?int $issuedByUserId = null): Appointment
  22. {
  23. if ($appointment->guide_issued_at) {
  24. return $appointment;
  25. }
  26. $appointment->update([
  27. 'guide_issued_at' => now(),
  28. 'guide_valid_until' => now()->addDays($this->validityDays())->toDateString(),
  29. 'guide_issued_by_user_id' => $issuedByUserId,
  30. 'service_price' => $appointment->service_price ?? $this->servicePrice($appointment),
  31. ]);
  32. return $appointment->fresh(['user', 'userDependent', 'partnerAgreement', 'partnerAgreementService']);
  33. }
  34. public function pdf(Appointment $appointment, ?int $issuedByUserId = null): PdfWrapper
  35. {
  36. $appointment = $this->issue($appointment, $issuedByUserId);
  37. return Pdf::loadView('pdf.appointment_guide', ['guide' => $this->data($appointment)])
  38. ->setPaper('a4');
  39. }
  40. public function fileName(Appointment $appointment): string
  41. {
  42. return "guia_{$appointment->order_number}.pdf";
  43. }
  44. /**
  45. * @return array<string, string|null>
  46. */
  47. public function data(Appointment $appointment): array
  48. {
  49. $price = $appointment->service_price ?? $this->servicePrice($appointment);
  50. return [
  51. 'order_number' => $appointment->order_number,
  52. 'holder_name' => $appointment->user?->name,
  53. 'holder_badge' => $appointment->user?->registration,
  54. 'dependent_name' => $appointment->userDependent?->name,
  55. // O nome do médico está embutido no nome do serviço cadastrado no convênio.
  56. 'doctor_name' => $appointment->partnerAgreementService?->name,
  57. 'clinic_name' => $appointment->partnerAgreement?->company_name,
  58. 'clinic_address' => $this->clinicAddress($appointment),
  59. 'clinic_phone' => $appointment->partnerAgreement?->phone,
  60. 'date' => $appointment->date?->format('d/m/Y'),
  61. 'time' => $appointment->time ? Carbon::parse($appointment->time)->format('H:i') : null,
  62. 'issued_at' => $appointment->guide_issued_at?->format('d/m/Y'),
  63. 'valid_until' => $appointment->guide_valid_until?->format('d/m/Y'),
  64. 'price' => $price !== null ? 'R$ ' . number_format((float) $price, 2, ',', '.') : null,
  65. 'observations' => $appointment->observations,
  66. ];
  67. }
  68. private function servicePrice(Appointment $appointment): ?string
  69. {
  70. $service = $appointment->partnerAgreementService;
  71. return $service?->associate_price ?? $service?->price;
  72. }
  73. private function clinicAddress(Appointment $appointment): ?string
  74. {
  75. $partner = $appointment->partnerAgreement;
  76. if (!$partner) {
  77. return null;
  78. }
  79. $parts = array_filter([$partner->address, $partner->neighborhood]);
  80. return $parts ? implode(' - ', $parts) : null;
  81. }
  82. private function validityDays(): int
  83. {
  84. $days = (int) (CompanySetting::query()->value('guide_validity_days') ?? 0);
  85. return $days > 0 ? $days : self::DEFAULT_VALIDITY_DAYS;
  86. }
  87. }