Merge branch 'staging' of itcorp.primaya.id:rajif/aso into staging
This commit is contained in:
@@ -277,6 +277,7 @@ class DiagnosisExclusionController extends Controller
|
|||||||
$gender = implode(",", $gender);
|
$gender = implode(",", $gender);
|
||||||
$gender = trim($gender, ",");
|
$gender = trim($gender, ",");
|
||||||
|
|
||||||
|
$exclusion->rules()->corporate_id = $corporate_id;
|
||||||
|
|
||||||
$exclusion->rules()->updateOrCreate([
|
$exclusion->rules()->updateOrCreate([
|
||||||
'exclusion_id' => $exclusion->id,
|
'exclusion_id' => $exclusion->id,
|
||||||
@@ -302,7 +303,6 @@ class DiagnosisExclusionController extends Controller
|
|||||||
'values' => $data['min_age'] ?? '',
|
'values' => $data['min_age'] ?? '',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
$exclusion->rules()->updateOrCreate([
|
$exclusion->rules()->updateOrCreate([
|
||||||
'exclusion_id' => $exclusion->id,
|
'exclusion_id' => $exclusion->id,
|
||||||
'name' => 'max_age',
|
'name' => 'max_age',
|
||||||
@@ -330,6 +330,59 @@ class DiagnosisExclusionController extends Controller
|
|||||||
return Helper::paginateResources(DiagnosisExclusionResource::collection($exclusions));
|
return Helper::paginateResources(DiagnosisExclusionResource::collection($exclusions));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bagaskoro BSD 20-10-2023
|
||||||
|
*
|
||||||
|
* Fungsi untuk get detil exclusion
|
||||||
|
*/
|
||||||
|
public function detilExclusion(Request $request, $corporate_id, $id_exclusion)
|
||||||
|
{
|
||||||
|
$corporate = Corporate::query()
|
||||||
|
->with(['currentPolicy', 'plans'])
|
||||||
|
->withCount('corporatePlans')
|
||||||
|
->withCount('employees')
|
||||||
|
->findOrFail($corporate_id);
|
||||||
|
|
||||||
|
$plans = $corporate['plans']->map(function ($plan) {
|
||||||
|
return $plan['code'];
|
||||||
|
});
|
||||||
|
|
||||||
|
$exclusions = Exclusion::query()
|
||||||
|
->where('id', $id_exclusion)
|
||||||
|
->where('type', 'diagnosis')
|
||||||
|
->where('deleted_at', null)
|
||||||
|
->with(['rules'])
|
||||||
|
->get();
|
||||||
|
|
||||||
|
$exclusion = DiagnosisExclusionResource::collection($exclusions);
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'error' => false,
|
||||||
|
'messages' => "success",
|
||||||
|
'data' => [
|
||||||
|
'exclusion' => empty($exclusion) ? [] : $exclusion[0],
|
||||||
|
'plans' => $plans,
|
||||||
|
]
|
||||||
|
],200);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bagaskoro BSD 19-10-2023
|
||||||
|
*
|
||||||
|
* Fungsi untuk update status active
|
||||||
|
*/
|
||||||
|
protected function messages()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'required' => ':attribute harus diisi',
|
||||||
|
'integer' => ':attribute harus angka',
|
||||||
|
'unique' => ':attribute (:input) sudah ada',
|
||||||
|
'max' => ':attribute maximal :max karakter',
|
||||||
|
'exists' => ':attribute (:input) tidak ditemukan',
|
||||||
|
'digits_between'=> ':attribute maximal :max digit minimal :min digit'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
public function updateActivation(Request $request)
|
public function updateActivation(Request $request)
|
||||||
{
|
{
|
||||||
// validation rule
|
// validation rule
|
||||||
@@ -340,8 +393,20 @@ class DiagnosisExclusionController extends Controller
|
|||||||
|
|
||||||
// validation error
|
// validation error
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
return response()->json($validator->getMessageBag(),400);
|
return response()->json([
|
||||||
|
'error' => true,
|
||||||
|
'messages' => $validator->getMessageBag()
|
||||||
|
],400);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Exclusion::where('id', $request->id)->update([
|
||||||
|
'active' => $request->active
|
||||||
|
]);
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'error' => false,
|
||||||
|
'messages' => "status berhasil diupdate",
|
||||||
|
'data' => []
|
||||||
|
],200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,8 +113,9 @@ Route::prefix('internal')->group(function () {
|
|||||||
|
|
||||||
|
|
||||||
Route::get('corporates/{corporate_id}/diagnosis-exclusions', [DiagnosisExclusionController::class, 'index']);
|
Route::get('corporates/{corporate_id}/diagnosis-exclusions', [DiagnosisExclusionController::class, 'index']);
|
||||||
|
Route::get('corporates/{corporate_id}/diagnosis-exclusions/{id_exclusion}', [DiagnosisExclusionController::class, 'detilExclusion']); // By Bagaskoro, get detil exclusion
|
||||||
Route::post('corporates/{corporate_id}/diagnosis-exclusions/store', [DiagnosisExclusionController::class, 'storeExclusion']);
|
Route::post('corporates/{corporate_id}/diagnosis-exclusions/store', [DiagnosisExclusionController::class, 'storeExclusion']);
|
||||||
Route::put('corporates/diagnosis-exclusions/update_activation', [DiagnosisExclusionController::class, 'updateActivation']);
|
Route::put('corporates/diagnosis-exclusions/update_activation', [DiagnosisExclusionController::class, 'updateActivation']); // By Bagaskoro, edit status aktif
|
||||||
Route::delete('diagnosis-exclusions/{id}', [DiagnosisExclusionController::class, 'destroy']);
|
Route::delete('diagnosis-exclusions/{id}', [DiagnosisExclusionController::class, 'destroy']);
|
||||||
Route::post('corporates/{corporate_id}/diagnosis-exclusions/import', [DiagnosisExclusionController::class, 'import']);
|
Route::post('corporates/{corporate_id}/diagnosis-exclusions/import', [DiagnosisExclusionController::class, 'import']);
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ use App\Models\CorporateService;
|
|||||||
use App\Models\CorporatePlan;
|
use App\Models\CorporatePlan;
|
||||||
use App\Models\CorporateBenefit;
|
use App\Models\CorporateBenefit;
|
||||||
use App\Models\Member;
|
use App\Models\Member;
|
||||||
|
use App\Models\CorporateHospital;
|
||||||
use App\Models\ExclusionRules;
|
use App\Models\ExclusionRules;
|
||||||
use App\Models\ExclusionImport;
|
use App\Models\ExclusionImport;
|
||||||
use App\Models\Icd;
|
use App\Models\Icd;
|
||||||
@@ -69,6 +70,16 @@ class AppServiceProvider extends ServiceProvider
|
|||||||
$this->logAuditTrail($model, 'deleted');
|
$this->logAuditTrail($model, 'deleted');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//Hospital
|
||||||
|
CorporateHospital::updated(function ($model) {
|
||||||
|
|
||||||
|
$this->logAuditTrail($model, 'updated');
|
||||||
|
});
|
||||||
|
|
||||||
|
CorporateHospital::deleted(function ($model) {
|
||||||
|
$this->logAuditTrail($model, 'deleted');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// Corporate Service
|
// Corporate Service
|
||||||
CorporateService::updated(function ($model) {
|
CorporateService::updated(function ($model) {
|
||||||
@@ -103,21 +114,20 @@ class AppServiceProvider extends ServiceProvider
|
|||||||
|
|
||||||
// Corporate Exclusion
|
// Corporate Exclusion
|
||||||
ExclusionRules::updated(function ($model) {
|
ExclusionRules::updated(function ($model) {
|
||||||
|
$this->logAuditTrail($model, 'updated');
|
||||||
$this->logAuditTrailExclusion($model, 'updated');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ExclusionRules::deleted(function ($model) {
|
ExclusionRules::deleted(function ($model) {
|
||||||
$this->logAuditTrailExclusion($model, 'deleted');
|
$this->logAuditTrail($model, 'deleted');
|
||||||
});
|
});
|
||||||
|
|
||||||
ExclusionImport::updated(function ($model) {
|
ExclusionImport::updated(function ($model) {
|
||||||
|
|
||||||
$this->logAuditTrailExclusion($model, 'updated');
|
$this->logAuditTrail($model, 'updated');
|
||||||
});
|
});
|
||||||
|
|
||||||
ExclusionImport::deleted(function ($model) {
|
ExclusionImport::deleted(function ($model) {
|
||||||
$this->logAuditTrailExclusion($model, 'deleted');
|
$this->logAuditTrail($model, 'deleted');
|
||||||
});
|
});
|
||||||
|
|
||||||
// ICD or exlusion
|
// ICD or exlusion
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ return new class extends Migration
|
|||||||
$table->string('name', 255);
|
$table->string('name', 255);
|
||||||
$table->text('description')->nullable();
|
$table->text('description')->nullable();
|
||||||
$table->tinyInteger('active')->default(1);
|
$table->tinyInteger('active')->default(1);
|
||||||
$table->text('reason');
|
$table->text('reason')->nullable();
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
$table->softDeletes();
|
$table->softDeletes();
|
||||||
$table->bigInteger('created_by')->nullable();
|
$table->bigInteger('created_by')->nullable();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
GENERATE_SOURCEMAP=false
|
GENERATE_SOURCEMAP=false
|
||||||
|
|
||||||
PORT=8083
|
PORT=8000
|
||||||
|
|
||||||
REACT_APP_HOST_API_URL="http://lms.test"
|
REACT_APP_HOST_API_URL="http://lms.test"
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
// form
|
// form
|
||||||
import { useFormContext, Controller } from 'react-hook-form';
|
import { useFormContext, Controller } from 'react-hook-form';
|
||||||
// @mui
|
// @mui
|
||||||
import { Checkbox, FormControlLabel, FormGroup, FormControlLabelProps } from '@mui/material';
|
import { Checkbox, FormControlLabel, FormGroup, FormControlLabelProps, SxProps } from '@mui/material';
|
||||||
|
import { Theme } from '@mui/system';
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -77,9 +78,10 @@ interface optionsCustomInterface {
|
|||||||
interface RHFCustomMultiCheckboxProps {
|
interface RHFCustomMultiCheckboxProps {
|
||||||
name: string;
|
name: string;
|
||||||
options: optionsCustomInterface[];
|
options: optionsCustomInterface[];
|
||||||
|
sx?: SxProps<Theme>
|
||||||
}
|
}
|
||||||
|
|
||||||
export function RHFCustomMultiCheckbox({ name, options, ...other }: RHFCustomMultiCheckboxProps) {
|
export function RHFCustomMultiCheckbox({ name, options, sx, ...other }: RHFCustomMultiCheckboxProps) {
|
||||||
const { control } = useFormContext();
|
const { control } = useFormContext();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -93,7 +95,7 @@ export function RHFCustomMultiCheckbox({ name, options, ...other }: RHFCustomMul
|
|||||||
: [...field.value, option.value];
|
: [...field.value, option.value];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormGroup>
|
<FormGroup sx={{ ...sx }}>
|
||||||
{options.map((option, index) => (
|
{options.map((option, index) => (
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
key={index}
|
key={index}
|
||||||
|
|||||||
@@ -0,0 +1,273 @@
|
|||||||
|
/**
|
||||||
|
* Core
|
||||||
|
* ============================================
|
||||||
|
*/
|
||||||
|
import axios from '@/utils/axios';
|
||||||
|
import { useForm } from 'react-hook-form';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
|
import { Box, IconButton, Typography, Grid, Card, TextField, Autocomplete, Button } from '@mui/material';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Components
|
||||||
|
* ============================================
|
||||||
|
*/
|
||||||
|
import Page from '../../../components/Page';
|
||||||
|
import { LoadingButton } from "@mui/lab";
|
||||||
|
import { FormProvider, RHFCustomMultiCheckbox, RHFTextField } from '@/components/hook-form';
|
||||||
|
import { enqueueSnackbar } from 'notistack';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Icon
|
||||||
|
* ============================================
|
||||||
|
*/
|
||||||
|
import ArrowBackIosNew from '@mui/icons-material/ArrowBackIosNew';
|
||||||
|
|
||||||
|
export default function Divisions() {
|
||||||
|
const pageTitle = 'Edit Exclusion';
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const { corporate_id, exclusion_id } = useParams(); // id di url
|
||||||
|
const [ plans, setPlans ] = useState<string[]>([]); // option untuk field plans
|
||||||
|
|
||||||
|
// checkbox option
|
||||||
|
// ====================================
|
||||||
|
const msc_checkbox_option = [
|
||||||
|
{
|
||||||
|
value: 'm',
|
||||||
|
label: 'Member',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 's',
|
||||||
|
label: 'Spouse',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'c',
|
||||||
|
label: 'Child',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const gender_checkbox_option = [
|
||||||
|
{
|
||||||
|
value: 'male',
|
||||||
|
label: 'Male',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'female',
|
||||||
|
label: 'Female',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
// setup form
|
||||||
|
// ====================================
|
||||||
|
const defaultValues: any = {
|
||||||
|
msc: [],
|
||||||
|
gender: [],
|
||||||
|
min_age: '',
|
||||||
|
max_age: '',
|
||||||
|
plans: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const methods = useForm<any>({
|
||||||
|
defaultValues
|
||||||
|
});
|
||||||
|
|
||||||
|
const { setValue, handleSubmit, reset, watch, formState: { isDirty, isSubmitting } } = methods;
|
||||||
|
const formValues = watch();
|
||||||
|
|
||||||
|
// set form value
|
||||||
|
// =====================================
|
||||||
|
useEffect(() => {
|
||||||
|
axios.get(`corporates/${corporate_id}/diagnosis-exclusions/${exclusion_id}`)
|
||||||
|
.then((res) => {
|
||||||
|
// plan option
|
||||||
|
setPlans(res.data.data.plans);
|
||||||
|
|
||||||
|
// set value
|
||||||
|
let res_plan = res.data.data.exclusion.rules.plan;
|
||||||
|
|
||||||
|
if (res_plan.length == 1 && res_plan[0] == '') {
|
||||||
|
res_plan = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
reset({
|
||||||
|
msc : res.data.data.exclusion.rules.msc[0].split(','),
|
||||||
|
gender : res.data.data.exclusion.rules.gender[0].split(','),
|
||||||
|
min_age : res.data.data.exclusion.value_rules.min_age,
|
||||||
|
max_age : res.data.data.exclusion.value_rules.max_age,
|
||||||
|
plans : res_plan,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}, [exclusion_id]);
|
||||||
|
|
||||||
|
// Submit Form
|
||||||
|
// =====================================
|
||||||
|
const submitHandler = async (data: any) => {
|
||||||
|
let one_row = {
|
||||||
|
msc: {
|
||||||
|
m: data.msc.includes('m'),
|
||||||
|
s: data.msc.includes('s'),
|
||||||
|
c: data.msc.includes('c'),
|
||||||
|
},
|
||||||
|
gender : {
|
||||||
|
male : data.gender.includes('male') == true ? 1 : 0,
|
||||||
|
female: data.gender.includes('female') == true ? 1 : 0,
|
||||||
|
},
|
||||||
|
min_age: data.min_age,
|
||||||
|
max_age: data.max_age,
|
||||||
|
plan : data.plans.join(','),
|
||||||
|
icd_id : exclusion_id,
|
||||||
|
}
|
||||||
|
|
||||||
|
return axios
|
||||||
|
.post(`/corporates/${corporate_id}/diagnosis-exclusions/store`, {
|
||||||
|
type: 'one_row',
|
||||||
|
icd_id: exclusion_id,
|
||||||
|
one_row
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
enqueueSnackbar('Exclusion Updated', {
|
||||||
|
variant: 'success',
|
||||||
|
});
|
||||||
|
|
||||||
|
reset({
|
||||||
|
msc : data.msc,
|
||||||
|
gender : data.gender,
|
||||||
|
min_age : data.min_age,
|
||||||
|
max_age : data.max_age,
|
||||||
|
plans : data.plans,
|
||||||
|
})
|
||||||
|
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.catch((res) => {
|
||||||
|
enqueueSnackbar('Terjadi kesalahan pada server', {
|
||||||
|
variant: 'error',
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Page title={pageTitle}>
|
||||||
|
<Box sx={{ display: 'flex', alignItems: 'center', pl: '12px', mb: '40px' }}>
|
||||||
|
<IconButton size='large' color='inherit' onClick={() => navigate(`/corporates/${corporate_id}/diagnosis-exclusions`)} >
|
||||||
|
<ArrowBackIosNew/>
|
||||||
|
</IconButton>
|
||||||
|
|
||||||
|
<Typography variant="h5" sx={{ marginLeft: '24px' }}>
|
||||||
|
{pageTitle}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Box sx={{ px: '28px' }}>
|
||||||
|
<FormProvider methods={methods} onSubmit={handleSubmit(submitHandler)}>
|
||||||
|
<Card sx={{ padding: '24px' }}>
|
||||||
|
<Grid container spacing={6}>
|
||||||
|
{/* MSC row */}
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Grid container spacing={2}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="body1" component="div" color={'GrayText'}>
|
||||||
|
MSC* :
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<RHFCustomMultiCheckbox name="msc" options={msc_checkbox_option} sx={{ flexDirection: 'row' }} />
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Gender row */}
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Grid container spacing={2}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="body1" component="div" color={'GrayText'}>
|
||||||
|
Gender* :
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<RHFCustomMultiCheckbox name="gender" options={gender_checkbox_option} sx={{ flexDirection: 'row' }} />
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Age row */}
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Grid container spacing={3}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="body1" component="div" color={'GrayText'}>
|
||||||
|
Age* :
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} sx={{display: 'flex', gap: 1}}>
|
||||||
|
<Grid container spacing={2}>
|
||||||
|
<Grid item xs={3} md={3}>
|
||||||
|
<RHFTextField
|
||||||
|
id="min_age"
|
||||||
|
name='min_age'
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={3} md={3}>
|
||||||
|
<RHFTextField
|
||||||
|
id="max_age"
|
||||||
|
name='max_age'
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Plan Section */}
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Grid container spacing={3}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="body1" component="div" color={'GrayText'}>
|
||||||
|
Plan* :
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} sx={{display: 'flex', gap: 1}}>
|
||||||
|
<Autocomplete
|
||||||
|
options={plans}
|
||||||
|
fullWidth
|
||||||
|
multiple
|
||||||
|
limitTags={5}
|
||||||
|
getOptionLabel={(option) => {
|
||||||
|
return option ?? false
|
||||||
|
}}
|
||||||
|
value={formValues.plans}
|
||||||
|
isOptionEqualToValue={(option, value) =>{
|
||||||
|
return option === value
|
||||||
|
}}
|
||||||
|
renderInput={(params) => (
|
||||||
|
<TextField {...params} label="Plan" variant="outlined" />
|
||||||
|
)}
|
||||||
|
onChange={(event,value) => {
|
||||||
|
setValue('plans', value, {shouldDirty: true});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Button Cancle & Save */}
|
||||||
|
<Grid item xs={12} md={12}>
|
||||||
|
<Box display="flex" justifyContent={'flex-end'}>
|
||||||
|
<Box display="flex" gap={1}>
|
||||||
|
<Button variant="outlined" color="inherit" onClick={() => navigate(`/corporates/${corporate_id}/diagnosis-exclusions`)}>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<LoadingButton disabled={!isDirty} type="submit" variant="contained" loading={isSubmitting}>
|
||||||
|
Save Changes
|
||||||
|
</LoadingButton>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Card>
|
||||||
|
</FormProvider>
|
||||||
|
</Box>
|
||||||
|
</Page>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -476,22 +476,36 @@ export default function List(props: any) {
|
|||||||
active: row.active == 1 ? 0 : 1,
|
active: row.active == 1 ? 0 : 1,
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
// setDataTableData({
|
setDataTableData({
|
||||||
// ...dataTableData,
|
...dataTableData,
|
||||||
// data: dataTableData.data.map((model) => {
|
data: dataTableData.data.map((model) => {
|
||||||
// let updatedModel = model;
|
let updatedModel = model;
|
||||||
// if (row.id == model.id) {
|
|
||||||
// updatedModel.active = res.data.corporate.active;
|
if (model.id == row.id) {
|
||||||
// }
|
updatedModel.active = row.active == 1 ? 0 : 1;
|
||||||
// return updatedModel;
|
}
|
||||||
// }),
|
|
||||||
// });
|
return updatedModel;
|
||||||
|
}),
|
||||||
|
});
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
enqueueSnackbar(
|
if (error.response.status == 400) {
|
||||||
error.response.data.message ?? error.message ?? 'Failed Processing Request',
|
let data = error.response.data.messages;
|
||||||
{ variant: 'error' }
|
|
||||||
);
|
for (const key in data) {
|
||||||
|
enqueueSnackbar(
|
||||||
|
data[key][0],
|
||||||
|
{ variant: 'error' }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
enqueueSnackbar(
|
||||||
|
error.response.data.message ?? error.message ?? 'Failed Processing Request',
|
||||||
|
{ variant: 'error' }
|
||||||
|
);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -539,7 +553,7 @@ export default function List(props: any) {
|
|||||||
<FindInPageOutlined />
|
<FindInPageOutlined />
|
||||||
Detail
|
Detail
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem onClick={() => navigate(`/corporates/${corporate_id}/diagnosis-exclusions/history`)} >
|
<MenuItem onClick={() => navigate(`/corporates/${corporate_id}/diagnosis-exclusions/${row.id}/edit`)} >
|
||||||
<EditOutlined />
|
<EditOutlined />
|
||||||
Edit
|
Edit
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
@@ -630,222 +644,6 @@ export default function List(props: any) {
|
|||||||
</Card>
|
</Card>
|
||||||
</Box>
|
</Box>
|
||||||
) : null }
|
) : null }
|
||||||
{/* {open == true ? (
|
|
||||||
openEdit == false ? (
|
|
||||||
<Box sx={{ borderBottom: 1 }}>
|
|
||||||
<div>
|
|
||||||
<Typography variant="body" sx={{ fontWeight: 'bold' }}>
|
|
||||||
Excluded Only for :
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
{row.rules.msc && (
|
|
||||||
<Typography variant="body" component="div">
|
|
||||||
MSC : {row.rules.msc.join(', ') ?? '-'}
|
|
||||||
</Typography>
|
|
||||||
)}
|
|
||||||
{row.rules.gender && (
|
|
||||||
<Typography variant="body" component="div">
|
|
||||||
Gender : {row.rules.gender.join(', ') ?? '-'}
|
|
||||||
</Typography>
|
|
||||||
)}
|
|
||||||
{(row.rules.min_age || row.rules.max_age) && (
|
|
||||||
<Typography variant="body" component="div">
|
|
||||||
Age : {row.rules.min_age ?? '-'} - {row.rules.max_age ?? '-'}
|
|
||||||
</Typography>
|
|
||||||
)}
|
|
||||||
{row.rules.plan && (
|
|
||||||
<Typography variant="body" component="div">
|
|
||||||
Plan : {row.rules.plan.join(', ') ?? '-'}
|
|
||||||
</Typography>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</Box>
|
|
||||||
) : (
|
|
||||||
// <CollapseEdit row={row} index={index} plans={plans} />
|
|
||||||
<Box sx={{ borderBottom: 1, pb: 2 }}>
|
|
||||||
<Typography variant="body2" sx={{ fontWeight: 'bold', mb: 2 }}>
|
|
||||||
Edit Exclusion :
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
<Stack direction={'column'} spacing={2}>
|
|
||||||
<FormControl fullWidth>
|
|
||||||
<Grid container spacing={2}>
|
|
||||||
<Grid item xs={2} md={2}>
|
|
||||||
<Typography id="demo-simple-select-label">MSC</Typography>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<Grid item xs={10} md={10}>
|
|
||||||
<Stack direction={'row'} spacing={2}>
|
|
||||||
<Grid item xs={3} md={3}>
|
|
||||||
<FormControlLabel
|
|
||||||
control={
|
|
||||||
<Checkbox
|
|
||||||
checked={row.value_rules.msc?.m == '1'}
|
|
||||||
onChange={(event) => {
|
|
||||||
// handleConfigExclusion(event, row, 'm', 'msc');
|
|
||||||
handleChange(index, event, 'msc', row.id, 'm');
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label="Member"
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={3} md={3}>
|
|
||||||
<FormControlLabel
|
|
||||||
control={
|
|
||||||
<Checkbox
|
|
||||||
checked={row.value_rules.msc?.s == '1'}
|
|
||||||
onChange={(event) => {
|
|
||||||
// handleConfigExclusion(event, row, 's', 'msc');
|
|
||||||
handleChange(index, event, 'msc', row.id, 's');
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label="Spouse"
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={3} md={3}>
|
|
||||||
<FormControlLabel
|
|
||||||
control={
|
|
||||||
<Checkbox
|
|
||||||
checked={row.value_rules.msc?.c == '1'}
|
|
||||||
onChange={(event) => {
|
|
||||||
// handleConfigExclusion(event, row, 'c', 'msc');
|
|
||||||
handleChange(index, event, 'msc', row.id, 'c');
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label="Child"
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
</Stack>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormControl fullWidth>
|
|
||||||
<Grid container spacing={2}>
|
|
||||||
<Grid item xs={2} md={2}>
|
|
||||||
<Typography id="demo-simple-select-label">Gender</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={10} md={10}>
|
|
||||||
<Stack direction={'row'} spacing={2}>
|
|
||||||
<Grid item xs={3} md={3}>
|
|
||||||
<FormControlLabel
|
|
||||||
control={
|
|
||||||
<Checkbox
|
|
||||||
checked={row.value_rules.gender?.male == '1'}
|
|
||||||
onChange={(event) => {
|
|
||||||
// handleConfigExclusion(event, row, 'male', 'gender');
|
|
||||||
handleChange(index, event, 'gender', row.id, 'male');
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label="Male"
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={3} md={3}>
|
|
||||||
<FormControlLabel
|
|
||||||
control={
|
|
||||||
<Checkbox
|
|
||||||
checked={row.value_rules.gender?.female == '1'}
|
|
||||||
onChange={(event) => {
|
|
||||||
// handleConfigExclusion(event, row, 'female', 'gender');
|
|
||||||
handleChange(index, event, 'gender', row.id, 'female');
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label="Female"
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
</Stack>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</FormControl>
|
|
||||||
<FormControl fullWidth>
|
|
||||||
<Grid container spacing={2}>
|
|
||||||
<Grid item xs={2} md={2}>
|
|
||||||
<Typography id="demo-simple-select-label">Age</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={10} md={10}>
|
|
||||||
<Stack direction={'row'} spacing={2}>
|
|
||||||
<Grid item xs={3} md={3}>
|
|
||||||
<TextField
|
|
||||||
id="outlined-number"
|
|
||||||
type="number"
|
|
||||||
defaultValue={row.value_rules.min_age ?? ''}
|
|
||||||
onChange={(event) => {
|
|
||||||
handleMinAge(event);
|
|
||||||
handleChange(index, event, 'min_age', row.id);
|
|
||||||
}}
|
|
||||||
onKeyDown={(event) => {
|
|
||||||
if (event.key === 'Enter') {
|
|
||||||
handleConfigExclusion(event, row, minAge, 'min_age');
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={3} md={3}>
|
|
||||||
<TextField
|
|
||||||
id="outlined-number"
|
|
||||||
type="number"
|
|
||||||
defaultValue={row.value_rules.max_age ?? ''}
|
|
||||||
onChange={(event) => {
|
|
||||||
handleMaxAge(event);
|
|
||||||
handleChange(index, event, 'max_age', row.id);
|
|
||||||
}}
|
|
||||||
onKeyDown={(event) => {
|
|
||||||
if (event.key === 'Enter') {
|
|
||||||
handleConfigExclusion(event, row, maxAge, 'max_age');
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
</Stack>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</FormControl>
|
|
||||||
<FormControl fullWidth>
|
|
||||||
<Grid container spacing={2}>
|
|
||||||
<Grid item xs={2} md={2}>
|
|
||||||
<Typography id="demo-simple-select-label">Plan</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={10} md={10}>
|
|
||||||
<Stack direction={'row'} spacing={2}>
|
|
||||||
<Grid item xs={12} md={12}>
|
|
||||||
<Autocomplete
|
|
||||||
id="combo-box-demo"
|
|
||||||
options={plans}
|
|
||||||
multiple
|
|
||||||
limitTags={5}
|
|
||||||
fullWidth
|
|
||||||
getOptionLabel={(option) => option.label}
|
|
||||||
defaultValue={converToArray(row.value_rules.plan) || []}
|
|
||||||
isOptionEqualToValue={(option, value) =>
|
|
||||||
option.value === value.value
|
|
||||||
}
|
|
||||||
onChange={(event, value) => {
|
|
||||||
handlePlanChange(event, value);
|
|
||||||
handleChange(index, event, 'plan', row.id, value);
|
|
||||||
}}
|
|
||||||
onKeyDown={(event) => {
|
|
||||||
if (event.key === 'Enter') {
|
|
||||||
handleConfigExclusion(event, row, valuePlan, 'plan');
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
renderInput={(params) => (
|
|
||||||
<TextField {...params} label="Plan" variant="outlined" />
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
</Stack>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</FormControl>
|
|
||||||
</Stack>
|
|
||||||
</Box>
|
|
||||||
)
|
|
||||||
) : null} */}
|
|
||||||
</Collapse>
|
</Collapse>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
|
|||||||
@@ -14,19 +14,28 @@ export default function CorporateHospitalForm({ isEdit }: Props) {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { corporate_id, id, organization_id } = useParams();
|
const { corporate_id, id, organization_id } = useParams();
|
||||||
const [dataHospital, setDataHospital] = useState(null);
|
const [dataHospital, setDataHospital] = useState(null);
|
||||||
const [addData, setAddData] = useState(null);
|
|
||||||
let idHospital = organization_id && isEdit ? organization_id : 0;
|
let idHospital = organization_id && isEdit ? organization_id : 0;
|
||||||
const [indexData, setIndexData] = useState(idHospital);
|
const [indexData, setIndexData] = useState(idHospital);
|
||||||
const [updateData, setUpdateData] = useState(null);
|
const [updateData, setUpdateData] = useState(null);
|
||||||
|
const [dataDefault, setDataDefault] = useState(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
axios.get('/corporates/' + corporate_id + '/hospitals/data')
|
axios.get('/corporates/' + corporate_id + '/hospitals/data')
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
setDataHospital(res.data);
|
setDataHospital(res.data);
|
||||||
|
const data = {
|
||||||
|
corporate_id : corporate_id ? corporate_id : null,
|
||||||
|
organization_id : res.data[0] ? res.data[0].id : null,
|
||||||
|
code : res.data[0] ? res.data[0].code : null,
|
||||||
|
name : res.data[0] ? res.data[0].name : null,
|
||||||
|
}
|
||||||
|
setDataDefault(data);
|
||||||
})
|
})
|
||||||
|
|
||||||
}, [isEdit]);
|
}, [isEdit]);
|
||||||
|
|
||||||
|
const [addData, setAddData] = useState(dataDefault);
|
||||||
|
|
||||||
const handlePageChange = (index:any) => {
|
const handlePageChange = (index:any) => {
|
||||||
setIndexData(index);
|
setIndexData(index);
|
||||||
const data = {
|
const data = {
|
||||||
@@ -36,11 +45,12 @@ export default function CorporateHospitalForm({ isEdit }: Props) {
|
|||||||
name : dataHospital ? dataHospital[index].name : null,
|
name : dataHospital ? dataHospital[index].name : null,
|
||||||
}
|
}
|
||||||
setAddData(data);
|
setAddData(data);
|
||||||
|
|
||||||
}
|
}
|
||||||
const handleSaveData = () => {
|
const handleSaveData = () => {
|
||||||
//Save data
|
//Save data
|
||||||
axios
|
axios
|
||||||
.post('/corporates/'+corporate_id+'/hospitals/save', addData)
|
.post('/corporates/'+corporate_id+'/hospitals/save', (addData ? addData : dataDefault))
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if(response.data)
|
if(response.data)
|
||||||
{
|
{
|
||||||
|
|||||||
158
frontend/dashboard/src/pages/Corporates/Hospital/History.tsx
Normal file
158
frontend/dashboard/src/pages/Corporates/Hospital/History.tsx
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
|
import HeaderBreadcrumbs from "../../../components/HeaderBreadcrumbs";
|
||||||
|
import Page from "../../../components/Page";
|
||||||
|
import { useContext, useEffect, useState } from 'react';
|
||||||
|
import { Hospital } from '../../../@types/corporates';
|
||||||
|
import { Corporate } from "@/@types/corporates";
|
||||||
|
import { ConfiguredCorporateContext } from "@/contexts/ConfiguredCorporateContext";
|
||||||
|
import {
|
||||||
|
Stack,
|
||||||
|
Typography,
|
||||||
|
Card,
|
||||||
|
Paper,
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableContainer,
|
||||||
|
TableHead,
|
||||||
|
TableRow,
|
||||||
|
Collapse,
|
||||||
|
Box,
|
||||||
|
Tab,
|
||||||
|
} from '@mui/material';
|
||||||
|
import axios from '@/utils/axios';
|
||||||
|
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
|
||||||
|
import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
|
||||||
|
import { fDate, fDateTime } from '@/utils/formatTime';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default function HospitalHistory() {
|
||||||
|
const { corporate_id, id } = useParams();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const [corporate, setCorporate] = useState<Corporate|null>();
|
||||||
|
|
||||||
|
const [ currentHospital, setCurrentHospital ] = useState<Hospital>();
|
||||||
|
|
||||||
|
const configuredCorporateContext = useContext(ConfiguredCorporateContext);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setCorporate(configuredCorporateContext.currentCorporate);
|
||||||
|
const model = 'App\\Models\\CorporateHospital';
|
||||||
|
const url = `/audittrail/${id}?model=${model}`;
|
||||||
|
axios.get(url)
|
||||||
|
.then((res) => {
|
||||||
|
setCurrentHospital(res.data);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Terjadi kesalahan:', error);
|
||||||
|
});
|
||||||
|
}, [corporate_id, id, configuredCorporateContext]);
|
||||||
|
|
||||||
|
const [openRows, setOpenRows] = useState({});
|
||||||
|
|
||||||
|
const handleRowToggle = (index) => {
|
||||||
|
setOpenRows((prevOpenRows) => ({
|
||||||
|
...prevOpenRows,
|
||||||
|
[index]: !prevOpenRows[index],
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Page title="History Hospital">
|
||||||
|
<HeaderBreadcrumbs
|
||||||
|
heading={'History Hospital'}
|
||||||
|
links={[
|
||||||
|
{
|
||||||
|
name: 'Corporates',
|
||||||
|
href: '/corporates',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: corporate?.name ?? '-',
|
||||||
|
href: '/corporates/'+corporate_id,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Hospital',
|
||||||
|
href: '/corporates/'+corporate_id+'/hospitals',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'History',
|
||||||
|
href: '/corporates/'+corporate_id+'/hospitals/history',
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
<Card>
|
||||||
|
<TableContainer component={Paper}>
|
||||||
|
<Table aria-label="collapsible table">
|
||||||
|
{/* Condition Table Body */}
|
||||||
|
{currentHospital?.data.map((item, index) => (
|
||||||
|
<TableBody key={index}>
|
||||||
|
<TableRow sx={{backgroundColor: '#919EAB29'}}>
|
||||||
|
<TableCell align="left" sx={{fontWeight: 'bold', width: '95%'}}><Typography variant="subtitle1">Data has {item.action} by {item.user_id} on {fDateTime(item.updated_at)}</Typography></TableCell>
|
||||||
|
<TableCell align="left" sx={{width: '5%'}}>
|
||||||
|
{openRows[index] ? (
|
||||||
|
<KeyboardArrowDownIcon sx={{ cursor: 'pointer' }} onClick={() => handleRowToggle(index)} />
|
||||||
|
) : (
|
||||||
|
<KeyboardArrowRightIcon sx={{ cursor: 'pointer' }} onClick={() => handleRowToggle(index)} />
|
||||||
|
)}
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
<TableRow sx={{display: openRows[index] ? '' : 'none',}}>
|
||||||
|
<TableCell colSpan={2}>
|
||||||
|
{/* COLLAPSIBLE ROW */}
|
||||||
|
<Collapse in={openRows[index]} timeout="auto" unmountOnExit>
|
||||||
|
<TableContainer component={Paper}>
|
||||||
|
<Table aria-label="collapsible table">
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell align="left">
|
||||||
|
<Typography sx={{width: '25%'}} variant="subtitle2">Field</Typography>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="left">
|
||||||
|
<Typography sx={{width: '25%'}} variant="subtitle2">Old Value</Typography>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="left">
|
||||||
|
<Typography sx={{width: '50%'}} variant="subtitle2">New Value</Typography>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
{Object.entries(item.old_values).map(([key, value]) => {
|
||||||
|
let renderedValue;
|
||||||
|
if (key === 'code' || key === 'name') {
|
||||||
|
renderedValue = item.new_values[key];
|
||||||
|
const field = key.charAt(0).toUpperCase() + key.slice(1);
|
||||||
|
return (
|
||||||
|
<TableRow key={key}>
|
||||||
|
<TableCell align="left">
|
||||||
|
<Typography variant="body2">{field ? field : '-'}</Typography>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="left">
|
||||||
|
<Typography variant="body2">{value ? value : '-'}</Typography>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="left">
|
||||||
|
<Typography variant="body2">{renderedValue ? renderedValue : ''}</Typography>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
</Collapse>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableBody>
|
||||||
|
))}
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
</Card>
|
||||||
|
</Page>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -96,10 +96,10 @@ export default function PlanList() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<TableRow>
|
<TableRow sx={{ '& > *': open ? {borderBottom: 'unset'} : {}, cursor: open ? 'pointer' : '' }} onClick={() => {if(open==true) setOpen(!open)}}>
|
||||||
<TableCell align="center">{row.code ? row.code : '-'}</TableCell>
|
<TableCell align="left">{row.code ? row.code : '-'}</TableCell>
|
||||||
<TableCell align="left">{row.name ? row.name : '-'}</TableCell>
|
<TableCell align="left">{row.name ? row.name : '-'}</TableCell>
|
||||||
<TableCell align="center">
|
<TableCell align="left">
|
||||||
{row.active === 1 ? (
|
{row.active === 1 ? (
|
||||||
<Label color='success' >
|
<Label color='success' >
|
||||||
Active
|
Active
|
||||||
@@ -110,7 +110,7 @@ export default function PlanList() {
|
|||||||
</Label>
|
</Label>
|
||||||
)}
|
)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell align="center">
|
<TableCell align="left">
|
||||||
<TableMoreMenu actions={
|
<TableMoreMenu actions={
|
||||||
<>
|
<>
|
||||||
<MenuItem onClick={() => setOpen(!open)}>
|
<MenuItem onClick={() => setOpen(!open)}>
|
||||||
@@ -125,7 +125,7 @@ export default function PlanList() {
|
|||||||
<CachedOutlinedIcon />
|
<CachedOutlinedIcon />
|
||||||
Update Status
|
Update Status
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem onClick={() => navigate ('')}>
|
<MenuItem onClick={() => navigate ('/corporates/'+corporate_id+'/hospitals/'+row.id+'/history')}>
|
||||||
<HistoryIcon />
|
<HistoryIcon />
|
||||||
History
|
History
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
@@ -135,8 +135,8 @@ export default function PlanList() {
|
|||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
{/* COLLAPSIBLE ROW */}
|
{/* COLLAPSIBLE ROW */}
|
||||||
<TableRow sx={{display: open ? '' : 'none',}}>
|
<TableRow sx={{display: open ? '' : 'none', cursor: open ? 'pointer' : ''}} onClick={() => {if(open==true) setOpen(!open)}}>
|
||||||
<TableCell colSpan={4 }>
|
<TableCell colSpan={4}>
|
||||||
<Collapse in={open} timeout="auto" unmountOnExit>
|
<Collapse in={open} timeout="auto" unmountOnExit>
|
||||||
<Card sx={{padding:2}}>
|
<Card sx={{padding:2}}>
|
||||||
<Box sx={{ pb: 2 }}>
|
<Box sx={{ pb: 2 }}>
|
||||||
@@ -290,16 +290,16 @@ export default function PlanList() {
|
|||||||
{/* Table Head */}
|
{/* Table Head */}
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell sx={{width: '20%'}} align="center">
|
<TableCell sx={{width: '20%'}} align="left">
|
||||||
<Typography variant='subtitle2'>Code</Typography>
|
<Typography variant='subtitle2'>Code</Typography>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell sx={{width: '50%'}} align="left">
|
<TableCell sx={{width: '50%'}} align="left">
|
||||||
<Typography variant='subtitle2'>Hospital</Typography>
|
<Typography variant='subtitle2'>Hospital</Typography>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell sx={{width: '20%'}} align="center">
|
<TableCell sx={{width: '20%'}} align="left">
|
||||||
<Typography variant='subtitle2'>Status</Typography>
|
<Typography variant='subtitle2'>Status</Typography>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell sx={{width: '10%'}} align="center">
|
<TableCell sx={{width: '10%'}} align="left">
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
|
|||||||
166
frontend/dashboard/src/pages/Corporates/Member/History.tsx
Normal file
166
frontend/dashboard/src/pages/Corporates/Member/History.tsx
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
|
import HeaderBreadcrumbs from "../../../components/HeaderBreadcrumbs";
|
||||||
|
import Page from "../../../components/Page";
|
||||||
|
import { useContext, useEffect, useState } from 'react';
|
||||||
|
import { Member } from '../../../@types/corporates';
|
||||||
|
import { Corporate } from "@/@types/corporates";
|
||||||
|
import { ConfiguredCorporateContext } from "@/contexts/ConfiguredCorporateContext";
|
||||||
|
import {
|
||||||
|
Stack,
|
||||||
|
Typography,
|
||||||
|
Card,
|
||||||
|
Paper,
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableContainer,
|
||||||
|
TableHead,
|
||||||
|
TableRow,
|
||||||
|
Collapse,
|
||||||
|
Box,
|
||||||
|
Tab,
|
||||||
|
} from '@mui/material';
|
||||||
|
import axios from '@/utils/axios';
|
||||||
|
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
|
||||||
|
import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
|
||||||
|
import { fDate, fDateTime } from '@/utils/formatTime';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default function MemberHistory() {
|
||||||
|
const { corporate_id, member_id } = useParams();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const [corporate, setCorporate] = useState<Corporate|null>();
|
||||||
|
|
||||||
|
const [ currentMember, setCurrentMember ] = useState<Member>();
|
||||||
|
|
||||||
|
const configuredCorporateContext = useContext(ConfiguredCorporateContext);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setCorporate(configuredCorporateContext.currentCorporate);
|
||||||
|
const model = 'App\\Models\\Member';
|
||||||
|
const url = `/audittrail/${member_id}?model=${model}`;
|
||||||
|
axios.get(url)
|
||||||
|
.then((res) => {
|
||||||
|
setCurrentMember(res.data);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Terjadi kesalahan:', error);
|
||||||
|
});
|
||||||
|
}, [corporate_id, member_id, configuredCorporateContext]);
|
||||||
|
|
||||||
|
const [openRows, setOpenRows] = useState({});
|
||||||
|
|
||||||
|
const handleRowToggle = (index) => {
|
||||||
|
setOpenRows((prevOpenRows) => ({
|
||||||
|
...prevOpenRows,
|
||||||
|
[index]: !prevOpenRows[index],
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Page title="History Member">
|
||||||
|
<HeaderBreadcrumbs
|
||||||
|
heading={'History Member'}
|
||||||
|
links={[
|
||||||
|
{
|
||||||
|
name: 'Corporates',
|
||||||
|
href: '/corporates',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: corporate?.name ?? '-',
|
||||||
|
href: '/corporates/'+corporate_id,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Member',
|
||||||
|
href: '/corporates/'+corporate_id+'/members',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'History',
|
||||||
|
href: '/corporates/'+corporate_id+'/members/history',
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
<Card>
|
||||||
|
<TableContainer component={Paper}>
|
||||||
|
<Table aria-label="collapsible table">
|
||||||
|
{/* Condition Table Body */}
|
||||||
|
{currentMember?.data.map((item, index) => (
|
||||||
|
<TableBody key={index}>
|
||||||
|
<TableRow sx={{backgroundColor: '#919EAB29'}}>
|
||||||
|
<TableCell align="left" sx={{fontWeight: 'bold', width: '95%'}}><Typography variant="subtitle1">Data has {item.action} by {item.user_id} on {fDateTime(item.updated_at)}</Typography></TableCell>
|
||||||
|
<TableCell align="left" sx={{width: '5%'}}>
|
||||||
|
{openRows[index] ? (
|
||||||
|
<KeyboardArrowDownIcon sx={{ cursor: 'pointer' }} onClick={() => handleRowToggle(index)} />
|
||||||
|
) : (
|
||||||
|
<KeyboardArrowRightIcon sx={{ cursor: 'pointer' }} onClick={() => handleRowToggle(index)} />
|
||||||
|
)}
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
<TableRow sx={{display: openRows[index] ? '' : 'none',}}>
|
||||||
|
<TableCell colSpan={2}>
|
||||||
|
{/* COLLAPSIBLE ROW */}
|
||||||
|
<Collapse in={openRows[index]} timeout="auto" unmountOnExit>
|
||||||
|
<TableContainer component={Paper}>
|
||||||
|
<Table aria-label="collapsible table">
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell align="left">
|
||||||
|
<Typography sx={{width: '25%'}} variant="subtitle2">Field</Typography>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="left">
|
||||||
|
<Typography sx={{width: '25%'}} variant="subtitle2">Old Value</Typography>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="left">
|
||||||
|
<Typography sx={{width: '50%'}} variant="subtitle2">New Value</Typography>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
{Object.entries(item.old_values).map(([key, value]) => {
|
||||||
|
let renderedValue;
|
||||||
|
if (key === 'reason' || key === 'updated_at') {
|
||||||
|
switch (key) {
|
||||||
|
case 'updated_at':
|
||||||
|
renderedValue = fDateTime(item.new_values[key]);
|
||||||
|
value = fDateTime(value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
renderedValue = item.new_values[key];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const field = key.charAt(0).toUpperCase() + key.slice(1);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TableRow key={key}>
|
||||||
|
<TableCell align="left">
|
||||||
|
<Typography variant="body2">{field ? field : '-'}</Typography>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="left">
|
||||||
|
<Typography variant="body2">{value ? value : '-'}</Typography>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="left">
|
||||||
|
<Typography variant="body2">{renderedValue ? renderedValue : ''}</Typography>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
</Collapse>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableBody>
|
||||||
|
))}
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
</Card>
|
||||||
|
</Page>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -424,7 +424,7 @@ export default function CorporatePlanList({handleSubmitSuccess}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const [columns, setColumns] = React.useState([
|
const [columns, setColumns] = React.useState([
|
||||||
{ id: 'member_id', label: 'Member ID', minWidth: 100, align: 'center', width: '10%' },
|
{ id: 'member_id', label: 'Member ID', minWidth: 100, align: 'left', width: '10%' },
|
||||||
{ id: 'effective_date', label: 'Effective Date', minWidth: 100, align: 'left', width: '20%' },
|
{ id: 'effective_date', label: 'Effective Date', minWidth: 100, align: 'left', width: '20%' },
|
||||||
{ id: 'name', label: 'Name', minWidth: 100, align: 'left', width: '20%' },
|
{ id: 'name', label: 'Name', minWidth: 100, align: 'left', width: '20%' },
|
||||||
{ id: 'plan_id', label: 'Plan ID', minWidth: 100, align: 'left', width: '10%' },
|
{ id: 'plan_id', label: 'Plan ID', minWidth: 100, align: 'left', width: '10%' },
|
||||||
@@ -470,8 +470,8 @@ export default function CorporatePlanList({handleSubmitSuccess}) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<TableRow key={row.id || index}>
|
<TableRow key={row.id || index} sx={{ '& > *': open ? {borderBottom: 'unset'} : {}, cursor: open ? 'pointer' : '' }} onClick={() => {if(open==true) setOpen(!open)}}>
|
||||||
<TableCell align="center">
|
<TableCell align="left">
|
||||||
<Typography variant='body2'>{row.member_id ? row.member_id : '-'}</Typography>
|
<Typography variant='body2'>{row.member_id ? row.member_id : '-'}</Typography>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell align="left">
|
<TableCell align="left">
|
||||||
@@ -489,7 +489,7 @@ export default function CorporatePlanList({handleSubmitSuccess}) {
|
|||||||
<TableCell align="left">
|
<TableCell align="left">
|
||||||
<Typography variant='body2'>{row.terminated_date ? row.terminated_date : '-'}</Typography>
|
<Typography variant='body2'>{row.terminated_date ? row.terminated_date : '-'}</Typography>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell align='center'>
|
<TableCell align='left'>
|
||||||
<TableMoreMenu actions={
|
<TableMoreMenu actions={
|
||||||
<>
|
<>
|
||||||
<MenuItem onClick={() => setOpen(!open)}>
|
<MenuItem onClick={() => setOpen(!open)}>
|
||||||
@@ -500,7 +500,7 @@ export default function CorporatePlanList({handleSubmitSuccess}) {
|
|||||||
<CachedOutlinedIcon />
|
<CachedOutlinedIcon />
|
||||||
Update Status
|
Update Status
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem onClick={() => navigate ('')}>
|
<MenuItem onClick={() => navigate ('/corporates/'+corporate_id+'/members/'+row.id+'/history')}>
|
||||||
<HistoryIcon />
|
<HistoryIcon />
|
||||||
History
|
History
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
@@ -510,7 +510,7 @@ export default function CorporatePlanList({handleSubmitSuccess}) {
|
|||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
{/* COLLAPSIBLE ROW */}
|
{/* COLLAPSIBLE ROW */}
|
||||||
<TableRow sx={{display: open ? '' : 'none',}}>
|
<TableRow sx={{display: open ? '' : 'none', cursor: open ? 'pointer' : ''}} onClick={() => {if(open==true) setOpen(!open)}}>
|
||||||
<TableCell colSpan={8}>
|
<TableCell colSpan={8}>
|
||||||
<Collapse in={open} timeout="auto" unmountOnExit>
|
<Collapse in={open} timeout="auto" unmountOnExit>
|
||||||
<Card sx={{padding:2}}>
|
<Card sx={{padding:2}}>
|
||||||
|
|||||||
@@ -169,6 +169,10 @@ export default function Router() {
|
|||||||
path: ':corporate_id/diagnosis-exclusions',
|
path: ':corporate_id/diagnosis-exclusions',
|
||||||
element: <DiagnosisExclusions />,
|
element: <DiagnosisExclusions />,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: ':corporate_id/diagnosis-exclusions/:exclusion_id/edit',
|
||||||
|
element: <EditDiagnosisExclusions />,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: ':corporate_id/diagnosis-exclusions/history',
|
path: ':corporate_id/diagnosis-exclusions/history',
|
||||||
element: <DiagnosisExclusionsHistory />,
|
element: <DiagnosisExclusionsHistory />,
|
||||||
@@ -186,6 +190,10 @@ export default function Router() {
|
|||||||
path: ':corporate_id/hospitals/edit/:id/:organization_id',
|
path: ':corporate_id/hospitals/edit/:id/:organization_id',
|
||||||
element: <HospitalCreateUpdate />,
|
element: <HospitalCreateUpdate />,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: ':corporate_id/hospitals/:id/history',
|
||||||
|
element: <HospitalHistory />,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: ':corporate_id/claim-history',
|
path: ':corporate_id/claim-history',
|
||||||
element: <CorporateClaimHistories />,
|
element: <CorporateClaimHistories />,
|
||||||
@@ -437,7 +445,7 @@ const CorporateDivisionsCreate = Loadable(
|
|||||||
);
|
);
|
||||||
|
|
||||||
const CorporateMembers = Loadable(lazy(() => import('../pages/Corporates/Member/Index')));
|
const CorporateMembers = Loadable(lazy(() => import('../pages/Corporates/Member/Index')));
|
||||||
const CorporateHistoryMembers = Loadable(lazy(() => import('../pages/Corporates/Member/sections/History')));
|
const CorporateHistoryMembers = Loadable(lazy(() => import('../pages/Corporates/Member/History')));
|
||||||
|
|
||||||
const BenefitCreate = Loadable(lazy(() => import('../pages/Corporates/Benefit/Create')));
|
const BenefitCreate = Loadable(lazy(() => import('../pages/Corporates/Benefit/Create')));
|
||||||
const Benefits = Loadable(lazy(() => import('../pages/Corporates/Benefit/Index')));
|
const Benefits = Loadable(lazy(() => import('../pages/Corporates/Benefit/Index')));
|
||||||
@@ -467,6 +475,9 @@ const CorporatePlansHistory = Loadable(lazy(() => import('../pages/Corporates/Pl
|
|||||||
const DiagnosisExclusions = Loadable(
|
const DiagnosisExclusions = Loadable(
|
||||||
lazy(() => import('../pages/Corporates/DiagnosisExclusion/Index'))
|
lazy(() => import('../pages/Corporates/DiagnosisExclusion/Index'))
|
||||||
);
|
);
|
||||||
|
const EditDiagnosisExclusions = Loadable(
|
||||||
|
lazy(() => import('../pages/Corporates/DiagnosisExclusion/Edit'))
|
||||||
|
);
|
||||||
const DiagnosisExclusionsHistory = Loadable(
|
const DiagnosisExclusionsHistory = Loadable(
|
||||||
lazy(() => import('../pages/Corporates/DiagnosisExclusion/History'))
|
lazy(() => import('../pages/Corporates/DiagnosisExclusion/History'))
|
||||||
);
|
);
|
||||||
@@ -516,6 +527,7 @@ const HospitalCreateUpdate = Loadable(lazy(() => import('../pages/Corporates/Hos
|
|||||||
const CorporateClaimHistories = Loadable(
|
const CorporateClaimHistories = Loadable(
|
||||||
lazy(() => import('../pages/Corporates/ClaimHistory/Index'))
|
lazy(() => import('../pages/Corporates/ClaimHistory/Index'))
|
||||||
);
|
);
|
||||||
|
const HospitalHistory = Loadable(lazy(() => import('../pages/Corporates/Hospital/History')));
|
||||||
|
|
||||||
const CorporateHistories = Loadable(
|
const CorporateHistories = Loadable(
|
||||||
lazy(() => import('../pages/Corporates/History'))
|
lazy(() => import('../pages/Corporates/History'))
|
||||||
|
|||||||
Reference in New Issue
Block a user