Update customer service
This commit is contained in:
@@ -35,12 +35,15 @@ class DailyMonitoringController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function GetMemberList()
|
public function GetMemberList()
|
||||||
{
|
{
|
||||||
$memberList = DB::table('claims')
|
$memberList = DB::table('request_logs')
|
||||||
->leftJoin('members', 'claims.member_id', '=', 'members.id')
|
->leftJoin('members', 'request_logs.member_id', '=', 'members.id')
|
||||||
->leftJoin('member_plans', 'members.id', '=', 'member_plans.id')
|
->leftJoin('member_plans', 'request_logs.member_id', '=', 'member_plans.member_id')
|
||||||
->select('members.member_id','members.name','member_plans.start AS startdate','member_plans.end AS enddate')
|
->leftJoin('organizations', 'organizations.id', '=', 'request_logs.organization_id')
|
||||||
->groupBy('claims.member_id')
|
->select('members.member_id','members.name','member_plans.start AS startdate','member_plans.end AS enddate', 'request_logs.submission_date as addmision_date', 'organizations.name as provider' )
|
||||||
->orderBy('claims.created_at', 'desc')
|
->where('request_logs.service_code', 'IP')
|
||||||
|
->where('request_logs.status_final_log', 'approved')
|
||||||
|
->groupBy('request_logs.member_id')
|
||||||
|
->orderBy('request_logs.created_at', 'desc')
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
@@ -62,15 +65,14 @@ class DailyMonitoringController extends Controller
|
|||||||
->where('member_id', $member_id)
|
->where('member_id', $member_id)
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
$claimList = DB::table('claims')
|
$claimList = DB::table('request_logs')
|
||||||
->leftJoin('claim_requests', 'claims.claim_request_id', '=', 'claim_requests.id')
|
->leftJoin('services', 'services.code', '=', 'request_logs.service_code')
|
||||||
->leftJoin('claim_history_cares', 'claims.id', '=', 'claim_history_cares.claim_id')
|
->leftJoin('members', 'members.id', '=', 'request_logs.member_id')
|
||||||
->leftJoin('services', 'claim_requests.service_code', '=', 'services.code')
|
->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',)
|
||||||
->leftJoin('members', 'claims.member_id', '=', 'members.id')
|
->where('request_logs.service_code', 'IP')
|
||||||
->select('claims.id AS claim_id','claim_history_cares.admission_date','claim_history_cares.discharge_date','claim_requests.code AS claim_code','services.name AS service_type','claims.status AS claim_status','members.member_id',)
|
->where('request_logs.status_final_log', 'approved')
|
||||||
->where("claims.member_id", "=", $memberDetail->id)
|
->where("request_logs.member_id", "=", $memberDetail->id)
|
||||||
->where("claim_requests.claim_id", "!=",null)
|
->orderBy("request_logs.created_at", "desc")
|
||||||
->orderBy("claims.created_at", "desc")
|
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
|
|||||||
@@ -306,10 +306,12 @@ class RequestLogController extends Controller
|
|||||||
{
|
{
|
||||||
$id = $request->id;
|
$id = $request->id;
|
||||||
$requestLog = RequestLog::findOrFail($id);
|
$requestLog = RequestLog::findOrFail($id);
|
||||||
|
$status = $request->status ?? 'requested';
|
||||||
|
|
||||||
|
|
||||||
// Update Request LOG untuk lanjut ke Final LOG
|
// Update Request LOG untuk lanjut ke Final LOG
|
||||||
$requestLog->final_log = 1;
|
$requestLog->final_log = 1;
|
||||||
$requestLog->status_final_log = 'requested';
|
$requestLog->status_final_log = $status;
|
||||||
$requestLog->save();
|
$requestLog->save();
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,136 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Internal\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Helpers\Helper;
|
||||||
|
use App\Models\RequestLogMedicine;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Routing\Controller;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
|
||||||
|
class RequestLogMedicineController extends Controller
|
||||||
|
{
|
||||||
|
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
* @return Renderable
|
||||||
|
*/
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
return view('internal::create');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the specified resource.
|
||||||
|
* @param int $id
|
||||||
|
* @return Renderable
|
||||||
|
*/
|
||||||
|
public function show($id)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
* @param Request $request
|
||||||
|
* @return Renderable
|
||||||
|
*/
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
|
||||||
|
$customMessages = [
|
||||||
|
'required' => 'Kolom :attribute wajib diisi.',
|
||||||
|
'numeric' => 'Kolom :attribute harus berupa angka.',
|
||||||
|
];
|
||||||
|
|
||||||
|
$validator = Validator::make($request->all(), [
|
||||||
|
'medicine' => 'required|array',
|
||||||
|
'medicine.*' => 'required',
|
||||||
|
], $customMessages);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return Helper::responseJson([],'error', 400, $validator->errors());
|
||||||
|
} else {
|
||||||
|
$medicine = $request->medicine;
|
||||||
|
|
||||||
|
if (count($medicine)>0){
|
||||||
|
// BeginTransaction
|
||||||
|
DB::beginTransaction();
|
||||||
|
foreach($medicine as $key => $value){
|
||||||
|
$data = [
|
||||||
|
'request_log_id' => $value['request_log_id'],
|
||||||
|
'medicine' => $value['medicine_name'],
|
||||||
|
'price' => $value['medicine_price'],
|
||||||
|
];
|
||||||
|
// Insert Data
|
||||||
|
try {
|
||||||
|
RequestLogMedicine::create($data);
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
DB::rollBack();
|
||||||
|
return Helper::responseJson(status: 'failed', statusCode: 500, message: $th->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DB::commit();
|
||||||
|
return Helper::responseJson(status: 'success', statusCode: 201, message: 'success', data: $request->toArray());
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$requestLogMedicine = RequestLogMedicine::insert($data);
|
||||||
|
return $requestLogMedicine;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for editing the specified resource.
|
||||||
|
* @param int $id
|
||||||
|
* @return Renderable
|
||||||
|
*/
|
||||||
|
public function edit($id)
|
||||||
|
{
|
||||||
|
return view('internal::edit');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
* @param Request $request
|
||||||
|
* @param int $id
|
||||||
|
* @return Renderable
|
||||||
|
*/
|
||||||
|
public function update(Request $request, $id)
|
||||||
|
{
|
||||||
|
$requestLogBenefit = requestLogBenefit::findOrFail($id);
|
||||||
|
$requestLogBenefit->amount_approved = $request->amount_approved;
|
||||||
|
$requestLogBenefit->amount_incurred = $request->amount_incurred;
|
||||||
|
$requestLogBenefit->amount_not_approved = $request->amount_not_approved;
|
||||||
|
$requestLogBenefit->excess_paid = $request->excess_paid;
|
||||||
|
$requestLogBenefit->keterangan = $request->keterangan;
|
||||||
|
|
||||||
|
$requestLogBenefit->save();
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'error' => false,
|
||||||
|
'message' => 'Update succses',
|
||||||
|
'data' => $requestLogBenefit],
|
||||||
|
200);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
* @param int $id
|
||||||
|
* @return Renderable
|
||||||
|
*/
|
||||||
|
public function destroy($id)
|
||||||
|
{
|
||||||
|
$RequestLogMedicine = RequestLogMedicine::findOrFail($id);
|
||||||
|
$RequestLogMedicine->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -7,9 +7,10 @@ use Modules\Internal\Http\Controllers\Api\AppointmentController;
|
|||||||
use Modules\Internal\Http\Controllers\Api\BenefitController;
|
use Modules\Internal\Http\Controllers\Api\BenefitController;
|
||||||
use Modules\Internal\Http\Controllers\Api\CityController;
|
use Modules\Internal\Http\Controllers\Api\CityController;
|
||||||
use Modules\Internal\Http\Controllers\Api\ClaimController;
|
use Modules\Internal\Http\Controllers\Api\ClaimController;
|
||||||
|
use Modules\Internal\Http\Controllers\Api\ClaimRequestController;
|
||||||
use Modules\Internal\Http\Controllers\Api\RequestLogController;
|
use Modules\Internal\Http\Controllers\Api\RequestLogController;
|
||||||
use Modules\Internal\Http\Controllers\Api\RequestLogBenefitController;
|
use Modules\Internal\Http\Controllers\Api\RequestLogBenefitController;
|
||||||
use Modules\Internal\Http\Controllers\Api\ClaimRequestController;
|
use Modules\Internal\Http\Controllers\Api\RequestLogMedicineController;
|
||||||
use Modules\Internal\Http\Controllers\Api\CorporateBenefitController;
|
use Modules\Internal\Http\Controllers\Api\CorporateBenefitController;
|
||||||
use Modules\Internal\Http\Controllers\Api\CorporateController;
|
use Modules\Internal\Http\Controllers\Api\CorporateController;
|
||||||
use Modules\Internal\Http\Controllers\Api\CorporateFormulariumController;
|
use Modules\Internal\Http\Controllers\Api\CorporateFormulariumController;
|
||||||
@@ -258,12 +259,17 @@ Route::prefix('internal')->group(function () {
|
|||||||
Route::get('customer-service/request/data', [RequestLogController::class, 'generateDataRequestLogExcel']);
|
Route::get('customer-service/request/data', [RequestLogController::class, 'generateDataRequestLogExcel']);
|
||||||
|
|
||||||
Route::post('customer-service/request/final-log', [RequestLogController::class, 'updateFinalLog']);
|
Route::post('customer-service/request/final-log', [RequestLogController::class, 'updateFinalLog']);
|
||||||
|
|
||||||
// insert benefit
|
// insert benefit
|
||||||
Route::post('customer-service/request/insert-benefit', [RequestLogBenefitController::class, 'store']);
|
Route::post('customer-service/request/insert-benefit', [RequestLogBenefitController::class, 'store']);
|
||||||
Route::delete('customer-service/request/benefit_data/{id}', [RequestLogBenefitController::class, 'destroy']);
|
Route::delete('customer-service/request/benefit_data/{id}', [RequestLogBenefitController::class, 'destroy']);
|
||||||
Route::put('customer-service/request/benefit_data/{id}', [RequestLogBenefitController::class, 'update']);
|
Route::put('customer-service/request/benefit_data/{id}', [RequestLogBenefitController::class, 'update']);
|
||||||
|
|
||||||
|
// insert medicine
|
||||||
|
Route::post('customer-service/request/medicine-data', [RequestLogMedicineController::class, 'store']);
|
||||||
|
Route::delete('customer-service/request/medicine-data/{id}', [RequestLogMedicineController::class, 'destroy']);
|
||||||
|
Route::put('customer-service/request/medicine-data/{id}', [RequestLogMedicineController::class, 'update']);
|
||||||
|
|
||||||
Route::get('search-organizations', [OrganizationController::class, 'searchOrganization']);
|
Route::get('search-organizations', [OrganizationController::class, 'searchOrganization']);
|
||||||
Route::get('search-specialities', [SpecialityController::class, 'searchSpeciality']);
|
Route::get('search-specialities', [SpecialityController::class, 'searchSpeciality']);
|
||||||
Route::resource('organizations', OrganizationController::class);
|
Route::resource('organizations', OrganizationController::class);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use App\Models\CorporateBenefit;
|
|||||||
use App\Models\ClaimRequest;
|
use App\Models\ClaimRequest;
|
||||||
use App\Models\CorporateService;
|
use App\Models\CorporateService;
|
||||||
use App\Models\RequestLogBenefit;
|
use App\Models\RequestLogBenefit;
|
||||||
|
use App\Models\RequestLogMedicine;
|
||||||
use App\Models\Exclusion;
|
use App\Models\Exclusion;
|
||||||
use App\Models\Icd;
|
use App\Models\Icd;
|
||||||
use App\Helpers\Helper;
|
use App\Helpers\Helper;
|
||||||
@@ -26,6 +27,7 @@ class RequestLogShowResource extends JsonResource
|
|||||||
$corporateId = $requestLog['member']['current_plan']['corporate_id'] ?? 0;
|
$corporateId = $requestLog['member']['current_plan']['corporate_id'] ?? 0;
|
||||||
$benefit = CorporateBenefit::with('benefit')->where('plan_id', $corporateId)->get()->toArray();
|
$benefit = CorporateBenefit::with('benefit')->where('plan_id', $corporateId)->get()->toArray();
|
||||||
$benefitDetailLog = RequestLogBenefit::with('benefit')->where('request_log_id', $requestLog['id'])->get()->toArray();
|
$benefitDetailLog = RequestLogBenefit::with('benefit')->where('request_log_id', $requestLog['id'])->get()->toArray();
|
||||||
|
$medicineDetailLog = RequestLogMedicine::where('request_log_id', $requestLog['id'])->get()->toArray();
|
||||||
$benefitData = [];
|
$benefitData = [];
|
||||||
if (count($benefit)){
|
if (count($benefit)){
|
||||||
foreach($benefit as $data){
|
foreach($benefit as $data){
|
||||||
@@ -33,13 +35,23 @@ class RequestLogShowResource extends JsonResource
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Medicine
|
||||||
|
$medicineData = [];
|
||||||
|
if (count($medicineDetailLog)){
|
||||||
|
foreach($medicineDetailLog as $data){
|
||||||
|
array_push($medicineData, $data);
|
||||||
|
}
|
||||||
|
}
|
||||||
// Service Rule
|
// Service Rule
|
||||||
$corporateService = CorporateService::query()
|
$corporateService = CorporateService::query()
|
||||||
->where('corporate_id', $corporateId)
|
->where('corporate_id', $corporateId)
|
||||||
->where('service_code', $requestLog['service_code'])
|
->where('service_code', $requestLog['service_code'])
|
||||||
->with(['configs'])
|
->with(['configs'])
|
||||||
->first();
|
->first();
|
||||||
$config = $corporateService->configs->pluck('value', 'name')->toArray();
|
$config = [];
|
||||||
|
if ($corporateService) {
|
||||||
|
$config = $corporateService->configs->pluck('value', 'name')->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
// Exclusion Service or diagnosis
|
// Exclusion Service or diagnosis
|
||||||
$exclusions = Exclusion::query()
|
$exclusions = Exclusion::query()
|
||||||
@@ -70,6 +82,7 @@ class RequestLogShowResource extends JsonResource
|
|||||||
'benefit_data' => $benefitDetailLog,
|
'benefit_data' => $benefitDetailLog,
|
||||||
'config_service' => $config,
|
'config_service' => $config,
|
||||||
'exclusion' => $exclusions,
|
'exclusion' => $exclusions,
|
||||||
|
'medicine' => $medicineData,
|
||||||
'files' => $requestLog['files'],
|
'files' => $requestLog['files'],
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
30
app/Models/RequestLogMedicine.php
Normal file
30
app/Models/RequestLogMedicine.php
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class RequestLogMedicine extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
public $fillable = [
|
||||||
|
'request_log_id',
|
||||||
|
'medicine',
|
||||||
|
'price',
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $hidden = [
|
||||||
|
'created_at',
|
||||||
|
'updated_at',
|
||||||
|
'deleted_at',
|
||||||
|
'created_by',
|
||||||
|
'updated_by',
|
||||||
|
'deleted_by',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function benefit(){
|
||||||
|
return $this->belongsTo(Benefit::class, 'benefit_id', 'id');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
<?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_medicines', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->timestamps();
|
||||||
|
$table->foreignId('request_log_id');
|
||||||
|
$table->integer('price');
|
||||||
|
$table->string('medicine');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('request_log_medicines');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -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_logs', function (Blueprint $table) {
|
||||||
|
$table->dateTime('discharge_date')->after('submission_date')->nullable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('request_logs', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('discharge_date');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -13,9 +13,10 @@ return new class extends Migration
|
|||||||
*/
|
*/
|
||||||
public function up()
|
public function up()
|
||||||
{
|
{
|
||||||
Schema::create('claim_daily_monitoring', function (Blueprint $table) {
|
Schema::create('request_log_daily_monitorings', function (Blueprint $table) {
|
||||||
$table->bigIncrements('id');
|
$table->id();
|
||||||
$table->integer('claim_id');
|
$table->foreignId('request_log_id');
|
||||||
|
$table->timestamps();
|
||||||
$table->text('subject');
|
$table->text('subject');
|
||||||
$table->decimal('body_temperature', 11, 2);
|
$table->decimal('body_temperature', 11, 2);
|
||||||
$table->decimal('respiration_rate', 11, 2);
|
$table->decimal('respiration_rate', 11, 2);
|
||||||
@@ -23,7 +24,9 @@ return new class extends Migration
|
|||||||
$table->decimal('diastole', 11, 2);
|
$table->decimal('diastole', 11, 2);
|
||||||
$table->text('analysis');
|
$table->text('analysis');
|
||||||
$table->text('complaints');
|
$table->text('complaints');
|
||||||
$table->timestamps();
|
$table->dateTime('lab_date')->nullable();
|
||||||
|
$table->string('provider')->nullable();
|
||||||
|
$table->string('examination')->nullable();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,6 +37,6 @@ return new class extends Migration
|
|||||||
*/
|
*/
|
||||||
public function down()
|
public function down()
|
||||||
{
|
{
|
||||||
Schema::dropIfExists('claim_daily_monitoring');
|
Schema::dropIfExists('request_log_daily_monitorings');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -13,7 +13,7 @@ type MuiDialogProps = {
|
|||||||
openDialog: boolean;
|
openDialog: boolean;
|
||||||
setOpenDialog: Function;
|
setOpenDialog: Function;
|
||||||
content?: ReactElement;
|
content?: ReactElement;
|
||||||
action?: ReactElement;
|
action?: ReactElement|null;
|
||||||
maxWidth?: string;
|
maxWidth?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export default function ClaimListRow ({ ...props }: Props) {
|
|||||||
<TableRow hover sx={{ '& > td': { borderBottom: '1' } }}>
|
<TableRow hover sx={{ '& > td': { borderBottom: '1' } }}>
|
||||||
<TableCell align="left" />
|
<TableCell align="left" />
|
||||||
<TableCell align="left">
|
<TableCell align="left">
|
||||||
{props.row.admission_date == "0000-00-00 00:00:00" ?
|
{props.row.admission_date == null?
|
||||||
('-')
|
('-')
|
||||||
:
|
:
|
||||||
(
|
(
|
||||||
@@ -50,7 +50,7 @@ export default function ClaimListRow ({ ...props }: Props) {
|
|||||||
)}
|
)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell align="left">
|
<TableCell align="left">
|
||||||
{props.row.discharge_date == "0000-00-00 00:00:00" ?
|
{props.row.discharge_date == null ?
|
||||||
('-')
|
('-')
|
||||||
:
|
:
|
||||||
(
|
(
|
||||||
@@ -62,9 +62,29 @@ export default function ClaimListRow ({ ...props }: Props) {
|
|||||||
</Label>
|
</Label>
|
||||||
)}
|
)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell align="left">{props.row.claim_code}</TableCell>
|
<TableCell align="left">{props.row.code}</TableCell>
|
||||||
<TableCell align="left">{props.row.service_type}</TableCell>
|
<TableCell align="left">{props.row.service_name}</TableCell>
|
||||||
<TableCell align="left">{props.row.claim_status}</TableCell>
|
<TableCell align="left">
|
||||||
|
{props.row.discharge_date == null ?
|
||||||
|
(
|
||||||
|
<Label
|
||||||
|
variant="ghost"
|
||||||
|
color="warning"
|
||||||
|
>
|
||||||
|
On Monitor
|
||||||
|
</Label>
|
||||||
|
) :
|
||||||
|
(
|
||||||
|
<Label
|
||||||
|
variant="ghost"
|
||||||
|
color="success"
|
||||||
|
>
|
||||||
|
Close Monitor
|
||||||
|
</Label>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
</TableCell>
|
||||||
<TableCell align="right" onClick={(e) => e.stopPropagation()}>
|
<TableCell align="right" onClick={(e) => e.stopPropagation()}>
|
||||||
<Stack direction="row" justifyContent="flex-end" spacing={1}>
|
<Stack direction="row" justifyContent="flex-end" spacing={1}>
|
||||||
<TableMoreMenu actions={
|
<TableMoreMenu actions={
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ export default function DailyMonitoringList() {
|
|||||||
<TableCell style={TableHeadStyle} align="left" width={'*'}>Name</TableCell>
|
<TableCell style={TableHeadStyle} align="left" width={'*'}>Name</TableCell>
|
||||||
<TableCell style={TableHeadStyle} align="left" width={160}>Start Date</TableCell>
|
<TableCell style={TableHeadStyle} align="left" width={160}>Start Date</TableCell>
|
||||||
<TableCell style={TableHeadStyle} align="left" width={160}>End Date</TableCell>
|
<TableCell style={TableHeadStyle} align="left" width={160}>End Date</TableCell>
|
||||||
|
<TableCell style={TableHeadStyle} align="left" width={160}>Admission Date</TableCell>
|
||||||
|
<TableCell style={TableHeadStyle} align="left" width={160}>Provider</TableCell>
|
||||||
<TableCell align="left" width={"10"} />
|
<TableCell align="left" width={"10"} />
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
|
|||||||
@@ -53,6 +53,15 @@ export default function DailyMonitoringListRow ({ ...props }: Props) {
|
|||||||
{fDate(props.row.enddate)}
|
{fDate(props.row.enddate)}
|
||||||
</Label>
|
</Label>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
<TableCell align="left">
|
||||||
|
<Label
|
||||||
|
variant="ghost"
|
||||||
|
color="default"
|
||||||
|
>
|
||||||
|
{fDate(props.row.addmision_date)}
|
||||||
|
</Label>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="left">{props.row.provider}</TableCell>
|
||||||
<TableCell align="right" onClick={(e) => e.stopPropagation()}>
|
<TableCell align="right" onClick={(e) => e.stopPropagation()}>
|
||||||
<Stack direction="row" justifyContent="flex-end" spacing={1}>
|
<Stack direction="row" justifyContent="flex-end" spacing={1}>
|
||||||
<TableMoreMenu actions={
|
<TableMoreMenu actions={
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ export type DailyMonitoringListType = {
|
|||||||
name : string,
|
name : string,
|
||||||
startdate : string,
|
startdate : string,
|
||||||
enddate : string,
|
enddate : string,
|
||||||
|
addmision_date : string,
|
||||||
|
provider : string
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,355 +0,0 @@
|
|||||||
/**
|
|
||||||
* Core
|
|
||||||
* ============================================
|
|
||||||
*/
|
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
import { useNavigate } from 'react-router';
|
|
||||||
import { Box, FormControlLabel, Grid, Checkbox, Typography, CircularProgress , Button, styled, Stack, IconButton, Card} from '@mui/material';
|
|
||||||
import { LoadingButton } from '@mui/lab';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Components
|
|
||||||
* ============================================
|
|
||||||
*/
|
|
||||||
// - Global -
|
|
||||||
import Label from '@/components/Label';
|
|
||||||
// - Local -
|
|
||||||
import FormCreateSearch from './FormCreateSearch';
|
|
||||||
import FormCreateListChoose from './FormCreateListChoose';
|
|
||||||
import FormCreateBtnUpload from './FormCreateBtnUpload';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Icon, Utils, Types, Functions, theme, hook
|
|
||||||
* ============================================
|
|
||||||
*/
|
|
||||||
import { ArrowBackIosNew } from '@mui/icons-material';
|
|
||||||
import { fDateTimesecond } from '@/utils/formatTime';
|
|
||||||
import { MemberListType } from '../Model/Types';
|
|
||||||
import { addClaimRequest, getMemberList } from '../Model/Functions';
|
|
||||||
import palette from '@/theme/palette';
|
|
||||||
import FormCreateFilesUpload from './FormCreateFilesUpload';
|
|
||||||
import useLoadOnScroll from '@/hooks/useLoadOnScroll';
|
|
||||||
import useCollapseDrawer from '@/hooks/useCollapseDrawer';
|
|
||||||
import FormCreateBtnChoose from './FormCreateBtnChoose';
|
|
||||||
import axios from '../../../utils/axios';
|
|
||||||
|
|
||||||
export default function FormCreate() {
|
|
||||||
const navigate = useNavigate()
|
|
||||||
const defaultListChoosed:MemberListType[] = [];
|
|
||||||
|
|
||||||
// State
|
|
||||||
// -------------------------
|
|
||||||
const [keyword, setKeyword] = useState<string>('');
|
|
||||||
const [listChoosed, setListChoosed] = useState<MemberListType[]>([]);
|
|
||||||
const [isChoosed, setIsChoosed] = useState<boolean>(false);
|
|
||||||
const [formIsLoading, setFormIsLoading] = useState<boolean>(false);
|
|
||||||
|
|
||||||
// List Choose - auto Scroll
|
|
||||||
// -------------------------
|
|
||||||
const fetchFunction = async (page: number): Promise<MemberListType[]> => getMemberList(page, keyword)
|
|
||||||
|
|
||||||
const {data: MemberList, isLoading: scrollIsLoading, setData, resetLastPage, refetchData} = useLoadOnScroll<MemberListType>(fetchFunction);
|
|
||||||
|
|
||||||
// List Choose - Search
|
|
||||||
// -------------------------
|
|
||||||
const handleSearch = (keyword: string) => {
|
|
||||||
setData([])
|
|
||||||
resetLastPage()
|
|
||||||
setKeyword(keyword)
|
|
||||||
refetchData()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function - Clear Form
|
|
||||||
// -----------------------------
|
|
||||||
const clearForm = () => {
|
|
||||||
setListChoosed(defaultListChoosed);
|
|
||||||
setIsChoosed(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function - Choose Patien Type
|
|
||||||
// -----------------------------
|
|
||||||
const handleChoosePatienType = (data: MemberListType, type: string) => {
|
|
||||||
let newListChoosed = listChoosed.map((list) => {
|
|
||||||
if (data.id == list.id) {
|
|
||||||
list.patien_type = type
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
})
|
|
||||||
setListChoosed(newListChoosed)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function - Handle Btn Upload
|
|
||||||
// -----------------------------
|
|
||||||
const handleChangeInput = (data: MemberListType, type_file: 'kondisi'|'diagnosa'|'penunjang', file: any) => {
|
|
||||||
let newListChoosed = listChoosed.map((list) => {
|
|
||||||
if (data.id == list.id) {
|
|
||||||
if (type_file == 'kondisi') {
|
|
||||||
if (list.file_kondisi == undefined) {
|
|
||||||
list.file_kondisi = [file];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
list.file_kondisi.push(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type_file == 'diagnosa') {
|
|
||||||
if (list.file_diagnosa == undefined) {
|
|
||||||
list.file_diagnosa = [file];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
list.file_diagnosa.push(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type_file == 'penunjang') {
|
|
||||||
if (list.file_penunjang == undefined) {
|
|
||||||
list.file_penunjang = [file];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
list.file_penunjang.push(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
})
|
|
||||||
|
|
||||||
setListChoosed(newListChoosed)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function - Handle Remove Fle
|
|
||||||
// -----------------------------
|
|
||||||
const handleRemoveFile = (data: MemberListType, type_file: 'kondisi'|'diagnosa'|'penunjang', target_index: number) => {
|
|
||||||
let newListChoosed = listChoosed.map((list) => {
|
|
||||||
if (data.id == list.id) {
|
|
||||||
if (type_file == 'kondisi') {
|
|
||||||
list.file_kondisi = list.file_kondisi?.filter((file: any, index: number) =>{
|
|
||||||
if (target_index !== index) {
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type_file == 'diagnosa') {
|
|
||||||
list.file_diagnosa = list.file_diagnosa?.filter((file: any, index: number) =>{
|
|
||||||
if (target_index !== index) {
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type_file == 'penunjang') {
|
|
||||||
list.file_penunjang = list.file_penunjang?.filter((file: any, index: number) =>{
|
|
||||||
if (target_index !== index) {
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
})
|
|
||||||
|
|
||||||
setListChoosed(newListChoosed)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function - Handle Submit Form
|
|
||||||
// -----------------------------
|
|
||||||
const handleSubmit = async () => {
|
|
||||||
setFormIsLoading(true)
|
|
||||||
let response = await addClaimRequest(listChoosed)
|
|
||||||
setFormIsLoading(false)
|
|
||||||
|
|
||||||
if (response == true) {
|
|
||||||
clearForm()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let isDirty = listChoosed.some((row) => {
|
|
||||||
if (row.patien_type == undefined) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Box>
|
|
||||||
{/* Back Button */}
|
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', mb: 5}}>
|
|
||||||
<IconButton size='large' color='inherit' onClick={() => isChoosed==false ? navigate(`/claim-requests`) : setIsChoosed(false)} >
|
|
||||||
<ArrowBackIosNew/>
|
|
||||||
</IconButton>
|
|
||||||
|
|
||||||
<Typography variant="h5" sx={{ marginLeft: '24px' }}>
|
|
||||||
{'Create Claim Requests'}
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* Choose Section */}
|
|
||||||
<Grid container spacing={4} sx={{ px: 2, position: 'relative', display: isChoosed==false ? 'inherit' : 'none' }}>
|
|
||||||
{/* Search */}
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<FormCreateSearch onEmpty={() => handleSearch('')} onSubmit={(keyword) => handleSearch(keyword)} />
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Grid container spacing={2}>
|
|
||||||
{/* List */}
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Grid container spacing={2}>
|
|
||||||
{
|
|
||||||
MemberList.map((row, index) => {
|
|
||||||
return (
|
|
||||||
<FormCreateListChoose
|
|
||||||
key={index}
|
|
||||||
data={row}
|
|
||||||
ListChoosed={listChoosed}
|
|
||||||
handleCheckedProp={(checked, data) => {
|
|
||||||
checked ? setListChoosed((prevData) => [...prevData, data]) : setListChoosed((items) => items.filter(item => item.id != data.id))
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{/* Loading */}
|
|
||||||
<Grid item xs={12} sx={{ display: scrollIsLoading === false ? 'none' : 'flex', justifyContent: 'center', marginTop: '40px' }}>
|
|
||||||
<CircularProgress />
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{/* Submit List */}
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<FormCreateBtnChoose disabled={listChoosed.length==0} title={`Create Number Batch (${listChoosed.length})`} handleClickProp={() => setIsChoosed(true)} />
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{/* Input Section */}
|
|
||||||
<Grid container spacing={10} sx={{ px: 2, display: isChoosed==true ? 'inherit' : 'none' }}>
|
|
||||||
{
|
|
||||||
listChoosed.map((row, index) => {
|
|
||||||
return (
|
|
||||||
<Grid key={index} item xs={12}>
|
|
||||||
<Grid container spacing={6}>
|
|
||||||
{/* Patien Name */}
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Card sx={{ border: '1px solid rgba(0,0,0,0.05)', display: 'flex', justifyContent: 'space-between', borderRadius: '12px', px: '24px', py: '16px' }}>
|
|
||||||
<Box>
|
|
||||||
<Typography variant="body2" sx={{ fontWeight: 600 }}>
|
|
||||||
{row.name}
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="caption" color={palette.light.grey[500]} sx={{ fontWeight: 600 }}>
|
|
||||||
{row.member_id}
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Label variant="ghost" color="default">
|
|
||||||
{fDateTimesecond(new Date())}
|
|
||||||
</Label>
|
|
||||||
</Card>
|
|
||||||
</Grid>
|
|
||||||
{/* Patien Type */}
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Grid container spacing={2}>
|
|
||||||
{row.service_type.map((r,i) => {
|
|
||||||
const code = r.code
|
|
||||||
return (
|
|
||||||
<Grid item xs={6}>
|
|
||||||
<Button
|
|
||||||
sx={{ padding: 2, width: '100%',border: row.patien_type === code ? '1px solid #19BBBB' : '1px solid #919EAB52' }}
|
|
||||||
variant="outlined"
|
|
||||||
color={row.patien_type === code ? 'primary' : 'inherit'}
|
|
||||||
onClick={() => {
|
|
||||||
handleChoosePatienType(row, code)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{r.name}
|
|
||||||
</Button>
|
|
||||||
</Grid>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{/* File Kondisi */}
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Grid container spacing={2}>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Typography variant="h6">Condition Document</Typography>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{row.file_kondisi && row.file_kondisi.map((file, index) => (
|
|
||||||
<Grid item xs={12} key={index}>
|
|
||||||
<FormCreateFilesUpload file={file} handleRemoveFileProp={() => handleRemoveFile(row, 'kondisi', index)} />
|
|
||||||
</Grid>
|
|
||||||
))}
|
|
||||||
|
|
||||||
<Grid item xs={12} sx={{display: 'flex', gap: 1}}>
|
|
||||||
<FormCreateBtnUpload handleChangeInputProp={(file) => handleChangeInput(row, 'kondisi', file)} />
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{/* File Diagnosa */}
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Grid container spacing={2}>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Typography variant="h6">Diagnosis Document</Typography>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{row.file_diagnosa && row.file_diagnosa.map((file, index) => (
|
|
||||||
<Grid item xs={12} key={index}>
|
|
||||||
<FormCreateFilesUpload file={file} handleRemoveFileProp={() => handleRemoveFile(row, 'diagnosa', index)} />
|
|
||||||
</Grid>
|
|
||||||
))}
|
|
||||||
|
|
||||||
<Grid item xs={12} sx={{display: 'flex', gap: 1}}>
|
|
||||||
<FormCreateBtnUpload handleChangeInputProp={(file) => handleChangeInput(row, 'diagnosa', file)} />
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{/* File Penunjang */}
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Grid container spacing={2}>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Typography variant="h6">Supporting Result Document</Typography>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{row.file_penunjang && row.file_penunjang.map((file, index) => (
|
|
||||||
<Grid item xs={12} key={index}>
|
|
||||||
<FormCreateFilesUpload file={file} handleRemoveFileProp={() => handleRemoveFile(row, 'penunjang', index)} />
|
|
||||||
</Grid>
|
|
||||||
))}
|
|
||||||
|
|
||||||
<Grid item xs={12} sx={{display: 'flex', gap: 1}}>
|
|
||||||
<FormCreateBtnUpload handleChangeInputProp={(file) => handleChangeInput(row, 'penunjang', file)} />
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
<Grid item xs={12} sx={{ display: 'flex', justifyContent: 'flex-end' }}>
|
|
||||||
<Box display="flex" gap={1}>
|
|
||||||
<Button variant="outlined" color="inherit" onClick={() => clearForm()}>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
<LoadingButton disabled={isDirty} type="submit" variant="contained" loading={formIsLoading} onClick={() => handleSubmit()}>
|
|
||||||
Save Changes
|
|
||||||
</LoadingButton>
|
|
||||||
</Box>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</Box>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
import { styled, Button } from "@mui/material";
|
|
||||||
import useCollapseDrawer from "@/hooks/useCollapseDrawer";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Custom Style
|
|
||||||
* ============================================
|
|
||||||
*/
|
|
||||||
const DivCustom1 = styled('div')(({ theme }) => ({
|
|
||||||
background: 'white',
|
|
||||||
position: 'fixed',
|
|
||||||
left: '350px',
|
|
||||||
right: 0,
|
|
||||||
bottom: 0,
|
|
||||||
paddingLeft: '32px',
|
|
||||||
paddingRight: '32px',
|
|
||||||
paddingTop: '32px',
|
|
||||||
paddingBottom: '48px',
|
|
||||||
[theme.breakpoints.between('sm', 'lg')]: {
|
|
||||||
left: '0px',
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
disabled: boolean,
|
|
||||||
title : string,
|
|
||||||
handleClickProp: () => void
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function FormCreateBtnChoose ({disabled, title, handleClickProp}: Props) {
|
|
||||||
const { collapseClick } = useCollapseDrawer();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<DivCustom1 sx={{ left: collapseClick ? '80px' : '350px' }}>
|
|
||||||
<Button variant="contained" color="primary" disabled={disabled} sx={{ width: '100%', p: '11px' }} onClick={handleClickProp}>
|
|
||||||
{title}
|
|
||||||
</Button>
|
|
||||||
</DivCustom1>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
import { useRef } from "react";
|
|
||||||
import { Box, ButtonBase, Typography } from "@mui/material";
|
|
||||||
import Iconify from "@/components/Iconify";
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
handleChangeInputProp: (event: any) => void
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function FormCreateBtnUpload ({handleChangeInputProp}: Props) {
|
|
||||||
const fileInput = useRef<HTMLInputElement>(null);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ButtonBase sx={{ py: 5, border: '2px dashed #F9FAFB',bgcolor: '#919EAB52',borderRadius: '8px',width: '100%', height: '60px'}} onClick={() => fileInput.current?.click()}>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
display: 'flex',
|
|
||||||
placeItems: 'center',
|
|
||||||
gap: 1,
|
|
||||||
placeContent: 'center',
|
|
||||||
py:'11px'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Iconify icon="icon-park-outline:upload-one" fontSize="1.5em" />
|
|
||||||
<Typography variant="body1" fontWeight="bold" fontSize={'15px'}>
|
|
||||||
Upload Result
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
<input
|
|
||||||
type="file"
|
|
||||||
id="file"
|
|
||||||
ref={fileInput}
|
|
||||||
style={{ display: 'none' }}
|
|
||||||
multiple
|
|
||||||
onChange={(event) => handleChangeInputProp(event.target.files ? event.target.files[0] : {})}
|
|
||||||
accept="application/pdf"
|
|
||||||
/>
|
|
||||||
</ButtonBase>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
import Iconify from "@/components/Iconify";
|
|
||||||
import { ArrowBackIosNew, InsertDriveFile } from '@mui/icons-material';
|
|
||||||
import { Stack, Typography } from "@mui/material";
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
file: any,
|
|
||||||
handleRemoveFileProp: () => void,
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function FormCreateFilesUpload({ file, handleRemoveFileProp }: Props) {
|
|
||||||
return (
|
|
||||||
<Stack direction="row" justifyContent={'space-between'} sx={{ mb: '16px' }}>
|
|
||||||
<Stack direction="row" spacing={1} sx={{color: '#19BBBB'}}>
|
|
||||||
<InsertDriveFile />
|
|
||||||
<Typography variant="body2" gutterBottom>{file.name ? file.name : '-'}</Typography>
|
|
||||||
</Stack>
|
|
||||||
<Iconify
|
|
||||||
icon="eva:trash-2-outline"
|
|
||||||
color={'darkred'}
|
|
||||||
onClick={() => {handleRemoveFileProp()}}
|
|
||||||
sx={{cursor: 'pointer'}}
|
|
||||||
></Iconify>
|
|
||||||
</Stack>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
/**
|
|
||||||
* Core
|
|
||||||
* ============================================
|
|
||||||
*/
|
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
import { Box, FormControlLabel, Grid, Checkbox, Typography, Card} from '@mui/material';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Components
|
|
||||||
* ============================================
|
|
||||||
*/
|
|
||||||
// - Global -
|
|
||||||
import Label from '@/components/Label';
|
|
||||||
// - Local -
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Icon, Utils, Types, Functions, theme, hook
|
|
||||||
* ============================================
|
|
||||||
*/
|
|
||||||
import { fDateTimesecond } from '@/utils/formatTime';
|
|
||||||
import { MemberListType } from '../Model/Types';
|
|
||||||
import palette from '@/theme/palette';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Props
|
|
||||||
* =====================================================
|
|
||||||
*/
|
|
||||||
type Props = {
|
|
||||||
data: MemberListType,
|
|
||||||
ListChoosed: MemberListType[],
|
|
||||||
handleCheckedProp: (checked: boolean, data: MemberListType) => void,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function FormCreateListChoose({data, ListChoosed, handleCheckedProp}: Props) {
|
|
||||||
const [isChoosed, setIsChoosed] = useState<boolean>(false)
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setIsChoosed(false);
|
|
||||||
|
|
||||||
ListChoosed.forEach(list => {
|
|
||||||
if (list.id == data.id) {
|
|
||||||
setIsChoosed(true);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}, [ListChoosed])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Card sx={{
|
|
||||||
border: '0px solid rgba(0,0,0,0.125)', px: '24px', py: '16px', borderRadius: '12px', display: 'flex', justifyContent: 'space-between',
|
|
||||||
bgcolor: (theme) => {
|
|
||||||
return isChoosed ? palette.light.primary.lighter : palette.light.background.default
|
|
||||||
}
|
|
||||||
}}>
|
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', px: '8px'}}>
|
|
||||||
<FormControlLabel
|
|
||||||
label=""
|
|
||||||
control={<Checkbox onChange={(event, checked) => handleCheckedProp(checked, data)} />}
|
|
||||||
checked={isChoosed}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Box>
|
|
||||||
<Typography variant="body2" sx={{ fontWeight: 600 }}>
|
|
||||||
{data.name}
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="caption" color={palette.light.grey[500]} sx={{ fontWeight: 600 }}>
|
|
||||||
{data.member_id}
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Label variant="ghost" color="default">
|
|
||||||
{fDateTimesecond(new Date())}
|
|
||||||
</Label>
|
|
||||||
</Card>
|
|
||||||
</Grid>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
/**
|
|
||||||
* Core
|
|
||||||
* ============================================
|
|
||||||
*/
|
|
||||||
import { useEffect } from 'react';
|
|
||||||
import { useForm } from 'react-hook-form';
|
|
||||||
import { Grid } from '@mui/material';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Components
|
|
||||||
* ============================================
|
|
||||||
*/
|
|
||||||
// - Global -
|
|
||||||
import { FormProvider, RHFTextField } from '@/components/hook-form';
|
|
||||||
// - Local -
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Icon, Utils, Types, Functions
|
|
||||||
* ============================================
|
|
||||||
*/
|
|
||||||
import { Search } from '@mui/icons-material';
|
|
||||||
import { SearchType } from '../Model/Types';
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
onSubmit: (keyword: string) => void,
|
|
||||||
onEmpty: () => void,
|
|
||||||
};
|
|
||||||
|
|
||||||
const FormCreateSearch = ({ onSubmit, onEmpty }: Props) => {
|
|
||||||
const defaultValuesSearchForm = {
|
|
||||||
keyword: ''
|
|
||||||
};
|
|
||||||
|
|
||||||
const methodsSearchForm = useForm<SearchType>({
|
|
||||||
defaultValues: defaultValuesSearchForm
|
|
||||||
});
|
|
||||||
|
|
||||||
const { handleSubmit, formState: { isDirty } } = methodsSearchForm;
|
|
||||||
|
|
||||||
// search on submit
|
|
||||||
const onSubmitSearch = (data: SearchType ) => {
|
|
||||||
onSubmit(data.keyword);
|
|
||||||
}
|
|
||||||
|
|
||||||
// search on empty
|
|
||||||
useEffect(() => {
|
|
||||||
if (isDirty === false) {
|
|
||||||
onEmpty()
|
|
||||||
}
|
|
||||||
},[isDirty])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FormProvider methods={methodsSearchForm} onSubmit={handleSubmit(onSubmitSearch)}>
|
|
||||||
<Grid container direction={"row"}>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<RHFTextField
|
|
||||||
name="keyword"
|
|
||||||
placeholder="Search..."
|
|
||||||
autoComplete='off'
|
|
||||||
fullWidth
|
|
||||||
InputProps={{ startAdornment: <Search /> }}
|
|
||||||
sx={{ input: { paddingLeft: '14px' } }}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</FormProvider>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default FormCreateSearch
|
|
||||||
@@ -1,456 +0,0 @@
|
|||||||
import * as Yup from 'yup';
|
|
||||||
import { useSnackbar } from 'notistack';
|
|
||||||
import { useNavigate } from 'react-router-dom';
|
|
||||||
import { yupResolver } from '@hookform/resolvers/yup';
|
|
||||||
import { Controller, useForm } from 'react-hook-form';
|
|
||||||
import React, { useRef, useEffect, useMemo, useState } from 'react';
|
|
||||||
import axios from '../../../utils/axios';
|
|
||||||
import { FormProvider, RHFTextField } from '../../../components/hook-form';
|
|
||||||
|
|
||||||
import { makeFormData } from '@/utils/jsonToFormData';
|
|
||||||
import {
|
|
||||||
Autocomplete,
|
|
||||||
Button,
|
|
||||||
Grid,
|
|
||||||
Stack,
|
|
||||||
Table,
|
|
||||||
TableBody,
|
|
||||||
TableCell,
|
|
||||||
TableRow,
|
|
||||||
TextField,
|
|
||||||
Typography,
|
|
||||||
useTheme,
|
|
||||||
List,
|
|
||||||
ListItem,
|
|
||||||
IconButton,
|
|
||||||
ListItemAvatar,
|
|
||||||
Avatar,
|
|
||||||
ListItemText,
|
|
||||||
Card,
|
|
||||||
InputAdornment,
|
|
||||||
Divider,
|
|
||||||
ButtonBase,
|
|
||||||
Box,
|
|
||||||
} from '@mui/material';
|
|
||||||
import Iconify from '../../../components/Iconify';
|
|
||||||
import CalendarTodayIcon from '@mui/icons-material/CalendarToday';
|
|
||||||
import { LoadingButton } from '@mui/lab';
|
|
||||||
import { fCurrency } from '../../../utils/formatNumber';
|
|
||||||
import MemberSelectDialog from '../../../components/dialogs/MemberSelectDialog';
|
|
||||||
import { Add, ArrowBackIosNew, DeleteOutline } from '@mui/icons-material';
|
|
||||||
import { ClaimRequest, Files } from '@/@types/claims';
|
|
||||||
import { fDateTimesecond } from '@/utils/formatTime';
|
|
||||||
|
|
||||||
interface FormValuesProps extends Partial<ClaimRequest> {
|
|
||||||
taxes: boolean;
|
|
||||||
inStock: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
isEdit: boolean;
|
|
||||||
currentClaim?: ClaimRequest;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function FormEdit({ isEdit, currentClaim }: Props) {
|
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
const { enqueueSnackbar } = useSnackbar();
|
|
||||||
|
|
||||||
const EditClaimSchema = Yup.object().shape({
|
|
||||||
organization_id: Yup.string().required('Code Provider is required'),
|
|
||||||
});
|
|
||||||
|
|
||||||
const defaultValues = useMemo(
|
|
||||||
() => ({
|
|
||||||
id: currentClaim?.id || '-',
|
|
||||||
code: currentClaim?.code || '-',
|
|
||||||
member_name: currentClaim?.member?.name || '-',
|
|
||||||
date: currentClaim?.submission_date ? fDateTimesecond(currentClaim?.submission_date) : '-',
|
|
||||||
claim_method: currentClaim?.payment_type || '-',
|
|
||||||
service_type: currentClaim?.service_code || '-',
|
|
||||||
organization_id: currentClaim?.organization?.code || '-',
|
|
||||||
}),
|
|
||||||
[currentClaim]
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isEdit && currentClaim) {
|
|
||||||
reset(defaultValues);
|
|
||||||
}
|
|
||||||
if (!isEdit) {
|
|
||||||
reset(defaultValues);
|
|
||||||
}
|
|
||||||
// setFileKondisis(currentClaim?.files_by_type?.claim_diagnosis);
|
|
||||||
// setFileDiagnosas(currentClaim?.files_by_type?.claim_diagnosis);
|
|
||||||
setFileHasilPenunjangCurrent(currentClaim?.files_by_type?.claim_result);
|
|
||||||
}, [isEdit, currentClaim]);
|
|
||||||
|
|
||||||
|
|
||||||
const methods = useForm<FormValuesProps>({
|
|
||||||
resolver: yupResolver(EditClaimSchema),
|
|
||||||
defaultValues,
|
|
||||||
});
|
|
||||||
|
|
||||||
const {
|
|
||||||
reset,
|
|
||||||
watch,
|
|
||||||
control,
|
|
||||||
setValue,
|
|
||||||
getValues,
|
|
||||||
setError,
|
|
||||||
handleSubmit,
|
|
||||||
formState: { isSubmitting },
|
|
||||||
} = methods;
|
|
||||||
|
|
||||||
const values = watch();
|
|
||||||
|
|
||||||
const [isCheckingLimit, setIsCheckingLimit] = useState(false);
|
|
||||||
const [isEligible, setIsEligible] = useState(false);
|
|
||||||
const [memberBenefits, setMemberBenefits] = useState([]);
|
|
||||||
const [diagnosisOption, setDiagnosisOption] = useState([]);
|
|
||||||
const [isMemberDialogOpen, setIsMemberDialogOpen] = useState(false);
|
|
||||||
const [member, setMember] = useState({})
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Files Result Kondisi
|
|
||||||
const fileKondisiInput = useRef<HTMLInputElement>(null);
|
|
||||||
const [fileKondisis, setFileKondisis] = useState<Files>([]);
|
|
||||||
|
|
||||||
const handleKondisiInputChange = (event) => {
|
|
||||||
if (event.target.files[0]) {
|
|
||||||
setFileKondisis([...fileKondisis, ...event.target.files]);
|
|
||||||
} else {
|
|
||||||
console.log('NO FILE');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const removeKondisiFiles = (filesState, index) => {
|
|
||||||
setFileKondisis(
|
|
||||||
filesState.filter((file, fileIndex) => {
|
|
||||||
return fileIndex != index;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Files Result Diagnosa
|
|
||||||
const fileDiagnosaInput = useRef<HTMLInputElement>(null);
|
|
||||||
const [fileDiagnosas, setFileDiagnosas] = useState([]);
|
|
||||||
|
|
||||||
const handleDiagnosaInputChange = (event) => {
|
|
||||||
if (event.target.files[0]) {
|
|
||||||
setFileDiagnosas([...fileDiagnosas, ...event.target.files]);
|
|
||||||
} else {
|
|
||||||
console.log('NO FILE');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const removeDiagnosaFiles = (filesState, index) => {
|
|
||||||
setFileDiagnosas(
|
|
||||||
filesState.filter((file, fileIndex) => {
|
|
||||||
return fileIndex != index;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Files Result Hasil Penunjang
|
|
||||||
const fileHasilPenunjangInput = useRef<HTMLInputElement>(null);
|
|
||||||
const [fileHasilPenunjangs, setFileHasilPenunjangs] = useState([]);
|
|
||||||
const [fileHasilPenunjangsCurrent, setFileHasilPenunjangCurrent] = useState([]);
|
|
||||||
|
|
||||||
const handleResultInputChange = (event) => {
|
|
||||||
if (event.target.files[0]) {
|
|
||||||
setFileHasilPenunjangs([...fileHasilPenunjangs, ...event.target.files]);
|
|
||||||
} else {
|
|
||||||
console.log('NO FILE');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const removeFiles = (filesState, index) => {
|
|
||||||
setFileHasilPenunjangs(
|
|
||||||
filesState.filter((file, fileIndex) => {
|
|
||||||
return fileIndex != index;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const onSubmit = async (data: FormValuesProps) => {
|
|
||||||
try {
|
|
||||||
// const formData = new FormData();
|
|
||||||
// formData.append('result_files', fileHasilPenunjangs);
|
|
||||||
// formData.append('diagnosa_files', fileDiagnosaInput);
|
|
||||||
// formData.append('kondisi_files', fileKondisiInput);
|
|
||||||
// formData.append('provider_code', data.organization_id);
|
|
||||||
// formData.append('_method', 'PUT');
|
|
||||||
const formData = makeFormData({
|
|
||||||
result_files: fileHasilPenunjangs,
|
|
||||||
diagnosa_files: fileDiagnosas,
|
|
||||||
kondisi_files: fileKondisis,
|
|
||||||
provider_code: data.organization_id,
|
|
||||||
_method: 'PUT'
|
|
||||||
});
|
|
||||||
|
|
||||||
const response = await axios.put(`/claim-requests/${data.id}`, formData);
|
|
||||||
|
|
||||||
reset();
|
|
||||||
enqueueSnackbar('Claim Request Updated Successfully!', { variant: 'success' });
|
|
||||||
navigate('/claim-requests');
|
|
||||||
} catch (error: any) {
|
|
||||||
if (error && error.response.status === 422) {
|
|
||||||
for (const [key, value] of Object.entries(error.response.data.errors)) {
|
|
||||||
// setError(key, { message: value[0] });
|
|
||||||
enqueueSnackbar('Failed Processing Request', { variant: 'error' });
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
enqueueSnackbar(error.message ?? 'Failed Processing Request', { variant: 'error' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FormProvider methods={methods} onSubmit={handleSubmit(onSubmit)}>
|
|
||||||
<Stack direction="row" alignItems="center" sx={{ mb: 5 }}>
|
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center'}}>
|
|
||||||
<IconButton size='large' color='inherit' onClick={() => navigate(`/claim-requests`)} >
|
|
||||||
<ArrowBackIosNew/>
|
|
||||||
</IconButton>
|
|
||||||
|
|
||||||
<Typography variant="h5" sx={{ marginLeft: '24px' }}>
|
|
||||||
{'Edit Claim Requests'}
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</Stack>
|
|
||||||
|
|
||||||
<Card sx={{paddingX:2, paddingY:2}}>
|
|
||||||
<Grid container spacing={2}>
|
|
||||||
<Grid item xs={5}>
|
|
||||||
<Typography variant="subtitle1">Code*</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={7}>
|
|
||||||
<Typography variant="subtitle1">Name*</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={5}>
|
|
||||||
<RHFTextField name="code" label="Code" disabled/>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={7}>
|
|
||||||
<RHFTextField name="member_name" label="Name" disabled/>
|
|
||||||
</Grid>
|
|
||||||
{/* <input type="hidden" name="id"/> */}
|
|
||||||
|
|
||||||
|
|
||||||
<Grid item xs={12}></Grid>
|
|
||||||
|
|
||||||
<Grid item xs={3}>
|
|
||||||
<Typography variant="subtitle1">Date of Submission*</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={3}>
|
|
||||||
<Typography variant="subtitle1">Claim Method*</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={3}>
|
|
||||||
<Typography variant="subtitle1">Service Type*</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={3}>
|
|
||||||
<Typography variant="subtitle1">Code Provider*</Typography>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
|
|
||||||
<Grid item xs={3}>
|
|
||||||
<RHFTextField InputProps={{endAdornment: (
|
|
||||||
<InputAdornment position="end">
|
|
||||||
<CalendarTodayIcon />
|
|
||||||
</InputAdornment>
|
|
||||||
), }}
|
|
||||||
name="date" label="Date of Submission" disabled/>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={3}>
|
|
||||||
<RHFTextField name="claim_method" label="Claim Method" disabled/>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={3}>
|
|
||||||
<RHFTextField name="service_type" label="Service Type*" disabled/>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={3}>
|
|
||||||
<RHFTextField name="organization_id" label="Code Provider*"/>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
|
|
||||||
{/* -------------------------------Upload Dokumen Kondisi------------------------------- */}
|
|
||||||
<React.Fragment>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Typography variant='h6'> Condition Document</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
{fileKondisis &&
|
|
||||||
fileKondisis.map((file, index) => (
|
|
||||||
<Stack sx={{marginTop: 2}} direction="row" justifyContent={'space-between'} key={index}>
|
|
||||||
<Typography sx={{ color: "text.secondary" }}>{file.name}</Typography>
|
|
||||||
<Iconify
|
|
||||||
icon="eva:trash-2-outline"
|
|
||||||
color={'darkred'}
|
|
||||||
onClick={() => {
|
|
||||||
removeKondisiFiles(fileKondisis, index);
|
|
||||||
}}
|
|
||||||
></Iconify>
|
|
||||||
</Stack>
|
|
||||||
))}
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<ButtonBase sx={{ p: 4, border: '2px dashed #F9FAFB',
|
|
||||||
bgcolor: '#919EAB52',
|
|
||||||
borderRadius: '8px',
|
|
||||||
width: '100%', height: '60px'}} onClick={() => fileKondisiInput.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 File
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
<input
|
|
||||||
type="file"
|
|
||||||
id="file"
|
|
||||||
ref={fileKondisiInput}
|
|
||||||
style={{ display: 'none' }}
|
|
||||||
multiple
|
|
||||||
onChange={handleKondisiInputChange}
|
|
||||||
accept="application/pdf"
|
|
||||||
/>
|
|
||||||
</ButtonBase>
|
|
||||||
</Grid>
|
|
||||||
</React.Fragment>
|
|
||||||
{/* -------------------------------Upload Dokumen Diagnosa------------------------------- */}
|
|
||||||
<React.Fragment>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Typography variant='h6'> Diagnosis Document</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
{fileDiagnosas &&
|
|
||||||
fileDiagnosas.map((file, index) => (
|
|
||||||
<Stack sx={{marginTop: 2}} direction="row" justifyContent={'space-between'} key={index}>
|
|
||||||
<Typography sx={{ color: "text.secondary" }}>{file.name}</Typography>
|
|
||||||
<Iconify
|
|
||||||
icon="eva:trash-2-outline"
|
|
||||||
color={'darkred'}
|
|
||||||
onClick={() => {
|
|
||||||
removeDiagnosaFiles(fileDiagnosas, index);
|
|
||||||
}}
|
|
||||||
></Iconify>
|
|
||||||
</Stack>
|
|
||||||
))}
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<ButtonBase sx={{ p: 4, border: '2px dashed #F9FAFB',
|
|
||||||
bgcolor: '#919EAB52',
|
|
||||||
borderRadius: '8px',
|
|
||||||
width: '100%', height: '60px'}} onClick={() => fileDiagnosaInput.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"
|
|
||||||
ref={fileDiagnosaInput}
|
|
||||||
style={{ display: 'none' }}
|
|
||||||
multiple
|
|
||||||
onChange={handleDiagnosaInputChange}
|
|
||||||
accept="application/pdf"
|
|
||||||
/>
|
|
||||||
</ButtonBase>
|
|
||||||
</Grid>
|
|
||||||
</React.Fragment>
|
|
||||||
{/* -------------------------------Upload Result Hasil Penunjang------------------------------- */}
|
|
||||||
<React.Fragment>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Typography variant='h6'> Supporting Result Document</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
{fileHasilPenunjangs &&
|
|
||||||
fileHasilPenunjangs.map((file, index) => (
|
|
||||||
<Stack sx={{marginTop: 2}} direction="row" justifyContent={'space-between'} key={index}>
|
|
||||||
<Typography sx={{ color: "text.secondary" }}>{file.name}</Typography>
|
|
||||||
<Iconify
|
|
||||||
icon="eva:trash-2-outline"
|
|
||||||
color={'darkred'}
|
|
||||||
onClick={() => {
|
|
||||||
removeFiles(fileHasilPenunjangs, index);
|
|
||||||
}}
|
|
||||||
></Iconify>
|
|
||||||
</Stack>
|
|
||||||
))}
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<ButtonBase sx={{ p: 4, border: '2px dashed #F9FAFB',
|
|
||||||
bgcolor: '#919EAB52',
|
|
||||||
borderRadius: '8px',
|
|
||||||
width: '100%', height: '60px'}} onClick={() => fileHasilPenunjangInput.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"
|
|
||||||
ref={fileHasilPenunjangInput}
|
|
||||||
style={{ display: 'none' }}
|
|
||||||
multiple
|
|
||||||
onChange={handleResultInputChange}
|
|
||||||
accept="application/pdf"
|
|
||||||
/>
|
|
||||||
</ButtonBase>
|
|
||||||
</Grid>
|
|
||||||
</React.Fragment>
|
|
||||||
|
|
||||||
</Grid>
|
|
||||||
</Card>
|
|
||||||
<Grid container marginTop={3}>
|
|
||||||
<Grid item xs={12} md={12} >
|
|
||||||
<Stack direction="row" alignItems="center" justifyContent="flex-end">
|
|
||||||
<Button
|
|
||||||
sx={{
|
|
||||||
margin: 1
|
|
||||||
}}
|
|
||||||
type="submit"
|
|
||||||
variant="contained"
|
|
||||||
size="large"
|
|
||||||
color='inherit'
|
|
||||||
onClick={() => navigate(`/claim-requests`)}
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
<LoadingButton
|
|
||||||
type="submit"
|
|
||||||
variant="contained"
|
|
||||||
size="large"
|
|
||||||
loading={isSubmitting}
|
|
||||||
>
|
|
||||||
Update
|
|
||||||
</LoadingButton>
|
|
||||||
</Stack>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</FormProvider>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
import * as Yup from 'yup';
|
|
||||||
import { Box, IconButton } from '@mui/material';
|
|
||||||
import { ArrowBackIosNew } from '@mui/icons-material';
|
|
||||||
import { yupResolver } from '@hookform/resolvers/yup';
|
|
||||||
import { Autocomplete, Button, Card, Collapse, Container, Divider, Grid, Stack, Table, TableBody, TableCell, TableRow, TextField, Typography } from '@mui/material';
|
|
||||||
import { Controller, useForm } from 'react-hook-form';
|
|
||||||
import { useParams } from 'react-router-dom';
|
|
||||||
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
|
|
||||||
import { FormProvider, RHFCheckbox, RHFSelect, RHFTextField } from '../../components/hook-form';
|
|
||||||
import Page from '../../components/Page';
|
|
||||||
import useSettings from '../../hooks/useSettings';
|
|
||||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
||||||
import MemberSelectDialog from '../../components/dialogs/MemberSelectDialog';
|
|
||||||
import { styled } from '@mui/system';
|
|
||||||
import axios from '../../utils/axios';
|
|
||||||
import { enqueueSnackbar } from 'notistack';
|
|
||||||
import { LoadingButton } from '@mui/lab';
|
|
||||||
import { fCurrency } from '../../utils/formatNumber';
|
|
||||||
import Iconify from '../../components/Iconify';
|
|
||||||
import { ClaimRequest } from '@/@types/claims';
|
|
||||||
import FormEdit from './Components/FormEdit';
|
|
||||||
import FormCreate from './Components/FormCreate';
|
|
||||||
|
|
||||||
export default function ClaimsCreateUpdate() {
|
|
||||||
|
|
||||||
const { themeStretch } = useSettings();
|
|
||||||
const { id } = useParams();
|
|
||||||
|
|
||||||
const isEdit = id ? true : false;
|
|
||||||
|
|
||||||
const [currentClaim, setCurrentClaim] = useState<ClaimRequest>();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isEdit) {
|
|
||||||
axios.get('/claim-requests/' + id).then((res) => {
|
|
||||||
console.log('Yeet', res.data);
|
|
||||||
setCurrentClaim(res.data.data);
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(currentClaim)
|
|
||||||
}
|
|
||||||
}, [id]);
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Page title={isEdit ? `Edit Claim Request` : "Create New Claim"}>
|
|
||||||
<Container maxWidth={themeStretch ? false : 'xl'}>
|
|
||||||
{
|
|
||||||
id == undefined
|
|
||||||
?
|
|
||||||
(
|
|
||||||
<FormCreate />
|
|
||||||
)
|
|
||||||
:
|
|
||||||
(
|
|
||||||
<FormEdit isEdit={isEdit} currentClaim={currentClaim} />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
</Container>
|
|
||||||
</Page>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,306 +0,0 @@
|
|||||||
// mui
|
|
||||||
import { Container, Grid, Stack, Typography, Card, TextField, Divider, ButtonBase, Box, IconButton } from '@mui/material';
|
|
||||||
// components
|
|
||||||
import Page from '../../components/Page';
|
|
||||||
// utils
|
|
||||||
import useSettings from '../../hooks/useSettings';
|
|
||||||
// react
|
|
||||||
import { useNavigate, useParams, useLocation } from 'react-router-dom';
|
|
||||||
import { useEffect, useState, useRef } from 'react';
|
|
||||||
import axios from '../../utils/axios';
|
|
||||||
// pages
|
|
||||||
import DetailTimeline from '../../pages/ClaimRequests/DetailTimeline';
|
|
||||||
import DetailStepper from '../../pages/ClaimRequests/DetailStepper';
|
|
||||||
import { format } from 'date-fns';
|
|
||||||
import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos';
|
|
||||||
import Button from '@mui/material/Button';
|
|
||||||
import AddIcon from '@mui/icons-material/Add';
|
|
||||||
import RemoveIcon from '@mui/icons-material/Remove';
|
|
||||||
import { DatePicker, LocalizationProvider } from '@mui/x-date-pickers';
|
|
||||||
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
|
|
||||||
import Iconify from '@/components/Iconify';
|
|
||||||
import { fPostFormat } from '@/utils/formatTime';
|
|
||||||
import InsertDriveFileIcon from '@mui/icons-material/InsertDriveFile';
|
|
||||||
import DownloadIcon from '@mui/icons-material/Download';
|
|
||||||
import { Dialog, DialogTitle, DialogContent, DialogActions } from '@mui/material';
|
|
||||||
import CloseIcon from '@mui/icons-material/Close';
|
|
||||||
import { fDateTimesecond } from '@/utils/formatTime';
|
|
||||||
import { makeFormData } from '@/utils/jsonToFormData';
|
|
||||||
|
|
||||||
import { enqueueSnackbar } from 'notistack';
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
export default function Detail() {
|
|
||||||
const location = useLocation();
|
|
||||||
const queryParams = new URLSearchParams(location.search);
|
|
||||||
const code = queryParams.get('code');
|
|
||||||
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const { themeStretch } = useSettings();
|
|
||||||
const [data, setData] = useState();
|
|
||||||
const [dataDialog, setDataDialog] = useState();
|
|
||||||
const [document, setDocument] = useState(null);
|
|
||||||
|
|
||||||
const { id } = useParams();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
axios
|
|
||||||
.get('/claim-requests/detail/'+id)
|
|
||||||
.then((response) => {
|
|
||||||
setData(response.data);
|
|
||||||
setDataDialog(response.data.data.dialog_submits);
|
|
||||||
setDocument(response.data.data.documents);
|
|
||||||
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.error(error);
|
|
||||||
});
|
|
||||||
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const [isInvoiceVisible, setInvoiceVisibility] = useState(false);
|
|
||||||
|
|
||||||
const handleInvoice = () => {
|
|
||||||
setInvoiceVisibility(!isInvoiceVisible);
|
|
||||||
}
|
|
||||||
const currentDate = new Date();
|
|
||||||
const formattedCurrentDate = format(currentDate, 'dd MMM yyyy');
|
|
||||||
const [dateInvoice, setDateInvoice] = useState(currentDate);
|
|
||||||
|
|
||||||
const fileInvoiceInput = useRef<HTMLInputElement>(null);
|
|
||||||
const [fileInvoices, setFileInvoices] = useState([]);
|
|
||||||
|
|
||||||
const handleInvoiceInputChange = (event) => {
|
|
||||||
if (event.target.files[0]) {
|
|
||||||
setFileInvoices([...fileInvoices, ...event.target.files]);
|
|
||||||
} else {
|
|
||||||
console.log('NO FILE');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const removeInvoiceFiles = (filesState, index) => {
|
|
||||||
setFileInvoices(
|
|
||||||
filesState.filter((file, fileIndex) => {
|
|
||||||
return fileIndex != index;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
};
|
|
||||||
const date = dateInvoice ? fPostFormat(dateInvoice, 'yyyy-MM-dd') : null;
|
|
||||||
|
|
||||||
const [openDialogSubmit, setOpenDialogSubmit] = useState(false);
|
|
||||||
const handleCloseDialogSubmit = () => {
|
|
||||||
setOpenDialogSubmit(false);
|
|
||||||
}
|
|
||||||
const handleSubmitData = () => {
|
|
||||||
// if(fileInvoices.length > 0)
|
|
||||||
// {
|
|
||||||
//submit data
|
|
||||||
axios
|
|
||||||
.post('claim-requests/'+id+'/approve')
|
|
||||||
.then((response) => {
|
|
||||||
enqueueSnackbar('Success Submit Claim Request', { variant: 'success' });
|
|
||||||
setOpenDialogSubmit(false);
|
|
||||||
})
|
|
||||||
.catch(({ response }) => {
|
|
||||||
enqueueSnackbar(response.data.message ?? 'Something went wrong!', { variant: 'error' });
|
|
||||||
});
|
|
||||||
//Upload file invoices
|
|
||||||
const formData = makeFormData({
|
|
||||||
date:date,
|
|
||||||
invoice_files: fileInvoices,
|
|
||||||
});
|
|
||||||
axios
|
|
||||||
.post('claim-requests/'+id+'/invoice-files', formData)
|
|
||||||
.then((response) => {
|
|
||||||
enqueueSnackbar(response.data.message ?? 'Success upload invoice', { variant: 'success' });
|
|
||||||
})
|
|
||||||
.catch(({ response }) => {
|
|
||||||
enqueueSnackbar(response.data.message ?? 'Something Went Wrong', { variant: 'error' });
|
|
||||||
});
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// enqueueSnackbar('Please upload file invoice, before submit', { variant: 'warning' });
|
|
||||||
// }
|
|
||||||
|
|
||||||
setTimeout(() =>
|
|
||||||
{
|
|
||||||
window.location.reload();
|
|
||||||
}, 5000);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
const check_invoice = document?.find((dataInvoice) => dataInvoice.type === 'claim-invoice');
|
|
||||||
|
|
||||||
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}}>{(data && data.data) ? data.data.status.code : ''}</Typography>
|
|
||||||
{data ? (
|
|
||||||
<Stack direction="row" spacing={2} ml="auto">
|
|
||||||
<Typography variant="body2" sx={{color: '#757575'}}>Submission Date</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}>
|
|
||||||
<Stack direction="row" alignItems="center">
|
|
||||||
<Typography variant="subtitle1">Format Claim</Typography>
|
|
||||||
<Button variant="outlined" color="primary" startIcon={< DownloadIcon/>} sx={{marginLeft: 'auto'}}>
|
|
||||||
<Typography variant="button" display="block">Import</Typography>
|
|
||||||
</Button>
|
|
||||||
</Stack>
|
|
||||||
</Grid>
|
|
||||||
{check_invoice ? (
|
|
||||||
<Grid item xs={12} md={12}>
|
|
||||||
<Stack direction="row" alignItems="center">
|
|
||||||
<Typography variant="subtitle1">Request Claim</Typography>
|
|
||||||
<Button variant="outlined" color="primary" startIcon={ isInvoiceVisible ? < RemoveIcon/> : < AddIcon/>} sx={{marginLeft: 'auto'}} onClick={() => handleInvoice()}>
|
|
||||||
<Typography variant="button" display="block">Invoice</Typography>
|
|
||||||
</Button>
|
|
||||||
</Stack>
|
|
||||||
</Grid>
|
|
||||||
) : ''}
|
|
||||||
<Grid item xs={12} md={12} sx={{display : isInvoiceVisible ? '' : 'none',}}>
|
|
||||||
<Card sx={{padding: 2}}>
|
|
||||||
<Stack direction="column" spacing={2}>
|
|
||||||
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
|
||||||
<DatePicker
|
|
||||||
label="Invoice Date"
|
|
||||||
value={dateInvoice}
|
|
||||||
onChange={(newValue) => {
|
|
||||||
setDateInvoice(newValue);
|
|
||||||
}}
|
|
||||||
inputFormat="dd MMM yyyy"
|
|
||||||
renderInput={(params) => <TextField sx={{width:'40%'}} {...params} defaultValue={formattedCurrentDate} required/>}
|
|
||||||
/>
|
|
||||||
</LocalizationProvider>
|
|
||||||
<Stack
|
|
||||||
divider={<Divider orientation="horizontal" flexItem />}
|
|
||||||
spacing={1}
|
|
||||||
sx={{ marginY: 2 }}
|
|
||||||
>
|
|
||||||
{fileInvoices &&
|
|
||||||
fileInvoices.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={() => {
|
|
||||||
removeInvoiceFiles(fileInvoices, index);
|
|
||||||
}}
|
|
||||||
sx={{cursor: 'pointer'}}
|
|
||||||
></Iconify>
|
|
||||||
</Stack>
|
|
||||||
))}
|
|
||||||
</Stack>
|
|
||||||
<ButtonBase sx={{ p: 4, border: '2px dashed #F9FAFB',
|
|
||||||
bgcolor: '#919EAB52',
|
|
||||||
borderRadius: '8px',
|
|
||||||
width: '100%', height: '60px'}} onClick={() => fileInvoiceInput.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 Invoice
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
<input
|
|
||||||
type="file"
|
|
||||||
id="file"
|
|
||||||
ref={fileInvoiceInput}
|
|
||||||
style={{ display: 'none' }}
|
|
||||||
multiple
|
|
||||||
onChange={handleInvoiceInputChange}
|
|
||||||
accept="application/pdf"
|
|
||||||
/>
|
|
||||||
</ButtonBase>
|
|
||||||
</Stack>
|
|
||||||
</Card>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12} md={12}>
|
|
||||||
<DetailTimeline data={data}/>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12} md={12}>
|
|
||||||
<Stack direction="row" padding={4}>
|
|
||||||
{dataDialog && dataDialog.status === 'requested' ? (
|
|
||||||
<>
|
|
||||||
<Button variant="outlined" sx={{color: '#212B36', marginLeft: 'auto', borderColor: '#919EAB52'}} >Cancel</Button>
|
|
||||||
<Button sx={{backgroundColor: '#19BBBB', marginLeft: 1}} variant="contained" onClick={()=> setOpenDialogSubmit(true)}>Submit</Button>
|
|
||||||
</>
|
|
||||||
) : ''}
|
|
||||||
{/* Dialog Submits */}
|
|
||||||
<Dialog open={openDialogSubmit} onClose={handleCloseDialogSubmit} fullWidth={true}>
|
|
||||||
<DialogTitle sx={{ backgroundColor: '#19BBBB', color: '#FFF', padding: 2 }}>
|
|
||||||
<Stack direction="row" alignItems="center" justifyContent="space-between">
|
|
||||||
<Stack direction="row" alignItems='center' spacing={1}>
|
|
||||||
<Typography variant="h6">Confirmation</Typography>
|
|
||||||
</Stack>
|
|
||||||
<IconButton sx={{ color: '#FFF' }} onClick={handleCloseDialogSubmit}>
|
|
||||||
<CloseIcon />
|
|
||||||
</IconButton>
|
|
||||||
</Stack>
|
|
||||||
</DialogTitle>
|
|
||||||
<DialogContent>
|
|
||||||
{dataDialog ? (
|
|
||||||
<Stack spacing={2} padding={2}>
|
|
||||||
<Typography variant='body1'>Are you sure to submit this claim ?</Typography>
|
|
||||||
<Card sx={{padding:2}} >
|
|
||||||
<Stack direction='row' spacing={2}>
|
|
||||||
<Typography variant='subtitle2' sx={{color: '#919EAB', width: '30%'}}>Code</Typography>
|
|
||||||
<Typography variant='subtitle2' sx={{width: '70%'}}>{dataDialog.code}</Typography>
|
|
||||||
</Stack>
|
|
||||||
<Stack direction='row' spacing={2}>
|
|
||||||
<Typography variant='subtitle2' sx={{color: '#919EAB', width: '30%'}}>Name</Typography>
|
|
||||||
<Typography variant='subtitle2' sx={{width: '70%'}}>{dataDialog.name}</Typography>
|
|
||||||
</Stack>
|
|
||||||
<Stack direction='row' spacing={2}>
|
|
||||||
<Typography variant='subtitle2' sx={{color: '#919EAB', width: '30%'}}>Date Submission</Typography>
|
|
||||||
<Typography variant='subtitle2' sx={{width: '70%'}}>{fDateTimesecond(dataDialog.submission_date)}</Typography>
|
|
||||||
</Stack>
|
|
||||||
<Stack direction='row' spacing={2}>
|
|
||||||
<Typography variant='subtitle2' sx={{color: '#919EAB', width: '30%'}}>Claim Method</Typography>
|
|
||||||
<Typography variant='subtitle2' sx={{width: '70%'}}>Service Type</Typography>
|
|
||||||
</Stack>
|
|
||||||
<Stack direction='row' spacing={2}>
|
|
||||||
<Typography variant='subtitle2' sx={{color: '#919EAB', width: '30%'}}>Service Type</Typography>
|
|
||||||
<Typography variant='subtitle2' sx={{width: '70%'}}>
|
|
||||||
{dataDialog.service_code === 'IP' ? 'Inpatient' : 'Outpatient'}
|
|
||||||
</Typography>
|
|
||||||
</Stack>
|
|
||||||
</Card>
|
|
||||||
</Stack>
|
|
||||||
) : ''}
|
|
||||||
</DialogContent>
|
|
||||||
<DialogActions>
|
|
||||||
<Button variant="outlined" sx={{color: '#212B36', borderColor: '#919EAB52'}} onClick={handleCloseDialogSubmit}>Cancel</Button>
|
|
||||||
<Button sx={{backgroundColor: '#19BBBB'}} onClick={handleSubmitData} variant="contained">Submit</Button>
|
|
||||||
</DialogActions>
|
|
||||||
</Dialog>
|
|
||||||
</Stack>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
) : ''}
|
|
||||||
</Container>
|
|
||||||
</Page>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
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>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,426 +0,0 @@
|
|||||||
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 InsertDriveFileIcon from '@mui/icons-material/InsertDriveFile';
|
|
||||||
import DescriptionIcon from '@mui/icons-material/Description';
|
|
||||||
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';
|
|
||||||
|
|
||||||
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);
|
|
||||||
const [document, setDocument] = useState(null);
|
|
||||||
useEffect(() => {
|
|
||||||
if (data && data.data) {
|
|
||||||
setTimeline(data.data.timeline);
|
|
||||||
setRequestFile(data.data.request_files);
|
|
||||||
setDocument(data.data.documents);
|
|
||||||
}
|
|
||||||
|
|
||||||
}, [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" 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>
|
|
||||||
{dataTimeline.status === 'requested' ? (
|
|
||||||
<Card sx={{marginTop: 2 }}>
|
|
||||||
<Stack sx={{marginLeft: 2, marginRight: 2, marginTop: 2 }}>
|
|
||||||
<Stack direction="row" spacing={2} sx={{marginBottom: 2, paddingBottom: 2, borderBottom: '1px solid #919EAB52' }} alignItems="center">
|
|
||||||
<DescriptionIcon />
|
|
||||||
<Typography variant="Subtitle2" sx={{fontWeight: 'bold'}}>Documents</Typography>
|
|
||||||
</Stack>
|
|
||||||
<Stack direction="column" spacing={2} sx={{marginBottom: 2}}>
|
|
||||||
{document?.map((dataDocument, index) => (
|
|
||||||
<Stack direction="column" spacing={2} key={index}>
|
|
||||||
<Typography variant="Subtitle2" gutterBottom>
|
|
||||||
{dataDocument.type === 'claim-diagnosis' ?
|
|
||||||
'Diagnosis'
|
|
||||||
: dataDocument.type === 'claim-kondisi' ?
|
|
||||||
'Condition'
|
|
||||||
: dataDocument.type === 'claim-result' ?
|
|
||||||
'Supporting Result'
|
|
||||||
: dataDocument.type === 'claim-invoice' ?
|
|
||||||
'Invoice'
|
|
||||||
: ''}
|
|
||||||
</Typography>
|
|
||||||
<Stack direction="row" spacing={1} sx={{color: '#19BBBB'}}>
|
|
||||||
<InsertDriveFileIcon />
|
|
||||||
<a
|
|
||||||
href={dataDocument.path}
|
|
||||||
style={{ cursor: 'pointer', textDecoration: 'underline', color: '#19BBBB' }}
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
<Typography variant="body2" gutterBottom>{dataDocument.original_name ? dataDocument.original_name : '-'}</Typography>
|
|
||||||
</a>
|
|
||||||
</Stack>
|
|
||||||
</Stack>
|
|
||||||
))}
|
|
||||||
</Stack>
|
|
||||||
</Stack>
|
|
||||||
</Card>
|
|
||||||
) : ''}
|
|
||||||
</TimelineContent>
|
|
||||||
</TimelineItem>
|
|
||||||
</Timeline>
|
|
||||||
))}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -7,7 +7,7 @@ import List from "./List";
|
|||||||
|
|
||||||
export default function Claims() {
|
export default function Claims() {
|
||||||
|
|
||||||
const pageTitle = 'Claim Request';
|
const pageTitle = 'Inpatient Monitoring';
|
||||||
return (
|
return (
|
||||||
<Page title={ pageTitle } sx={{ mx: 2}}>
|
<Page title={ pageTitle } sx={{ mx: 2}}>
|
||||||
|
|
||||||
@@ -16,8 +16,8 @@ export default function Claims() {
|
|||||||
links={[
|
links={[
|
||||||
{ name: 'Dashboard', href: '/dashboard' },
|
{ name: 'Dashboard', href: '/dashboard' },
|
||||||
{
|
{
|
||||||
name: 'Claim Request',
|
name: 'Inpatient Monitoring',
|
||||||
href: '/claim-requests',
|
href: '/inpatient_monitoring',
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ import Label from '@/components/Label';
|
|||||||
import TableMoreMenu from '@/components/table/TableMoreMenu';
|
import TableMoreMenu from '@/components/table/TableMoreMenu';
|
||||||
import { Import } from '@/@types/claims';
|
import { Import } from '@/@types/claims';
|
||||||
|
|
||||||
import { FinalLogType } from './Model/Types';
|
import { FinalLogType } from '../../CustomerService/FinalLog/Model/Types';
|
||||||
// import LoadingButton from '@/theme/overrides/LoadingButton';
|
// import LoadingButton from '@/theme/overrides/LoadingButton';
|
||||||
|
|
||||||
export default function List() {
|
export default function List() {
|
||||||
@@ -344,7 +344,7 @@ export default function List() {
|
|||||||
{open ? <KeyboardArrowDownIcon /> : <KeyboardArrowRightIcon />}
|
{open ? <KeyboardArrowDownIcon /> : <KeyboardArrowRightIcon />}
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</TableCell> */ }
|
</TableCell> */ }
|
||||||
<TableCell align="left">
|
{/* <TableCell align="left">
|
||||||
<Typography
|
<Typography
|
||||||
// onClick={() => {
|
// onClick={() => {
|
||||||
// handleShowClaim(row);
|
// handleShowClaim(row);
|
||||||
@@ -352,9 +352,9 @@ export default function List() {
|
|||||||
>
|
>
|
||||||
{row.id}
|
{row.id}
|
||||||
</Typography>
|
</Typography>
|
||||||
</TableCell>
|
</TableCell> */}
|
||||||
<TableCell align="left">{row.code}</TableCell>
|
<TableCell align="left">{row.code}</TableCell>
|
||||||
<TableCell align="left">{row.member?.full_name}</TableCell>
|
<TableCell align="left">{row.member_name}</TableCell>
|
||||||
<TableCell align="left"><Label>{fDateTimesecond(row.submission_date)}</Label></TableCell>
|
<TableCell align="left"><Label>{fDateTimesecond(row.submission_date)}</Label></TableCell>
|
||||||
<TableCell align="left">{row.service_name}</TableCell>
|
<TableCell align="left">{row.service_name}</TableCell>
|
||||||
<TableCell align="left">{row.payment_type_name}</TableCell>
|
<TableCell align="left">{row.payment_type_name}</TableCell>
|
||||||
@@ -370,11 +370,11 @@ export default function List() {
|
|||||||
<TableCell align="right">
|
<TableCell align="right">
|
||||||
<TableMoreMenu actions={
|
<TableMoreMenu actions={
|
||||||
<>
|
<>
|
||||||
<MenuItem onClick={() => navigate(`/claim-requests/edit/${row.id}`)}>
|
{/* <MenuItem onClick={() => navigate(`/claim-requests/edit/${row.id}`)}>
|
||||||
<EditOutlinedIcon />
|
<EditOutlinedIcon />
|
||||||
Edit
|
Edit
|
||||||
</MenuItem>
|
</MenuItem> */}
|
||||||
<MenuItem onClick={() => navigate ('/claim-requests/detail/'+row.id+'')}>
|
<MenuItem onClick={() => navigate ('/custormer-service/final-log/detail/'+row.id+'')}>
|
||||||
<FindInPageOutlinedIcon />
|
<FindInPageOutlinedIcon />
|
||||||
Detail
|
Detail
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
@@ -476,9 +476,9 @@ export default function List() {
|
|||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
{/* <TableCell style={headStyle} align="left" /> */}
|
{/* <TableCell style={headStyle} align="left" /> */}
|
||||||
<TableCell style={headStyle} align="left">
|
{/* <TableCell style={headStyle} align="left">
|
||||||
ID Request LOG
|
ID Request LOG
|
||||||
</TableCell>
|
</TableCell> */}
|
||||||
<TableCell style={headStyle} align="left">
|
<TableCell style={headStyle} align="left">
|
||||||
Code
|
Code
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|||||||
@@ -1,79 +0,0 @@
|
|||||||
import axios from '@/utils/axios';
|
|
||||||
import { enqueueSnackbar } from 'notistack';
|
|
||||||
import { MemberListType } from './Types';
|
|
||||||
import { makeFormData } from '@/utils/jsonToFormData';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Listing Member
|
|
||||||
*/
|
|
||||||
export const getMemberList = async ( page: number, keyword: string ): Promise<MemberListType[]> => {
|
|
||||||
const response = await axios.get(`/claim-requests/list-member?page=${page}&keyword=${keyword}`)
|
|
||||||
.then((res) =>{
|
|
||||||
return res.data.data.member_list;
|
|
||||||
})
|
|
||||||
.catch((res) => {
|
|
||||||
enqueueSnackbar("server error !", {
|
|
||||||
variant: 'error',
|
|
||||||
});
|
|
||||||
|
|
||||||
return [];
|
|
||||||
});
|
|
||||||
|
|
||||||
return response;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add Claim Request
|
|
||||||
*/
|
|
||||||
export const addClaimRequest = async ( data: MemberListType[] ): Promise<boolean> => {
|
|
||||||
// Mapping
|
|
||||||
const formData = new FormData();
|
|
||||||
|
|
||||||
data.map((row, index) => {
|
|
||||||
formData.append(`member_id[${index}]`, row.id.toString());
|
|
||||||
formData.append(`service_code[${index}]`, row.patien_type??'');
|
|
||||||
|
|
||||||
if (row.file_kondisi != undefined) {
|
|
||||||
row.file_kondisi.forEach((file, file_index) => {
|
|
||||||
console.log(file);
|
|
||||||
|
|
||||||
formData.append(`file_kondisi[member_${row.id}][${file_index}]`, file);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (row.file_diagnosa != undefined) {
|
|
||||||
row.file_diagnosa.forEach((file, file_index) => {
|
|
||||||
console.log(file);
|
|
||||||
|
|
||||||
formData.append(`file_diagnosa[member_${row.id}][${file_index}]`, file);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (row.file_penunjang != undefined) {
|
|
||||||
row.file_penunjang.forEach((file, file_index) => {
|
|
||||||
console.log(file);
|
|
||||||
|
|
||||||
formData.append(`file_penunjang[member_${row.id}][${file_index}]`, file);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Axios
|
|
||||||
const response = await axios.post(`/claim-requests`, formData)
|
|
||||||
.then((res) =>{
|
|
||||||
enqueueSnackbar("Berhasil membuat data !", {
|
|
||||||
variant: 'success',
|
|
||||||
});
|
|
||||||
|
|
||||||
return true;
|
|
||||||
})
|
|
||||||
.catch((res) => {
|
|
||||||
enqueueSnackbar("server error !", {
|
|
||||||
variant: 'error',
|
|
||||||
});
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
return response;
|
|
||||||
};
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
import { Member } from "@/@types/member"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Search Type
|
|
||||||
*/
|
|
||||||
export type SearchType = {
|
|
||||||
keyword: string,
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Member List
|
|
||||||
*/
|
|
||||||
export type FinalLogType = {
|
|
||||||
id : number,
|
|
||||||
code : string,
|
|
||||||
member : Member,
|
|
||||||
submission_date : string,
|
|
||||||
service_name : string,
|
|
||||||
payment_type_name : string,
|
|
||||||
status_final_log : string,
|
|
||||||
status : string,
|
|
||||||
files_by_type : files_by_type,
|
|
||||||
}
|
|
||||||
|
|
||||||
export type files_by_type = {
|
|
||||||
claim_diagnosis : file[],
|
|
||||||
claim_kondisi : file[],
|
|
||||||
claim_result : file[],
|
|
||||||
}
|
|
||||||
|
|
||||||
export type file = {
|
|
||||||
name: string,
|
|
||||||
url: string[],
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,214 @@
|
|||||||
|
import { Card, Grid, MenuItem, Typography } from "@mui/material";
|
||||||
|
import { Stack } from '@mui/material';
|
||||||
|
import { BenefitData, DetailFinalLogType } from "../FinalLog/Model/Types";
|
||||||
|
import { useEffect, useState, useRef, useMemo } from 'react';
|
||||||
|
import { Box } from "@mui/material";
|
||||||
|
|
||||||
|
|
||||||
|
import { fDate, fDateTimesecond, toTitleCase } from "@/utils/formatTime";
|
||||||
|
import Label from '@/components/Label';
|
||||||
|
|
||||||
|
import AddIcon from '@mui/icons-material/Add';
|
||||||
|
import { Button } from "@mui/material";
|
||||||
|
import MoreMenu from "@/components/MoreMenu";
|
||||||
|
import { Delete, EditOutlined } from "@mui/icons-material";
|
||||||
|
import { fNumber } from "@/utils/formatNumber";
|
||||||
|
import palette from "@/theme/palette";
|
||||||
|
import DialogBenefit from "../FinalLog/Components/DialogBenefit";
|
||||||
|
import DialogEditBenefit from "../FinalLog/Components/DialogEditBenefit";
|
||||||
|
import DialogDelete from "../FinalLog/Components/DialogDelete";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
type CardDetail = {
|
||||||
|
requestLog: DetailFinalLogType|undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const style1 = {
|
||||||
|
color: '#919EAB',
|
||||||
|
width: '30%'
|
||||||
|
}
|
||||||
|
const style2 = {
|
||||||
|
width: '70%'
|
||||||
|
}
|
||||||
|
const marginBottom1 = {
|
||||||
|
marginBottom: 1,
|
||||||
|
}
|
||||||
|
const marginBottom2 = {
|
||||||
|
marginBottom: 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
const [openDialogBenefit, setDialogBenefit] = useState(false);
|
||||||
|
// Handle Edit Detail Benefit
|
||||||
|
const [openDialogEditBenefit, setDialogEditBenefit] = useState(false)
|
||||||
|
const [BenefitConfigurationData, setBenefitConfigurationData] = useState<BenefitData>();
|
||||||
|
|
||||||
|
// Handel Delete Detail Benefit
|
||||||
|
const [idBenefitData, setIdBenefitData] = useState<number>();
|
||||||
|
const [openDialogDeleteBenefit, setDialogDeleteBenefit] = useState(false)
|
||||||
|
|
||||||
|
|
||||||
|
export default function CardBenefit({requestLog} : CardDetail ) {
|
||||||
|
return (
|
||||||
|
<Card sx={{padding:2}} >
|
||||||
|
<Stack direction="row" alignItems="center" sx={{marginBottom: 4}}>
|
||||||
|
<Typography variant='subtitle1' sx={{color: '#19BBBB'}} gutterBottom>Benefit</Typography>
|
||||||
|
<Button variant="outlined" startIcon={<AddIcon/>} sx={{marginLeft: 'auto'}} onClick={() => {
|
||||||
|
setDialogBenefit(true);
|
||||||
|
}} >
|
||||||
|
<Typography variant="button" display="block">Benefit</Typography>
|
||||||
|
</Button>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
{requestLog?.benefit_data?.map((item, index) => (
|
||||||
|
<Box key={index} sx={{ border: '1px solid rgba(0,0,0,0.125)', px: '24px', py: '20px', marginBottom: '24px', borderRadius: '12px'}}>
|
||||||
|
<Grid container spacing={2}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Grid container spacing={2}>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<Typography variant="body2" sx={{ fontWeight: 'bold'}}>
|
||||||
|
{item.benefit?.description}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6} sx={{ display: 'flex', placeContent: 'end' }}>
|
||||||
|
<MoreMenu actions={
|
||||||
|
<>
|
||||||
|
<MenuItem onClick={() => {
|
||||||
|
setDialogEditBenefit(true)
|
||||||
|
setIdBenefitData(item.id)
|
||||||
|
setBenefitConfigurationData(item)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<EditOutlined />
|
||||||
|
Edit
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem onClick={() => {
|
||||||
|
setIdBenefitData(item.id)
|
||||||
|
setDialogDeleteBenefit(true)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Delete color='error'/>
|
||||||
|
Delete
|
||||||
|
</MenuItem>
|
||||||
|
</>
|
||||||
|
} />
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Box sx={{ py: '8px', px: '12px', background: palette.light.grey[50012], borderRadius: '6px'}}>
|
||||||
|
<Grid container spacing={1}>
|
||||||
|
|
||||||
|
{/* Amount Incurred */}
|
||||||
|
<Grid item xs={2}>
|
||||||
|
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="caption">
|
||||||
|
Amount Incurred
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="caption" sx={{ fontWeight: 'bold' }}>
|
||||||
|
{fNumber(item.amount_incurred)}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Amount Approved */}
|
||||||
|
<Grid item xs={2}>
|
||||||
|
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="caption">
|
||||||
|
Amount Approved
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="caption" sx={{ fontWeight: 'bold' }}>
|
||||||
|
{fNumber(item.amount_approved)}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Amount Not Approved */}
|
||||||
|
<Grid item xs={3}>
|
||||||
|
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="caption">
|
||||||
|
Amount Not Approved
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="caption" sx={{ fontWeight: 'bold' }}>
|
||||||
|
{fNumber(item.amount_not_approved)}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Excess Paid* */}
|
||||||
|
<Grid item xs={2}>
|
||||||
|
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="caption">
|
||||||
|
Excess Paid*
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="caption" sx={{ fontWeight: 'bold' }}>
|
||||||
|
{fNumber(item.excess_paid)}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Keterangan* */}
|
||||||
|
<Grid item xs={3}>
|
||||||
|
<Grid container>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="caption">
|
||||||
|
Keterangan*
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="caption" sx={{ fontWeight: 'bold' }}>
|
||||||
|
{item.keterangan}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</Box>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</Box>
|
||||||
|
))}
|
||||||
|
<DialogBenefit
|
||||||
|
requestLog={requestLog}
|
||||||
|
openDialog={openDialogBenefit}
|
||||||
|
setOpenDialog={setDialogBenefit}
|
||||||
|
|
||||||
|
/>
|
||||||
|
{/* Dialog Edit */}
|
||||||
|
<DialogEditBenefit
|
||||||
|
id={idBenefitData}
|
||||||
|
data={BenefitConfigurationData}
|
||||||
|
openDialog={openDialogEditBenefit}
|
||||||
|
setOpenDialog={setDialogEditBenefit}
|
||||||
|
>
|
||||||
|
|
||||||
|
</DialogEditBenefit>
|
||||||
|
{/* Dialog Delete */}
|
||||||
|
<DialogDelete
|
||||||
|
id={idBenefitData}
|
||||||
|
openDialog={openDialogDeleteBenefit}
|
||||||
|
setOpenDialog={setDialogDeleteBenefit}
|
||||||
|
/>
|
||||||
|
|
||||||
|
</Card>
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
import { Card, Typography } from "@mui/material";
|
||||||
|
import { Stack } from '@mui/material';
|
||||||
|
import { DetailFinalLogType } from "../FinalLog/Model/Types";
|
||||||
|
import { fDate, fDateTimesecond, toTitleCase } from "@/utils/formatTime";
|
||||||
|
|
||||||
|
|
||||||
|
type CardDetail = {
|
||||||
|
requestLog: DetailFinalLogType|undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const style1 = {
|
||||||
|
color: '#919EAB',
|
||||||
|
width: '30%'
|
||||||
|
}
|
||||||
|
const style2 = {
|
||||||
|
width: '70%'
|
||||||
|
}
|
||||||
|
const marginBottom1 = {
|
||||||
|
marginBottom: 1,
|
||||||
|
}
|
||||||
|
const marginBottom2 = {
|
||||||
|
marginBottom: 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default function CardFile({requestLog} : CardDetail ) {
|
||||||
|
return (
|
||||||
|
<Card sx={{padding:2}} >
|
||||||
|
<Stack direction="row" alignItems="center" sx={{marginBottom: 4}}>
|
||||||
|
<Stack direction="column" spacing={2} sx={{marginBottom: 2}}>
|
||||||
|
<Typography variant='subtitle1' sx={{color: '#19BBBB'}} gutterBottom>Files History</Typography>
|
||||||
|
{requestLog?.files?.map((documentType, index) => (
|
||||||
|
<Stack direction="column" spacing={2} key={index}>
|
||||||
|
<Stack direction="row" spacing={1} sx={{color: '#19BBBB'}}>
|
||||||
|
<a
|
||||||
|
href={documentType.url}
|
||||||
|
style={{ cursor: 'pointer', textDecoration: 'none', color: '#19BBBB' }}
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<Typography variant="body2" gutterBottom>{documentType.original_name ? documentType.original_name : '-'}</Typography>
|
||||||
|
</a>
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
))}
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
</Card>
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
import { Card, Grid, Typography } from "@mui/material";
|
||||||
|
import { Stack } from '@mui/material';
|
||||||
|
import { DetailFinalLogType } from "../FinalLog/Model/Types";
|
||||||
|
import { fDate, fDateTimesecond, toTitleCase } from "@/utils/formatTime";
|
||||||
|
import DialogMedicine from "../FinalLog/Components/DialogMedicine";
|
||||||
|
import { fNumber } from "@/utils/formatNumber";
|
||||||
|
import { Button } from '@mui/material';
|
||||||
|
import AddIcon from '@mui/icons-material/Add';
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
type CardDetail = {
|
||||||
|
requestLog: DetailFinalLogType|undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const style1 = {
|
||||||
|
color: '#919EAB',
|
||||||
|
width: '30%'
|
||||||
|
}
|
||||||
|
const style2 = {
|
||||||
|
width: '70%'
|
||||||
|
}
|
||||||
|
const marginBottom1 = {
|
||||||
|
marginBottom: 1,
|
||||||
|
}
|
||||||
|
const marginBottom2 = {
|
||||||
|
marginBottom: 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
const [openDialogMedicine, setDialogMedicine] = useState(false);
|
||||||
|
|
||||||
|
|
||||||
|
export default function CardMedicine({requestLog} : CardDetail ) {
|
||||||
|
return (
|
||||||
|
<Card sx={{padding:2}} >
|
||||||
|
<Stack direction="row" alignItems="center" sx={{marginBottom: 4}}>
|
||||||
|
<Typography variant='subtitle1' sx={{color: '#19BBBB'}} gutterBottom>Medicine</Typography>
|
||||||
|
<Button variant="outlined" startIcon={<AddIcon/>} sx={{marginLeft: 'auto'}} onClick={() => {
|
||||||
|
setDialogMedicine(true)
|
||||||
|
}} >
|
||||||
|
<Typography variant="button" display="block">Medicine</Typography>
|
||||||
|
</Button>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
{requestLog?.medicine.map((item, index) => (
|
||||||
|
<Grid
|
||||||
|
container
|
||||||
|
direction="row"
|
||||||
|
alignItems="center"
|
||||||
|
justifyContent="space-between" // Menempatkan item ke sebelah kiri dan kanan
|
||||||
|
sx={{ marginBottom: 2 }}
|
||||||
|
>
|
||||||
|
<Typography variant='subtitle1'>{item.medicine}</Typography>
|
||||||
|
<Typography variant="subtitle1">Rp. {fNumber(item.price)}</Typography>
|
||||||
|
</Grid>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{/* <DialogMedicine
|
||||||
|
requestLog={requestLog}
|
||||||
|
openDialog={openDialogMedicine}
|
||||||
|
setOpenDialog={setDialogMedicine}
|
||||||
|
/> */}
|
||||||
|
</Card>
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
import { Card, Grid, Typography } from "@mui/material";
|
|
||||||
import { Stack } from '@mui/material';
|
|
||||||
import { DetailFinalLogType } from "../FinalLog/Model/Types";
|
|
||||||
import { useEffect, useState, useRef, useMemo } from 'react';
|
|
||||||
import { Box } from "@mui/material";
|
|
||||||
|
|
||||||
|
|
||||||
import { fDate, fDateTimesecond, toTitleCase } from "@/utils/formatTime";
|
|
||||||
import Label from '@/components/Label';
|
|
||||||
|
|
||||||
import AddIcon from '@mui/icons-material/Add';
|
|
||||||
import { Button } from "@mui/material";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type CardDetail = {
|
|
||||||
requestLog: DetailFinalLogType|undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
const style1 = {
|
|
||||||
color: '#919EAB',
|
|
||||||
width: '30%'
|
|
||||||
}
|
|
||||||
const style2 = {
|
|
||||||
width: '70%'
|
|
||||||
}
|
|
||||||
const marginBottom1 = {
|
|
||||||
marginBottom: 1,
|
|
||||||
}
|
|
||||||
const marginBottom2 = {
|
|
||||||
marginBottom: 2,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default function DetailBenefit({requestLog} : CardDetail ) {
|
|
||||||
return (
|
|
||||||
{requestLog.benefitData?.map((item, index) => (
|
|
||||||
<Box sx={{ marginTop:'10px', marginBottom:'10px', py: '8px', px: '12px', border:'1px solid #919EAB52', borderRadius: '6px'}}>
|
|
||||||
<Grid container spacing={2}>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Typography variant="subtitle1" sx={{ fontWeight: 'bold'}}>
|
|
||||||
{item.description}
|
|
||||||
</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={2.5}>
|
|
||||||
<Grid container spacing={2}>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Typography variant="subtitle1" component="div">
|
|
||||||
Amount Incurred*
|
|
||||||
</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12} sx={{display: 'flex', gap: 1}}>
|
|
||||||
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<Grid item xs={2.5}>
|
|
||||||
<Grid container spacing={2}>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Typography variant="subtitle1" component="div">
|
|
||||||
Amount Approved*
|
|
||||||
</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12} sx={{display: 'flex', gap: 1}}>
|
|
||||||
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<Grid item xs={2.5}>
|
|
||||||
<Grid container spacing={2}>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Typography variant="subtitle1" component="div">
|
|
||||||
Amount Not Approved*
|
|
||||||
</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12} sx={{display: 'flex', gap: 1}}>
|
|
||||||
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<Grid item xs={2.5}>
|
|
||||||
<Grid container spacing={2}>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Typography variant="subtitle1" component="div">
|
|
||||||
Excess Paid*
|
|
||||||
</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12} sx={{display: 'flex', gap: 1}}>
|
|
||||||
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<Grid item xs={2}>
|
|
||||||
<Grid container spacing={2}>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Typography variant="subtitle1" component="div">
|
|
||||||
Keterangan*
|
|
||||||
</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12} sx={{display: 'flex', gap: 1}}>
|
|
||||||
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</Box>
|
|
||||||
))}
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -23,14 +23,15 @@ export default function DialogConfirmation({requestLog, setOpenDialog, openDialo
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const handleSubmit = () => {
|
const handleSubmit = () => {
|
||||||
const formData = {
|
const formData = {
|
||||||
status : approve
|
status : approve,
|
||||||
|
id: requestLog?.id
|
||||||
}
|
}
|
||||||
axios
|
axios
|
||||||
.put(`customer-service/request/${requestLog?.id}`, formData)
|
.post(`customer-service/request/final-log`, formData)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
enqueueSnackbar('Verification Request LOG Success', { variant: 'success' });
|
enqueueSnackbar('Verification Final LOG Success', { variant: 'success' });
|
||||||
setOpenDialog(false);
|
setOpenDialog(false);
|
||||||
navigate('/custormer-service/request')
|
navigate('/custormer-service/final-log')
|
||||||
})
|
})
|
||||||
.catch(({ response }) => {
|
.catch(({ response }) => {
|
||||||
enqueueSnackbar(response.data.message ?? 'Something went wrong!', { variant: 'error' });
|
enqueueSnackbar(response.data.message ?? 'Something went wrong!', { variant: 'error' });
|
||||||
@@ -54,7 +55,7 @@ export default function DialogConfirmation({requestLog, setOpenDialog, openDialo
|
|||||||
|
|
||||||
const getContent = () => (
|
const getContent = () => (
|
||||||
<Stack spacing={1} marginTop={2}>
|
<Stack spacing={1} marginTop={2}>
|
||||||
<Typography variant="subtitle2">Are you sure to {approve == 'approved' ? 'approve' : 'deciline'} this request ?</Typography>
|
<Typography variant="subtitle2">Are you sure to {approve == 'approved' ? 'approve' : 'deciline'} this final log ?</Typography>
|
||||||
<Grid item xs={12} md={12} marginTop={4}>
|
<Grid item xs={12} md={12} marginTop={4}>
|
||||||
<Card sx={{padding:2, marginTop:2}} >
|
<Card sx={{padding:2, marginTop:2}} >
|
||||||
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
|
|||||||
@@ -66,4 +66,55 @@ export default function DialogDelete({id, setOpenDialog, openDialog,onSubmit} :
|
|||||||
maxWidth="xs"
|
maxWidth="xs"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function DialogDeleteMedicine({id, setOpenDialog, openDialog,onSubmit} : DialogDeleteType ) {
|
||||||
|
const handleSubmit = () => {
|
||||||
|
axios
|
||||||
|
.delete(`customer-service/request/medicine-data/${id}`)
|
||||||
|
.then((response) => {
|
||||||
|
enqueueSnackbar('Benefit Data has Deleted', { variant: 'success' });
|
||||||
|
setOpenDialog(false);
|
||||||
|
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 delete this detail medicine ?</Typography>
|
||||||
|
<DialogActions>
|
||||||
|
<Button variant="outlined" sx={{color: '#212B36', borderColor: '#919EAB52'}} onClick={handleCloseDialog}>Cancel</Button>
|
||||||
|
<Button color="error" variant="contained" onClick={handleSubmit}>Delete</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MuiDialog
|
||||||
|
title={{name: "Delete Medicine"}}
|
||||||
|
openDialog={openDialog}
|
||||||
|
setOpenDialog={setOpenDialog}
|
||||||
|
content={getContent()}
|
||||||
|
maxWidth="xs"
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
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 { DetailFinalLogType } from "../Model/Types";
|
||||||
|
import { fDateTimesecond, toTitleCase } from "@/utils/formatTime";
|
||||||
|
import axios from "@/utils/axios";
|
||||||
|
import { enqueueSnackbar } from "notistack";
|
||||||
|
import { useNavigate } from "react-router";
|
||||||
|
|
||||||
|
|
||||||
|
type DialogDeleteType = {
|
||||||
|
openDialog: boolean;
|
||||||
|
setOpenDialog: any;
|
||||||
|
onSubmit?: void;
|
||||||
|
id: number|undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function DialogDeleteMedicine({id, setOpenDialog, openDialog,onSubmit} : DialogDeleteType ) {
|
||||||
|
const handleSubmit = () => {
|
||||||
|
axios
|
||||||
|
.delete(`customer-service/request/medicine-data/${id}`)
|
||||||
|
.then((response) => {
|
||||||
|
enqueueSnackbar('Benefit Data has Deleted', { variant: 'success' });
|
||||||
|
setOpenDialog(false);
|
||||||
|
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 delete this detail medicine ?</Typography>
|
||||||
|
<DialogActions>
|
||||||
|
<Button variant="outlined" sx={{color: '#212B36', borderColor: '#919EAB52'}} onClick={handleCloseDialog}>Cancel</Button>
|
||||||
|
<Button color="error" variant="contained" onClick={handleSubmit}>Delete</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MuiDialog
|
||||||
|
title={{name: "Delete Medicine"}}
|
||||||
|
openDialog={openDialog}
|
||||||
|
setOpenDialog={setOpenDialog}
|
||||||
|
content={getContent()}
|
||||||
|
maxWidth="xs"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -24,7 +24,7 @@ type DialogDeleteType = {
|
|||||||
setOpenDialog: any;
|
setOpenDialog: any;
|
||||||
onSubmit?: void;
|
onSubmit?: void;
|
||||||
data: BenefitConfigurationListType|undefined;
|
data: BenefitConfigurationListType|undefined;
|
||||||
id: number;
|
id: number|undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function DialogEditBenefit({id, data, setOpenDialog, openDialog,onSubmit} : DialogDeleteType ) {
|
export default function DialogEditBenefit({id, data, setOpenDialog, openDialog,onSubmit} : DialogDeleteType ) {
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
|
import * as Yup from 'yup';
|
||||||
|
import { yupResolver } from '@hookform/resolvers/yup';
|
||||||
|
|
||||||
import MuiDialog from "@/components/MuiDialog";
|
import MuiDialog from "@/components/MuiDialog";
|
||||||
import { Button, Autocomplete, Card, Checkbox, DialogActions, Grid, Typography } from "@mui/material";
|
import { Button, Autocomplete, Card, Checkbox, DialogActions, Grid, Typography } from "@mui/material";
|
||||||
import { Paper } from "@mui/material";
|
import { Paper } from "@mui/material";
|
||||||
import { Stack } from '@mui/material';
|
import { Stack } from '@mui/material';
|
||||||
import React, { useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { DetailFinalLogType } from "../Model/Types";
|
import { DetailFinalLogType } from "../Model/Types";
|
||||||
|
import { MedicineType } from "../Model/Types";
|
||||||
import { fDateTimesecond, toTitleCase } from "@/utils/formatTime";
|
import { fDateTimesecond, toTitleCase } from "@/utils/formatTime";
|
||||||
import { useFieldArray, useForm } from 'react-hook-form';
|
import { useFieldArray, useForm } from 'react-hook-form';
|
||||||
import { FormProvider, RHFDatepicker, RHFSelect, RHFTextField } from '@/components/hook-form';
|
import { FormProvider, RHFDatepicker, RHFSelect, RHFTextField } from '@/components/hook-form';
|
||||||
@@ -13,8 +17,10 @@ import { enqueueSnackbar } from "notistack";
|
|||||||
import { useNavigate } from "react-router";
|
import { useNavigate } from "react-router";
|
||||||
import { LoadingButton } from '@mui/lab';
|
import { LoadingButton } from '@mui/lab';
|
||||||
import AddIcon from '@mui/icons-material/Add';
|
import AddIcon from '@mui/icons-material/Add';
|
||||||
|
import RemoveIcon from '@mui/icons-material/Remove';
|
||||||
import RHFTextFieldMoney from "@/components/hook-form/v2/RHFTextFieldMoney";
|
import RHFTextFieldMoney from "@/components/hook-form/v2/RHFTextFieldMoney";
|
||||||
|
import { IconButton } from '@mui/material';
|
||||||
|
import { postAddMedince } from '../Model/Functions';
|
||||||
|
|
||||||
type DialogConfirmationType = {
|
type DialogConfirmationType = {
|
||||||
openDialog: boolean;
|
openDialog: boolean;
|
||||||
@@ -23,128 +29,133 @@ type DialogConfirmationType = {
|
|||||||
requestLog: DetailFinalLogType|undefined;
|
requestLog: DetailFinalLogType|undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function DialogHMedicine({requestLog, setOpenDialog, openDialog } : DialogConfirmationType ) {
|
export default function DialogMedicine({requestLog, setOpenDialog, openDialog } : DialogConfirmationType ) {
|
||||||
|
|
||||||
interface FormValuesProps extends Partial<DetailFinalLogType> {
|
|
||||||
taxes: boolean;
|
|
||||||
inStock: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
const onSubmit = async (data: DetailFinalLogType) => {
|
|
||||||
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleCloseDialogMedicine = () => {
|
const handleCloseDialogMedicine = () => {
|
||||||
setOpenDialog(false)
|
setOpenDialog(false);
|
||||||
setMedicines([])
|
|
||||||
}
|
}
|
||||||
const [medicines, setMedicines] = useState([]);
|
|
||||||
|
|
||||||
const addMedicine = () => {
|
const requestID = requestLog?.id
|
||||||
setMedicines((prevMedicines) => [...prevMedicines, { medicine: '', price: '' }]);
|
|
||||||
|
const defaultValues: MedicineType = {
|
||||||
|
medicine : [{
|
||||||
|
id: 0,
|
||||||
|
medicine_name: '',
|
||||||
|
medicine_price: 0,
|
||||||
|
request_log_id: requestID,
|
||||||
|
medicine: '', // input to database
|
||||||
|
price: 0, // input to database
|
||||||
|
}],
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDelete = (index) => {
|
const validationSchema = Yup.object().shape({
|
||||||
// Update the medicines state to remove the medicine at the given index
|
medicine: Yup.array().of(
|
||||||
setMedicines((prevMeds) => prevMeds.filter((med, medIndex) => medIndex !== index));
|
Yup.object().shape({
|
||||||
};
|
medicine_name : Yup.string().typeError('').required(''),
|
||||||
|
medicine_price : Yup.number().typeError('').required(''),
|
||||||
|
request_log_id : Yup.number().typeError('').required(''),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
const removeMedicene = (i:number) => {
|
const methods = useForm<any>({
|
||||||
const index = medicines.indexOf(i);
|
resolver: yupResolver(validationSchema),
|
||||||
if (index > -1) { // only splice array when item is found
|
defaultValues
|
||||||
medicines.splice(index, 1); // 2nd parameter means remove one item only
|
});
|
||||||
|
|
||||||
|
const {fields, append, remove} = useFieldArray({name: 'medicine',control: methods.control})
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let temp = fields.map((item, i) => {
|
||||||
|
return {
|
||||||
|
medicine_name: 'test',
|
||||||
|
medicine_price: 0,
|
||||||
|
request_log_id: 3,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
reset({medicine: temp})
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const { handleSubmit, reset, watch, setValue, formState: { isDirty, isSubmitting, errors } } = methods;
|
||||||
|
// Submit Form
|
||||||
|
// =====================================
|
||||||
|
const submitHandler = async (data: MedicineType) => {
|
||||||
|
const response = await postAddMedince(data);
|
||||||
|
|
||||||
|
if (response == true) {
|
||||||
|
reset();
|
||||||
|
// navigate('custormer-service/final-log/detail/'+requestLog?.id);
|
||||||
|
window.location.reload()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const methods = useForm<DetailFinalLogType>();
|
|
||||||
const {
|
|
||||||
reset,
|
|
||||||
watch,
|
|
||||||
control,
|
|
||||||
setValue,
|
|
||||||
getValues,
|
|
||||||
setError,
|
|
||||||
handleSubmit,
|
|
||||||
resetField,
|
|
||||||
formState: { isSubmitting },
|
|
||||||
} = methods;
|
|
||||||
|
|
||||||
const {fields, append, remove} = useFieldArray<FormValuesProps>({name: "secondary_diagnosis_id", control})
|
|
||||||
|
|
||||||
const getContent = () => (
|
const getContent = () => (
|
||||||
<FormProvider methods={methods} onSubmit={handleSubmit(onSubmit)}>
|
<FormProvider methods={methods} onSubmit={handleSubmit(submitHandler)}>
|
||||||
<Stack spacing={2} sx={{marginTop: 2, padding: 2}}>
|
<Stack spacing={2} sx={{marginTop: 2, padding: 2}}>
|
||||||
<Grid container spacing={2}>
|
<Grid container spacing={2}>
|
||||||
{/* Medicine */}
|
{/* Medicine */}
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Stack direction="row" alignItems="center" sx={{marginBottom: 4}}>
|
<Stack direction="row" alignItems="center" sx={{marginBottom: 4}}>
|
||||||
<Typography variant='subtitle1' gutterBottom>Medicine*</Typography>
|
<Typography variant='subtitle1' gutterBottom>Medicine*</Typography>
|
||||||
<Button color="inherit" variant="outlined" startIcon={<AddIcon/>} sx={{marginLeft: 'auto'}} onClick={addMedicine}>
|
<Button color="inherit" variant="outlined" startIcon={<AddIcon/>} sx={{marginLeft: 'auto'}} onClick={() => append({medicine_name: '', medicine_price: 0, request_log_id: requestLog?.id })}>
|
||||||
<Typography variant="button" display="block">Medicine</Typography>
|
<Typography variant="button" display="block">Medicine</Typography>
|
||||||
</Button>
|
</Button>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
{/* Listing */}
|
{fields.map((field, index) => (
|
||||||
<Grid item xs={6}>
|
<React.Fragment key={index}>
|
||||||
<RHFTextField
|
|
||||||
name={`medicine[0].name`}
|
|
||||||
label="Medicine"
|
|
||||||
required
|
|
||||||
placeholder="Medicine"
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={6}>
|
|
||||||
<RHFTextFieldMoney
|
|
||||||
name={`medicine[0].price`}
|
|
||||||
label="Price"
|
|
||||||
required
|
|
||||||
placeholder="Price"
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
{medicines.map((medicine, index) => (
|
|
||||||
<React.Fragment key={index+1}>
|
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<RHFTextField
|
<RHFTextField
|
||||||
name={`medicine[${index+1}].name`}
|
id='medicine_name'
|
||||||
|
key={field.id}
|
||||||
|
name={`medicine.${index}.medicine_name`}
|
||||||
label="Medicine"
|
label="Medicine"
|
||||||
required
|
required
|
||||||
placeholder="Medicine"
|
placeholder="Medicine"
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6}>
|
<Grid item xs={5}>
|
||||||
<RHFTextFieldMoney
|
<RHFTextFieldMoney
|
||||||
name={`medicine[${index+1}].price`}
|
id='medicine_price'
|
||||||
|
key={field.id}
|
||||||
|
name={`medicine.${index}.medicine_price`}
|
||||||
label="Price"
|
label="Price"
|
||||||
required
|
required
|
||||||
placeholder="Price"
|
placeholder="Price"
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
{/* <Grid item xs={1}>
|
{
|
||||||
<Button variant="contained" color="error" onClick={() => handleDelete(index)}>
|
index != (fields.length-1) ?
|
||||||
Delete
|
(
|
||||||
</Button>
|
<Grid item xs={1} sx={{ textAlign: 'center' }}>
|
||||||
</Grid> */}
|
<IconButton size='large' color='error' onClick={() => remove(index)}>
|
||||||
|
<RemoveIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Grid>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
<DialogActions>
|
||||||
|
<Stack direction="row" alignItems="center" justifyContent="space-between" spacing={2}>
|
||||||
|
<Button color="inherit" variant="outlined" onClick={handleCloseDialogMedicine}><Typography>Cancel</Typography></Button>
|
||||||
|
<LoadingButton disabled={!isDirty} type="submit" variant="contained" loading={isSubmitting}>
|
||||||
|
Add
|
||||||
|
</LoadingButton>
|
||||||
|
</Stack>
|
||||||
|
</DialogActions>
|
||||||
|
|
||||||
</FormProvider>
|
</FormProvider>
|
||||||
);
|
);
|
||||||
|
|
||||||
const getAction = () => (
|
const getAction = () => null;
|
||||||
<Stack direction="row" alignItems="center" justifyContent="space-between" spacing={2}>
|
|
||||||
<Button color="inherit" variant="outlined" onClick={handleCloseDialogMedicine}><Typography>Cancel</Typography></Button>
|
|
||||||
<Button variant="contained"><Typography>Add</Typography></Button>
|
|
||||||
</Stack>
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
Collapse,
|
Collapse,
|
||||||
AccordionSummary,
|
AccordionSummary,
|
||||||
AccordionDetails,
|
AccordionDetails,
|
||||||
|
IconButton,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
// components
|
// components
|
||||||
import Page from '../../../components/Page';
|
import Page from '../../../components/Page';
|
||||||
@@ -37,19 +38,22 @@ import AddIcon from '@mui/icons-material/Add';
|
|||||||
import CardDetail from '../Components/CardDetail';
|
import CardDetail from '../Components/CardDetail';
|
||||||
import CardService from '../Components/CardService';
|
import CardService from '../Components/CardService';
|
||||||
import CardExclusion from '../Components/CardExclusion';
|
import CardExclusion from '../Components/CardExclusion';
|
||||||
|
import CardBenefit from '../Components/CardBenefit';
|
||||||
|
|
||||||
// Import Dialog
|
// Import Dialog
|
||||||
import DialogHospitalCare from './Components/DialogHospitalCare';
|
import DialogHospitalCare from './Components/DialogHospitalCare';
|
||||||
import DialogBenefit from './Components/DialogBenefit';
|
import DialogBenefit from './Components/DialogBenefit';
|
||||||
import DialogMedicine from './Components/DialogMedicine';
|
import DialogMedicine from './Components/DialogMedicine';
|
||||||
import DetailBenefit from '../Components/DetailBenefit';
|
import DialogDelete from './Components/DialogDelete';
|
||||||
import DialogEditBenefit from './Components/DialogEditBenefit';
|
import DialogEditBenefit from './Components/DialogEditBenefit';
|
||||||
|
import { DialogDeleteMedicine } from './Components/DialogDelete';
|
||||||
|
|
||||||
import MoreMenu from '@/components/MoreMenu';
|
import MoreMenu from '@/components/MoreMenu';
|
||||||
import { MenuItem } from '@mui/material';
|
import { MenuItem } from '@mui/material';
|
||||||
import { fNumber } from '@/utils/formatNumber';
|
import { fNumber } from '@/utils/formatNumber';
|
||||||
import palette from '@/theme/palette';
|
import palette from '@/theme/palette';
|
||||||
import DialogDelete from './Components/DialogDelete';
|
import CardMedicine from '../Components/CardMedicine';
|
||||||
|
import CardFile from '../Components/CardFile';
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
@@ -299,7 +303,13 @@ export default function Detail() {
|
|||||||
|
|
||||||
|
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
|
{/* PR Buat pindahin ke componen */}
|
||||||
|
{/* <CardBenefit
|
||||||
|
requestLog={requestLog}
|
||||||
|
>
|
||||||
|
|
||||||
|
</CardBenefit> */}
|
||||||
|
|
||||||
<DialogBenefit
|
<DialogBenefit
|
||||||
requestLog={requestLog}
|
requestLog={requestLog}
|
||||||
@@ -335,37 +345,45 @@ export default function Detail() {
|
|||||||
<Typography variant="button" display="block">Medicine</Typography>
|
<Typography variant="button" display="block">Medicine</Typography>
|
||||||
</Button>
|
</Button>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Card>
|
|
||||||
<DialogMedicine
|
|
||||||
requestLog={requestLog}
|
|
||||||
openDialog={openDialogMedicine}
|
|
||||||
setOpenDialog={setDialogMedicine}
|
|
||||||
/>
|
|
||||||
|
|
||||||
|
{requestLog?.medicine.map((item, index) => (
|
||||||
|
<Grid
|
||||||
|
container
|
||||||
|
direction="row"
|
||||||
|
alignItems="center"
|
||||||
|
justifyContent="space-between" // Menempatkan item ke sebelah kiri dan kanan
|
||||||
|
sx={{ marginBottom: 2 }}
|
||||||
|
>
|
||||||
|
<Typography variant='subtitle1'>{item.medicine}</Typography>
|
||||||
|
<Typography variant="subtitle1">Rp. {fNumber(item.price)}
|
||||||
|
<IconButton size='large' color='error' onClick={() => {
|
||||||
|
setIdBenefitData(item.id)
|
||||||
|
setDialogDeleteBenefit(true)
|
||||||
|
}}>
|
||||||
|
<Delete color='error'/>
|
||||||
|
</IconButton>
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
))}
|
||||||
|
|
||||||
|
<DialogMedicine
|
||||||
|
requestLog={requestLog}
|
||||||
|
openDialog={openDialogMedicine}
|
||||||
|
setOpenDialog={setDialogMedicine}
|
||||||
|
/>
|
||||||
|
<DialogDeleteMedicine
|
||||||
|
id={idBenefitData}
|
||||||
|
openDialog={openDialogDeleteBenefit}
|
||||||
|
setOpenDialog={setDialogDeleteBenefit}
|
||||||
|
/>
|
||||||
|
</Card>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
{/* File */}
|
{/* File */}
|
||||||
<Grid item xs={12} md={12}>
|
<Grid item xs={12} md={12}>
|
||||||
<Card sx={{padding:2}} >
|
<CardFile
|
||||||
<Stack direction="row" alignItems="center" sx={{marginBottom: 4}}>
|
requestLog={requestLog}
|
||||||
<Stack direction="column" spacing={2} sx={{marginBottom: 2}}>
|
/>
|
||||||
<Typography variant='subtitle1' sx={{color: '#19BBBB'}} gutterBottom>Files History</Typography>
|
|
||||||
{requestLog?.files?.map((documentType, index) => (
|
|
||||||
<Stack direction="column" spacing={2} key={index}>
|
|
||||||
<Stack direction="row" spacing={1} sx={{color: '#19BBBB'}}>
|
|
||||||
<a
|
|
||||||
href={documentType.url}
|
|
||||||
style={{ cursor: 'pointer', textDecoration: 'none', color: '#19BBBB' }}
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
<Typography variant="body2" gutterBottom>{documentType.original_name ? documentType.original_name : '-'}</Typography>
|
|
||||||
</a>
|
|
||||||
</Stack>
|
|
||||||
</Stack>
|
|
||||||
))}
|
|
||||||
</Stack>
|
|
||||||
</Stack>
|
|
||||||
</Card>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
{requestLog?.status_final_log == 'requested' ? (
|
{requestLog?.status_final_log == 'requested' ? (
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import axios from '@/utils/axios';
|
import axios from '@/utils/axios';
|
||||||
import { enqueueSnackbar } from 'notistack';
|
import { enqueueSnackbar } from 'notistack';
|
||||||
import { MemberListType } from './Types';
|
import { MedicineType, MemberListType } from './Types';
|
||||||
import { BenefitConfigurationListType } from './Types';
|
import { BenefitConfigurationListType } from './Types';
|
||||||
import { makeFormData } from '@/utils/jsonToFormData';
|
import { makeFormData } from '@/utils/jsonToFormData';
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ export const postAddBenefit = async (data: BenefitConfigurationListType):Promise
|
|||||||
/**
|
/**
|
||||||
* Edit Benefit
|
* Edit Benefit
|
||||||
*/
|
*/
|
||||||
export const postEditBenefit = async (id:number, data: BenefitConfigurationListType):Promise<boolean> => {
|
export const postEditBenefit = async (id:number|undefined, data: BenefitConfigurationListType):Promise<boolean> => {
|
||||||
const response = await axios.put(`customer-service/request/benefit_data/${id}`, {
|
const response = await axios.put(`customer-service/request/benefit_data/${id}`, {
|
||||||
...data
|
...data
|
||||||
})
|
})
|
||||||
@@ -151,3 +151,40 @@ export const postEditBenefit = async (id:number, data: BenefitConfigurationListT
|
|||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Medicine
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const postAddMedince = async (data: MedicineType):Promise<boolean> => {
|
||||||
|
const response = await axios.post(`customer-service/request/medicine-data`, {
|
||||||
|
...data
|
||||||
|
})
|
||||||
|
.then((res) =>{
|
||||||
|
enqueueSnackbar(res.data.message, {
|
||||||
|
variant: 'success',
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.catch((res) => {
|
||||||
|
if (res.response.status == 400) {
|
||||||
|
let arr_message = res.response.data.message;
|
||||||
|
|
||||||
|
// for (const key in arr_message) {
|
||||||
|
enqueueSnackbar(arr_message, {
|
||||||
|
variant: 'warning',
|
||||||
|
});
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
enqueueSnackbar("server error !", {
|
||||||
|
variant: 'error',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ export type FinalLogType = {
|
|||||||
id : number,
|
id : number,
|
||||||
code : string,
|
code : string,
|
||||||
member : Member,
|
member : Member,
|
||||||
|
member_name : string,
|
||||||
submission_date : string,
|
submission_date : string,
|
||||||
service_name : string,
|
service_name : string,
|
||||||
payment_type_name : string,
|
payment_type_name : string,
|
||||||
@@ -41,6 +42,7 @@ export type DetailFinalLogType = {
|
|||||||
benefit_data : BenefitData[],
|
benefit_data : BenefitData[],
|
||||||
config_service : ConfigService,
|
config_service : ConfigService,
|
||||||
exclusion : Exclusion[],
|
exclusion : Exclusion[],
|
||||||
|
medicine : Medicine[],
|
||||||
files : file[],
|
files : file[],
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,9 +53,26 @@ export type BenefitData = {
|
|||||||
excess_paid : number,
|
excess_paid : number,
|
||||||
keterangan : string,
|
keterangan : string,
|
||||||
benefit : Benefit,
|
benefit : Benefit,
|
||||||
|
request_log_id : number,
|
||||||
|
benefit_name : string,
|
||||||
|
description : string,
|
||||||
id : number,
|
id : number,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type BenefitConfigurationListType = {
|
||||||
|
request_log_id: number|undefined,
|
||||||
|
benefit_name: string,
|
||||||
|
benefit: {
|
||||||
|
description: string
|
||||||
|
},
|
||||||
|
amount_incurred: number,
|
||||||
|
amount_approved: number,
|
||||||
|
amount_not_approved: number,
|
||||||
|
excess_paid: number,
|
||||||
|
keterangan: string,
|
||||||
|
description: string,
|
||||||
|
}
|
||||||
|
|
||||||
export type Benefit = {
|
export type Benefit = {
|
||||||
id: number,
|
id: number,
|
||||||
code: string,
|
code: string,
|
||||||
@@ -104,15 +123,17 @@ export type Rule = {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type MedicineType = {
|
||||||
export type BenefitConfigurationListType = {
|
medicine: Medicine[],
|
||||||
request_log_id: number|undefined,
|
|
||||||
benefit_name: string,
|
|
||||||
amount_incurred: number,
|
|
||||||
amount_approved: number,
|
|
||||||
amount_not_approved: number,
|
|
||||||
excess_paid: number,
|
|
||||||
keterangan: string,
|
|
||||||
description: string,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type Medicine = {
|
||||||
|
id: number,
|
||||||
|
medicine_name: string,
|
||||||
|
medicine_price: number,
|
||||||
|
medicine: string,
|
||||||
|
price: number,
|
||||||
|
request_log_id: number|undefined,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -123,8 +123,8 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<div class="text-sm text-gray">Date of Admission</div>
|
<div class="text-sm text-gray">Date of Admission</div>
|
||||||
@if (isset($claimRequest))
|
@if (isset($requestLog))
|
||||||
<div class="text-md">{{ !empty($claimRequest->submission_date) ? \Carbon\Carbon::parse($claimRequest->submission_date)->format('d/m/Y') : now()->format('d/m/Y') }}</div>
|
<div class="text-md">{{ !empty($requestLog->submission_date) ? \Carbon\Carbon::parse($requestLog->submission_date)->format('d/m/Y') : now()->format('d/m/Y') }}</div>
|
||||||
@else
|
@else
|
||||||
<div class="text-md">{{ $dateOfAdmission->format('d/m/Y') }}</div>
|
<div class="text-md">{{ $dateOfAdmission->format('d/m/Y') }}</div>
|
||||||
@endif
|
@endif
|
||||||
@@ -140,7 +140,7 @@
|
|||||||
<table id="benefit-table">
|
<table id="benefit-table">
|
||||||
<tr>
|
<tr>
|
||||||
<th class="text-lg" style="font-weight: 600">Detail Benefit</th>
|
<th class="text-lg" style="font-weight: 600">Detail Benefit</th>
|
||||||
<th class="text-lg" style="font-weight: 600">Limit</th>
|
<!-- <th class="text-lg" style="font-weight: 600">Limit</th> -->
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
@@ -148,18 +148,34 @@
|
|||||||
<td class="text-lg">Medical Check Up</td>
|
<td class="text-lg">Medical Check Up</td>
|
||||||
<td class="text-lg">As Charged</td>
|
<td class="text-lg">As Charged</td>
|
||||||
</tr> --}}
|
</tr> --}}
|
||||||
|
@if ($member->currentPlan)
|
||||||
|
@foreach ($member->currentPlan->corporateBenefits as $corporateBenefit)
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>{{ @$corporateBenefit->benefit->description ?? '' }}</td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
@endif
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
@foreach ($member->currentPlan->corporateBenefits as $corporateBenefit)
|
<div class="benefit-table-wrapper" style="margin-top: 20px; width: 100%;">
|
||||||
|
<table id="benefit-table">
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ @$corporateBenefit->benefit->description ?? '' }}</td>
|
<th class="text-lg" style="font-weight: 600">Term on Condition</th>
|
||||||
@if($corporateBenefit->limit_amount == 999999999)
|
<!-- <th class="text-lg" style="font-weight: 600">Limit</th> -->
|
||||||
<td style="align-right">As Charged</td>
|
</tr>
|
||||||
@else
|
|
||||||
<td style="align-right">IDR {{ number_format($corporateBenefit->limit_amount, 0, ',', '.') ?? '' }}</td>
|
@if ($member->currentPlan)
|
||||||
@endif
|
@foreach ($member->currentPlan->corporateBenefits as $corporateBenefit)
|
||||||
</tr>
|
|
||||||
@endforeach
|
<tr>
|
||||||
|
<td>{{ @$corporateBenefit->benefit->description ?? '' }}</td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
@endif
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user