diff --git a/Modules/Primaya/Http/Controllers/Api/MemberController.php b/Modules/Primaya/Http/Controllers/Api/MemberController.php index 2ea07dcc..6cef0400 100644 --- a/Modules/Primaya/Http/Controllers/Api/MemberController.php +++ b/Modules/Primaya/Http/Controllers/Api/MemberController.php @@ -3,7 +3,10 @@ namespace Modules\Primaya\Http\Controllers\Api; use App\Helpers\Helper; +use App\Models\CorporateBenefit; use App\Models\Member; +use App\Models\MemberPlan; +use App\Models\Plan; use Illuminate\Contracts\Support\Renderable; use Illuminate\Http\Request; use Illuminate\Routing\Controller; @@ -38,6 +41,7 @@ class MemberController extends Controller { $members = DB::table('members') ->leftJoin('member_policies', 'member_policies.member_id','=', 'members.member_id') + ->leftJoin('corporate_employees', 'corporate_employees.member_id','=', 'members.member_id') ->leftJoin('persons', 'persons.id', '=', 'members.person_id') ->where('members.member_id', '=', $request->no_polis) ->where('members.birth_date', '=', $request->birth_date) @@ -59,49 +63,54 @@ class MemberController extends Controller { $res_data['members'] = $members; + // $services = DB::table('member_plans') + // ->leftJoin('plans', 'plans.id', '=', 'member_plans.plan_id') + // ->leftJoin('services', 'services.code', '=', 'plans.service_code') + // ->where('member_plans.member_id', $members->id) + // ->whereNull('member_plans.deleted_at') + // ->select('plans.service_code', 'services.name') + // ->get(); + // $res_data['services'] = $services; + $benefits = DB::table('member_plans') ->leftJoin('corporate_benefits','corporate_benefits.plan_id', '=', 'member_plans.plan_id') ->leftJoin('benefits', 'benefits.id', '=', 'corporate_benefits.benefit_id') ->leftJoin('plans', 'plans.id', '=', 'member_plans.plan_id') ->leftJoin('services', 'services.code', '=', 'plans.service_code') ->where('member_plans.member_id', '=', $members->id) + ->where('plans.service_code','=', 'OP') ->select( + 'benefits.id', 'benefits.description', 'benefits.code', 'corporate_benefits.corporate_id', - 'plans.service_code' + 'plans.service_code', + 'corporate_benefits.cashless_percentage', + 'corporate_benefits.reimbursement_percentage', ) ->get(); $res_data['benefits'] = $benefits; - $services = DB::table('member_plans') - ->leftJoin('plans', 'plans.id', '=', 'member_plans.plan_id') - ->leftJoin('services', 'services.code', '=', 'plans.service_code') - ->where('member_plans.member_id', $members->id) - ->whereNull('member_plans.deleted_at') - ->select('plans.service_code', 'services.name') - ->get(); - $res_data['services'] = $services; - // Group Services - $groupServices = []; - foreach ($res_data['benefits'] as $benefit) { - $serviceCode = $benefit->service_code; - $groupServices[$serviceCode][] = [ - 'description' => $benefit->description, - 'code' => $benefit->code, - ]; - } + // $groupServices = []; + // foreach ($res_data['benefits'] as $benefit) { + // $serviceCode = $benefit->service_code; + // $groupServices[$serviceCode][] = [ + // 'description' => $benefit->description, + // 'code' => $benefit->code, + // ]; + // } - $res_data['groupServices'] = $groupServices; + // $res_data['groupServices'] = $groupServices; - $res_data['type'] = $request->type; + // $res_data['type'] = $request->type; // Provider $providers = DB::table('organizations') ->where('organizations.type', '=', 'hospital') + ->where('organizations.code', '=', 'LMS') ->where('organizations.corporate_id_partner', '!=', 8) - ->orWhere('organizations.corporate_id_partner', NULL) + // ->orWhere('organizations.corporate_id_partner', NULL) ->where('status', '=', 'active') ->orderBy('organizations.name','asc') ->select( @@ -113,57 +122,104 @@ class MemberController extends Controller $res_data['providers'] = $providers; //company - $companies = DB::table('corporates') - ->where('corporates.active', '=', 1) + // $companies = DB::table('corporates') + // ->where('corporates.active', '=', 1) + // ->select( + // 'corporates.id', + // 'corporates.name' + // ) + // ->get(); + + // $res_data['companies'] = $companies; + + $corporateEmployee = DB::table('corporate_employees') + ->leftJoin('corporates', 'corporates.id', '=', 'corporate_employees.corporate_id') + ->leftJoin('corporate_policies', 'corporate_policies.corporate_id', '=', 'corporates.id') + // ->where('corporate_employees.status', 'ACTIVE') + ->where('corporates.active', 1) + ->where('corporate_policies.active', 1) + ->where('corporate_employees.member_id', $members->id) ->select( - 'corporates.id', - 'corporates.name' + 'corporate_policies.total_premi', + 'corporate_employees.corporate_id' ) - ->get(); - - $res_data['companies'] = $companies; - - //company - $companies = DB::table('corporates') - ->where('corporates.active', '=', 1) - ->select( - 'corporates.id', - 'corporates.name' - ) - ->get(); - - $res_data['companies'] = $companies; - - $corporateEmployeePremi = DB::table('corporate_employees') - ->leftJoin('corporates', 'corporates.id', '=', 'corporate_employees.corporate_id') - ->leftJoin('corporate_policies', 'corporate_policies.corporate_id', '=', 'corporates.id') - ->where('corporate_employees.status', 'ACTIVE') - ->where('corporates.active', 1) - ->where('corporate_policies.active', 1) - ->where('corporate_employees.member_id', $members->id) - ->value('corporate_policies.total_premi'); - - $res_data['total_premi'] = $corporateEmployeePremi ?? 0; + ->first(); + $res_data['total_premi'] = $corporateEmployee->total_premi ?? 0; $limitRules = DB::table('member_plans') ->leftJoin('plans', 'plans.id', '=', 'member_plans.plan_id') ->where('member_plans.member_id', $members->id) ->where('member_plans.status', 'active') ->where('plans.active', 1) - ->value('plans.limit_rules'); - + ->value('plans.limit_rules') ?? 0; $res_data['limit_rules'] = $limitRules ?? 0; - // specialities - $specialities = DB::table('specialities') - ->select( - 'specialities.id', - 'specialities.name' - ) - ->orderBy('specialities.name','asc') - ->get(); + $planMember = MemberPlan::where('member_id', $members->id)->get('plan_id'); - $res_data['specialities'] = $specialities; + $planId = Plan::whereIn('id', $planMember)->where('service_code', 'OP')->first(); + $benefit = CorporateBenefit::with(['benefit', 'plan'])->where('plan_id', $planId->id)->get()->toArray(); + $benefitData = []; + if (count($benefit)){ + foreach($benefit as $data){ + $data['benefit']['plan_id'] = $data['plan_id']; + $data['benefit']['limit_amount'] = $data['limit_amount']; + $data['benefit']['family_plan'] = $planId->family_plan; + $data['benefit']['max_frequency_period'] = $data['max_frequency_period']; + $data['benefit']['limit_amount_plan'] = $data['plan']['limit_rules']; + $data['benefit']['family_plan_plans'] = $data['plan']['family_plan']; + array_push($benefitData, $data['benefit']); + } + } + $memberUsage = Helper::getUsageMember($corporateEmployee->corporate_id, $members->id, $benefitData);; + + $res_data['used_limit'] = json_decode($memberUsage); + + $usedLimit = json_decode($memberUsage, true); + + $totalUsed = 0; + + if (is_array($usedLimit)) { + foreach ($usedLimit as $value) { + $totalUsed += (int) $value; + } + } + + $limitRules = (int) $limitRules; + + // hitung sisa + $remainingLimit = $limitRules - $totalUsed; + + // biar gak minus + if ($remainingLimit < 0) { + $remainingLimit = 0; + } + + // set ke response + $res_data['remaining_limit'] = $remainingLimit; + $res_data['total_used_limit'] = $totalUsed; + + // company + $companies = DB::table('corporates') + ->where('corporates.active', 1) + ->where('corporates.id', $corporateEmployee->corporate_id ?? null) + ->select( + 'corporates.id', + 'corporates.name' + ) + ->get(); + + $res_data['companies'] = $companies; + + // specialities + // $specialities = DB::table('specialities') + // ->select( + // 'specialities.id', + // 'specialities.name' + // ) + // ->orderBy('specialities.name','asc') + // ->get(); + + // $res_data['specialities'] = $specialities; return ApiResponse::apiResponse("Success", $res_data, trans('Message.success'), 200); @@ -175,4 +231,134 @@ class MemberController extends Controller } } + + public function calculateBenefit(Request $request) + { + $request->validate([ + 'member_id' => 'required|integer', + 'benefit_id' => 'required|integer', + 'biaya' => 'required|numeric|min:0' + ]); + + $memberId = $request->member_id; + $benefitId = $request->benefit_id; + $biaya = $request->biaya; + + // =============================== + // Ambil member + // =============================== + $member = DB::table('members')->where('id', $memberId)->first(); + + if (!$member) { + return ApiResponse::apiResponse("Data Not Found", [], "Member not found", 404); + } + + // =============================== + // Ambil corporate employee + // =============================== + $corporateEmployee = DB::table('corporate_employees') + ->where('member_id', $memberId) + ->first(); + + if (!$corporateEmployee) { + return ApiResponse::apiResponse("Data Not Found", [], "Corporate not found", 404); + } + + // =============================== + // Ambil Plan OP + // =============================== + $planMember = MemberPlan::where('member_id', $memberId)->pluck('plan_id'); + + $plan = Plan::whereIn('id', $planMember) + ->where('service_code', 'OP') + ->first(); + + if (!$plan) { + return ApiResponse::apiResponse("Data Not Found", [], "Plan OP not found", 404); + } + + // =============================== + // Ambil Benefit + // =============================== + $corporateBenefit = CorporateBenefit::where('plan_id', $plan->id) + ->where('benefit_id', $benefitId) + ->first(); + + if (!$corporateBenefit) { + return ApiResponse::apiResponse("Data Not Found", [], "Benefit not found", 404); + } + + // =============================== + // Hitung Used Limit (PAKAI HELPER) + // =============================== + $allBenefits = CorporateBenefit::with(['benefit', 'plan']) + ->where('plan_id', $plan->id) + ->get(); + + $benefitData = []; + + foreach ($allBenefits as $data) { + $benefitData[] = [ + 'id' => $data->benefit_id, + 'limit_amount' => $data->limit_amount ?? 0, + 'limit_amount_plan' => $plan->limit_rules ?? 0, + 'family_plan' => $plan->family_plan ?? 'S', + 'max_frequency_period' => $data->max_frequency_period ?? 0 + ]; + } + + $memberUsage = Helper::getUsageMember( + $corporateEmployee->corporate_id, + $memberId, + $benefitData + ); + + $usedLimitArray = json_decode($memberUsage, true); + + // total semua benefit (INI YANG BENAR) + $totalUsedLimit = is_array($usedLimitArray) ? array_sum($usedLimitArray) : 0; + + // tetap ambil per benefit (kalau mau ditampilkan) + $usedLimit = $totalUsedLimit; + + // =============================== + // Limit Logic + // =============================== + $limitPlan = $plan->limit_rules ?? 0; + $sisaLimit = $limitPlan - $totalUsedLimit; + + if ($sisaLimit < 0) { + $sisaLimit = 0; + } + + if ($sisaLimit < 0) { + $sisaLimit = 0; + } + + // =============================== + // Percentage Logic + // =============================== + $cashlessPercentage = $corporateBenefit->cashless_percentage ?? 0; + + $ditanggungPercentage = ($biaya * $cashlessPercentage) / 100; + + $ditanggungFinal = min($ditanggungPercentage, $sisaLimit); + + $sisaBayar = $biaya - $ditanggungFinal; + + // =============================== + // Response + // =============================== + return ApiResponse::apiResponse("Success", [ + 'member_id' => $memberId, + 'benefit_id' => $benefitId, + 'biaya' => $biaya, + 'cashless_percentage' => $cashlessPercentage, + 'limit_plan' => $limitPlan, + 'used_limit' => $usedLimit, + 'sisa_limit' => $sisaLimit, + 'ditanggung_asuransi' => $ditanggungFinal, + 'sisa_bayar_member' => $sisaBayar + ], "Calculation successful", 200); + } } diff --git a/Modules/Primaya/Http/Controllers/Api/RequestLogController.php b/Modules/Primaya/Http/Controllers/Api/RequestLogController.php index 81e090e7..fd66f551 100644 --- a/Modules/Primaya/Http/Controllers/Api/RequestLogController.php +++ b/Modules/Primaya/Http/Controllers/Api/RequestLogController.php @@ -109,7 +109,7 @@ class RequestLogController extends Controller 'type' => 'hospital', 'corporate_id_partner' => $request->corporate_id_partner ? implode(',', $request->corporate_id_partner) : null, 'created_at' => now(), - 'created_by' => auth()->user()->id + // 'created_by' => auth()->user()->id ]); // Insert data ke tabel addresses @@ -120,7 +120,7 @@ class RequestLogController extends Controller 'addressable_id' => $organization_id, 'type' => 'hospital', 'created_at' => now(), - 'created_by' => auth()->user()->id + // 'created_by' => auth()->user()->id ]); // Update main_address_id di tabel organizations @@ -235,7 +235,7 @@ class RequestLogController extends Controller 'amount_not_approved' => $value['amount_not_approved'], 'excess_paid' => $value['excess_paid'], 'keterangan' => $value['keterangan'] ?? '', - 'created_by' => auth()->user()->id, + // 'created_by' => auth()->user()->id, ]; RequestLogBenefit::create($data); @@ -246,4 +246,160 @@ class RequestLogController extends Controller return true; } + + public function requestLogAwal(Request $request) + { + $data = [ + 'member_id' => $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, + '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', + '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']), + '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', + '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']), + '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(), + 'status' => 'requested', + '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); + + 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); + } + } + } } diff --git a/Modules/Primaya/Routes/api.php b/Modules/Primaya/Routes/api.php index a90a9e7b..b3cda2d3 100644 --- a/Modules/Primaya/Routes/api.php +++ b/Modules/Primaya/Routes/api.php @@ -37,9 +37,14 @@ Route::prefix('v1')->group(function () { // Request LOG Route::controller(RequestLogController::class)->group(function () { + //Final Route::post('request-log', 'requestLog'); + //Awal + Route::post('request-log-awal', 'requestLogAwal'); }); + Route::post('calculate-benefit', [MemberController::class, 'calculateBenefit']); + Route::prefix('master')->group(function () { Route::get('specialities', [MasterController::class, 'specialities']); diff --git a/app/Services/AuthService.php b/app/Services/AuthService.php index b72e7836..9dd5fe3a 100644 --- a/app/Services/AuthService.php +++ b/app/Services/AuthService.php @@ -20,7 +20,7 @@ class AuthService exec($cmd); } } - + /** * Issue JWT access token for the given client */ @@ -90,23 +90,30 @@ class AuthService { try { $parts = explode('.', $token); + + if (count($parts) !== 3) { return false; } - $payload = json_decode(base64_decode(strtr($parts[1], '-_', '+/'))); + // $payload = json_decode(base64_decode(strtr($parts[1], '-_', '+/'))); + $payloadRaw = $parts[1]; + $payloadRaw = strtr($payloadRaw, '-_', '+/'); + $padding = strlen($payloadRaw) % 4; + if ($padding) { + $payloadRaw .= str_repeat('=', 4 - $padding); + } + $payload = json_decode(base64_decode($payloadRaw)); $clientId = $payload->sub ?? null; - if (!$clientId) { return false; } $clients = config('api_clients.clients'); - $client = collect($clients)->where('api_key', $clientId)->first(); + $client = collect($clients)->where('api_key', $clientId)->first(); if (!$client || !isset($client['api_secret'])) { return false; } - return \Firebase\JWT\JWT::decode($token, new \Firebase\JWT\Key($client['api_secret'], 'HS256')); } catch (\Exception $e) { return false;