566 lines
22 KiB
PHP
566 lines
22 KiB
PHP
<?php
|
|
|
|
namespace Modules\HospitalPortal\Http\Controllers\Api;
|
|
|
|
use App\Models\Benefit;
|
|
use App\Models\CorporateBenefit;
|
|
use App\Models\Member;
|
|
use App\Models\MemberPlan;
|
|
use App\Models\Organization;
|
|
use App\Models\Provider;
|
|
use App\Models\RequestLog;
|
|
use App\Models\RequestLogBenefit;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Routing\Controller;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Illuminate\Support\Str;
|
|
use PDF;
|
|
use Throwable;
|
|
|
|
class ProviderOnlineController extends Controller
|
|
{
|
|
public function getHeaderKey(Request $request)
|
|
{
|
|
$request->validate([
|
|
'username' => 'required|string',
|
|
'password' => 'required|string',
|
|
'kodeprovider' => 'required|string',
|
|
]);
|
|
|
|
$organization = Organization::query()->where('code', $request->kodeprovider)->first();
|
|
if (!$organization) {
|
|
return $this->headerError('Kode provider tidak ditemukan');
|
|
}
|
|
|
|
$provider = Provider::query()->firstOrNew([
|
|
'organization_id' => $organization->id,
|
|
'username' => $request->username,
|
|
]);
|
|
|
|
if ($provider->exists) {
|
|
$isPasswordValid = Hash::check($request->password, $provider->password) || $provider->password === $request->password;
|
|
if (!$isPasswordValid) {
|
|
return $this->headerError('Username atau password tidak valid');
|
|
}
|
|
} else {
|
|
$provider->password = Hash::make($request->password);
|
|
}
|
|
|
|
$provider->code = $request->kodeprovider;
|
|
$provider->status = 'active';
|
|
$provider->header_token = Str::random(64);
|
|
$provider->token = Str::random(64);
|
|
$provider->save();
|
|
|
|
return response()->json([
|
|
'header-token' => $provider->header_token,
|
|
'userid' => $provider->id,
|
|
'usertoken' => $provider->token,
|
|
'kodeprovider' => $organization->code,
|
|
'namaprovider' => $organization->name,
|
|
'errornumber' => 0,
|
|
'messagestring' => 'Success',
|
|
]);
|
|
}
|
|
|
|
public function checkEligibilitasPeserta(Request $request)
|
|
{
|
|
$request->validate([
|
|
'nokartu' => 'required|string',
|
|
'kodeprovider' => 'required|string',
|
|
'p_user_no' => 'required',
|
|
'p_token' => 'required|string',
|
|
]);
|
|
|
|
[$provider, $organization, $authError] = $this->resolveProvider($request->kodeprovider, $request->p_user_no, $request->p_token);
|
|
if ($authError) {
|
|
return $authError;
|
|
}
|
|
|
|
$member = Member::query()
|
|
->with(['person', 'currentCorporate', 'currentPolicy', 'memberPlans.plan'])
|
|
->where('member_id', $request->nokartu)
|
|
->first();
|
|
|
|
if (!$member) {
|
|
return $this->statusError('Peserta tidak ditemukan');
|
|
}
|
|
|
|
$benefits = $member->memberPlans
|
|
->map(function (MemberPlan $memberPlan) {
|
|
$plan = $memberPlan->plan;
|
|
if (!$plan) {
|
|
return null;
|
|
}
|
|
|
|
return [
|
|
'kodebenefit' => $plan->code,
|
|
'namabenefit' => $plan->corporate_plan_id,
|
|
'planid' => $plan->code,
|
|
];
|
|
})
|
|
->filter()
|
|
->values();
|
|
|
|
return response()->json([
|
|
'Status' => $this->okStatus(),
|
|
'Data' => [
|
|
'nokartu' => $member->member_id,
|
|
'memberid' => (string) $member->id,
|
|
'namapeserta' => $member->full_name,
|
|
'nomorbpjs' => $member->bpjs_id,
|
|
'jeniskelamin' => $member->gender_code,
|
|
'tanggallahir' => $this->isoDate($member->birth_date),
|
|
'hubungankeluarga' => $member->relation_with_principal,
|
|
'namaperusahaan' => optional($member->currentCorporate)->name,
|
|
'pesertavip' => 'N',
|
|
'namapenjamin' => optional($organization)->name,
|
|
'nomorpolis' => optional($member->currentPolicy)->code,
|
|
'tglmulaipolis' => $this->isoDate(optional($member->currentPolicy)->start),
|
|
'tglberakhirpolis' => $this->isoDate(optional($member->currentPolicy)->end),
|
|
'phone' => optional($member->person)->phone,
|
|
'email' => $member->email,
|
|
],
|
|
'Benefit' => $benefits,
|
|
]);
|
|
}
|
|
|
|
public function createPendaftaran(Request $request)
|
|
{
|
|
$request->validate([
|
|
'kodeprovider' => 'required|string',
|
|
'kodebenefit' => 'required|string',
|
|
'statusrujukan' => 'nullable|string',
|
|
'nomorrujukan' => 'nullable|string',
|
|
'keterangan' => 'nullable|string',
|
|
'nomorsep' => 'nullable|string',
|
|
'nokartu' => 'required|string',
|
|
'kelaskamar' => 'nullable|string',
|
|
'cobbpjs' => 'nullable|numeric',
|
|
'notransaksiprovider' => 'nullable|string',
|
|
'inacbgscode' => 'nullable|string',
|
|
'inacbgsamount' => 'nullable|numeric',
|
|
'p_user_no' => 'required',
|
|
'p_token' => 'required|string',
|
|
]);
|
|
|
|
[$provider, $organization, $authError] = $this->resolveProvider($request->kodeprovider, $request->p_user_no, $request->p_token);
|
|
if ($authError) {
|
|
return $authError;
|
|
}
|
|
|
|
$member = Member::query()
|
|
->with(['person', 'currentCorporate', 'currentPolicy'])
|
|
->where('member_id', $request->nokartu)
|
|
->first();
|
|
if (!$member) {
|
|
return $this->statusError('Peserta tidak ditemukan');
|
|
}
|
|
|
|
$plan = $this->resolvePlan($member, $request->kodebenefit);
|
|
|
|
$requestLog = RequestLog::query()->create([
|
|
'organization_id' => $organization->id,
|
|
'member_id' => $member->id,
|
|
'plan_id' => optional($plan)->id,
|
|
'policy_id' => optional($member->currentPolicy)->id ?? 0,
|
|
'payment_type' => 'cashless',
|
|
'service_code' => $request->kodebenefit,
|
|
'type_of_member' => 'member',
|
|
'status' => 'approved',
|
|
'source' => 'api',
|
|
'keterangan' => $request->keterangan,
|
|
'hak_kamar_pasien' => $request->kelaskamar ?? '',
|
|
'penempatan_kamar' => $request->kelaskamar,
|
|
'total_cob' => $request->cobbpjs,
|
|
'nominal' => 0,
|
|
'import_system' => 0,
|
|
'nomor_sep' => $request->nomorsep,
|
|
'inacbgs_code' => $request->inacbgscode,
|
|
'inacbgs_amount' => $request->inacbgsamount,
|
|
'no_transaksi_provider' => $request->notransaksiprovider,
|
|
'diagnosis' => '',
|
|
'reason' => '',
|
|
'reason_final' => '',
|
|
'catatan' => '',
|
|
'nomor_rujukan' => $request->nomorrujukan,
|
|
'status_rujukan' => $request->statusrujukan,
|
|
'submission_date' => now(),
|
|
'admission_date' => now(),
|
|
]);
|
|
|
|
$limitSubBenefit = collect();
|
|
if ($plan) {
|
|
$limitSubBenefit = CorporateBenefit::query()
|
|
->with('benefit')
|
|
->where('plan_id', $plan->id)
|
|
->get()
|
|
->map(function (CorporateBenefit $corporateBenefit) {
|
|
return [
|
|
'kodesubbenefit' => optional($corporateBenefit->benefit)->code,
|
|
'namasubbenefit' => optional($corporateBenefit->benefit)->description,
|
|
'batasan' => (string) ($corporateBenefit->limit_amount ?? 0),
|
|
];
|
|
});
|
|
}
|
|
|
|
return response()->json([
|
|
'Status' => $this->okStatus(),
|
|
'Data' => [[
|
|
'noklaim' => $requestLog->code,
|
|
'namapeserta' => $member->full_name,
|
|
'tanggallahir' => $this->isoDate($member->birth_date),
|
|
'nokartu' => $member->member_id,
|
|
'nopolis' => optional($member->currentPolicy)->code,
|
|
'nobpjs' => $member->bpjs_id,
|
|
'nosep' => $requestLog->nomor_sep,
|
|
'nomorrujukan' => $requestLog->nomor_rujukan,
|
|
'planid' => optional($plan)->code,
|
|
'masapolis' => optional($member->currentPolicy)->end ? Carbon::parse($member->currentPolicy->end)->format('d/m/Y') : null,
|
|
'namaperusahaan' => optional($member->currentCorporate)->name,
|
|
'namapenjamin' => $organization->name,
|
|
'tanggalmasuk' => $this->isoDate($requestLog->admission_date),
|
|
'tanggalkeluar' => $this->isoDate($requestLog->discharge_date),
|
|
'hakkamar' => $requestLog->penempatan_kamar,
|
|
'hakicu' => null,
|
|
'nosuratjaminan' => $requestLog->code,
|
|
'namapegawai' => null,
|
|
'namabenefit' => optional($plan)->corporate_plan_id,
|
|
'kodediagnosa' => $requestLog->diagnosis,
|
|
'keterangan' => $requestLog->keterangan,
|
|
'catatanTC1' => null,
|
|
'catatanTC2' => null,
|
|
'catatanTC3' => null,
|
|
'catatanTC4' => null,
|
|
'catatanTC5' => null,
|
|
'catatanTC6' => null,
|
|
'catatanTC7' => null,
|
|
'catatanTC8' => null,
|
|
'catatanTC9' => null,
|
|
'catatanTC10' => null,
|
|
'statusrujukan' => $requestLog->status_rujukan,
|
|
'statusklaim' => 0,
|
|
'notransaksiprovider' => $requestLog->no_transaksi_provider,
|
|
'inacbgscode' => $requestLog->inacbgs_code,
|
|
'inacbgsamount' => (float) ($requestLog->inacbgs_amount ?? 0),
|
|
]],
|
|
'LimitSubBenefit' => $limitSubBenefit->values(),
|
|
]);
|
|
}
|
|
|
|
public function createPengesahan(Request $request)
|
|
{
|
|
$request->validate([
|
|
'noklaim' => 'required|string',
|
|
'kodeprovider' => 'required|string',
|
|
'tanggalkeluar' => 'nullable|date',
|
|
'kodediagnosa' => 'nullable|string',
|
|
'inacbgscode' => 'nullable|string',
|
|
'inacbgsamount' => 'nullable|numeric',
|
|
'daftarbiaya' => 'nullable|array',
|
|
'daftarbiaya.*.kodesubbenefit' => 'required_with:daftarbiaya|string',
|
|
'daftarbiaya.*.biayaaju' => 'required_with:daftarbiaya|numeric',
|
|
'p_user_no' => 'required',
|
|
'p_token' => 'required|string',
|
|
]);
|
|
|
|
[$provider, $organization, $authError] = $this->resolveProvider($request->kodeprovider, $request->p_user_no, $request->p_token);
|
|
if ($authError) {
|
|
return $authError;
|
|
}
|
|
|
|
$requestLog = RequestLog::query()
|
|
->with(['member.person', 'member.currentCorporate', 'member.currentPolicy', 'plan'])
|
|
->where('code', $request->noklaim)
|
|
->where('organization_id', $organization->id)
|
|
->first();
|
|
if (!$requestLog) {
|
|
return $this->statusError('Nomor klaim tidak ditemukan');
|
|
}
|
|
|
|
$requestLog->update([
|
|
'status_final_log' => 'approve',
|
|
'final_log' => true,
|
|
'discharge_date' => $request->tanggalkeluar,
|
|
'diagnosis' => $request->kodediagnosa,
|
|
'inacbgs_code' => $request->inacbgscode ?? $requestLog->inacbgs_code,
|
|
'inacbgs_amount' => $request->inacbgsamount ?? $requestLog->inacbgs_amount,
|
|
]);
|
|
|
|
foreach (($request->daftarbiaya ?? []) as $biaya) {
|
|
$benefit = Benefit::query()->where('code', $biaya['kodesubbenefit'])->first();
|
|
if (!$benefit) {
|
|
continue;
|
|
}
|
|
|
|
RequestLogBenefit::query()->updateOrCreate(
|
|
[
|
|
'request_log_id' => $requestLog->id,
|
|
'benefit_id' => $benefit->id,
|
|
],
|
|
[
|
|
'amount_incurred' => $biaya['biayaaju'],
|
|
'amount_approved' => 0,
|
|
'amount_not_approved' => 0,
|
|
'excess_paid' => 0,
|
|
'keterangan' => null,
|
|
]
|
|
);
|
|
}
|
|
|
|
$requestLog->load(['requestLogBenefits.benefit']);
|
|
|
|
$biayaResponse = $requestLog->requestLogBenefits->map(function (RequestLogBenefit $requestLogBenefit) use ($requestLog) {
|
|
return [
|
|
'noklaim' => $requestLog->code,
|
|
'kodesubbenefit' => optional($requestLogBenefit->benefit)->code,
|
|
'namasubbenefit' => optional($requestLogBenefit->benefit)->description,
|
|
'kodebenefit' => optional($requestLog->plan)->code,
|
|
'namabenefit' => optional($requestLog->plan)->corporate_plan_id,
|
|
'biayaaju' => (float) ($requestLogBenefit->amount_incurred ?? 0),
|
|
'jaminanasuransi' => (float) ($requestLogBenefit->amount_approved ?? 0),
|
|
'jaminanpeserta' => (float) ($requestLogBenefit->excess_paid ?? 0),
|
|
'keterangan' => $requestLogBenefit->keterangan,
|
|
];
|
|
})->values();
|
|
|
|
return response()->json([
|
|
'Status' => $this->okStatus(),
|
|
'Data' => [[
|
|
'noklaim' => $requestLog->code,
|
|
'namapeserta' => optional($requestLog->member)->full_name,
|
|
'tanggallahir' => $this->isoDate(optional($requestLog->member)->birth_date),
|
|
'nokartu' => optional($requestLog->member)->member_id,
|
|
'nopolis' => optional(optional($requestLog->member)->currentPolicy)->code,
|
|
'nobpjs' => optional($requestLog->member)->bpjs_id,
|
|
'nosep' => $requestLog->nomor_sep,
|
|
'nomorrujukan' => $requestLog->nomor_rujukan,
|
|
'planid' => optional($requestLog->plan)->code,
|
|
'masapolis' => optional(optional($requestLog->member)->currentPolicy)->end ? Carbon::parse($requestLog->member->currentPolicy->end)->format('d/m/Y') : null,
|
|
'namaperusahaan' => optional(optional($requestLog->member)->currentCorporate)->name,
|
|
'namapenjamin' => $organization->name,
|
|
'tanggalmasuk' => $this->isoDate($requestLog->admission_date),
|
|
'tanggalkeluar' => $this->isoDate($requestLog->discharge_date),
|
|
'hakkamar' => $requestLog->penempatan_kamar,
|
|
'hakicu' => null,
|
|
'nosuratjaminan' => $requestLog->code,
|
|
'namapegawai' => null,
|
|
'namabenefit' => optional($requestLog->plan)->corporate_plan_id,
|
|
'kodediagnosa' => $requestLog->diagnosis,
|
|
'keterangan' => $requestLog->keterangan,
|
|
'catatanTC1' => null,
|
|
'catatanTC2' => null,
|
|
'catatanTC3' => null,
|
|
'catatanTC4' => null,
|
|
'catatanTC5' => null,
|
|
'catatanTC6' => null,
|
|
'catatanTC7' => null,
|
|
'catatanTC8' => null,
|
|
'catatanTC9' => null,
|
|
'catatanTC10' => null,
|
|
'statusrujukan' => $requestLog->status_rujukan,
|
|
'statusklaim' => 0,
|
|
'notransaksiprovider' => $requestLog->no_transaksi_provider,
|
|
'inacbgscode' => $requestLog->inacbgs_code,
|
|
'inacbgsamount' => (float) ($requestLog->inacbgs_amount ?? 0),
|
|
]],
|
|
'Biaya' => $biayaResponse,
|
|
]);
|
|
}
|
|
|
|
public function getRincianBiayaKlaim(Request $request)
|
|
{
|
|
$request->validate([
|
|
'noklaim' => 'required|string',
|
|
'kodeprovider' => 'required|string',
|
|
'p_user_no' => 'required',
|
|
'p_token' => 'required|string',
|
|
]);
|
|
|
|
[$provider, $organization, $authError] = $this->resolveProvider($request->kodeprovider, $request->p_user_no, $request->p_token);
|
|
if ($authError) {
|
|
return $authError;
|
|
}
|
|
|
|
$requestLog = RequestLog::query()
|
|
->with(['plan', 'requestLogBenefits.benefit'])
|
|
->where('code', $request->noklaim)
|
|
->where('organization_id', $organization->id)
|
|
->first();
|
|
if (!$requestLog) {
|
|
return $this->statusError('Nomor klaim tidak ditemukan');
|
|
}
|
|
|
|
$biaya = $requestLog->requestLogBenefits->map(function (RequestLogBenefit $requestLogBenefit) use ($requestLog) {
|
|
return [
|
|
'noklaim' => $requestLog->code,
|
|
'kodesubbenefit' => optional($requestLogBenefit->benefit)->code,
|
|
'namasubbenefit' => optional($requestLogBenefit->benefit)->description,
|
|
'kodebenefit' => optional($requestLog->plan)->code,
|
|
'namabenefit' => optional($requestLog->plan)->corporate_plan_id,
|
|
'biayaaju' => (float) ($requestLogBenefit->amount_incurred ?? 0),
|
|
'jaminanasuransi' => (float) ($requestLogBenefit->amount_approved ?? 0),
|
|
'jaminanpeserta' => (float) ($requestLogBenefit->excess_paid ?? 0),
|
|
'keterangan' => $requestLogBenefit->keterangan,
|
|
];
|
|
})->values();
|
|
|
|
return response()->json([
|
|
'Status' => $this->okStatus(),
|
|
'Data' => [
|
|
'noklaim' => $requestLog->code,
|
|
'kodeprovider' => $organization->code,
|
|
'nosep' => $requestLog->nomor_sep,
|
|
'keterangan' => $requestLog->keterangan,
|
|
'statusklaim' => $requestLog->status,
|
|
],
|
|
'Biaya' => $biaya,
|
|
]);
|
|
}
|
|
|
|
public function downloadStrukPendaftaran(Request $request)
|
|
{
|
|
$request->validate([
|
|
'noklaim' => 'required|string',
|
|
'kodeprovider' => 'required|string',
|
|
'p_user_no' => 'required',
|
|
'p_token' => 'required|string',
|
|
]);
|
|
|
|
[$provider, $organization, $authError] = $this->resolveProvider($request->kodeprovider, $request->p_user_no, $request->p_token);
|
|
if ($authError) {
|
|
return $authError;
|
|
}
|
|
|
|
$requestLog = RequestLog::query()->where('code', $request->noklaim)->where('organization_id', $organization->id)->first();
|
|
if (!$requestLog) {
|
|
return $this->statusError('Nomor klaim tidak ditemukan');
|
|
}
|
|
|
|
$member = Member::findOrFail($requestLog->member_id)
|
|
->load(['currentPlan', 'currentPolicy', 'currentPlan.corporateBenefits', 'currentPlan.corporateBenefits.benefit']);
|
|
$dateOfAdmission = $requestLog->admission_date ? Carbon::parse($requestLog->admission_date) : now();
|
|
|
|
try {
|
|
$pdf = PDF::loadView('pdf.guaranted_leter', compact('member', 'dateOfAdmission'));
|
|
return $pdf->download('Struk-Pendaftaran-' . $requestLog->code . '.pdf');
|
|
} catch (Throwable $e) {
|
|
return $this->statusError('Gagal generate PDF struk pendaftaran: ' . $e->getMessage(), 500);
|
|
}
|
|
}
|
|
|
|
public function downloadStrukPengesahan(Request $request)
|
|
{
|
|
$request->validate([
|
|
'noklaim' => 'required|string',
|
|
'kodeprovider' => 'required|string',
|
|
'p_user_no' => 'required',
|
|
'p_token' => 'required|string',
|
|
]);
|
|
|
|
[$provider, $organization, $authError] = $this->resolveProvider($request->kodeprovider, $request->p_user_no, $request->p_token);
|
|
if ($authError) {
|
|
return $authError;
|
|
}
|
|
|
|
$requestLog = RequestLog::query()->where('code', $request->noklaim)->where('organization_id', $organization->id)->first();
|
|
if (!$requestLog) {
|
|
return $this->statusError('Nomor klaim tidak ditemukan');
|
|
}
|
|
|
|
$member = Member::findOrFail($requestLog->member_id)
|
|
->load(['currentPlan', 'currentPolicy', 'currentPlan.corporateBenefits', 'currentPlan.corporateBenefits.benefit']);
|
|
$dateOfAdmission = $requestLog->discharge_date ? Carbon::parse($requestLog->discharge_date) : now();
|
|
|
|
try {
|
|
$pdf = PDF::loadView('pdf.guaranted_leter', compact('member', 'dateOfAdmission'));
|
|
return $pdf->download('Struk-Pengesahan-' . $requestLog->code . '.pdf');
|
|
} catch (Throwable $e) {
|
|
return $this->statusError('Gagal generate PDF struk pengesahan: ' . $e->getMessage(), 500);
|
|
}
|
|
}
|
|
|
|
private function resolveProvider(string $kodeProvider, $userId, string $token): array
|
|
{
|
|
$organization = Organization::query()->where('code', $kodeProvider)->first();
|
|
if (!$organization) {
|
|
return [null, null, $this->statusError('Kode provider tidak ditemukan')];
|
|
}
|
|
|
|
$provider = Provider::query()
|
|
->where('id', $userId)
|
|
->where('organization_id', $organization->id)
|
|
->where('code', $kodeProvider)
|
|
->where('status', 'active')
|
|
->first();
|
|
if (!$provider) {
|
|
return [null, null, $this->statusError('User provider tidak ditemukan')];
|
|
}
|
|
|
|
if ((string) $provider->token !== (string) $token) {
|
|
return [null, null, $this->statusError('Token tidak valid')];
|
|
}
|
|
|
|
return [$provider, $organization, null];
|
|
}
|
|
|
|
private function resolvePlan(Member $member, string $serviceCode)
|
|
{
|
|
$memberPlan = $member->memberPlans()->with('plan')
|
|
->where('status', 'active')
|
|
->orderByDesc('id')
|
|
->get()
|
|
->first(function (MemberPlan $item) use ($serviceCode) {
|
|
return optional($item->plan)->service_code === $serviceCode;
|
|
});
|
|
|
|
if ($memberPlan && $memberPlan->plan) {
|
|
return $memberPlan->plan;
|
|
}
|
|
|
|
return optional($member->memberPlans()->with('plan')->orderByDesc('id')->first())->plan;
|
|
}
|
|
|
|
private function okStatus(): array
|
|
{
|
|
return [
|
|
'errornumber' => 0,
|
|
'messagestring' => 'Success',
|
|
];
|
|
}
|
|
|
|
private function statusError(string $message, int $statusCode = 400)
|
|
{
|
|
return response()->json([
|
|
'Status' => [
|
|
'errornumber' => 1,
|
|
'messagestring' => $message,
|
|
],
|
|
'Data' => null,
|
|
], $statusCode);
|
|
}
|
|
|
|
private function headerError(string $message, int $statusCode = 400)
|
|
{
|
|
return response()->json([
|
|
'header-token' => null,
|
|
'userid' => 0,
|
|
'usertoken' => null,
|
|
'kodeprovider' => null,
|
|
'namaprovider' => null,
|
|
'errornumber' => 1,
|
|
'messagestring' => $message,
|
|
], $statusCode);
|
|
}
|
|
|
|
private function isoDate($date): ?string
|
|
{
|
|
if (empty($date)) {
|
|
return null;
|
|
}
|
|
|
|
return Carbon::parse($date)->toISOString();
|
|
}
|
|
}
|