diff --git a/Modules/Internal/Http/Controllers/Api/RequestLogBenefitController.php b/Modules/Internal/Http/Controllers/Api/RequestLogBenefitController.php index e00302e5..2463e9b4 100755 --- a/Modules/Internal/Http/Controllers/Api/RequestLogBenefitController.php +++ b/Modules/Internal/Http/Controllers/Api/RequestLogBenefitController.php @@ -72,7 +72,7 @@ class RequestLogBenefitController extends Controller 'amount_approved' => $value['amount_approved'], 'amount_not_approved' => $value['amount_not_approved'], 'excess_paid' => $value['excess_paid'], - 'keterangan' => $value['keterangan'], + 'keterangan' => $value['keterangan'] ?? '', 'created_by' => auth()->user()->id, // 'reason' => $value['reason'] ? $value['reason'] : null , diff --git a/Modules/Internal/Routes/api.php b/Modules/Internal/Routes/api.php index 057566ee..e0a613a0 100755 --- a/Modules/Internal/Routes/api.php +++ b/Modules/Internal/Routes/api.php @@ -96,6 +96,9 @@ Route::prefix('internal')->group(function () { Route::get('signa', [AutocompleteController::class, 'signaList']); Route::post('signa-add', [AutocompleteController::class, 'signaAdd']); + Route::get('service-member/{id}', [AutocompleteController::class, 'serviceCode']); + Route::get('specialis', [AutocompleteController::class, 'specialisList']); + Route::middleware('auth:sanctum')->group(function () { diff --git a/Modules/Internal/Transformers/RequestLogShowResource.php b/Modules/Internal/Transformers/RequestLogShowResource.php index f5a8390b..0627386a 100755 --- a/Modules/Internal/Transformers/RequestLogShowResource.php +++ b/Modules/Internal/Transformers/RequestLogShowResource.php @@ -145,6 +145,7 @@ class RequestLogShowResource extends JsonResource 'dppj' => $dppj, 'code_claim' => $claimCode, 'member_id' => $requestLog['member']['member_id'], + 'id_member' => $requestLog['member']['id'], 'type_of_member' => $requestLog['type_of_member'], 'corporate_id' => $corporateId, 'policy_number' =>$policyNumber->code ? $policyNumber->code : '-', @@ -177,8 +178,8 @@ class RequestLogShowResource extends JsonResource 'keterangan' => $requestLog['keterangan'], 'hak_kamar_pasien' => $requestLog['hak_kamar_pasien'], 'penempatan_kamar' => $requestLog['penempatan_kamar'], - 'nominal' => $requestLog['nominal'], - 'status_approval' => $requestLog['status_approval'], + 'nominal' => $requestLog['nominal'] ?? 0, + 'status_approval' => $requestLog['status_approval'] ?? '', 'catatan' => $requestLog['catatan'], 'reason' => $requestLog['reason'], 'diagnosis' => $icd, diff --git a/Modules/Primaya/Http/Controllers/Api/MasterController.php b/Modules/Primaya/Http/Controllers/Api/MasterController.php new file mode 100644 index 00000000..62656569 --- /dev/null +++ b/Modules/Primaya/Http/Controllers/Api/MasterController.php @@ -0,0 +1,63 @@ +get(); + + return response()->json([ + 'status' => 'success', + 'data' => $data + ]); + } + + public function benefits() + { + $corporateId = auth('corporate-api')->user()->corporate_id; + + $data = Benefit::whereHas('corporateBenefits', function ($q) use ($corporateId) { + $q->where('corporate_id', $corporateId); + }) + ->select('id', 'description') + ->get(); + + return response()->json([ + 'status' => 'success', + 'data' => $data + ]); + } + + public function organizations() + { + $data = Organization::select('id', 'name', 'code')->get(); + + return response()->json([ + 'status' => 'success', + 'data' => $data + ]); + } +} diff --git a/Modules/Primaya/Http/Controllers/Api/RequestLogController.php b/Modules/Primaya/Http/Controllers/Api/RequestLogController.php new file mode 100644 index 00000000..81e090e7 --- /dev/null +++ b/Modules/Primaya/Http/Controllers/Api/RequestLogController.php @@ -0,0 +1,249 @@ + $request->member_id, + 'service_code' => $request->service_code, + 'organization_id' => $request->organization_id, + 'organization_name' => !empty($request->organization_name) ? $request->organization_name : null, + 'address_provider' => !empty($request->address_provider) ? $request->address_provider : null, + 'submission_date' => $request->submission_date, + 'discharge_date' => $request->discharge_date, + 'corporate_id_partner' => !empty($request->corporate_id_partner) ? $request->corporate_id_partner : [], + 'specialities_id' => $request->specialities_id, + 'dppj' => $request->dppj + ]; + $validator = Validator::make($request->all(), [ + 'member_id' => 'required', + 'service_code' => 'required', + 'submission_date' => 'required', + 'discharge_date' => 'required', + 'specialities_id' => 'required', + 'dppj' => 'required', + ], [ + 'member_id.required' => trans('Validation.required',['attribute' => 'Member ID']), + 'service_code.required' => trans('Validation.required',['attribute' => 'Service Code']), + 'submission_date.required' => trans('Validation.required',['attribute' => 'Submission Date']), + 'discharge_date.required' => trans('Validation.required',['attribute' => 'Discharge Date']), + 'specialities_id.required' => trans('Validation.required',['attribute' => 'Specialities']), + 'dppj.required' => trans('Validation.required',['attribute' => 'DPJP']), + ]); + if(!empty($request->organization_id)) + { + $validator = Validator::make($request->all(), [ + 'organization_id' => 'required', + 'member_id' => 'required', + 'service_code' => 'required', + 'submission_date' => 'required', + 'discharge_date' => 'required', + 'specialities_id' => 'required', + 'dppj' => 'required', + ], [ + 'organization_id.required' => trans('Validation.required',['attribute' => 'Provider ID']), + 'member_id.required' => trans('Validation.required',['attribute' => 'Member ID']), + 'service_code.required' => trans('Validation.required',['attribute' => 'Service Code']), + 'submission_date.required' => trans('Validation.required',['attribute' => 'Submission Date']), + 'discharge_date.required' => trans('Validation.required',['attribute' => 'Discharge Date']), + 'specialities_id.required' => trans('Validation.required',['attribute' => 'Specialities']), + 'dppj.required' => trans('Validation.required',['attribute' => 'DPJP']), + ]); + } + if ($validator->fails()) + { + return ApiResponse::apiResponse('Bad Request', $data, $validator->errors(), 400); + } + else + { + //insert data to organization + try { + if (!empty($request->organization_name) && !empty($request->address_provider)) + { + // Memulai transaksi + DB::beginTransaction(); + + // Membuat singkatan dari nama rumah sakit + $singkatan = ""; + $words = explode(' ', $request->organization_name); + + foreach ($words as $word) { + $singkatan .= strtoupper(substr($word, 0, 2)); + } + + // Membuat kode organisasi + $kodeOrganisasi = "ORG000" . $singkatan; + + // Insert data ke tabel organizations + $organization_id = DB::table('organizations') + ->insertGetId([ + 'name' => $request->organization_name, + 'code' => $kodeOrganisasi, + 'type' => 'hospital', + 'corporate_id_partner' => $request->corporate_id_partner ? implode(',', $request->corporate_id_partner) : null, + 'created_at' => now(), + 'created_by' => auth()->user()->id + ]); + + // Insert data ke tabel addresses + $address_id = DB::table('addresses') + ->insertGetId([ + 'text'=> $request->address_provider, + 'addressable_type' => 'App\Models\Organization', + 'addressable_id' => $organization_id, + 'type' => 'hospital', + 'created_at' => now(), + 'created_by' => auth()->user()->id + ]); + + // Update main_address_id di tabel organizations + DB::table('organizations') + ->where('organizations.id', '=', $organization_id) + ->update(['main_address_id' => $address_id]); + + // Commit transaksi + DB::commit(); + $request->merge(['organization_id' => $organization_id]); + } + + try { + + DB::beginTransaction(); + + $requestLogControllerInstance = new PrimeCenterRequestLog(); + $code = $requestLogControllerInstance->getNextCode($request); + + $member = Member::find($request->member_id); + + $requestLogData = [ + 'code' => $code, + 'member_id' => $request->member_id, + 'submission_date' => $request->submission_date ?? now(), + 'discharge_date' => $request->discharge_date ?? now(), + 'status' => 'approved', + 'status_final_log' => 'approved', + 'final_log' => 1, + 'payment_type' => 'cashless', + 'service_code' => $request->service_code, + 'policy_id' => $member->currentPolicy->id ?? null, + 'organization_id' => $request->organization_id ?? 0, + 'source' => $request->source, + 'specialities_id' => $request->specialities_id, + 'dppj' => $request->dppj + ]; + + // SIMPAN LOG + $requestLog = RequestLog::create($requestLogData); + + /* + =============================== + INSERT BENEFIT DI SINI + =============================== + */ + + if (!empty($request->benefits)) { + + $benefitData = []; + + foreach ($request->benefits as $benefit) { + $benefitData[] = [ + 'request_log_id' => $requestLog->id, + 'benefit_id' => $benefit['benefit_id'], + 'amount_incurred' => $benefit['amount_incurred'] ?? 0, + 'amount_approved' => $benefit['amount_approved'] ?? 0, + 'amount_not_approved' => $benefit['amount_not_approved'] ?? 0, + 'excess_paid' => $benefit['excess_paid'] ?? 0, + 'keterangan' => $benefit['keterangan'] ?? '', + ]; + } + + $insertBenefit = $this->insertBenefit($benefitData); + + if (!$insertBenefit) { + throw new \Exception('Insert Benefit Gagal'); + } + } + + DB::commit(); + + return ApiResponse::apiResponse( + 'Success Create Log', + $requestLog, + 'Berhasil create LOG dan Benefit', + 200 + ); + + } catch (\Exception $e) { + + DB::rollBack(); + + return ApiResponse::apiResponse( + 'Server Error Create Log', + $data, + $e->getMessage(), + 500 + ); + } + } catch (\Exception $e) { + // Rollback transaksi jika terjadi kesalahan + DB::rollBack(); + + // Handle error, bisa di-log atau dikembalikan sebagai response + return ApiResponse::apiResponse('Server Error 3', $data, $e->getMessage(), 500); + } + } + } + + public function insertBenefit($benefitData) + { + if (count($benefitData) > 0) { + + foreach ($benefitData as $value) { + + $data = [ + 'request_log_id' => $value['request_log_id'], + 'benefit_id' => $value['benefit_id'], + 'amount_incurred' => $value['amount_incurred'], + 'amount_approved' => $value['amount_approved'], + 'amount_not_approved' => $value['amount_not_approved'], + 'excess_paid' => $value['excess_paid'], + 'keterangan' => $value['keterangan'] ?? '', + 'created_by' => auth()->user()->id, + ]; + + RequestLogBenefit::create($data); + } + + return true; + } + + return true; + } +} diff --git a/Modules/Primaya/Routes/api.php b/Modules/Primaya/Routes/api.php index 88f96d85..c12bd935 100644 --- a/Modules/Primaya/Routes/api.php +++ b/Modules/Primaya/Routes/api.php @@ -2,7 +2,9 @@ use Illuminate\Http\Request; use Modules\Primaya\Http\Controllers\Api\AuthController; +use Modules\Primaya\Http\Controllers\Api\MasterController; use Modules\Primaya\Http\Controllers\Api\MemberController; +use Modules\Primaya\Http\Controllers\Api\RequestLogController; use Modules\Primaya\Http\Middleware\Authentication; use Modules\Primaya\Http\Middleware\Authorization; @@ -32,6 +34,19 @@ Route::prefix('v1')->group(function () { Route::post('search-member', [MemberController::class, 'search']); }); + // Request LOG + Route::controller(RequestLogController::class)->group(function () { + Route::post('request-log', 'requestLog'); + }); + + Route::prefix('master')->group(function () { + + Route::get('specialities', [MasterController::class, 'specialities']); + Route::get('benefits', [MasterController::class, 'benefits']); + Route::get('organizations', [MasterController::class, 'organizations']); + + }); + }); }); diff --git a/app/Models/Benefit.php b/app/Models/Benefit.php index 5c0498af..ef4e4d0d 100644 --- a/app/Models/Benefit.php +++ b/app/Models/Benefit.php @@ -57,4 +57,8 @@ class Benefit extends Model // TODO corporate_benefits pivot ]); } + public function corporateBenefits() + { + return $this->hasMany(CorporateBenefit::class, 'benefit_id'); + } } diff --git a/frontend/dashboard/src/pages/CustomerService/FinalLog/Detail.tsx b/frontend/dashboard/src/pages/CustomerService/FinalLog/Detail.tsx index 7f5f5582..f6af3b8b 100644 --- a/frontend/dashboard/src/pages/CustomerService/FinalLog/Detail.tsx +++ b/frontend/dashboard/src/pages/CustomerService/FinalLog/Detail.tsx @@ -85,7 +85,67 @@ import { format } from 'date-fns'; // ---------------------------------------------------------------------- export default function Detail() { - //dari hospital portal + + + + const location = useLocation(); + const queryParams = new URLSearchParams(location.search); + + const navigate = useNavigate(); + const { themeStretch } = useSettings(); + const [requestLog, setRequestLog] = useState(); + const [isReversal, setIsReversal] = useState(false); + const [submitLoading, setSubmitLoading] = useState(false); + + const defaultValues: any = {nominal : 0}; + const validationSchema = Yup.object().shape({nominal: Yup.number().typeError('Nominal harus berupa angka').required('Nominal harus diisi')}) + + const methods = useForm({ + resolver: yupResolver(validationSchema), + defaultValues + }); + + const { handleSubmit, reset, watch, setValue, formState: { isDirty, isSubmitting, errors } } = methods; + + const onSubmit = async (data: any) => { + setSubmitLoading(true); + const formData = makeFormData({ + request_logs_id: id, + approval_files: fileApprovals, + nominal: data.nominal, + }); + axios + .post(`/customer-service/request/${id}/approval_files`, formData) + .then((response) => { + enqueueSnackbar('Berhasil membuat data', { variant: 'success' }); + + window.location.reload() + }) + .catch(({ response }) => { + enqueueSnackbar('Something Went Wrong', { variant: 'error' }); + }) + .then(() => { + setSubmitLoading(false); + }); + } + useEffect(() => { + if (!requestLog?.id_member) return + axios.get('service-member/'+ (requestLog?.id_member ?? null)) + .then((response) => { + setServiceOptions(response.data); + }).catch((error) => { + console.error('Error fetching ICD options:', error); + }); + + axios.get('specialis') + .then((response) => { + setSpecialisOptions(response.data); + }).catch((error) => { + console.error('Error fetching ICD options:', error); + }); + + }, [requestLog?.id_member]); + //dari hospital portal const [dischargeDate, setDischargeDate] = useState(format(new Date(), "yyyy MMM d HH:mm:ss")); const [serviceOptions, setServiceOptions] = useState([ { value: '-', label: '-' } @@ -93,25 +153,31 @@ export default function Detail() { const [specialisOptions, setSpecialisOptions] = useState([ { value: '-', label: '-' } ]); -useEffect(() => { - axios.get('service-member/'+1) - .then((response) => { - setServiceOptions(response.data); - }).catch((error) => { - console.error('Error fetching ICD options:', error); - }); - axios.get('specialis') - .then((response) => { - setSpecialisOptions(response.data); - }).catch((error) => { - console.error('Error fetching ICD options:', error); - }); + const [serviceCode, setServiceCode] = useState('') + const [idSpecialities, setIdSpecialities] = useState(null) + const [inputDppj, setInputDppj] = useState('') + useEffect(() => { + if (!requestLog) return + setServiceCode(requestLog.service_code ?? '') + setIdSpecialities(requestLog.specialitiesID ?? null) + setInputDppj(requestLog.dppj ?? '') + }, [requestLog]) + const selectedService = useMemo( + () => + serviceOptions.find( + (o) => String(o.value) === String(serviceCode) + ) || null, + [serviceOptions, serviceCode] + ) - }, []); -const [serviceCode, setServiceCode] = useState(""); -const [idSpecialities, setIdSpecialities] = useState(""); -const [inputDppj, setInputDppj] = useState(""); + const selectedSpecialis = useMemo( + () => + specialisOptions.find( + (o) => Number(o.value) === Number(idSpecialities) + ) || null, + [specialisOptions, idSpecialities] + ) function submitRequestFinalLog() { if(dischargeDate == '') { @@ -156,49 +222,6 @@ function submitRequestFinalLog() { }); } //end dari hospital portal - - - const location = useLocation(); - const queryParams = new URLSearchParams(location.search); - - const navigate = useNavigate(); - const { themeStretch } = useSettings(); - const [requestLog, setRequestLog] = useState(); - const [isReversal, setIsReversal] = useState(false); - const [submitLoading, setSubmitLoading] = useState(false); - - const defaultValues: any = {nominal : 0}; - const validationSchema = Yup.object().shape({nominal: Yup.number().typeError('Nominal harus berupa angka').required('Nominal harus diisi')}) - - const methods = useForm({ - resolver: yupResolver(validationSchema), - defaultValues - }); - - const { handleSubmit, reset, watch, setValue, formState: { isDirty, isSubmitting, errors } } = methods; - - const onSubmit = async (data: any) => { - setSubmitLoading(true); - const formData = makeFormData({ - request_logs_id: id, - approval_files: fileApprovals, - nominal: data.nominal, - }); - axios - .post(`/customer-service/request/${id}/approval_files`, formData) - .then((response) => { - enqueueSnackbar('Berhasil membuat data', { variant: 'success' }); - - window.location.reload() - }) - .catch(({ response }) => { - enqueueSnackbar('Something Went Wrong', { variant: 'error' }); - }) - .then(() => { - setSubmitLoading(false); - }); - } - const updateApproval = async () => { setSubmitLoading(true); axios @@ -530,17 +553,17 @@ function submitRequestFinalLog() { Tipe Service option.label || ""} - value={serviceOptions.find((opt) => opt.value == serviceCode) || null} - onChange={(event, newValue) => { - setServiceCode(newValue?.value || ""); - }} + value={selectedService} + getOptionLabel={(o) => o.label} + isOptionEqualToValue={(o, v) => o.value === v.value} + onChange={(_, v) => setServiceCode(v?.value ?? '')} renderInput={(params) => ( - + )} - /> + /> + + diff --git a/frontend/hospital-portal/src/sections/dashboard/DetailRequestFinalLog.tsx b/frontend/hospital-portal/src/sections/dashboard/DetailRequestFinalLog.tsx index 5075a24d..9647505f 100644 --- a/frontend/hospital-portal/src/sections/dashboard/DetailRequestFinalLog.tsx +++ b/frontend/hospital-portal/src/sections/dashboard/DetailRequestFinalLog.tsx @@ -296,10 +296,10 @@ export default function DetailRequestFinalLog() { >([]) useEffect(() => { - if (!requestLog?.id && !Log_id) return + if (!requestLog?.id_member) return axios - .get('service-member/' + (requestLog?.id ?? Log_id)) + .get('service-member/' + (requestLog?.id_member ?? null)) .then((res) => setServiceOptions(res.data)) .catch(console.error) @@ -307,7 +307,7 @@ export default function DetailRequestFinalLog() { .get('specialis') .then((res) => setSpecialisOptions(res.data)) .catch(console.error) - }, [requestLog?.id, Log_id]) + }, [requestLog?.id_member]) const [serviceCode, setServiceCode] = useState('')