Merge remote-tracking branch 'origin/staging' into origin/production
This commit is contained in:
@@ -10,6 +10,8 @@ use Illuminate\Support\Facades\DB;
|
||||
use Modules\Internal\Http\Controllers\Api\RequestLogController as primeCenterRequestLog;
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\File;
|
||||
use Dompdf\Dompdf;
|
||||
use Dompdf\Options;
|
||||
|
||||
class RequestLogController extends Controller
|
||||
{
|
||||
@@ -99,6 +101,7 @@ class RequestLogController extends Controller
|
||||
})
|
||||
->select(
|
||||
'request_logs.id',
|
||||
'request_logs.member_id',
|
||||
'request_logs.final_log',
|
||||
'request_logs.code',
|
||||
'members.name as full_name',
|
||||
@@ -281,4 +284,97 @@ class RequestLogController extends Controller
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function downlodLog($request_log_id)
|
||||
{
|
||||
$dataRequestLog = DB::table('request_logs')
|
||||
->where('request_logs.id', '=', $request_log_id)
|
||||
->first();
|
||||
$dataMember = DB::table('members')
|
||||
->where('members.id', '=', $dataRequestLog->member_id)
|
||||
->select(
|
||||
'members.principal_id',
|
||||
'members.name',
|
||||
'members.birth_date',
|
||||
'members.member_id',
|
||||
'members.gender',
|
||||
DB::raw('
|
||||
(Select persons.nik FROM persons WHERE persons.id = members.person_id LIMIT 1) AS nik
|
||||
'),
|
||||
DB::raw('
|
||||
"Link Sehat" AS penjamin
|
||||
'),
|
||||
DB::raw('
|
||||
(Select corporates.name FROM corporates
|
||||
INNER JOIN corporate_employees ON corporate_employees.corporate_id = corporates.id
|
||||
WHERE corporate_employees.member_id = members.id LIMIT 1) AS nama_perusahaan
|
||||
'),
|
||||
DB::raw('
|
||||
(Select member_policies.policy_id FROM member_policies WHERE member_policies.member_id = members.member_id LIMIT 1) AS no_polis
|
||||
'),
|
||||
DB::raw('
|
||||
(Select member_policies.status FROM member_policies WHERE member_policies.member_id = members.member_id LIMIT 1) AS status_polis
|
||||
'),
|
||||
DB::raw('
|
||||
(Select plans.code FROM member_plans
|
||||
INNER JOIN plans ON plans.id = member_plans.plan_id
|
||||
WHERE member_plans.member_id = members.id LIMIT 1) AS code_plan
|
||||
'),
|
||||
DB::raw('
|
||||
(Select plans.limit_rules FROM member_plans
|
||||
INNER JOIN plans ON plans.id = member_plans.plan_id
|
||||
WHERE member_plans.member_id = members.id LIMIT 1) AS limit_rules
|
||||
'),
|
||||
DB::raw('
|
||||
"IDR" AS mata_uang
|
||||
'),
|
||||
'members.members_effective_date AS mulai',
|
||||
'members.members_expire_date AS akhir'
|
||||
)
|
||||
->first();
|
||||
$data['namaKaryawan'] = '';
|
||||
if($dataMember->principal_id)
|
||||
{
|
||||
$dataNamaKaryawan = DB::table('members')
|
||||
->where('members.member_id', '=', $dataMember->principal_id)
|
||||
->select('members.name')
|
||||
->limit(1)
|
||||
->first();
|
||||
$data['namaKaryawan'] = $dataNamaKaryawan->name;
|
||||
}
|
||||
else{
|
||||
$data['namaKaryawan'] = $dataMember->name;
|
||||
}
|
||||
|
||||
$data['dataMember'] = $dataMember;
|
||||
|
||||
$data['request_logs'] = $dataRequestLog;
|
||||
|
||||
$pdf = new Dompdf();
|
||||
|
||||
$options = new Options();
|
||||
$options->set('isHtml5ParserEnabled', true);
|
||||
$options->set('isPhpEnabled', true);
|
||||
$options->set(['isRemoteEnabled' => true]);
|
||||
$pdf->setOptions($options);
|
||||
|
||||
// Halaman 1
|
||||
$html1 = view('pdf.req_log_page_1', $data);
|
||||
|
||||
// Halaman 2
|
||||
$html2 = view('pdf.req_log_page_2', $data);
|
||||
|
||||
// Gabung konten HTML dari dua tampilan
|
||||
$htmlCombined = $html1 . $html2;
|
||||
|
||||
$pdf->loadHtml($htmlCombined);
|
||||
$pdf->render();
|
||||
|
||||
$headers = [
|
||||
'Content-Type' => 'application/pdf',
|
||||
'Content-Disposition' => 'inline; filename="file.pdf"',
|
||||
];
|
||||
|
||||
return response($pdf->output(), 200, $headers);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ Route::prefix('v1')->group(function() {
|
||||
Route::get('get-request-log', 'getRequestLog');
|
||||
Route::get('get-final-log', 'getFinalLog');
|
||||
Route::post('request-final-log', 'requestFinalLog');
|
||||
Route::get('download-log/{request_log_id}', 'downlodLog');
|
||||
});
|
||||
//Notification
|
||||
Route::controller(NotificationController::class)->group(function() {
|
||||
|
||||
@@ -20,6 +20,8 @@ use Modules\Internal\Services\MemberEnrollmentService;
|
||||
use PDF;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Spatie\Browsershot\Browsershot;
|
||||
|
||||
class CorporateMemberController extends Controller
|
||||
{
|
||||
@@ -393,4 +395,70 @@ class CorporateMemberController extends Controller
|
||||
"file_url" => url('files/CorporateMembershipList.xlsx')
|
||||
]);
|
||||
}
|
||||
|
||||
public function sendAllECard(Request $request, $corporate_id){
|
||||
$members = Member::with([
|
||||
'currentPlan',
|
||||
'currentPolicy',
|
||||
'currentCorporate',
|
||||
// 'currentPlan.corporateBenefits.benefit'
|
||||
])->whereHas('currentCorporate', function ($query) use ($corporate_id) {
|
||||
$query->where('corporate_id', $corporate_id);
|
||||
})->get();
|
||||
$data = [];
|
||||
$countSuccesSend = 0;
|
||||
foreach($members as $member){
|
||||
// Simpan file PDF ke direktori yang diinginkan
|
||||
$pdfPath = storage_path('app/pdf/ecards/E-card-' . $member->name. '.pdf');
|
||||
// Cek apakah file sudah ada
|
||||
if (!File::exists($pdfPath)) {
|
||||
$pdf = PDF::loadView('pdf.ecard', compact('member'))->setPaper('A5', 'portrait');
|
||||
$pdf->save($pdfPath);
|
||||
}
|
||||
|
||||
$dataEmail = [
|
||||
// 'email' => $member->email,
|
||||
'email' => 'tbfajri',
|
||||
'name' => $member->name,
|
||||
'subject' => 'Digital E Card '. $member->name,
|
||||
'body' => '<h1>Hi ' . $member->name . '</h1> <br> ini adalah uji coba kirim e-card' ,
|
||||
'attach' => $pdfPath,
|
||||
];
|
||||
$sendEmail = Helper::sendEmailattachData($dataEmail);
|
||||
|
||||
if ($sendEmail === true){
|
||||
$countSuccesSend ++;
|
||||
|
||||
File::delete($pdfPath);
|
||||
} else {
|
||||
$dataFaild = [
|
||||
'email' => $member->email,
|
||||
'name' => $member->name,
|
||||
'message' => $sendEmail
|
||||
];
|
||||
array_push($data, $dataFaild);
|
||||
}
|
||||
}
|
||||
$response = [
|
||||
'data_fail_send' => count($data),
|
||||
'message' => $data,
|
||||
'data_succes_send' => $countSuccesSend,
|
||||
];
|
||||
|
||||
return response()->json($response);
|
||||
}
|
||||
|
||||
public function viewECard(Request $request, $member_id){
|
||||
$member = Member::with([
|
||||
'currentPlan',
|
||||
'currentPolicy',
|
||||
'currentCorporate',
|
||||
// 'currentPlan.corporateBenefits.benefit'
|
||||
])->find($member_id);
|
||||
|
||||
$pdf = PDF::loadView('pdf.ecard', compact('member'))->setPaper('A5', 'portrait');
|
||||
return $pdf->download('Ecard - '.$member->full_name.'.pdf');
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,12 +3,14 @@
|
||||
namespace Modules\Internal\Http\Controllers\Api;
|
||||
|
||||
use App\Models\DailyMonitoring;
|
||||
use App\Models\RequestDailyMonitoring;
|
||||
use App\Models\MedicalPlan;
|
||||
use DB;
|
||||
use Exception;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use App\Models\File;
|
||||
|
||||
/**
|
||||
* Bagaskoro BSD 27-10-2023
|
||||
@@ -17,6 +19,7 @@ use Illuminate\Support\Facades\Validator;
|
||||
*/
|
||||
class DailyMonitoringController extends Controller
|
||||
{
|
||||
protected $path_for_store = 'public/lab_result';
|
||||
protected function messages()
|
||||
{
|
||||
return [
|
||||
@@ -68,7 +71,7 @@ class DailyMonitoringController extends Controller
|
||||
$claimList = DB::table('request_logs')
|
||||
->leftJoin('services', 'services.code', '=', 'request_logs.service_code')
|
||||
->leftJoin('members', 'members.id', '=', 'request_logs.member_id')
|
||||
->select('request_logs.id','request_logs.submission_date AS admission_date','request_logs.discharge_date','request_logs.code','services.name as service_name','request_logs.status','members.name',)
|
||||
->select('request_logs.id','request_logs.submission_date AS admission_date','request_logs.discharge_date','request_logs.code','services.name as service_name','request_logs.status','members.name', 'members.member_id')
|
||||
->where('request_logs.service_code', 'IP')
|
||||
->where('request_logs.status_final_log', 'approved')
|
||||
->where("request_logs.member_id", "=", $memberDetail->id)
|
||||
@@ -88,21 +91,17 @@ class DailyMonitoringController extends Controller
|
||||
/**
|
||||
* Detail Monitoring List - by claim_code
|
||||
*/
|
||||
public function GetDetailMonitoringList(Request $request, $claim_code)
|
||||
public function GetDetailMonitoringList(Request $request, $request_code)
|
||||
{
|
||||
// get claim request
|
||||
$claim_request = DB::table('claim_requests')
|
||||
// get id request log
|
||||
$request_logs = DB::table('request_logs')
|
||||
->select('id')
|
||||
->where('code', $claim_code)
|
||||
->where('code', $request_code)
|
||||
->first();
|
||||
|
||||
// get claim
|
||||
$claim = DB::table('claims')
|
||||
->select('id')
|
||||
->where('claim_request_id', empty($claim_request)==false ? $claim_request->id : '')
|
||||
->first();
|
||||
|
||||
$detail_list = DailyMonitoring::where('claim_id', empty($claim) == false ? $claim->id : '')->orderBy("created_at", "desc")->get()->makeHidden(['updated_at']);
|
||||
$detail_list = RequestDailyMonitoring::where('request_log_id', empty($request_logs) == false ? $request_logs->id : '')
|
||||
->orderBy("created_at", "desc")
|
||||
->get();
|
||||
|
||||
return response()->json([
|
||||
'error' => false,
|
||||
@@ -213,4 +212,194 @@ class DailyMonitoringController extends Controller
|
||||
],500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Detail Request LOG LIST
|
||||
*/
|
||||
public function AddDetailMonitoringListRequestLog(Request $request, $request_code)
|
||||
{
|
||||
$request->merge(['request_code' => $request_code]);
|
||||
|
||||
// validation rule
|
||||
$validator = Validator::make($request->all(),[
|
||||
'request_code' => 'required|exists:request_logs,code',
|
||||
'subject' => 'required',
|
||||
'body_temperature' => 'required|numeric',
|
||||
'sistole' => 'required|numeric',
|
||||
'diastole' => 'required|numeric',
|
||||
'respiration_rate' => 'required|numeric',
|
||||
'analysis' => 'required',
|
||||
'medical_plan' => 'required',
|
||||
'non_medikamentosa_plan' => 'required',
|
||||
],$this->messages());
|
||||
|
||||
// validation error
|
||||
if ($validator->fails()) {
|
||||
return response()->json([
|
||||
'error' => true,
|
||||
'message' => $validator->getMessageBag()
|
||||
],400);
|
||||
}
|
||||
|
||||
// get claim request
|
||||
$request_log = DB::table('request_logs')
|
||||
->select('id')
|
||||
->where('code', $request_code)
|
||||
->first();
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
// insert claim daily monitoring
|
||||
$db_response = RequestDailyMonitoring::create([
|
||||
'request_log_id' => $request_log->id,
|
||||
'subject' => $request->subject,
|
||||
'sistole' => $request->sistole,
|
||||
'diastole' => $request->diastole,
|
||||
'body_temperature' => $request->body_temperature,
|
||||
'respiration_rate' => $request->respiration_rate,
|
||||
'analysis' => $request->analysis,
|
||||
'lab_date' => $request->lab_date,
|
||||
'provider' => $request->provider,
|
||||
'examination' => $request->examination,
|
||||
]);
|
||||
|
||||
|
||||
// cek medical plan
|
||||
$num_medical_plan = 0;
|
||||
foreach ($request->medical_plan as $row) {
|
||||
if ($row['medical_plan_str']) {
|
||||
$num_medical_plan++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($num_medical_plan == 0) {
|
||||
DB::rollBack();
|
||||
return response()->json([
|
||||
'error' => true,
|
||||
'message' => [
|
||||
'medical_plan' => ['medical plan harus diisi']
|
||||
],
|
||||
'data' => []
|
||||
],400);
|
||||
}
|
||||
|
||||
// insert medical plan
|
||||
foreach ($request->medical_plan as $row) {
|
||||
DB::table('request_log_medical_plan')->insert([
|
||||
'request_log_daily_monitoring_id' => $db_response->id,
|
||||
'plan' => $row['medical_plan_str'],
|
||||
'type' => 1,
|
||||
'created_at' => date('Y-m-d'),
|
||||
]);
|
||||
}
|
||||
|
||||
// insert non medical plan
|
||||
foreach ($request->non_medikamentosa_plan as $row) {
|
||||
DB::table('request_log_medical_plan')->insert([
|
||||
'request_log_daily_monitoring_id' => $db_response->id,
|
||||
'plan' => $row['non_medikamentosa_plan_str'],
|
||||
'type' => 2,
|
||||
'created_at' => date('Y-m-d'),
|
||||
]);
|
||||
}
|
||||
|
||||
// insert file result
|
||||
if ($request->confirmation_medical_leter){
|
||||
foreach ($request->confirmation_medical_leter as $file) {
|
||||
$name = 'labresult-' . uniqid();
|
||||
$extension= $file->getClientOriginalExtension();
|
||||
$fileName = $name . '.' . $extension;
|
||||
$path = $file->storeAs($this->path_for_store, $fileName);
|
||||
File::create([
|
||||
'fileable_type' => 'App\Models\LaboratoriumResult',
|
||||
'fileable_id' => $db_response->id,
|
||||
'type' => 'confirmation-medical-letter',
|
||||
'name' => $name,
|
||||
'original_name' => $fileName,
|
||||
'extension' => $extension,
|
||||
'path' => $path,
|
||||
]);
|
||||
|
||||
}
|
||||
}
|
||||
if ($request->medical_action_letter){
|
||||
foreach ($request->medical_action_letter as $file) {
|
||||
$name = 'labresult-' . uniqid();
|
||||
$extension= $file->getClientOriginalExtension();
|
||||
$fileName = $name . '.' . $extension;
|
||||
$path = $file->storeAs($this->path_for_store, $fileName);
|
||||
File::create([
|
||||
'fileable_type' => 'App\Models\LaboratoriumResult',
|
||||
'fileable_id' => $db_response->id,
|
||||
'type' => 'medical-action-letter',
|
||||
'name' => $name,
|
||||
'original_name' => $fileName,
|
||||
'extension' => $extension,
|
||||
'path' => $path,
|
||||
]);
|
||||
|
||||
// $file->storeAs($this->path_for_store, $fileName);
|
||||
}
|
||||
}
|
||||
if ($request->result){
|
||||
foreach ($request->result as $file) {
|
||||
$name = 'labresult-' . uniqid();
|
||||
$extension= $file->getClientOriginalExtension();
|
||||
$fileName = $name . '.' . $extension;
|
||||
$path = $file->storeAs($this->path_for_store, $fileName);
|
||||
File::create([
|
||||
'fileable_type' => 'App\Models\LaboratoriumResult',
|
||||
'fileable_id' => $db_response->id,
|
||||
'type' => 'laboratorium-result',
|
||||
'name' => $name,
|
||||
'original_name' => $fileName,
|
||||
'extension' => $extension,
|
||||
'path' => $path,
|
||||
]);
|
||||
|
||||
// $file->storeAs($this->path_for_store, $fileName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DB::commit();
|
||||
|
||||
return response()->json([
|
||||
'error' => false,
|
||||
'message' => "success",
|
||||
'data' => []
|
||||
],200);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
DB::rollBack();
|
||||
return response()->json([
|
||||
'error' => true,
|
||||
'message' => $e->getMessage(),
|
||||
'data' => []
|
||||
],500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Status Request LOG
|
||||
*/
|
||||
public function UpdateListRequestLog(Request $request, $request_code)
|
||||
{
|
||||
// get claim request
|
||||
$request_log = DB::table('request_logs')
|
||||
->where('code', $request_code)
|
||||
->update(['discharge_date' => now()]);
|
||||
if ($request_log) {
|
||||
return response()->json([
|
||||
'error' => false,
|
||||
'message' => "success",
|
||||
'data' => []
|
||||
], 200);
|
||||
} else {
|
||||
return response()->json([
|
||||
'error' => true,
|
||||
'message' => $e->getMessage(),
|
||||
'data' => []
|
||||
],500);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,6 +170,8 @@ Route::prefix('internal')->group(function () {
|
||||
Route::prefix('daily_monitoring')->group(function () {
|
||||
Route::get('detail/{claim_code}/list', [DailyMonitoringController::class, 'GetDetailMonitoringList']);
|
||||
Route::post('detail/{claim_code}/add', [DailyMonitoringController::class, 'AddDetailMonitoringList']);
|
||||
Route::post('detail/{claim_code}/add-request', [DailyMonitoringController::class, 'AddDetailMonitoringListRequestLog']);
|
||||
Route::post('detail/{claim_code}/update-status', [DailyMonitoringController::class, 'UpdateListRequestLog']);
|
||||
});
|
||||
|
||||
// Laboratorium Result
|
||||
@@ -284,6 +286,9 @@ Route::prefix('internal')->group(function () {
|
||||
Route::resource('doctors', DoctorController::class);
|
||||
|
||||
Route::post('generate-log/{member_id}', [CorporateMemberController::class, 'generateLog']);
|
||||
|
||||
Route::get('send_card/{corporate_id}', [CorporateMemberController::class, 'sendAllECard']);
|
||||
Route::get('view_card/{member_id}', [CorporateMemberController::class, 'viewECard']);
|
||||
Route::controller(ClaimRequestController::class)->group(function () {
|
||||
Route::post('files-mcu', 'filesMcu');
|
||||
});
|
||||
|
||||
@@ -324,6 +324,12 @@ class MemberEnrollmentService
|
||||
// "Ingestion Status",
|
||||
];
|
||||
|
||||
public $doc_headers_send_email = [
|
||||
"Name",
|
||||
"Email",
|
||||
"Message"
|
||||
];
|
||||
|
||||
public function __construct(Member $member)
|
||||
{
|
||||
app()->setLocale('en');
|
||||
|
||||
@@ -317,7 +317,6 @@ class Helper
|
||||
{
|
||||
// Buat instance PHPMailer
|
||||
$mail = new PHPMailer(true);
|
||||
|
||||
try {
|
||||
// Server settings
|
||||
$mail->isSMTP();
|
||||
@@ -341,8 +340,46 @@ class Helper
|
||||
// Kirim email
|
||||
$mail->send();
|
||||
return true;
|
||||
|
||||
} catch (\Exception $e) {
|
||||
//var_dump($mail->ErrorInfo);die();
|
||||
dd($e);
|
||||
return ($mail->ErrorInfo);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function sendEmailattachData($data = array())
|
||||
{
|
||||
// Buat instance PHPMailer
|
||||
$mail = new PHPMailer(true);
|
||||
try {
|
||||
// Server settings
|
||||
$mail->isSMTP();
|
||||
$mail->Host = 'smtp.gmail.com';
|
||||
$mail->SMTPAuth = true;
|
||||
$mail->Username = env('EMAIL');
|
||||
$mail->Password = env('PW_EMAIL');
|
||||
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
|
||||
$mail->Port = 465;
|
||||
$mail->SMTPSecure = "ssl";
|
||||
|
||||
// Penerima email
|
||||
$mail->setFrom(env('EMAIL'), env('NAME_EMAIL'));
|
||||
$mail->addAddress($data['email'], $data['name']);
|
||||
|
||||
// Konten email
|
||||
$mail->isHTML(true);
|
||||
$mail->Subject = $data['subject'];
|
||||
$mail->Body = $data['body'];
|
||||
$mail->addAttachment($data['attach'], 'e-card.pdf');
|
||||
|
||||
// Kirim email
|
||||
$mail->send();
|
||||
return true;
|
||||
|
||||
} catch (\Exception $e) {
|
||||
dd($mail->ErrorInfo);
|
||||
return ($mail->ErrorInfo);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,19 +255,46 @@ class Member extends Model
|
||||
);
|
||||
}
|
||||
|
||||
protected function birthDate(): Attribute
|
||||
// protected function birthDate(): Attribute
|
||||
// {
|
||||
// // $date = $this->person->birth_date ?? ($this->birth_date ?? null);
|
||||
// $date = $this->birth_date ?? ($this->person->birth_date ?? null);
|
||||
// return Attribute::make(
|
||||
// get: fn () => !empty($date) ? Carbon::parse($date)->format('Y-m-d') : null
|
||||
// );
|
||||
// }
|
||||
|
||||
protected function birthDateeCard(): Attribute
|
||||
{
|
||||
// $date = $this->person->birth_date ?? ($this->birth_date ?? null);
|
||||
$date = $this->person->birth_date ?? ($this->birth_date ?? null);
|
||||
$date = $this->birth_date ?? ($this->birth_date ?? this->person->birth_date);
|
||||
return Attribute::make(
|
||||
get: fn () => !empty($date) ? Carbon::parse($date)->format('Y-m-d') : null
|
||||
get: fn () => !empty($date) ? Carbon::parse($date)->format('d / M / Y') : null
|
||||
);
|
||||
}
|
||||
|
||||
protected function startDate(): Attribute
|
||||
{
|
||||
// $date = $this->person->birth_date ?? ($this->birth_date ?? null);
|
||||
$date = $this->members_effective_date;
|
||||
return Attribute::make(
|
||||
get: fn () => !empty($date) ? Carbon::parse($date)->format('d / M / Y') : null
|
||||
);
|
||||
}
|
||||
|
||||
protected function endDate(): Attribute
|
||||
{
|
||||
// $date = $this->person->birth_date ?? ($this->birth_date ?? null);
|
||||
$date = $this->members_expire_date;
|
||||
return Attribute::make(
|
||||
get: fn () => !empty($date) ? Carbon::parse($date)->format('d / M / Y') : null
|
||||
);
|
||||
}
|
||||
|
||||
protected function gender(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->person->gender ?? null
|
||||
get: fn () => ucfirst($this->person->gender) ?? null
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
99
app/Models/RequestDailyMonitoring.php
Normal file
99
app/Models/RequestDailyMonitoring.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use DB;
|
||||
|
||||
class RequestDailyMonitoring extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = "request_log_daily_monitorings";
|
||||
|
||||
protected $fillable = [
|
||||
'request_log_id',
|
||||
'subject',
|
||||
'body_temperature',
|
||||
'respiration_rate',
|
||||
'sistole',
|
||||
'diastole',
|
||||
'analysis',
|
||||
'lab_date',
|
||||
'provider',
|
||||
'examination',
|
||||
];
|
||||
|
||||
protected $appends = ['medical_plan', 'non_medikamentosa_plan', 'document', 'discharge_date'];
|
||||
|
||||
public function getBodyTemperatureAttribute()
|
||||
{
|
||||
return round($this->attributes['body_temperature'], 0);
|
||||
}
|
||||
|
||||
public function getSistoleAttribute()
|
||||
{
|
||||
return round($this->attributes['sistole'], 0);
|
||||
}
|
||||
|
||||
public function getDiastoleAttribute()
|
||||
{
|
||||
return round($this->attributes['diastole'], 0);
|
||||
}
|
||||
|
||||
public function getRespirationRateAttribute()
|
||||
{
|
||||
return round($this->attributes['respiration_rate'], 0);
|
||||
}
|
||||
|
||||
public function getMedicalPlanAttribute()
|
||||
{
|
||||
$arr_medical_plan = [];
|
||||
$medical_plan = DB::table('request_log_medical_plan')->where(['request_log_daily_monitoring_id' => $this->attributes['id'], 'type' => 1])->get();
|
||||
|
||||
foreach ($medical_plan as $row) {
|
||||
$arr_medical_plan[] = [
|
||||
'medical_plan_str' => $row->plan
|
||||
];
|
||||
}
|
||||
|
||||
return $arr_medical_plan;
|
||||
}
|
||||
|
||||
public function getNonMedikamentosaPlanAttribute()
|
||||
{
|
||||
$arr_non_medikamentosa_plan = [];
|
||||
$non_medikamentosa_plan = DB::table('request_log_medical_plan')->where(['request_log_daily_monitoring_id' => $this->attributes['id'], 'type' => 2])->get();
|
||||
|
||||
foreach ($non_medikamentosa_plan as $row) {
|
||||
$arr_non_medikamentosa_plan[] = [
|
||||
'non_medikamentosa_plan_str' => $row->plan
|
||||
];
|
||||
}
|
||||
|
||||
return $arr_non_medikamentosa_plan;
|
||||
}
|
||||
|
||||
public function getDocumentAttribute()
|
||||
{
|
||||
$arr_document = [];
|
||||
$document = DB::table('files')->where(['fileable_type' => 'App\Models\LaboratoriumResult', 'fileable_id' => $this->attributes['id']])->get();
|
||||
|
||||
foreach ($document as $row) {
|
||||
$arr_document[] = [
|
||||
'file_name' => $row->original_name,
|
||||
'path' => env('APP_URL') . '/storage/lab_result/' . $row->original_name,
|
||||
'type' => $row->type,
|
||||
];
|
||||
}
|
||||
|
||||
return $arr_document;
|
||||
}
|
||||
|
||||
public function getDischargeDateAttribute()
|
||||
{
|
||||
return $discharge_date = DB::table('request_logs')->where('id', $this->attributes['request_log_id'])->select('discharge_date')->first();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('request_log_medical_plan', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('request_log_daily_monitoring_id');
|
||||
$table->string('plan');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('request_log_medical_plan');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('request_log_medical_plan', function (Blueprint $table) {
|
||||
$table->integer('type')->after('plan');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('request_log_medical_plan', function (Blueprint $table) {
|
||||
$table->dropColumn('type');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -22,6 +22,8 @@ import TableMoreMenu from '@/components/table/TableMoreMenu';
|
||||
*/
|
||||
import { fDate } from "@/utils/formatTime";
|
||||
import { ClaimListType } from "../Model/Types";
|
||||
import { ClearOutlined, LoopOutlined } from "@mui/icons-material";
|
||||
import DialogConfirmation from "./DialogConfirmation";
|
||||
|
||||
type Props = {
|
||||
row: ClaimListType,
|
||||
@@ -30,6 +32,14 @@ type Props = {
|
||||
|
||||
export default function ClaimListRow ({ ...props }: Props) {
|
||||
const navigate = useNavigate()
|
||||
const [openDialogSubmit, setOpenDialogSubmit] = useState(false);
|
||||
const [code, setCode] = useState('');
|
||||
const [member_id, setMemberId] = useState('');
|
||||
const handleUpdate = (code: string, member_id: string) => {
|
||||
setOpenDialogSubmit(true)
|
||||
setMemberId(member_id)
|
||||
setCode(code)
|
||||
}
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
@@ -87,21 +97,45 @@ export default function ClaimListRow ({ ...props }: Props) {
|
||||
</TableCell>
|
||||
<TableCell align="right" onClick={(e) => e.stopPropagation()}>
|
||||
<Stack direction="row" justifyContent="flex-end" spacing={1}>
|
||||
<TableMoreMenu actions={
|
||||
<>
|
||||
<MenuItem onClick={() => navigate(`/case_management/daily_monitoring/${props.row.member_id}/claims/${props.row.claim_code}/list_monitoring`)}>
|
||||
<Visibility />
|
||||
View
|
||||
</MenuItem>
|
||||
<MenuItem onClick={() => navigate(`/case_management/daily_monitoring/${props.row.member_id}/claims/${props.row.claim_code}/add_monitoring`)}>
|
||||
<AddIcon />
|
||||
Daily Monitoring
|
||||
</MenuItem>
|
||||
</>
|
||||
} />
|
||||
{props.row.discharge_date == null ?
|
||||
(
|
||||
<TableMoreMenu actions={
|
||||
<>
|
||||
<MenuItem onClick={() => navigate(`/case_management/daily_monitoring/${props.row.member_id}/claims/${props.row.code}/list_monitoring`)}>
|
||||
<Visibility />
|
||||
View
|
||||
</MenuItem>
|
||||
<MenuItem onClick={() => navigate(`/case_management/daily_monitoring/${props.row.member_id}/claims/${props.row.code}/add_monitoring`)}>
|
||||
<AddIcon />
|
||||
Daily Monitoring
|
||||
</MenuItem>
|
||||
<MenuItem onClick={() => handleUpdate(props.row.code, props.row.member_id)}>
|
||||
<LoopOutlined />
|
||||
Update Status
|
||||
</MenuItem>
|
||||
</>
|
||||
} />
|
||||
) :
|
||||
(
|
||||
<TableMoreMenu actions={
|
||||
<>
|
||||
<MenuItem onClick={() => navigate(`/case_management/daily_monitoring/${props.row.member_id}/claims/${props.row.code}/list_monitoring`)}>
|
||||
<Visibility />
|
||||
View
|
||||
</MenuItem>
|
||||
</>
|
||||
} />
|
||||
)
|
||||
}
|
||||
|
||||
</Stack>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<DialogConfirmation
|
||||
setOpenDialog={setOpenDialogSubmit}
|
||||
row={props.row}
|
||||
openDialog={openDialogSubmit}
|
||||
/>
|
||||
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
import { useFieldArray, useForm } from 'react-hook-form';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { Box, IconButton, Typography, Grid, Card, Button } from '@mui/material';
|
||||
import { Box, IconButton, Typography, Grid, Card, Button, ButtonBase, Stack } from '@mui/material';
|
||||
import { LoadingButton } from "@mui/lab";
|
||||
|
||||
/**
|
||||
@@ -13,6 +13,7 @@ import { LoadingButton } from "@mui/lab";
|
||||
*/
|
||||
import Page from '@/components/Page';
|
||||
import { FormProvider, RHFTextField } from '@/components/hook-form';
|
||||
import RHFDatePickerV2 from '@/components/hook-form/RHFDatePickerV2';
|
||||
|
||||
/**
|
||||
* Icon
|
||||
@@ -21,6 +22,7 @@ import { FormProvider, RHFTextField } from '@/components/hook-form';
|
||||
import ArrowBackIosNew from '@mui/icons-material/ArrowBackIosNew';
|
||||
import AddIcon from '@mui/icons-material/Add';
|
||||
import RemoveIcon from '@mui/icons-material/Remove';
|
||||
import InsertDriveFileIcon from '@mui/icons-material/InsertDriveFile';
|
||||
|
||||
/**
|
||||
* Utils, Types, Functions
|
||||
@@ -28,11 +30,18 @@ import RemoveIcon from '@mui/icons-material/Remove';
|
||||
*/
|
||||
import { AddMonitoringDetail } from '../Model/Functions';
|
||||
import { DetailMonitoringListType} from '../Model/Types';
|
||||
import FormCreateFilesUpload from '@/pages/CustomerService/FinalLog/Components/FormCreateFilesUpload';
|
||||
import MultiFilePreview from '@/components/upload/MultiFilePreview';
|
||||
import Iconify from '@/components/Iconify';
|
||||
import { useRef } from 'react';
|
||||
|
||||
export default function DetailMonitoringList() {
|
||||
const { member_id, claim_code } = useParams();
|
||||
const navigate = useNavigate()
|
||||
const pageTitle = claim_code??'_ _ _ _';
|
||||
const fileInput1 = useRef<HTMLInputElement>(null);
|
||||
const fileInput2 = useRef<HTMLInputElement>(null);
|
||||
const fileInput3 = useRef<HTMLInputElement>(null);
|
||||
|
||||
// setup form
|
||||
// ====================================
|
||||
@@ -50,16 +59,99 @@ export default function DetailMonitoringList() {
|
||||
medical_plan : [{
|
||||
medical_plan_str: ''
|
||||
}],
|
||||
created_at : ''
|
||||
non_medikamentosa_plan : [{
|
||||
non_medikamentosa_plan_str: ''
|
||||
}],
|
||||
confirmation_medical_leter : [],
|
||||
medical_action_letter : [],
|
||||
result : [],
|
||||
created_at : '',
|
||||
lab_date : '',
|
||||
provider : '',
|
||||
examination : '',
|
||||
};
|
||||
|
||||
const methods = useForm<any>({
|
||||
defaultValues
|
||||
});
|
||||
|
||||
const {fields, append, remove} = useFieldArray({name: 'medical_plan',control: methods.control})
|
||||
const {fields: fields1, append: append1, remove: remove1} = useFieldArray({name: 'medical_plan',control: methods.control})
|
||||
const {fields: fields2, append: append2, remove: remove2} = useFieldArray({name: 'non_medikamentosa_plan',control: methods.control})
|
||||
|
||||
const { handleSubmit, reset, formState: { isDirty, isSubmitting } } = methods;
|
||||
const { handleSubmit, reset, watch, setValue, formState: { isDirty, isSubmitting } } = methods;
|
||||
const formValues = watch();
|
||||
// Handle File Input
|
||||
// =====================================
|
||||
const handleInputChangeConfirmationMedicalLeter = (event: any) => {
|
||||
if (event.target.files[0]) {
|
||||
|
||||
let arr_confirmation_medical_leter_file = formValues.confirmation_medical_leter;
|
||||
arr_confirmation_medical_leter_file.push(event.target.files[0]);
|
||||
|
||||
setValue('confirmation_medical_leter', arr_confirmation_medical_leter_file);
|
||||
}
|
||||
else {
|
||||
console.log('NO FILE');
|
||||
}
|
||||
};
|
||||
const handleInputChangeMedicalActionLetter = (event: any) => {
|
||||
if (event.target.files[0]) {
|
||||
|
||||
let arr_medical_action_letter = formValues.medical_action_letter;
|
||||
arr_medical_action_letter.push(event.target.files[0]);
|
||||
|
||||
setValue('medical_action_letter', arr_medical_action_letter)
|
||||
console.log('test2')
|
||||
}
|
||||
else {
|
||||
console.log('NO FILE');
|
||||
}
|
||||
};
|
||||
|
||||
const handleInputChangeResult = (event: any) => {
|
||||
if (event.target.files[0]) {
|
||||
|
||||
let arr_result = formValues.result;
|
||||
arr_result.push(event.target.files[0]);
|
||||
|
||||
setValue('result', arr_result)
|
||||
console.log('test3')
|
||||
}
|
||||
else {
|
||||
console.log('NO FILE');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Handle Remove File
|
||||
// =====================================
|
||||
const handleRemoveFileConfirmationMedicalLeter = (target_index: number) => {
|
||||
let arr_confirmation_medical_leter_file = formValues.confirmation_medical_leter.filter((file: any, index: number) =>{
|
||||
if (target_index !== index) {
|
||||
return file;
|
||||
}
|
||||
});
|
||||
|
||||
setValue('confirmation_medical_leter', arr_confirmation_medical_leter_file)
|
||||
};
|
||||
const handleRemoveFileMedicalActionLetter = (target_index: number) => {
|
||||
let arr_medical_action_letter = formValues.medical_action_letter.filter((file: any, index: number) =>{
|
||||
if (target_index !== index) {
|
||||
return file;
|
||||
}
|
||||
});
|
||||
|
||||
setValue('medical_action_letter', arr_medical_action_letter)
|
||||
};
|
||||
const handleRemoveFileResult = (target_index: number) => {
|
||||
let arr_result = formValues.result.filter((file: any, index: number) =>{
|
||||
if (target_index !== index) {
|
||||
return file;
|
||||
}
|
||||
});
|
||||
|
||||
setValue('result', arr_result)
|
||||
};
|
||||
|
||||
// Submit Form
|
||||
// =====================================
|
||||
@@ -70,8 +162,8 @@ export default function DetailMonitoringList() {
|
||||
|
||||
if (response == true) {
|
||||
reset();
|
||||
navigate('case_management/daily_monitoring/'+claim_code+'claims');
|
||||
window.location.reload()
|
||||
navigate('/case_management/daily_monitoring/'+member_id+'/claims', { replace: true });
|
||||
// window.location.reload()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,7 +289,7 @@ export default function DetailMonitoringList() {
|
||||
</Grid>
|
||||
|
||||
{/* Complaints */}
|
||||
<Grid item xs={12}>
|
||||
{/* <Grid item xs={12}>
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="body1" component="div">
|
||||
@@ -212,7 +304,7 @@ export default function DetailMonitoringList() {
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid> */}
|
||||
|
||||
{/* Analysis */}
|
||||
<Grid item xs={12}>
|
||||
@@ -242,7 +334,7 @@ export default function DetailMonitoringList() {
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{
|
||||
fields.map((field,index) => {
|
||||
fields1.map((field,index) => {
|
||||
return (
|
||||
<Grid key={field.id} container sx={{ mb: 3 }}>
|
||||
<Grid item xs={11}>
|
||||
@@ -253,10 +345,10 @@ export default function DetailMonitoringList() {
|
||||
/>
|
||||
</Grid>
|
||||
{
|
||||
index == (fields.length-1) ?
|
||||
index == (fields1.length-1) ?
|
||||
(
|
||||
<Grid item xs={1} sx={{ textAlign: 'center' }}>
|
||||
<IconButton size='large' color='primary' onClick={() => append({medical_plan_str: ''})}>
|
||||
<IconButton size='large' color='primary' onClick={() => append1({medical_plan_str: ''})}>
|
||||
<AddIcon />
|
||||
</IconButton>
|
||||
</Grid>
|
||||
@@ -264,7 +356,7 @@ export default function DetailMonitoringList() {
|
||||
:
|
||||
(
|
||||
<Grid item xs={1} sx={{ textAlign: 'center' }}>
|
||||
<IconButton size='large' color='error' onClick={() => remove(index)}>
|
||||
<IconButton size='large' color='error' onClick={() => remove1(index)}>
|
||||
<RemoveIcon />
|
||||
</IconButton>
|
||||
</Grid>
|
||||
@@ -278,7 +370,268 @@ export default function DetailMonitoringList() {
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
{/* Button Cancle & Save */}
|
||||
{/* Non Medikamentosa Plan* */}
|
||||
<Grid item xs={12}>
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="body1" component="div">
|
||||
Non Medikamentosa Plan* :
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{
|
||||
fields2.map((field,index) => {
|
||||
return (
|
||||
<Grid key={field.id} container sx={{ mb: 3 }}>
|
||||
<Grid item xs={11}>
|
||||
<RHFTextField
|
||||
id="analysis"
|
||||
name={`non_medikamentosa_plan.${index}.non_medikamentosa_plan_str`}
|
||||
placeholder='Non Medikamentosa'
|
||||
/>
|
||||
</Grid>
|
||||
{
|
||||
index == (fields2.length-1) ?
|
||||
(
|
||||
<Grid item xs={1} sx={{ textAlign: 'center' }}>
|
||||
<IconButton size='large' color='primary' onClick={() => append2({non_medikamentosa_plan_str: ''})}>
|
||||
<AddIcon />
|
||||
</IconButton>
|
||||
</Grid>
|
||||
)
|
||||
:
|
||||
(
|
||||
<Grid item xs={1} sx={{ textAlign: 'center' }}>
|
||||
<IconButton size='large' color='error' onClick={() => remove2(index)}>
|
||||
<RemoveIcon />
|
||||
</IconButton>
|
||||
</Grid>
|
||||
)
|
||||
}
|
||||
</Grid>
|
||||
)
|
||||
})
|
||||
}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
{/* Confirmation Medical Letter */}
|
||||
<Grid item xs={12}>
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="body1" component="div">
|
||||
Confirmation Medical Letter*
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{
|
||||
formValues.confirmation_medical_leter.map((file: any, index: number) => (
|
||||
<Stack direction="row" justifyContent={'space-between'} key={index} sx={{ mb: '16px' }}>
|
||||
<Stack direction="row" spacing={1} sx={{color: '#19BBBB'}}>
|
||||
<InsertDriveFileIcon />
|
||||
<Typography variant="body2" gutterBottom>{file.name ? file.name : '-'}</Typography>
|
||||
</Stack>
|
||||
<Iconify
|
||||
icon="eva:trash-2-outline"
|
||||
color={'darkred'}
|
||||
onClick={() => handleRemoveFileConfirmationMedicalLeter(index)}
|
||||
sx={{cursor: 'pointer'}}
|
||||
></Iconify>
|
||||
</Stack>
|
||||
))
|
||||
}
|
||||
</Grid>
|
||||
<Grid item xs={12} sx={{display: 'flex', gap: 1}}>
|
||||
<ButtonBase sx={{ p: 4, border: '2px dashed #F9FAFB',bgcolor: '#919EAB52',borderRadius: '8px',width: '100%', height: '60px'}} onClick={() => fileInput1.current?.click()}>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
placeItems: 'center',
|
||||
gap: 1,
|
||||
placeContent: 'center',
|
||||
}}
|
||||
>
|
||||
<Iconify icon="icon-park-outline:upload-one" fontSize="3em" />
|
||||
<Typography variant="body1" fontWeight="bold">
|
||||
Upload File
|
||||
</Typography>
|
||||
</Box>
|
||||
<input
|
||||
type="file"
|
||||
id="file_input"
|
||||
ref={fileInput1}
|
||||
style={{ display: 'none' }}
|
||||
multiple
|
||||
onChange={(e) => handleInputChangeConfirmationMedicalLeter(e)}
|
||||
accept="application/pdf"
|
||||
/>
|
||||
</ButtonBase>
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
{/* Medical Action Letter */}
|
||||
<Grid item xs={12}>
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="body1" component="div">
|
||||
Medical Action Letter*
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{
|
||||
formValues.medical_action_letter.map((file: any, index: number) => (
|
||||
<Stack direction="row" justifyContent={'space-between'} key={index} sx={{ mb: '16px' }}>
|
||||
<Stack direction="row" spacing={1} sx={{color: '#19BBBB'}}>
|
||||
<InsertDriveFileIcon />
|
||||
<Typography variant="body2" gutterBottom>{file.name ? file.name : '-'}</Typography>
|
||||
</Stack>
|
||||
<Iconify
|
||||
icon="eva:trash-2-outline"
|
||||
color={'darkred'}
|
||||
onClick={() => handleRemoveFileMedicalActionLetter(index)}
|
||||
sx={{cursor: 'pointer'}}
|
||||
></Iconify>
|
||||
</Stack>
|
||||
))
|
||||
}
|
||||
</Grid>
|
||||
<Grid item xs={12} sx={{display: 'flex', gap: 1}}>
|
||||
<ButtonBase sx={{ p: 4, border: '2px dashed #F9FAFB',bgcolor: '#919EAB52',borderRadius: '8px',width: '100%', height: '60px'}} onClick={() => fileInput2.current?.click()}>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
placeItems: 'center',
|
||||
gap: 1,
|
||||
placeContent: 'center',
|
||||
}}
|
||||
>
|
||||
<Iconify icon="icon-park-outline:upload-one" fontSize="3em" />
|
||||
<Typography variant="body1" fontWeight="bold">
|
||||
Upload File
|
||||
</Typography>
|
||||
</Box>
|
||||
<input
|
||||
type="file"
|
||||
id="file_2"
|
||||
ref={fileInput2}
|
||||
style={{ display: 'none' }}
|
||||
multiple
|
||||
onChange={handleInputChangeMedicalActionLetter}
|
||||
accept="application/pdf"
|
||||
/>
|
||||
</ButtonBase>
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
|
||||
{/* Laboratorium */}
|
||||
<Grid item xs={12}>
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="body1" component="div">
|
||||
Laboratorium Result*
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Typography variant="body1" component="div">
|
||||
Date*
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Typography variant="body1" component="div">
|
||||
Provider*
|
||||
</Typography>
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={6} sx={{display: 'flex', gap: 1}}>
|
||||
<RHFDatePickerV2
|
||||
label='Date'
|
||||
name="lab_date"
|
||||
dateFormat='dd MMM yyyy'
|
||||
fullWidth
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={6} sx={{display: 'flex', gap: 1}}>
|
||||
<RHFTextField
|
||||
id="provider"
|
||||
name='provider'
|
||||
placeholder='Provider'
|
||||
label='Provider'
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="body1" component="div">
|
||||
Examination*
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} sx={{display: 'flex', gap: 1}}>
|
||||
<RHFTextField
|
||||
id="examination"
|
||||
name='examination'
|
||||
placeholder='examination'
|
||||
label='Examination'
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="body1" component="div">
|
||||
Laboratorium Result*
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{
|
||||
formValues.result.map((file: any, index: number) => (
|
||||
<Stack direction="row" justifyContent={'space-between'} key={index} sx={{ mb: '16px' }}>
|
||||
<Stack direction="row" spacing={1} sx={{color: '#19BBBB'}}>
|
||||
<InsertDriveFileIcon />
|
||||
<Typography variant="body2" gutterBottom>{file.name ? file.name : '-'}</Typography>
|
||||
</Stack>
|
||||
<Iconify
|
||||
icon="eva:trash-2-outline"
|
||||
color={'darkred'}
|
||||
onClick={() => handleRemoveFileResult(index)}
|
||||
sx={{cursor: 'pointer'}}
|
||||
></Iconify>
|
||||
</Stack>
|
||||
))
|
||||
}
|
||||
</Grid>
|
||||
<Grid item xs={12} sx={{display: 'flex', gap: 1}}>
|
||||
<ButtonBase sx={{ p: 4, border: '2px dashed #F9FAFB',bgcolor: '#919EAB52',borderRadius: '8px',width: '100%', height: '60px'}} onClick={() => fileInput3.current?.click()}>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
placeItems: 'center',
|
||||
gap: 1,
|
||||
placeContent: 'center',
|
||||
}}
|
||||
>
|
||||
<Iconify icon="icon-park-outline:upload-one" fontSize="3em" />
|
||||
<Typography variant="body1" fontWeight="bold">
|
||||
Upload File
|
||||
</Typography>
|
||||
</Box>
|
||||
<input
|
||||
type="file"
|
||||
id="file_3"
|
||||
ref={fileInput3}
|
||||
style={{ display: 'none' }}
|
||||
multiple
|
||||
onChange={handleInputChangeResult}
|
||||
accept="application/pdf"
|
||||
/>
|
||||
</ButtonBase>
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
|
||||
{/* Button Cancel & Save */}
|
||||
<Grid item xs={12} md={12}>
|
||||
<Box display="flex" justifyContent={'flex-end'}>
|
||||
<Box display="flex" gap={1}>
|
||||
@@ -286,7 +639,7 @@ export default function DetailMonitoringList() {
|
||||
Cancel
|
||||
</Button>
|
||||
<LoadingButton disabled={!isDirty} type="submit" variant="contained" loading={isSubmitting}>
|
||||
Save Changes
|
||||
Add
|
||||
</LoadingButton>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
@@ -27,7 +27,7 @@ import FiberManualRecord from '@mui/icons-material/FiberManualRecord';
|
||||
* Utils, Types, Functions
|
||||
* ============================================
|
||||
*/
|
||||
import { fDate } from "@/utils/formatTime";
|
||||
import { fDate, fDateOnly } from '@/utils/formatTime';
|
||||
import { getMonitoringDetailList } from '../Model/Functions';
|
||||
import { DetailMonitoringListType } from '../Model/Types';
|
||||
|
||||
@@ -87,6 +87,22 @@ export default function DetailMonitoringList() {
|
||||
>
|
||||
{row.created_at ? fDate(row.created_at) : '-'}
|
||||
</Label>
|
||||
|
||||
{row.discharge_date.discharge_date ?
|
||||
(<Label
|
||||
variant="ghost"
|
||||
color="success"
|
||||
sx={{marginLeft: '85%'}}
|
||||
>
|
||||
Close Monitoring
|
||||
</Label>) : (<Label
|
||||
variant="ghost"
|
||||
color="warning"
|
||||
sx={{marginLeft: '77%'}}
|
||||
>
|
||||
On Monitoring
|
||||
</Label>)}
|
||||
|
||||
</Box>
|
||||
|
||||
{/* card body */}
|
||||
@@ -160,21 +176,6 @@ export default function DetailMonitoringList() {
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={12}>
|
||||
<Grid container gap={1}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="body1" sx={{ fontWeight: 'bold' }}>
|
||||
Subject :
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="body2" color={"GrayText"}>
|
||||
{row.subject}
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={12}>
|
||||
<Grid container gap={1}>
|
||||
<Grid item xs={12}>
|
||||
@@ -190,21 +191,6 @@ export default function DetailMonitoringList() {
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={12}>
|
||||
<Grid container gap={1}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="body1" sx={{ fontWeight: 'bold' }}>
|
||||
Complaints :
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="body2" color={"GrayText"}>
|
||||
{row.complaints}
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={12}>
|
||||
<Grid container gap={1}>
|
||||
<Grid item xs={12}>
|
||||
@@ -215,7 +201,7 @@ export default function DetailMonitoringList() {
|
||||
<Grid item xs={12}>
|
||||
<List sx={{ color: 'GrayText' }}>
|
||||
{
|
||||
row.medical_plan.map((data, index) => {
|
||||
row.medical_plan?.map((data, index) => {
|
||||
return (
|
||||
<ListItem key={index}>
|
||||
<FiberManualRecord sx={{ fontSize: '8px', mr: '10px' }} /> {data.medical_plan_str}
|
||||
@@ -227,6 +213,164 @@ export default function DetailMonitoringList() {
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={12}>
|
||||
<Grid container gap={1}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="body1" sx={{ fontWeight: 'bold' }}>
|
||||
Non Medikamentosa Plan :
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<List sx={{ color: 'GrayText' }}>
|
||||
{
|
||||
row.non_medikamentosa_plan?.map((data, index) => {
|
||||
return (
|
||||
<ListItem key={index}>
|
||||
<FiberManualRecord sx={{ fontSize: '8px', mr: '10px' }} /> {data.non_medikamentosa_plan_str}
|
||||
</ListItem>
|
||||
)
|
||||
})
|
||||
}
|
||||
</List>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={12}>
|
||||
<Grid container gap={1}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="body1" sx={{ fontWeight: 'bold' }}>
|
||||
Laboratorium Result :
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={6}>
|
||||
<Typography variant="body1" sx={{ fontWeight: 'bold' }}>
|
||||
Date
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Typography variant="body2" color={"GrayText"}>
|
||||
{ row.lab_date != null ? fDate(row.lab_date) : '-'}
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={6}>
|
||||
<Typography variant="body1" sx={{ fontWeight: 'bold' }}>
|
||||
Location
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Typography variant="body2" color={"GrayText"}>
|
||||
{row.provider}
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={6}>
|
||||
<Typography variant="body1" sx={{ fontWeight: 'bold' }}>
|
||||
Examination
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Typography variant="body2" color={"GrayText"}>
|
||||
{row.examination}
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={12}>
|
||||
<Grid container gap={1}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="body1" sx={{ fontWeight: 'bold' }}>
|
||||
Document Confirmation Medical Letter:
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<List sx={{ color: 'GrayText' }}>
|
||||
{row.document?.map((data, index) => (
|
||||
<ListItem key={index}>
|
||||
{data.type === 'confirmation-medical-letter' ? (
|
||||
<>
|
||||
<FiberManualRecord sx={{ fontSize: '8px', mr: '10px' }} />
|
||||
<a
|
||||
href={data.path} // Replace 'data.download_link' with the actual download link
|
||||
target="_blank" // Optional: Open the link in a new tab
|
||||
rel="noopener noreferrer" // Recommended when using target="_blank"
|
||||
>
|
||||
{data.file_name}
|
||||
</a>
|
||||
</>
|
||||
) : null}
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Grid container gap={1}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="body1" sx={{ fontWeight: 'bold' }}>
|
||||
Document Medical Action Letter:
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<List sx={{ color: 'GrayText' }}>
|
||||
{row.document?.map((data, index) => (
|
||||
<ListItem key={index}>
|
||||
{data.type === 'medical-action-letter' ? (
|
||||
<>
|
||||
<FiberManualRecord sx={{ fontSize: '8px', mr: '10px' }} />
|
||||
<a
|
||||
href={data.path} // Replace 'data.download_link' with the actual download link
|
||||
target="_blank" // Optional: Open the link in a new tab
|
||||
rel="noopener noreferrer" // Recommended when using target="_blank"
|
||||
>
|
||||
{data.file_name}
|
||||
</a>
|
||||
</>
|
||||
) : null}
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Grid container gap={1}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="body1" sx={{ fontWeight: 'bold' }}>
|
||||
Document Laboratorium Result:
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<List sx={{ color: 'GrayText' }}>
|
||||
{row.document?.map((data, index) => (
|
||||
<ListItem key={index}>
|
||||
{data.type === 'laboratorium-result' ? (
|
||||
<>
|
||||
<FiberManualRecord sx={{ fontSize: '8px', mr: '10px' }} />
|
||||
<a
|
||||
href={data.path} // Replace 'data.download_link' with the actual download link
|
||||
target="_blank" // Optional: Open the link in a new tab
|
||||
rel="noopener noreferrer" // Recommended when using target="_blank"
|
||||
>
|
||||
{data.file_name}
|
||||
</a>
|
||||
</>
|
||||
) : null}
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
</Card>
|
||||
</Grid>
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
import MuiDialog from "@/components/MuiDialog";
|
||||
import { Button, Card, Checkbox, DialogActions, Grid, Typography } from "@mui/material";
|
||||
import { Paper } from "@mui/material";
|
||||
import { Stack } from '@mui/material';
|
||||
import React, { useState } from 'react';
|
||||
import { fDate, fDateTimesecond, toTitleCase } from "@/utils/formatTime";
|
||||
import axios from "@/utils/axios";
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
import { useNavigate } from "react-router";
|
||||
import { replace } from "lodash";
|
||||
import { ClaimListType } from "../Model/Types";
|
||||
import Label from "@/components/Label";
|
||||
|
||||
|
||||
type DialogConfirmationType = {
|
||||
openDialog: boolean;
|
||||
setOpenDialog: any;
|
||||
onSubmit?: void;
|
||||
row: ClaimListType;
|
||||
}
|
||||
|
||||
export default function DialogConfirmation({ setOpenDialog, openDialog, row} : DialogConfirmationType ) {
|
||||
|
||||
const navigate = useNavigate();
|
||||
const handleSubmit = () => {
|
||||
axios
|
||||
.post(`case_management/daily_monitoring/detail/${row.code}/update-status`)
|
||||
.then((response) => {
|
||||
enqueueSnackbar('Close Monitoring Success', { variant: 'success' });
|
||||
setOpenDialog(false);
|
||||
navigate(`/case_management/daily_monitoring/${row.member_id}/claims`, { replace: true })
|
||||
window.location.reload();
|
||||
})
|
||||
.catch(({ response }) => {
|
||||
enqueueSnackbar(response.data.message ?? 'Something went wrong!', { variant: 'error' });
|
||||
});
|
||||
}
|
||||
|
||||
const style1 = {
|
||||
color: '#919EAB',
|
||||
width: '30%'
|
||||
}
|
||||
const style2 = {
|
||||
width: '70%'
|
||||
}
|
||||
const marginBottom1 = {
|
||||
marginBottom: 1,
|
||||
}
|
||||
|
||||
const handleCloseDialog = () => {
|
||||
setOpenDialog(false);
|
||||
}
|
||||
|
||||
const getContent = () => (
|
||||
<Stack spacing={1} marginTop={2}>
|
||||
<Typography variant="subtitle2">Are you sure to closed this monitoring ?</Typography>
|
||||
<Grid item xs={12} md={12} marginTop={4}>
|
||||
<Card sx={{padding:2, marginTop:2}} >
|
||||
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||
<Typography variant='subtitle2' sx={style1} gutterBottom>Name</Typography>
|
||||
<Typography variant='subtitle2' sx={style2} gutterBottom>{row.name}</Typography>
|
||||
</Stack>
|
||||
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||
<Typography variant='subtitle2' sx={style1} gutterBottom>Code</Typography>
|
||||
<Typography variant='subtitle2' sx={style2} gutterBottom>{row.code}</Typography>
|
||||
</Stack>
|
||||
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||
<Typography variant='subtitle2' sx={style1} gutterBottom>Admision Date</Typography>
|
||||
<Typography variant='subtitle2' sx={style2} gutterBottom> <Label variant="ghost">{fDate(row.admission_date)}</Label></Typography>
|
||||
</Stack>
|
||||
</Card>
|
||||
</Grid>
|
||||
<DialogActions>
|
||||
<Button variant="outlined" sx={{color: '#212B36', borderColor: '#919EAB52'}} onClick={handleCloseDialog}>Cancel</Button>
|
||||
<Button color="primary" variant="contained" onClick={handleSubmit}>Yes</Button>
|
||||
|
||||
|
||||
</DialogActions>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
|
||||
return (
|
||||
<MuiDialog
|
||||
title={{name: "Confirmation"}}
|
||||
openDialog={openDialog}
|
||||
setOpenDialog={setOpenDialog}
|
||||
content={getContent()}
|
||||
maxWidth="sm"
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
import axios from '@/utils/axios';
|
||||
import { makeFormData } from '@/utils/jsonToFormData';
|
||||
import { enqueueSnackbar } from 'notistack';
|
||||
import { DailyMonitoringListType, DetailMonitoringListType, ResponseListingClaimType } from "./Types";
|
||||
import { fDate, fDateOnly } from '@/utils/formatTime';
|
||||
|
||||
/**
|
||||
* Listing Daily Monitoring
|
||||
@@ -44,9 +46,11 @@ export const getClaimList = async ( member_id: string ): Promise<ResponseListing
|
||||
* Add Monitoring Detail
|
||||
*/
|
||||
export const AddMonitoringDetail = async ( claim_code: string,data: DetailMonitoringListType ): Promise<boolean> => {
|
||||
const response = await axios.post(`/case_management/daily_monitoring/detail/${claim_code}/add`, {
|
||||
...data
|
||||
})
|
||||
data.lab_date = data.lab_date != '' && data.lab_date != null ? fDateOnly(data.lab_date) : '';
|
||||
|
||||
const formData = makeFormData({...data});
|
||||
|
||||
const response = await axios.post(`/case_management/daily_monitoring/detail/${claim_code}/add-request`, formData)
|
||||
.then((res) =>{
|
||||
enqueueSnackbar(res.data.message, {
|
||||
variant: 'success',
|
||||
|
||||
@@ -35,6 +35,9 @@ export type ClaimListType = {
|
||||
admission_date : string,
|
||||
discharge_date : string,
|
||||
claim_code : string,
|
||||
name : string,
|
||||
code : string,
|
||||
service_name : string,
|
||||
claim_status : string,
|
||||
service_type : string,
|
||||
member_id : string
|
||||
@@ -54,10 +57,32 @@ export type DetailMonitoringListType = {
|
||||
diastole : string
|
||||
analysis : string,
|
||||
complaints : string,
|
||||
lab_date : string,
|
||||
provider : string,
|
||||
examination : string,
|
||||
medical_plan : MedicalPlanStrType[],
|
||||
non_medikamentosa_plan : NonMedikamentosaPlanType[],
|
||||
confirmation_medical_leter : files[],
|
||||
medical_action_letter : files[],
|
||||
result : files[],
|
||||
document : document[],
|
||||
created_at : string|null
|
||||
}
|
||||
|
||||
export type MedicalPlanStrType = {
|
||||
medical_plan_str: string
|
||||
}
|
||||
|
||||
export type NonMedikamentosaPlanType = {
|
||||
non_medikamentosa_plan_str: string
|
||||
}
|
||||
|
||||
export type files = {
|
||||
file: string
|
||||
}
|
||||
|
||||
export type document = {
|
||||
file_name: string,
|
||||
path: string,
|
||||
type: string
|
||||
}
|
||||
|
||||
@@ -94,6 +94,7 @@ export default function CorporatePlanList({handleSubmitSuccess}) {
|
||||
const { corporate_id } = useParams();
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const [importResult, setImportResult] = useState(null);
|
||||
const [sendResult, setSendResult] = useState(null);
|
||||
|
||||
const [openDialog, setOpenDialog] = useState(false);
|
||||
const [isDialog, setIsDialog] = useState('');
|
||||
@@ -267,6 +268,25 @@ export default function CorporatePlanList({handleSubmitSuccess}) {
|
||||
});
|
||||
}
|
||||
|
||||
const handleSendAllEcard = () => {
|
||||
setImportLoading(true);
|
||||
setDataTableLoading(true);
|
||||
axios
|
||||
.get(`send_card/${corporate_id}`)
|
||||
.then((response) => {
|
||||
loadDataTableData();
|
||||
})
|
||||
|
||||
.catch((response) => {
|
||||
enqueueSnackbar(
|
||||
'Looks like something went wrong. Please check your data and try again.',
|
||||
{ variant: 'error' }
|
||||
);
|
||||
setImportLoading(false);
|
||||
loadDataTableData();
|
||||
});
|
||||
}
|
||||
|
||||
const handleCancelImportButton = () => {
|
||||
importPlan.current.value = '';
|
||||
importPlan.current.dispatchEvent(new Event('change', { bubbles: true }));
|
||||
@@ -363,6 +383,9 @@ export default function CorporatePlanList({handleSubmitSuccess}) {
|
||||
<MenuItem onClick={handleMemberList}>
|
||||
<Typography variant='body2'>Download Member</Typography>
|
||||
</MenuItem>
|
||||
<MenuItem onClick={handleSendAllEcard}>
|
||||
<Typography variant='body2'>Send All Ecard</Typography>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</Stack>
|
||||
)}
|
||||
@@ -413,6 +436,7 @@ export default function CorporatePlanList({handleSubmitSuccess}) {
|
||||
</Box>
|
||||
</Stack>
|
||||
)}
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -470,6 +494,21 @@ export default function CorporatePlanList({handleSubmitSuccess}) {
|
||||
const style1 = {
|
||||
color: '#637381'
|
||||
}
|
||||
|
||||
|
||||
const handleDownloadEcard = (id: number) => {
|
||||
axios
|
||||
.get(`view_card/${id}`, {
|
||||
responseType: 'blob',
|
||||
})
|
||||
.then((response) => {
|
||||
window.open(URL.createObjectURL(response.data));
|
||||
})
|
||||
.catch((response) => {
|
||||
enqueueSnackbar(response.message, { variant: 'error' });
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
@@ -527,6 +566,10 @@ export default function CorporatePlanList({handleSubmitSuccess}) {
|
||||
<CachedOutlinedIcon />
|
||||
Update Status
|
||||
</MenuItem>
|
||||
<MenuItem onClick={() => handleDownloadEcard(row.id)}>
|
||||
<DownloadIcon />
|
||||
Download E-card
|
||||
</MenuItem>
|
||||
<MenuItem onClick={() => navigate ('/corporates/'+corporate_id+'/members/'+row.id+'/history')}>
|
||||
<HistoryIcon />
|
||||
History
|
||||
|
||||
@@ -98,8 +98,8 @@ export default function Router() {
|
||||
element: <Claim />,
|
||||
},
|
||||
{
|
||||
path: '/detail/:id',
|
||||
element: <DetailClaimReport />,
|
||||
path: '/claim/detail/:id',
|
||||
element: <DetailClaim />,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -126,3 +126,4 @@ const Claim = Loadable(lazy(() => import('@/pages/Claim')));
|
||||
const NotFound = Loadable(lazy(() => import('@/pages/Page404')));
|
||||
|
||||
const DetailClaimReport = Loadable(lazy(()=> import('@/sections/dashboard/Detail')));
|
||||
const DetailClaim = Loadable(lazy(()=> import('@/sections/claim/Detail')));
|
||||
|
||||
69
frontend/hospital-portal/src/sections/claim/Detail.tsx
Normal file
69
frontend/hospital-portal/src/sections/claim/Detail.tsx
Normal file
@@ -0,0 +1,69 @@
|
||||
// mui
|
||||
import { Container, Grid, Stack, Typography } from '@mui/material';
|
||||
// components
|
||||
import Page from '../../components/Page';
|
||||
// utils
|
||||
import useSettings from '../../hooks/useSettings';
|
||||
// section
|
||||
import CardFamilyInformation from '../../sections/alarm-center/user-profile/CardFamilyInformation';
|
||||
// react
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import ButtonBack from '../../components/ButtonBack';
|
||||
import { useEffect, useState, useContext } from 'react';
|
||||
import axios from '../../utils/axios';
|
||||
// pages
|
||||
import DetailTimeline from '../../sections/dashboard/DetailTimeline';
|
||||
import DetailStepper from '../../sections/dashboard/DetailStepper';
|
||||
import { format } from 'date-fns';
|
||||
import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos';
|
||||
import { LanguageContext } from '@/contexts/LanguageContext';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export default function Detail() {
|
||||
const { localeData }: any = useContext(LanguageContext);
|
||||
const navigate = useNavigate();
|
||||
const { themeStretch } = useSettings();
|
||||
const [data, setData] = useState();
|
||||
|
||||
const { id } = useParams();
|
||||
|
||||
useEffect(() => {
|
||||
axios
|
||||
.get('/detail-claim-requests/' + id)
|
||||
.then((response) => {
|
||||
setData(response.data);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Page title="Detail">
|
||||
<Container maxWidth={themeStretch ? false : 'xl'}>
|
||||
<Stack direction="row" alignItems="center" sx={{ marginBottom: 3 }}>
|
||||
<ArrowBackIosIcon onClick={() => navigate(-1)} sx={{cursor:'pointer'}}/>
|
||||
<Typography variant="h5" sx={{marginLeft:2}}>Detail</Typography>
|
||||
{data ? (
|
||||
<Stack direction="row" spacing={2} ml="auto">
|
||||
<Typography variant="body2" sx={{color: '#757575'}}>{localeData.txtDialogMember5}</Typography>
|
||||
<Typography variant="body2" fontWeight="bold">{(data && data.data) ? format(new Date(data.data.status.submission_date), "d MMM yyyy") : ''}</Typography>
|
||||
</Stack>
|
||||
) : ''}
|
||||
</Stack>
|
||||
{data ? (
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12} md={12}>
|
||||
<DetailStepper data={data}/>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={12}>
|
||||
<DetailTimeline data={data}/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
) : ''}
|
||||
</Container>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
import * as React from 'react';
|
||||
import Box from '@mui/material/Box';
|
||||
import Stepper from '@mui/material/Stepper';
|
||||
import Step from '@mui/material/Step';
|
||||
import StepLabel from '@mui/material/StepLabel';
|
||||
import { useEffect, useState } from 'react';
|
||||
import ClearIcon from '@mui/icons-material/Clear';
|
||||
|
||||
const steps = [
|
||||
'Request',
|
||||
'Review',
|
||||
'Approval',
|
||||
'Decline',
|
||||
];
|
||||
|
||||
export default function HorizontalLinearAlternativeLabelStepper({data}) {
|
||||
const [active, setActive] = useState(0);
|
||||
const [status, SetStatus] = useState(null);
|
||||
let updatedSteps = [...steps];
|
||||
useEffect(() => {
|
||||
if (data && data.data) {
|
||||
if (data.data.status.status === 'requested') {
|
||||
setActive(1);
|
||||
updatedSteps = updatedSteps.filter(step => step !== 'Decline');
|
||||
}
|
||||
else if (data.data.status.status === 'reviewed') {
|
||||
setActive(2);
|
||||
updatedSteps = updatedSteps.filter(step => step !== 'Decline');
|
||||
}
|
||||
else if (data.data.status.status === 'approved')
|
||||
{
|
||||
setActive(3);
|
||||
updatedSteps = updatedSteps.filter(step => step !== 'Decline');
|
||||
}
|
||||
else if(data.data.status.status === 'declined')
|
||||
{
|
||||
setActive(4)
|
||||
updatedSteps = updatedSteps.filter(step => step !== 'Approval');
|
||||
}
|
||||
}
|
||||
SetStatus(updatedSteps);
|
||||
}, [data]);
|
||||
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<Box sx={{ width: '100%', marginBottom: 2 }}>
|
||||
<Stepper activeStep={active} alternativeLabel>
|
||||
{status?.map((label) => (
|
||||
<Step key={label}>
|
||||
<StepLabel icon={label==='Decline' ? <ClearIcon sx={{ color: 'white', backgroundColor: 'red', borderRadius: '50%' }} /> : ''}>{label}</StepLabel>
|
||||
</Step>
|
||||
))}
|
||||
</Stepper>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
386
frontend/hospital-portal/src/sections/claim/DetailTimeline.tsx
Normal file
386
frontend/hospital-portal/src/sections/claim/DetailTimeline.tsx
Normal file
@@ -0,0 +1,386 @@
|
||||
import * as React from 'react';
|
||||
import Timeline from '@mui/lab/Timeline';
|
||||
import TimelineItem, { timelineItemClasses } from '@mui/lab/TimelineItem';
|
||||
import TimelineSeparator from '@mui/lab/TimelineSeparator';
|
||||
import TimelineConnector from '@mui/lab/TimelineConnector';
|
||||
import TimelineContent from '@mui/lab/TimelineContent';
|
||||
import TimelineDot from '@mui/lab/TimelineDot';
|
||||
import {Typography, Card, Stack, ButtonBase, Box, Divider} from '@mui/material';
|
||||
import { styled } from '@mui/material/styles';
|
||||
import Paper from '@mui/material/Paper';
|
||||
import Button from '@mui/material/Button';
|
||||
import AddIcon from '@mui/icons-material/Add';
|
||||
import Iconify from '../../components/Iconify';
|
||||
import { useEffect, useState, useRef } from 'react';
|
||||
import { format } from 'date-fns';
|
||||
import { LoadingButton } from '@mui/lab';
|
||||
import axios from '../../utils/axios';
|
||||
import { makeFormData } from '@/utils/jsonToFormData';
|
||||
import { enqueueSnackbar } from 'notistack';
|
||||
import { useParams} from 'react-router-dom';
|
||||
import InsertDriveFileIcon from '@mui/icons-material/InsertDriveFile';
|
||||
|
||||
const Item1 = styled(Paper)(({ theme }) => ({
|
||||
...theme.typography.body2,
|
||||
padding: theme.spacing(1),
|
||||
textAlign: 'center',
|
||||
backgroundColor: '#919EAB29',
|
||||
color: '#637381',
|
||||
width: 'fit-content',
|
||||
marginRight: 'auto',
|
||||
}));
|
||||
|
||||
const Item2 = styled(Paper)(({ theme }) => ({
|
||||
backgroundColor: theme.palette.mode === 'dark' ? '#1A2027' : '#fff',
|
||||
...theme.typography.body2,
|
||||
padding: theme.spacing(1),
|
||||
textAlign: 'center',
|
||||
color: theme.palette.text.secondary,
|
||||
width: 'fit-content',
|
||||
marginLeft: 'auto',
|
||||
}));
|
||||
|
||||
export default function NoOppositeContent({data}) {
|
||||
const [timeline, setTimeline] = useState(null);
|
||||
const [requestFile, setRequestFile] = useState(null);
|
||||
useEffect(() => {
|
||||
if (data && data.data) {
|
||||
setTimeline(data.data.timeline);
|
||||
setRequestFile(data.data.request_files);
|
||||
}
|
||||
|
||||
}, [data]);
|
||||
|
||||
// Diagnosis
|
||||
const fileRequestDocumentInputDiagnosis = useRef<HTMLInputElement>(null);
|
||||
const [fileDiagnosis, setFileDiagnosis] = useState([]);
|
||||
const handleRequestDocumentInputChangeDiagnosis = (event) => {
|
||||
if (event.target.files[0]) {
|
||||
setFileDiagnosis([...fileDiagnosis, ...event.target.files]);
|
||||
}
|
||||
};
|
||||
const removeFileDiagnois = (filesState, index) => {
|
||||
setFileDiagnosis(
|
||||
filesState.filter((file, fileIndex) => {
|
||||
return fileIndex != index;
|
||||
})
|
||||
);
|
||||
};
|
||||
// Kondisi
|
||||
const fileRequestDocumentInputKondisi = useRef<HTMLInputElement>(null);
|
||||
const [fileKondisi, setFileKondisi] = useState([]);
|
||||
const handleRequestDocumentInputChangeKondisi = (event) => {
|
||||
if (event.target.files[0]) {
|
||||
setFileKondisi([...fileKondisi, ...event.target.files]);
|
||||
}
|
||||
};
|
||||
const removeFileKondisi = (filesState, index) => {
|
||||
setFileKondisi(
|
||||
filesState.filter((file, fileIndex) => {
|
||||
return fileIndex != index;
|
||||
})
|
||||
);
|
||||
};
|
||||
// Result
|
||||
const fileRequestDocumentInputResult = useRef<HTMLInputElement>(null);
|
||||
const [fileResult, setFileResult] = useState([]);
|
||||
const handleRequestDocumentInputChangeResult = (event) => {
|
||||
if (event.target.files[0]) {
|
||||
setFileResult([...fileResult, ...event.target.files]);
|
||||
}
|
||||
};
|
||||
const removeFileResult = (filesState, index) => {
|
||||
setFileResult(
|
||||
filesState.filter((file, fileIndex) => {
|
||||
return fileIndex != index;
|
||||
})
|
||||
);
|
||||
};
|
||||
const { id } = useParams();
|
||||
const [submitLoading, setSubmitLoading] = useState(false);
|
||||
const submitRequestFiles = () => {
|
||||
setSubmitLoading(true);
|
||||
const formData = makeFormData({
|
||||
fileDiagnosis: fileDiagnosis,
|
||||
fileKondisis: fileKondisi,
|
||||
fileResults: fileResult
|
||||
});
|
||||
axios
|
||||
.post('claim-requests/'+id+'/request-files', formData)
|
||||
.then((response) => {
|
||||
window.location.reload();
|
||||
})
|
||||
.catch(({ response }) => {
|
||||
enqueueSnackbar(response.data.message ?? 'Something Went Wrong', { variant: 'error' });
|
||||
});
|
||||
}
|
||||
const submitButton = requestFile?.find((dataRequestFile) => dataRequestFile.check_files === null);
|
||||
return (
|
||||
<>
|
||||
{timeline?.map((dataTimeline, index) => (
|
||||
<Timeline
|
||||
sx={{
|
||||
[`& .${timelineItemClasses.root}:before`]: {
|
||||
flex: 0,
|
||||
padding: 0,
|
||||
},
|
||||
}}
|
||||
key={index}
|
||||
>
|
||||
<Typography variant="body2" gutterBottom fontWeight="bold">{dataTimeline.date ? format(new Date(dataTimeline.date), "d MMM yyyy") : ''}</Typography>
|
||||
<TimelineItem>
|
||||
<TimelineSeparator>
|
||||
<TimelineDot />
|
||||
<TimelineConnector />
|
||||
</TimelineSeparator>
|
||||
<TimelineContent spacing={3}>
|
||||
<Card sx={{ borderRadius: '6px', paddingY: 2 }}>
|
||||
<Stack sx={{marginLeft: 2, marginRight: 2, marginTop: 2 }}>
|
||||
<Stack direction="row" spacing={2} sx={{marginBottom: 2, paddingBottom: 2, borderBottom: '1px solid #919EAB52' }}>
|
||||
<Item1>{dataTimeline.date ? format(new Date(dataTimeline.date), "HH : mm") : ''}</Item1>
|
||||
<Item2 sx={{backgroundColor: dataTimeline.txt_status_backgroundColor, color: dataTimeline.txt_status_color}}>{dataTimeline.txt_status}</Item2>
|
||||
</Stack>
|
||||
<Stack direction="row" spacing={2} sx={{marginBottom: 2}}>
|
||||
<Typography variant="body2" gutterBottom>Detail:</Typography>
|
||||
<Typography variant="body2" gutterBottom>{dataTimeline.description}</Typography>
|
||||
</Stack>
|
||||
{dataTimeline.status === 'reviewed' && requestFile ? (
|
||||
<>
|
||||
{submitButton ? (
|
||||
<Typography variant="body2" gutterBottom>Request Document</Typography>
|
||||
) : (
|
||||
<Typography sx={{color: '#19BBBB'}} variant="body2" gutterBottom>Request Document Success Uploaded</Typography>
|
||||
)}
|
||||
{/* Diagnosis */}
|
||||
{requestFile?.map((dataRequestFile, index) => {
|
||||
if(dataRequestFile.type !== 'claim-diagnosis' || dataRequestFile.check_files !== null){
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<Stack spacing={2} sx={{marginBottom: 2}} key={index}>
|
||||
<Typography variant="body2" gutterBottom fontWeight="bold">
|
||||
Diagnosis
|
||||
</Typography>
|
||||
<Stack
|
||||
divider={<Divider orientation="horizontal" flexItem />}
|
||||
spacing={1}
|
||||
sx={{ marginY: 2 }}
|
||||
>
|
||||
{fileDiagnosis &&
|
||||
fileDiagnosis.map((file, index) => (
|
||||
<Stack direction="row" justifyContent={'space-between'} key={index}>
|
||||
<Stack direction="row" spacing={1} sx={{color: '#19BBBB'}}>
|
||||
<InsertDriveFileIcon />
|
||||
<Typography variant="body2" gutterBottom>{file.name ? file.name : '-'}</Typography>
|
||||
</Stack>
|
||||
<Iconify
|
||||
icon="eva:trash-2-outline"
|
||||
color={'darkred'}
|
||||
onClick={() => {
|
||||
removeFileDiagnois(fileDiagnosis, index);
|
||||
}}
|
||||
sx={{cursor: 'pointer'}}
|
||||
></Iconify>
|
||||
</Stack>
|
||||
))}
|
||||
</Stack>
|
||||
<ButtonBase
|
||||
sx={{
|
||||
p: 4,
|
||||
border: '2px dashed #F9FAFB',
|
||||
bgcolor: '#919EAB52',
|
||||
borderRadius: '8px',
|
||||
width: '100%',
|
||||
height: '60px',
|
||||
}}
|
||||
onClick={() => fileRequestDocumentInputDiagnosis.current?.click()}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
placeItems: 'center',
|
||||
gap: 1,
|
||||
placeContent: 'center',
|
||||
}}
|
||||
>
|
||||
<Iconify icon="icon-park-outline:upload-one" fontSize="3em" />
|
||||
<Typography variant="body1" fontWeight="bold">
|
||||
Add Result
|
||||
</Typography>
|
||||
</Box>
|
||||
<input
|
||||
type="file"
|
||||
id={`file-${index}`}
|
||||
ref={fileRequestDocumentInputDiagnosis}
|
||||
style={{ display: 'none' }}
|
||||
multiple
|
||||
onChange={(event) => handleRequestDocumentInputChangeDiagnosis(event)}
|
||||
accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel, text/plain, application/pdf"
|
||||
/>
|
||||
</ButtonBase>
|
||||
</Stack>
|
||||
);
|
||||
})}
|
||||
{/* Kondisi */}
|
||||
{requestFile?.map((dataRequestFile, index) => {
|
||||
if(dataRequestFile.type !== 'claim-kondisi' || dataRequestFile.check_files !== null){
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<Stack spacing={2} sx={{marginBottom: 2}} key={index}>
|
||||
<Typography variant="body2" gutterBottom fontWeight="bold">
|
||||
Condition
|
||||
</Typography>
|
||||
<Stack
|
||||
divider={<Divider orientation="horizontal" flexItem />}
|
||||
spacing={1}
|
||||
sx={{ marginY: 2 }}
|
||||
>
|
||||
{fileKondisi &&
|
||||
fileKondisi.map((file, index) => (
|
||||
<Stack direction="row" justifyContent={'space-between'} key={index}>
|
||||
<Stack direction="row" spacing={1} sx={{color: '#19BBBB'}}>
|
||||
<InsertDriveFileIcon />
|
||||
<Typography variant="body2" gutterBottom>{file.name ? file.name : '-'}</Typography>
|
||||
</Stack>
|
||||
<Iconify
|
||||
icon="eva:trash-2-outline"
|
||||
color={'darkred'}
|
||||
onClick={() => {
|
||||
removeFileKondisi(fileKondisi, index);
|
||||
}}
|
||||
sx={{cursor: 'pointer'}}
|
||||
></Iconify>
|
||||
</Stack>
|
||||
))}
|
||||
</Stack>
|
||||
<ButtonBase
|
||||
sx={{
|
||||
p: 4,
|
||||
border: '2px dashed #F9FAFB',
|
||||
bgcolor: '#919EAB52',
|
||||
borderRadius: '8px',
|
||||
width: '100%',
|
||||
height: '60px',
|
||||
}}
|
||||
onClick={() => fileRequestDocumentInputKondisi.current?.click()}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
placeItems: 'center',
|
||||
gap: 1,
|
||||
placeContent: 'center',
|
||||
}}
|
||||
>
|
||||
<Iconify icon="icon-park-outline:upload-one" fontSize="3em" />
|
||||
<Typography variant="body1" fontWeight="bold">
|
||||
Add Result
|
||||
</Typography>
|
||||
</Box>
|
||||
<input
|
||||
type="file"
|
||||
id={`file-${index}`}
|
||||
ref={fileRequestDocumentInputKondisi}
|
||||
style={{ display: 'none' }}
|
||||
multiple
|
||||
onChange={(event) => handleRequestDocumentInputChangeKondisi(event)}
|
||||
accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel, text/plain, application/pdf"
|
||||
/>
|
||||
</ButtonBase>
|
||||
</Stack>
|
||||
);
|
||||
})}
|
||||
{/* Supporting Result */}
|
||||
{requestFile?.map((dataRequestFile, index) => {
|
||||
if(dataRequestFile.type !== 'claim-result' || dataRequestFile.check_files !== null){
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<Stack spacing={2} sx={{marginBottom: 2}} key={index}>
|
||||
<Typography variant="body2" gutterBottom fontWeight="bold">
|
||||
Supporting Result
|
||||
</Typography>
|
||||
<Stack
|
||||
divider={<Divider orientation="horizontal" flexItem />}
|
||||
spacing={1}
|
||||
sx={{ marginY: 2 }}
|
||||
>
|
||||
{fileResult &&
|
||||
fileResult.map((file, index) => (
|
||||
<Stack direction="row" justifyContent={'space-between'} key={index}>
|
||||
<Stack direction="row" spacing={1} sx={{color: '#19BBBB'}}>
|
||||
<InsertDriveFileIcon />
|
||||
<Typography variant="body2" gutterBottom>{file.name ? file.name : '-'}</Typography>
|
||||
</Stack>
|
||||
<Iconify
|
||||
icon="eva:trash-2-outline"
|
||||
color={'darkred'}
|
||||
onClick={() => {
|
||||
removeFileResult(fileResult, index);
|
||||
}}
|
||||
sx={{cursor: 'pointer'}}
|
||||
></Iconify>
|
||||
</Stack>
|
||||
))}
|
||||
</Stack>
|
||||
<ButtonBase
|
||||
sx={{
|
||||
p: 4,
|
||||
border: '2px dashed #F9FAFB',
|
||||
bgcolor: '#919EAB52',
|
||||
borderRadius: '8px',
|
||||
width: '100%',
|
||||
height: '60px',
|
||||
}}
|
||||
onClick={() => fileRequestDocumentInputResult.current?.click()}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
placeItems: 'center',
|
||||
gap: 1,
|
||||
placeContent: 'center',
|
||||
}}
|
||||
>
|
||||
<Iconify icon="icon-park-outline:upload-one" fontSize="3em" />
|
||||
<Typography variant="body1" fontWeight="bold">
|
||||
Add Result
|
||||
</Typography>
|
||||
</Box>
|
||||
<input
|
||||
type="file"
|
||||
id={`file-${index}`}
|
||||
ref={fileRequestDocumentInputResult}
|
||||
style={{ display: 'none' }}
|
||||
multiple
|
||||
onChange={(event) => handleRequestDocumentInputChangeResult(event)}
|
||||
accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel, text/plain, application/pdf"
|
||||
/>
|
||||
</ButtonBase>
|
||||
</Stack>
|
||||
);
|
||||
})}
|
||||
{submitButton ? (
|
||||
<LoadingButton
|
||||
variant="contained"
|
||||
sx={{ marginTop: 2, p: 2, backgroundColor: '#19BBBB' }}
|
||||
onClick={() => {
|
||||
submitRequestFiles();
|
||||
}}
|
||||
loading={submitLoading}
|
||||
>
|
||||
Submit
|
||||
</LoadingButton>
|
||||
) : ''}
|
||||
</>
|
||||
) : ''}
|
||||
</Stack>
|
||||
</Card>
|
||||
</TimelineContent>
|
||||
</TimelineItem>
|
||||
</Timeline>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -313,7 +313,7 @@ export default function TableList() {
|
||||
action:
|
||||
<TableMoreMenu actions={
|
||||
<>
|
||||
<MenuItem>
|
||||
<MenuItem onClick={() => navigate ('/claim/detail/'+obj.claim_request_id)}>
|
||||
<Iconify icon="eva:eye-fill" />
|
||||
View
|
||||
</MenuItem>
|
||||
|
||||
@@ -44,7 +44,6 @@ export default function FormRequestClaim({ member, handleSubmitSuccess }: FormRe
|
||||
axios
|
||||
.post('/request-log', formData)
|
||||
.then((response) => {
|
||||
console.log(response);
|
||||
if (response && response.data && response.data.meta) {
|
||||
enqueueSnackbar(response.data.meta.message, { variant: 'success' });
|
||||
handleSubmitSuccess();
|
||||
|
||||
@@ -51,23 +51,16 @@ function handleChangeTab(event: React.SyntheticEvent, newValue: string) {
|
||||
const [data, setData] = useState([]);
|
||||
|
||||
// Download LOG
|
||||
async function handleDownloadLog(claimRequest:any) {
|
||||
async function handleDownloadLog(request_log_id:any) {
|
||||
return axios
|
||||
.get(`claim-requests/${claimRequest}/log`, {
|
||||
.get(`download-log/${request_log_id}`, {
|
||||
responseType: 'blob',
|
||||
})
|
||||
.then((response) => {
|
||||
window.open(URL.createObjectURL(response.data));
|
||||
// setLoadingLog(false);
|
||||
window.open(URL.createObjectURL(response.data), '_blank');
|
||||
})
|
||||
// .then((blobFile) => {
|
||||
// new File([blobFile], 'asdads.pdf', { type: blobFile.type })
|
||||
// setLoadingLog(false);
|
||||
// })
|
||||
.catch((response) => {
|
||||
console.log(response);
|
||||
enqueueSnackbar(response.message, { variant: 'error' });
|
||||
// setLoadingLog(false);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -357,13 +350,13 @@ function handleChangeTab(event: React.SyntheticEvent, newValue: string) {
|
||||
<Iconify icon="eva:eye-fill" />
|
||||
View
|
||||
</MenuItem>
|
||||
{obj.status === 'approved' ? (
|
||||
<MenuItem onClick={() => handleDownloadLog(obj.claim_request_id)}>
|
||||
{/* {obj.status === 'approved' ? ( */}
|
||||
<MenuItem onClick={() => handleDownloadLog(obj.id)}>
|
||||
<Iconify icon="eva:download-fill" />
|
||||
Download LOG
|
||||
</MenuItem>
|
||||
):''}
|
||||
{obj.final_log === 0 ? (
|
||||
{/* ):''} */}
|
||||
{obj.final_log === 0 && obj.status === 'approved' ? (
|
||||
<MenuItem onClick={() => handleRequestFinalLog(obj.id, obj.full_name, obj.no_polis, obj.submission_date) }>
|
||||
<Iconify icon="fa:file-text" />
|
||||
Request Final LOG
|
||||
|
||||
@@ -355,7 +355,7 @@ export default function TableListFinalLog() {
|
||||
Download LOG
|
||||
</MenuItem>
|
||||
):''}
|
||||
{!obj.check_claim ? (
|
||||
{!obj.check_claim && obj.status === 'approved' ? (
|
||||
<MenuItem onClick={() => handleRequestClaimSubmit(obj.member_id, obj.service_code, obj.id, obj.full_name, obj.no_polis, obj.submission_date) }>
|
||||
<Iconify icon="fa:file-text" />
|
||||
Submit Claim
|
||||
|
||||
Binary file not shown.
BIN
public/files/Corporate Plan & Benefit Import2.xlsx
Normal file
BIN
public/files/Corporate Plan & Benefit Import2.xlsx
Normal file
Binary file not shown.
Binary file not shown.
BIN
public/images/background-vale.png
Normal file
BIN
public/images/background-vale.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.8 KiB |
BIN
public/images/logo-default.png
Normal file
BIN
public/images/logo-default.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
122
resources/views/pdf/ecard.blade.php
Normal file
122
resources/views/pdf/ecard.blade.php
Normal file
@@ -0,0 +1,122 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
|
||||
{{-- <link rel="stylesheet" href="{{ asset('css/app.css') }}"> --}}
|
||||
|
||||
<style>
|
||||
/* @font-face {
|
||||
font-family: Public Sans;
|
||||
src: url('{{asset('fonts/PublicSans-Medium.ttf')}}');
|
||||
src: url('{{asset('fonts/PublicSans-Medium.ttf')}}') format('truetype');
|
||||
} */
|
||||
|
||||
html, body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Public Sans';
|
||||
color: #404040;
|
||||
font-size: 20px;
|
||||
margin: 0; /* Reset default margin */
|
||||
padding: 0; /* Reset default padding */
|
||||
background-image: url("{{ public_path('images/background-vale.png') }}");
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover; /* Adjust as needed */
|
||||
}
|
||||
|
||||
.text-sm {
|
||||
font-size: 18px;
|
||||
color: #FFFFFF
|
||||
}
|
||||
.text-md {
|
||||
font-size: 18px;
|
||||
color: #159C9C
|
||||
}
|
||||
.text-lg {
|
||||
font-size: 22px;
|
||||
color: #117D7D;
|
||||
|
||||
}
|
||||
.text-gray {
|
||||
color: #919EAB;
|
||||
}
|
||||
|
||||
.content {
|
||||
margin: 10% 0 0 0;
|
||||
}
|
||||
|
||||
.image-container {
|
||||
margin-left: 75%; /* Adjust the margin as needed */
|
||||
}
|
||||
|
||||
.label {
|
||||
background-color: #117D7D;
|
||||
color: #fff;
|
||||
border-radius: 15px;
|
||||
padding: 8px; /* Sesuaikan dengan kebutuhan Anda */
|
||||
font-size: 18px;
|
||||
gap: 4px;
|
||||
display: inline-flex; /* Untuk memastikan ikon dan teks berada dalam satu baris */
|
||||
align-items: center; /* Untuk memastikan ikon dan teks berada dalam satu baris */
|
||||
}
|
||||
|
||||
.label svg {
|
||||
margin-right: 4px; /* Jarak antara ikon dan teks */
|
||||
}
|
||||
|
||||
.text-sm {
|
||||
font-size: 18px; /* Sesuaikan dengan kebutuhan Anda */
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<br><br><br><br>
|
||||
<div class="content">
|
||||
<div class="text-container">
|
||||
<span class="text-md"> Member Name </span>
|
||||
<p class="text-lg"><b>{{ $member->fullName }}</b></p>
|
||||
|
||||
<span class="text-md"> Member ID </span>
|
||||
<p class="text-lg"><b>{{ $member->member_id }}</b></p>
|
||||
|
||||
<span class="text-md"> Policy Holder </span>
|
||||
<p class="text-lg"><b>{{ $member->currentCorporate->name }}</b></p>
|
||||
|
||||
<span class="text-md"> Policy Number </span>
|
||||
<p class="text-lg"><b>{{ $member->currentPolicy->code }}</b></p>
|
||||
|
||||
<span class="text-md"> Date of Birth </span>
|
||||
<p class="text-lg"><b>{{ $member->birthDateeCard }}</b></p>
|
||||
|
||||
<span class="text-md"> Gender </span>
|
||||
<p class="text-lg"><b>{{ $member->gender }}</b></p>
|
||||
|
||||
<span class="text-md"> Start Date </span>
|
||||
<p class="text-lg"><b>{{ $member->startDate }}</b></p>
|
||||
|
||||
<div class="image-container">
|
||||
<img src="{{ public_path('images/logo-default.png')}}" height="30px">
|
||||
</div>
|
||||
<span class="label">
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6.00082 0.166992C9.22257 0.166992 11.8342 2.77858 11.8342 6.00033C11.8342 9.22208 9.22257 11.8337 6.00082 11.8337C4.96994 11.8353 3.9572 11.5625 3.06666 11.0432L0.169822 11.8337L0.958489 8.93566C0.438793 8.04484 0.165766 7.03166 0.167489 6.00033C0.167489 2.77858 2.77907 0.166992 6.00082 0.166992ZM4.01282 3.25866L3.89615 3.26333C3.82063 3.26793 3.74681 3.28777 3.67916 3.32166C3.61588 3.35749 3.55811 3.40229 3.50766 3.45466C3.43766 3.52058 3.39799 3.57774 3.35541 3.63316C3.13964 3.91369 3.02347 4.25809 3.02524 4.61199C3.02641 4.89783 3.10107 5.17608 3.21774 5.43624C3.45632 5.96241 3.84891 6.51949 4.36691 7.03574C4.49174 7.15999 4.61424 7.28483 4.74607 7.40091C5.38972 7.9676 6.15672 8.37627 6.98607 8.59441L7.31741 8.64516C7.42532 8.65099 7.53324 8.64283 7.64174 8.63758C7.81163 8.62881 7.97751 8.5828 8.12766 8.50283C8.20405 8.46348 8.2786 8.42065 8.35107 8.37449C8.35107 8.37449 8.37615 8.35816 8.42399 8.32199C8.50274 8.26366 8.55116 8.22224 8.61649 8.15399C8.66491 8.10383 8.7069 8.04491 8.73899 7.97783C8.78449 7.88274 8.82999 7.70132 8.84865 7.55024C8.86265 7.43474 8.85857 7.37174 8.85682 7.33266C8.85449 7.27024 8.80257 7.20549 8.74599 7.17808L8.40649 7.02583C8.40649 7.02583 7.89899 6.80474 7.58865 6.66358C7.55618 6.6494 7.52138 6.64129 7.48599 6.63966C7.44608 6.63556 7.40575 6.64005 7.36772 6.65283C7.32969 6.66561 7.29483 6.68638 7.26549 6.71374C7.26257 6.71257 7.22349 6.74583 6.80174 7.25683C6.77753 7.28935 6.74419 7.31394 6.70596 7.32744C6.66773 7.34095 6.62634 7.34276 6.58707 7.33266C6.54907 7.32247 6.51184 7.3096 6.47565 7.29416C6.40332 7.26383 6.37824 7.25216 6.32865 7.23116C5.99386 7.08506 5.68389 6.88766 5.4099 6.64608C5.3364 6.58191 5.26816 6.51191 5.19815 6.44424C4.96866 6.22446 4.76866 5.97583 4.60315 5.70458L4.56874 5.64916C4.54402 5.61192 4.52403 5.57175 4.50924 5.52958C4.48707 5.44383 4.54482 5.37499 4.54482 5.37499C4.54482 5.37499 4.68657 5.21983 4.75249 5.13583C4.81666 5.05416 4.8709 4.97483 4.9059 4.91824C4.97474 4.80741 4.99632 4.69366 4.96016 4.60558C4.79682 4.20658 4.62766 3.80933 4.45382 3.41499C4.4194 3.33683 4.31732 3.28083 4.22457 3.26974C4.19307 3.26624 4.16157 3.26274 4.13007 3.26041C4.05173 3.25652 3.97323 3.2573 3.89499 3.26274L4.01224 3.25808L4.01282 3.25866Z" fill="white"/>
|
||||
</svg>
|
||||
<span class="text-sm">
|
||||
08114123962
|
||||
</span>
|
||||
</span>
|
||||
<span class="text-md" style="margin-left:39%"><b> Valid until: {{ $member->endDate }}</b></span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
268
resources/views/pdf/req_log_page_1.blade.php
Normal file
268
resources/views/pdf/req_log_page_1.blade.php
Normal file
@@ -0,0 +1,268 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<style>
|
||||
.triangle1 {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 10.24px solid transparent;
|
||||
border-right: 318.24px solid transparent;
|
||||
border-bottom: 75.5px solid #008C8C;
|
||||
position: absolute;
|
||||
top: -55.12px;
|
||||
left: -60.91px;
|
||||
transform: rotate(-12deg);
|
||||
}
|
||||
|
||||
.triangle2 {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 10.24px solid transparent;
|
||||
border-right: 550.24px solid transparent;
|
||||
border-bottom: 110.5px solid #19BBBB;
|
||||
position: absolute;
|
||||
top: -55.12px;
|
||||
left: -100.91px;
|
||||
transform: rotate(-20deg);
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100vh;
|
||||
background-color: #ffffff; /* Ganti dengan warna latar belakang yang diinginkan */
|
||||
}
|
||||
.content {
|
||||
padding: 20px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.content img {
|
||||
width: 25%;
|
||||
max-width: 600px; /* batasan lebar maksimum gambar */
|
||||
margin-top: 20px; /* jarak antara segitiga dan gambar */
|
||||
}
|
||||
.corner-text {
|
||||
font-family: 'Calibri', sans-serif;
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.top-right {
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
.bottom-right {
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
.bottom-left {
|
||||
bottom: 10px;
|
||||
left: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
.title-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-family: 'Calibri', sans-serif;
|
||||
font-size: 18px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.additional-text {
|
||||
font-family: 'Calibri', sans-serif;
|
||||
font-size: 12px;
|
||||
}
|
||||
.claim-info {
|
||||
font-family: 'Calibri', sans-serif;
|
||||
font-size: 14px;
|
||||
/* color: #008C8C; */
|
||||
text-align: left;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
table, th, td {
|
||||
/* border: 1px solid #008C8C; */
|
||||
}
|
||||
|
||||
th, td {
|
||||
padding: 4px;
|
||||
text-align: left;
|
||||
}
|
||||
.hot-line {
|
||||
font-family: 'Calibri', sans-serif;
|
||||
background-color: #048B8C;
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
margin-top: 10px;
|
||||
padding: 2px;
|
||||
color: #ffffff;
|
||||
}
|
||||
.txt-tindakan {
|
||||
font-family: 'Calibri', sans-serif;
|
||||
margin-top: 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.txt-pernyataan {
|
||||
font-family: 'Calibri', sans-serif;
|
||||
margin-top: 40px;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="triangle2"></div>
|
||||
<div class="triangle1"></div>
|
||||
<div class="content">
|
||||
<div class="corner-text top-right">
|
||||
The Future Of Healthcare At Your Fingertips
|
||||
</div>
|
||||
<img src="data:image/png;base64,{{ base64_encode(file_get_contents( public_path('images/logo-default.png') )) }}">
|
||||
<div class="title-container">
|
||||
<div class="title">
|
||||
<b>SURAT JAMINAN</b>
|
||||
</div>
|
||||
<div class="additional-text">
|
||||
(SURAT JAMINAN INI HARUS DITANDATANGANI OLEH PASIEN)
|
||||
</div>
|
||||
</div>
|
||||
<table class="claim-info">
|
||||
<tr>
|
||||
<td style="width: 20%;">No. Klaim</td>
|
||||
<td style="width: 1%;">:</td>
|
||||
<td style="width: 29%;">{{$request_logs->code}}</td>
|
||||
<td style="width: 20%;">Tanggal</td>
|
||||
<td style="width: 1%;">:</td>
|
||||
<td style="width: 29%;">{{ \Carbon\Carbon::parse($request_logs->submission_date)->format('d M Y') }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Kepada</td>
|
||||
<td>:</td>
|
||||
<td>{{ $dataMember->name }}</td>
|
||||
<td>Plan Polis</td>
|
||||
<td>:</td>
|
||||
<td>{{ $dataMember->code_plan }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="hot-line">
|
||||
(HOT LINE LINK SEHAT)
|
||||
</div>
|
||||
<div class="txt-tindakan">
|
||||
Link Sehat bertindak mewakili perusahaan asuransi/penanggung untuk mengeluarkan Surat Jaminan Awal untuk peserta dibawah ini :
|
||||
</div>
|
||||
<table class="claim-info">
|
||||
<tr>
|
||||
<td style="width: 20%;">Jenis Surat Jaminan</td>
|
||||
<td style="width: 1%;">:</td>
|
||||
<td style="width: 29%;"><b>SURAT JAMINAN AWAL</b></td>
|
||||
<td style="width: 20%;">Penjamin</td>
|
||||
<td style="width: 1%;">:</td>
|
||||
<td style="width: 29%;">{{ $dataMember->penjamin }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Nama Peserta</td>
|
||||
<td>:</td>
|
||||
<td>{{ $dataMember->name }}</td>
|
||||
<td>Nama Perusahaan</td>
|
||||
<td>:</td>
|
||||
<td>{{ $dataMember->nama_perusahaan }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Nama Karyawan</td>
|
||||
<td>:</td>
|
||||
<td>{{ $namaKaryawan }}</td>
|
||||
<td>No. Polis</td>
|
||||
<td>:</td>
|
||||
<td>{{ $dataMember->code_plan }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Tanggal Lahir</td>
|
||||
<td>:</td>
|
||||
<td>{{ \Carbon\Carbon::parse($dataMember->birth_date)->format('d M Y') }}</td>
|
||||
<td>Produk</td>
|
||||
<td>:</td>
|
||||
<td>{{ $dataMember->no_polis }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Jenis Kelamin</td>
|
||||
<td>:</td>
|
||||
<td>{{ $dataMember->gender == 'male' ? 'Laki-Laki' : 'Perempuan' }}</td>
|
||||
<td>Tipe</td>
|
||||
<td>:</td>
|
||||
<td>{{ $dataMember->limit_rules == '999999999' ? 'As Charge' : 'Max Amount, Rp '.number_format($dataMember->limit_rules, 2, ',', '.') }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Member ID</td>
|
||||
<td>:</td>
|
||||
<td>{{ $dataMember->member_id }}</td>
|
||||
<td>Status Polis</td>
|
||||
<td>:</td>
|
||||
<td>{{ $dataMember->status_polis == 'active' ? 'Aktif' : 'Tidak Aktif' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Identitas Peserta</td>
|
||||
<td>:</td>
|
||||
<td>{{ $dataMember->nik }}</td>
|
||||
<td>Tanggal Mulai Akhir</td>
|
||||
<td>:</td>
|
||||
<td>{{ \Carbon\Carbon::parse($dataMember->mulai)->format('d M Y') }} - {{ \Carbon\Carbon::parse($dataMember->akhir)->format('d M Y') }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Hak Kamar Pasien</td>
|
||||
<td>:</td>
|
||||
<td></td>
|
||||
<td>Mata Uang</td>
|
||||
<td>:</td>
|
||||
<td>{{ $dataMember->mata_uang }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Tanggal Pembayaran</td>
|
||||
<td>:</td>
|
||||
<td></td>
|
||||
<td>Rumah Sakit</td>
|
||||
<td>:</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td>Alamat</td>
|
||||
<td>:</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="txt-pernyataan">
|
||||
Surat Jaminan ini dinyatakan berlaku apabila disertai surat jaminan akhir dengan nominal yang tertera pada akhir perawatan.
|
||||
</div>
|
||||
<div class="corner-text bottom-right">
|
||||
The Future Of Healthcare At Your Fingertips
|
||||
</div>
|
||||
<div class="corner-text bottom-left">
|
||||
<b>PT Link Medis Sehat</b><br>
|
||||
<b>Primaya Hospital Corporate</b><br>
|
||||
Graha Cempaka Mas Blok D5-6<br>
|
||||
Jl. Let. Jend. Suprapto, Jakarta Pusat 10640, Indonesia<br>
|
||||
<b>Telp</b> (021) 4217746/47
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
254
resources/views/pdf/req_log_page_2.blade.php
Normal file
254
resources/views/pdf/req_log_page_2.blade.php
Normal file
@@ -0,0 +1,254 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<style>
|
||||
.triangle1 {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 10.24px solid transparent;
|
||||
border-right: 318.24px solid transparent;
|
||||
border-bottom: 75.5px solid #008C8C;
|
||||
position: absolute;
|
||||
top: -55.12px;
|
||||
left: -60.91px;
|
||||
transform: rotate(-12deg);
|
||||
}
|
||||
|
||||
.triangle2 {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 10.24px solid transparent;
|
||||
border-right: 550.24px solid transparent;
|
||||
border-bottom: 110.5px solid #19BBBB;
|
||||
position: absolute;
|
||||
top: -55.12px;
|
||||
left: -100.91px;
|
||||
transform: rotate(-20deg);
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100vh;
|
||||
background-color: #ffffff; /* Ganti dengan warna latar belakang yang diinginkan */
|
||||
}
|
||||
.content {
|
||||
padding: 20px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.content img {
|
||||
width: 25%;
|
||||
max-width: 600px; /* batasan lebar maksimum gambar */
|
||||
margin-top: 20px; /* jarak antara segitiga dan gambar */
|
||||
}
|
||||
.corner-text {
|
||||
font-family: 'Calibri', sans-serif;
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.top-right {
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
.bottom-right {
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
.bottom-right-ttd {
|
||||
color: #000000;
|
||||
bottom: 120px;
|
||||
right: 10px;
|
||||
}
|
||||
.bottom-left {
|
||||
bottom: 10px;
|
||||
left: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
.bottom-left-ttd {
|
||||
color: #000000;
|
||||
bottom: 120px;
|
||||
left: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.bottom-left-ttd-1 {
|
||||
color: #000000;
|
||||
bottom: 250px;
|
||||
left: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
.title-container-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
margin-top: 40px;
|
||||
border: 1px solid; /* Warna garis tepi dan lebar dapat disesuaikan */
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-family: 'Calibri', sans-serif;
|
||||
font-size: 18px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.additional-text {
|
||||
font-family: 'Calibri', sans-serif;
|
||||
font-size: 12px;
|
||||
}
|
||||
.claim-info {
|
||||
font-family: 'Calibri', sans-serif;
|
||||
font-size: 12px;
|
||||
/* color: #008C8C; */
|
||||
text-align: left;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
table, th, td {
|
||||
/* border: 1px solid #008C8C; */
|
||||
}
|
||||
|
||||
th, td {
|
||||
padding: 4px;
|
||||
text-align: left;
|
||||
}
|
||||
.hot-line {
|
||||
font-family: 'Calibri', sans-serif;
|
||||
background-color: #048B8C;
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
margin-top: 10px;
|
||||
padding: 2px;
|
||||
color: #ffffff;
|
||||
}
|
||||
.txt-tindakan {
|
||||
font-family: 'Calibri', sans-serif;
|
||||
margin-top: 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.txt-pernyataan {
|
||||
font-family: 'Calibri', sans-serif;
|
||||
margin-top: 40px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.txt-syarat {
|
||||
font-family: 'Calibri', sans-serif;
|
||||
font-size: 14px;
|
||||
text-align: left;
|
||||
}
|
||||
container {
|
||||
position: relative;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.left-bottom {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
left: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.right-bottom {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="triangle2"></div>
|
||||
<div class="triangle1"></div>
|
||||
<div class="content">
|
||||
<div class="corner-text top-right">
|
||||
The Future Of Healthcare At Your Fingertips
|
||||
</div>
|
||||
<img src="data:image/png;base64,{{ base64_encode(file_get_contents( public_path('images/logo-default.png') )) }}">
|
||||
<div class="title-container-page">
|
||||
<div class="txt-syarat">SYARAT DAN KETENTUAN</div>
|
||||
<table class="claim-info">
|
||||
<tr>
|
||||
<td style="width: 100%;">1. Surat jaminan ini hanya berlaku untuk diagnosa yang tercantum diatas.
|
||||
Apabila ditemukan adanya perubahan atau penambahan diagnosa, maka Link Sehat berhak membatalkan surat jaminan.
|
||||
Mohon untuk menghubungi Link Sehat apabila ada perubahan diagnosa dan diagnosa tambahan.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="width: 100%;">2. Surat jaminan ini dinyatakan berlaku apabila disertai surat jaminan akhir dengan
|
||||
nominal yang tertera pada kolom diatas.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="width: 100%;">3. Surat jaminan ini tidak berlaku untuk biaya diluar medis seperti makan/minum
|
||||
diluar ketentuan, tagihan telepon, binatu, dan lain-lain. Mohon ditagihkan langsung kepeserta.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="width: 100%;">4. Rumah sakit harap segera menghubungi Link Sehat apabila biaya rumah sakit melebihi batas tertanggung diatas.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="width: 100%;">5. Rumah sakit wajib menghubungi Link Sehat sebelum pasien meninggalkan rumah sakit
|
||||
dapat menghubungi biaya apa saja yang dijamin oleh Link Sehat. Jika peserta meninggalkan rumah sakit sebelum mengkonfirmasikan ke Link Sehat,
|
||||
maka Link Sehat tidak bertanggung jawab atas biaya yang tidak dijamin oleh pihak asuransi.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="width: 100%;">6. Peserta bertanggung jawab untuk menyelesaikan secara langsung kepada pihak rumah sakit dan penyedia jasa medis
|
||||
apabila terjadi selisih biaya (ekses) atas seluruh biaya perawatan, biaya medis, dan yang lain yang telah terjadi sehubungan
|
||||
dengan rawat inap, maupun atas perihal perawatan medis yang tidak tercakup dalam polis asuransi dikarenakan karena alasan apapun.
|
||||
Apabila biaya-biaya tersebut telah dijamin oleh Link Sehat atas nama nasabah, maka peserta akan membayar kembali ke pihak Link Sehat
|
||||
secara penuh termasuk biaya berhubungan dengan penagihan (apabila ada) yang terjadi ke pihak Link Sehat atas biaya yang tidak termasuk dalam manfaat polis.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="width: 100%;">7. Dengan ini perserta menyatakan mengetahui dan menyetujui ketentuan selisih biaya yang telah disebutkan diatas.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="width: 100%;">8. Dalam hal surat jaminan ini tidak ditandatangani oleh peserta yang bersangkutan maka rumah sakit berkewajiban untuk menyampaikan keadaan tersebut
|
||||
kepada Link Sehat dalam kurun waktu paling lambat 1x24 jam, dalam hal tidak ada perubahan dalam jangka waktu yang telah ditentukan tersebut
|
||||
maka dianggap peserta yang bersangkutan telah setuju dengan ketentuan yang terdapat dalam surat jaminan ini.</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<!-- <div class="container">
|
||||
<div class="left-bottom">
|
||||
Hormat Kami,<br>
|
||||
Acknowledged,<br>
|
||||
[Nama Analyst]
|
||||
</div>
|
||||
|
||||
|
||||
</div> -->
|
||||
<div class="corner-text bottom-left-ttd-1">
|
||||
Hormat Kami,<br>
|
||||
Acknowledged,
|
||||
</div>
|
||||
<div class="corner-text bottom-left-ttd">
|
||||
[..................................................]
|
||||
</div>
|
||||
<div class="corner-text bottom-right-ttd">
|
||||
[{{ $dataMember->name }}]
|
||||
</div>
|
||||
<div class="corner-text bottom-right">
|
||||
The Future Of Healthcare At Your Fingertip
|
||||
</div>
|
||||
<div class="corner-text bottom-left">
|
||||
<b>PT Link Medis Sehat</b><br>
|
||||
<b>Primaya Hospital Corporate</b><br>
|
||||
Graha Cempaka Mas Blok D5-6<br>
|
||||
Jl. Let. Jend. Suprapto, Jakarta Pusat 10640, Indonesia<br>
|
||||
<b>Telp</b> (021) 4217746/47
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
37
resources/views/pdf/view.blade.php
Normal file
37
resources/views/pdf/view.blade.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<!-- your/view.blade.php -->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Ivan Julian</title>
|
||||
<style>
|
||||
body {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
h1, p {
|
||||
/* Gaya teks Anda */
|
||||
}
|
||||
|
||||
img {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0.3; /* Sesuaikan dengan tingkat kecerahan yang diinginkan */
|
||||
z-index: -1; /* Letakkan gambar di belakang konten lain */
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Sisipkan gambar sebagai elemen img -->
|
||||
<img src="{{public_path('images/logo-linksehat-vertical-default.png')}}" width="100px">
|
||||
|
||||
<!-- Konten HTML -->
|
||||
<h1>Hello, {{ $key }}</h1>
|
||||
<p>This is a simple example for generating PDF in Laravel using Dompdf.</p>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user