| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- <?php
- namespace App\Services;
- use App\Enums\AppointmentStatusEnum;
- use App\Models\Appointment;
- use App\Models\CompanySetting;
- use Barryvdh\DomPDF\Facade\Pdf;
- use Barryvdh\DomPDF\PDF as PdfWrapper;
- use Carbon\Carbon;
- class AppointmentGuideService
- {
- private const DEFAULT_VALIDITY_DAYS = 30;
- public function canIssue(Appointment $appointment): bool
- {
- return in_array($appointment->status, [
- AppointmentStatusEnum::CONFIRMADO,
- AppointmentStatusEnum::CONCLUIDO,
- ], true)
- && $appointment->date !== null
- && $appointment->time !== null;
- }
- public function issue(Appointment $appointment, ?int $issuedByUserId = null): Appointment
- {
- if ($appointment->guide_issued_at) {
- return $appointment;
- }
- $appointment->update([
- 'guide_issued_at' => now(),
- 'guide_valid_until' => now()->addDays($this->validityDays())->toDateString(),
- 'guide_issued_by_user_id' => $issuedByUserId,
- 'service_price' => $appointment->service_price ?? $this->servicePrice($appointment),
- ]);
- return $appointment->fresh(['user', 'userDependent', 'partnerAgreement', 'partnerAgreementService']);
- }
- public function pdf(Appointment $appointment, ?int $issuedByUserId = null): PdfWrapper
- {
- $appointment = $this->issue($appointment, $issuedByUserId);
- return Pdf::loadView('pdf.appointment_guide', ['guide' => $this->data($appointment)])
- ->setPaper('a4');
- }
- public function fileName(Appointment $appointment): string
- {
- return "guia_{$appointment->order_number}.pdf";
- }
- /**
- * @return array<string, string|null>
- */
- public function data(Appointment $appointment): array
- {
- $price = $appointment->service_price ?? $this->servicePrice($appointment);
- return [
- 'order_number' => $appointment->order_number,
- 'holder_name' => $appointment->user?->name,
- 'holder_badge' => $appointment->user?->registration,
- 'dependent_name' => $appointment->userDependent?->name,
- // O nome do médico está embutido no nome do serviço cadastrado no convênio.
- 'doctor_name' => $appointment->partnerAgreementService?->name,
- 'clinic_name' => $appointment->partnerAgreement?->company_name,
- 'clinic_address' => $this->clinicAddress($appointment),
- 'clinic_phone' => $appointment->partnerAgreement?->phone,
- 'date' => $appointment->date?->format('d/m/Y'),
- 'time' => $appointment->time ? Carbon::parse($appointment->time)->format('H:i') : null,
- 'issued_at' => $appointment->guide_issued_at?->format('d/m/Y'),
- 'valid_until' => $appointment->guide_valid_until?->format('d/m/Y'),
- 'price' => $price !== null ? 'R$ ' . number_format((float) $price, 2, ',', '.') : null,
- 'observations' => $appointment->observations,
- ];
- }
- private function servicePrice(Appointment $appointment): ?string
- {
- $service = $appointment->partnerAgreementService;
- return $service?->associate_price ?? $service?->price;
- }
- private function clinicAddress(Appointment $appointment): ?string
- {
- $partner = $appointment->partnerAgreement;
- if (!$partner) {
- return null;
- }
- $parts = array_filter([$partner->address, $partner->neighborhood]);
- return $parts ? implode(' - ', $parts) : null;
- }
- private function validityDays(): int
- {
- $days = (int) (CompanySetting::query()->value('guide_validity_days') ?? 0);
- return $days > 0 ? $days : self::DEFAULT_VALIDITY_DAYS;
- }
- }
|