| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- <?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
- {
- $released = in_array($appointment->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<string, mixed>
- */
- 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<int, array<string, string|null>>
- */
- 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;
- }
- }
|