This commit is contained in:
ivan-sim
2024-06-18 16:38:06 +07:00
parent 605fc72e89
commit 4ab48219ab
6 changed files with 253 additions and 85 deletions

View File

@@ -277,4 +277,50 @@ class CorporateMemberController extends Controller
return response()->json($deposit);
}
public function getLimits($corporate_id, $member_id)
{
$deposit = DB::table('corporate_policies')
->select('total_premi')
->where('corporate_id','=', $corporate_id)
->first();
$usage = DB::table('corporate_employees')
->join('request_logs', 'request_logs.member_id', '=', 'corporate_employees.member_id')
->join('request_log_benefits', 'request_log_benefits.request_log_id', '=', 'request_logs.id')
->where('corporate_employees.corporate_id', '=', $corporate_id)
->where('request_logs.member_id', '=', $member_id)
->sum('request_log_benefits.amount_approved');
$services = DB::table('member_plans')
->leftJoin('plans', 'plans.id', '=', 'member_plans.plan_id')
->leftJoin('services', 'services.code', '=', 'plans.service_code')
->where('member_plans.member_id', '=', $member_id)
->whereNull('member_plans.deleted_at')
->select(
'plans.service_code',
'services.name as title',
'plans.limit_rules as total',
DB::raw("
(
SELECT SUM(request_log_benefits.amount_approved)
FROM request_logs
INNER JOIN request_log_benefits
ON request_log_benefits.request_log_id = request_logs.id
WHERE request_logs.member_id = $member_id
AND request_logs.service_code = plans.service_code
) as current
")
)
->get();
// Ganti dengan logika Anda untuk mendapatkan data deposit
$deposit = [
'deposit' => $deposit->total_premi,
'usage' => $usage,
'services' => $services
];
return response()->json($deposit);
}
}

View File

@@ -72,6 +72,8 @@ Route::prefix('client')->group(function () {
Route::get('corporate', [CorporateCurrentController::class, 'index']);
Route::put('corporate-update', [CorporateCurrentController::class, 'update']);
Route::get('get-deposits', [CorporateMemberController::class, 'getDeposit']);
Route::get('get-limits/{member_id}', [CorporateMemberController::class, 'getLimits']);
});
Route::get('claims/{id}', [ClaimController::class, 'show']);

View File

@@ -23,11 +23,11 @@ class DataServiceMonitoring extends JsonResource
$filesFinalLogKondisi = [];
if (count($this->files)>0){
foreach ($this->files as $key => $value) {
/*
Sementara di buat satu dulu, jangan di hapus..
/*
Sementara di buat satu dulu, jangan di hapus..
karena suka labil client nya, tiba2 hide tiba2 munculin fitur :D
*/
// if($value->type == 'final-log-result'){
array_push($filesFinalLogResult, $value);
// };
@@ -71,7 +71,7 @@ class DataServiceMonitoring extends JsonResource
$main_diagnosis = $d;
}
$diagnosis = '-';
}
}
if ($key > 0){
if ($icd) {
@@ -86,6 +86,7 @@ class DataServiceMonitoring extends JsonResource
return [
'companyName' => $this->member->currentCorporate->name ?? null,
'serviceCode' => $this->service_code ?? null,
'member_id' => $this->member->id ?? null,
'memberId' => $this->member->member_id ?? null,
'fullName' => $this->member->full_name ?? null,
'dateOfBirth' => $this->member->birth_date ?? null,
@@ -121,7 +122,7 @@ class DataServiceMonitoring extends JsonResource
$arr_document = [];
$document = DB::table('files')
->where([
'fileable_type' => 'App\Models\LaboratoriumResult',
'fileable_type' => 'App\Models\LaboratoriumResult',
'fileable_id' => $requestLogDailyMonitoring->id,
'deleted_at' => null
])
@@ -138,7 +139,7 @@ class DataServiceMonitoring extends JsonResource
}
}
return [
'time' => Carbon::parse($requestLogDailyMonitoring->submission_date)->format('H:i') ?? null,
'status' => 'Done' ?? null,
@@ -180,12 +181,12 @@ class DataServiceMonitoring extends JsonResource
})
->map(function ($groupedItems) {
return collect($groupedItems)
->map(function ($test) {
$arr_document = [];
$document = DB::table('files')
->where([
'fileable_type' => 'App\Models\LaboratoriumResult',
'fileable_type' => 'App\Models\LaboratoriumResult',
'fileable_id' => $test->id,
'deleted_at' => null
])
@@ -201,7 +202,7 @@ class DataServiceMonitoring extends JsonResource
];
}
}
return [
'code' => $test->code,
'date' => Carbon::parse($test->lab_date)->format('d M Y') ?? null,

View File

@@ -84,7 +84,8 @@ class PermissionTableSeeder extends Seeder
'corporate-client-portal',
'alarm-center-list-client-portal',
'formularium-list-client-portal',
'case-management-client-portal'
'case-management-client-portal',
'service-monitoring-limit-client-portal',
]
]
];

