Update customer service
This commit is contained in:
@@ -35,12 +35,15 @@ class DailyMonitoringController extends Controller
|
||||
*/
|
||||
public function GetMemberList()
|
||||
{
|
||||
$memberList = DB::table('claims')
|
||||
->leftJoin('members', 'claims.member_id', '=', 'members.id')
|
||||
->leftJoin('member_plans', 'members.id', '=', 'member_plans.id')
|
||||
->select('members.member_id','members.name','member_plans.start AS startdate','member_plans.end AS enddate')
|
||||
->groupBy('claims.member_id')
|
||||
->orderBy('claims.created_at', 'desc')
|
||||
$memberList = DB::table('request_logs')
|
||||
->leftJoin('members', 'request_logs.member_id', '=', 'members.id')
|
||||
->leftJoin('member_plans', 'request_logs.member_id', '=', 'member_plans.member_id')
|
||||
->leftJoin('organizations', 'organizations.id', '=', 'request_logs.organization_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' )
|
||||
->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();
|
||||
|
||||
return response()->json([
|
||||
@@ -62,15 +65,14 @@ class DailyMonitoringController extends Controller
|
||||
->where('member_id', $member_id)
|
||||
->first();
|
||||
|
||||
$claimList = DB::table('claims')
|
||||
->leftJoin('claim_requests', 'claims.claim_request_id', '=', 'claim_requests.id')
|
||||
->leftJoin('claim_history_cares', 'claims.id', '=', 'claim_history_cares.claim_id')
|
||||
->leftJoin('services', 'claim_requests.service_code', '=', 'services.code')
|
||||
->leftJoin('members', 'claims.member_id', '=', 'members.id')
|
||||
->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("claims.member_id", "=", $memberDetail->id)
|
||||
->where("claim_requests.claim_id", "!=",null)
|
||||
->orderBy("claims.created_at", "desc")
|
||||
$claimList = DB::table('request_logs')
|
||||
->leftJoin('services', 'services.code', '=', 'request_logs.service_code')
|
||||
->leftJoin('members', 'members.id', '=', 'request_logs.member_id')
|
||||
->select('request_logs.id','request_logs.submission_date AS admission_date','request_logs.discharge_date','request_logs.code','services.name as service_name','request_logs.status','members.name',)
|
||||
->where('request_logs.service_code', 'IP')
|
||||
->where('request_logs.status_final_log', 'approved')
|
||||
->where("request_logs.member_id", "=", $memberDetail->id)
|
||||
->orderBy("request_logs.created_at", "desc")
|
||||
->get();
|
||||
|
||||
return response()->json([
|
||||
|
||||
@@ -306,10 +306,12 @@ class RequestLogController extends Controller
|
||||
{
|
||||
$id = $request->id;
|
||||
$requestLog = RequestLog::findOrFail($id);
|
||||
$status = $request->status ?? 'requested';
|
||||
|
||||
|
||||
// Update Request LOG untuk lanjut ke Final LOG
|
||||
$requestLog->final_log = 1;
|
||||
$requestLog->status_final_log = 'requested';
|
||||
$requestLog->status_final_log = $status;
|
||||
$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\CityController;
|
||||
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\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\CorporateController;
|
||||
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::post('customer-service/request/final-log', [RequestLogController::class, 'updateFinalLog']);
|
||||
|
||||
// insert benefit
|
||||
Route::post('customer-service/request/insert-benefit', [RequestLogBenefitController::class, 'store']);
|
||||
Route::delete('customer-service/request/benefit_data/{id}', [RequestLogBenefitController::class, 'destroy']);
|
||||
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-specialities', [SpecialityController::class, 'searchSpeciality']);
|
||||
Route::resource('organizations', OrganizationController::class);
|
||||
|
||||
@@ -7,6 +7,7 @@ use App\Models\CorporateBenefit;
|
||||
use App\Models\ClaimRequest;
|
||||
use App\Models\CorporateService;
|
||||
use App\Models\RequestLogBenefit;
|
||||
use App\Models\RequestLogMedicine;
|
||||
use App\Models\Exclusion;
|
||||
use App\Models\Icd;
|
||||
use App\Helpers\Helper;
|
||||
@@ -26,6 +27,7 @@ class RequestLogShowResource extends JsonResource
|
||||
$corporateId = $requestLog['member']['current_plan']['corporate_id'] ?? 0;
|
||||
$benefit = CorporateBenefit::with('benefit')->where('plan_id', $corporateId)->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 = [];
|
||||
if (count($benefit)){
|
||||
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
|
||||
$corporateService = CorporateService::query()
|
||||
->where('corporate_id', $corporateId)
|
||||
->where('service_code', $requestLog['service_code'])
|
||||
->with(['configs'])
|
||||
->first();
|
||||
$config = $corporateService->configs->pluck('value', 'name')->toArray();
|
||||
$config = [];
|
||||
if ($corporateService) {
|
||||
$config = $corporateService->configs->pluck('value', 'name')->toArray();
|
||||
}
|
||||
|
||||
// Exclusion Service or diagnosis
|
||||
$exclusions = Exclusion::query()
|
||||
@@ -70,6 +82,7 @@ class RequestLogShowResource extends JsonResource
|
||||
'benefit_data' => $benefitDetailLog,
|
||||
'config_service' => $config,
|
||||
'exclusion' => $exclusions,
|
||||
'medicine' => $medicineData,
|
||||
'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()
|
||||
{
|
||||
Schema::create('claim_daily_monitoring', function (Blueprint $table) {
|
||||
$table->bigIncrements('id');
|
||||
$table->integer('claim_id');
|
||||
Schema::create('request_log_daily_monitorings', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('request_log_id');
|
||||
$table->timestamps();
|
||||
$table->text('subject');
|
||||
$table->decimal('body_temperature', 11, 2);
|
||||
$table->decimal('respiration_rate', 11, 2);
|
||||
@@ -23,7 +24,9 @@ return new class extends Migration
|
||||
$table->decimal('diastole', 11, 2);
|
||||
$table->text('analysis');
|
||||
$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()
|
||||
{
|
||||
Schema::dropIfExists('claim_daily_monitoring');
|
||||
Schema::dropIfExists('request_log_daily_monitorings');
|
||||
}
|
||||
};
|
||||
@@ -13,7 +13,7 @@ type MuiDialogProps = {
|
||||
openDialog: boolean;
|
||||
setOpenDialog: Function;
|
||||
content?: ReactElement;
|
||||
action?: ReactElement;
|
||||
action?: ReactElement|null;
|
||||
maxWidth?: string;
|
||||
};
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ export default function ClaimListRow ({ ...props }: Props) {
|
||||
<TableRow hover sx={{ '& > td': { borderBottom: '1' } }}>
|
||||
<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 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>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell align="left">{props.row.claim_code}</TableCell>
|
||||
<TableCell align="left">{props.row.service_type}</TableCell>
|
||||
<TableCell align="left">{props.row.claim_status}</TableCell>
|
||||
<TableCell align="left">{props.row.code}</TableCell>
|
||||
<TableCell align="left">{props.row.service_name}</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()}>
|
||||
<Stack direction="row" justifyContent="flex-end" spacing={1}>
|
||||
<TableMoreMenu actions={
|
||||
|
||||
@@ -52,6 +52,8 @@ export default function DailyMonitoringList() {
|
||||
<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}>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"} />
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
|
||||
@@ -53,6 +53,15 @@ export default function DailyMonitoringListRow ({ ...props }: Props) {
|
||||
{fDate(props.row.enddate)}
|
||||
</Label>
|
||||
</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()}>
|
||||
<Stack direction="row" justifyContent="flex-end" spacing={1}>
|
||||
<TableMoreMenu actions={
|
||||
|
||||
@@ -6,6 +6,8 @@ export type DailyMonitoringListType = {
|
||||
name : string,
|
||||
startdate : 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() {
|
||||
|
||||
const pageTitle = 'Claim Request';
|
||||
const pageTitle = 'Inpatient Monitoring';
|
||||
return (
|
||||
<Page title={ pageTitle } sx={{ mx: 2}}>
|
||||
|
||||
@@ -16,8 +16,8 @@ export default function Claims() {
|
||||
links={[
|
||||
{ name: 'Dashboard', href: '/dashboard' },
|
||||
{
|
||||
name: 'Claim Request',
|
||||
href: '/claim-requests',
|
||||
name: 'Inpatient Monitoring',
|
||||
href: '/inpatient_monitoring',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
@@ -49,7 +49,7 @@ import Label from '@/components/Label';
|
||||
import TableMoreMenu from '@/components/table/TableMoreMenu';
|
||||
import { Import } from '@/@types/claims';
|
||||
|
||||
import { FinalLogType } from './Model/Types';
|
||||
import { FinalLogType } from '../../CustomerService/FinalLog/Model/Types';
|
||||
// import LoadingButton from '@/theme/overrides/LoadingButton';
|
||||
|
||||
export default function List() {
|
||||
@@ -344,7 +344,7 @@ export default function List() {
|
||||
{open ? <KeyboardArrowDownIcon /> : <KeyboardArrowRightIcon />}
|
||||
</IconButton>
|
||||
</TableCell> */ }
|
||||
<TableCell align="left">
|
||||
{/* <TableCell align="left">
|
||||
<Typography
|
||||
// onClick={() => {
|
||||
// handleShowClaim(row);
|
||||
@@ -352,9 +352,9 @@ export default function List() {
|
||||
>
|
||||
{row.id}
|
||||
</Typography>
|
||||
</TableCell>
|
||||
</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">{row.service_name}</TableCell>
|
||||
<TableCell align="left">{row.payment_type_name}</TableCell>
|
||||
@@ -370,11 +370,11 @@ export default function List() {
|
||||
<TableCell align="right">
|
||||
<TableMoreMenu actions={
|
||||
<>
|
||||
<MenuItem onClick={() => navigate(`/claim-requests/edit/${row.id}`)}>
|
||||
{/* <MenuItem onClick={() => navigate(`/claim-requests/edit/${row.id}`)}>
|
||||
<EditOutlinedIcon />
|
||||
Edit
|
||||
</MenuItem>
|
||||
<MenuItem onClick={() => navigate ('/claim-requests/detail/'+row.id+'')}>
|
||||
</MenuItem> */}
|
||||
<MenuItem onClick={() => navigate ('/custormer-service/final-log/detail/'+row.id+'')}>
|
||||
<FindInPageOutlinedIcon />
|
||||
Detail
|
||||
</MenuItem>
|
||||
@@ -476,9 +476,9 @@ export default function List() {
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
{/* <TableCell style={headStyle} align="left" /> */}
|
||||
<TableCell style={headStyle} align="left">
|
||||
{/* <TableCell style={headStyle} align="left">
|
||||
ID Request LOG
|
||||
</TableCell>
|
||||
</TableCell> */}
|
||||
<TableCell style={headStyle} align="left">
|
||||
Code
|
||||
</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 handleSubmit = () => {
|
||||
const formData = {
|
||||
status : approve
|
||||
status : approve,
|
||||
id: requestLog?.id
|
||||
}
|
||||
axios
|
||||
.put(`customer-service/request/${requestLog?.id}`, formData)
|
||||
.post(`customer-service/request/final-log`, formData)
|
||||
.then((response) => {
|
||||
enqueueSnackbar('Verification Request LOG Success', { variant: 'success' });
|
||||
enqueueSnackbar('Verification Final LOG Success', { variant: 'success' });
|
||||
setOpenDialog(false);
|
||||
navigate('/custormer-service/request')
|
||||
navigate('/custormer-service/final-log')
|
||||
})
|
||||
.catch(({ response }) => {
|
||||
enqueueSnackbar(response.data.message ?? 'Something went wrong!', { variant: 'error' });
|
||||
@@ -54,7 +55,7 @@ export default function DialogConfirmation({requestLog, setOpenDialog, openDialo
|
||||
|
||||
const getContent = () => (
|
||||
<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}>
|
||||
<Card sx={{padding:2, marginTop:2}} >
|
||||
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||
|
||||
@@ -66,4 +66,55 @@ export default function DialogDelete({id, setOpenDialog, openDialog,onSubmit} :
|
||||
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;
|
||||
onSubmit?: void;
|
||||
data: BenefitConfigurationListType|undefined;
|
||||
id: number;
|
||||
id: number|undefined;
|
||||
}
|
||||
|
||||
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 { Button, Autocomplete, Card, Checkbox, DialogActions, Grid, Typography } from "@mui/material";
|
||||
import { Paper } 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 { MedicineType } from "../Model/Types";
|
||||
import { fDateTimesecond, toTitleCase } from "@/utils/formatTime";
|
||||
import { useFieldArray, useForm } from 'react-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 { LoadingButton } from '@mui/lab';
|
||||
import AddIcon from '@mui/icons-material/Add';
|
||||
import RemoveIcon from '@mui/icons-material/Remove';
|
||||
import RHFTextFieldMoney from "@/components/hook-form/v2/RHFTextFieldMoney";
|
||||
|
||||
import { IconButton } from '@mui/material';
|
||||
import { postAddMedince } from '../Model/Functions';
|
||||
|
||||
type DialogConfirmationType = {
|
||||
openDialog: boolean;
|
||||
@@ -23,128 +29,133 @@ type DialogConfirmationType = {
|
||||
requestLog: DetailFinalLogType|undefined;
|
||||
}
|
||||
|
||||
export default function DialogHMedicine({requestLog, setOpenDialog, openDialog } : DialogConfirmationType ) {
|
||||
|
||||
interface FormValuesProps extends Partial<DetailFinalLogType> {
|
||||
taxes: boolean;
|
||||
inStock: boolean;
|
||||
}
|
||||
|
||||
const onSubmit = async (data: DetailFinalLogType) => {
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
export default function DialogMedicine({requestLog, setOpenDialog, openDialog } : DialogConfirmationType ) {
|
||||
const handleCloseDialogMedicine = () => {
|
||||
setOpenDialog(false)
|
||||
setMedicines([])
|
||||
setOpenDialog(false);
|
||||
}
|
||||
const [medicines, setMedicines] = useState([]);
|
||||
|
||||
const addMedicine = () => {
|
||||
setMedicines((prevMedicines) => [...prevMedicines, { medicine: '', price: '' }]);
|
||||
|
||||
const requestID = requestLog?.id
|
||||
|
||||
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) => {
|
||||
// Update the medicines state to remove the medicine at the given index
|
||||
setMedicines((prevMeds) => prevMeds.filter((med, medIndex) => medIndex !== index));
|
||||
};
|
||||
const validationSchema = Yup.object().shape({
|
||||
medicine: Yup.array().of(
|
||||
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 index = medicines.indexOf(i);
|
||||
if (index > -1) { // only splice array when item is found
|
||||
medicines.splice(index, 1); // 2nd parameter means remove one item only
|
||||
const methods = useForm<any>({
|
||||
resolver: yupResolver(validationSchema),
|
||||
defaultValues
|
||||
});
|
||||
|
||||
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 = () => (
|
||||
<FormProvider methods={methods} onSubmit={handleSubmit(onSubmit)}>
|
||||
<FormProvider methods={methods} onSubmit={handleSubmit(submitHandler)}>
|
||||
<Stack spacing={2} sx={{marginTop: 2, padding: 2}}>
|
||||
<Grid container spacing={2}>
|
||||
{/* Medicine */}
|
||||
<Grid item xs={12}>
|
||||
<Stack direction="row" alignItems="center" sx={{marginBottom: 4}}>
|
||||
<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>
|
||||
</Button>
|
||||
</Stack>
|
||||
</Grid>
|
||||
|
||||
{/* Listing */}
|
||||
<Grid item xs={6}>
|
||||
<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}>
|
||||
{fields.map((field, index) => (
|
||||
<React.Fragment key={index}>
|
||||
<Grid item xs={6}>
|
||||
<RHFTextField
|
||||
name={`medicine[${index+1}].name`}
|
||||
id='medicine_name'
|
||||
key={field.id}
|
||||
name={`medicine.${index}.medicine_name`}
|
||||
label="Medicine"
|
||||
required
|
||||
placeholder="Medicine"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Grid item xs={5}>
|
||||
<RHFTextFieldMoney
|
||||
name={`medicine[${index+1}].price`}
|
||||
id='medicine_price'
|
||||
key={field.id}
|
||||
name={`medicine.${index}.medicine_price`}
|
||||
label="Price"
|
||||
required
|
||||
placeholder="Price"
|
||||
/>
|
||||
</Grid>
|
||||
{/* <Grid item xs={1}>
|
||||
<Button variant="contained" color="error" onClick={() => handleDelete(index)}>
|
||||
Delete
|
||||
</Button>
|
||||
</Grid> */}
|
||||
{
|
||||
index != (fields.length-1) ?
|
||||
(
|
||||
<Grid item xs={1} sx={{ textAlign: 'center' }}>
|
||||
<IconButton size='large' color='error' onClick={() => remove(index)}>
|
||||
<RemoveIcon />
|
||||
</IconButton>
|
||||
</Grid>
|
||||
) : null
|
||||
}
|
||||
|
||||
</React.Fragment>
|
||||
))}
|
||||
|
||||
</Grid>
|
||||
</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>
|
||||
);
|
||||
|
||||
const getAction = () => (
|
||||
<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>
|
||||
);
|
||||
|
||||
const getAction = () => null;
|
||||
|
||||
|
||||
return (
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
Collapse,
|
||||
AccordionSummary,
|
||||
AccordionDetails,
|
||||
IconButton,
|
||||
} from '@mui/material';
|
||||
// components
|
||||
import Page from '../../../components/Page';
|
||||
@@ -37,19 +38,22 @@ import AddIcon from '@mui/icons-material/Add';
|
||||
import CardDetail from '../Components/CardDetail';
|
||||
import CardService from '../Components/CardService';
|
||||
import CardExclusion from '../Components/CardExclusion';
|
||||
import CardBenefit from '../Components/CardBenefit';
|
||||
|
||||
// Import Dialog
|
||||
import DialogHospitalCare from './Components/DialogHospitalCare';
|
||||
import DialogBenefit from './Components/DialogBenefit';
|
||||
import DialogMedicine from './Components/DialogMedicine';
|
||||
import DetailBenefit from '../Components/DetailBenefit';
|
||||
import DialogDelete from './Components/DialogDelete';
|
||||
import DialogEditBenefit from './Components/DialogEditBenefit';
|
||||
import { DialogDeleteMedicine } from './Components/DialogDelete';
|
||||
|
||||
import MoreMenu from '@/components/MoreMenu';
|
||||
import { MenuItem } from '@mui/material';
|
||||
import { fNumber } from '@/utils/formatNumber';
|
||||
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>
|
||||
|
||||
|
||||
{/* PR Buat pindahin ke componen */}
|
||||
{/* <CardBenefit
|
||||
requestLog={requestLog}
|
||||
>
|
||||
|
||||
</CardBenefit> */}
|
||||
|
||||
<DialogBenefit
|
||||
requestLog={requestLog}
|
||||
@@ -335,37 +345,45 @@ export default function Detail() {
|
||||
<Typography variant="button" display="block">Medicine</Typography>
|
||||
</Button>
|
||||
</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>
|
||||
|
||||
{/* File */}
|
||||
<Grid item xs={12} md={12}>
|
||||
<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>
|
||||
<CardFile
|
||||
requestLog={requestLog}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
{requestLog?.status_final_log == 'requested' ? (
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import axios from '@/utils/axios';
|
||||
import { enqueueSnackbar } from 'notistack';
|
||||
import { MemberListType } from './Types';
|
||||
import { MedicineType, MemberListType } from './Types';
|
||||
import { BenefitConfigurationListType } from './Types';
|
||||
import { makeFormData } from '@/utils/jsonToFormData';
|
||||
|
||||
@@ -119,7 +119,7 @@ export const postAddBenefit = async (data: BenefitConfigurationListType):Promise
|
||||
/**
|
||||
* 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}`, {
|
||||
...data
|
||||
})
|
||||
@@ -151,3 +151,40 @@ export const postEditBenefit = async (id:number, data: BenefitConfigurationListT
|
||||
|
||||
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,
|
||||
code : string,
|
||||
member : Member,
|
||||
member_name : string,
|
||||
submission_date : string,
|
||||
service_name : string,
|
||||
payment_type_name : string,
|
||||
@@ -41,6 +42,7 @@ export type DetailFinalLogType = {
|
||||
benefit_data : BenefitData[],
|
||||
config_service : ConfigService,
|
||||
exclusion : Exclusion[],
|
||||
medicine : Medicine[],
|
||||
files : file[],
|
||||
}
|
||||
|
||||
@@ -51,9 +53,26 @@ export type BenefitData = {
|
||||
excess_paid : number,
|
||||
keterangan : string,
|
||||
benefit : Benefit,
|
||||
request_log_id : number,
|
||||
benefit_name : string,
|
||||
description : string,
|
||||
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 = {
|
||||
id: number,
|
||||
code: string,
|
||||
@@ -104,15 +123,17 @@ export type Rule = {
|
||||
|
||||
}
|
||||
|
||||
|
||||
export type BenefitConfigurationListType = {
|
||||
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 MedicineType = {
|
||||
medicine: Medicine[],
|
||||
}
|
||||
|
||||
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>
|
||||
<td>
|
||||
<div class="text-sm text-gray">Date of Admission</div>
|
||||
@if (isset($claimRequest))
|
||||
<div class="text-md">{{ !empty($claimRequest->submission_date) ? \Carbon\Carbon::parse($claimRequest->submission_date)->format('d/m/Y') : now()->format('d/m/Y') }}</div>
|
||||
@if (isset($requestLog))
|
||||
<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
|
||||
<div class="text-md">{{ $dateOfAdmission->format('d/m/Y') }}</div>
|
||||
@endif
|
||||
@@ -140,7 +140,7 @@
|
||||
<table id="benefit-table">
|
||||
<tr>
|
||||
<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>
|
||||
|
||||
|
||||
@@ -148,18 +148,34 @@
|
||||
<td class="text-lg">Medical Check Up</td>
|
||||
<td class="text-lg">As Charged</td>
|
||||
</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)
|
||||
|
||||
<tr>
|
||||
<td>{{ @$corporateBenefit->benefit->description ?? '' }}</td>
|
||||
@if($corporateBenefit->limit_amount == 999999999)
|
||||
<td style="align-right">As Charged</td>
|
||||
@else
|
||||
<td style="align-right">IDR {{ number_format($corporateBenefit->limit_amount, 0, ',', '.') ?? '' }}</td>
|
||||
@endif
|
||||
</tr>
|
||||
@endforeach
|
||||
<div class="benefit-table-wrapper" style="margin-top: 20px; width: 100%;">
|
||||
<table id="benefit-table">
|
||||
<tr>
|
||||
<th class="text-lg" style="font-weight: 600">Term on Condition</th>
|
||||
<!-- <th class="text-lg" style="font-weight: 600">Limit</th> -->
|
||||
</tr>
|
||||
|
||||
@if ($member->currentPlan)
|
||||
@foreach ($member->currentPlan->corporateBenefits as $corporateBenefit)
|
||||
|
||||
<tr>
|
||||
<td>{{ @$corporateBenefit->benefit->description ?? '' }}</td>
|
||||
|
||||
</tr>
|
||||
@endforeach
|
||||
@endif
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user