status, [ AppointmentStatusEnum::CONFIRMADO, AppointmentStatusEnum::CONCLUIDO, ], true); if (!$released) { return false; } if ($appointment->isExame()) { return $appointment->exams->isNotEmpty(); } return $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', 'exams.partnerAgreementService', ]); } public function pdf(Appointment $appointment, ?int $issuedByUserId = null): PdfWrapper { $appointment = $this->issue($appointment, $issuedByUserId); $view = $appointment->isExame() ? 'pdf.appointment_exam_guide' : 'pdf.appointment_guide'; return Pdf::loadView($view, ['guide' => $this->data($appointment)]) ->setPaper('a4'); } public function fileName(Appointment $appointment): string { return "guia_{$appointment->order_number}.pdf"; } /** * @return array */ public function data(Appointment $appointment): array { $price = $appointment->service_price ?? $this->servicePrice($appointment); return [ 'order_number' => $appointment->order_number, 'type' => $appointment->type?->value, 'holder_name' => $appointment->user?->name, 'holder_badge' => $appointment->user?->registration, 'holder_cpf' => $appointment->user?->cpf, '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, 'exams' => $this->exams($appointment), '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' => $this->money($price), 'observations' => $appointment->observations, ]; } /** * @return array> */ private function exams(Appointment $appointment): array { if (!$appointment->isExame()) { return []; } return $appointment->exams ->map(fn($exam) => [ 'name' => $exam->partnerAgreementService?->name, 'price' => $this->money($exam->service_price), ]) ->all(); } private function money(string|float|null $value): ?string { return $value !== null ? 'R$ ' . number_format((float) $value, 2, ',', '.') : null; } private function servicePrice(Appointment $appointment): ?string { if ($appointment->isExame()) { return (string) $appointment->exams->sum(fn($exam) => (float) $exam->service_price); } $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; } }