View File

@@ -20,11 +20,14 @@ import {
ListItemText,
ListItemButton,
Divider,
CardContent,
LinearProgress
} from '@mui/material';
import { styled } from '@mui/material/styles';
import { Download as DownloadIcon, Circle as CircleIcon, TableView } from '@mui/icons-material';
// components
import Page from '../../components/Page';
import { fCurrency } from '../../utils/formatNumber';
// utils
import { useState, SyntheticEvent, useContext, useEffect } from 'react';
import { UserCurrentCorporateContext } from '../../contexts/UserCurrentCorporate';
@@ -45,6 +48,8 @@ import TableMoreMenu from '../../components/table/TableMoreMenu';
import Label from '../../components/Label';
import { fSplit } from '../../utils/formatNumber';
import useAuth from '../../hooks/useAuth';
interface TabPanelProps {
children?: React.ReactNode;
index: number;
@@ -208,6 +213,13 @@ type ServiceMonitoringProps = {
};
export default function ServiceMonitoring() {
const {user} = useAuth();
const checkIfNameExists = (name) => {
return user.user.permissions.some(item => item.name === name);
};
const nameToCheck = 'service-monitoring-limit-client-porta';
const doesNameExist = checkIfNameExists(nameToCheck);
const navigate = useNavigate();
const controller = new AbortController();
@@ -221,7 +233,7 @@ export default function ServiceMonitoring() {
const { corporateValue } = useContext(UserCurrentCorporateContext);
const { memberId, requestLogId } = useParams();
const [depositData, setDepositData] = useState({ deposit: 0, limit: 0, usage: 0 });
useEffect(() => {
(async () => {
try {
@@ -236,6 +248,18 @@ export default function ServiceMonitoring() {
if (response.data.data.serviceCode !== 'IP') {
setValue(1);
}
var member_id = response.data.data.member_id;
const fetchDepositData = async () => {
try {
const response = await axios.get(`${corporateValue}/get-limits/${member_id}`);
setDepositData(response.data);
} catch (error) {
console.error('Failed to fetch deposit data:', error);
}
};
fetchDepositData();
} catch (error: any) {
console.error('Error fetching data:', error.message);
} finally {
@@ -248,7 +272,7 @@ export default function ServiceMonitoring() {
};
}, [corporateValue]);
const renderHTML = (data:string) => {
return (
<div style={{marginLeft: 20}}
@@ -256,7 +280,32 @@ export default function ServiceMonitoring() {
/>
);
}
const formatNumber = (number) => {
return new Intl.NumberFormat('id-ID').format(number);
};
const LimitPlanCard = ({ title, current, total }) => (
<Card variant="outlined" sx={{ minWidth: 200, m: 1 }}>
<CardContent>
<Typography variant="h6" component="div">
{title}
</Typography>
<Typography variant="subtitle2" color="text.secondary">
Yearly Limits
</Typography>
<Typography variant="subtitle1">
{formatNumber(current)} / {formatNumber(total)}
</Typography>
<LinearProgress variant="determinate" value={(current / total) * 100} />
</CardContent>
</Card>
);
const plans = [
{ title: 'Outpatient', current: 200000, total: 1000000 },
{ title: 'Inpatient', current: 1000000, total: 5000000 },
{ title: 'Dental', current: 250000, total: 1000000 },
{ title: 'Maternity', current: 0, total: 3000000 },
];
return (
<Page title="Service Monitoring">
@@ -277,14 +326,14 @@ export default function ServiceMonitoring() {
<Grid item xs={12}>
<Card sx={{ borderRadius: 2, padding: 3 }}>
<Grid container spacing={5}>
<Grid item xs={12}>
<Typography component={'h6'} fontWeight={700} fontSize={18}>
{loading ? <Skeleton animation="wave" width={175} /> : 'Employee Profile'}
</Typography>
</Grid>
<Grid item xs={12} container spacing={3}>
<Grid item container spacing={3}>
<Grid item container xs={12} md={6} spacing={1.5}>
<Grid item xs={12}>
<Grid item xs={12}>
<Typography component={'h6'} fontWeight={700} fontSize={18}>
{loading ? <Skeleton animation="wave" width={175} /> : 'Employee Profile'}
</Typography>
</Grid>
<Grid item xs={12}>
<Typography variant="subtitle2" color={'grey.600'}>
{loading ? <Skeleton animation={'wave'} width={200} /> : 'Company Name'}
</Typography>
@@ -300,8 +349,6 @@ export default function ServiceMonitoring() {
)}
</Typography>
</Grid>
</Grid>
<Grid item container xs={12} md={6} spacing={1.5}>
<Grid item xs={12}>
<Typography variant="subtitle2" color={'grey.600'}>
{loading ? <Skeleton animation={'wave'} width={200} /> : 'Member ID'}
@@ -318,8 +365,6 @@ export default function ServiceMonitoring() {
)}
</Typography>
</Grid>
</Grid>
<Grid item container xs={12} md={6} spacing={1.5}>
<Grid item xs={12}>
<Typography variant="subtitle2" color={'grey.600'}>
{loading ? <Skeleton animation={'wave'} width={200} /> : 'Full Name'}
@@ -336,8 +381,6 @@ export default function ServiceMonitoring() {
)}
</Typography>
</Grid>
</Grid>
<Grid item container xs={12} md={6} spacing={1.5}>
<Grid item xs={12}>
<Typography variant="subtitle2" color={'grey.600'}>
{loading ? <Skeleton animation={'wave'} width={200} /> : 'Date of Birth'}
@@ -354,8 +397,6 @@ export default function ServiceMonitoring() {
)}
</Typography>
</Grid>
</Grid>
<Grid item container xs={12} md={6} spacing={1.5}>
<Grid item xs={12}>
<Typography variant="subtitle2" color={'grey.600'}>
{loading ? <Skeleton animation={'wave'} width={200} /> : 'Phone Number'}
@@ -372,8 +413,6 @@ export default function ServiceMonitoring() {
)}
</Typography>
</Grid>
</Grid>
<Grid item container xs={12} md={6} spacing={1.5}>
<Grid item xs={12}>
<Typography variant="subtitle2" color={'grey.600'}>
{loading ? <Skeleton animation={'wave'} width={200} /> : 'Email'}
@@ -391,6 +430,43 @@ export default function ServiceMonitoring() {
</Typography>
</Grid>
</Grid>
<Grid item container xs={12} md={6} spacing={1.5}>
{doesNameExist ? (
<Stack direction="column">
<Box display="flex" flexWrap="wrap" justifyContent="left">
<Card variant="outlined" sx={{ minWidth: 200, marginBottom: 1, borderRadius: 2, padding: 0 }}>
<CardContent>
<Typography variant="h6" component="div">
Limit
</Typography>
<Typography variant="subtitle2" color="text.secondary">
Yearly Limits
</Typography>
<Typography variant="subtitle1">
{formatNumber(depositData.usage)} / {formatNumber(depositData.deposit)}
</Typography>
<LinearProgress variant="determinate" value={(depositData.usage / depositData.deposit) * 100} />
</CardContent>
</Card>
</Box>
<Card sx={{ borderRadius: 2, padding: 3 }}>
<Typography component={'h6'} fontWeight={700} fontSize={18}>
Limit Plan
</Typography>
<Box display="flex" flexWrap="wrap" justifyContent="left">
{depositData.services?.map((plan) => (
<LimitPlanCard
key={plan.title}
title={plan.title}
current={plan.current}
total={plan.total}
/>
))}
</Box>
</Card>
</Stack>
) : ''}
</Grid>
</Grid>
<Grid item xs={12} paddingY={2}>
<Typography component={'h6'} fontWeight={700} fontSize={18}>
@@ -400,7 +476,7 @@ export default function ServiceMonitoring() {
</Grid>
</Card>
</Grid>
<Grid item container xs={12} spacing={5}>
<Grid item container xs={12} md={6}>
@@ -501,9 +577,9 @@ export default function ServiceMonitoring() {
<Grid item>
{loading ? (
<Skeleton animation="wave" width={300} />
) : data && data.files && data.files.result.length > 0 ?
) : data && data.files && data.files.result.length > 0 ?
(
data.files.result.map((file, index) =>
data.files.result.map((file, index) =>
(
(
<Stack direction="column" spacing={2} key={index}>
@@ -539,9 +615,9 @@ export default function ServiceMonitoring() {
<Grid item>
{loading ? (
<Skeleton animation="wave" width={300} />
) : data && data.files && data.files.diagnosis.length > 0 ?
) : data && data.files && data.files.diagnosis.length > 0 ?
(
data.files.diagnosis.map((file, index) =>
data.files.diagnosis.map((file, index) =>
(
(
<Stack direction="column" spacing={2} key={index}>
@@ -577,9 +653,9 @@ export default function ServiceMonitoring() {
{/* <Grid item>
{loading ? (
<Skeleton animation="wave" width={300} />
) : data && data.files && data.files.kondisi.length > 0 ?
) : data && data.files && data.files.kondisi.length > 0 ?
(
data.files.kondisi.map((file, index) =>
data.files.kondisi.map((file, index) =>
(
(
<Stack direction="column" spacing={2} key={index}>
@@ -1180,7 +1256,7 @@ export default function ServiceMonitoring() {
{file.original_name}
</a>
</li>
)
)
)
) : (
<li>-</li>
@@ -1259,7 +1335,7 @@ export default function ServiceMonitoring() {
{file.original_name}
</a>
</li>
)
)
)
) : (
<li>-</li>

View File

@@ -1,5 +1,5 @@
// @mui
import { CardContent,Button, Container, Grid, styled, Typography, Card, Stack } from '@mui/material';
import { Box,CardContent,Button, Container, Grid, styled, Typography, Card, Stack } from '@mui/material';
// hooks
import useSettings from '../../hooks/useSettings';
// components
@@ -15,16 +15,34 @@ import { useContext, useEffect, useState } from 'react';
import { UserCurrentCorporateContext } from '../../contexts/UserCurrentCorporate';
import { useNavigate, useParams } from 'react-router-dom';
// ----------------------------------------------------------------------
export default function Dashboard() {
const navigate = useNavigate();
const { themeStretch } = useSettings();
const { logout } = useAuth();
const { user } = useAuth();
const loadSomething = () => {
axios.get('/user')
};
const checkIfNameExists = (name) => {
return user.user.permissions.some(item => item.name === name);
};
const nameToCheck = 'dashboard-list-client-portal';
const doesNameExist = checkIfNameExists(nameToCheck);
useEffect(() => {
const doesNameExist = checkIfNameExists(nameToCheck);
if (!doesNameExist) {
navigate('/corporate');
}
}, [nameToCheck, user, navigate]);
// const loadSomething = () => {
// axios.get('/user')
// };
const Wallet = styled(AccountBalanceWalletIcon)(({ theme }) => ({
color: 'orange',
@@ -78,55 +96,79 @@ const [depositData, setDepositData] = useState({ deposit: 0, limit: 0, usage: 0
fetchDepositData();
}, [corporateValue]);
const handleGoBack = () => {
// Logic untuk kembali ke halaman sebelumnya atau halaman utama
navigate('/corporate')
};
return (
<Page title="Dashboard">
<Container maxWidth={themeStretch ? false : 'xl'}>
<Typography variant="h3" component="h1" paragraph>
Dashboard
</Typography>
{doesNameExist ? (
<Grid container spacing={2}>
<Grid item xs={4}>
{/* <SomethingUsage /> */}
<DefaultCard>
<CardContent>
<Stack direction="column" alignItems="flex-start" justifyContent="space-between" sx={{ mb: 0.6 }}>
<Stack direction="row" alignItems="center" justifyContent="space-between" sx={{ width: '100%' }}>
<Typography variant='h4'>{fCurrency(depositData.deposit)}</Typography>
<Wallet />
</Stack>
<Typography variant='h6'>Deposit</Typography>
</Stack>
</CardContent>
</DefaultCard>
</Grid>
<Grid item xs={4}>
<DefaultCard>
<CardContent>
<Stack direction="column" alignItems="flex-start" justifyContent="space-between" sx={{ mb: 0.6 }}>
<Stack direction="row" alignItems="center" justifyContent="space-between" sx={{ width: '100%' }}>
<Typography variant='h4'>{fCurrency(depositData.limit)}</Typography>
<TrendUp />
</Stack>
<Typography variant='h6'>Limit</Typography>
</Stack>
</CardContent>
</DefaultCard>
</Grid>
<Grid item xs={4}>
<DefaultCard>
<CardContent>
<Stack direction="column" alignItems="flex-start" justifyContent="space-between" sx={{ mb: 0.6 }}>
<Stack direction="row" alignItems="center" justifyContent="space-between" sx={{ width: '100%' }}>
<Typography variant='h4'>{fCurrency(depositData.usage)}</Typography>
<Monet />
</Stack>
<Typography variant='h6'>This Year Usage</Typography>
</Stack>
</CardContent>
</DefaultCard>
</Grid>
</Grid>
):(
<Box
display="flex"
flexDirection="column"
alignItems="center"
justifyContent="center"
minHeight="55vh"
textAlign="center"
padding={2}
>
<Typography variant="body1" color="textSecondary" paragraph>
Maaf, halaman ini tidak bisa diakses atau tidak ada.
</Typography>
<Button variant="contained" color="primary" onClick={handleGoBack}>
Kembali
</Button>
</Box>
)}
<Grid container spacing={2}>
<Grid item xs={4}>
{/* <SomethingUsage /> */}
<DefaultCard>
<CardContent>
<Stack direction="column" alignItems="flex-start" justifyContent="space-between" sx={{ mb: 0.6 }}>
<Stack direction="row" alignItems="center" justifyContent="space-between" sx={{ width: '100%' }}>
<Typography variant='h4'>{fCurrency(depositData.deposit)}</Typography>
<Wallet />
</Stack>
<Typography variant='h6'>Deposit</Typography>
</Stack>
</CardContent>
</DefaultCard>
</Grid>
<Grid item xs={4}>
<DefaultCard>
<CardContent>
<Stack direction="column" alignItems="flex-start" justifyContent="space-between" sx={{ mb: 0.6 }}>
<Stack direction="row" alignItems="center" justifyContent="space-between" sx={{ width: '100%' }}>
<Typography variant='h4'>{fCurrency(depositData.limit)}</Typography>
<TrendUp />
</Stack>
<Typography variant='h6'>Limit</Typography>
</Stack>
</CardContent>
</DefaultCard>
</Grid>
<Grid item xs={4}>
<DefaultCard>
<CardContent>
<Stack direction="column" alignItems="flex-start" justifyContent="space-between" sx={{ mb: 0.6 }}>
<Stack direction="row" alignItems="center" justifyContent="space-between" sx={{ width: '100%' }}>
<Typography variant='h4'>{fCurrency(depositData.usage)}</Typography>
<Monet />
</Stack>
<Typography variant='h6'>This Year Usage</Typography>
</Stack>
</CardContent>
</DefaultCard>
</Grid>
</Grid>
</Container>
</Page>
);