bugs fix dan fitur submission di claim request

This commit is contained in:
2024-02-23 11:01:25 +07:00
parent a8dd5f866c
commit ccf7bee67a
11 changed files with 220 additions and 180 deletions

View File

@@ -133,10 +133,21 @@ class ClaimRequestController extends Controller
if ($request->hasFile('additional_files')) {
foreach ($request->additional_files as $file) {
$pathFile = File::storeFile('additional-files', $newClaimRequest->id, $file);
$newClaimRequest->files()->updateOrCreate([
$pathFile = File::storeFile('additional-files', $request->request_logs_id, $file);
// $newClaimRequest->files()->updateOrCreate([
// 'type' => 'additional-files',
// 'name' => File::getFileName('additional-files', $newClaimRequest->id, $file),
// 'original_name' => $file->getClientOriginalName(),
// 'extension' => $file->getClientOriginalExtension(),
// 'path' => $pathFile,
// 'created_by' => auth()->user()->id,
// 'updated_by' => auth()->user()->id,
// ]);
File::updateOrCreate([
'fileable_type' => 'App\Models\RequestLog',
'fileable_id' => $request->request_logs_id,
'type' => 'additional-files',
'name' => File::getFileName('additional-files', $newClaimRequest->id, $file),
'name' => File::getFileName('additional-files', $request->request_logs_id, $file),
'original_name' => $file->getClientOriginalName(),
'extension' => $file->getClientOriginalExtension(),
'path' => $pathFile,

View File

@@ -244,6 +244,7 @@ class RequestLogController extends Controller
$results = DB::table('request_logs')
->leftJoin('members', 'request_logs.member_id', '=', 'members.id')
->where('request_logs.deleted_at', null)
->when($request->input('search'), function ($query, $search) {
$query->where(function ($query) use ($search) {
$query->orWhere('request_logs.code', 'like', "%" . $search . "%")

View File

@@ -516,90 +516,6 @@ class ClaimRequestController extends Controller
public function claimRequestDetail($claimRequestId)
{
// $status = DB::table('claim_requests')
// ->leftJoin('claims', 'claim_requests.id', '=', 'claims.claim_request_id')
// ->leftJoin('members', 'claim_requests.member_id', '=', 'members.id')
// ->leftJoin('corporate_employees', 'members.id', '=', 'corporate_employees.member_id')
// ->leftJoin('corporate_divisions', 'corporate_employees.division_id', '=', 'corporate_divisions.id')
// ->where('claim_requests.id', '=', $claimRequestId)
// ->select(
// 'claim_requests.submission_date',
// 'claim_requests.code',
// DB::raw('
// CASE
// WHEN claim_requests.status = "requested" THEN "requested"
// WHEN claim_requests.status = "approved" AND claims.status = "approved" THEN "approved"
// WHEN claim_requests.status = "approved" AND claims.status = "declined" THEN "declined"
// WHEN claim_requests.status = "approved" AND claims.status = "disbrusmented" THEN "disbrusmented"
// /*WHEN claim_requests.status = "approved" AND claims.status = "received" THEN "pending"*/
// WHEN claim_requests.status = "approved" AND claims.status = "received" THEN "reviewed"
// ELSE ""
// END AS status
// ')
// )
// ->first();
// $results['status'] = $status;
// $timeline = DB::table('claim_logs')
// ->where('claim_logs.claim_request_id', '=', $claimRequestId)
// ->select(
// DB::raw('
// CASE
// WHEN claim_logs.status = "requested" THEN "Request"
// WHEN claim_logs.status = "reviewed" THEN "Review"
// WHEN claim_logs.status = "approved" THEN "Approval"
// WHEN claim_logs.status = "declined" THEN "Decline"
// ELSE "-"
// END AS txt_status
// '),
// DB::raw('
// CASE
// WHEN claim_logs.status = "requested" THEN "#159C9C"
// WHEN claim_logs.status = "reviewed" THEN "#0C53B7"
// WHEN claim_logs.status = "approved" THEN "#229A16"
// WHEN claim_logs.status = "declined" THEN "#FF4842"
// ELSE "-"
// END AS txt_status_color
// '),
// DB::raw('
// CASE
// WHEN claim_logs.status = "requested" THEN "#00AB5529"
// WHEN claim_logs.status = "reviewed" THEN "#1890FF29"
// WHEN claim_logs.status = "approved" THEN "#54D62C29"
// WHEN claim_logs.status = "declined" THEN "#FF48427A"
// ELSE "-"
// END AS txt_status_backgroundColor
// '),
// 'claim_logs.date',
// 'claim_logs.description',
// 'claim_logs.status'
// )
// ->orderBy('claim_logs.id', 'desc')
// ->get();
// $results['timeline'] = $timeline;
// $request_files = DB::table('claim_request_files')
// ->where('claim_request_files.claim_request_id', '=', $claimRequestId)
// ->select(
// 'claim_request_files.*',
// DB::raw('(SELECT files.fileable_id FROM files WHERE files.fileable_id = claim_request_files.claim_request_id AND files.type = claim_request_files.type LIMIT 1) AS check_files'),
// )
// ->get();
// $results['request_files'] = $request_files;
// $documents = DB::table('files')
// ->where('fileable_type', 'App\Models\ClaimRequest')
// ->where('fileable_id', $claimRequestId)
// ->select('original_name', \DB::raw("CONCAT('" . env('APP_URL') . "/storage/', path) as path"), 'type')
// ->orderBy('id', 'desc')
// ->get();
// $results['documents'] = $documents;
// $dialog_submits = DB::table('claim_requests')
// ->leftJoin('members', 'claim_requests.member_id','=', 'members.id')
// ->where('claim_requests.id', $claimRequestId)
// ->select('claim_requests.code', 'members.name', 'claim_requests.submission_date', 'claim_requests.service_code','claim_requests.status')
// ->first();
// $results['dialog_submits'] = $dialog_submits;
// return Helper::responseJson($results);
$claimRequest = ClaimRequest::findOrFail($claimRequestId);
$claimRequest->load([
'requestLog',
@@ -788,4 +704,22 @@ class ClaimRequestController extends Controller
return Helper::responseJson(data: $request->toArray(), message: 'Invoice Success Uploaded');
}
public function submition($id){
$claimRequest = ClaimRequest::findOrFail($id);
$claimRequest->status = 'submission';
$claimRequest->claim_management = 1;
$claimRequest->status_claim_management = 'received';
$claimRequest->submission_date_claim_management = date('Y-m-d H:i:s');
$claimRequest->submission_by_claim_management = auth()->user()->id;
$claimRequest->save();
return response()->json([
'error' => false,
'message' => 'Update succses',
'data' => $claimRequest],
200);
}
}

View File

@@ -311,6 +311,7 @@ Route::prefix('internal')->group(function () {
Route::get('claim-requests', [ClaimRequestController::class, 'index'])->name('claim-requests.index');
Route::get('claim-requests/list-member', [ClaimRequestController::class, 'getClaimMemberInfiniteScroll']); // Bagaskoro, BSD 31 Oktober 2023
Route::post('claim-requests/{id}/approve', [ClaimRequestController::class, 'approve'])->name('claim-requests.approve');
Route::post('claim-requests/{id}/submition', [ClaimRequestController::class, 'submition'])->name('claim-requests.submition');
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::post('claim-requests/{id}/update', [ClaimRequestController::class, 'update']);

View File

@@ -75,6 +75,7 @@ class ClaimRequestShowResource extends JsonResource
$response = [
'id' => $data['id'],
'code' => $data['code'],
'status' => $data['status'],
'request_log_id' => $data['request_log_id'],
'request_log' => $requestLogData,
'provider' => $data['request_log']['organization']['name'],

View File

@@ -26,6 +26,15 @@ class ClaimRequest extends Model
'service_code',
'policy_id',
'status',
// New field for claim management
'claim_management',
'status_claim_management',
'submission_date_claim_management',
'submission_by_claim_management',
'approval_date_claim_management',
'approval_by_claim_management',
'reason_decline',
//
'claim_id',
'organization_id',
'code',

View File

@@ -0,0 +1,47 @@
<?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->integer('claim_management')
->default(0)
->after('status')
->comment('untuk flag request masuk ke final, jika 0 masih request dan 1 itu sudah masuk ke finallog');
$table->string('status_claim_management')->after('claim_management')->nullable();
$table->dateTime('submission_date_claim_management')->after('status_claim_management')->nullable();
$table->string('submission_by_claim_management')->after('submission_date_claim_management')->nullable();
$table->dateTime('approval_date_claim_management')->after('submission_by_claim_management')->nullable();
$table->string('approval_by_claim_management')->after('approval_date_claim_management')->nullable();
$table->string('reason_decline')->after('approval_by_claim_management')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('claim_requests', function (Blueprint $table) {
$table->dropColumn('claim_management');
$table->dropColumn('status_claim_management');
$table->dropColumn('submission_date_claim_management');
$table->dropColumn('submission_by_claim_management');
$table->dropColumn('approval_date_claim_management');
$table->dropColumn('approval_by_claim_management');
$table->dropColumn('reason_decline');
});
}
};

View File

@@ -1,35 +1,30 @@
import MuiDialog from "@/components/MuiDialog";
import { Autocomplete, Button, Card, Checkbox, DialogActions, Grid, TextField, Typography } from "@mui/material";
import { Button, Card, Checkbox, DialogActions, Grid, TextField, TextareaAutosize, 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 { DetailClaimRequest } from "../Model/Types";
import { fDateTimesecond, toTitleCase } from "@/utils/formatTime";
import axios from "@/utils/axios";
import { enqueueSnackbar, useSnackbar } from "notistack";
import { enqueueSnackbar } from "notistack";
import { useNavigate } from "react-router";
import * as Yup from 'yup';
import { yupResolver } from '@hookform/resolvers/yup';
import { RHFTextField } from "@/components/hook-form";
type DialogConfirmationType = {
openDialog: boolean;
setOpenDialog: any;
onSubmit?: void;
approve: string;
claimRequest: ClaimRequest|undefined;
requestLog: DetailClaimRequest|undefined;
}
export default function DialogConfirmation({claimRequest, setOpenDialog, openDialog, approve, onSubmit} : DialogConfirmationType ) {
export default function DialogConfirmation({requestLog, 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,
@@ -38,24 +33,28 @@ export default function DialogConfirmation({claimRequest, setOpenDialog, openDia
};
const handleApprove = () => {
setFormData((prevData) => ({
...prevData,
status: approve,
}));
handleSubmit();
};
const handleSubmit = () => {
axios
.post(`customer-service/request/final-log`, formData)
.post(`claim-requests/${requestLog?.id}/submition`, formData)
.then((response) => {
enqueueSnackbar('Verification Request LOG Success', { variant: 'success' });
enqueueSnackbar('Submition Claim Request Success', { variant: 'success' });
setOpenDialog(false);
if (requestLog?.service_type == 'Inpatient'){
navigate('/case_management/inpatient_monitoring');
} else {
navigate('/custormer-service/final-log');
}
navigate('/claim-requests')
})
.catch(({ response }) => {
enqueueSnackbar(response.data.message ?? 'Something went wrong!', { variant: 'error' });
});
}
const style1 = {
color: '#919EAB',
width: '30%'
@@ -66,34 +65,57 @@ export default function DialogConfirmation({claimRequest, setOpenDialog, openDia
const marginBottom1 = {
marginBottom: 1,
}
const marginBottom2 = {
marginBottom: 2,
}
const resetForm = () => {
setFormData({
status: approve,
no_identitas: requestLog?.no_identitas ?? '',
keterangan: '',
hak_kamar_pasien: '',
penempatan_kamar: '',
});
};
const handleCloseDialog = () => {
setOpenDialog(false);
resetForm();
}
const handleNumericInput = (input: any) => {
const numericInput = input.replace(/\D/g, '');
return numericInput;
};
const handleKeyPress = (e:any) => {
if (e.key === 'Enter' && !e.shiftKey) {
// Menghentikan default "Enter" (tidak membuat baris baru)
e.preventDefault();
// Menambahkan karakter baris baru
handleChange('keterangan', `${formData.keterangan}\n`);
}
};
console.log(approve, 'test')
const getContent = () => (
<Stack spacing={1} marginTop={2}>
<Typography variant="subtitle2">Are you sure to {approve == 'approved' ? 'approve' : 'deciline'} this final log ?</Typography>
<Typography variant="subtitle1">Are you sure to submit 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>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>
<Typography variant='subtitle2' sx={style1} gutterBottom>Code</Typography>
<Typography variant='subtitle2' sx={style2} gutterBottom>{requestLog?.code}</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={style1} gutterBottom>Date Submission</Typography>
<Typography variant='subtitle2' sx={style2} gutterBottom>{requestLog?.submission_date ? fDateTimesecond(requestLog?.submission_date) : '-'}</Typography>
</Stack>
<Stack direction='row' spacing={2} sx={marginBottom1}>
@@ -105,58 +127,10 @@ export default function DialogConfirmation({claimRequest, setOpenDialog, openDia
<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>
) }
<Button color="primary" variant="contained" onClick={() => handleApprove()}>Submit</Button>
</DialogActions>
</Stack>
);
@@ -168,7 +142,7 @@ export default function DialogConfirmation({claimRequest, setOpenDialog, openDia
openDialog={openDialog}
setOpenDialog={setOpenDialog}
content={getContent()}
maxWidth="xl"
maxWidth="md"
/>
);
}

View File

@@ -38,6 +38,8 @@ import DialogDeleteFileLog from './Components/DialogDeleteFileLog';
import DialogBenefit from '../CustomerService/FinalLog/Components/DialogBenefit';
import DialogDeleteBenefit from '../CustomerService/FinalLog/Components/DialogDeleteBenefit';
import DialogEditBenefit from '../CustomerService/FinalLog/Components/DialogEditBenefit';
import DialogConfirmation from './Components/DialogConfirmation';
// ----------------------------------------------------------------------
@@ -49,6 +51,7 @@ export default function Detail() {
const navigate = useNavigate();
const { themeStretch } = useSettings();
const [claimRequests, setClaimRequest] = useState<DetailClaimRequest>();
const [openDialogSubmit, setOpenDialogSubmit] = useState(false);
const { id } = useParams();
@@ -421,7 +424,7 @@ export default function Detail() {
<Grid item xs={12}>
<Grid container spacing={2}>
<Grid item xs={6}>
<Typography variant="body2" sx={{ fontWeight: 'bold'}}>
<Typography variant="subtitle1" sx={{ fontWeight: 'bold'}}>
Total Benefit
</Typography>
</Grid>
@@ -436,12 +439,12 @@ export default function Detail() {
<Grid item xs={2}>
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
<Grid item xs={12}>
<Typography variant="caption">
<Typography variant="subtitle1">
Amount Incurred
</Typography>
</Grid>
<Grid item xs={12}>
<Typography variant="caption" sx={{ fontWeight: 'bold' }}>
<Typography variant="subtitle2" sx={{ fontWeight: 'bold' }}>
{totalAmountIncurred ? fNumber(totalAmountIncurred) : '0'}
</Typography>
</Grid>
@@ -452,12 +455,12 @@ export default function Detail() {
<Grid item xs={2}>
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
<Grid item xs={12}>
<Typography variant="caption">
<Typography variant="subtitle1">
Amount Approved
</Typography>
</Grid>
<Grid item xs={12}>
<Typography variant="caption" sx={{ fontWeight: 'bold' }}>
<Typography variant="subtitle2" sx={{ fontWeight: 'bold' }}>
{totalAmountApproved ? fNumber(totalAmountApproved) : '0'}
</Typography>
</Grid>
@@ -468,12 +471,12 @@ export default function Detail() {
<Grid item xs={3}>
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
<Grid item xs={12}>
<Typography variant="caption">
<Typography variant="subtitle1">
Amount Not Approved
</Typography>
</Grid>
<Grid item xs={12}>
<Typography variant="caption" sx={{ fontWeight: 'bold' }}>
<Typography variant="subtitle2" sx={{ fontWeight: 'bold' }}>
{totalAmountNotApproved ? fNumber(totalAmountNotApproved) : 0}
</Typography>
</Grid>
@@ -484,12 +487,12 @@ export default function Detail() {
<Grid item xs={2}>
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
<Grid item xs={12}>
<Typography variant="caption">
<Typography variant="subtitle1">
Excess Paid
</Typography>
</Grid>
<Grid item xs={12}>
<Typography variant="caption" sx={{ fontWeight: 'bold' }}>
<Typography variant="subtitle2" sx={{ fontWeight: 'bold' }}>
{totalExcessPaid ? fNumber(totalExcessPaid) : 0}
</Typography>
</Grid>
@@ -497,6 +500,23 @@ export default function Detail() {
</Grid>
</Grid>
</Box>
<Grid container spacing={1} marginY={2}>
<Grid item xs={6}>
<Typography variant="subtitle1">
Biaya disetujui
</Typography>
</Grid>
<Grid item xs={6} textAlign="right">
<Typography variant="subtitle1" sx={{ fontWeight: 'bold' }}>
{totalAmountApproved ? fNumber(totalAmountApproved) : '0'}
</Typography>
</Grid>
<Grid item xs={12}>
<Typography variant="subtitle2">
Nominal diatas 1 juta akan menunggu persetujuan senior analyst
</Typography>
</Grid>
</Grid>
</Grid>
</Grid>
@@ -504,6 +524,8 @@ export default function Detail() {
: (
null
)}
</Box>
</Card>
@@ -542,6 +564,42 @@ export default function Detail() {
requestLog={requestLog}
openDialog={openDialogEditDetail}
/> */}
{(claimRequests?.status === 'requested') || (claimRequests?.status === 'decline') ? (
<Grid item xs={12} md={12}>
<Stack direction="row" padding={4} sx={{ justifyContent: 'flex-end' }}>
<div style={{ marginRight: '10px' }}> {/* Perubahan sintaksis disini */}
<Button
variant="outlined"
color='inherit'
onClick={() => {
navigate('/claim-requests')
}}
>
Cancel
</Button>
</div>
<div>
<Button
variant="contained"
onClick={() => {
setOpenDialogSubmit(true);
setApprove('approved');
}}
>
Submit
</Button>
</div>
<DialogConfirmation
setOpenDialog={setOpenDialogSubmit}
requestLog={claimRequests}
openDialog={openDialogSubmit}
approve={approve}
>
</DialogConfirmation>
</Stack>
</Grid>
) : null}
</Grid>
</Grid>

View File

@@ -468,8 +468,12 @@ export default function List() {
<TableCell align="left">{row.service_name}</TableCell>
<TableCell align="left">{row.payment_type_name}</TableCell>
<TableCell align="left">
{ row.status == "requested" ?
{ row.status == "requested" ?
(<Label variant='ghost' color='primary'>{capitalizeFirstLetter(row.status)}</Label>) :
row.status == "submission" ?
(<Label color='info'> {capitalizeFirstLetter(row.status)}</Label>) :
row.status == "decline" ?
(<Label color='error'> {capitalizeFirstLetter(row.status)}</Label>) :
(<Label color='success'> {capitalizeFirstLetter(row.status)}</Label>)
}
</TableCell>

View File

@@ -189,7 +189,7 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl
const submitHandler = async (data: BenefitConfigurationListType) => {
const mapData = data.benefit_data.map((item) => ({
...item,
reason: item.reason.value
reason: item.reason ? item.reason.value : null
}));
const newData = {