From 22e30615648a3eb88276dd396b9b49a8d5639b3d Mon Sep 17 00:00:00 2001 From: korospace Date: Thu, 2 Nov 2023 17:40:33 +0700 Subject: [PATCH] progress 2 feature/dashboard-create-claim-request --- .../Api/ClaimRequestController.php | 20 +- .../Api/ClaimRequestController.php | 141 ++++++- .../Api/DailyMonitoringController.php | 2 +- Modules/Internal/Routes/api.php | 3 +- frontend/client-portal/.env.development | 4 +- .../CaseManagement/DailyMonitoring/Claim.tsx | 10 +- .../Components/DailyMonitoringList.tsx | 10 +- .../ClaimRequests/Components/FormCreate.tsx | 361 ++++++++++++++++++ .../Components/FormCreateBtnChoose.tsx | 39 ++ .../Components/FormCreateBtnUpload.tsx | 39 ++ .../Components/FormCreateFilesUpload.tsx | 25 ++ .../{ => Components}/FormCreateListChoose.tsx | 2 +- .../{ => Components}/FormCreateSearch.tsx | 2 +- .../{Form.tsx => Components/FormEdit.tsx} | 40 +- .../src/pages/ClaimRequests/CreateUpdate.tsx | 21 +- .../src/pages/ClaimRequests/FormCreate.tsx | 110 ------ .../pages/ClaimRequests/Model/Functions.tsx | 51 +++ .../src/pages/ClaimRequests/Model/Types.tsx | 10 +- 18 files changed, 712 insertions(+), 178 deletions(-) create mode 100644 frontend/dashboard/src/pages/ClaimRequests/Components/FormCreate.tsx create mode 100644 frontend/dashboard/src/pages/ClaimRequests/Components/FormCreateBtnChoose.tsx create mode 100644 frontend/dashboard/src/pages/ClaimRequests/Components/FormCreateBtnUpload.tsx create mode 100644 frontend/dashboard/src/pages/ClaimRequests/Components/FormCreateFilesUpload.tsx rename frontend/dashboard/src/pages/ClaimRequests/{ => Components}/FormCreateListChoose.tsx (98%) rename frontend/dashboard/src/pages/ClaimRequests/{ => Components}/FormCreateSearch.tsx (97%) rename frontend/dashboard/src/pages/ClaimRequests/{Form.tsx => Components/FormEdit.tsx} (92%) delete mode 100644 frontend/dashboard/src/pages/ClaimRequests/FormCreate.tsx diff --git a/Modules/Client/Http/Controllers/Api/ClaimRequestController.php b/Modules/Client/Http/Controllers/Api/ClaimRequestController.php index 23dd68f1..3a4d5abf 100644 --- a/Modules/Client/Http/Controllers/Api/ClaimRequestController.php +++ b/Modules/Client/Http/Controllers/Api/ClaimRequestController.php @@ -48,17 +48,17 @@ class ClaimRequestController extends Controller ]); if ($request->member_id){ foreach($request->member_id as $key => $member_id){ - - $code = $this->getNextCode(); + + $code = $this->getNextCode(); $member = Member::find($member_id); $newClaimRequest = ClaimRequestService::storeClaimRequest( - row: [], - code: $code, - member: $member, - paymentType: 'reimbursement', - serviceCode: $request->service_code[$key], + row: [], + code: $code, + member: $member, + paymentType: 'reimbursement', + serviceCode: $request->service_code[$key], ); - + ClaimRequested::dispatch($newClaimRequest); // Log History $newClaimRequest->histories()->create([ @@ -127,9 +127,9 @@ class ClaimRequestController extends Controller } } } - - + + return Helper::responseJson(data: $request->toArray(), message: 'Claim Request berhasil ajukan!'); } diff --git a/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php b/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php index 85cae6d7..6b311ed5 100644 --- a/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php +++ b/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php @@ -25,6 +25,8 @@ use App\Models\Member; class ClaimRequestController extends Controller { + private static $code_prefix = 'CRQ-C'; + /** * Display a listing of the resource. * @return Renderable @@ -64,14 +66,109 @@ class ClaimRequestController extends Controller return view('internal::create'); } - /** - * Store a newly created resource in storage. - * @param Request $request - * @return Renderable - */ - public function store(Request $request) + public function createNew(Request $request) { - // + $request->validate([ + 'member_id' => 'required|array', + 'member_id.*' => 'required', + 'service_code.*' => 'required|in:OP,IP' + ]); + + if ($request->member_id){ + foreach($request->member_id as $key => $member_id){ + + $code = $this->getNextCode(); + $member = Member::find($member_id); + + DB::beginTransaction(); + + try { + $newClaimRequest = ClaimRequestService::storeClaimRequest( + row: [], + code: $code, + member: $member, + paymentType: 'reimbursement', + serviceCode: $request->service_code[$key], + ); + + ClaimRequested::dispatch($newClaimRequest); + + // Log History + $newClaimRequest->histories()->create([ + 'title' => 'New Claim Requested', + 'description' => "Claim Requested for Member : {$member->member_id} - ({$member->full_name})", + 'type' => 'info', + 'system_origin' => 'client-portal' + ]); + + // Claim Log + DB::table('claim_logs') ->insert([ + 'claim_request_id' => $newClaimRequest->id, + 'status' => 'requested', + 'date' => date('Y-m-d H:i:s'), + 'description' => "Claim Requested for Member : {$member->member_id} - ({$member->full_name})", + 'system_origin' => 'hospital-portal', + 'created_by' => auth()->user()->id, + 'created_at' => date('Y-m-d H:i:s'), + 'updated_at'=> date('Y-m-d H:i:s'), + ]); + + if ($request->hasFile('laboratorium')) { + foreach ($request->laboratorium[$key] as $file) { + $pathFile = File::storeFile('claim-result', $newClaimRequest->id, $file); + $newClaimRequest->files()->updateOrCreate([ + 'type' => 'claim-result', + 'name' => File::getFileName('claim-result', $newClaimRequest->id, $file), + 'original_name' => $file->getClientOriginalName(), + 'extension' => $file->getClientOriginalExtension(), + 'path' => $pathFile, + 'created_by' => auth()->user()->id, + 'updated_by' => auth()->user()->id, + ]); + } + } + + if ($request->hasFile('prescription')) { + foreach ($request->prescription[$key] as $file) { + $pathFile = File::storeFile('claim-diagnosis', $newClaimRequest->id, $file); + $newClaimRequest->files()->updateOrCreate([ + 'type' => 'claim-diagnosis', + 'name' => File::getFileName('claim-diagnosis', $newClaimRequest->id, $file), + 'original_name' => $file->getClientOriginalName(), + 'extension' => $file->getClientOriginalExtension(), + 'path' => $pathFile, + 'created_by' => auth()->user()->id, + 'updated_by' => auth()->user()->id, + ]); + } + } + + if ($request->hasFile('invoice')) { + foreach ($request->invoice[$key] as $file) { + $pathFile = File::storeFile('claim-kondisi', $newClaimRequest->id, $file); + $newClaimRequest->files()->updateOrCreate([ + 'type' => 'claim-kondisi', + 'name' => File::getFileName('claim-kondisi', $newClaimRequest->id, $file), + 'original_name' => $file->getClientOriginalName(), + 'extension' => $file->getClientOriginalExtension(), + 'path' => $pathFile, + 'created_by' => auth()->user()->id, + 'updated_by' => auth()->user()->id, + ]); + } + } + + DB::commit(); + } + catch (\Throwable $th) { + DB::rollBack(); + + return Helper::responseJson(status: 'failed', statusCode: 500, message: $th->getMessage()); + } + } + } + + return Helper::responseJson(status: 'success', statusCode: 201, message: 'Claim Request berhasil ajukan!', data: $request->toArray()); } /** @@ -510,4 +607,34 @@ class ClaimRequestController extends Controller ] ],200); } + + public static function getNextCode() + { + // $last_number = ClaimRequest::max('code'); + // $next_number = empty($last_number) ? 1 : ((int) explode('-', $last_number)[2] + 1); + // return self::makeCode($next_number); + + $last_numeric_code = ClaimRequest::select(DB::raw('MAX(CAST(SUBSTRING_INDEX(code, "-", -1) AS SIGNED)) as max_numeric_code')) + ->whereRaw('SUBSTRING_INDEX(code, "-", -1) REGEXP "^[0-9]+$"') + ->value('max_numeric_code'); + // $next_number = 1; + if ($last_numeric_code) { + // // Jika ada kode sebelumnya, pecah kode dan tambahkan 1 ke angka terakhir + // $parts = explode('-', $last_code); + // $last_number = (int) end($parts); + $next_number = $last_numeric_code + 1; + } + + return self::makeCode($next_number); + } + + + public static function makeCode($next_number) + { + // Pastikan $next_number adalah integer positif + $next_number = max(1, (int) $next_number); + + // Menghasilkan kode dengan format yang diinginkan + return self::$code_prefix . '-' . str_pad($next_number, 5, '0', STR_PAD_LEFT); + } } diff --git a/Modules/Internal/Http/Controllers/Api/DailyMonitoringController.php b/Modules/Internal/Http/Controllers/Api/DailyMonitoringController.php index b6573618..fc13caaa 100644 --- a/Modules/Internal/Http/Controllers/Api/DailyMonitoringController.php +++ b/Modules/Internal/Http/Controllers/Api/DailyMonitoringController.php @@ -66,7 +66,7 @@ class DailyMonitoringController extends Controller ->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',) + ->select('claims.id AS claim_id','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(); diff --git a/Modules/Internal/Routes/api.php b/Modules/Internal/Routes/api.php index 17b2095d..68f70101 100644 --- a/Modules/Internal/Routes/api.php +++ b/Modules/Internal/Routes/api.php @@ -245,9 +245,10 @@ Route::prefix('internal')->group(function () { Route::post('files-mcu', 'filesMcu'); }); Route::get('claim-requests', [ClaimRequestController::class, 'index'])->name('claim-requests.index'); - Route::get('claim-requests/list-member', [ClaimRequestController::class, 'getClaimMemberInfiniteScroll']); // Bagaskoro, BSD 31 Oktober 2023 + Route::get('claim-requests/list-member', [ClaimRequestController::class, 'getClaimMemberInfiniteScroll']); // Bagaskoro, BSD 31 Oktober 2023 Route::post('claim-requests/{id}/approve', [ClaimRequestController::class, 'approve'])->name('claim-requests.approve'); Route::get('claim-requests/{id}', [ClaimRequestController::class, 'show'])->name('claim-requests.show'); + Route::post('claim-requests', [ClaimRequestController::class, 'createNew']); // Bagaskoro, BSD 2 November 2023 Route::put('claim-requests/{id}', [ClaimRequestController::class, 'update'])->name('claim-requests.update'); Route::post('claim-requests/import', [ClaimRequestController::class, 'importClaim'])->name('claim-requests.importClaim'); Route::get('claim-requests/detail/{id}', [ClaimRequestController::class, 'claimRequestDetail']); diff --git a/frontend/client-portal/.env.development b/frontend/client-portal/.env.development index d7d23df0..1292c8a9 100644 --- a/frontend/client-portal/.env.development +++ b/frontend/client-portal/.env.development @@ -4,4 +4,6 @@ PORT=8083 REACT_APP_HOST_API_URL="https://aso-api.linksehat.dev/api/client" -VITE_API_URL="https://aso-api.linksehat.dev/api/client" +# VITE_API_URL="https://aso-api.linksehat.dev/api/client" +VITE_API_URL="http://localhost:8000/api/client" + diff --git a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Claim.tsx b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Claim.tsx index b77d578e..7e753b93 100644 --- a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Claim.tsx +++ b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Claim.tsx @@ -32,12 +32,6 @@ export default function Claim() { const [memberDetail, setMemberDetail] = useState(); const [claimList, setClaimList] = useState(); - // Use Effect - // -------------------- - useEffect(() => { - loadDataTableData(); - }, []) - // Load Data // ------------------- const loadDataTableData = async () => { @@ -47,6 +41,10 @@ export default function Claim() { setClaimList(response.claim_list); } + useEffect(() => { + loadDataTableData(); + }, [loadDataTableData]) + return ( diff --git a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DailyMonitoringList.tsx b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DailyMonitoringList.tsx index 500b4f9f..0c1bc81f 100644 --- a/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DailyMonitoringList.tsx +++ b/frontend/dashboard/src/pages/CaseManagement/DailyMonitoring/Components/DailyMonitoringList.tsx @@ -25,12 +25,6 @@ export default function DailyMonitoringList() { fontWeight: 'bold', }; - // Use Effect - // -------------------- - useEffect(() => { - loadDataTableData(); - }, []) - // Load Data // ------------------- const loadDataTableData = async () => { @@ -42,6 +36,10 @@ export default function DailyMonitoringList() { setDataTableData(response); } + useEffect(() => { + loadDataTableData(); + }, []) + return ( diff --git a/frontend/dashboard/src/pages/ClaimRequests/Components/FormCreate.tsx b/frontend/dashboard/src/pages/ClaimRequests/Components/FormCreate.tsx new file mode 100644 index 00000000..a36259a6 --- /dev/null +++ b/frontend/dashboard/src/pages/ClaimRequests/Components/FormCreate.tsx @@ -0,0 +1,361 @@ +/** + * Core + * ============================================ + */ +import { useEffect, useState } from 'react'; +import { useNavigate } from 'react-router'; +import { Box, FormControlLabel, Grid, Checkbox, Typography, CircularProgress , Button, styled, Stack, IconButton, Card} from '@mui/material'; +import { LoadingButton } from '@mui/lab'; + +/** + * Components + * ============================================ +*/ +// - Global - +import Label from '@/components/Label'; +// - Local - +import FormCreateSearch from './FormCreateSearch'; +import FormCreateListChoose from './FormCreateListChoose'; +import FormCreateBtnUpload from './FormCreateBtnUpload'; + +/** + * Icon, Utils, Types, Functions, theme, hook + * ============================================ + */ +import { ArrowBackIosNew } from '@mui/icons-material'; +import { fDateTimesecond } from '@/utils/formatTime'; +import { MemberListType } from '../Model/Types'; +import { addClaimRequest, getMemberList } from '../Model/Functions'; +import palette from '@/theme/palette'; +import FormCreateFilesUpload from './FormCreateFilesUpload'; +import useLoadOnScroll from '@/hooks/useLoadOnScroll'; +import useCollapseDrawer from '@/hooks/useCollapseDrawer'; +import FormCreateBtnChoose from './FormCreateBtnChoose'; + +export default function FormCreate() { + const navigate = useNavigate() + const defaultListChoosed:MemberListType[] = []; + + // State + // ------------------------- + const [keyword, setKeyword] = useState(''); + const [listChoosed, setListChoosed] = useState([]); + const [isChoosed, setIsChoosed] = useState(false); + const [formIsLoading, setFormIsLoading] = useState(false); + + // List Choose - auto Scroll + // ------------------------- + const fetchFunction = async (page: number): Promise => getMemberList(page, keyword) + + const {data: MemberList, isLoading: scrollIsLoading, setData, resetLastPage, refetchData} = useLoadOnScroll(fetchFunction); + + // List Choose - Search + // ------------------------- + const handleSearch = (keyword: string) => { + setData([]) + resetLastPage() + setKeyword(keyword) + refetchData() + } + + // Function - Clear Form + // ----------------------------- + const clearForm = () => { + setListChoosed(defaultListChoosed); + setIsChoosed(false); + } + + // Function - Choose Patien Type + // ----------------------------- + const handleChoosePatienType = (data: MemberListType, type: string) => { + let newListChoosed = listChoosed.map((list) => { + if (data.id == list.id) { + list.patien_type = type + } + + return list; + }) + + setListChoosed(newListChoosed) + } + + // Function - Handle Btn Upload + // ----------------------------- + const handleChangeInput = (data: MemberListType, type_file: 'invoice'|'prescription'|'laboratorium', file: any) => { + let newListChoosed = listChoosed.map((list) => { + if (data.id == list.id) { + if (type_file == 'invoice') { + if (list.invoice_files == undefined) { + list.invoice_files = [file]; + } + else { + list.invoice_files.push(file); + } + } + + if (type_file == 'prescription') { + if (list.prescription_files == undefined) { + list.prescription_files = [file]; + } + else { + list.prescription_files.push(file); + } + } + + if (type_file == 'laboratorium') { + if (list.laboratorium_files == undefined) { + list.laboratorium_files = [file]; + } + else { + list.laboratorium_files.push(file); + } + } + } + + return list; + }) + + setListChoosed(newListChoosed) + } + + // Function - Handle Remove Fle + // ----------------------------- + const handleRemoveFile = (data: MemberListType, type_file: 'invoice'|'prescription'|'laboratorium', target_index: number) => { + let newListChoosed = listChoosed.map((list) => { + if (data.id == list.id) { + if (type_file == 'invoice') { + list.invoice_files = list.invoice_files?.filter((file: any, index: number) =>{ + if (target_index !== index) { + return file; + } + }); + } + + if (type_file == 'prescription') { + list.prescription_files = list.prescription_files?.filter((file: any, index: number) =>{ + if (target_index !== index) { + return file; + } + }); + } + + if (type_file == 'laboratorium') { + list.laboratorium_files = list.laboratorium_files?.filter((file: any, index: number) =>{ + if (target_index !== index) { + return file; + } + }); + } + } + + return list; + }) + + setListChoosed(newListChoosed) + } + + // Function - Handle Submit Form + // ----------------------------- + const handleSubmit = async () => { + setFormIsLoading(true) + let response = await addClaimRequest(listChoosed) + setFormIsLoading(false) + + if (response == true) { + clearForm() + } + } + + let isDirty = listChoosed.some((row) => { + if (row.patien_type == undefined) { + return true + } + }) + + return ( + + {/* Back Button */} + + isChoosed==false ? navigate(`/claim-requests`) : setIsChoosed(false)} > + + + + + {'Create Claim Requests'} + + + + {/* Choose Section */} + + {/* Search */} + + handleSearch('')} onSubmit={(keyword) => handleSearch(keyword)} /> + + + + + {/* List */} + + + { + MemberList.map((row, index) => { + return ( + { + checked ? setListChoosed((prevData) => [...prevData, data]) : setListChoosed((items) => items.filter(item => item.id != data.id)) + }} + /> + ) + }) + } + + + + {/* Loading */} + + + + + {/* Submit List */} + + setIsChoosed(true)} /> + + + + + + {/* Input Section */} + + { + listChoosed.map((row, index) => { + return ( + + + {/* Patien Name */} + + + + + {row.name} + + + {row.member_id} + + + + + + + + {/* Patien Type */} + + + + + + + + + + + + {/* Invoice */} + + + + Real Invoice + + + {row.invoice_files && row.invoice_files.map((file, index) => ( + + handleRemoveFile(row, 'invoice', index)} /> + + ))} + + + handleChangeInput(row, 'invoice', file)} /> + + + + + {/* Prescription */} + + + + Doctor's Prescription and Another Documents + + + {row.prescription_files && row.prescription_files.map((file, index) => ( + + handleRemoveFile(row, 'prescription', index)} /> + + ))} + + + handleChangeInput(row, 'prescription', file)} /> + + + + + {/* Laboratorium */} + + + + Laboratory Results + + + {row.laboratorium_files && row.laboratorium_files.map((file, index) => ( + + handleRemoveFile(row, 'laboratorium', index)} /> + + ))} + + + handleChangeInput(row, 'laboratorium', file)} /> + + + + + + + ) + }) + } + + + + + handleSubmit()}> + Save Changes + + + + + + ) +} diff --git a/frontend/dashboard/src/pages/ClaimRequests/Components/FormCreateBtnChoose.tsx b/frontend/dashboard/src/pages/ClaimRequests/Components/FormCreateBtnChoose.tsx new file mode 100644 index 00000000..cffd3bc3 --- /dev/null +++ b/frontend/dashboard/src/pages/ClaimRequests/Components/FormCreateBtnChoose.tsx @@ -0,0 +1,39 @@ +import { styled, Button } from "@mui/material"; +import useCollapseDrawer from "@/hooks/useCollapseDrawer"; + +/** + * Custom Style + * ============================================ +*/ +const DivCustom1 = styled('div')(({ theme }) => ({ + background: 'white', + position: 'fixed', + left: '350px', + right: 0, + bottom: 0, + paddingLeft: '32px', + paddingRight: '32px', + paddingTop: '32px', + paddingBottom: '48px', + [theme.breakpoints.between('sm', 'lg')]: { + left: '0px', + }, +})); + +type Props = { + disabled: boolean, + title : string, + handleClickProp: () => void +} + +export default function FormCreateBtnChoose ({disabled, title, handleClickProp}: Props) { + const { collapseClick } = useCollapseDrawer(); + + return ( + + + + ) +} diff --git a/frontend/dashboard/src/pages/ClaimRequests/Components/FormCreateBtnUpload.tsx b/frontend/dashboard/src/pages/ClaimRequests/Components/FormCreateBtnUpload.tsx new file mode 100644 index 00000000..ac40b098 --- /dev/null +++ b/frontend/dashboard/src/pages/ClaimRequests/Components/FormCreateBtnUpload.tsx @@ -0,0 +1,39 @@ +import { useRef } from "react"; +import { Box, ButtonBase, Typography } from "@mui/material"; +import Iconify from "@/components/Iconify"; + +type Props = { + handleChangeInputProp: (event: any) => void +} + +export default function FormCreateBtnUpload ({handleChangeInputProp}: Props) { + const fileInput = useRef(null); + + return ( + fileInput.current?.click()}> + + + + Upload Result + + + handleChangeInputProp(event.target.files ? event.target.files[0] : {})} + accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel, text/plain, application/pdf" + /> + + ) +} diff --git a/frontend/dashboard/src/pages/ClaimRequests/Components/FormCreateFilesUpload.tsx b/frontend/dashboard/src/pages/ClaimRequests/Components/FormCreateFilesUpload.tsx new file mode 100644 index 00000000..7ab9d7bd --- /dev/null +++ b/frontend/dashboard/src/pages/ClaimRequests/Components/FormCreateFilesUpload.tsx @@ -0,0 +1,25 @@ +import Iconify from "@/components/Iconify"; +import { ArrowBackIosNew, InsertDriveFile } from '@mui/icons-material'; +import { Stack, Typography } from "@mui/material"; + +type Props = { + file: any, + handleRemoveFileProp: () => void, +} + +export default function FormCreateFilesUpload({ file, handleRemoveFileProp }: Props) { + return ( + + + + {file.name ? file.name : '-'} + + {handleRemoveFileProp()}} + sx={{cursor: 'pointer'}} + > + + ) +} diff --git a/frontend/dashboard/src/pages/ClaimRequests/FormCreateListChoose.tsx b/frontend/dashboard/src/pages/ClaimRequests/Components/FormCreateListChoose.tsx similarity index 98% rename from frontend/dashboard/src/pages/ClaimRequests/FormCreateListChoose.tsx rename to frontend/dashboard/src/pages/ClaimRequests/Components/FormCreateListChoose.tsx index ce4c6747..03c8d0b1 100644 --- a/frontend/dashboard/src/pages/ClaimRequests/FormCreateListChoose.tsx +++ b/frontend/dashboard/src/pages/ClaimRequests/Components/FormCreateListChoose.tsx @@ -18,7 +18,7 @@ import Label from '@/components/Label'; * ============================================ */ import { fDateTimesecond } from '@/utils/formatTime'; -import { MemberListType } from './Model/Types'; +import { MemberListType } from '../Model/Types'; import palette from '@/theme/palette'; /** diff --git a/frontend/dashboard/src/pages/ClaimRequests/FormCreateSearch.tsx b/frontend/dashboard/src/pages/ClaimRequests/Components/FormCreateSearch.tsx similarity index 97% rename from frontend/dashboard/src/pages/ClaimRequests/FormCreateSearch.tsx rename to frontend/dashboard/src/pages/ClaimRequests/Components/FormCreateSearch.tsx index f21b78d6..026b886b 100644 --- a/frontend/dashboard/src/pages/ClaimRequests/FormCreateSearch.tsx +++ b/frontend/dashboard/src/pages/ClaimRequests/Components/FormCreateSearch.tsx @@ -19,7 +19,7 @@ import { FormProvider, RHFTextField } from '@/components/hook-form'; * ============================================ */ import { Search } from '@mui/icons-material'; -import { SearchType } from './Model/Types'; +import { SearchType } from '../Model/Types'; type Props = { onSubmit: (keyword: string) => void, diff --git a/frontend/dashboard/src/pages/ClaimRequests/Form.tsx b/frontend/dashboard/src/pages/ClaimRequests/Components/FormEdit.tsx similarity index 92% rename from frontend/dashboard/src/pages/ClaimRequests/Form.tsx rename to frontend/dashboard/src/pages/ClaimRequests/Components/FormEdit.tsx index 6aaf56e1..faa95bf0 100644 --- a/frontend/dashboard/src/pages/ClaimRequests/Form.tsx +++ b/frontend/dashboard/src/pages/ClaimRequests/Components/FormEdit.tsx @@ -4,8 +4,8 @@ import { useNavigate } from 'react-router-dom'; import { yupResolver } from '@hookform/resolvers/yup'; import { Controller, useForm } from 'react-hook-form'; import React, { useRef, useEffect, useMemo, useState } from 'react'; -import axios from '../../utils/axios'; -import { FormProvider, RHFTextField } from '../../components/hook-form'; +import axios from '../../../utils/axios'; +import { FormProvider, RHFTextField } from '../../../components/hook-form'; import { makeFormData } from '@/utils/jsonToFormData'; import { @@ -32,12 +32,12 @@ import { ButtonBase, Box, } from '@mui/material'; -import Iconify from '../../components/Iconify'; +import Iconify from '../../../components/Iconify'; import CalendarTodayIcon from '@mui/icons-material/CalendarToday'; import { LoadingButton } from '@mui/lab'; -import { fCurrency } from '../../utils/formatNumber'; -import MemberSelectDialog from '../../components/dialogs/MemberSelectDialog'; -import { Add, DeleteOutline } from '@mui/icons-material'; +import { fCurrency } from '../../../utils/formatNumber'; +import MemberSelectDialog from '../../../components/dialogs/MemberSelectDialog'; +import { Add, ArrowBackIosNew, DeleteOutline } from '@mui/icons-material'; import { ClaimRequest, Files } from '@/@types/claims'; import { fDateTimesecond } from '@/utils/formatTime'; @@ -51,7 +51,7 @@ type Props = { currentClaim?: ClaimRequest; }; -export default function ClaimForm({ isEdit, currentClaim }: Props) { +export default function FormEdit({ isEdit, currentClaim }: Props) { const navigate = useNavigate(); const { enqueueSnackbar } = useSnackbar(); @@ -90,7 +90,7 @@ export default function ClaimForm({ isEdit, currentClaim }: Props) { resolver: yupResolver(EditClaimSchema), defaultValues, }); - + const { reset, watch, @@ -188,8 +188,8 @@ export default function ClaimForm({ isEdit, currentClaim }: Props) { _method: 'PUT' }); - const response = await axios.post(`/claim-requests/${data.id}`, formData); - + const response = await axios.put(`/claim-requests/${data.id}`, formData); + reset(); enqueueSnackbar('Claim Request Updated Successfully!', { variant: 'success' }); navigate('/claim-requests'); @@ -208,6 +208,18 @@ export default function ClaimForm({ isEdit, currentClaim }: Props) { return ( + + + navigate(`/claim-requests`)} > + + + + + {'Edit Claim Requests'} + + + + @@ -224,7 +236,7 @@ export default function ClaimForm({ isEdit, currentClaim }: Props) { {/* */} - + @@ -246,7 +258,7 @@ export default function ClaimForm({ isEdit, currentClaim }: Props) { - ), }} + ), }} name="date" label="Date of Submission" disabled/> @@ -310,7 +322,7 @@ export default function ClaimForm({ isEdit, currentClaim }: Props) { - {/* -------------------------------Upload Dokumen Diagnosa------------------------------- */} + {/* -------------------------------Upload Dokumen Diagnosa------------------------------- */} Diagnosis Document @@ -360,7 +372,7 @@ export default function ClaimForm({ isEdit, currentClaim }: Props) { - {/* -------------------------------Upload Result Hasil Penunjang------------------------------- */} + {/* -------------------------------Upload Result Hasil Penunjang------------------------------- */} Supporting Result Document diff --git a/frontend/dashboard/src/pages/ClaimRequests/CreateUpdate.tsx b/frontend/dashboard/src/pages/ClaimRequests/CreateUpdate.tsx index fa6b83b3..c710deaa 100644 --- a/frontend/dashboard/src/pages/ClaimRequests/CreateUpdate.tsx +++ b/frontend/dashboard/src/pages/ClaimRequests/CreateUpdate.tsx @@ -4,7 +4,7 @@ import { ArrowBackIosNew } from '@mui/icons-material'; import { yupResolver } from '@hookform/resolvers/yup'; import { Autocomplete, Button, Card, Collapse, Container, Divider, Grid, Stack, Table, TableBody, TableCell, TableRow, TextField, Typography } from '@mui/material'; import { Controller, useForm } from 'react-hook-form'; -import { useParams, useNavigate } from 'react-router-dom'; +import { useParams } from 'react-router-dom'; import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs'; import { FormProvider, RHFCheckbox, RHFSelect, RHFTextField } from '../../components/hook-form'; import Page from '../../components/Page'; @@ -18,12 +18,11 @@ import { LoadingButton } from '@mui/lab'; import { fCurrency } from '../../utils/formatNumber'; import Iconify from '../../components/Iconify'; import { ClaimRequest } from '@/@types/claims'; -import Form from './Form'; -import FormCreate from './FormCreate'; +import FormEdit from './Components/FormEdit'; +import FormCreate from './Components/FormCreate'; export default function ClaimsCreateUpdate() { - const navigate = useNavigate() const { themeStretch } = useSettings(); const { id } = useParams(); @@ -46,18 +45,6 @@ export default function ClaimsCreateUpdate() { return ( - - - navigate(`/claim-requests`)} > - - - - - {id == undefined ? 'Create Claim Requests' : 'Edit Claim Requests'} - - - - { id == undefined ? @@ -66,7 +53,7 @@ export default function ClaimsCreateUpdate() { ) : ( -
+ ) } diff --git a/frontend/dashboard/src/pages/ClaimRequests/FormCreate.tsx b/frontend/dashboard/src/pages/ClaimRequests/FormCreate.tsx deleted file mode 100644 index 0f7c936f..00000000 --- a/frontend/dashboard/src/pages/ClaimRequests/FormCreate.tsx +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Core - * ============================================ - */ -import { useEffect, useState } from 'react'; -import { Box, FormControlLabel, Grid, Checkbox, Typography, CircularProgress , Button, styled} from '@mui/material'; - -/** - * Components - * ============================================ -*/ -// - Global - -import Label from '@/components/Label'; -// - Local - -import FormCreateSearch from './FormCreateSearch'; - -/** - * Icon, Utils, Types, Functions, theme, hook - * ============================================ - */ -import { MemberListType } from './Model/Types'; -import { getMemberList } from './Model/Functions'; -import useLoadOnScroll from '@/hooks/useLoadOnScroll'; -import FormCreateListChoose from './FormCreateListChoose'; - -/** - * Custom Style - * ============================================ -*/ -const DivCustom1 = styled('div')(({ theme }) => ({ - left: '350px', - [theme.breakpoints.between('sm', 'lg')]: { - left: '0px', - }, -})); - -export default function FormCreate() { - // State - // ------------------------- - const [keyword, setKeyword] = useState(''); - const [listChoosed, setListChoosed] = useState([]); - const [isChoosed, setIsChoosed] = useState(false); - - // List Choose - auto Scroll - // ------------------------- - const fetchFunction = async (page: number): Promise => getMemberList(page, keyword) - const {data: MemberList, isLoading, setData, resetLastPage, refetchData} = useLoadOnScroll(fetchFunction); - - // List Choose - Search - // ------------------------- - const handleSearch = (keyword: string) => { - setData([]) - resetLastPage() - setKeyword(keyword) - refetchData() - } - - return ( - - {/* Choose Section */} - - {/* Search */} - - handleSearch('')} onSubmit={(keyword) => handleSearch(keyword)} /> - - - - - {/* List */} - - - { - MemberList.map((row, index) => { - return ( - { - checked ? setListChoosed((prevData) => [...prevData, data]) : setListChoosed((items) => items.filter(item => item.id != data.id)) - }} - /> - ) - }) - } - - - - {/* Loading */} - - - - - {/* Submit List */} - - - - - - - - - - {/* Input Section */} - - - ) -} diff --git a/frontend/dashboard/src/pages/ClaimRequests/Model/Functions.tsx b/frontend/dashboard/src/pages/ClaimRequests/Model/Functions.tsx index 4d64f49a..8a94db2a 100644 --- a/frontend/dashboard/src/pages/ClaimRequests/Model/Functions.tsx +++ b/frontend/dashboard/src/pages/ClaimRequests/Model/Functions.tsx @@ -1,6 +1,7 @@ import axios from '@/utils/axios'; import { enqueueSnackbar } from 'notistack'; import { MemberListType } from './Types'; +import { makeFormData } from '@/utils/jsonToFormData'; /** * Listing Member @@ -20,3 +21,53 @@ export const getMemberList = async ( page: number, keyword: string ): Promise => { + // Mapping + const formData = new FormData(); + + data.map((row, index) => { + formData.append(`member_id[${index}]`, row.id.toString()); + formData.append(`service_code[${index}]`, row.patien_type??''); + + if (row.invoice_files != undefined) { + row.invoice_files.forEach((file, file_index) => { + formData.append(`invoice[${index}][${file_index}]`, file); + }); + } + + if (row.prescription_files != undefined) { + row.prescription_files.forEach((file, file_index) => { + formData.append(`prescription[${index}][${file_index}]`, file); + }); + } + + if (row.laboratorium_files != undefined) { + row.laboratorium_files.forEach((file, file_index) => { + formData.append(`laboratorium[${index}][${file_index}]`, file); + }); + } + }) + + // Axios + const response = await axios.post(`/claim-requests`, formData) + .then((res) =>{ + enqueueSnackbar("Berhasil membuat data !", { + variant: 'success', + }); + + return true; + }) + .catch((res) => { + enqueueSnackbar("server error !", { + variant: 'error', + }); + + return false; + }); + + return response; +}; diff --git a/frontend/dashboard/src/pages/ClaimRequests/Model/Types.tsx b/frontend/dashboard/src/pages/ClaimRequests/Model/Types.tsx index d82acdf9..963abd1b 100644 --- a/frontend/dashboard/src/pages/ClaimRequests/Model/Types.tsx +++ b/frontend/dashboard/src/pages/ClaimRequests/Model/Types.tsx @@ -9,7 +9,11 @@ export type SearchType = { * Member List */ export type MemberListType = { - id : string, - member_id : string, - name : string, + id : string, + member_id : string, + name : string, + patien_type? : string, + invoice_files? : any[], + laboratorium_files? : any[], + prescription_files? : any[] }