diff --git a/Modules/HospitalPortal/Http/Controllers/Api/ClaimRequestController.php b/Modules/HospitalPortal/Http/Controllers/Api/ClaimRequestController.php index d565c5ae..744e056d 100644 --- a/Modules/HospitalPortal/Http/Controllers/Api/ClaimRequestController.php +++ b/Modules/HospitalPortal/Http/Controllers/Api/ClaimRequestController.php @@ -2,14 +2,19 @@ namespace Modules\HospitalPortal\Http\Controllers\Api; +use App\Events\ClaimRequested; use App\Helpers\Helper; use App\Models\ClaimRequest; use App\Models\File; use App\Models\Member; +use App\Services\ClaimRequestService; +use App\Services\ClaimService; use Exception; use Illuminate\Contracts\Support\Renderable; use Illuminate\Http\Request; use Illuminate\Routing\Controller; +use Modules\HospitalPortal\Transformers\ClaimRequestResource; +use Modules\HospitalPortal\Transformers\ClaimRequestShowResource; use PDF; class ClaimRequestController extends Controller @@ -56,15 +61,20 @@ class ClaimRequestController extends Controller public function store(Request $request) { $request->validate([ - // 'submission_date' => 'required', 'member_id' => 'required', - // 'files' => '' ]); - $newClaimRequest = ClaimRequest::create([ - 'member_id' => $request->member_id, - 'submission_date' => now(), - 'status' => 'requested' + $member = Member::find($request->member_id); + $newClaimRequest = ClaimRequestService::storeClaimRequest(member: $member); + + ClaimRequested::dispatch($newClaimRequest); + + // Log History + $newClaimRequest->histories()->create([ + 'title' => 'New Claim Requested', + 'description' => "Claim Requested for Member : {$member->member_id} - ({$member->full_name})", + 'type' => 'info', + 'system_origin' => 'hospital-portal' ]); if ($request->hasFile('result_files')) { @@ -111,7 +121,6 @@ class ClaimRequestController extends Controller ]); } } - // return ($request->result_files[0]->getClientOriginalName()); return Helper::responseJson(data: $request->toArray(), message: 'Claim Request berhasil ajukan!'); } @@ -123,7 +132,14 @@ class ClaimRequestController extends Controller */ public function show($id) { - return view('hospitalportal::show'); + $claimRequest = ClaimRequest::findOrFail($id); + $claimRequest->load([ + 'histories' => function ($history) { + $history->latest(); + } + ]); + + return Helper::responseJson(data: ClaimRequestShowResource::make($claimRequest)); } /** diff --git a/Modules/HospitalPortal/Routes/api.php b/Modules/HospitalPortal/Routes/api.php index fcc4cccf..b3599848 100644 --- a/Modules/HospitalPortal/Routes/api.php +++ b/Modules/HospitalPortal/Routes/api.php @@ -39,5 +39,6 @@ Route::prefix('hospitalportal')->group(function () { Route::get('claim-requests', [ClaimRequestController::class, 'index'])->name('claim-requests.index'); Route::post('claim-requests', [ClaimRequestController::class, 'store'])->name('claim-requests.store'); Route::get('claim-requests/{claim_request_id}/log', [ClaimRequestController::class, 'generateLog'])->name('claim-requests.generate-log'); + Route::get('claim-requests/{id}', [ClaimRequestController::class, 'show'])->name('claim-requests.show'); }); }); diff --git a/Modules/HospitalPortal/Transformers/ClaimRequestResource.php b/Modules/HospitalPortal/Transformers/ClaimRequestResource.php new file mode 100644 index 00000000..b907c1a6 --- /dev/null +++ b/Modules/HospitalPortal/Transformers/ClaimRequestResource.php @@ -0,0 +1,31 @@ +histories->mapToGroups(function($history) { + return [$history->created_at->format('Y-m-d') => $history]; + }); + $data['histories_by_date'] = []; + foreach ($historiesGroupByDate as $date => $histories) { + $data['histories_by_date'][] = [ + 'date' => $date, + 'histories' => $histories + ]; + } + + return $data; //parent::toArray($request); + } +} diff --git a/Modules/HospitalPortal/Transformers/ClaimRequestShowResource.php b/Modules/HospitalPortal/Transformers/ClaimRequestShowResource.php new file mode 100644 index 00000000..6bda3c8e --- /dev/null +++ b/Modules/HospitalPortal/Transformers/ClaimRequestShowResource.php @@ -0,0 +1,31 @@ +histories->mapToGroups(function($history) { + return [$history->created_at->format('Y-m-d') => $history]; + }); + $data['histories_by_date'] = []; + foreach ($historiesGroupByDate as $date => $histories) { + $data['histories_by_date'][] = [ + 'date' => $date, + 'histories' => $histories + ]; + } + + return $data; + } +} diff --git a/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php b/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php index 6ea96244..9dbe39fa 100644 --- a/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php +++ b/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php @@ -11,6 +11,7 @@ use Illuminate\Http\Request; use Illuminate\Routing\Controller; use Knp\Snappy\Pdf; use Modules\Internal\Transformers\ClaimRequestResource; +use Modules\Internal\Transformers\ClaimRequestShowResource; class ClaimRequestController extends Controller { @@ -67,7 +68,15 @@ class ClaimRequestController extends Controller */ public function show($id) { - return view('internal::show'); + $claimRequest = ClaimRequest::findOrFail($id); + $claimRequest->load([ + 'histories' => function ($history) { + $history->latest(); + }, + 'files' + ]); + + return Helper::responseJson(data: ClaimRequestShowResource::make($claimRequest)); } /** @@ -104,9 +113,20 @@ class ClaimRequestController extends Controller public function approve($id) { $claimRequest = ClaimRequest::findOrFail($id); - + $member = $claimRequest->member; + $claimRequest->status = 'approved'; $claimRequest->save(); + + // Store Generated Documents + $logContent = view('pdf.guaranted_leter', compact('member', 'claimRequest')); + $claimRequest->generatedDocuments()->create([ + 'type' => 'guarantee_letter', + 'title' => 'Guarantee Letter for '. $member->full_name, + 'document_type' => 'type', + 'html_content' => $logContent, + 'system_origin' => 'primecenter' + ]); return $claimRequest; } diff --git a/Modules/Internal/Routes/api.php b/Modules/Internal/Routes/api.php index 3c8f664c..7947cf63 100755 --- a/Modules/Internal/Routes/api.php +++ b/Modules/Internal/Routes/api.php @@ -135,6 +135,7 @@ Route::prefix('internal')->group(function () { Route::get('claim-requests', [ClaimRequestController::class, 'index'])->name('claim-requests.index'); Route::post('claim-requests/{id}/approve', [ClaimRequestController::class, 'approve'])->name('claim-requests.approve'); + Route::get('claim-requests/{id}', [ClaimRequestController::class, 'show'])->name('claim-requests.show'); }); Route::get('province', [ProvinceController::class, 'index']); diff --git a/Modules/Internal/Transformers/ClaimRequestShowResource.php b/Modules/Internal/Transformers/ClaimRequestShowResource.php new file mode 100644 index 00000000..33af672a --- /dev/null +++ b/Modules/Internal/Transformers/ClaimRequestShowResource.php @@ -0,0 +1,40 @@ +histories->mapToGroups(function($history) { + return [$history->created_at->format('Y-m-d') => $history]; + }); + $data['histories_by_date'] = []; + foreach ($historiesGroupByDate as $date => $histories) { + $data['histories_by_date'][] = [ + 'date' => $date, + 'histories' => $histories + ]; + } + + // Map Files by type + $filesGroupByType = $this->files->mapToGroups(function($file) { + return [Str::slug($file->type, '_') => $file]; + }); + $data['files_by_type'] = $filesGroupByType; + + return $data; + } +} diff --git a/app/Events/ClaimRequested.php b/app/Events/ClaimRequested.php index d810b28d..d08ba6ff 100644 --- a/app/Events/ClaimRequested.php +++ b/app/Events/ClaimRequested.php @@ -2,6 +2,7 @@ namespace App\Events; +use App\Models\ClaimRequest; use Illuminate\Broadcasting\Channel; use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Broadcasting\PresenceChannel; @@ -14,14 +15,16 @@ class ClaimRequested { use Dispatchable, InteractsWithSockets, SerializesModels; + public $claim_request; + /** * Create a new event instance. * * @return void */ - public function __construct() + public function __construct(ClaimRequest $claimRequest) { - // + $this->claim_request = $claimRequest; } /** diff --git a/app/Http/Controllers/GeneratedDocumentController.php b/app/Http/Controllers/GeneratedDocumentController.php new file mode 100644 index 00000000..c634543a --- /dev/null +++ b/app/Http/Controllers/GeneratedDocumentController.php @@ -0,0 +1,92 @@ +html_content.$document->html_content.$document->html_content.$document->html_content.$document->html_content; + } + + public function header(Request $request) + { + return ' + + + + + +
'.json_encode($request->toArray()).'
+            
+                
+                    
+                        
+                        
+                        
+                    
+                
+            
asdkjasnd asjdkadsn qkjwenkqwjenkqwjen
+ + '; + } + + public function footer() + { + return "

Footer Fatherfucker

"; + } + + public function pdf($id) + { + // return 'fuck'; + // $document = GeneratedDocument::findOrFail($id); + + // $pdf = PDF::loadFile('http://localhost:8000/'); + // $pdf = PDF::loadFile('http://aso-linksehat.local/'); + // return $pdf->inline(); + // dd(route('generated-document.show', $id)); + // $pdf = PDF::loadFile(route('generated-document.show', $id)); + // return $pdf->inline(); + + // $snappy = App::make('snappy.pdf'); + // $html = '

Bill

You owe me money, dude.

'; + // // $snappy->generateFromHtml($html, '/tmp/bill-123.pdf'); + // // $snappy->generate('http://www.github.com', '/tmp/github.pdf'); + // //Or output: + // return new Response( + // $snappy->getOutputFromHtml($html), + // 200, + // array( + // 'Content-Type' => 'application/pdf', + // 'Content-Disposition' => 'attachment; filename="file.pdf"' + // ) + // ); + + $pdf = PDF::loadFile(route('generated-document.show', $id)); + + // $pdf->loadFile(route('generated-document.show', $id)); + // $pdf->loadFile(route('generated-document.show', $id)); + // $pdf->loadFile(route('generated-document.show', $id)); + // $pdf->loadFile(route('generated-document.show', $id)); + + // $pdf->setPaper('a4')->setOrientation('landscape')->setOption('margin-bottom', 0); + + // $pdf->setOption('header-html', route('pdf.header')); + // $pdf->setOption('footer-html', route('pdf.header')); + // $pdf->setOption('footer-center', 'asdasdasd'); + + // $pdf->setOption('footer-html', route('pdf.footer')); + // $pdf->loadHtml('asdasdasd'); + + return $pdf->inline(); + } +} diff --git a/app/Listeners/NotifyClaimRequested.php b/app/Listeners/NotifyClaimRequested.php new file mode 100644 index 00000000..39594eb1 --- /dev/null +++ b/app/Listeners/NotifyClaimRequested.php @@ -0,0 +1,35 @@ +notify(new ClaimRequestedNotification()); + } +} diff --git a/app/Models/Claim.php b/app/Models/Claim.php index 9d3b0518..c8fc65c1 100644 --- a/app/Models/Claim.php +++ b/app/Models/Claim.php @@ -18,8 +18,11 @@ use Illuminate\Support\Str; class Claim extends Model { use HasFactory, Blameable, SoftDeletes; + + protected static $code_prefix = 'CLM'; protected $fillable = [ + 'claim_request_id', 'code', 'member_id', 'total_claim', @@ -54,7 +57,8 @@ class Claim extends Model static::creating(function ($model) { try { - $model->code = (string) Str::orderedUuid(); // generate uuid + $model->uuid = (string) Str::orderedUuid(); // generate uuid + $model->code = self::getNextCode(); } catch (\Exception $e) { abort(500, $e->getMessage()); } @@ -78,9 +82,9 @@ class Claim extends Model 'status' => $model->status ]); - if ($model->status == 'requested') { - ClaimRequested::dispatch($model); - } + // if ($model->status == 'requested') { + // ClaimRequested::dispatch($model); + // } if ($model->status == 'received') { ClaimReceived::dispatch($model); @@ -104,6 +108,20 @@ class Claim extends Model } }); } + + public static function getNextCode() + { + $last_number = self::withTrashed()->max('code'); + $next_number = empty($last_number) ? 1 : ((int) explode('-', $last_number)[1] + 1); + + return self::makeCode($next_number); + } + + public static function makeCode($next_number) + { + return (string) self::$code_prefix .'-'. str_pad($next_number, 5, 0, STR_PAD_LEFT); + } + public function files() { diff --git a/app/Models/ClaimHistory.php b/app/Models/ClaimHistory.php new file mode 100644 index 00000000..fbcb4994 --- /dev/null +++ b/app/Models/ClaimHistory.php @@ -0,0 +1,48 @@ +belongsTo(ClaimHistory::class, 'parent_id'); + } + + public function childs() + { + return $this->hasMany(Claimhistory::class, 'parent_id'); + } + + public function claim() + { + return $this->belongsTo(Claim::class, 'claim_id'); + } + + public function historiable() + { + return $this->morphTo(); + } +} diff --git a/app/Models/ClaimRequest.php b/app/Models/ClaimRequest.php index 15dbadcd..dda5aa9a 100644 --- a/app/Models/ClaimRequest.php +++ b/app/Models/ClaimRequest.php @@ -2,10 +2,13 @@ namespace App\Models; +use App\Events\ClaimReceived; +use App\Events\ClaimRequested; use App\Traits\Blameable; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; +use Str; class ClaimRequest extends Model { @@ -13,17 +16,91 @@ class ClaimRequest extends Model protected static $code_prefix = 'CRQ'; + public $fillable = [ + 'submission_date', + 'member_id', + 'status', + 'claim_id' + ]; + + protected $hidden = [ + // 'created_at', + 'updated_at', + 'deleted_at', + 'created_by', + 'updated_by', + 'deleted_by', + ]; + + public static $status = [ + 'draft' => 'Draft', + 'requested' => 'Requested', + 'received' => 'Received', + 'approved' => 'Approved', + 'postpone' => 'Postpone', + 'paid' => 'Paid', + 'declined' => 'Declined' + ]; + protected static function boot() { parent::boot(); static::creating(function ($model) { try { + $model->uuid = (string) Str::orderedUuid(); // generate uuid $model->code = self::getNextCode(); } catch (\Exception $e) { abort(500, $e->getMessage()); } }); + + static::created(function ($model) { + // try { + // if (!empty($model->status) && $model->status == 'requested') { + // $model->histories()->create([ + // 'title' => 'New Claim Requested', + // 'description' => "Claim Requested for Member : {$model->member->member_id} - ({$model->member->full_name})", + // 'type' => 'info' + // ]); + // } + // } catch (\Exception $e) { + // abort(500, $e->getMessage()); + // } + }); + + static::updated(function ($model) { + if ($model->hasChanges(['status'])) { + + // if ($model->status == 'requested') { + // $model->histories()->create([ + // 'title' => 'New Claim Requested', + // 'description' => "Claim Requested for Member : {$model->member->member_id} - ({$model->member->full_name})", + // 'type' => 'info' + // ]); + // } + + // if ($model->status == 'received') { + // ClaimReceived::dispatch($model); + // } + + // if ($model->status == 'approved') { + // ClaimApproved::dispatch($model); + // } + + // if ($model->status == 'postpone') { + // ClaimPostpone::dispatch($model); + // } + + // if ($model->status == 'paid') { + // ClaimPaid::dispatch($model); + // } + + // if ($model->status == 'declined') { + // ClaimDeclined::dispatch($model); + // } + } + }); } public static function getNextCode() @@ -39,17 +116,26 @@ class ClaimRequest extends Model return (string) self::$code_prefix .'-'. str_pad($next_number, 5, 0, STR_PAD_LEFT); } - public $fillable = [ - 'submission_date', - 'member_id', - 'status' - ]; + public function claims() + { + return $this->hasMany(Claim::class, 'claim_request_id'); + } public function files() { return $this->morphMany(File::class, 'fileable'); } + public function generatedDocuments() + { + return $this->morphMany(GeneratedDocument::class, 'generated_documentable'); + } + + public function histories() + { + return $this->morphMany(ClaimHistory::class, 'historiable'); + } + public function member() { return $this->belongsTo(Member::class, 'member_id', 'id'); diff --git a/app/Models/GeneratedDocument.php b/app/Models/GeneratedDocument.php new file mode 100644 index 00000000..43bc828f --- /dev/null +++ b/app/Models/GeneratedDocument.php @@ -0,0 +1,41 @@ +belongsTo(GeneratedDocument::class, 'parent_id'); + } + + public function childs() + { + return $this->hasMany(GeneratedDocument::class, 'parent_id'); + } + + public function generated_documentable() + { + return $this->morphTo(); + } + + public function makePdf() + { + return PDF::loadFile(route('generated-document.show', $this->id)); + } +} diff --git a/app/Models/OLDLMS/Kota.php b/app/Models/OLDLMS/Kota.php new file mode 100644 index 00000000..9a08d2a4 --- /dev/null +++ b/app/Models/OLDLMS/Kota.php @@ -0,0 +1,27 @@ +belongsTo(Provinsi::class, 'nIDProvinsi', 'nID'); + } +} diff --git a/app/Models/OLDLMS/Provinsi.php b/app/Models/OLDLMS/Provinsi.php new file mode 100644 index 00000000..b9281188 --- /dev/null +++ b/app/Models/OLDLMS/Provinsi.php @@ -0,0 +1,22 @@ +line('The introduction to the notification.') + ->action('Notification Action', url('/')) + ->line('Thank you for using our application!'); + } + + /** + * Get the array representation of the notification. + * + * @param mixed $notifiable + * @return array + */ + public function toArray($notifiable) + { + return [ + 'asdasd' => 'asdasdsd' + ]; + } +} diff --git a/app/Providers/ClaimRequested.php b/app/Providers/ClaimRequested.php new file mode 100644 index 00000000..f866235c --- /dev/null +++ b/app/Providers/ClaimRequested.php @@ -0,0 +1,36 @@ + [ + NotifyClaimRequested::class, + ], + ClaimApproved::class => [ LogClaimJournal::class, - ] + ], + ]; /** @@ -43,6 +49,6 @@ class EventServiceProvider extends ServiceProvider */ public function shouldDiscoverEvents() { - return false; + return true; } } diff --git a/app/Services/ClaimRequestService.php b/app/Services/ClaimRequestService.php new file mode 100644 index 00000000..16e79772 --- /dev/null +++ b/app/Services/ClaimRequestService.php @@ -0,0 +1,39 @@ + $member->id, + 'submission_date' => $submissionDate ?? now(), + 'status' => $status + ]; + + $claimRequest = ClaimRequest::create($claimRequestData); + + DB::commit(); + return $claimRequest; + } catch (\Exception $error) { + DB::rollBack(); + + throw new \Exception($error); + } + } + +} \ No newline at end of file diff --git a/app/Services/ClaimService.php b/app/Services/ClaimService.php index 5ce1ce5d..23115e21 100644 --- a/app/Services/ClaimService.php +++ b/app/Services/ClaimService.php @@ -119,8 +119,6 @@ class ClaimService{ ->active() ->first(); - // dd($benefit->toArray()); - // dd(compact(['plan', 'policy', 'corporate', 'benefit'])); $limits = [ 'total_limit' => $corporateBenefit ? $corporateBenefit->limit_amount : 0, 'frequency_limit_name' => $corporateBenefit ? $corporateBenefit->max_frequency_period_name : null, @@ -163,22 +161,21 @@ class ClaimService{ return $limits; } - public static function storeClaim($member, $diagnosis, $totalClaim, $benefit, $status) + public static function storeClaim($member, $diagnosis = null, $totalClaim = null, $benefit = null, $status = 'requested', $claimRequest = null) { try { DB::beginTransaction(); $claimData = [ 'member_id' => $member->id, + 'claim_request_id' => $claimRequest->id ?? null, 'diagnosis_id' => $diagnosis->id ?? null, - 'total_claim' => $totalClaim, + 'total_claim' => $totalClaim ?? null, 'currency' => 'IDR', - 'plan_id' => $member->currentPlan->id, - 'benefit_id' => $benefit->id, + 'plan_id' => $member->currentPlan->id ?? null, + 'benefit_id' => $benefit->id ?? null, 'status' => $status ]; - // $claimData[$status.'_at'] = now(); - // $claimData[$status.'_by'] = auth()->user()->id ?? null; $claim = Claim::create($claimData); diff --git a/database/migrations/2022_11_22_135948_create_claims_table.php b/database/migrations/2022_11_22_135948_create_claims_table.php index 0624149e..132007c3 100644 --- a/database/migrations/2022_11_22_135948_create_claims_table.php +++ b/database/migrations/2022_11_22_135948_create_claims_table.php @@ -15,7 +15,9 @@ return new class extends Migration { Schema::create('claims', function (Blueprint $table) { $table->id(); + $table->uuid('uuid'); $table->string('code')->index(); + $table->foreignId('claim_request_id')->nullable()->index(); $table->foreignId('member_id')->index(); // $table->foreignId('diagnosis_id')->index()->nullable(); $table->string('currency'); diff --git a/database/migrations/2023_02_14_102144_create_claim_requests_table.php b/database/migrations/2023_02_14_102144_create_claim_requests_table.php index 8da85e8d..36564820 100644 --- a/database/migrations/2023_02_14_102144_create_claim_requests_table.php +++ b/database/migrations/2023_02_14_102144_create_claim_requests_table.php @@ -15,6 +15,7 @@ return new class extends Migration { Schema::create('claim_requests', function (Blueprint $table) { $table->id(); + $table->uuid('uuid'); $table->string('code')->index(); $table->dateTime('submission_date')->nullable(); $table->foreignId('member_id'); diff --git a/database/migrations/2023_02_24_125948_create_claim_histories_table.php b/database/migrations/2023_02_24_125948_create_claim_histories_table.php new file mode 100644 index 00000000..9275ec51 --- /dev/null +++ b/database/migrations/2023_02_24_125948_create_claim_histories_table.php @@ -0,0 +1,43 @@ +id(); + $table->morphs('historiable'); + $table->string('title')->nullable(); + $table->string('description')->nullable(); + $table->string('type'); + $table->foreignId('parent_id')->nullable(); + $table->text('data')->nullable(); + $table->string('system_origin')->nullable(); + + $table->timestamps(); + $table->softDeletes(); + $table->unsignedBigInteger('created_by')->nullable()->index(); + $table->unsignedBigInteger('updated_by')->nullable()->index(); + $table->unsignedBigInteger('deleted_by')->nullable()->index(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('claim_histories'); + } +}; diff --git a/database/migrations/2023_02_24_134555_create_generated_documents_table.php b/database/migrations/2023_02_24_134555_create_generated_documents_table.php new file mode 100644 index 00000000..3f7c4343 --- /dev/null +++ b/database/migrations/2023_02_24_134555_create_generated_documents_table.php @@ -0,0 +1,44 @@ +id(); + $table->morphs('generated_documentable', 'generated_document_index'); + $table->string('type'); + $table->string('title'); + $table->string('document_type')->nullable(); + $table->string('system_origin'); + $table->text('html_content')->nullable(); + $table->text('data')->nullable(); + $table->foreignId('parent_id')->nullable(); + + $table->timestamps(); + $table->softDeletes(); + $table->unsignedBigInteger('created_by')->nullable()->index(); + $table->unsignedBigInteger('updated_by')->nullable()->index(); + $table->unsignedBigInteger('deleted_by')->nullable()->index(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('generated_documents'); + } +}; diff --git a/database/migrations/2023_02_27_133120_create_notifications_table.php b/database/migrations/2023_02_27_133120_create_notifications_table.php new file mode 100644 index 00000000..4357c9ef --- /dev/null +++ b/database/migrations/2023_02_27_133120_create_notifications_table.php @@ -0,0 +1,35 @@ +uuid('id')->primary(); + $table->string('type'); + $table->morphs('notifiable'); + $table->text('data'); + $table->timestamp('read_at')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('notifications'); + } +}; diff --git a/frontend/dashboard/src/components/dialogs/DialogDetailClaim.tsx b/frontend/dashboard/src/components/dialogs/DialogDetailClaim.tsx new file mode 100644 index 00000000..64495bef --- /dev/null +++ b/frontend/dashboard/src/components/dialogs/DialogDetailClaim.tsx @@ -0,0 +1,296 @@ +// @mui +import { + Button, + Box, + Stepper, + Step, + StepLabel, + Card, + Typography, + Divider, + Stack, + CircularProgress, +} from '@mui/material'; +import { Add } from '@mui/icons-material'; +// components +import MuiDialog from '@/components/MuiDialog'; +// theme +import palette from '@/theme/palette'; +// React +import { ReactElement, useEffect, useState } from 'react'; +import { fDate } from '@/utils/formatTime'; +import { addMinutes, format } from 'date-fns'; +import { LoadingButton } from '@mui/lab'; +import { enqueueSnackbar } from 'notistack'; +import Iconify from '../Iconify'; + +type DataContent = { + claim: object; + isLoading: boolean; + handleDownloadLog: void; +}; + +type MuiDialogProps = { + title?: { + name?: string; + icon?: string; + }; + openDialog: boolean; + setOpenDialog: Function; + content?: ReactElement; + data?: DataContent[]; +}; + +const steps = ['Review', 'Approval', 'Disbursement']; + +const DialogDetailClaim = ({ title, openDialog, setOpenDialog, data }: MuiDialogProps) => { + const claim = data.claim ?? null; + + // --------------------------------------------- + // Step + const [currentStep, setCurrentStep] = useState(0); + useEffect( + function () { + if (claim?.status == 'requested') { + setCurrentStep(0); + } + if (claim?.status == 'approved') { + setCurrentStep(1); + } + if (claim?.status == 'closed') { + setCurrentStep(2); + } + }, + [data] + ); + + // ---------------------------------------------------- + // Date Stamp + let currentDate = null; + + // ---------------------------------------------------- + // Download LOG + const [loadingDownloadLog, setLoadingDownloadLog] = useState(false); + const handleDownloadLog = async (claimRequest) => { + setLoadingDownloadLog(true); + await data.handleDownloadLog(claimRequest).then(() => { + setLoadingDownloadLog(false); + }); + }; + + // ---------------------------------------------------- + // Handle Upload Invoice + const handleUploadInvoice = () => { + enqueueSnackbar('Something went wrong, please contact Link Medis Sehat', { variant: 'error' }); + }; + + const getContent = () => ( + <> + {data.isLoading && ( + + + + )} + + {!data.isLoading && ( + <> + + + Claim Request + + + Submission date + {/* {JSON.stringify(data)} */} + + {claim.created_at && fDate(claim.created_at)} + + + + + + {steps.map((label) => ( + + {label} + + ))} + + + + {/* { claim.status == 'approved' && ( + + } + fullWidth + // sx={{ typography: 'subtitle2', borderColor: '#F5F5F5' }} + onClick={() => {handleUploadInvoice()}} + > + Upload Invoice + + + )} */} + + {claim.histories_by_date && + claim.histories_by_date.map((historiesByDate) => ( + + + + {fDate(historiesByDate.date)} + + + + + + + {historiesByDate.histories && + historiesByDate.histories.map((history) => ( + + {/* ---------------------------------TYPE INFO------------------------------------ */} + + + + {fDate(history.created_at, 'HH:mm')} WIB + + + Request + + + + + + {history.title} + + + {history.description} + + + + + ))} + + + + ))} + + + + + {/* ---------------------------------TYPE INFO------------------------------------ */} + + + + Dokumen Kelengkapan + + {/* + Dokumen + */} + + + + Kondisi + + } + spacing={1} + sx={{ marginY: 2 }} + > + {claim.files_by_type?.claim_kondisi && + claim.files_by_type.claim_kondisi.map((file, index) => ( + + + + - {file.name} + + + + ))} + + + Diagnosa + } + spacing={1} + sx={{ marginY: 2 }} + > + {claim.files_by_type?.claim_diagnosis && + claim.files_by_type.claim_diagnosis.map((file, index) => ( + + + + - {file.name} + + + + ))} + + + Hasil + } + spacing={1} + sx={{ marginY: 2 }} + > + {claim.files_by_type?.result && + claim.files_by_type.result.map((file, index) => ( + + + + - {file.name} + + + + ))} + + + + + + + )} + + ); + + return ( + + ); +}; + +export default DialogDetailClaim; diff --git a/frontend/dashboard/src/pages/ClaimRequests/List.tsx b/frontend/dashboard/src/pages/ClaimRequests/List.tsx index 57c05191..20b72dd4 100755 --- a/frontend/dashboard/src/pages/ClaimRequests/List.tsx +++ b/frontend/dashboard/src/pages/ClaimRequests/List.tsx @@ -36,12 +36,12 @@ import { LoadingButton } from '@mui/lab'; import { enqueueSnackbar } from 'notistack'; import { Divider } from '@mui/material'; import Iconify from '@/components/Iconify'; +import DialogDetailClaim from '@/components/dialogs/DialogDetailClaim'; // import LoadingButton from '@/theme/overrides/LoadingButton'; export default function List() { const [searchParams, setSearchParams] = useSearchParams(); const [importResult, setImportResult] = useState(null); - const navigate = useNavigate(); function SearchInput(props: any) { // SEARCH @@ -184,6 +184,16 @@ export default function List() { {row.service_type} { row.status == 'requested' && ( {handleApprove(row)}}>Approve )} + + + { + handleShowClaim(row); + }} + > + + + {/* COLLAPSIBLE ROW */} @@ -278,6 +288,33 @@ export default function List() { ); } + + + // --------------------------------------------------------- + // Dialog Detail Claim Request + const [openDialogDetailClaim, setOpenDialogDetailClaim] = useState(false); + const [loadingClaimDetail, setLoadingClaimDetail] = useState(true); + const [currentClaim, setCurrentClaim] = useState(null); + + function handleShowClaim(claimRequest) { + setLoadingClaimDetail(true); + setOpenDialogDetailClaim(true); + + axios.get(`/claim-requests/${claimRequest.id}`) + .then(({data}) => { + setCurrentClaim(data.data); + setLoadingClaimDetail(false); + }) + .catch((err) => { + enqueueSnackbar(err.message, {variant: 'error'}) + }) + } + + function handleDownloadLog() { + + } + + return ( @@ -289,6 +326,14 @@ export default function List() { handlePageChange={handlePageChange} TableContent={} /> + + + ); } diff --git a/frontend/hospital-portal/src/components/dialogs/DialogDetailClaim.tsx b/frontend/hospital-portal/src/components/dialogs/DialogDetailClaim.tsx index 6766175e..8abc61b7 100644 --- a/frontend/hospital-portal/src/components/dialogs/DialogDetailClaim.tsx +++ b/frontend/hospital-portal/src/components/dialogs/DialogDetailClaim.tsx @@ -22,6 +22,7 @@ import { fDate } from '@/utils/formatTime'; import { addMinutes, format } from 'date-fns'; import { LoadingButton } from '@mui/lab'; import { enqueueSnackbar } from 'notistack'; +import Iconify from '../Iconify'; type DataContent = { claim: object; @@ -63,22 +64,25 @@ const DialogDetailClaim = ({ title, openDialog, setOpenDialog, data }: MuiDialog [data] ); + // ---------------------------------------------------- + // Date Stamp + let currentDate = null; // ---------------------------------------------------- // Download LOG - const [loadingDownloadLog, setLoadingDownloadLog] = useState(false) + const [loadingDownloadLog, setLoadingDownloadLog] = useState(false); const handleDownloadLog = async (claimRequest) => { - setLoadingDownloadLog(true) + setLoadingDownloadLog(true); await data.handleDownloadLog(claimRequest).then(() => { - setLoadingDownloadLog(false) - }) - } + setLoadingDownloadLog(false); + }); + }; // ---------------------------------------------------- // Handle Upload Invoice const handleUploadInvoice = () => { - enqueueSnackbar('Something went wrong, please contact Link Medis Sehat', {variant: 'error'}) - } + enqueueSnackbar('Something went wrong, please contact Link Medis Sehat', { variant: 'error' }); + }; const getContent = () => ( <> @@ -102,9 +106,13 @@ const DialogDetailClaim = ({ title, openDialog, setOpenDialog, data }: MuiDialog Submission date {/* {JSON.stringify(data)} */} - {claim && fDate(claim.created_at)} + + {claim.created_at && fDate(claim.created_at)} + + + {/* ----------------STEP---------------- */} {steps.map((label) => ( @@ -115,129 +123,117 @@ const DialogDetailClaim = ({ title, openDialog, setOpenDialog, data }: MuiDialog - { claim.status == 'approved' && ( - - } - fullWidth - // sx={{ typography: 'subtitle2', borderColor: '#F5F5F5' }} - onClick={() => {handleUploadInvoice()}} - > - Upload Invoice - - )} - - - - {fDate(claim.created_at)} - - - + {/* { claim.status == 'approved' && ( + + } + fullWidth + // sx={{ typography: 'subtitle2', borderColor: '#F5F5F5' }} + onClick={() => {handleUploadInvoice()}} + > + Upload Invoice + + + )} */} + + - - {/* Download LOG */} - {claim.status == 'approved' && ( - - - - {format( - addMinutes( - new Date(claim.created_at), - 15 //Math.floor(Math.random() * (20 - 15 + 1)) + 15 - ), - 'HH:mm' - )}{' '} - WIB - - Approved - - - - - } - fullWidth - // sx={{ typography: 'subtitle2', borderColor: '#F5F5F5' }} - onClick={() => {handleDownloadLog(claim)}} - > - Download Guarantee Letter - - - - )} - - - {/* Item 1 */} - {claim.status == 'requested' && ( - - - 09:10 WIB - - Approval - - - - - - Details : mohon melengkapi kekurangan dokumen - - - Lab pemeriksaan darah - - - - - )} - - {/* Item 2 */} - + {/* ---------------------------------TYPE INFO------------------------------------ */} + - {/* // TODO sementara tanggal random */} - - {format( - addMinutes( - new Date(claim.created_at), - 10// Math.floor(Math.random() * (15 - 5 + 1)) + 5 - ), - 'HH:mm' - )}{' '} - WIB + + Pengajuan Penjaminan - + + + + } + fullWidth + // sx={{ typography: 'subtitle2', borderColor: '#F5F5F5' }} + onClick={() => {}} + > + Upload Invoice + + + + + + + {claim.histories_by_date && + claim.histories_by_date.map((historiesByDate) => ( + + + + {fDate(historiesByDate.date)} + + + + + + + {historiesByDate.histories && + historiesByDate.histories.map((history) => ( + + {/* ---------------------------------TYPE INFO------------------------------------ */} + + + + {fDate(history.created_at, 'HH:mm')} WIB + + + Request + + + + + + {history.title} + + + {history.description} + + + + + ))} + + + + ))} + + + + + {/* ---------------------------------TYPE INFO------------------------------------ */} + + + + Dokumen Kelengkapan + + {/* - Approval - + Dokumen + */} + + Kondisi - - Details : Penilaian Dokter - - - - {/* Item 3 */} - - - {fDate(claim.created_at, 'HH:mm')} WIB - } + spacing={1} + sx={{ marginY: 2 }} > - Review - - - - - - Details : Klaim Diajukan - + {claim.files_by_type?.claim_kondisi && + claim.files_by_type.claim_kondisi.map((file, index) => ( + + + + - {file.name} + + + + ))} + + + Diagnosa + } + spacing={1} + sx={{ marginY: 2 }} + > + {claim.files_by_type?.claim_diagnosis && + claim.files_by_type.claim_diagnosis.map((file, index) => ( + + + + - {file.name} + + + + ))} + + + Hasil + } + spacing={1} + sx={{ marginY: 2 }} + > + {claim.files_by_type?.result && + claim.files_by_type.result.map((file, index) => ( + + + + - {file.name} + + + + ))} + diff --git a/frontend/hospital-portal/src/pages/Dashboard.tsx b/frontend/hospital-portal/src/pages/Dashboard.tsx index c9a9d56a..c394df27 100755 --- a/frontend/hospital-portal/src/pages/Dashboard.tsx +++ b/frontend/hospital-portal/src/pages/Dashboard.tsx @@ -14,6 +14,7 @@ import { Input } from '@mui/material'; //sections import TableList from '@/sections/dashboard/TableList'; import { fDate } from '@/utils/formatTime'; +import DialogDetailClaim from '@/components/dialogs/DialogDetailClaim'; // ---------------------------------------------------------------------- @@ -96,6 +97,7 @@ export default function Dashboard() { + ); } diff --git a/frontend/hospital-portal/src/sections/dashboard/CardNotification.tsx b/frontend/hospital-portal/src/sections/dashboard/CardNotification.tsx index 635d24a2..47bfd58d 100644 --- a/frontend/hospital-portal/src/sections/dashboard/CardNotification.tsx +++ b/frontend/hospital-portal/src/sections/dashboard/CardNotification.tsx @@ -7,7 +7,7 @@ import Iconify from '@/components/Iconify'; // React import { useState } from 'react'; import DialogNotification from './DialogNotification'; -import DialogDetailClaim from './DialogDetailClaim'; +import DialogDetailClaim from '@/components/dialogs/DialogDetailClaim'; // ---------------------------------------------------------------------- diff --git a/frontend/hospital-portal/src/sections/dashboard/DialogNotification.tsx b/frontend/hospital-portal/src/sections/dashboard/DialogNotification.tsx index c93a27b2..feaef61f 100644 --- a/frontend/hospital-portal/src/sections/dashboard/DialogNotification.tsx +++ b/frontend/hospital-portal/src/sections/dashboard/DialogNotification.tsx @@ -5,8 +5,8 @@ import { Card, Divider, Link, Stack, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; // Component import MuiDialog from '../../components/MuiDialog'; +import DialogDetailClaim from '@/components/dialogs/DialogDetailClaim'; // Sections -import DialogDetailClaim from './DialogDetailClaim'; type DataContent = { info: string; diff --git a/frontend/hospital-portal/src/sections/dashboard/TableList.tsx b/frontend/hospital-portal/src/sections/dashboard/TableList.tsx index adc9dad5..0aeb07cf 100755 --- a/frontend/hospital-portal/src/sections/dashboard/TableList.tsx +++ b/frontend/hospital-portal/src/sections/dashboard/TableList.tsx @@ -313,6 +313,27 @@ export default function TableList(props: any) { })(); }, [appliedParams, searchParams, order, orderBy, setSearchParams]); + // --------------------------------------------------------- + // Dialog Detail Claim + const [openDialogDetailClaim, setOpenDialogDetailClaim] = useState(false); + const [loadingClaimDetail, setLoadingClaimDetail] = useState(true); + const [currentClaim, setCurrentClaim] = useState(null); + + function handleShowClaim(claimRequest) { + setLoadingClaimDetail(true); + setOpenDialogDetailClaim(true); + + axios.get(`/claim-requests/${claimRequest.id}`) + .then(({data}) => { + console.log(data.data); + setCurrentClaim(data.data); + setLoadingClaimDetail(false); + }) + .catch((err) => { + enqueueSnackbar(err.message, {variant: 'error'}) + }) + } + // ----------------------------------------------------------------- // Download LOG async function handleDownloadLog(claimRequest) { @@ -334,21 +355,6 @@ export default function TableList(props: any) { }); } - // --------------------------------------------------------- - // Dialog Detail Claim - const [openDialogDetailClaim, setOpenDialogDetailClaim] = useState(false); - const [loadingClaimDetail, setLoadingClaimDetail] = useState(true); - const [currentClaim, setCurrentClaim] = useState(null); - - function handleShowClaim(claimRequest) { - setLoadingClaimDetail(true); - setOpenDialogDetailClaim(true); - setTimeout(function () { - setCurrentClaim(claimRequest); - setLoadingClaimDetail(false); - }, 300); - } - return ( @@ -513,12 +519,15 @@ export default function TableList(props: any) { {/* End Field 2 */} + + + ); } diff --git a/frontend/hospital-portal/src/sections/dashboard/DialogDetailClaim.tsx b/frontend/hospital-portal/src/sections/dashboard/asdasdasdDialogDetailClaim.tsx similarity index 100% rename from frontend/hospital-portal/src/sections/dashboard/DialogDetailClaim.tsx rename to frontend/hospital-portal/src/sections/dashboard/asdasdasdDialogDetailClaim.tsx diff --git a/resources/files/providers.csv:Zone.Identifier b/resources/files/providers.csv:Zone.Identifier new file mode 100644 index 00000000..1cc360cb --- /dev/null +++ b/resources/files/providers.csv:Zone.Identifier @@ -0,0 +1,4 @@ +[ZoneTransfer] +ZoneId=3 +ReferrerUrl=https://docs.google.com/ +HostUrl=https://doc-0g-9k-sheets.googleusercontent.com/export/36l11cvnhaccqmms6c85sbeosg/4je7nlqn7u5a74q5t8end74f28/1677645605000/106328900561681991688/114852934422671877320/1ZAov4ChGcV8LSn_2NVJT9sXneZCn9UKABvSXo8gkJeY?format=csv&id=1ZAov4ChGcV8LSn_2NVJT9sXneZCn9UKABvSXo8gkJeY&gid=0&dat=AP36HMUCq80X-P4ovM8wnZWhyaZAwfeMUSZjzSDLtxiRu-U-HKLyptb3Vn7NLxgzHGDj_wJGYjOx3kjxhcZdakeaTvUvwmpzgNI9sX1IDd6S0ohIn5YqmLA-_TqClPlWfpXoQHNeqcoTofr7KR0Iq1cpd5vvPH1OywrhxwV5z_333pXpsRUt3PU3pjAb4nQry85CtovhYGAhQOXH2u5b2HVSpR249DlF7fPghEbu0qKdDuTiAdySlTAu-p0p2MZlEZKbS19PYS-oerxtKoyg45ZsGXajCBuHKq1vMO9wQ56xRuFQQ9l-pTinl8GQdZAqSsDDfO0NntfIsv_Ijq35MLWIx0NjwR4NymWPB-fTCPq5lrgSK0q_tonWBLsscJrEttK2Lh1dBDqTdqC4bQb1Fe5ssUQrZL7_XFDKBaIvaW5oH5nrgpcw0WwnezY_QrHS52rb-wY1LUyk1fEUQl8znuVySnchKJrczVU1GXMWHLYUlyNyV1aEyQWYp0BHg-Iee0wG8HClnMbNMaiVpruWcEvH5tTrJ2CkjRQSjIK-08TAJB02cbHsWgOlV9TswWnsvo_Rsd7aCuZsGXFxaw644s0NmUp445s1-0Jidf10v0Ki1n3C2rO9asezai2ppWEN453GbKYf1mCnwhlzGCsYpCAvk-306KdMVDQB7KnNKrRJdlAMUkGAoV2YTU4Y_ADwAtuh8YenWgPTEUZqlWNbStyPpByzZIojn9mLYgScML4daDETGBzaI2KjO5IbAKBceXJl9kdxA9EfRnyTkDUXTphNA2baI6PiIIBeO0U6dX3zWt-rH0TOY2a3CznzB5bVcbHVmOLzSVyax-936E7S55_c18JzEG_5HbdnyDu4k8tUwj63p2sAwpswDd2CdpWnSkvG45ntPDvuUflSzNxILiISeWJxRcUjZ0XBjxLOqCYIS3f-Usgi diff --git a/routes/web.php b/routes/web.php index 4e6b69b8..68d4b54a 100755 --- a/routes/web.php +++ b/routes/web.php @@ -1,6 +1,7 @@ name('postpone-pay'); \ No newline at end of file +Route::get('postpone-pay/{member_id}', [PaymentController::class, 'postponePay'])->name('postpone-pay'); + +Route::get('c1in24b6ct1c279489u12nc89b7cb4y890uj12iub3yd/{id}', [GeneratedDocumentController::class, 'show'])->name('generated-document.show'); +Route::get('pdf/header', [GeneratedDocumentController::class, 'header'])->name('pdf.header'); +Route::get('pdf/footer', [GeneratedDocumentController::class, 'footer'])->name('pdf.footer'); +Route::get('pdf/{id}', [GeneratedDocumentController::class, 'pdf']); \ No newline at end of file