From 79c8e475e827576e0ecdea1fdf857e3f85333299 Mon Sep 17 00:00:00 2001 From: korospace Date: Fri, 3 Nov 2023 11:32:09 +0700 Subject: [PATCH] finishing benefit configuration --- .../Http/Controllers/Api/ClaimController.php | 125 ++++++++-- Modules/Internal/Routes/api.php | 10 +- .../Transformers/ClaimHistoryCareResource.php | 4 +- app/Models/ClaimHistoryCare.php | 2 +- ...3_add_column_to_claim_service_benefits.php | 38 +++ .../hook-form/v2/RHFTextFieldMoney.tsx | 2 - .../dashboard/src/pages/Claims/Detail.tsx | 210 ++++++++-------- .../src/pages/Claims/Model/Functions.tsx | 69 ++++-- .../src/pages/Claims/Model/Types.tsx | 1 + .../components/BenefitConfigurationDialog.tsx | 230 ++++++++++-------- .../components/BenefitConfigurationList.tsx | 16 +- 11 files changed, 443 insertions(+), 264 deletions(-) create mode 100644 database/migrations/2023_11_03_110023_add_column_to_claim_service_benefits.php diff --git a/Modules/Internal/Http/Controllers/Api/ClaimController.php b/Modules/Internal/Http/Controllers/Api/ClaimController.php index 8b5d8400..81441485 100644 --- a/Modules/Internal/Http/Controllers/Api/ClaimController.php +++ b/Modules/Internal/Http/Controllers/Api/ClaimController.php @@ -59,7 +59,7 @@ class ClaimController extends Controller ->where('status', '!=', 'requested') // Penjagaan agar approve baru masuk ke claim management ->latest() ->paginate(10); - + return response()->json($claims); } @@ -118,8 +118,8 @@ class ClaimController extends Controller { $claim = Claim::query() ->with([ - 'member', - // 'member.currentPlan', + 'member', + // 'member.currentPlan', // 'member.currentPlan.benefits', 'member.currentCorporate', // 'member.currentPolicy', @@ -159,9 +159,9 @@ class ClaimController extends Controller { $claim = Claim::query() ->with([ - 'member', + 'member', 'plan', - 'member.currentPlan', + 'member.currentPlan', 'member.currentPlan.benefits', 'member.currentCorporate', 'member.currentPolicy', @@ -205,7 +205,7 @@ class ClaimController extends Controller 'amount_not_approved' => $request->amount_not_approved, 'excess_paid' => $request->excess_paid, ]; - + $validator = Validator::make($request->all(), [ 'benefit_desc' => 'required', 'amount_incurred' => 'required|numeric', @@ -213,11 +213,11 @@ class ClaimController extends Controller 'amount_not_approved' => 'required|numeric', 'excess_paid' => 'required|numeric', ], $customMessages); - + if ($validator->fails()) { return ApiResponse::apiResponse('Bad Request', $data, $validator->errors(), 400); } - + // Validasi berhasil, lanjutkan dengan pembaruan data $claim = Claim::findOrFail($id); $claim->fill([ @@ -227,8 +227,8 @@ class ClaimController extends Controller 'amount_not_approved' => $request->amount_not_approved, 'excess_paid' => $request->excess_paid, ])->save(); - - return $claim; + + return $claim; } /** @@ -259,12 +259,12 @@ class ClaimController extends Controller return $claim; } - + public function updateItems(Request $request, $id) { $request->validate([]); $claim = Claim::findOrFail($id); - + $order = 1; $data = []; $claim->items()->forceDelete(); @@ -290,7 +290,7 @@ class ClaimController extends Controller // Update total $claim->total_claim = $totalClaim; $claim->save(); - + return Helper::responseJson([], message: "Item Claim berhasil di update"); } @@ -304,7 +304,7 @@ class ClaimController extends Controller foreach ($request->primary as $diagnosisId) { $claim->diagnoses()->create([ 'claim_id' => $claim->id, - 'type' => 'primary', + 'type' => 'primary', 'diagnosis_id' => $diagnosisId, 'note' => '', 'description' => '', @@ -316,7 +316,7 @@ class ClaimController extends Controller foreach ($request->secondary as $diagnosisId) { $claim->diagnoses()->create([ 'claim_id' => $claim->id, - 'type' => 'secondary', + 'type' => 'secondary', 'diagnosis_id' => $diagnosisId, 'note' => '', 'description' => '', @@ -433,7 +433,7 @@ class ClaimController extends Controller // TODO Fix this tipu tipu $inpationBenefit = $claim->member->currentPlan->benefits()->first(); - + $pdf = PDF::loadView('pdf.final_log', [ 'claim' => $claim, 'member' => $claim->member, @@ -441,7 +441,7 @@ class ClaimController extends Controller 'hospital' => $hospital, 'inpationBenefit' => $inpationBenefit ]); - + return $pdf->download('Final LOG '.$claim->code.'.pdf'); $view = view('pdf.final_log', [ @@ -461,7 +461,7 @@ class ClaimController extends Controller $writer = WriterEntityFactory::createXLSXWriter(); // Membuka penulis untuk menulis ke file $writer->openToFile(public_path('files/Benefit Usage Report.xlsx')); - + // Sheet 1 $writer->getCurrentSheet()->setName('Worksheet'); $headers_map_to_table_fields = Claim::$listing_doc_headers; @@ -477,7 +477,7 @@ class ClaimController extends Controller return $diagnosis->where('type', 'primary'); }, 'diagnoses.icd', - 'plan', + 'plan', 'benefit', 'claimRequest', 'claimRequest.service', @@ -598,7 +598,7 @@ class ClaimController extends Controller // ]; // $row = WriterEntityFactory::createRowFromArray($rowData); // $writer->addRow($row); - + // } $writer->close(); @@ -618,7 +618,7 @@ class ClaimController extends Controller ->select('claim_requests.id') ->first(); $claim_id = $data_claim_requests->id; - + $customer_data = DB::table('claim_requests') ->leftJoin('claims', 'claim_requests.id', '=', 'claims.claim_request_id') ->leftJoin('members', 'claim_requests.member_id', '=', 'members.id') @@ -633,7 +633,7 @@ class ClaimController extends Controller 'members.payor_id', 'members.member_id', 'claim_requests.payment_type', - 'corporates.name AS coporate_name', + 'corporates.name AS coporate_name', ) ->first(); $results['customer_data'] = $customer_data; @@ -844,7 +844,7 @@ class ClaimController extends Controller ]); } } - + return Helper::responseJson([]); } @@ -903,7 +903,7 @@ class ClaimController extends Controller 'updated_at' => date('Y-m-d H:i:s'), ]; } - DB::table('claim_request_files')->insert($dataToInsert); + DB::table('claim_request_files')->insert($dataToInsert); return Helper::responseJson([]); } @@ -999,4 +999,81 @@ class ClaimController extends Controller return Helper::responseJson(message: 'Data Berhasil di update'); } + + /** + * Get Benefit Configuration + * + * Bagaskoro, BSD 03 November 2023 + */ + public function getBenefitConfiguration(Request $request, $claim_id) { + + $benefit_list = DB::table('claims') + ->leftJoin('claim_services', 'claims.claim_request_id', '=', 'claim_services.claim_request_id') + ->leftJoin('claim_service_benefits', 'claim_services.id', '=', 'claim_service_benefits.claim_service_id') + ->leftJoin('benefits', 'claim_service_benefits.benefit_id', '=', 'benefits.id') + ->select("claim_service_benefits.id AS claim_service_benefits_id", "benefits.description AS benefit_name", "claim_service_benefits.amount_incurred", "claim_service_benefits.amount_approved", "claim_service_benefits.amount_not_approved", "claim_service_benefits.excess_paid") + ->where("claims.id", "=", $claim_id) + ->get(); + + return response()->json([ + 'error' => false, + 'message' => "success", + 'data' => [ + 'benefit_list' => $benefit_list, + ] + ],200); + } + + /** + * Edit Benefit Configuration + * + * Bagaskoro, BSD 03 November 2023 + */ + public function editBenefitConfiguration(Request $request, $claim_service_benefits_id) { + $request->merge(['claim_service_benefits_id' => $claim_service_benefits_id]); + + // validation rule + $validator = Validator::make($request->all(),[ + 'claim_service_benefits_id' => 'required|exists:claim_service_benefits,id', + 'amount_incurred' => 'required|numeric', + 'amount_approved' => 'required|numeric', + 'amount_not_approved' => 'required|numeric', + 'excess_paid' => 'required|numeric', + ],$this->messages()); + + // validation error + if ($validator->fails()) { + return response()->json([ + 'error' => true, + 'message' => $validator->getMessageBag() + ],400); + } + + try { + DB::table('claim_service_benefits')->where('id', $claim_service_benefits_id)->update([ + 'amount_incurred' => $request->amount_incurred, + 'amount_approved' => $request->amount_approved, + 'amount_not_approved' => $request->amount_not_approved, + 'excess_paid' => $request->excess_paid, + ]); + } + catch (\Throwable $th) { + return Helper::responseJson(status: 'failed', statusCode: 500, message: $th->getMessage()); + } + + return Helper::responseJson(status: 'success', statusCode: 200, message: "data berhasil disimpan !"); + } + + protected function messages() + { + return [ + 'required' => ':attribute harus diisi', + 'integer' => ':attribute harus angka', + 'unique' => ':attribute (:input) sudah ada', + 'max' => ':attribute maximal :max karakter', + 'exists' => ':attribute (:input) tidak ditemukan', + 'numeric' => ':attribute harus angka', + 'digits_between'=> ':attribute maximal :max digit minimal :min digit' + ]; + } } diff --git a/Modules/Internal/Routes/api.php b/Modules/Internal/Routes/api.php index b13ca405..42dfefa0 100644 --- a/Modules/Internal/Routes/api.php +++ b/Modules/Internal/Routes/api.php @@ -108,7 +108,7 @@ Route::prefix('internal')->group(function () { Route::get('corporates/{corporate_id}/hospitals/data', [HospitalController::class, 'dataHospital']); Route::post('corporates/{corporate_id}/hospitals/save', [HospitalController::class, 'store']); Route::put('corporates/{corporate_id}/hospitals/{id}/edit', [HospitalController::class, 'update']); - + Route::get('corporates/{corporate_id}/members', [CorporateMemberController::class, 'index']); Route::get('corporates/{corporate_id}/members/list', [CorporateMemberController::class, 'generateMemberList']); @@ -117,7 +117,7 @@ Route::prefix('internal')->group(function () { Route::get('corporates/{corporate_id}/diagnosis', [DiagnosisExclusionController::class, 'listDiagnosis']); - + Route::get('corporates/{corporate_id}/diagnosis-exclusions', [DiagnosisExclusionController::class, 'index']); Route::get('corporates/{corporate_id}/diagnosis-exclusions/{id_exclusion}', [DiagnosisExclusionController::class, 'detilExclusion']); // By Bagaskoro, get detil exclusion Route::post('corporates/{corporate_id}/diagnosis-exclusions/store', [DiagnosisExclusionController::class, 'storeExclusion']); @@ -140,8 +140,8 @@ Route::prefix('internal')->group(function () { Route::post('corporates/{corporate_id}/formulariums/import', [CorporateFormulariumController::class, 'import']); Route::put('corporates/{corporate_id}/formulariums-update-status/{id}', [CorporateFormulariumController::class, 'active']); Route::put('corporates/{corporate_id}/formulariums/{formularium_id}/{action}', [CorporateFormulariumController::class, 'updateStatus']); - - + + Route::controller(CorporateController::class)->group(function () { Route::post('add-files-doc', 'addFilesDoc'); Route::post('get-files-doc', 'getFilesDoc'); @@ -231,6 +231,8 @@ Route::prefix('internal')->group(function () { Route::post('claims/request-documents', [ClaimController::class, 'requestDocuments']); Route::get('claims/get-services/{id}', [ClaimController::class, 'getServices']); Route::post('claims/save-services', [ClaimController::class, 'saveServices']); + Route::get('claims/{id}/benefit-configuration', [ClaimController::class, 'getBenefitConfiguration']); // Bagaskoro, BSD 03 November 2023 + Route::put('claims/benefit-configuration/edit/{id}', [ClaimController::class, 'editBenefitConfiguration']); // Bagaskoro, BSD 03 November 2023 Route::get('search-organizations', [OrganizationController::class, 'searchOrganization']); Route::get('search-specialities', [SpecialityController::class, 'searchSpeciality']); diff --git a/Modules/Internal/Transformers/ClaimHistoryCareResource.php b/Modules/Internal/Transformers/ClaimHistoryCareResource.php index feff9ff5..8e39e041 100644 --- a/Modules/Internal/Transformers/ClaimHistoryCareResource.php +++ b/Modules/Internal/Transformers/ClaimHistoryCareResource.php @@ -19,11 +19,11 @@ class ClaimHistoryCareResource extends JsonResource $claim = parent::toArray($request); $secondaryDiagnosis = DiagnosisSecondaryClaimHistoryCare::where('claim_history_care_id', $claim['id'])->with(['icd'])->get()->toArray(); - + $data = [ 'id' => $claim['id'], 'service_code' => $claim['service_code'], - 'admision_date' => $claim['admision_date'], + 'admission_date' => $claim['admission_date'], 'discharge_date' => $claim['discharge_date'], 'claim_id' => $claim['claim_id'], 'organization_id' => $claim['organization_id'], diff --git a/app/Models/ClaimHistoryCare.php b/app/Models/ClaimHistoryCare.php index e526a3de..ba12b585 100644 --- a/app/Models/ClaimHistoryCare.php +++ b/app/Models/ClaimHistoryCare.php @@ -10,7 +10,7 @@ class ClaimHistoryCare extends Model use HasFactory; protected $fillable = [ 'service_code', - 'admision_date', + 'admission_date', 'discharge_date', 'claim_id', 'organization_id', diff --git a/database/migrations/2023_11_03_110023_add_column_to_claim_service_benefits.php b/database/migrations/2023_11_03_110023_add_column_to_claim_service_benefits.php new file mode 100644 index 00000000..9e313d16 --- /dev/null +++ b/database/migrations/2023_11_03_110023_add_column_to_claim_service_benefits.php @@ -0,0 +1,38 @@ +integer('amount_incurred')->default(0)->after('benefit_id'); + $table->integer('amount_approved')->default(0)->after('amount_incurred'); + $table->integer('amount_not_approved')->default(0)->after('amount_approved'); + $table->integer('excess_paid')->default(0)->after('amount_not_approved'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('claim_service_benefits', function (Blueprint $table) { + $table->dropColumn('amount_incurred'); + $table->dropColumn('amount_approved'); + $table->dropColumn('amount_not_approved'); + $table->dropColumn('excess_paid'); + }); + } +}; diff --git a/frontend/dashboard/src/components/hook-form/v2/RHFTextFieldMoney.tsx b/frontend/dashboard/src/components/hook-form/v2/RHFTextFieldMoney.tsx index 078c39b2..c0ecd1cc 100644 --- a/frontend/dashboard/src/components/hook-form/v2/RHFTextFieldMoney.tsx +++ b/frontend/dashboard/src/components/hook-form/v2/RHFTextFieldMoney.tsx @@ -26,8 +26,6 @@ export default function RHFTextFieldMoney({ name, ...other }: IProps & TextField autoComplete="off" fullWidth error={!!error} helperText={error?.message} - onFocus={() => { (values[name] === '0') && setValue(name, '') }} - onBlur={() => { (values[name] === '') && setValue(name, '0') }} {...other} inputProps={{ min: 0, max: 5, style: { textAlign: 'right' } }} InputProps={{ diff --git a/frontend/dashboard/src/pages/Claims/Detail.tsx b/frontend/dashboard/src/pages/Claims/Detail.tsx index ff3f073a..3ba87703 100644 --- a/frontend/dashboard/src/pages/Claims/Detail.tsx +++ b/frontend/dashboard/src/pages/Claims/Detail.tsx @@ -1,16 +1,16 @@ import * as Yup from 'yup'; // mui -import { - Container, - Grid, - Stack, - Typography, - Card, - TextField, - Divider, - ButtonBase, - Box, - IconButton, +import { + Container, + Grid, + Stack, + Typography, + Card, + TextField, + Divider, + ButtonBase, + Box, + IconButton, Autocomplete, FormControl, InputLabel, @@ -93,7 +93,7 @@ export default function Detail() { }); getService(); - }, []); + }, []); function toTitleCase(str: string | null) { return str.replace(/\w\S*/g, function(txt) { @@ -117,7 +117,7 @@ export default function Detail() { const handleCloseDialogRequest = () => { setOpenDialogRequest(false); } - + const [conditionChecked, setConditionChecked] = useState(true); const [diagnosisChecked, setDiagnosisChecked] = useState(false); const [supportingResultChecked, setSupportingResultChecked] = useState(false); @@ -139,7 +139,7 @@ export default function Detail() { const isRequiredFieldsFilled = () => { return noteField.trim() !== ''; }; - + const handelRequestDocument = () => { const dataForm = { claim_id: id, @@ -161,12 +161,12 @@ export default function Detail() { } /*---------------------- Handle History Hospital Care ----------------------------*/ - + interface FormValuesProps extends Partial { taxes: boolean; inStock: boolean; } - + /**------------- Handle History Hospital Care ---------------------*/ const [currentClaimHistoryCare, setCurrentClaimHistoryCare] = useState(null); @@ -191,7 +191,7 @@ export default function Detail() { setCorporateId(response.data.data.corporate_id) setCurrentClaimHistoryCare(response.data.data.history_hospital_care) setClaim(response.data.data) - }) + }) }, []) useEffect( () => { @@ -200,14 +200,14 @@ export default function Detail() { .get(`corporates/${corporate_id}/diagnosis`) .then((response) => { setMainDiagnosis(response.data.data) - }) + }) // setOrganization atau hospital atau location axios .get(`corporates/${corporate_id}/hospitals`) .then((response) => { setOrganization(response.data.data) - }) + }) }, [corporate_id]) @@ -219,7 +219,7 @@ export default function Detail() { .then((response) => { reset({ service_code: response.data.data.service_code, - admision_date: response.data.data.admision_date, + admission_date: response.data.data.admission_date, discharge_date: response.data.data.discharge_date, organization_id: response.data.data.organization_id, practitioner_id: response.data.data.practitioner_id, @@ -229,7 +229,7 @@ export default function Detail() { main_diagnosis_id: response.data.data.main_diagnosis_id, }); - setCarehistory(response.data.data); + setCarehistory(response.data.data); }) .catch((error) => { console.error(error); @@ -242,9 +242,9 @@ export default function Detail() { }) .catch((error) => { console.error(error); - }); - } - + }); + } + }, [claimHistoryId]) useEffect( () => { @@ -253,14 +253,14 @@ export default function Detail() { const [openDialogHospitalCare, setOpenHospitalCare] = useState(false); - + const handleCloseDialogHospitalCare = () => { setEdit(false) setOpenHospitalCare(false); setClaimHistoryId(null) reset(); } - + const [openDialogApproval, setOpenDialogApproval] = useState(false); const handleCloseDialogApprove = () => { @@ -281,20 +281,20 @@ export default function Detail() { { variant: 'success' } ); window.location.reload(); - + } // Handle Location Change const handleLocationChange = (organization_id:number) => { // if (newValue) { const selectedValue = organization_id; - setValue('organization_id', selectedValue); + setValue('organization_id', selectedValue); // let data = { // ...values, // practitioner_id: 0 // } // reset(data) - + axios .get('/doctors?search=&organization_id=' + selectedValue) .then((response) => { @@ -309,14 +309,14 @@ export default function Detail() { const handleDoctorChange = (event, newValue) => { if (newValue) { const selectedValue = newValue.id; - setValue('practitioner_id', selectedValue); + setValue('practitioner_id', selectedValue); } } const handleMainDiagnosisChange = (event, newValue) => { if (newValue) { const selectedValue = newValue.id; - setValue('main_diagnosis_id', selectedValue); + setValue('main_diagnosis_id', selectedValue); } } @@ -329,7 +329,7 @@ export default function Detail() { value: 0 } }], - admision_date: isEdit ? carehistory?.admision_date : '', + admission_date: isEdit ? carehistory?.admission_date : '', discharge_date: isEdit ? carehistory?.discharge_date : '', organization_id: isEdit ? carehistory?.organization_id : '', practitioner_id: isEdit ? carehistory?.practitioner_id : '', @@ -338,12 +338,12 @@ export default function Detail() { sign: isEdit ? carehistory?.sign : '', main_diagnosis_id: isEdit ? carehistory?.main_diagnosis_id : 0, }), - [] + [] ) let NewClaimHistoryCareSchema = Yup.object().shape({ service_code: Yup.string().required('Name is required'), - // admision_date: Yup.date().required('Admisision Date is required'), + // admission_date: Yup.date().required('Admisision Date is required'), // discharge_date: Yup.date().required('Discharge Date is required'), // organization_id: Yup.number().required('Location is required'), // practitioner_id: Yup.number().required('Doctor is required'), @@ -357,7 +357,7 @@ export default function Detail() { resolver: yupResolver(NewClaimHistoryCareSchema), defaultValues, }); - + const { reset, watch, @@ -372,16 +372,16 @@ export default function Detail() { const values = watch(); - + console.log(values, 'debugs') const {fields, append, remove} = useFieldArray({name: "secondary_diagnosis_id", control}) - + const onSubmit = async (data: FormValuesProps) => { if (isEdit){ let newData = { service_code: data.service_code, - admision_date: data.admision_date ? fDateOnly(data.admision_date) : null, + admission_date: data.admission_date ? fDateOnly(data.admission_date) : null, discharge_date: data.discharge_date ? fDateOnly(data.discharge_date) : null, organization_id: data.organization_id, practitioner_id: data.practitioner_id, @@ -391,7 +391,7 @@ export default function Detail() { secondary_diagnosis_id: data.secondary_diagnosis_id ? data.secondary_diagnosis_id.map((row) => row.value.id) : null, main_diagnosis_id: data.main_diagnosis_id, } - + const response:any = await axios.post(`/claims/carehistory/${claimHistoryId}/update`, newData); // if (response.status == 'success'){ setOpenHospitalCare(false) @@ -406,7 +406,7 @@ export default function Detail() { } else { let newData = { service_code: data.service_code, - admision_date: data.admision_date ? fDateOnly(data.admision_date) : null, + admission_date: data.admission_date ? fDateOnly(data.admission_date) : null, discharge_date: data.discharge_date ? fDateOnly(data.discharge_date) : null, organization_id: data.organization_id, practitioner_id: data.practitioner_id, @@ -415,9 +415,9 @@ export default function Detail() { sign: data.sign, secondary_diagnosis_id: data.secondary_diagnosis_id ? data.secondary_diagnosis_id.map((row) => row.value.id) : null, main_diagnosis_id: data.main_diagnosis_id, - + } - + const response:any = await axios.post(`/claims/${id}/carehistory`, newData); // if (response.status == 'success'){ @@ -428,9 +428,9 @@ export default function Detail() { ); navigate('/claims/detail/'+id); // } - + } - + reset(); } @@ -459,7 +459,7 @@ export default function Detail() { ) }) } - + function handleNewHospitalCare() { setEdit(false); setOpenHospitalCare(true); @@ -474,12 +474,12 @@ export default function Detail() { //Service const [openDialogService, setOpenDialogService] = useState(false); - const handleCloseDialogService = () => { + const handleCloseDialogService = () => { setOpenDialogService(false); } const handleConditionChangeService = (event) => { const selectedItem = event.target.value; - + if (valBenefitNames.includes(selectedItem)) { // Item is already selected, remove it setValBenefitNames(valBenefitNames.filter(item => item !== selectedItem)); @@ -488,7 +488,7 @@ export default function Detail() { setValBenefitNames([...valBenefitNames, selectedItem]); } }; - + //Data const [serviceTypeData, setServiceTypeData] = useState(null); const [benefitNameData, setBenefitNameData] = useState(null); @@ -509,9 +509,9 @@ export default function Detail() { //Hospital const [valHospital, setValHospital] = useState(''); const [valHospitalError, setValHospitalError] = useState(''); - //txt name + //txt name const [txtName, setTxtName] = useState('Add Service'); - //flag add or edit service + //flag add or edit service const [flagAddService, setFlagAddService] = useState('add'); //id claim_services const [idService, setIdService] = useState(null); @@ -532,7 +532,7 @@ export default function Detail() { setBenefitNameData(response.data.data.benefit_name), setHospitalData(response.data.data.hospital), ]); - + } catch (error) { } } @@ -548,11 +548,11 @@ export default function Detail() { setDateAd(serviceData.addmission_date); setDateDis(serviceData.discharge_date); setIdService(serviceData.id); - + setOpenDialogService(true); setTxtName('Edit Service'); setFlagAddService('edit'); - + if (serviceTypeData) { setValServiceType(serviceData.service_id); setValHospital(serviceData.hospital_id); @@ -582,7 +582,7 @@ export default function Detail() { }) .catch((error) => { enqueueSnackbar('Something Went Wrong', { variant: 'error' }); - }) + }) } const [openDialogSubmit, setOpenDialogSubmit] = useState(false); @@ -793,7 +793,7 @@ export default function Detail() { - {currentClaimHistoryCare?.map((claimHistoryCare, index) => + {currentClaimHistoryCare?.map((claimHistoryCare, index) => claimHistoryCare.status === 0 ? ( {/* Tambahkan key untuk setiap elemen dalam loop */} @@ -804,17 +804,17 @@ export default function Detail() { handleEditHospitalCare(claimHistoryCare.id)}> - Edit + Edit {setOpenDialogApproval(true); setClaimHistoryId(claimHistoryCare.id)}}> - Update Status + Update Status }/> Admission Date : - { fDate(claimHistoryCare.admision_date)} {/* Perbaikan typo di 'admission_date' */} + { fDate(claimHistoryCare.admission_date)} {/* Perbaikan typo di 'admission_date' */} Discharge Date : @@ -841,7 +841,7 @@ export default function Detail() { ) : null )} - + {/* Dialog for input and update */} @@ -873,27 +873,27 @@ export default function Detail() { Admission Date* - + Discharge Date* - + {/* Location */} Location* { + getOptionLabel={(option) => { return option.name ?? false }} isOptionEqualToValue={(option, value) =>{ return option.organization_id == value.organization_id }} - + onChange={(e, selectedOption) => { if (selectedOption) { const selectedOrganizationId = selectedOption.organization_id; @@ -901,7 +901,7 @@ export default function Detail() { } }} value={organization.find(row => row.organization_id == values.organization_id)} - + renderInput={(params) => ( )} /> - + {/* Dokter */} - + Doctor* { + getOptionLabel={(option) => { return option.name ?? false }} isOptionEqualToValue={(option, value) =>{ @@ -931,14 +931,14 @@ export default function Detail() { }} value={doctor.find(row => row.id == values.practitioner_id)} - + onChange={handleDoctorChange} renderInput={(params) => ( - @@ -975,7 +975,7 @@ export default function Detail() { options={main_diagnosis} limitTags={1} fullWidth - getOptionLabel={(option) => { + getOptionLabel={(option) => { return option.name ?? false }} isOptionEqualToValue={(option, value) =>{ @@ -1012,11 +1012,11 @@ export default function Detail() { - - + + - + {/* Dialog for approval */} @@ -1038,7 +1038,7 @@ export default function Detail() { Admission Date - { carehistory ? fDate(carehistory?.admision_date) : '-'} + { carehistory ? fDate(carehistory?.admission_date) : '-'} Discharge Date @@ -1069,8 +1069,8 @@ export default function Detail() { - - + + @@ -1083,7 +1083,7 @@ export default function Detail() { Diagnostic History - {currentClaimHistoryCare?.map((claimHistoryCare, index) => + {currentClaimHistoryCare?.map((claimHistoryCare, index) => claimHistoryCare.status === 1 ? ( {/* Tambahkan key untuk setiap elemen dalam loop */} @@ -1094,7 +1094,7 @@ export default function Detail() { Admission Date : - { fDate(claimHistoryCare.admision_date)} {/* Perbaikan typo di 'admission_date' */} + { fDate(claimHistoryCare.admission_date)} {/* Perbaikan typo di 'admission_date' */} Discharge Date : @@ -1129,7 +1129,7 @@ export default function Detail() { Diagnosis Summary - {currentClaimHistoryCare?.map((claimHistoryCare, index) => + {currentClaimHistoryCare?.map((claimHistoryCare, index) => claimHistoryCare.status === 1 ? ( {/* Tambahkan key untuk setiap elemen dalam loop */} @@ -1145,8 +1145,8 @@ export default function Detail() { Main Diagnosis : {claimHistoryCare.icd?.name} - - {/* {claimHistoryCare.comparative_diagnosis?.map((comparativeDiagnosis, i) => + + {/* {claimHistoryCare.comparative_diagnosis?.map((comparativeDiagnosis, i) => ( {i == 0 ? 'Comparative Diagnosis :' : ''} @@ -1168,7 +1168,7 @@ export default function Detail() { )) )} - + ) : null @@ -1222,7 +1222,7 @@ export default function Detail() { ): ''} - + {/* Dialog Service */} @@ -1288,11 +1288,11 @@ export default function Detail() { setValServiceType(e.target.value); setValServiceTypeError(e.target.value === '' ? 'This field is required' : ''); }} - + > {serviceTypeData?.map((item, index) => ( {item.name} - ))} + ))} {valServiceTypeError} @@ -1332,7 +1332,7 @@ export default function Detail() { label={item.description} /> - ))} + ))} {valBenefitNameError} @@ -1355,11 +1355,11 @@ export default function Detail() { setValHospital(e.target.value); setValHospitalError(e.target.value === '' ? 'This field is required' : ''); }} - + > {hospitalData?.map((item, index) => ( {item.name} - ))} + ))} {valHospitalError} @@ -1406,9 +1406,9 @@ export default function Detail() { <> {(customerData && customerData.status === 'received') ? ( <> - - - ) } - + {/* Dialog Submits */} diff --git a/frontend/dashboard/src/pages/Claims/Model/Functions.tsx b/frontend/dashboard/src/pages/Claims/Model/Functions.tsx index 57dc588c..7577c2a8 100644 --- a/frontend/dashboard/src/pages/Claims/Model/Functions.tsx +++ b/frontend/dashboard/src/pages/Claims/Model/Functions.tsx @@ -1,23 +1,58 @@ +import axios from "@/utils/axios"; +import { enqueueSnackbar } from "notistack"; import { BenefitConfigurationListType } from "./Types"; /** * Get Benefit Configuration List */ -export const getBenefitConfigurationList = async ( ): Promise => { - return [ - { - benefit_name: 'Konsultasi Dokter Umum', - amount_incurred: 75000, - amount_approved: 75000, - amount_not_approved: 0, - excess_paid: 0 - }, - { - benefit_name: 'Biaya Perawatan Setelah Rawat Inap', - amount_incurred: 925000, - amount_approved: 50000, - amount_not_approved: 425000, - excess_paid: 0 - }, - ]; +export const getBenefitConfigurationList = async ( claim_id: string ): Promise => { + const response = await axios.get(`/claims/${claim_id}/benefit-configuration`) + .then((res) =>{ + return res.data.data.benefit_list; + }) + .catch((res) => { + enqueueSnackbar("server error !", { + variant: 'error', + }); + + return []; + }); + + return response; +}; + +/** + * Edit Benefit Configuration + */ +export const editBenefitConfiguration = async ( data: BenefitConfigurationListType ): Promise => { + const response = await axios.put(`/claims/benefit-configuration/edit/${data.claim_service_benefits_id}`, { + ...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("server error !", { + variant: 'error', + }); + } + + return false; + }); + + return response; }; diff --git a/frontend/dashboard/src/pages/Claims/Model/Types.tsx b/frontend/dashboard/src/pages/Claims/Model/Types.tsx index 421b1d12..08351c5b 100644 --- a/frontend/dashboard/src/pages/Claims/Model/Types.tsx +++ b/frontend/dashboard/src/pages/Claims/Model/Types.tsx @@ -2,6 +2,7 @@ * Benefit Configuration List Type */ export type BenefitConfigurationListType = { + claim_service_benefits_id: number, benefit_name: string, amount_incurred: number, amount_approved: number, diff --git a/frontend/dashboard/src/pages/Claims/components/BenefitConfigurationDialog.tsx b/frontend/dashboard/src/pages/Claims/components/BenefitConfigurationDialog.tsx index 13a032b2..10242067 100644 --- a/frontend/dashboard/src/pages/Claims/components/BenefitConfigurationDialog.tsx +++ b/frontend/dashboard/src/pages/Claims/components/BenefitConfigurationDialog.tsx @@ -1,5 +1,8 @@ +import * as Yup from 'yup'; +import { yupResolver } from '@hookform/resolvers/yup'; import { useEffect, useState } from 'react'; import { Box, Grid } from '@mui/material'; +import { LoadingButton } from '@mui/lab'; import Button from '@mui/material/Button'; import { styled } from '@mui/material/styles'; import Dialog from '@mui/material/Dialog'; @@ -10,7 +13,8 @@ import IconButton from '@mui/material/IconButton'; import CloseIcon from '@mui/icons-material/Close'; import Typography from '@mui/material/Typography'; import { useForm } from 'react-hook-form'; -import { FormProvider, RHFTextField } from '@/components/hook-form'; +import { FormProvider } from '@/components/hook-form'; +import RHFTextFieldMoney from '@/components/hook-form/v2/RHFTextFieldMoney'; /** * Custom Style @@ -24,8 +28,9 @@ const BootstrapDialog = styled(Dialog)(({ theme }) => ({ * Utils, Types, Functions * ============================================ */ -import { BenefitConfigurationListType } from '../Model/Types'; import palette from '@/theme/palette'; +import { BenefitConfigurationListType } from '../Model/Types'; +import { editBenefitConfiguration } from '../Model/Functions'; /** * Props @@ -35,6 +40,7 @@ type Props = { data?: BenefitConfigurationListType, isOpen: boolean, handleCancleProp: () => void, + handleSuccessProp: () => void, }; export default function BenefitConfigurationDialog({ ...props }: Props) { @@ -42,6 +48,7 @@ export default function BenefitConfigurationDialog({ ...props }: Props) { // setup form // ==================================== const defaultValues: BenefitConfigurationListType = { + claim_service_benefits_id: 0, benefit_name: '', amount_incurred: 0, amount_approved: 0, @@ -49,21 +56,38 @@ export default function BenefitConfigurationDialog({ ...props }: Props) { excess_paid: 0, }; + const validationSchema = Yup.object().shape({ + amount_incurred : Yup.string().typeError('').required(''), + amount_approved : Yup.string().typeError('').required(''), + amount_not_approved : Yup.string().typeError('').required(''), + excess_paid : Yup.string().typeError('').required(''), + }); + const methods = useForm({ + resolver: yupResolver(validationSchema), defaultValues }); - const { handleSubmit, reset, setValue, formState: { isDirty, isSubmitting } } = methods; + const { handleSubmit, reset, watch, setValue, formState: { isDirty, isSubmitting, errors } } = methods; + + console.log(errors); + console.log(watch()); // Submit Form // ===================================== const submitHandler = async (data: BenefitConfigurationListType) => { - return true; + let response = await editBenefitConfiguration(data); + + if (response == true) { + props.handleSuccessProp() + props.handleCancleProp() + } } // Set Value Form // ===================================== useEffect(() => { + setValue('claim_service_benefits_id', props.data?.claim_service_benefits_id) setValue('amount_incurred', props.data?.amount_incurred) setValue('amount_approved', props.data?.amount_approved) setValue('amount_not_approved', props.data?.amount_not_approved) @@ -71,124 +95,124 @@ export default function BenefitConfigurationDialog({ ...props }: Props) { }, [props.data]) return ( - - - - - Client Benefit Configuration - + + + + + Client Benefit Configuration + - theme.palette.grey[0]}} - > - - - + theme.palette.grey[0]}} + > + + + - - - - - {/* Benefit Name */} - - - {props.data?.benefit_name} - - + + + + + {/* Benefit Name */} + + + {props.data?.benefit_name} + + - - - - - - - Amount Incurred* - - - - - + + + + + + + Amount Incurred* + + + + + - - - - - Amount Approved* - - - - - + + + + + Amount Approved* + + + + + - - - - - Amount Not Approved* - - - - - + + + + + Amount Not Approved* + + + + + - - - - - Excess Paid* - - - - - + + + + + Excess Paid* + + + + - + - + + - - - - - - + + + + Save Changes + + + + ); } diff --git a/frontend/dashboard/src/pages/Claims/components/BenefitConfigurationList.tsx b/frontend/dashboard/src/pages/Claims/components/BenefitConfigurationList.tsx index ba741ece..bb824758 100644 --- a/frontend/dashboard/src/pages/Claims/components/BenefitConfigurationList.tsx +++ b/frontend/dashboard/src/pages/Claims/components/BenefitConfigurationList.tsx @@ -3,6 +3,7 @@ * ============================================ */ import { useEffect, useState } from 'react'; +import { useParams } from 'react-router'; import { Box, Typography, Grid, MenuItem } from '@mui/material'; /** @@ -26,8 +27,11 @@ import { BenefitConfigurationListType } from '../Model/Types'; import { getBenefitConfigurationList } from '../Model/Functions'; import palette from '@/theme/palette'; import BenefitConfigurationDialog from './BenefitConfigurationDialog'; +import { fNumber } from '@/utils/formatNumber'; export default function BenefitConfigurationList() { + const { id: claim_id } = useParams(); + // State // -------------------- const [BenefitConfigurationList, setBenefitConfigurationList] = useState(); @@ -43,7 +47,7 @@ export default function BenefitConfigurationList() { // Load Data // ------------------- const loadDataTableData = async () => { - const response = await getBenefitConfigurationList(); + const response = await getBenefitConfigurationList(claim_id??''); setBenefitConfigurationList(response); } @@ -94,7 +98,7 @@ export default function BenefitConfigurationList() { - {row.amount_incurred} + {fNumber(row.amount_incurred)} @@ -110,7 +114,7 @@ export default function BenefitConfigurationList() { - {row.amount_approved} + {fNumber(row.amount_approved)} @@ -126,7 +130,7 @@ export default function BenefitConfigurationList() { - {row.amount_not_approved} + {fNumber(row.amount_not_approved)} @@ -142,7 +146,7 @@ export default function BenefitConfigurationList() { - {row.excess_paid} + {fNumber(row.excess_paid)} @@ -158,7 +162,7 @@ export default function BenefitConfigurationList() { } {/* Dialog */} - setIsDialogOpen(false)} /> + setIsDialogOpen(false)} handleSuccessProp={() => loadDataTableData()} /> ); }