From 0c5960275c5034ad895050ab7e6aa31b98908c88 Mon Sep 17 00:00:00 2001 From: ivan-sim Date: Fri, 27 Oct 2023 09:07:29 +0700 Subject: [PATCH 01/10] Update --- .../dashboard/src/pages/Claims/Detail.tsx | 85 +------------------ 1 file changed, 1 insertion(+), 84 deletions(-) diff --git a/frontend/dashboard/src/pages/Claims/Detail.tsx b/frontend/dashboard/src/pages/Claims/Detail.tsx index 22ff9ef1..546e0984 100644 --- a/frontend/dashboard/src/pages/Claims/Detail.tsx +++ b/frontend/dashboard/src/pages/Claims/Detail.tsx @@ -9,23 +9,13 @@ import { useNavigate, useParams, useLocation } from 'react-router-dom'; import { useEffect, useState, useRef } from 'react'; import axios from '../../utils/axios'; // pages -import DetailTimeline from '../../pages/ClaimRequests/DetailTimeline'; -import DetailStepper from '../../pages/ClaimRequests/DetailStepper'; import { format } from 'date-fns'; import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos'; import Button from '@mui/material/Button'; import AddIcon from '@mui/icons-material/Add'; -import RemoveIcon from '@mui/icons-material/Remove'; -import { DatePicker, LocalizationProvider } from '@mui/x-date-pickers'; -import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'; -import Iconify from '@/components/Iconify'; -import { fPostFormat } from '@/utils/formatTime'; import InsertDriveFileIcon from '@mui/icons-material/InsertDriveFile'; -import DownloadIcon from '@mui/icons-material/Download'; import { Dialog, DialogTitle, DialogContent, DialogActions } from '@mui/material'; import CloseIcon from '@mui/icons-material/Close'; -import { fDateTimesecond } from '@/utils/formatTime'; -import { makeFormData } from '@/utils/jsonToFormData'; import FormGroup from '@mui/material/FormGroup'; import FormControlLabel from '@mui/material/FormControlLabel'; import Checkbox from '@mui/material/Checkbox'; @@ -41,8 +31,6 @@ export default function Detail() { const navigate = useNavigate(); const { themeStretch } = useSettings(); - const [data, setData] = useState(); - const [dataDialog, setDataDialog] = useState(); const [customerData, setCustomerData] = useState(null); const [documentData, setDocumentData] = useState(null); const [requestDocumentData, setRequestDocumentData] = useState(null); @@ -61,78 +49,7 @@ export default function Detail() { console.error(error); }); - }, []); - - const [isInvoiceVisible, setInvoiceVisibility] = useState(false); - - const handleInvoice = () => { - setInvoiceVisibility(!isInvoiceVisible); - } - const currentDate = new Date(); - const formattedCurrentDate = format(currentDate, 'dd MMM yyyy'); - const [dateInvoice, setDateInvoice] = useState(currentDate); - - const fileInvoiceInput = useRef(null); - const [fileInvoices, setFileInvoices] = useState([]); - - const handleInvoiceInputChange = (event) => { - if (event.target.files[0]) { - setFileInvoices([...fileInvoices, ...event.target.files]); - } else { - console.log('NO FILE'); - } - }; - const removeInvoiceFiles = (filesState, index) => { - setFileInvoices( - filesState.filter((file, fileIndex) => { - return fileIndex != index; - }) - ); - }; - const date = dateInvoice ? fPostFormat(dateInvoice, 'yyyy-MM-dd') : null; - - const [openDialogSubmit, setOpenDialogSubmit] = useState(false); - const handleCloseDialogSubmit = () => { - setOpenDialogSubmit(false); - } - const handleSubmitData = () => { - if(fileInvoices.length > 0) - { - //submit data - axios - .post('claim-requests/'+id+'/approve') - .then((response) => { - enqueueSnackbar('Success Submit Claim Request', { variant: 'success' }); - setOpenDialogSubmit(false); - }) - .catch(({ response }) => { - enqueueSnackbar(response.data.message ?? 'Something went wrong!', { variant: 'error' }); - }); - //Upload file invoices - const formData = makeFormData({ - date:date, - invoice_files: fileInvoices, - }); - axios - .post('claim-requests/'+id+'/invoice-files', formData) - .then((response) => { - enqueueSnackbar(response.data.message ?? 'Success upload invoice', { variant: 'success' }); - }) - .catch(({ response }) => { - enqueueSnackbar(response.data.message ?? 'Something Went Wrong', { variant: 'error' }); - }); - } - else - { - enqueueSnackbar('Please upload file invoice, before submit', { variant: 'warning' }); - } - - setTimeout(() => - { - window.location.reload(); - }, 5000); - - }; + }, []); function toTitleCase(str) { return str.replace(/\w\S*/g, function(txt) { From 63af52cb85ece58e5b6c9ef50f019990cf59072b Mon Sep 17 00:00:00 2001 From: Tb Fajri Date: Fri, 27 Oct 2023 09:28:08 +0700 Subject: [PATCH 02/10] update backend claim history hospital --- .../Http/Controllers/Api/ClaimController.php | 95 +++++++++++++++++++ Modules/Internal/Routes/api.php | 6 ++ .../Transformers/ClaimHistoryCareResource.php | 44 +++++++++ app/Models/ClaimHistoryCare.php | 47 +++++++++ .../DiagnosisSecondaryClaimHistoryCare.php | 28 ++++++ app/Models/Icd.php | 10 ++ app/Models/Organization.php | 4 + app/Models/Practitioner.php | 7 ++ ...110846_create_claim_history_care_table.php | 42 ++++++++ ...sis_secondary_claim_history_care_table.php | 34 +++++++ 10 files changed, 317 insertions(+) create mode 100644 Modules/Internal/Transformers/ClaimHistoryCareResource.php create mode 100644 app/Models/ClaimHistoryCare.php create mode 100644 app/Models/DiagnosisSecondaryClaimHistoryCare.php create mode 100644 database/migrations/2023_10_26_110846_create_claim_history_care_table.php create mode 100644 database/migrations/2023_10_26_115410_create_diagnosis_secondary_claim_history_care_table.php diff --git a/Modules/Internal/Http/Controllers/Api/ClaimController.php b/Modules/Internal/Http/Controllers/Api/ClaimController.php index 78c739ea..749bbc5a 100644 --- a/Modules/Internal/Http/Controllers/Api/ClaimController.php +++ b/Modules/Internal/Http/Controllers/Api/ClaimController.php @@ -8,6 +8,8 @@ use App\Models\Claim; use App\Models\Icd; use App\Models\Member; use App\Models\Organization; +use App\Models\ClaimHistoryCare; +use App\Models\DiagnosisSecondaryClaimHistoryCare; use App\Services\ClaimService; use Illuminate\Contracts\Support\Renderable; use Illuminate\Http\Request; @@ -16,6 +18,7 @@ use Modules\HospitalPortal\Helpers\ApiResponse; use Illuminate\Support\Facades\Validator; use Modules\Internal\Transformers\ClaimShowResource; use Modules\Internal\Transformers\ClaimEditResource; +use Modules\Internal\Transformers\ClaimHistoryCareResource; use Box\Spout\Reader\Common\Creator\ReaderEntityFactory; use Box\Spout\Writer\Common\Creator\WriterEntityFactory; @@ -526,4 +529,96 @@ class ClaimController extends Controller "file_url" => url('files/Benefit Usage Report.xlsx') ]); } + + //////////////////// History Care Hospital /////////////////////////// + + public function storeHistoryCare(Request $request, $id){ + $request->validate([ + 'service_code' => 'required', + 'admision_date' => 'required', + 'discharge_date' => 'required', + 'organization_id' => 'required', + 'practitioner_id' => 'required', + 'medical_record_number' => 'required', + 'symptoms' => 'required', + 'sign' => 'required', + 'main_diagnosis_id' => 'required', + ]); + + $data = [ + 'service_code' => $request->service_code, + 'admision_date' => $request->admision_date, + 'discharge_date' => $request->discharge_date, + 'organization_id' => $request->organization_id, + 'practitioner_id' => $request->practitioner_id, + 'medical_record_number' => $request->medical_record_number, + 'symptoms' => $request->symptoms, + 'sign' => $request->sign, + 'claim_id' => $id, + 'main_diagnosis_id' => $request->main_diagnosis_id, + 'status' => 0, + ]; + + $claimHistoryCare = ClaimHistoryCare::create($data); + if (count($request->secondary_diagnosis_id)) { + foreach($request->secondary_diagnosis_id as $value){ + $dataSecondary = [ + 'claim_history_care_id' => $claimHistoryCare->id, + 'icd_id' => intval($value) + ]; + DiagnosisSecondaryClaimHistoryCare::create($dataSecondary); + } + } + + return Helper::responseJson($claimHistoryCare); + } + + public function updateHistoryCare(Request $request, $id){ + $data = $request->validate([ + 'service_code' => 'required', + 'admision_date' => 'required', + 'discharge_date' => 'required', + 'organization_id' => 'required', + 'practitioner_id' => 'required', + 'medical_record_number' => 'required', + 'symptoms' => 'required', + 'sign' => 'required', + 'main_diagnosis_id' => 'required', + ]); + + // $data['status'] = 0; + + $claimHistoryCare = ClaimHistoryCare::findOrFail($id); + $claimHistoryCare->update($data); + + // Hapus diagnosis sekunder yang terkait + DiagnosisSecondaryClaimHistoryCare::where('claim_history_care_id', $id)->delete(); + + if (count($request->secondary_diagnosis_id)) { + foreach ($request->secondary_diagnosis_id as $value) { + $dataSecondary = [ + 'claim_history_care_id' => $claimHistoryCare->id, + 'icd_id' => intval($value), + ]; + DiagnosisSecondaryClaimHistoryCare::create($dataSecondary); + } + } + + return Helper::responseJson(message: 'Data Berhasil di update'); + + } + + public function showHistoryCare($id){ + $data = ClaimHistoryCare::with(['organization', 'practitioner', 'practitioner.person', 'icd'])->find($id); + + return Helper::responseJson(ClaimHistoryCareResource::make($data)); + } + + public function approvalHistoryCare(Request $request, $id){ + $claimHistoryCare = ClaimHistoryCare::findOrFail($id); + $claimHistoryCare->status = $request->status; + $claimHistoryCare->save(); + + return Helper::responseJson(message: 'Data Berhasil di update'); + } } diff --git a/Modules/Internal/Routes/api.php b/Modules/Internal/Routes/api.php index a4a57e86..1aef58cc 100644 --- a/Modules/Internal/Routes/api.php +++ b/Modules/Internal/Routes/api.php @@ -191,6 +191,12 @@ Route::prefix('internal')->group(function () { Route::post('claims/{id}/decline', [ClaimController::class, 'decline'])->name('claim.decline'); Route::post('claims/{id}/approve', [ClaimController::class, 'approve'])->name('claim.approve'); Route::post('claims/{id}/re-open', [ClaimController::class, 'reOpen'])->name('claim.re-open'); + + Route::post('claims/{id}/carehistory', [ClaimController::class, 'storeHistoryCare']); + Route::post('claims/carehistory/{id}/update', [ClaimController::class, 'updateHistoryCare']); + Route::get('claims/carehistory/{id}', [ClaimController::class, 'showHistoryCare']); + Route::post('claims/carehistory/{id}/approval', [ClaimController::class, 'approvalHistoryCare']); + Route::post('claims', [ClaimController::class, 'store']); Route::get('claims/{id}', [ClaimController::class, 'show']); Route::put('claims/{id}', [ClaimController::class, 'update']); diff --git a/Modules/Internal/Transformers/ClaimHistoryCareResource.php b/Modules/Internal/Transformers/ClaimHistoryCareResource.php new file mode 100644 index 00000000..feff9ff5 --- /dev/null +++ b/Modules/Internal/Transformers/ClaimHistoryCareResource.php @@ -0,0 +1,44 @@ +with(['icd'])->get()->toArray(); + + $data = [ + 'id' => $claim['id'], + 'service_code' => $claim['service_code'], + 'admision_date' => $claim['admision_date'], + 'discharge_date' => $claim['discharge_date'], + 'claim_id' => $claim['claim_id'], + 'organization_id' => $claim['organization_id'], + 'organization_name' => $claim['organization'] ? $claim['organization']['name'] : '-', + 'practitioner_id' => $claim['practitioner_id'], + 'practitioner_name' => $claim['practitioner'] ? $claim['practitioner']['person']['name'] : '-', + 'medical_record_number' => $claim['medical_record_number'], + 'symptoms' => $claim['symptoms'], + 'sign' => $claim['sign'], + 'main_diagnosis_id' => $claim['main_diagnosis_id'], + 'main_diagnosis_name' => $claim['icd'] ? $claim['icd']['name'] : '-', + 'status' => $claim['status'], + 'secondary_diagnosis' => $secondaryDiagnosis, + ]; + + return $data; + } +} diff --git a/app/Models/ClaimHistoryCare.php b/app/Models/ClaimHistoryCare.php new file mode 100644 index 00000000..448d2e2a --- /dev/null +++ b/app/Models/ClaimHistoryCare.php @@ -0,0 +1,47 @@ +belongsTo(Organization::class, 'organization_id'); + } + + public function practitioner() + { + return $this->belongsTo(Practitioner::class, 'practitioner_id'); + } + + public function icd() + { + return $this->belongsTo(Icd::class, 'main_diagnosis_id'); + } + + + +} diff --git a/app/Models/DiagnosisSecondaryClaimHistoryCare.php b/app/Models/DiagnosisSecondaryClaimHistoryCare.php new file mode 100644 index 00000000..113015ec --- /dev/null +++ b/app/Models/DiagnosisSecondaryClaimHistoryCare.php @@ -0,0 +1,28 @@ +belongsTo(Icd::class, 'icd_id'); + } +} diff --git a/app/Models/Icd.php b/app/Models/Icd.php index 981c5a57..b2495a6d 100644 --- a/app/Models/Icd.php +++ b/app/Models/Icd.php @@ -74,4 +74,14 @@ class Icd extends Model }); } + public function claim_history_care() + { + return $this->hasMany(CliamHistoryCare::class, 'main_diagnosis_id', 'id'); + } + + public function diagnosis_secondary_claim_history_care() + { + return $this->hasMany(DiagnosisSecondaryCliamHistoryCare::class, 'icd_id', 'id'); + } + } diff --git a/app/Models/Organization.php b/app/Models/Organization.php index 568abede..9b15406d 100644 --- a/app/Models/Organization.php +++ b/app/Models/Organization.php @@ -107,4 +107,8 @@ class Organization extends Model { return $this->hasMany(ClaimRequest::class, 'organization_id', 'id'); } + public function claim_history_care() + { + return $this->hasOne(ClaimHistoryCare::class, 'organization_id', 'id'); + } } diff --git a/app/Models/Practitioner.php b/app/Models/Practitioner.php index 43d0fac8..c602d1a3 100644 --- a/app/Models/Practitioner.php +++ b/app/Models/Practitioner.php @@ -47,4 +47,11 @@ class Practitioner extends Model { return $this->hasMany(PractitionerRole::class, 'practitioner_id'); } + + public function claim_history_care() + { + return $this->hasMany(ClaimHistoryCare::class, 'practitioner_id'); + } + + } diff --git a/database/migrations/2023_10_26_110846_create_claim_history_care_table.php b/database/migrations/2023_10_26_110846_create_claim_history_care_table.php new file mode 100644 index 00000000..93c60d3f --- /dev/null +++ b/database/migrations/2023_10_26_110846_create_claim_history_care_table.php @@ -0,0 +1,42 @@ +id(); + $table->timestamps(); + $table->string('service_code'); + $table->date('admision_date'); + $table->date('discharge_date'); + $table->integer('claim_id'); + $table->integer('organization_id'); + $table->integer('practitioner_id'); + $table->string('medical_record_number'); + $table->string('symptoms'); + $table->string('sign'); + $table->integer('main_diagnosis_id'); + $table->integer('status'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('claim_history_cares'); + } +}; diff --git a/database/migrations/2023_10_26_115410_create_diagnosis_secondary_claim_history_care_table.php b/database/migrations/2023_10_26_115410_create_diagnosis_secondary_claim_history_care_table.php new file mode 100644 index 00000000..02fa5dc2 --- /dev/null +++ b/database/migrations/2023_10_26_115410_create_diagnosis_secondary_claim_history_care_table.php @@ -0,0 +1,34 @@ +id(); + $table->timestamps(); + $table->integer('claim_history_care_id'); + $table->integer('icd_id'); + + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('diagnosis_secondary_claim_history_care'); + } +}; From 239e95f5df00850af85e79940c92aea8aecbb6e8 Mon Sep 17 00:00:00 2001 From: Tb Fajri Date: Fri, 27 Oct 2023 13:57:24 +0700 Subject: [PATCH 03/10] add kolom active --- app/Models/FormulariumTemplate.php | 1 + ...10_add_column_to_formularium_templates.php | 32 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 database/migrations/2023_10_27_134210_add_column_to_formularium_templates.php diff --git a/app/Models/FormulariumTemplate.php b/app/Models/FormulariumTemplate.php index afaca178..91bb22c0 100644 --- a/app/Models/FormulariumTemplate.php +++ b/app/Models/FormulariumTemplate.php @@ -13,6 +13,7 @@ class FormulariumTemplate extends Model protected $fillable = [ 'name', 'description', + 'active', ]; protected $hidden = [ diff --git a/database/migrations/2023_10_27_134210_add_column_to_formularium_templates.php b/database/migrations/2023_10_27_134210_add_column_to_formularium_templates.php new file mode 100644 index 00000000..2b9830d2 --- /dev/null +++ b/database/migrations/2023_10_27_134210_add_column_to_formularium_templates.php @@ -0,0 +1,32 @@ +tinyInteger('active')->default(1)->after('description'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('formularium_templates', function (Blueprint $table) { + $table->dropColumn('active'); + }); + } +}; From 0585f9f5f038e2463d24702d081e643485cd8f20 Mon Sep 17 00:00:00 2001 From: korospace Date: Fri, 27 Oct 2023 15:23:16 +0700 Subject: [PATCH 04/10] finishing part 1 --- frontend/dashboard/.env.development | 3 +- .../layouts/dashboard/navbar/NavConfig.tsx | 6 + .../CaseManagement/DailyMonitoring/Claim.tsx | 73 +++++ .../DailyMonitoring/Components/ClaimList.tsx | 80 +++++ .../Components/ClaimListRow.tsx | 88 ++++++ .../Components/DailyMonitoringList.tsx | 93 ++++++ .../Components/DailyMonitoringListRow.tsx | 72 +++++ .../Components/DetailMonitoringForm.tsx | 294 ++++++++++++++++++ .../Components/DetailMonitoringList.tsx | 241 ++++++++++++++ .../DailyMonitoring/Model/Functions.ts | 107 +++++++ .../DailyMonitoring/Model/Types.ts | 57 ++++ .../CaseManagement/DailyMonitoring/index.tsx | 48 +++ .../Corporates/DiagnosisExclusion/List.tsx | 6 +- .../src/pages/Master/Diagnosis/History.tsx | 10 +- frontend/dashboard/src/routes/index.tsx | 33 +- 15 files changed, 1201 insertions(+), 10 deletions(-) create mode 100644 frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Claim.tsx create mode 100644 frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/ClaimList.tsx create mode 100644 frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/ClaimListRow.tsx create mode 100644 frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DailyMonitoringList.tsx create mode 100644 frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DailyMonitoringListRow.tsx create mode 100644 frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DetailMonitoringForm.tsx create mode 100644 frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DetailMonitoringList.tsx create mode 100644 frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Model/Functions.ts create mode 100644 frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Model/Types.ts create mode 100644 frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/index.tsx diff --git a/frontend/dashboard/.env.development b/frontend/dashboard/.env.development index 0bf5d75c..1e59ea7f 100644 --- a/frontend/dashboard/.env.development +++ b/frontend/dashboard/.env.development @@ -4,4 +4,5 @@ PORT=8000 REACT_APP_HOST_API_URL="http://lms.test" -VITE_API_URL="https://aso-api.linksehat.dev/api/internal" +# VITE_API_URL="https://aso-api.linksehat.dev/api/internal" +VITE_API_URL="http://localhost:8000/api/internal" diff --git a/frontend/dashboard/src/layouts/dashboard/navbar/NavConfig.tsx b/frontend/dashboard/src/layouts/dashboard/navbar/NavConfig.tsx index 7663ef6c..a43f0b2c 100644 --- a/frontend/dashboard/src/layouts/dashboard/navbar/NavConfig.tsx +++ b/frontend/dashboard/src/layouts/dashboard/navbar/NavConfig.tsx @@ -72,6 +72,12 @@ const navConfig = [ // { title: 'Report', path: '/case-report' }, // ], }, + { + title: 'CASE MANAGEMENT', + children: [ + { title: 'Daily Monitoring', path: '/case_management/daily_monitoring' }, + ], + }, { title: 'CUSTOMER SERVICES', children: [ diff --git a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Claim.tsx b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Claim.tsx new file mode 100644 index 00000000..b77d578e --- /dev/null +++ b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Claim.tsx @@ -0,0 +1,73 @@ +/** + * Core + * ============================================ + */ +import { useEffect, useState } from 'react'; +import { useNavigate, useParams } from 'react-router-dom'; +import { Box, Grid, IconButton, Typography } from '@mui/material'; +import { ArrowBackIosNew } from '@mui/icons-material'; + +/** + * Components + * ============================================ +*/ +// - Global - +import Page from '../../../components/Page'; +// - Local - + +/** + * Utils, Types, Functions + * ============================================ + */ +import { getClaimList } from './Model/Functions'; +import { ClaimListType, MemberDetailType } from './Model/Types'; +import ClaimList from './Components/ClaimList'; + +export default function Claim() { + const navigate = useNavigate() + const { member_id } = useParams(); + + // State + // -------------------- + const [memberDetail, setMemberDetail] = useState(); + const [claimList, setClaimList] = useState(); + + // Use Effect + // -------------------- + useEffect(() => { + loadDataTableData(); + }, []) + + // Load Data + // ------------------- + const loadDataTableData = async () => { + const response = await getClaimList(member_id??''); + + setMemberDetail(response.member_detail); + setClaimList(response.claim_list); + } + + return ( + + + {/* back button */} + + + navigate(`/case_management/daily_monitoring`)} > + + + + + {memberDetail?.name??'_ _ _'} + + + + + {/* tabel claims */} + + + + + + ); +} diff --git a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/ClaimList.tsx b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/ClaimList.tsx new file mode 100644 index 00000000..cc9d7c5f --- /dev/null +++ b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/ClaimList.tsx @@ -0,0 +1,80 @@ +/** + * Core + * ============================================ + */ +import { useEffect, useState } from "react"; +import { Box, Paper, TableContainer, Table, TableHead, TableRow, TableCell, TableBody } from "@mui/material"; + +/** + * Component + * ============================================ + */ +import ClaimListRow from "./ClaimListRow"; + +/** + * Types & Functions + * ============================================ + */ +import { ClaimListType } from "../Model/Types"; + +type Props = { + claim_list: ClaimListType[] | null, +} + +export default function ClaimList({ ...props }: Props) { + // Tabel Style + // -------------------- + const TableHeadStyle = { + fontWeight: 'bold', + }; + + return ( + + + + {/* Head Table */} + + + + Admission Date + Discharge Date + Code + Service Type + Status + + + + + {/* Body Table */} + {props.claim_list == null ? + ( + + + Loading + + + ) + : + ( + props.claim_list.length == 0 ? + ( + + + No Data + + + ) + : + ( + + {props.claim_list.map((row: ClaimListType, index) => ( + + ))} + + ) + )} +
+
+
+ ) +} diff --git a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/ClaimListRow.tsx b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/ClaimListRow.tsx new file mode 100644 index 00000000..2b07815d --- /dev/null +++ b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/ClaimListRow.tsx @@ -0,0 +1,88 @@ +/** + * Core + * ============================================ + */ +import React, { useState } from "react"; +import { useNavigate } from "react-router"; +import { Box, Collapse, MenuItem, TableCell, TableRow, Stack } from "@mui/material"; +import Visibility from '@mui/icons-material/Visibility'; +import AddIcon from '@mui/icons-material/Add'; + +/** + * Component + * ============================================ + */ +// - Global - +import Label from "@/components/Label"; +import TableMoreMenu from '@/components/table/TableMoreMenu'; + +/** + * Utils, Types, Functions + * ============================================ + */ +import { fDate } from "@/utils/formatTime"; +import { ClaimListType } from "../Model/Types"; + +type Props = { + row: ClaimListType, + number: number +} + +export default function ClaimListRow ({ ...props }: Props) { + const navigate = useNavigate() + + return ( + + + td': { borderBottom: '1' } }}> + + + {props.row.admission_dates == "0000-00-00 00:00:00" ? + ('-') + : + ( + + )} + + + {props.row.discharge_dates == "0000-00-00 00:00:00" ? + ('-') + : + ( + + )} + + {props.row.claim_code} + {props.row.service_type} + {props.row.claim_status} + e.stopPropagation()}> + + + navigate(`/case_management/daily_monitoring/${props.row.member_id}/claims/${props.row.claim_code}/list_monitoring`)}> + + View + + navigate(`/case_management/daily_monitoring/${props.row.member_id}/claims/${props.row.claim_code}/add_monitoring`)}> + + Daily Monitoring + + + } /> + + + + + + ); +} diff --git a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DailyMonitoringList.tsx b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DailyMonitoringList.tsx new file mode 100644 index 00000000..500b4f9f --- /dev/null +++ b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DailyMonitoringList.tsx @@ -0,0 +1,93 @@ +/** + * Core + * ============================================ + */ +import { useEffect, useState } from "react"; +import { Box, Paper, TableContainer, Table, TableHead, TableRow, TableCell, TableBody } from "@mui/material"; + +/** + * Types & Functions + * ============================================ + */ +import { getDailyMonitoringList } from "../Model/Functions"; +import { DailyMonitoringListType } from "../Model/Types"; +import DailyMonitoringListRow from "./DailyMonitoringListRow"; + +export default function DailyMonitoringList() { + // State + // -------------------- + const [dataTableIsLoading, setDataTableLoading] = useState(true); + const [dataTableData, setDataTableData] = useState([]); + + // Tabel Style + // -------------------- + const TableHeadStyle = { + fontWeight: 'bold', + }; + + // Use Effect + // -------------------- + useEffect(() => { + loadDataTableData(); + }, []) + + // Load Data + // ------------------- + const loadDataTableData = async () => { + setDataTableLoading(true); + + const response = await getDailyMonitoringList(); + + setDataTableLoading(false); + setDataTableData(response); + } + + return ( + + + + {/* Head Table */} + + + + Member ID + Name + Start Date + End Date + + + + + {/* Body Table */} + {dataTableIsLoading ? + ( + + + Loading + + + ) + : + ( + dataTableData.length == 0 ? + ( + + + No Data + + + ) + : + ( + + {dataTableData.map((row: DailyMonitoringListType, index) => ( + + ))} + + ) + )} +
+
+
+ ) +} diff --git a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DailyMonitoringListRow.tsx b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DailyMonitoringListRow.tsx new file mode 100644 index 00000000..40dc5395 --- /dev/null +++ b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DailyMonitoringListRow.tsx @@ -0,0 +1,72 @@ +/** + * Core + * ============================================ + */ +import React, { useState } from "react"; +import { useNavigate } from "react-router"; +import { Box, Collapse, MenuItem, TableCell, TableRow, Stack } from "@mui/material"; +import Visibility from '@mui/icons-material/Visibility'; + +/** + * Component + * ============================================ + */ +// - Global - +import Label from "@/components/Label"; +import TableMoreMenu from '@/components/table/TableMoreMenu'; + +/** + * Utils, Types, Functions + * ============================================ + */ +import { fDate } from "@/utils/formatTime"; +import { DailyMonitoringListType } from "../Model/Types"; + +type Props = { + row: DailyMonitoringListType, + number: number +} + +export default function DailyMonitoringListRow ({ ...props }: Props) { + const navigate = useNavigate() + + return ( + + + td': { borderBottom: '1' } }}> + + {props.row.member_id} + {props.row.name} + + + + + + + e.stopPropagation()}> + + + navigate(`/case_management/daily_monitoring/${props.row.member_id}/claims`)}> + + View + + + } /> + + + + + + ); +} diff --git a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DetailMonitoringForm.tsx b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DetailMonitoringForm.tsx new file mode 100644 index 00000000..2919085e --- /dev/null +++ b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DetailMonitoringForm.tsx @@ -0,0 +1,294 @@ +/** + * Core + * ============================================ + */ +import { useFieldArray, useForm } from 'react-hook-form'; +import { useNavigate, useParams } from 'react-router-dom'; +import { Box, IconButton, Typography, Grid, Card, Button } from '@mui/material'; +import { LoadingButton } from "@mui/lab"; + +/** + * Components + * ============================================ +*/ +import Page from '@/components/Page'; +import { FormProvider, RHFTextField } from '@/components/hook-form'; + +/** + * Icon + * ============================================ + */ +import ArrowBackIosNew from '@mui/icons-material/ArrowBackIosNew'; +import AddIcon from '@mui/icons-material/Add'; +import RemoveIcon from '@mui/icons-material/Remove'; + +/** + * Utils, Types, Functions + * ============================================ + */ +import { AddClaimDetail } from '../Model/Functions'; +import { DetailMonitoringListType} from '../Model/Types'; + +export default function DetailMonitoringList() { + const { member_id, claim_code } = useParams(); + const navigate = useNavigate() + const pageTitle = claim_code??'_ _ _ _'; + + // setup form + // ==================================== + const defaultValues: any = { + subject : '', + body_temperature: '', + sistole : '', + diastole : '', + respiration_rate: '', + complaints : '', + analysis : '', + medical_plan : [{ + medical_plan_str: '' + }] + }; + + const methods = useForm({ + defaultValues + }); + + const {fields, append, remove} = useFieldArray({name: 'medical_plan',control: methods.control}) + + const { handleSubmit, reset, formState: { isDirty, isSubmitting } } = methods; + + // Submit Form + // ===================================== + const submitHandler = async (data: DetailMonitoringListType) => { + console.log(claim_code); + + const response = await AddClaimDetail(claim_code??'', data); + + if (response == true) { + reset(); + } + } + + return ( + + + navigate(`/case_management/daily_monitoring/${member_id}/claims`)} > + + + + + {pageTitle} + + + + + + + + {/* Subject */} + + + + + Subject* : + + + + + + + + + {/* Objectif */} + + + + + Objectif + + + + + + + Body Temperature* : + + + + + Sistole* : + + + + + Diastole* : + + + + + Respiration Rate* : + + + + + + + + + + + + Cel + + + + + + + + mm[Hg] + + + + + + + + mm[Hg] + + + + + + + + /min + + + + + + + + {/* Complaints */} + + + + + Complaints* : + + + + + + + + + {/* Analysis */} + + + + + Analysis* : + + + + + + + + + {/* Medical Plan */} + + + + + Medical Plan* : + + + + { + fields.map((field,index) => { + return ( + + + + + { + index == (fields.length-1) ? + ( + + append({medical_plan_str: ''})}> + + + + ) + : + ( + + remove(index)}> + + + + ) + } + + ) + }) + } + + + + + {/* Button Cancle & Save */} + + + + + + Save Changes + + + + + + + + + + ); +} diff --git a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DetailMonitoringList.tsx b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DetailMonitoringList.tsx new file mode 100644 index 00000000..18829123 --- /dev/null +++ b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DetailMonitoringList.tsx @@ -0,0 +1,241 @@ +/** + * Core + * ============================================ + */ +import { useEffect, useState } from 'react'; +import { useFieldArray, useForm } from 'react-hook-form'; +import { useNavigate, useParams } from 'react-router-dom'; +import { Box, IconButton, Typography, Grid, Card, List, ListItem } from '@mui/material'; +import { LoadingButton } from "@mui/lab"; + +/** + * Components + * ============================================ +*/ +// - Global - +import Page from '@/components/Page'; +import Label from "@/components/Label"; + +/** + * Icon + * ============================================ + */ +import ArrowBackIosNew from '@mui/icons-material/ArrowBackIosNew'; +import FiberManualRecord from '@mui/icons-material/FiberManualRecord'; + +/** + * Utils, Types, Functions + * ============================================ + */ +import { fDate } from "@/utils/formatTime"; +import { AddClaimDetail, getClaimDetailList } from '../Model/Functions'; +import { DetailMonitoringListType } from '../Model/Types'; + + +export default function DetailMonitoringList() { + const { member_id, claim_code } = useParams(); + const navigate = useNavigate() + const pageTitle = claim_code??'_ _ _ _'; + + // State + // -------------------- + const [detailMonitoringList, setDetailMonitoringList] = useState(); + + // Use Effect + // -------------------- + useEffect(() => { + loadDataTableData(); + }, []) + + // Load Data + // ------------------- + const loadDataTableData = async () => { + const response = await getClaimDetailList(claim_code??''); + + setDetailMonitoringList(response); + } + + return ( + + + {/* back button */} + + + navigate(`/case_management/daily_monitoring/${member_id}/claims`)} > + + + + + {pageTitle} + + + + + {/* tabel claims */} + + + { + detailMonitoringList?.map((row, index) => { + return ( + + + {/* card header */} + + + + + {/* card body */} + + + + + + Subject : + + + + + {row.subject} + + + + + + + + + + Object : + + + + + + + Body Temperature + + + + + {row.body_temperature} + + + + + Sistole + + + + + {row.sistole} mm[Hg] + + + + + Diastole + + + + + {row.diastole} mm[Hg] + + + + + Respiration Rate + + + + + {row.respiration_rate} / min + + + + + + + + + + + + Subject : + + + + + {row.subject} + + + + + + + + + + Analysis : + + + + + {row.analysis} + + + + + + + + + + Complaints : + + + + + {row.complaints} + + + + + + + + + + Medical Plan : + + + + + { + row.medical_plan.map((str, index) => { + return ( + + {str} + + ) + }) + } + + + + + + + + ) + }) + } + + + + + ); +} diff --git a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Model/Functions.ts b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Model/Functions.ts new file mode 100644 index 00000000..40aafe9e --- /dev/null +++ b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Model/Functions.ts @@ -0,0 +1,107 @@ +import axios from '@/utils/axios'; +import { enqueueSnackbar } from 'notistack'; +import { DailyMonitoringListType, DetailMonitoringListType, ResponseListingClaimType } from "./Types"; + +/** + * Listing Daily Monitoring + */ +export const getDailyMonitoringList = async ( ): Promise => { + const response = await axios.get('/case_management/daily_monitoring/memberlist') + .then((res) =>{ + return res.data.data.member_list; + }) + .catch((res) => { + enqueueSnackbar(res.response.data.message, { + variant: 'error', + }); + + return []; + }); + + return response; +}; + +/** + * Listing Claim + */ +export const getClaimList = async ( member_id: string ): Promise => { + const response = await axios.get(`/case_management/daily_monitoring/claimlist/${member_id}`) + .then((res) =>{ + return res.data.data; + }) + .catch((res) => { + enqueueSnackbar(res.response.data.message, { + variant: 'error', + }); + + return null; + }); + + return response; +}; + +/** + * Add Claim Detail + */ +export const AddClaimDetail = async ( claim_code: string,data: DetailMonitoringListType ): Promise => { + const response = await axios.post(`/case_management/daily_monitoring/detail/${claim_code}/add`, { + ...data + }) + .then((res) =>{ + enqueueSnackbar(res.data.message, { + variant: 'success', + }); + + return true; + }) + .catch((res) => { + if (res.response.status == 400) { + let arr_message = res.response.data.message; + + for (const key in arr_message) { + enqueueSnackbar(arr_message[key][0], { + variant: 'warning', + }); + } + } + else { + enqueueSnackbar(res.response.data.message, { + variant: 'error', + }); + } + + return false; + }); + + return response; +}; + +/** + * Get Claim Detail List + */ +export const getClaimDetailList = async ( claim_code: string ): Promise => { + const response = await axios.get(`/case_management/daily_monitoring/detail/${claim_code}/list`) + .then((res) =>{ + return res.data.data.detail_list; + }) + .catch((res) => { + if (res.response.status == 400) { + let arr_message = res.response.data.message; + + for (const key in arr_message) { + enqueueSnackbar(arr_message[key][0], { + variant: 'warning', + }); + } + } + else { + enqueueSnackbar(res.response.data.message, { + variant: 'error', + }); + } + + return []; + }); + + return response; +}; diff --git a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Model/Types.ts b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Model/Types.ts new file mode 100644 index 00000000..d6c1b3be --- /dev/null +++ b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Model/Types.ts @@ -0,0 +1,57 @@ +/** + * List Daily Monitoring + */ +export type DailyMonitoringListType = { + member_id : string, + name : string, + startdate : string, + enddate : string, +} + +/** + * Response Listing Claim + */ +export type ResponseListingClaimType = { + member_detail : MemberDetailType, + claim_list : ClaimListType[], +} + +/** + * Member Detail + */ +export type MemberDetailType = { + id : string, + member_id : string, + name : string, +} + +/** + * List Claim + */ +export type ClaimListType = { + claim_id : number, + admission_dates : string, + discharge_dates : string, + claim_code : string, + claim_status : string, + service_type : string, + member_id : string +} + +/** + * Detail Claim + */ +export type DetailMonitoringListType = { + id : string|null, + claim_id : string|null, + claim_code : string, + subject : string, + body_temperature: string, + respiration_rate: string, + sistole : string, + diastole : string + analysis : string, + complaints : string, + medical_plan : string[], + created_at : string|null +} diff --git a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/index.tsx b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/index.tsx new file mode 100644 index 00000000..d0ed4b43 --- /dev/null +++ b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/index.tsx @@ -0,0 +1,48 @@ +/** + * Core + * ============================================ + */ +import { Box, Grid } from '@mui/material'; + +/** + * Components + * ============================================ +*/ +// - Global - +import Page from '../../../components/Page'; +import HeaderBreadcrumbs from "../../../components/HeaderBreadcrumbs"; +// - Local - +import DailyMonitoringList from './Components/DailyMonitoringList'; + +export default function DailyMonitoring() { + const pageTitle = "Daily Monitoring"; + + return ( + + + {/* page header */} + + + + + {/* tabel daily monitoring */} + + + + + + ); +} diff --git a/frontend/dashboard/src/pages/Corporates/DiagnosisExclusion/List.tsx b/frontend/dashboard/src/pages/Corporates/DiagnosisExclusion/List.tsx index aeba400e..0bb45008 100644 --- a/frontend/dashboard/src/pages/Corporates/DiagnosisExclusion/List.tsx +++ b/frontend/dashboard/src/pages/Corporates/DiagnosisExclusion/List.tsx @@ -984,7 +984,7 @@ export default function List(props: any) { Status - + navigate(`/corporates/${corporate_id}/diagnosis-exclusions/history`)}> @@ -999,7 +999,7 @@ export default function List(props: any) { {dataTableIsLoading ? ( - + Loading @@ -1007,7 +1007,7 @@ export default function List(props: any) { ) : dataTableData.data.length == 0 ? ( - + No Data diff --git a/frontend/dashboard/src/pages/Master/Diagnosis/History.tsx b/frontend/dashboard/src/pages/Master/Diagnosis/History.tsx index 1574ccf6..0f514a2b 100644 --- a/frontend/dashboard/src/pages/Master/Diagnosis/History.tsx +++ b/frontend/dashboard/src/pages/Master/Diagnosis/History.tsx @@ -86,7 +86,7 @@ export default function CustomizedAccordions() { setExpanded(newExpanded ? panel : false); }; const pageTitle = 'Diagnosis History'; - + const { themeStretch } = useSettings(); const { id } = useParams(); @@ -152,10 +152,10 @@ export default function CustomizedAccordions() { {Object.entries(item.old_values).map(([key, value]) => { let renderedValue; - if (key === 'deleted_by' || - key === 'deleted_at' || - key === 'created_by' || - key === 'created_at' || + if (key === 'deleted_by' || + key === 'deleted_at' || + key === 'created_by' || + key === 'created_at' || key === 'updated_by' || key === 'description'|| key === 'version'|| diff --git a/frontend/dashboard/src/routes/index.tsx b/frontend/dashboard/src/routes/index.tsx index 2b4a159b..737ed901 100644 --- a/frontend/dashboard/src/routes/index.tsx +++ b/frontend/dashboard/src/routes/index.tsx @@ -216,7 +216,28 @@ export default function Router() { path: 'corporates/:corporate_id/edit', element: , }, - + { + path: 'case_management', // Case Management + element: '', + children: [ + { + path: 'daily_monitoring', + element: + }, + { + path: 'daily_monitoring/:member_id/claims', + element: + }, + { + path: 'daily_monitoring/:member_id/claims/:claim_code/add_monitoring', + element: + }, + { + path: 'daily_monitoring/:member_id/claims/:claim_code/list_monitoring', + element: + }, + ] + }, { path: 'corporates/:corporate_id/corporate-plans/create', element: , @@ -507,6 +528,16 @@ const CorporateFormularium = Loadable(lazy(() => import('../pages/Corporates/For const CorporateFormulariumCreate = Loadable(lazy(() => import('../pages/Corporates/Formularium/New/CreateForm'))); const CorporateFormulariumHistory = Loadable(lazy(() => import('../pages/Corporates/Formularium/New/History'))) +/** + * Case Management + * ------------------------------- + */ +// Daily Monitoring +const DailyMonitoring = Loadable(lazy(() => import('../pages/CaseManagement/DailyMonitoring/index'))) +const DailyMonitoringClaims = Loadable(lazy(() => import('../pages/CaseManagement/DailyMonitoring/Claim'))) +const DetailMonitoringForm = Loadable(lazy(() => import('../pages/CaseManagement/DailyMonitoring/Components/DetailMonitoringForm'))) +const DetailMonitoringList = Loadable(lazy(() => import('../pages/CaseManagement/DailyMonitoring/Components/DetailMonitoringList'))) + const MasterDiagnosisTemplate = Loadable(lazy(() => import('../pages/Master/Diagnosis/Master/Index'))); const MasterDiagnosisTemplateCreate = Loadable(lazy(() => import('../pages/Master/Diagnosis/Master/CreateUpdate'))); const MasterDiagnosisTemplateHistories = Loadable( From 670f62328beaeabe2a3b97e3b41a0648a36a42a3 Mon Sep 17 00:00:00 2001 From: korospace Date: Fri, 27 Oct 2023 15:28:02 +0700 Subject: [PATCH 05/10] membuat endpoint daily monitoring --- .../Api/DailyMonitoringController.php | 192 ++++++++++++++++++ app/Models/ClaimDailyMonitoring.php | 59 ++++++ app/Models/MedicalPlan.php | 18 ++ ...32_create_claim_daily_monitoring_table.php | 39 ++++ ...10_27_112206_create_medical_plan_table.php | 33 +++ 5 files changed, 341 insertions(+) create mode 100644 Modules/Internal/Http/Controllers/Api/DailyMonitoringController.php create mode 100644 app/Models/ClaimDailyMonitoring.php create mode 100644 app/Models/MedicalPlan.php create mode 100644 database/migrations/2023_10_27_111432_create_claim_daily_monitoring_table.php create mode 100644 database/migrations/2023_10_27_112206_create_medical_plan_table.php diff --git a/Modules/Internal/Http/Controllers/Api/DailyMonitoringController.php b/Modules/Internal/Http/Controllers/Api/DailyMonitoringController.php new file mode 100644 index 00000000..55fd376a --- /dev/null +++ b/Modules/Internal/Http/Controllers/Api/DailyMonitoringController.php @@ -0,0 +1,192 @@ + ':attribute harus diisi', + 'integer' => ':attribute harus angka', + 'unique' => ':attribute (:input) sudah ada', + 'max' => ':attribute maximal :max karakter', + 'exists' => ':attribute (:input) tidak ditemukan', + 'numeric' => ':attribute harus angka', + 'digits_between'=> ':attribute maximal :max digit minimal :min digit' + ]; + } + + /** + * Member List + */ + public function GetMemberList() + { + $memberList = DB::table('claims') + ->leftJoin('members', 'claims.member_id', '=', 'members.id') + ->leftJoin('member_plans', 'members.id', '=', 'member_plans.id') + ->select('members.member_id','members.name','member_plans.start AS startdate','member_plans.end AS enddate') + ->groupBy('claims.member_id') + ->orderBy('claims.created_at', 'desc') + ->get(); + + return response()->json([ + 'error' => false, + 'message' => "success", + 'data' => [ + 'member_list'=> $memberList, + ] + ],200); + } + + /** + * Claim List - by member id + */ + public function GetClaimList(Request $request, $member_id) + { + $memberDetail = DB::table('members') + ->select('id','member_id','name') + ->where('member_id', $member_id) + ->first(); + + $claimList = DB::table('claims') + ->leftJoin('claim_requests', 'claims.claim_request_id', '=', 'claim_requests.id') + ->leftJoin('services', 'claim_requests.service_code', '=', 'services.code') + ->leftJoin('members', 'claims.member_id', '=', 'members.id') + ->select('claims.id AS claim_id','claims.admission_dates','claims.discharge_dates','claim_requests.code AS claim_code','services.name AS service_type','claims.status AS claim_status','members.member_id',) + ->where("claims.member_id", "=", $memberDetail->id) + ->get(); + + return response()->json([ + 'error' => false, + 'message' => "success", + 'data' => [ + 'member_detail'=> $memberDetail, + 'claim_list' => $claimList, + ] + ],200); + } + + /** + * Detail Monitoring List - by claim_code + */ + public function GetDetailMonitoringList(Request $request, $claim_code) + { + // get claim request + $claim_request = DB::table('claim_requests') + ->select('id') + ->where('code', $claim_code) + ->first(); + + // get claim + $claim = DB::table('claims') + ->select('id') + ->where('claim_request_id', empty($claim_request)==false ? $claim_request->id : '') + ->first(); + + $detail_list = ClaimDailyMonitoring::where('claim_id', empty($claim) == false ? $claim->id : '')->get()->makeHidden(['updated_at']); + + return response()->json([ + 'error' => false, + 'message' => "success", + 'data' => [ + 'detail_list'=> $detail_list, + ] + ],200); + } + + /** + * Add Detail Monitoring List + */ + public function AddDetailMonitoringList(Request $request, $claim_code) + { + $request->merge(['claim_code' => $claim_code]); + + // validation rule + $validator = Validator::make($request->all(),[ + 'claim_code' => 'required|exists:claim_requests,code', + 'subject' => 'required', + 'sistole' => 'required|numeric', + 'diastole' => 'required|numeric', + 'body_temperature' => 'required|numeric', + 'respiration_rate' => 'required|numeric', + 'analysis' => 'required', + 'complaints' => 'required', + 'medical_plan' => 'required', + ],$this->messages()); + + // validation error + if ($validator->fails()) { + return response()->json([ + 'error' => true, + 'message' => $validator->getMessageBag() + ],400); + } + + // get claim request + $claim_request = DB::table('claim_requests') + ->select('id') + ->where('code', $claim_code) + ->first(); + + // get claim + $claim = DB::table('claims') + ->select('id') + ->where('claim_request_id', $claim_request->id) + ->first(); + + DB::beginTransaction(); + + try { + // insert claim daily monitoring + $db_response = ClaimDailyMonitoring::create([ + 'claim_id' => $claim->id, + 'subject' => $request->subject, + 'sistole' => $request->sistole, + 'diastole' => $request->diastole, + 'body_temperature' => $request->body_temperature, + 'respiration_rate' => $request->respiration_rate, + 'analysis' => $request->analysis, + 'complaints' => $request->complaints, + ]); + + // insert medical plan + foreach ($request->medical_plan as $row) { + MedicalPlan::create([ + 'claim_daily_monitoring_id' => $db_response->id, + 'plan' => $row['medical_plan_str'], + ]); + } + + DB::commit(); + + return response()->json([ + 'error' => false, + 'message' => "success", + 'data' => [] + ],200); + } + catch (Exception $e) { + DB::rollBack(); + + return response()->json([ + 'error' => true, + 'message' => $e->getMessage(), + 'data' => [] + ],500); + } + } +} diff --git a/app/Models/ClaimDailyMonitoring.php b/app/Models/ClaimDailyMonitoring.php new file mode 100644 index 00000000..1fd11fb9 --- /dev/null +++ b/app/Models/ClaimDailyMonitoring.php @@ -0,0 +1,59 @@ +attributes['body_temperature'], 0); + } + + public function getSistoleAttribute() + { + return round($this->attributes['sistole'], 0); + } + + public function getDiastoleAttribute() + { + return round($this->attributes['diastole'], 0); + } + + public function getRespirationRateAttribute() + { + return round($this->attributes['respiration_rate'], 0); + } + + public function getMedicalPlanAttribute() + { + $arr_medical_plan = []; + $medical_plan = DB::table('medical_plan')->where('claim_daily_monitoring_id','=',$this->attributes['id'])->get(); + + foreach ($medical_plan as $row) { + $arr_medical_plan[] = $row->plan; + } + + return $arr_medical_plan; + } +} diff --git a/app/Models/MedicalPlan.php b/app/Models/MedicalPlan.php new file mode 100644 index 00000000..41bc2570 --- /dev/null +++ b/app/Models/MedicalPlan.php @@ -0,0 +1,18 @@ +bigIncrements('id'); + $table->integer('claim_id'); + $table->text('subject'); + $table->decimal('body_temperature', 11, 2); + $table->decimal('respiration_rate', 11, 2); + $table->decimal('sistole', 11, 2); + $table->decimal('diastole', 11, 2); + $table->text('analysis'); + $table->text('complaints'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('claim_daily_monitoring'); + } +}; diff --git a/database/migrations/2023_10_27_112206_create_medical_plan_table.php b/database/migrations/2023_10_27_112206_create_medical_plan_table.php new file mode 100644 index 00000000..35306662 --- /dev/null +++ b/database/migrations/2023_10_27_112206_create_medical_plan_table.php @@ -0,0 +1,33 @@ +bigIncrements('id'); + $table->bigInteger('claim_daily_monitoring_id'); + $table->text('plan'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('medical_plan'); + } +}; From 0eff99c4561bcd768d19b1ad42c2a31ec60b85f8 Mon Sep 17 00:00:00 2001 From: korospace Date: Fri, 27 Oct 2023 15:43:32 +0700 Subject: [PATCH 06/10] finishing part 2 --- .../Http/Controllers/Api/DailyMonitoringController.php | 3 ++- Modules/Internal/Routes/api.php | 10 ++++++++++ config/database.php | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Modules/Internal/Http/Controllers/Api/DailyMonitoringController.php b/Modules/Internal/Http/Controllers/Api/DailyMonitoringController.php index 55fd376a..3723de92 100644 --- a/Modules/Internal/Http/Controllers/Api/DailyMonitoringController.php +++ b/Modules/Internal/Http/Controllers/Api/DailyMonitoringController.php @@ -68,6 +68,7 @@ class DailyMonitoringController extends Controller ->leftJoin('members', 'claims.member_id', '=', 'members.id') ->select('claims.id AS claim_id','claims.admission_dates','claims.discharge_dates','claim_requests.code AS claim_code','services.name AS service_type','claims.status AS claim_status','members.member_id',) ->where("claims.member_id", "=", $memberDetail->id) + ->orderBy("claims.created_at", "desc") ->get(); return response()->json([ @@ -97,7 +98,7 @@ class DailyMonitoringController extends Controller ->where('claim_request_id', empty($claim_request)==false ? $claim_request->id : '') ->first(); - $detail_list = ClaimDailyMonitoring::where('claim_id', empty($claim) == false ? $claim->id : '')->get()->makeHidden(['updated_at']); + $detail_list = ClaimDailyMonitoring::where('claim_id', empty($claim) == false ? $claim->id : '')->orderBy("created_at", "desc")->get()->makeHidden(['updated_at']); return response()->json([ 'error' => false, diff --git a/Modules/Internal/Routes/api.php b/Modules/Internal/Routes/api.php index 6c664350..57d3db76 100644 --- a/Modules/Internal/Routes/api.php +++ b/Modules/Internal/Routes/api.php @@ -37,6 +37,7 @@ use Modules\Internal\Http\Controllers\Api\PrescriptionController; use Modules\Internal\Http\Controllers\Api\SpecialityController; use Modules\Internal\Http\Controllers\Api\VillageController; use Modules\Internal\Http\Controllers\Api\AuditTrailController; +use Modules\Internal\Http\Controllers\Api\DailyMonitoringController; use Modules\Internal\Http\Controllers\ClaimEncounterController; /* @@ -147,6 +148,15 @@ Route::prefix('internal')->group(function () { // Audittrail Route::get('audittrail/{corporate_id}', [AuditTrailController::class, 'index']); + Route::prefix('case_management')->group(function () { + Route::prefix('daily_monitoring')->group(function () { + Route::get('memberlist', [DailyMonitoringController::class, 'GetMemberList']); + Route::get('claimlist/{member_id}', [DailyMonitoringController::class, 'GetClaimList']); + Route::get('detail/{claim_code}/list', [DailyMonitoringController::class, 'GetDetailMonitoringList']); + Route::post('detail/{claim_code}/add', [DailyMonitoringController::class, 'AddDetailMonitoringList']); + }); + }); + Route::get('master/diagnosis-template', [DiagnosisTemplateController::class, 'index']); Route::get('master/diagnosis-template/search', [DiagnosisTemplateController::class, 'search']); Route::post('master/diagnosis-template/store', [DiagnosisTemplateController::class, 'store']); diff --git a/config/database.php b/config/database.php index e529ac2f..2b1a1a86 100644 --- a/config/database.php +++ b/config/database.php @@ -56,7 +56,7 @@ return [ 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'prefix_indexes' => true, - 'strict' => env('DB_STRICT', true), + 'strict' => env('DB_STRICT', false), 'engine' => null, 'options' => extension_loaded('pdo_mysql') ? array_filter([ PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), From 4ec2ca9bb2b550a3d01ee1ab4ae3a4afde0d5cbf Mon Sep 17 00:00:00 2001 From: korospace Date: Fri, 27 Oct 2023 16:04:38 +0700 Subject: [PATCH 07/10] memperbaiki handle error front end feature/daily-monitoring --- .../DailyMonitoring/Model/Functions.ts | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Model/Functions.ts b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Model/Functions.ts index 40aafe9e..8ffd0eb8 100644 --- a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Model/Functions.ts +++ b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Model/Functions.ts @@ -11,7 +11,7 @@ export const getDailyMonitoringList = async ( ): Promise { - enqueueSnackbar(res.response.data.message, { + enqueueSnackbar("server error !", { variant: 'error', }); @@ -30,7 +30,7 @@ export const getClaimList = async ( member_id: string ): Promise { - enqueueSnackbar(res.response.data.message, { + enqueueSnackbar("server error !", { variant: 'error', }); @@ -65,7 +65,7 @@ export const AddClaimDetail = async ( claim_code: string,data: DetailMonitoringL } } else { - enqueueSnackbar(res.response.data.message, { + enqueueSnackbar("server error !", { variant: 'error', }); } @@ -85,20 +85,9 @@ export const getClaimDetailList = async ( claim_code: string ): Promise { - if (res.response.status == 400) { - let arr_message = res.response.data.message; - - for (const key in arr_message) { - enqueueSnackbar(arr_message[key][0], { - variant: 'warning', - }); - } - } - else { - enqueueSnackbar(res.response.data.message, { - variant: 'error', - }); - } + enqueueSnackbar("server error !", { + variant: 'error', + }); return []; }); From b6095f13018483437525034f6658a2c5b4ba9572 Mon Sep 17 00:00:00 2001 From: korospace Date: Fri, 27 Oct 2023 18:09:27 +0700 Subject: [PATCH 08/10] progress feature/laboratorium-result --- .../layouts/dashboard/navbar/NavConfig.tsx | 1 + .../DailyMonitoring/Components/ClaimList.tsx | 1 - .../CaseManagement/DailyMonitoring/index.tsx | 2 +- .../LaboratoriumResult/Claim.tsx | 73 +++++++++++++++ .../Components/ClaimList.tsx | 79 ++++++++++++++++ .../Components/ClaimListRow.tsx | 88 ++++++++++++++++++ .../Components/LaboratoriumResultList.tsx | 93 +++++++++++++++++++ .../Components/LaboratoriumResultListRow.tsx | 72 ++++++++++++++ .../LaboratoriumResult/Model/Functions.ts | 41 ++++++++ .../LaboratoriumResult/Model/Types.ts | 39 ++++++++ .../LaboratoriumResult/index.tsx | 48 ++++++++++ frontend/dashboard/src/routes/index.tsx | 13 ++- 12 files changed, 547 insertions(+), 3 deletions(-) create mode 100644 frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Claim.tsx create mode 100644 frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Components/ClaimList.tsx create mode 100644 frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Components/ClaimListRow.tsx create mode 100644 frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Components/LaboratoriumResultList.tsx create mode 100644 frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Components/LaboratoriumResultListRow.tsx create mode 100644 frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Model/Functions.ts create mode 100644 frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Model/Types.ts create mode 100644 frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/index.tsx diff --git a/frontend/dashboard/src/layouts/dashboard/navbar/NavConfig.tsx b/frontend/dashboard/src/layouts/dashboard/navbar/NavConfig.tsx index af7799b5..b6ea734b 100644 --- a/frontend/dashboard/src/layouts/dashboard/navbar/NavConfig.tsx +++ b/frontend/dashboard/src/layouts/dashboard/navbar/NavConfig.tsx @@ -76,6 +76,7 @@ const navConfig = [ title: 'CASE MANAGEMENT', children: [ { title: 'Daily Monitoring', path: '/case_management/daily_monitoring' }, + { title: 'Laboratorium Result', path: '/case_management/laboratorium_result' }, ], }, { diff --git a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/ClaimList.tsx b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/ClaimList.tsx index cc9d7c5f..b9363926 100644 --- a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/ClaimList.tsx +++ b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/ClaimList.tsx @@ -2,7 +2,6 @@ * Core * ============================================ */ -import { useEffect, useState } from "react"; import { Box, Paper, TableContainer, Table, TableHead, TableRow, TableCell, TableBody } from "@mui/material"; /** diff --git a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/index.tsx b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/index.tsx index d0ed4b43..fb989405 100644 --- a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/index.tsx +++ b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/index.tsx @@ -31,7 +31,7 @@ export default function DailyMonitoring() { href: '/dashboard', }, { - name: 'Daily Monitoring', + name: pageTitle, href: '/case_management/daily_monitoring', }, ]} diff --git a/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Claim.tsx b/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Claim.tsx new file mode 100644 index 00000000..0388bc25 --- /dev/null +++ b/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Claim.tsx @@ -0,0 +1,73 @@ +/** + * Core + * ============================================ + */ +import { useEffect, useState } from 'react'; +import { useNavigate, useParams } from 'react-router-dom'; +import { Box, Grid, IconButton, Typography } from '@mui/material'; +import { ArrowBackIosNew } from '@mui/icons-material'; + +/** + * Components + * ============================================ +*/ +// - Global - +import Page from '../../../components/Page'; +// - Local - + +/** + * Utils, Types, Functions + * ============================================ + */ +import { getClaimList } from './Model/Functions'; +import { ClaimListType, MemberDetailType } from './Model/Types'; +import ClaimList from './Components/ClaimList'; + +export default function Claim() { + const navigate = useNavigate() + const { member_id } = useParams(); + + // State + // -------------------- + const [memberDetail, setMemberDetail] = useState(); + const [claimList, setClaimList] = useState(); + + // Use Effect + // -------------------- + useEffect(() => { + loadDataTableData(); + }, []) + + // Load Data + // ------------------- + const loadDataTableData = async () => { + const response = await getClaimList(member_id??''); + + setMemberDetail(response.member_detail); + setClaimList(response.claim_list); + } + + return ( + + + {/* back button */} + + + navigate(`/case_management/laboratorium_result`)} > + + + + + {memberDetail?.name??'_ _ _'} + + + + + {/* tabel claims */} + + + + + + ); +} diff --git a/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Components/ClaimList.tsx b/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Components/ClaimList.tsx new file mode 100644 index 00000000..b9363926 --- /dev/null +++ b/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Components/ClaimList.tsx @@ -0,0 +1,79 @@ +/** + * Core + * ============================================ + */ +import { Box, Paper, TableContainer, Table, TableHead, TableRow, TableCell, TableBody } from "@mui/material"; + +/** + * Component + * ============================================ + */ +import ClaimListRow from "./ClaimListRow"; + +/** + * Types & Functions + * ============================================ + */ +import { ClaimListType } from "../Model/Types"; + +type Props = { + claim_list: ClaimListType[] | null, +} + +export default function ClaimList({ ...props }: Props) { + // Tabel Style + // -------------------- + const TableHeadStyle = { + fontWeight: 'bold', + }; + + return ( + + + + {/* Head Table */} + + + + Admission Date + Discharge Date + Code + Service Type + Status + + + + + {/* Body Table */} + {props.claim_list == null ? + ( + + + Loading + + + ) + : + ( + props.claim_list.length == 0 ? + ( + + + No Data + + + ) + : + ( + + {props.claim_list.map((row: ClaimListType, index) => ( + + ))} + + ) + )} +
+
+
+ ) +} diff --git a/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Components/ClaimListRow.tsx b/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Components/ClaimListRow.tsx new file mode 100644 index 00000000..60b633ff --- /dev/null +++ b/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Components/ClaimListRow.tsx @@ -0,0 +1,88 @@ +/** + * Core + * ============================================ + */ +import React, { useState } from "react"; +import { useNavigate } from "react-router"; +import { Box, Collapse, MenuItem, TableCell, TableRow, Stack } from "@mui/material"; +import Visibility from '@mui/icons-material/Visibility'; +import AddIcon from '@mui/icons-material/Add'; + +/** + * Component + * ============================================ + */ +// - Global - +import Label from "@/components/Label"; +import TableMoreMenu from '@/components/table/TableMoreMenu'; + +/** + * Utils, Types, Functions + * ============================================ + */ +import { fDate } from "@/utils/formatTime"; +import { ClaimListType } from "../Model/Types"; + +type Props = { + row: ClaimListType, + number: number +} + +export default function ClaimListRow ({ ...props }: Props) { + const navigate = useNavigate() + + return ( + + + td': { borderBottom: '1' } }}> + + + {props.row.admission_dates == "0000-00-00 00:00:00" ? + ('-') + : + ( + + )} + + + {props.row.discharge_dates == "0000-00-00 00:00:00" ? + ('-') + : + ( + + )} + + {props.row.claim_code} + {props.row.service_type} + {props.row.claim_status} + e.stopPropagation()}> + + + navigate(`/case_management/laboratorium_result/${props.row.member_id}/claims/${props.row.claim_code}/list_lab_result`)}> + + View + + navigate(`/case_management/laboratorium_result/${props.row.member_id}/claims/${props.row.claim_code}/add_lab_result`)}> + + Daily Monitoring + + + } /> + + + + + + ); +} diff --git a/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Components/LaboratoriumResultList.tsx b/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Components/LaboratoriumResultList.tsx new file mode 100644 index 00000000..accfc853 --- /dev/null +++ b/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Components/LaboratoriumResultList.tsx @@ -0,0 +1,93 @@ +/** + * Core + * ============================================ + */ +import { useEffect, useState } from "react"; +import { Box, Paper, TableContainer, Table, TableHead, TableRow, TableCell, TableBody } from "@mui/material"; + +/** + * Types & Functions + * ============================================ + */ +import { getDailyMonitoringList } from "../Model/Functions"; +import { LaboratoriumResultListType } from "../Model/Types"; +import LaboratoriumListRow from "./LaboratoriumResultListRow"; + +export default function LaboratoriumResultList() { + // State + // -------------------- + const [dataTableIsLoading, setDataTableLoading] = useState(true); + const [dataTableData, setDataTableData] = useState([]); + + // Tabel Style + // -------------------- + const TableHeadStyle = { + fontWeight: 'bold', + }; + + // Use Effect + // -------------------- + useEffect(() => { + loadDataTableData(); + }, []) + + // Load Data + // ------------------- + const loadDataTableData = async () => { + setDataTableLoading(true); + + const response = await getDailyMonitoringList(); + + setDataTableLoading(false); + setDataTableData(response); + } + + return ( + + + + {/* Head Table */} + + + + Member ID + Name + Start Date + End Date + + + + + {/* Body Table */} + {dataTableIsLoading ? + ( + + + Loading + + + ) + : + ( + dataTableData.length == 0 ? + ( + + + No Data + + + ) + : + ( + + {dataTableData.map((row: LaboratoriumResultListType, index) => ( + + ))} + + ) + )} +
+
+
+ ) +} diff --git a/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Components/LaboratoriumResultListRow.tsx b/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Components/LaboratoriumResultListRow.tsx new file mode 100644 index 00000000..00c482de --- /dev/null +++ b/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Components/LaboratoriumResultListRow.tsx @@ -0,0 +1,72 @@ +/** + * Core + * ============================================ + */ +import React, { useState } from "react"; +import { useNavigate } from "react-router"; +import { Box, Collapse, MenuItem, TableCell, TableRow, Stack } from "@mui/material"; +import Visibility from '@mui/icons-material/Visibility'; + +/** + * Component + * ============================================ + */ +// - Global - +import Label from "@/components/Label"; +import TableMoreMenu from '@/components/table/TableMoreMenu'; + +/** + * Utils, Types, Functions + * ============================================ + */ +import { fDate } from "@/utils/formatTime"; +import { LaboratoriumResultListType } from "../Model/Types"; + +type Props = { + row: LaboratoriumResultListType, + number: number +} + +export default function LaboratoriumResultListRow ({ ...props }: Props) { + const navigate = useNavigate() + + return ( + + + td': { borderBottom: '1' } }}> + + {props.row.member_id} + {props.row.name} + + + + + + + e.stopPropagation()}> + + + navigate(`/case_management/laboratorium_result/${props.row.member_id}/claims`)}> + + View + + + } /> + + + + + + ); +} diff --git a/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Model/Functions.ts b/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Model/Functions.ts new file mode 100644 index 00000000..cb4c94cb --- /dev/null +++ b/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Model/Functions.ts @@ -0,0 +1,41 @@ +import axios from '@/utils/axios'; +import { enqueueSnackbar } from 'notistack'; +import { LaboratoriumResultListType, ResponseListingClaimType } from "./Types"; + +/** + * Listing Daily Monitoring + */ +export const getDailyMonitoringList = async ( ): Promise => { + const response = await axios.get('/case_management/daily_monitoring/memberlist') + .then((res) =>{ + return res.data.data.member_list; + }) + .catch((res) => { + enqueueSnackbar("server error !", { + variant: 'error', + }); + + return []; + }); + + return response; +}; + +/** + * Listing Claim + */ +export const getClaimList = async ( member_id: string ): Promise => { + const response = await axios.get(`/case_management/daily_monitoring/claimlist/${member_id}`) + .then((res) =>{ + return res.data.data; + }) + .catch((res) => { + enqueueSnackbar("server error !", { + variant: 'error', + }); + + return null; + }); + + return response; +}; diff --git a/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Model/Types.ts b/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Model/Types.ts new file mode 100644 index 00000000..701231a7 --- /dev/null +++ b/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Model/Types.ts @@ -0,0 +1,39 @@ +/** + * List Laboratorium + */ +export type LaboratoriumResultListType = { + member_id : string, + name : string, + startdate : string, + enddate : string, +} + +/** + * Response Listing Claim + */ +export type ResponseListingClaimType = { + member_detail : MemberDetailType, + claim_list : ClaimListType[], +} + +/** + * Member Detail + */ +export type MemberDetailType = { + id : string, + member_id : string, + name : string, +} + +/** + * List Claim + */ +export type ClaimListType = { + claim_id : number, + admission_dates : string, + discharge_dates : string, + claim_code : string, + claim_status : string, + service_type : string, + member_id : string +} diff --git a/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/index.tsx b/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/index.tsx new file mode 100644 index 00000000..f5e676bd --- /dev/null +++ b/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/index.tsx @@ -0,0 +1,48 @@ +/** + * Core + * ============================================ + */ +import { Box, Grid } from '@mui/material'; + +/** + * Components + * ============================================ +*/ +// - Global - +import Page from '../../../components/Page'; +import HeaderBreadcrumbs from "../../../components/HeaderBreadcrumbs"; +// - Local - +import LaboratoriumResultList from './Components/LaboratoriumResultList'; + +export default function LaboratoriumResult() { + const pageTitle = "Laboratorium Result"; + + return ( + + + {/* page header */} + + + + + {/* tabel daily monitoring */} + + + + + + ); +} diff --git a/frontend/dashboard/src/routes/index.tsx b/frontend/dashboard/src/routes/index.tsx index a6680391..71a087a2 100644 --- a/frontend/dashboard/src/routes/index.tsx +++ b/frontend/dashboard/src/routes/index.tsx @@ -221,7 +221,7 @@ export default function Router() { element: '', children: [ { - path: 'daily_monitoring', + path: 'daily_monitoring', // Daily Monitoring element: }, { @@ -236,6 +236,14 @@ export default function Router() { path: 'daily_monitoring/:member_id/claims/:claim_code/list_monitoring', element: }, + { + path: 'laboratorium_result', // Laboratorium Result + element: + }, + { + path: 'laboratorium_result/:member_id/claims', + element: + }, ] }, { @@ -561,6 +569,9 @@ const DailyMonitoring = Loadable(lazy(() => import('../pages/CaseManagemen const DailyMonitoringClaims = Loadable(lazy(() => import('../pages/CaseManagement/DailyMonitoring/Claim'))) const DetailMonitoringForm = Loadable(lazy(() => import('../pages/CaseManagement/DailyMonitoring/Components/DetailMonitoringForm'))) const DetailMonitoringList = Loadable(lazy(() => import('../pages/CaseManagement/DailyMonitoring/Components/DetailMonitoringList'))) +// Laboratorium Result +const LaboratoriumResult = Loadable(lazy(() => import('../pages/CaseManagement/LaboratoriumResult/index'))) +const LaboratoriumResultClaims = Loadable(lazy(() => import('../pages/CaseManagement/LaboratoriumResult/Claim'))) const MasterDiagnosisTemplate = Loadable(lazy(() => import('../pages/Master/Diagnosis/Master/Index'))); const MasterDiagnosisTemplateCreate = Loadable(lazy(() => import('../pages/Master/Diagnosis/Master/CreateUpdate'))); From b76a9b56f09c79aebb4e5ce2a57e910135ca0311 Mon Sep 17 00:00:00 2001 From: korospace Date: Sat, 28 Oct 2023 19:00:04 +0700 Subject: [PATCH 09/10] finishing part 1 --- .../Api/DailyMonitoringController.php | 27 +- .../Api/LaboratoriumResultController.php | 148 +++++++++++ Modules/Internal/Routes/api.php | 13 +- ...ailyMonitoring.php => DailyMonitoring.php} | 6 +- app/Models/LaboratoriumResult.php | 39 +++ ...60127_create_laboratorium_result_table.php | 35 +++ .../components/hook-form/RHFDatePickerV2.tsx | 53 ++++ .../Components/DetailMonitoringForm.tsx | 14 +- .../Components/DetailMonitoringList.tsx | 8 +- .../DailyMonitoring/Model/Functions.ts | 12 +- .../DailyMonitoring/Model/Types.ts | 8 +- .../Components/DetailLabResultForm.tsx | 237 ++++++++++++++++++ .../Components/DetailLabResultList.tsx | 165 ++++++++++++ .../LaboratoriumResult/Model/Functions.ts | 65 ++++- .../LaboratoriumResult/Model/Types.ts | 18 ++ .../src/pages/ClaimRequests/Detail.tsx | 16 +- frontend/dashboard/src/routes/index.tsx | 10 + 17 files changed, 840 insertions(+), 34 deletions(-) create mode 100644 Modules/Internal/Http/Controllers/Api/LaboratoriumResultController.php rename app/Models/{ClaimDailyMonitoring.php => DailyMonitoring.php} (90%) create mode 100644 app/Models/LaboratoriumResult.php create mode 100644 database/migrations/2023_10_28_160127_create_laboratorium_result_table.php create mode 100644 frontend/dashboard/src/components/hook-form/RHFDatePickerV2.tsx create mode 100644 frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Components/DetailLabResultForm.tsx create mode 100644 frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Components/DetailLabResultList.tsx diff --git a/Modules/Internal/Http/Controllers/Api/DailyMonitoringController.php b/Modules/Internal/Http/Controllers/Api/DailyMonitoringController.php index 3723de92..b6573618 100644 --- a/Modules/Internal/Http/Controllers/Api/DailyMonitoringController.php +++ b/Modules/Internal/Http/Controllers/Api/DailyMonitoringController.php @@ -2,7 +2,7 @@ namespace Modules\Internal\Http\Controllers\Api; -use App\Models\ClaimDailyMonitoring; +use App\Models\DailyMonitoring; use App\Models\MedicalPlan; use DB; use Exception; @@ -98,7 +98,7 @@ class DailyMonitoringController extends Controller ->where('claim_request_id', empty($claim_request)==false ? $claim_request->id : '') ->first(); - $detail_list = ClaimDailyMonitoring::where('claim_id', empty($claim) == false ? $claim->id : '')->orderBy("created_at", "desc")->get()->makeHidden(['updated_at']); + $detail_list = DailyMonitoring::where('claim_id', empty($claim) == false ? $claim->id : '')->orderBy("created_at", "desc")->get()->makeHidden(['updated_at']); return response()->json([ 'error' => false, @@ -153,7 +153,7 @@ class DailyMonitoringController extends Controller try { // insert claim daily monitoring - $db_response = ClaimDailyMonitoring::create([ + $db_response = DailyMonitoring::create([ 'claim_id' => $claim->id, 'subject' => $request->subject, 'sistole' => $request->sistole, @@ -164,6 +164,27 @@ class DailyMonitoringController extends Controller 'complaints' => $request->complaints, ]); + // cek medical plan + $num_medical_plan = 0; + + foreach ($request->medical_plan as $row) { + if ($row['medical_plan_str']) { + $num_medical_plan++; + } + } + + if ($num_medical_plan == 0) { + DB::rollBack(); + + return response()->json([ + 'error' => true, + 'message' => [ + 'medical_plan' => ['medical plan harus diisi'] + ], + 'data' => [] + ],400); + } + // insert medical plan foreach ($request->medical_plan as $row) { MedicalPlan::create([ diff --git a/Modules/Internal/Http/Controllers/Api/LaboratoriumResultController.php b/Modules/Internal/Http/Controllers/Api/LaboratoriumResultController.php new file mode 100644 index 00000000..81239f6e --- /dev/null +++ b/Modules/Internal/Http/Controllers/Api/LaboratoriumResultController.php @@ -0,0 +1,148 @@ + ':attribute harus diisi', + 'integer' => ':attribute harus angka', + 'unique' => ':attribute (:input) sudah ada', + 'max' => ':attribute maximal :max karakter', + 'exists' => ':attribute (:input) tidak ditemukan', + 'numeric' => ':attribute harus angka', + 'digits_between'=> ':attribute maximal :max digit minimal :min digit' + ]; + } + + /** + * Detail Lab Result List - by claim_code + */ + public function GetDetailLabResultList(Request $request, $claim_code) + { + // get claim request + $claim_request = DB::table('claim_requests') + ->select('id') + ->where('code', $claim_code) + ->first(); + + // get claim + $claim = DB::table('claims') + ->select('id') + ->where('claim_request_id', empty($claim_request)==false ? $claim_request->id : '') + ->first(); + + $detail_list = LaboratoriumResult::where('claim_id', empty($claim) == false ? $claim->id : '')->orderBy("created_at", "desc")->get()->makeHidden(['updated_at']); + + return response()->json([ + 'error' => false, + 'message' => "success", + 'data' => [ + 'lab_result_list'=> $detail_list, + ] + ],200); + } + + /** + * Add Detail Lab Result List + */ + public function AddDetailLabResultList(Request $request, $claim_code) + { + $request->merge(['claim_code' => $claim_code]); + + // validation rule + $validator = Validator::make($request->all(),[ + 'claim_code' => 'required|exists:claim_requests,code', + 'date' => 'required', + 'location' => 'required', + 'examination' => 'required', + 'lab_result_file' => 'required', + ],$this->messages()); + + // validation error + if ($validator->fails()) { + return response()->json([ + 'error' => true, + 'message' => $validator->getMessageBag() + ],400); + } + + // get claim request + $claim_request = DB::table('claim_requests') + ->select('id') + ->where('code', $claim_code) + ->first(); + + // get claim + $claim = DB::table('claims') + ->select('id') + ->where('claim_request_id', $claim_request->id) + ->first(); + + DB::beginTransaction(); + + try { + // insert lab result + $db_response = LaboratoriumResult::create([ + 'claim_id' => $claim->id, + 'date' => $request->date, + 'location' => $request->location, + 'examination' => $request->examination, + ]); + + // insert file result + foreach ($request->lab_result_file as $file) { + $name = 'labresult-' . uniqid(); + $extension= $file->getClientOriginalExtension(); + $fileName = $name . '.' . $extension; + + File::create([ + 'fileable_type' => 'App\Models\LaboratoriumResult', + 'fileable_id' => $db_response->id, + 'type' => 'laboratorium-result', + 'name' => $name, + 'original_name' => $fileName, + 'extension' => $extension, + 'path' => '', + ]); + + $file->storeAs($this->path_for_store, $fileName); + } + + DB::commit(); + + return response()->json([ + 'error' => false, + 'message' => "success", + 'data' => [] + ],200); + } + catch (Exception $e) { + DB::rollBack(); + + return response()->json([ + 'error' => true, + 'message' => $e->getMessage(), + 'data' => [] + ],500); + } + } +} diff --git a/Modules/Internal/Routes/api.php b/Modules/Internal/Routes/api.php index bf539592..fa7dcf5b 100644 --- a/Modules/Internal/Routes/api.php +++ b/Modules/Internal/Routes/api.php @@ -38,6 +38,7 @@ use Modules\Internal\Http\Controllers\Api\SpecialityController; use Modules\Internal\Http\Controllers\Api\VillageController; use Modules\Internal\Http\Controllers\Api\AuditTrailController; use Modules\Internal\Http\Controllers\Api\DailyMonitoringController; +use Modules\Internal\Http\Controllers\Api\LaboratoriumResultController; use Modules\Internal\Http\Controllers\ClaimEncounterController; /* @@ -149,12 +150,20 @@ Route::prefix('internal')->group(function () { Route::get('audittrail/{corporate_id}', [AuditTrailController::class, 'index']); Route::prefix('case_management')->group(function () { + Route::get('memberlist', [DailyMonitoringController::class, 'GetMemberList']); + Route::get('claimlist/{member_id}', [DailyMonitoringController::class, 'GetClaimList']); + + // Daily Monitoring Route::prefix('daily_monitoring')->group(function () { - Route::get('memberlist', [DailyMonitoringController::class, 'GetMemberList']); - Route::get('claimlist/{member_id}', [DailyMonitoringController::class, 'GetClaimList']); Route::get('detail/{claim_code}/list', [DailyMonitoringController::class, 'GetDetailMonitoringList']); Route::post('detail/{claim_code}/add', [DailyMonitoringController::class, 'AddDetailMonitoringList']); }); + + // Laboratorium Result + Route::prefix('laboratorium_result')->group(function () { + Route::get('detail/{claim_code}/list', [LaboratoriumResultController::class, 'GetDetailLabResultList']); + Route::post('detail/{claim_code}/add', [LaboratoriumResultController::class, 'AddDetailLabResultList']); + }); }); Route::get('master/diagnosis-template', [DiagnosisTemplateController::class, 'index']); diff --git a/app/Models/ClaimDailyMonitoring.php b/app/Models/DailyMonitoring.php similarity index 90% rename from app/Models/ClaimDailyMonitoring.php rename to app/Models/DailyMonitoring.php index 1fd11fb9..2285102c 100644 --- a/app/Models/ClaimDailyMonitoring.php +++ b/app/Models/DailyMonitoring.php @@ -6,7 +6,7 @@ use DB; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; -class ClaimDailyMonitoring extends Model +class DailyMonitoring extends Model { use HasFactory; @@ -51,7 +51,9 @@ class ClaimDailyMonitoring extends Model $medical_plan = DB::table('medical_plan')->where('claim_daily_monitoring_id','=',$this->attributes['id'])->get(); foreach ($medical_plan as $row) { - $arr_medical_plan[] = $row->plan; + $arr_medical_plan[] = [ + 'medical_plan_str' => $row->plan + ]; } return $arr_medical_plan; diff --git a/app/Models/LaboratoriumResult.php b/app/Models/LaboratoriumResult.php new file mode 100644 index 00000000..de65e237 --- /dev/null +++ b/app/Models/LaboratoriumResult.php @@ -0,0 +1,39 @@ +select('name','original_name','path','extension')->where("type","=","laboratorium-result")->where('fileable_id','=',$this->attributes['id'])->get(); + + foreach ($files as $row) { + $row->path = url($this->path_for_public . "/" . $row->original_name); + + $arr_files[] = [ + 'lab_result_file_obj' => $row + ]; + } + + return $arr_files; + } +} diff --git a/database/migrations/2023_10_28_160127_create_laboratorium_result_table.php b/database/migrations/2023_10_28_160127_create_laboratorium_result_table.php new file mode 100644 index 00000000..77320316 --- /dev/null +++ b/database/migrations/2023_10_28_160127_create_laboratorium_result_table.php @@ -0,0 +1,35 @@ +bigIncrements('id'); + $table->integer('claim_id'); + $table->string('date'); + $table->text('location'); + $table->text('examination'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('laboratorium_result'); + } +}; diff --git a/frontend/dashboard/src/components/hook-form/RHFDatePickerV2.tsx b/frontend/dashboard/src/components/hook-form/RHFDatePickerV2.tsx new file mode 100644 index 00000000..ef1853be --- /dev/null +++ b/frontend/dashboard/src/components/hook-form/RHFDatePickerV2.tsx @@ -0,0 +1,53 @@ +// form +import { useFormContext, Controller } from 'react-hook-form'; +// @mui +import { FormHelperText, TextField } from '@mui/material'; +import { DesktopDatePicker, LocalizationProvider } from '@mui/lab'; +import AdapterDateFns from '@mui/lab/AdapterDateFns'; + +// ---------------------------------------------------------------------- + +interface IProps { + name: string; + label: string; + dateFormat: string; + fullWidth?: boolean; + minDate?: any; + maxDate?: any; + disabled?: boolean; +} + +export default function RHFDatePickerV2({ name, label, dateFormat, minDate, maxDate, disabled, ...other }: IProps) { + const { control } = useFormContext(); + + const { fullWidth } = other; + + return ( + + ( + <> + field.onChange(date)} + inputFormat={dateFormat} + value={field.value} + mask={''} + minDate={(minDate) ? new Date(minDate) : null} + maxDate={(maxDate) ? new Date(maxDate) : null} + renderInput={(params) => } + /> + {!!error && ( + + {error.message} + + )} + + )} + /> + + ); +} diff --git a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DetailMonitoringForm.tsx b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DetailMonitoringForm.tsx index 2919085e..50905ec4 100644 --- a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DetailMonitoringForm.tsx +++ b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DetailMonitoringForm.tsx @@ -26,7 +26,7 @@ import RemoveIcon from '@mui/icons-material/Remove'; * Utils, Types, Functions * ============================================ */ -import { AddClaimDetail } from '../Model/Functions'; +import { AddMonitoringDetail } from '../Model/Functions'; import { DetailMonitoringListType} from '../Model/Types'; export default function DetailMonitoringList() { @@ -36,7 +36,10 @@ export default function DetailMonitoringList() { // setup form // ==================================== - const defaultValues: any = { + const defaultValues: DetailMonitoringListType = { + id : '', + claim_code : '', + claim_id : '', subject : '', body_temperature: '', sistole : '', @@ -46,7 +49,8 @@ export default function DetailMonitoringList() { analysis : '', medical_plan : [{ medical_plan_str: '' - }] + }], + created_at : '' }; const methods = useForm({ @@ -62,7 +66,7 @@ export default function DetailMonitoringList() { const submitHandler = async (data: DetailMonitoringListType) => { console.log(claim_code); - const response = await AddClaimDetail(claim_code??'', data); + const response = await AddMonitoringDetail(claim_code??'', data); if (response == true) { reset(); @@ -71,7 +75,7 @@ export default function DetailMonitoringList() { return ( - + navigate(`/case_management/daily_monitoring/${member_id}/claims`)} > diff --git a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DetailMonitoringList.tsx b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DetailMonitoringList.tsx index 18829123..da31d37d 100644 --- a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DetailMonitoringList.tsx +++ b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DetailMonitoringList.tsx @@ -28,7 +28,7 @@ import FiberManualRecord from '@mui/icons-material/FiberManualRecord'; * ============================================ */ import { fDate } from "@/utils/formatTime"; -import { AddClaimDetail, getClaimDetailList } from '../Model/Functions'; +import { getMonitoringDetailList } from '../Model/Functions'; import { DetailMonitoringListType } from '../Model/Types'; @@ -50,7 +50,7 @@ export default function DetailMonitoringList() { // Load Data // ------------------- const loadDataTableData = async () => { - const response = await getClaimDetailList(claim_code??''); + const response = await getMonitoringDetailList(claim_code??''); setDetailMonitoringList(response); } @@ -215,10 +215,10 @@ export default function DetailMonitoringList() { { - row.medical_plan.map((str, index) => { + row.medical_plan.map((data, index) => { return ( - {str} + {data.medical_plan_str} ) }) diff --git a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Model/Functions.ts b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Model/Functions.ts index 8ffd0eb8..05ace34d 100644 --- a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Model/Functions.ts +++ b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Model/Functions.ts @@ -6,7 +6,7 @@ import { DailyMonitoringListType, DetailMonitoringListType, ResponseListingClaim * Listing Daily Monitoring */ export const getDailyMonitoringList = async ( ): Promise => { - const response = await axios.get('/case_management/daily_monitoring/memberlist') + const response = await axios.get('/case_management/memberlist') .then((res) =>{ return res.data.data.member_list; }) @@ -25,7 +25,7 @@ export const getDailyMonitoringList = async ( ): Promise => { - const response = await axios.get(`/case_management/daily_monitoring/claimlist/${member_id}`) + const response = await axios.get(`/case_management/claimlist/${member_id}`) .then((res) =>{ return res.data.data; }) @@ -41,9 +41,9 @@ export const getClaimList = async ( member_id: string ): Promise => { +export const AddMonitoringDetail = async ( claim_code: string,data: DetailMonitoringListType ): Promise => { const response = await axios.post(`/case_management/daily_monitoring/detail/${claim_code}/add`, { ...data }) @@ -77,9 +77,9 @@ export const AddClaimDetail = async ( claim_code: string,data: DetailMonitoringL }; /** - * Get Claim Detail List + * Get Monitoring Detail List */ -export const getClaimDetailList = async ( claim_code: string ): Promise => { +export const getMonitoringDetailList = async ( claim_code: string ): Promise => { const response = await axios.get(`/case_management/daily_monitoring/detail/${claim_code}/list`) .then((res) =>{ return res.data.data.detail_list; diff --git a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Model/Types.ts b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Model/Types.ts index d6c1b3be..fc5fc9ac 100644 --- a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Model/Types.ts +++ b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Model/Types.ts @@ -39,7 +39,7 @@ export type ClaimListType = { } /** - * Detail Claim + * Detail Monitoring List */ export type DetailMonitoringListType = { id : string|null, @@ -52,6 +52,10 @@ export type DetailMonitoringListType = { diastole : string analysis : string, complaints : string, - medical_plan : string[], + medical_plan : MedicalPlanStrType[], created_at : string|null } + +export type MedicalPlanStrType = { + medical_plan_str: string +} diff --git a/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Components/DetailLabResultForm.tsx b/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Components/DetailLabResultForm.tsx new file mode 100644 index 00000000..7d6191dd --- /dev/null +++ b/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Components/DetailLabResultForm.tsx @@ -0,0 +1,237 @@ +/** + * Core + * ============================================ + */ +import { useRef } from 'react'; +import { useFieldArray, useForm } from 'react-hook-form'; +import { useNavigate, useParams } from 'react-router-dom'; +import { Box, IconButton, Typography, Grid, Card, Button, ButtonBase, Stack } from '@mui/material'; +import { LoadingButton } from "@mui/lab"; + +/** + * Components + * ============================================ +*/ +import Page from '@/components/Page'; +import { FormProvider, RHFDatepicker, RHFTextField } from '@/components/hook-form'; +import RHFDatePickerV2 from '@/components/hook-form/RHFDatePickerV2'; + +/** + * Icon + * ============================================ + */ +import ArrowBackIosNew from '@mui/icons-material/ArrowBackIosNew'; +import Iconify from '@/components/Iconify'; +import InsertDriveFileIcon from '@mui/icons-material/InsertDriveFile'; + +/** + * Utils, Types, Functions + * ============================================ + */ +import { AddLabResultDetail } from '../Model/Functions'; +import { DetailLabResultListType} from '../Model/Types'; + +export default function DetailMonitoringList() { + const { member_id, claim_code } = useParams(); + const navigate = useNavigate() + const pageTitle = claim_code??'_ _ _ _'; + const fileInput = useRef(null); + + // setup form + // ==================================== + const defaultValues: DetailLabResultListType = { + id : '', + claim_id : '', + claim_code : '', + date : '', + location : '', + examination : '', + lab_result_file : [], + created_at : '' + }; + + const methods = useForm({ + defaultValues + }); + + const { handleSubmit, reset, watch, setValue, formState: { isDirty, isSubmitting } } = methods; + const formValues = watch(); + + // Handle File Input + // ===================================== + const handleInputChange = (event: any) => { + if (event.target.files[0]) { + + let arr_lab_result_file = formValues.lab_result_file; + arr_lab_result_file.push(event.target.files[0]); + + setValue('lab_result_file', arr_lab_result_file) + } + else { + console.log('NO FILE'); + } + }; + + // Handle Remove File + // ===================================== + const handleRemoveFile = (target_index: number) => { + let arr_lab_result_file = formValues.lab_result_file.filter((file: any, index: number) =>{ + if (target_index !== index) { + return file; + } + }); + + setValue('lab_result_file', arr_lab_result_file) + }; + + // Submit Form + // ===================================== + const submitHandler = async (data: DetailLabResultListType) => { + const response = await AddLabResultDetail(claim_code??'', data); + + if (response == true) { + reset(defaultValues); + } + } + + return ( + + + navigate(`/case_management/laboratorium_result/${member_id}/claims`)} > + + + + + {pageTitle} + + + + + + + + {/* Date */} + + + + + Date* : + + + + + + + + + {/* Location */} + + + + + Location* : + + + + + + + + + {/* Examination */} + + + + + Examination* : + + + + + + + + + {/* list file & button upload */} + + + + { + formValues.lab_result_file.map((file: any, index: number) => ( + + + + {file.name ? file.name : '-'} + + handleRemoveFile(index)} + sx={{cursor: 'pointer'}} + > + + )) + } + + + fileInput.current?.click()}> + + + + Upload Result + + + + + + + + + {/* Button Cancle & Save */} + + + + + + Save Changes + + + + + + + + + + ) +} diff --git a/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Components/DetailLabResultList.tsx b/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Components/DetailLabResultList.tsx new file mode 100644 index 00000000..6336fd8e --- /dev/null +++ b/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Components/DetailLabResultList.tsx @@ -0,0 +1,165 @@ +/** + * Core + * ============================================ + */ +import { useEffect, useState } from 'react'; +import { useFieldArray, useForm } from 'react-hook-form'; +import { useNavigate, useParams } from 'react-router-dom'; +import { Box, IconButton, Typography, Grid, Card, List, ListItem, Stack, Link } from '@mui/material'; +import { LoadingButton } from "@mui/lab"; + +/** + * Components + * ============================================ +*/ +// - Global - +import Page from '@/components/Page'; +import Label from "@/components/Label"; + +/** + * Icon + * ============================================ + */ +import ArrowBackIosNew from '@mui/icons-material/ArrowBackIosNew'; +import InsertDriveFileIcon from '@mui/icons-material/InsertDriveFile'; + +/** + * Utils, Types, Functions + * ============================================ + */ +import { fDate } from "@/utils/formatTime"; +import { getLabResultDetailList } from '../Model/Functions'; +import { DetailLabResultListType } from '../Model/Types'; + + +export default function DetailLabResultList() { + const { member_id, claim_code } = useParams(); + const navigate = useNavigate() + const pageTitle = claim_code??'_ _ _ _'; + + // State + // -------------------- + const [LabResultList, setLabResultList] = useState(); + + // Use Effect + // -------------------- + useEffect(() => { + loadDataTableData(); + }, []) + + // Load Data + // ------------------- + const loadDataTableData = async () => { + const response = await getLabResultDetailList(claim_code??''); + + setLabResultList(response); + } + + return ( + + + {/* back button */} + + + navigate(`/case_management/daily_monitoring/${member_id}/claims`)} > + + + + + {pageTitle} + + + + + {/* tabel claims */} + + + { + LabResultList?.map((row, index) => { + return ( + + + {/* card header */} + + + + + {/* card body */} + + + + + + Date + + + + + {row.date} + + + + + Location + + + + + {row.location} + + + + + Examination + + + + + {row.examination} + + + + + + + + + + Document : + + + + { + row.lab_result_file.map((data, index) => { + return ( + + + + + {data.lab_result_file_obj.original_name??'-'} + + + + ) + }) + } + + + + + + + ) + }) + } + + + + + ); +} diff --git a/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Model/Functions.ts b/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Model/Functions.ts index cb4c94cb..cc674bc6 100644 --- a/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Model/Functions.ts +++ b/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Model/Functions.ts @@ -1,12 +1,14 @@ import axios from '@/utils/axios'; +import { makeFormData } from '@/utils/jsonToFormData'; import { enqueueSnackbar } from 'notistack'; -import { LaboratoriumResultListType, ResponseListingClaimType } from "./Types"; +import { DetailLabResultListType, LaboratoriumResultListType, ResponseListingClaimType } from "./Types"; +import { fDate } from '@/utils/formatTime'; /** * Listing Daily Monitoring */ export const getDailyMonitoringList = async ( ): Promise => { - const response = await axios.get('/case_management/daily_monitoring/memberlist') + const response = await axios.get('/case_management/memberlist') .then((res) =>{ return res.data.data.member_list; }) @@ -25,7 +27,7 @@ export const getDailyMonitoringList = async ( ): Promise => { - const response = await axios.get(`/case_management/daily_monitoring/claimlist/${member_id}`) + const response = await axios.get(`/case_management/claimlist/${member_id}`) .then((res) =>{ return res.data.data; }) @@ -39,3 +41,60 @@ export const getClaimList = async ( member_id: string ): Promise => { + data.date = data.date != '' ? fDate(data.date) : ''; + + const formData = makeFormData({...data}); + + const response = await axios.post(`/case_management/laboratorium_result/detail/${claim_code}/add`, formData) + .then((res) =>{ + enqueueSnackbar(res.data.message, { + variant: 'success', + }); + + return true; + }) + .catch((res) => { + if (res.response.status == 400) { + let arr_message = res.response.data.message; + + for (const key in arr_message) { + enqueueSnackbar(arr_message[key][0], { + variant: 'warning', + }); + } + } + else { + enqueueSnackbar("server error !", { + variant: 'error', + }); + } + + return false; + }); + + return response; +}; + +/** + * Get Lab Result Detail List + */ +export const getLabResultDetailList = async ( claim_code: string ): Promise => { + const response = await axios.get(`/case_management/laboratorium_result/detail/${claim_code}/list`) + .then((res) =>{ + return res.data.data.lab_result_list; + }) + .catch((res) => { + enqueueSnackbar("server error !", { + variant: 'error', + }); + + return []; + }); + + return response; +}; diff --git a/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Model/Types.ts b/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Model/Types.ts index 701231a7..8a4e3a8d 100644 --- a/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Model/Types.ts +++ b/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Model/Types.ts @@ -37,3 +37,21 @@ export type ClaimListType = { service_type : string, member_id : string } + +/** + * Detail Lab Result List + */ +export type DetailLabResultListType = { + id : string|null, + claim_id : string|null, + claim_code : string, + date : string, + location : string, + examination : string, + lab_result_file : LabResultFileStrType[], + created_at : string|null +} + +export type LabResultFileStrType = { + lab_result_file_obj: any +} diff --git a/frontend/dashboard/src/pages/ClaimRequests/Detail.tsx b/frontend/dashboard/src/pages/ClaimRequests/Detail.tsx index 3af03ad6..85b17f2b 100644 --- a/frontend/dashboard/src/pages/ClaimRequests/Detail.tsx +++ b/frontend/dashboard/src/pages/ClaimRequests/Detail.tsx @@ -49,7 +49,7 @@ export default function Detail() { .then((response) => { setData(response.data); setDataDialog(response.data.data.dialog_submits); - + }) .catch((error) => { console.error(error); @@ -71,6 +71,8 @@ export default function Detail() { const handleInvoiceInputChange = (event) => { if (event.target.files[0]) { + console.log('ok'); + setFileInvoices([...fileInvoices, ...event.target.files]); } else { console.log('NO FILE'); @@ -84,7 +86,7 @@ export default function Detail() { ); }; const date = dateInvoice ? fPostFormat(dateInvoice, 'yyyy-MM-dd') : null; - + const [openDialogSubmit, setOpenDialogSubmit] = useState(false); const handleCloseDialogSubmit = () => { setOpenDialogSubmit(false); @@ -121,13 +123,13 @@ export default function Detail() { enqueueSnackbar('Please upload file invoice, before submit', { variant: 'warning' }); } - setTimeout(() => + setTimeout(() => { window.location.reload(); }, 5000); - + }; - + return ( @@ -209,7 +211,7 @@ export default function Detail() { placeItems: 'center', gap: 1, placeContent: 'center', - + }} > @@ -297,4 +299,4 @@ export default function Detail() { ); -} \ No newline at end of file +} diff --git a/frontend/dashboard/src/routes/index.tsx b/frontend/dashboard/src/routes/index.tsx index 71a087a2..aec83214 100644 --- a/frontend/dashboard/src/routes/index.tsx +++ b/frontend/dashboard/src/routes/index.tsx @@ -244,6 +244,14 @@ export default function Router() { path: 'laboratorium_result/:member_id/claims', element: }, + { + path: 'laboratorium_result/:member_id/claims/:claim_code/add_lab_result', + element: + }, + { + path: 'laboratorium_result/:member_id/claims/:claim_code/list_lab_result', + element: + }, ] }, { @@ -572,6 +580,8 @@ const DetailMonitoringList = Loadable(lazy(() => import('../pages/CaseManagemen // Laboratorium Result const LaboratoriumResult = Loadable(lazy(() => import('../pages/CaseManagement/LaboratoriumResult/index'))) const LaboratoriumResultClaims = Loadable(lazy(() => import('../pages/CaseManagement/LaboratoriumResult/Claim'))) +const DetailLabResultForm = Loadable(lazy(() => import('../pages/CaseManagement/LaboratoriumResult/Components/DetailLabResultForm'))) +const DetailLabResultList = Loadable(lazy(() => import('../pages/CaseManagement/LaboratoriumResult/Components/DetailLabResultList'))) const MasterDiagnosisTemplate = Loadable(lazy(() => import('../pages/Master/Diagnosis/Master/Index'))); const MasterDiagnosisTemplateCreate = Loadable(lazy(() => import('../pages/Master/Diagnosis/Master/CreateUpdate'))); From f625d4225f1598ca6c964bebd0358ede7eb0be64 Mon Sep 17 00:00:00 2001 From: korospace Date: Sat, 28 Oct 2023 19:07:04 +0700 Subject: [PATCH 10/10] target blank untuk list dokumen laboratorium --- .../LaboratoriumResult/Components/DetailLabResultList.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Components/DetailLabResultList.tsx b/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Components/DetailLabResultList.tsx index 6336fd8e..928df320 100644 --- a/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Components/DetailLabResultList.tsx +++ b/frontend/dashboard/src/pages/CaseManagement/LaboratoriumResult/Components/DetailLabResultList.tsx @@ -138,7 +138,7 @@ export default function DetailLabResultList() { row.lab_result_file.map((data, index) => { return ( - + {data.lab_result_file_obj.original_name??'-'}