From 2f84f43ae588bbc0a32709caf0cc96a3e77c056b Mon Sep 17 00:00:00 2001 From: Muhammad Fajar Date: Thu, 27 Oct 2022 14:37:12 +0700 Subject: [PATCH] api doctor detail --- .../Http/Controllers/Api/DoctorController.php | 31 ++-- .../Transformers/Dashboard/DoctorResource.php | 2 +- .../Dashboard/HospitalResource.php | 8 +- .../Linksehat/Transformers/DoctorResource.php | 10 +- .../Doctors/DoctorResourceDetail.php | 66 +++++++ app/Helpers/Helper.php | 170 +++++++++++++----- app/Models/Organization.php | 2 +- app/Models/Practice.php | 19 ++ app/Models/PractitionerRole.php | 33 ---- config/app.php | 4 +- .../2022_07_28_032235_create_icd_table.php | 6 +- 11 files changed, 245 insertions(+), 106 deletions(-) create mode 100644 Modules/Linksehat/Transformers/Doctors/DoctorResourceDetail.php diff --git a/Modules/Linksehat/Http/Controllers/Api/DoctorController.php b/Modules/Linksehat/Http/Controllers/Api/DoctorController.php index 70971780..cad318e6 100644 --- a/Modules/Linksehat/Http/Controllers/Api/DoctorController.php +++ b/Modules/Linksehat/Http/Controllers/Api/DoctorController.php @@ -5,12 +5,13 @@ namespace Modules\Linksehat\Http\Controllers\Api; use App\Helpers\Helper; use App\Models\Practitioner; use App\Models\PractitionerRole; +use App\Models\PractitionerRoleAvailability; use DB; use Illuminate\Contracts\Support\Renderable; use Illuminate\Http\Request; use Illuminate\Routing\Controller; use Modules\Linksehat\Transformers\DoctorResource; -use Modules\Linksehat\Transformers\PractitionerRoleToDoctorDetailResource; +use Modules\Linksehat\Transformers\Doctors\DoctorResourceDetail; use Modules\Linksehat\Transformers\PractitionerRoleToDoctorResource; class DoctorController extends Controller @@ -92,27 +93,23 @@ class DoctorController extends Controller */ public function show(Request $request, $id) { - $doctor = Practitioner::query() + $queryDoctor = PractitionerRole::query() ->with([ - 'practitionerRoles', - 'practitionerRoles.metas', - 'practitionerRoles.speciality', - 'practitionerRoles.organization' => function ($query) { - $query->leftJoin('addresses', function ($q) { - $q->on('organizations.main_address_id', '=', 'addresses.id'); - $q->where('addresses.addressable_type', '=', Organization::class); - }); - }, - 'practitionerRoles.practices', - 'practitionerRoles.availabilities', - 'person', - 'metas', + 'practitioner', + 'speciality', + 'practices.prices' ]) ->findOrFail($id); - // return $doctor; + $queryAvailables = PractitionerRoleAvailability::query()->with(['days' => function ($query) { + $query->select(['availability_id', 'day']); + }])->where('practitioner_role_id', $id)->get(['id', 'start_time']); - return response()->json(DoctorResource::make($doctor)); + // return $queryDoctor; + $doctor = DoctorResourceDetail::make($queryDoctor); + $doctor['day_available'] = Helper::dailyAvailabilities($queryAvailables); + // return $doctor; + return response()->json(compact('doctor')); } /** diff --git a/Modules/Linksehat/Transformers/Dashboard/DoctorResource.php b/Modules/Linksehat/Transformers/Dashboard/DoctorResource.php index f7305833..92d81465 100644 --- a/Modules/Linksehat/Transformers/Dashboard/DoctorResource.php +++ b/Modules/Linksehat/Transformers/Dashboard/DoctorResource.php @@ -17,7 +17,7 @@ class DoctorResource extends JsonResource return [ 'id' => $this->practitioner->person->id, 'name' => $this->practitioner->person->name, - 'specialis' => $this->speciality->name, + 'specialis' => "Spesialis " . $this->speciality->name, 'photos' => [ 'title' => 'doctors-avatar-' . $this->id, 'url' => asset('images/default-doctor-avatar.png') diff --git a/Modules/Linksehat/Transformers/Dashboard/HospitalResource.php b/Modules/Linksehat/Transformers/Dashboard/HospitalResource.php index 68b21bd6..bdcdcbdf 100644 --- a/Modules/Linksehat/Transformers/Dashboard/HospitalResource.php +++ b/Modules/Linksehat/Transformers/Dashboard/HospitalResource.php @@ -15,10 +15,16 @@ class HospitalResource extends JsonResource */ public function toArray($request) { + if (empty($this->distance)) { + $address = $this->currentAddress->text; + } else { + $address = $this->currentAddress; + } + return [ 'id' => $this->id, 'name' => $this->name, - 'address' => $this->currentAddress->text ?? null, + 'address' => $address ?? null, 'distance' => $this->distance ? ($this->distance < 1 ? round($this->distance * 1000, 2) . " m" : round($this->distance, 2) . " km") : null, 'photos' => [ 'title' => Str::slug($this->name), diff --git a/Modules/Linksehat/Transformers/DoctorResource.php b/Modules/Linksehat/Transformers/DoctorResource.php index 9dd06382..1bbd951e 100644 --- a/Modules/Linksehat/Transformers/DoctorResource.php +++ b/Modules/Linksehat/Transformers/DoctorResource.php @@ -25,7 +25,7 @@ class DoctorResource extends JsonResource // 'speciality' => SpecialityResource::make($practitionerRole->speciality), // 'str' => '3121100888826697', // 'sip' => '73/B.16/31.71.05.1003.01.015.S.2/4/-1.779.3/e/2020', - + // 'is_chat_available' => $practitionerRole->is_chat_available, // 'is_video_available' => $practitionerRole->is_video_available, // 'is_walkin_available' => $practitionerRole->is_walkin_available, @@ -52,7 +52,7 @@ class DoctorResource extends JsonResource // 'hospital' => HospitalResource::make($practitionerRole->organization), // 'str' => '3121100888826697', // 'sip' => '73/B.16/31.71.05.1003.01.015.S.2/4/-1.779.3/e/2020', - + // 'is_chat_available' => $practitionerRole->is_chat_available, // 'is_video_available' => $practitionerRole->is_video_available, // 'is_walkin_available' => $practitionerRole->is_walkin_available, @@ -61,7 +61,7 @@ class DoctorResource extends JsonResource $hospitals[$practitionerRole->organization_id]['id'] = $practitionerRole->hospital_id; - $hospitals[$practitionerRole->organization_id]['code'] = $practitionerRole->organization->code; + // $hospitals[$practitionerRole->organization_id]['code'] = $practitionerRole->organization->code; $hospitals[$practitionerRole->organization_id]['name'] = $practitionerRole->organization->name; $hospitals[$practitionerRole->organization_id]['description'] = $practitionerRole->organization->description; $hospitals[$practitionerRole->organization_id]['address'] = $practitionerRole->organization->currentAddress->text; @@ -81,7 +81,7 @@ class DoctorResource extends JsonResource 'speciality' => SpecialityResource::make($practitionerRole->speciality), 'str' => '3121100888826697', 'sip' => '73/B.16/31.71.05.1003.01.015.S.2/4/-1.779.3/e/2020', - + 'is_chat_available' => $practitionerRole->is_chat_available, 'is_video_available' => $practitionerRole->is_video_available, 'is_walkin_available' => $practitionerRole->is_walkin_available, @@ -110,7 +110,7 @@ class DoctorResource extends JsonResource 'name_suffix' => $this->person->name_suffix ?? null, 'gender' => $this->person->gender ?? null, 'is_online' => false, - 'is_insurance_covered' => rand(0,1) == 1, + 'is_insurance_covered' => rand(0, 1) == 1, 'price_range' => 'Rp 100.000 - Rp 350.000', 'price_start' => '100000', 'price_end' => '350000', diff --git a/Modules/Linksehat/Transformers/Doctors/DoctorResourceDetail.php b/Modules/Linksehat/Transformers/Doctors/DoctorResourceDetail.php new file mode 100644 index 00000000..8890da13 --- /dev/null +++ b/Modules/Linksehat/Transformers/Doctors/DoctorResourceDetail.php @@ -0,0 +1,66 @@ +practices as $practice) { + $prices[$practice->service_code] = Helper::currencyIdrFormat($practice->price); + } + + $award[] = explode("\n", $this->practitioner->meta->award); + $education[] = explode("\n", $this->practitioner->meta->education); + + $queryHospitals = Organization::query() + ->without('meta') + ->where('organizations.type', 'hospital') + ->leftJoin('addresses', function ($q) { + $q->on('organizations.main_address_id', '=', 'addresses.id'); + $q->where('addresses.addressable_type', '=', Organization::class); + }); + if ($request->has('lat') && !empty($request->lat) && $request->has('lng') && !empty($request->lng)) { + $queryHospitals = $queryHospitals->selectRaw("organizations.*, addresses.text AS currentAddress, 6371 * acos (cos ( radians($request->lat) ) * cos( radians( addresses.lat ) ) * cos( radians( addresses.lng ) - radians($request->lng) ) + sin ( radians($request->lat) ) * sin( radians( addresses.lat ) )) as distance")->orderBy('distance', 'ASC'); + } + $queryHospitals = $queryHospitals->orderBy('organizations.name', 'asc')->where('organizations.id', $this->organization_id)->get(); + + return [ + 'name' => $this->practitioner->person->full_name, + 'length_of_work_year' => rand(1, 20), + 'price' => $prices, + 'rating' => rand(50, 100), + 'photos' => [ + 'title' => 'doctor-avatar-' . $this->practitioner->person->id, + 'url' => asset('images/default-doctor-avatar.png') + ], + 'spesialis' => [ + [ + 'name' => 'Spesialis ' . $this->speciality->name, + 'str' => random_int(1000000000000000, 5000000000000000) + ], + ], + 'award' => $award, + 'education' => $education, + 'location_practect' => HospitalResource::collection($queryHospitals), + 'available' => [ + 'is_chat_available' => $this->is_chat_available, + 'is_video_available' => $this->is_video_available, + 'is_walkin_available' => $this->is_walkin_available, + 'is_instant_chat_available' => $this->is_instant_chat_available, + 'day_available' => $this->day_available + ] + ]; + } +} diff --git a/app/Helpers/Helper.php b/app/Helpers/Helper.php index 2caf886e..85f56d8c 100644 --- a/app/Helpers/Helper.php +++ b/app/Helpers/Helper.php @@ -4,63 +4,147 @@ namespace App\Helpers; use Carbon\Carbon; use Carbon\CarbonPeriod; -use Illuminate\Support\Collection; -class Helper{ +class Helper +{ public static function genderNormalization($anyGenderCode) { - if ($anyGenderCode == 'M') { - return 'male'; - } else if ($anyGenderCode == 'F') { - return 'female'; - } else if ($anyGenderCode == 'O') { - return 'others'; - } else if ($anyGenderCode == 'U') { - return 'unknown'; - } else { - return null; - } + if ($anyGenderCode == 'M') { + return 'male'; + } else if ($anyGenderCode == 'F') { + return 'female'; + } else if ($anyGenderCode == 'O') { + return 'others'; + } else if ($anyGenderCode == 'U') { + return 'unknown'; + } else { + return null; + } } public static function paginateResources($resource) { - return [ - 'current_page' => $resource->currentPage(), - 'data' => $resource->items(), - 'first_page_url' => '', - 'from' => $resource->firstItem(), - 'last_page' => $resource->lastPage(), - 'last_page_url' => '', - 'links' => $resource->links(null, $resource->items()), - 'next_page_url' => $resource->nextPageUrl(), - ]; + return [ + 'current_page' => $resource->currentPage(), + 'data' => $resource->items(), + 'first_page_url' => '', + 'from' => $resource->firstItem(), + 'last_page' => $resource->lastPage(), + 'last_page_url' => '', + 'links' => $resource->links(null, $resource->items()), + 'next_page_url' => $resource->nextPageUrl(), + ]; } - public static function dailyAvailabilitiesToDate($dailyAvailabilities, $startDate, $endDate = null) { - - Carbon::setLocale('id'); + public static function dailyAvailabilitiesToDate($dailyAvailabilities, $startDate, $endDate = null) + { - $startDate = Carbon::parse($startDate); - if ( empty($endDate) ) { - $endDate = $startDate; - } else { - $endDate = Carbon::parse($endDate); - } - $ranges = CarbonPeriod::create($startDate, $endDate); + Carbon::setLocale('id'); - $datesAvailabilities = []; - foreach ( $ranges as $date ) { - - $datesAvailabilities[] = [ - 'date' => $date->format('Y-m-d'), - 'day' => $date->dayName, - 'slot' => $dailyAvailabilities[$date->dayName], - 'timezone' => 'WIB' + $startDate = Carbon::parse($startDate); + if (empty($endDate)) { + $endDate = $startDate; + } else { + $endDate = Carbon::parse($endDate); + } + $ranges = CarbonPeriod::create($startDate, $endDate); + + $datesAvailabilities = []; + foreach ($ranges as $date) { + + $datesAvailabilities[] = [ + 'date' => $date->format('Y-m-d'), + 'day' => $date->dayName, + 'slot' => $dailyAvailabilities[$date->dayName], + 'timezone' => 'WIB' + ]; + } + + return $datesAvailabilities; + } + + public static function dailyAvailabilities($availabilities) + { + $hours = [ + 'Pagi' => [], + 'Siang' => [], + 'Sore' => [], + 'Petang' => [], + 'Malam' => [] ]; - } + foreach ($availabilities as $availability) { + $time = explode(':', $availability->start_time); - return $datesAvailabilities; + if (count($availability->days)) { + foreach ($availability->days as $key => $day) { + $periods = CarbonPeriod::create(now(), now()->lastOfMonth()->addDays(1)) + ->filter(function (Carbon $date) use ($day) { + switch ($day->day) { + case 'Senin': + return $date->isMonday(); + break; + case 'Selasa': + return $date->isTuesday(); + break; + case 'Rabu': + return $date->isWednesday(); + break; + case 'Kamis': + return $date->isThursday(); + break; + case 'Jumat': + return $date->isFriday(); + break; + case 'Sabtu': + return $date->isSaturday(); + break; + case 'Minggu': + return $date->isSunday(); + break; + } + })->toArray(); + } + foreach ($periods as $day) { + foreach ($hours as $hour => $value) { + if (Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp >= Carbon::createFromTime(05, 00, 00)->timestamp && Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp <= Carbon::createFromTime(10, 59, 00)->timestamp && $hour === "Pagi") { + $schedules[Carbon::create($day)->day][$hour][] = substr($availability->start_time, 0, -3); + } elseif (Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp >= Carbon::createFromTime(11, 00, 00)->timestamp && Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp <= Carbon::createFromTime(15, 00, 00)->timestamp && $hour === "Siang") { + $schedules[Carbon::create($day)->day][$hour][] = substr($availability->start_time, 0, -3); + } elseif (Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp >= Carbon::createFromTime(15, 01, 00)->timestamp && Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp <= Carbon::createFromTime(18, 00, 00)->timestamp && $hour === "Sore") { + $schedules[Carbon::create($day)->day][$hour][] = substr($availability->start_time, 0, -3); + } elseif (Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp >= Carbon::createFromTime(18, 00, 00)->timestamp && Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp <= Carbon::createFromTime(19, 00, 00)->timestamp && $hour === "Petang") { + $schedules[Carbon::create($day)->day][$hour][] = substr($availability->start_time, 0, -3); + } elseif (Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp >= Carbon::createFromTime(19, 00, 00)->timestamp && Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp <= Carbon::createFromTime(24, 00, 00)->timestamp && $hour === "Malam") { + $schedules[Carbon::create($day)->day][$hour][] = substr($availability->start_time, 0, -3); + } + } + } + } else { + foreach ($hours as $hour => $value) { + for ($i = Carbon::now()->day; $i <= Carbon::now()->daysInMonth; $i++) { + if (Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp >= Carbon::createFromTime(05, 00, 00)->timestamp && Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp <= Carbon::createFromTime(10, 59, 00)->timestamp && $hour === "Pagi") { + $schedules[$i][$hour][] = substr($availability->start_time, 0, -3); + } elseif (Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp >= Carbon::createFromTime(11, 00, 00)->timestamp && Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp <= Carbon::createFromTime(15, 00, 00)->timestamp && $hour === "Siang") { + $schedules[$i][$hour][] = substr($availability->start_time, 0, -3); + } elseif (Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp >= Carbon::createFromTime(15, 01, 00)->timestamp && Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp <= Carbon::createFromTime(18, 00, 00)->timestamp && $hour === "Sore") { + $schedules[$i][$hour][] = substr($availability->start_time, 0, -3); + } elseif (Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp >= Carbon::createFromTime(18, 00, 00)->timestamp && Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp <= Carbon::createFromTime(19, 00, 00)->timestamp && $hour === "Petang") { + $schedules[$i][$hour][] = substr($availability->start_time, 0, -3); + } elseif (Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp >= Carbon::createFromTime(19, 00, 00)->timestamp && Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp <= Carbon::createFromTime(24, 00, 00)->timestamp && $hour === "Malam") { + $schedules[$i][$hour][] = substr($availability->start_time, 0, -3); + } + } + } + } + } + + return (object) $schedules; + } + + public static function currencyIdrFormat($price) + { + return "Rp. " . number_format($price, 0, ',', '.'); } } diff --git a/app/Models/Organization.php b/app/Models/Organization.php index 2e1c6fbe..0990877c 100644 --- a/app/Models/Organization.php +++ b/app/Models/Organization.php @@ -27,7 +27,7 @@ class Organization extends Model public $appends = [ 'meta' ]; - + public function setCodeAttribute($value) { $this->attributes['code'] = !empty($value) ? $value : Str::upper(Str::random('6')); diff --git a/app/Models/Practice.php b/app/Models/Practice.php index 09e5e0b5..0c2ca774 100644 --- a/app/Models/Practice.php +++ b/app/Models/Practice.php @@ -18,6 +18,25 @@ class Practice extends Model 'deleted_by' ]; + // public $appends = [ + // 'price' + // ]; + + // public function getPriceAttribute() + // { + // $orgPrice = []; + // foreach ($this->prices as $price) { + // $orgPrice[$this->service_code] = $price->price_net; + // } + + // return $orgPrice; + // } + + public function getPriceAttribute() + { + return $this->prices->where('priceable_id', $this->id)->max('price_net'); + } + public function prices() { return $this->morphMany(Price::class, 'priceable'); diff --git a/app/Models/PractitionerRole.php b/app/Models/PractitionerRole.php index ae2363ec..1b320f92 100644 --- a/app/Models/PractitionerRole.php +++ b/app/Models/PractitionerRole.php @@ -39,39 +39,6 @@ class PractitionerRole extends Model return $this->practices->where('service_code', 'instant-chat')->where('active', 1)->count() >= 1; } - public function getDailyAvailabilitiesAttribute() - { - $schedules = [ - 'Senin' => [], - 'Selasa' => [], - 'Rabu' => [], - 'Kamis' => [], - 'Jumat' => [], - 'Sabtu' => [], - 'Minggu' => [] - ]; - - foreach ($this->availabilities as $availability) { - - if (count($availability->days)) { - - foreach ($availability->days as $day) { - $schedules[$day][] = $availability->start_time; - } - - } else { - - foreach ($schedules as $day => $times) { - $schedules[$day][] = $availability->start_time; - } - - } - - } - - return $schedules; - } - public function metas() { return $this->morphMany(Meta::class, 'metaable'); diff --git a/config/app.php b/config/app.php index d9b54f83..7b65882a 100644 --- a/config/app.php +++ b/config/app.php @@ -69,7 +69,7 @@ return [ | */ - 'timezone' => 'UTC', + 'timezone' => 'Asia/Jakarta', /* |-------------------------------------------------------------------------- @@ -82,7 +82,7 @@ return [ | */ - 'locale' => 'en', + 'locale' => 'id', /* |-------------------------------------------------------------------------- diff --git a/database/migrations/2022_07_28_032235_create_icd_table.php b/database/migrations/2022_07_28_032235_create_icd_table.php index 39d95fd5..0baf30b1 100644 --- a/database/migrations/2022_07_28_032235_create_icd_table.php +++ b/database/migrations/2022_07_28_032235_create_icd_table.php @@ -18,13 +18,13 @@ return new class extends Migration $table->string('rev'); $table->string('version')->nullable(); $table->string('code'); - $table->string('name'); + $table->string('name', 256); $table->text('description')->nullable(); $table->string('parent_code')->nullable()->index(); - + $table->timestamps(); $table->softDeletes(); - + $table->foreignId('created_by')->nullable(); $table->foreignId('updated_by')->nullable(); $table->foreignId('deleted_by')->nullable();