add fitur search, edit dan filter claim request

This commit is contained in:
2024-02-20 14:54:02 +07:00
parent 8895311a8f
commit 2c868c00ec
12 changed files with 543 additions and 282 deletions

View File

@@ -37,9 +37,18 @@ class ClaimRequestController extends Controller
->when($request->search, function ($q, $search) {
$q->where('code', 'LIKE', "%".$search."%");
$q->orWhereHas('member', function ($subQuery) use ($search) {
$subQuery->where('name', 'LIKE', "%".$search."");
$subQuery->where('name', 'LIKE', "%".$search."%");
});
})
->when($request->start_date, function ($q, $startDate) {
$q->where('submission_date', '>', $startDate);
})
->when($request->end_date, function ($q, $endDate) {
$q->where('submission_date', '<', $endDate);
})
->when($request->service_code, function ($q, $serviceCode) {
$q->whereIn('service_code', $serviceCode);
})
->when($request->orderBy, function ($q, $orderBy) use ($request) {
if (in_array($orderBy, ['submission_date', 'code'])) {
$q->orderBy($orderBy, $request->order);
@@ -262,12 +271,8 @@ class ClaimRequestController extends Controller
'claim',
'organization',
]);
$organization = Organization::where('code', $request->provider_code)->first();
if (!$organization) {
return response()->json(['error' => true, 'message' => 'Data tidak ditemukan'], 404);
}
$updateClaimRequest = ClaimRequestService::updateClaimRequest(organization_id: $organization->id, claim_request_id: $id);
$updateClaimRequest = ClaimRequestService::updateClaimRequest(reason: $request->reason, submission_date: $request->date, claim_request_id: $id);
ClaimRequested::dispatch($updateClaimRequest);
// Log History

View File

@@ -312,7 +312,7 @@ Route::prefix('internal')->group(function () {
Route::post('claim-requests/{id}/approve', [ClaimRequestController::class, 'approve'])->name('claim-requests.approve');
Route::get('claim-requests/{id}', [ClaimRequestController::class, 'show'])->name('claim-requests.show');
Route::post('claim-requests', [ClaimRequestController::class, 'createNew']); // Bagaskoro, BSD 2 November 2023
Route::put('claim-requests/{id}', [ClaimRequestController::class, 'update'])->name('claim-requests.update');
Route::post('claim-requests/{id}/update', [ClaimRequestController::class, 'update']);
Route::post('claim-requests/import', [ClaimRequestController::class, 'importClaim'])->name('claim-requests.importClaim');
Route::get('claim-requests/detail/{id}', [ClaimRequestController::class, 'claimRequestDetail']);
Route::post('claim-requests/{id}/invoice-files', [ClaimRequestController::class, 'invoiceFiles']);

View File

@@ -4,6 +4,7 @@ namespace Modules\Internal\Transformers;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Str;
use App\Models\Service;
class ClaimRequestShowResource extends JsonResource
{
@@ -17,6 +18,15 @@ class ClaimRequestShowResource extends JsonResource
{
$data = parent::toArray($request);
$service = Service::where('code',$data['service_code'])->first();
if($service){
$serviceName = $service->name;
} else {
$serviceName = '-';
}
$data['service_name'] = $serviceName;
// Map Histories to Group by Dates
$historiesGroupByDate = $this->histories->mapToGroups(function($history) {
return [$history->created_at->format('Y-m-d') => $history];

View File

@@ -8,6 +8,7 @@ use App\Traits\Blameable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Altek\Accountant\Contracts\Recordable;
use Str;
class ClaimRequest extends Model
@@ -28,7 +29,8 @@ class ClaimRequest extends Model
'claim_id',
'organization_id',
'code',
'request_log_id'
'request_log_id',
'reason'
];
protected $hidden = [

View File

@@ -14,6 +14,7 @@ use App\Models\CorporateBenefit;
use App\Models\Member;
use App\Models\MemberPlan;
use App\Models\CorporateHospital;
use App\Models\ClaimRequest;
use App\Models\ExclusionRules;
use App\Models\ExclusionImport;
use App\Models\Icd;
@@ -147,6 +148,15 @@ class AppServiceProvider extends ServiceProvider
$this->logAuditTrail($model, 'deleted');
});
ClaimRequest::updated(function ($model) {
$this->logAuditTrail($model, 'updated');
});
ClaimRequest::deleted(function ($model) {
$this->logAuditTrail($model, 'deleted');
});
// ICD or exlusion
Icd::updated(function ($model) {
$this->logAuditTrail($model, 'updated');

View File

@@ -110,19 +110,23 @@ class ClaimRequestService{
}
}
public static function updateClaimRequest($organization_id, $claim_request_id){
public static function updateClaimRequest($reason, $submission_date, $claim_request_id){
try {
$data = [
'organization_id' => $organization_id
];
DB::commit();
$update = ClaimRequest::where('id', $claim_request_id)->update($data);
return ClaimRequest::find($claim_request_id);
$claimRequest = ClaimRequest::find($claim_request_id);
if (!$claimRequest) {
throw new \Exception("Claim request not found");
}
$claimRequest->submission_date = $submission_date;
$claimRequest->reason = $reason;
$claimRequest->save();
return $claimRequest;
} catch (\Exception $error) {
DB::rollBack();
throw new \Exception($error);
throw new \Exception($error->getMessage());
}
}

View File

@@ -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('claim_requests', function (Blueprint $table) {
$table->string('reason')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('claim_requests', function (Blueprint $table) {
$table->dropColumn('reason');
});
}
};

View File

@@ -10,12 +10,16 @@ export type ClaimRequest = {
service_code: string;
claim_method: string;
service_type: string;
service_name: string;
code_provider: string;
file_condition: Files;
member: Member;
claim: {
organization: Organizations
}
organization: {
code: string
}
};
export type Claims = {

View File

@@ -0,0 +1,174 @@
import MuiDialog from "@/components/MuiDialog";
import { Autocomplete, Button, Card, Checkbox, DialogActions, Grid, TextField, Typography } from "@mui/material";
import { Paper } from "@mui/material";
import { Stack } from '@mui/material';
import React, { useEffect, useState } from 'react';
import { ClaimRequest, Files } from '@/@types/claims';
import { fDateOnly, fDateTimesecond, toTitleCase } from "@/utils/formatTime";
import axios from "@/utils/axios";
import { enqueueSnackbar, useSnackbar } from "notistack";
import { useNavigate } from "react-router";
import * as Yup from 'yup';
import { yupResolver } from '@hookform/resolvers/yup';
type DialogConfirmationType = {
openDialog: boolean;
setOpenDialog: any;
onSubmit?: void;
approve: string;
claimRequest: ClaimRequest|undefined;
}
export default function DialogConfirmation({claimRequest, setOpenDialog, openDialog, approve, onSubmit} : DialogConfirmationType ) {
const navigate = useNavigate();
const { enqueueSnackbar } = useSnackbar();
const [formData, setFormData] = useState({
date: claimRequest?.date,
id: claimRequest?.id,
reason: claimRequest?.reason
});
const handleChange = (field, value) => {
setFormData((prevData) => ({
...prevData,
[field]: value,
}));
};
const handleSubmit = () => {
axios
.post(`customer-service/request/final-log`, formData)
.then((response) => {
enqueueSnackbar('Verification Request LOG Success', { variant: 'success' });
setOpenDialog(false);
if (requestLog?.service_type == 'Inpatient'){
navigate('/case_management/inpatient_monitoring');
} else {
navigate('/custormer-service/final-log');
}
})
.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 marginBottom2 = {
marginBottom: 2,
}
const handleCloseDialog = () => {
setOpenDialog(false);
}
const getContent = () => (
<Stack spacing={1} marginTop={2}>
<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}>
<Typography variant='subtitle2' sx={style1} gutterBottom>Member ID</Typography>
<Typography variant='subtitle2' sx={style2} gutterBottom>{requestLog?.member_id}</Typography>
</Stack>
<Stack direction='row' spacing={2} sx={marginBottom1}>
<Typography variant='subtitle2' sx={style1} gutterBottom>Policy Number</Typography>
<Typography variant='subtitle2' sx={style2} gutterBottom>{requestLog?.policy_number}</Typography>
</Stack>
<Stack direction='row' spacing={2} sx={marginBottom1}>
<Typography variant='subtitle2' sx={style1} gutterBottom>Name</Typography>
<Typography variant='subtitle2' sx={style2} gutterBottom>{requestLog?.name}</Typography>
</Stack>
<Stack direction='row' spacing={2} sx={marginBottom1}>
<Typography variant='subtitle2' sx={style1} gutterBottom>Submission Date</Typography>
<Typography variant='subtitle2' sx={style2} gutterBottom>{requestLog?.submission_date ? fDateTimesecond(requestLog?.submission_date) : '-'}</Typography>
</Stack>
<Stack direction='row' spacing={2} sx={marginBottom1}>
<Typography variant='subtitle2' sx={style1} gutterBottom>Claim Method</Typography>
<Typography variant='subtitle2' sx={style2} gutterBottom>{requestLog?.claim_method ? toTitleCase(requestLog?.claim_method) : '-'}</Typography>
</Stack>
<Stack direction='row' spacing={2} sx={marginBottom1}>
<Typography variant='subtitle2' sx={style1} gutterBottom>Service Type</Typography>
<Typography variant='subtitle2' sx={style2} gutterBottom>{requestLog?.service_type}</Typography>
</Stack>
</Card>
<Card sx={{padding:2, marginTop:2}} >
<Stack direction='row' spacing={2} sx={marginBottom2}>
<Typography variant='subtitle2' sx={style1} gutterBottom>Discharge Date</Typography>
<TextField
label="Discharge Date"
variant="outlined"
fullWidth
type="date"
value={formData.discharge_date ? fDateOnly(formData.discharge_date) : ''}
onChange={(e) => handleChange('discharge_date', e.target.value)}
/>
</Stack>
<Stack direction='row' spacing={2} sx={marginBottom2}>
<Typography variant='subtitle2' sx={style1} gutterBottom>Catatan</Typography>
<TextField
label="Catatan"
variant="outlined"
fullWidth
value={formData.catatan}
onChange={(e) => handleChange('catatan', e.target.value)}
/>
</Stack>
<Stack direction='row' spacing={2} sx={marginBottom2}>
<Typography variant='subtitle2' sx={style1} gutterBottom>Diagnosis ICD - X</Typography>
<Autocomplete
multiple
options={icdOptions}
getOptionLabel={(option) => option.label}
fullWidth
value={icdOptions.filter((icd) => formData.icdCodes.includes(icd.value))}
onChange={(e, newValues) => handleChange('icdCodes', newValues.map((value) => value.value))}
renderInput={(params) => (
<TextField
{...params}
label="Diagnosis ICD - X"
variant="outlined"
/>
)}
/>
</Stack>
</Card>
</Grid>
<DialogActions>
<Button variant="outlined" sx={{color: '#212B36', borderColor: '#919EAB52'}} onClick={handleCloseDialog}>Cancel</Button>
{approve == 'approved' ? (
<Button color="primary" variant="contained" onClick={() => handleApprove()}>Approve</Button>
) : (
<Button color="error" variant="contained" onClick={() => handleApprove()}>Decline</Button>
) }
</DialogActions>
</Stack>
);
return (
<MuiDialog
title={{name: "Confirmation"}}
openDialog={openDialog}
setOpenDialog={setOpenDialog}
content={getContent()}
maxWidth="xl"
/>
);
}

View File

@@ -5,7 +5,7 @@ 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 { FormProvider, RHFDatepicker, RHFTextField } from '../../../components/hook-form';
import { makeFormData } from '@/utils/jsonToFormData';
import {
@@ -31,6 +31,7 @@ import {
Divider,
ButtonBase,
Box,
DialogActions,
} from '@mui/material';
import Iconify from '../../../components/Iconify';
import CalendarTodayIcon from '@mui/icons-material/CalendarToday';
@@ -39,7 +40,10 @@ 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';
import { fDateOnly, fDateTimesecond, fPostFormat } from '@/utils/formatTime';
import RHFDatePicker from '@/components/hook-form/RHFDatePickerV2';
import RHFDateTimePicker from '@/components/hook-form/v2/RHFDateTimePicker';
import MuiDialog from '@/components/MuiDialog';
interface FormValuesProps extends Partial<ClaimRequest> {
taxes: boolean;
@@ -57,7 +61,7 @@ export default function FormEdit({ isEdit, currentClaim }: Props) {
const { enqueueSnackbar } = useSnackbar();
const EditClaimSchema = Yup.object().shape({
organization_id: Yup.string().required('Code Provider is required'),
date: Yup.string().required('Date Submission is required'),
});
const defaultValues = useMemo(
@@ -73,6 +77,16 @@ export default function FormEdit({ isEdit, currentClaim }: Props) {
[currentClaim]
);
const [date, setDate] = useState(currentClaim?.submission_date)
const id = currentClaim?.id
useEffect(() => {
setDate(currentClaim?.submission_date)
}, [currentClaim]);
console.log(date);
useEffect(() => {
if (isEdit && currentClaim) {
reset(defaultValues);
@@ -80,9 +94,6 @@ export default function FormEdit({ isEdit, currentClaim }: Props) {
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]);
@@ -97,99 +108,25 @@ export default function FormEdit({ isEdit, currentClaim }: Props) {
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();
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);
// formData.append('date', fPostFormat(id));
// const response = await axios.post(`/claim-requests/${data.id}/update`, formData);
reset();
enqueueSnackbar('Claim Request Updated Successfully!', { variant: 'success' });
navigate('/claim-requests');
@@ -205,6 +142,118 @@ export default function FormEdit({ isEdit, currentClaim }: Props) {
}
};
const handleApprove = () => {
if(selectedReason.value != '-'){
const formData = makeFormData({
date: fPostFormat(date),
reason: selectedReason.value,
});
const response = axios.post(`/claim-requests/${id}/update`, formData);
if (!response.error){
reset();
enqueueSnackbar('Claim Request Updated Successfully!', { variant: 'success' });
navigate('/claim-requests');
} else {
enqueueSnackbar('Claim Request Updated Error!', { variant: 'error' });
}
} else {
setError('Please select a reason')
}
}
const [openDialog, setOpenDialog] = useState(false);
const style1 = {
color: '#919EAB',
width: '30%'
}
const style2 = {
width: '70%'
}
const marginBottom1 = {
marginBottom: 1,
}
const marginBottom2 = {
marginBottom: 2,
}
const handleCloseDialog = () => {
setOpenDialog(false);
}
const reason = [
{ value: 'Wrong Setting', label: 'Wrong Setting' },
{ value: 'Hospital Request', label: 'Hospital Request' }
];
const [selectedReason, setSelectedReason] = React.useState({value:'-', label:''});
const [error, setError] = useState('');
const getContent = () => (
<Stack spacing={1} marginTop={2}>
<Typography variant="subtitle2">Are you sure to update this claim ?</Typography>
<Grid item xs={12} md={12} marginTop={4}>
<Card sx={{padding:2, marginTop:2}} >
<Stack direction='row' spacing={2} sx={marginBottom1}>
<Typography variant='subtitle2' sx={style1} gutterBottom>Code</Typography>
<Typography variant='subtitle2' sx={style2} gutterBottom>{currentClaim?.code}</Typography>
</Stack>
<Stack direction='row' spacing={2} sx={marginBottom1}>
<Typography variant='subtitle2' sx={style1} gutterBottom>Name</Typography>
<Typography variant='subtitle2' sx={style2} gutterBottom>{currentClaim?.member?.name}</Typography>
</Stack>
<Stack direction='row' spacing={2} sx={marginBottom1}>
<Typography variant='subtitle2' sx={style1} gutterBottom>Date of Submission</Typography>
<Typography variant='subtitle2' sx={style2} gutterBottom>{date ? fDateTimesecond(date) : '-'}</Typography>
</Stack>
<Stack direction='row' spacing={2} sx={marginBottom1}>
<Typography variant='subtitle2' sx={style1} gutterBottom>Claim Method</Typography>
<Typography variant='subtitle2' sx={style2} gutterBottom>{currentClaim?.payment_type}</Typography>
</Stack>
<Stack direction='row' spacing={2} sx={marginBottom1}>
<Typography variant='subtitle2' sx={style1} gutterBottom>Service Type</Typography>
<Typography variant='subtitle2' sx={style2} gutterBottom>{currentClaim?.service_name || '-'}</Typography>
</Stack>
<Stack direction='row' spacing={2} sx={marginBottom1}>
<Typography variant='subtitle2' sx={style1} gutterBottom>Code Provider</Typography>
<Typography variant='subtitle2' sx={style2} gutterBottom>{currentClaim?.organization?.code || '-'}</Typography>
</Stack>
</Card>
<Card sx={{padding:2, marginTop:2}} >
<Typography variant="subtitle1" marginY={2}>Reason for Update*</Typography>
<Stack direction='row' spacing={2} sx={marginBottom2}>
<Autocomplete
options={reason}
getOptionLabel={(option) => option.label}
fullWidth
value={selectedReason}
onChange={(event, newValue) => {
setSelectedReason(newValue);
// Validasi jika newValue adalah null
if (!newValue) {
setError('Please select a reason');
} else {
setError('');
}
}}
renderInput={(params) => (
<TextField
{...params}
label="Reason for updates"
variant="outlined"
name='reason'
error={Boolean(error)} // Menampilkan error jika ada
helperText={error} // Menampilkan pesan kesalahan
/>
)}
/>
</Stack>
</Card>
</Grid>
<DialogActions>
<Button variant="outlined" sx={{color: '#212B36', borderColor: '#919EAB52'}} onClick={handleCloseDialog}>Cancel</Button>
<Button color="primary" variant="contained" onClick={() => handleApprove()}>Approve</Button>
</DialogActions>
</Stack>
)
return (
<FormProvider methods={methods} onSubmit={handleSubmit(onSubmit)}>
@@ -254,12 +303,18 @@ export default function FormEdit({ isEdit, currentClaim }: Props) {
<Grid item xs={3}>
<RHFTextField InputProps={{endAdornment: (
<InputAdornment position="end">
<CalendarTodayIcon />
</InputAdornment>
), }}
name="date" label="Date of Submission" disabled/>
<Controller
name="date"
control={control}
render={({ field }) => (
<RHFDateTimePicker
{...field}
label="Date of Submission"
value={field.value || null}
onChange={() => setDate(field.value)}
/>
)}
/>
</Grid>
<Grid item xs={3}>
<RHFTextField name="claim_method" label="Claim Method" disabled/>
@@ -268,161 +323,8 @@ export default function FormEdit({ isEdit, currentClaim }: Props) {
<RHFTextField name="service_type" label="Service Type*" disabled/>
</Grid>
<Grid item xs={3}>
<RHFTextField name="organization_id" label="Code Provider*"/>
<RHFTextField name="organization_id" label="Code Provider*" disabled/>
</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}>
@@ -440,17 +342,24 @@ export default function FormEdit({ isEdit, currentClaim }: Props) {
>
Cancel
</Button>
<LoadingButton
type="submit"
<Button
// type="submit"
variant="contained"
size="large"
loading={isSubmitting}
onClick={() => date ? setOpenDialog(true) : setOpenDialog(false)}
>
Update
</LoadingButton>
</Button>
</Stack>
</Grid>
</Grid>
<MuiDialog
title={{name: "Update Status"}}
openDialog={openDialog}
setOpenDialog={setOpenDialog}
content={getContent()}
maxWidth="md"
/>
</FormProvider>
);
}

View File

@@ -33,7 +33,6 @@ export default function ClaimsCreateUpdate() {
useEffect(() => {
if (isEdit) {
axios.get('/claim-requests/' + id).then((res) => {
console.log('Yeet', res.data);
setCurrentClaim(res.data.data);
});

View File

@@ -19,6 +19,7 @@ import {
Chip,
TableHead,
Grid,
Autocomplete,
} from '@mui/material';
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
@@ -43,25 +44,59 @@ import { enqueueSnackbar } from 'notistack';
import { Divider } from '@mui/material';
import Iconify from '@/components/Iconify';
import DialogDetailClaim from '@/components/dialogs/DialogDetailClaim';
import { fDateTimesecond } from '@/utils/formatTime';
import { fDateOnly, fDateTimesecond } from '@/utils/formatTime';
import { capitalizeFirstLetter } from '@/utils/formatString';
import Label from '@/components/Label';
import TableMoreMenu from '@/components/table/TableMoreMenu';
import { Import } from '@/@types/claims';
import { DesktopDatePicker, LocalizationProvider } from '@mui/x-date-pickers';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
// import LoadingButton from '@/theme/overrides/LoadingButton';
export default function List() {
type ServiceCode = {
value: string,
label: string
}
const { themeColorPresets } = useSettings();
const [searchParams, setSearchParams] = useSearchParams();
const [importResult, setImportResult] = useState<Import>(null);
const [selectedOptions, setSelectedOptions] = useState<ServiceCode|undefined>([]); // State untuk nilai terpilih
const navigate = useNavigate()
const defaultValue = [
{
value: '-',
label: '-'
}
];
const [serviceCode, setServiceCode] = useState(defaultValue);
const handleOptionService = () => {
}
const handleFilter = (event: React.SyntheticEvent<Element, Event>, newValue: { value: string, label: string }[], name:string) => { //
const serviceCodeArray :string[] = [];
const codeArray :string[] = [];
const typeArray :string[] = [];
const planArray :string[] = [];
if (name == 'service_code'){
newValue.map(row => {
serviceCodeArray.push(row.value);
})
setSelectedOptions(newValue)
}
var entries = [...searchParams.entries(), ['service_code', serviceCodeArray ?? '']];
const filter = Object.fromEntries(entries);
loadDataTableData(filter);
}
function SearchInput(props: any) {
// SEARCH
const searchInput = useRef<HTMLInputElement>(null);
const [searchText, setSearchText] = useState('');
const handleSearchChange = (event: any) => {
const newSearchText = event.target.value ?? '';
setSearchText(newSearchText);
@@ -79,16 +114,83 @@ export default function List() {
return (
<form onSubmit={handleSearchSubmit} style={{ width: '100%' }}>
<TextField
id="search-input"
ref={searchInput}
label="Search"
variant="outlined"
fullWidth
onChange={handleSearchChange}
value={searchText}
placeholder='Search Code or Name...'
/>
<Grid container spacing={2} >
<Grid item md={5}>
<TextField
id="search-input"
ref={searchInput}
label="Search"
variant="outlined"
fullWidth
onChange={handleSearchChange}
value={searchText}
placeholder='Search Code or Name...'
/>
</Grid>
<Grid item md={2}>
<LocalizationProvider dateAdapter={AdapterDateFns}>
<DesktopDatePicker
label="Start Date"
value={searchParams.get('start_date')}
inputFormat="dd/MM/yyyy"
onChange={(value) => {
try {
if (value && !!Date.parse(value)) {
const date:string = value ? fDateOnly(value) : '';
var entries = [...searchParams.entries(), ['start_date', date ?? '']];
const filter = Object.fromEntries(entries);
setSearchParams(filter);
loadDataTableData(filter);
}
} catch (e) {}
}}
renderInput={(params) => <TextField {...params} variant="outlined" />}
/>
</LocalizationProvider>
</Grid>
<Grid item md={2}>
<LocalizationProvider dateAdapter={AdapterDateFns}>
<DesktopDatePicker
label="End Date"
inputFormat="MM/dd/yyyy"
value={searchParams.get('end_date')}
onChange={(value) => {
try {
if (value && !!Date.parse(value)) {
const date = fDateOnly(value);
var entries = [...searchParams.entries(), ['end_date', date ?? '']];
const filter = Object.fromEntries(entries);
setSearchParams(filter);
loadDataTableData(filter);
}
} catch (e) {}
}}
renderInput={(params) => <TextField {...params} variant="outlined" />}
/>
</LocalizationProvider>
</Grid>
<Grid item md={3}>
<Autocomplete
id="combo-box-demo"
options={serviceCode}
multiple
limitTags={1}
value={selectedOptions}
onChange={
(event, newValue) => handleFilter(event, newValue, 'service_code')
}
fullWidth
disableCloseOnSelect
getOptionLabel={(option) => option.label}
renderInput={(params) => (
<TextField {...params} label="Service" variant="outlined" />
)}
/>
</Grid>
</Grid>
</form>
);
}
@@ -279,11 +381,21 @@ export default function List() {
);
const loadDataTableData = async (appliedFilter: any | null = null) => {
axios.get('service').then((response) => {
const formattedData = response.data.data.map(service => ({
value: service.code,
label: service.name
}));
setServiceCode(formattedData);
});
setDataTableLoading(true);
const filter = appliedFilter ? appliedFilter : Object.fromEntries([...searchParams.entries()]);
const response = await axios.get('/claim-requests', { params: filter });
// console.log(response.data);
console.log(response.data);
setDataTableLoading(false);
setDataTableData(response.data);
};