update api user dan export alamr center client

This commit is contained in:
2023-11-06 13:19:05 +07:00
parent 23886c52d2
commit 4aa6eaa889
26 changed files with 585 additions and 227 deletions

View File

@@ -2,13 +2,21 @@
namespace Modules\Client\Http\Controllers\Api;
use Illuminate\Support\Facades\DB;
use App\Helpers\Helper;
use App\Models\Claim;
use App\Models\CorporateEmployee;
use App\Models\Icd;
use App\Models\ClaimHistoryCare;
use App\Models\Corporate;
use App\Services\ClaimService;
use Illuminate\Contracts\Support\Renderable;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Modules\Client\Transformers\ClaimShowResource;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use Illuminate\Support\Facades\Storage;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
class ClaimController extends Controller
{
@@ -133,4 +141,124 @@ class ClaimController extends Controller
{
//
}
public function export($corporate_id){
$corporate = Corporate::where('id', $corporate_id)->with(['currentPolicy'])->first();
$member_id = CorporateEmployee::where('corporate_id', $corporate_id)->get('member_id')->toArray();
// dd($member_id);
$claim = Claim::whereIn('member_id', $member_id)->with(['member', 'member.plans'])->get();
$data = [];
if (count( $claim) > 0){
$temp = [];
foreach($claim as $c) {
$diagnosis = ClaimHistoryCare::where('claim_id', 34)->with('icd')->get();
$diagnosisName = '';
if (count($diagnosis) > 0){
$tempDiagnosis = [];
foreach($diagnosis as $key => $d){
$diagnosis = Icd::where('id', $d['main_diagnosis_id'])->first();
array_push($tempDiagnosis, $diagnosis->name);
}
$diagnosisName = implode(", ", $tempDiagnosis);
}
$temp['id'] = $c['id'];
$temp['plan_id'] = $c['member']['plans'][0]['code'];
$temp['payor_id'] = $c['member']['payor_id'];
$temp['corporate_id'] = $corporate->name;
$temp['policy_number'] = $corporate->currentPolicy->code;
$temp['member_id'] = $c['member']['member_id'];
$temp['benefit_code'] = $c['benefit_code'];
$temp['benefit_desc'] = $c['benefit_desc'];
$temp['amount_incurred'] = $c['amount_incurred'];
$temp['amount_approved'] = $c['amount_approved'];
$temp['amount_not_approved'] = $c['amount_not_approved'];
$temp['excess_paid'] = $c['excess_paid'];
$temp['diganosis'] = $diagnosisName;
array_push($data, $temp);
}
$headers = [
['value' => 'Plan ID', 'cell' => 'A1', 'mergeCell' => false, 'mergeToCell' => ''],
['value' => 'Payor ID', 'cell' => 'B1', 'mergeCell' => false, 'mergeToCell' => ''],
['value' => 'Corporate ID', 'cell' => 'C1', 'mergeCell' => false, 'mergeToCell' => ''],
['value' => 'Policy Number', 'cell' => 'D1', 'mergeCell' => false, 'mergeToCell' => ''],
['value' => 'Member ID', 'cell' => 'E1', 'mergeCell' => false, 'mergeToCell' => ''],
['value' => 'Benefit Code', 'cell' => 'F1', 'mergeCell' => false, 'mergeToCell' => ''],
['value' => 'Benefit Desc', 'cell' => 'G1', 'mergeCell' => false, 'mergeToCell' => ''],
['value' => 'Amt Incurred', 'cell' => 'H1', 'mergeCell' => false, 'mergeToCell' => ''],
['value' => 'Amt Approved', 'cell' => 'I1', 'mergeCell' => false, 'mergeToCell' => ''],
['value' => 'Amt Not Approved', 'cell' => 'J1', 'mergeCell' => false, 'mergeToCell' => ''],
['value' => 'Excess Paid', 'cell' => 'K1', 'mergeCell' => false, 'mergeToCell' => ''],
['value' => 'Diagnosis', 'cell' => 'L1', 'mergeCell' => false, 'mergeToCell' => 'J2'],
];
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
foreach ($headers as $header) {
$sheet->setCellValue($header['cell'], $header['value']);
if ($header['mergeCell'] === true) {
$sheet->mergeCells($header['cell'] . ':' . $header['mergeToCell']);
}
$sheet->getStyle($header['cell'])->getFont()->setBold(true);
$sheet->getStyle($header['cell'])->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER)->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER);
}
$startFrom = 2;
foreach($data as $i => $d){
$sheet->setCellValue('A' . $startFrom, $d['plan_id'] ?? '-');
$sheet->setCellValue('B' . $startFrom, $d['payor_id'] ?? '-');
$sheet->setCellValue('C' . $startFrom, $d['corporate_id'] ?? '-');
$sheet->setCellValue('D' . $startFrom, $d['policy_number'] ?? '-');
$sheet->setCellValue('E' . $startFrom, $d['member_id'] ?? '-');
$sheet->setCellValue('F' . $startFrom, $d['benefit_code'] ?? '-');
$sheet->setCellValue('G' . $startFrom, $d['benefit_desc'] ?? '-');
$sheet->setCellValue('H' . $startFrom, $d['amount_incurred'] ?? '-');
$sheet->setCellValue('I' . $startFrom, $d['amount_approved'] ?? '-');
$sheet->setCellValue('J' . $startFrom, $d['amount_not_approved'] ?? '-');
$sheet->setCellValue('K' . $startFrom, $d['excess_paid'] ?? '-');
$sheet->setCellValue('L' . $startFrom, $d['diganosis'] ?? '-');
$startFrom++;
}
foreach (['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J','K'] as $header) {
if ($header === 'A') {
$spreadsheet->getActiveSheet()->getColumnDimension($header)->setWidth(35, 'px');
} elseif ($header === 'H' || $header === 'I') {
$spreadsheet->getActiveSheet()->getColumnDimension($header)->setWidth(100, 'px');
} else {
$spreadsheet->getActiveSheet()->getColumnDimension($header)->setAutoSize(true);
}
}
$spreadsheet->getActiveSheet()->getStyle('A2:A' . $startFrom)->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER)->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER);
$sheet->getDefaultRowDimension()->setRowHeight(-1);
$sheet->setTitle('Alarm Center Report');
$writer = new Xlsx($spreadsheet);
ob_start();
$writer->save('php://output');
$content = ob_get_contents();
ob_end_clean();
$fileName = 'result-' . now()->getPreciseTimestamp(3) . '-alarm-center-report.xlsx';
Storage::disk('public')->put('temp/' . $fileName, $content);
$fileUrl = url('storage/temp/' . $fileName);
return Helper::responseJson([
"file_url" => $fileUrl
]);
}
}
}

View File

@@ -19,7 +19,7 @@ class ClaimRequestController extends Controller
* Display a listing of the resource.
* @return Renderable
*/
private static $code_prefix = 'CRQ-C';
private static $code_prefix = 'CP';
public function index()
{
return view('client::index');

View File

@@ -6,6 +6,7 @@ use App\Helpers\Helper;
use App\Models\Member;
use App\Models\Claim;
use App\Models\ClaimRequest;
use App\Models\CorporateEmployee;
use App\Services\CorporateMemberService;
use Illuminate\Contracts\Support\Renderable;
use Illuminate\Http\Request;
@@ -115,8 +116,9 @@ class CorporateMemberController extends Controller
public function serviceMonitoring($corporate_id, $claim_id)
{
$data = Claim::where('id', $claim_id)->first();
return Helper::responseJson(DataServiceMonitoring::make($data));
}
}

View File

@@ -52,6 +52,7 @@ Route::prefix('client')->group(function () {
Route::get('service-monitoring/{id}', [CorporateMemberController::class, 'serviceMonitoring']);
Route::get('claims/status', [ClaimController::class, 'status']);
Route::get('claims', [ClaimController::class, 'index']);
Route::get('claims/export', [ClaimController::class, 'export']);
Route::get('claims/{claim_id}/encounters', [ClaimEncounterController::class, 'getEncounterData']);
Route::get('topup', [TopUpController::class, 'index']);
// Route::get('topup', [TopUpController::class, 'get']);
@@ -63,6 +64,8 @@ Route::prefix('client')->group(function () {
Route::get('corporate', [CorporateCurrentController::class, 'index']);
Route::put('corporate-update', [CorporateCurrentController::class, 'update']);
});
Route::get('claims/{id}', [ClaimController::class, 'show']);

View File

@@ -3,11 +3,22 @@
namespace Modules\Client\Transformers\AlarmCenter;
use App\Models\ClaimRequest;
use App\Models\DiagnosisSecondaryClaimHistoryCare;
use App\Models\ClaimEncounter;
use App\Models\ClaimHistoryCare;
use App\Models\Encounter;
use App\Models\Member;
use App\Models\Icd;
use App\Models\Organization;
use App\Models\MedicalPlan;
use App\Models\CorporateEmployee;
use App\Models\DailyMonitoring;
use App\Models\LaboratoriumResult;
use App\Helpers\Helper;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Facades\Storage;
@@ -24,14 +35,87 @@ class DataServiceMonitoring extends JsonResource
$claim_request = ClaimRequest::findOrFail($this->claim_request_id);
$member = Member::findOrFail($this->member_id);
$encounter = ClaimEncounter::where('claim_id', $this->id)->first();
if ($encounter) {
$final_encounter = Encounter::findOrFail($this->final_encounter_id);
$data = Organization::findOrFail($final_encounter->healthcare_id);
$hospital = $data->name;
// History Care Hospital
$historyCareHospital = ClaimHistoryCare::where('claim_id', $this->id)->first();
if ($historyCareHospital) {
$hospital = Organization::findOrFail($historyCareHospital->organization_id)->name;
$mainDianosis = Icd::findOrFail($historyCareHospital->main_diagnosis_id)->name;
$mainDianosisCode = Icd::findOrFail($historyCareHospital->main_diagnosis_id)->code;
$comporatationDiagnosis = DiagnosisSecondaryClaimHistoryCare::where('claim_history_care_id', $historyCareHospital->id)->first();
$comporatationDiagnosisName = Icd::findOrFail($comporatationDiagnosis->icd_id)->name;
$comporatationDiagnosisCode = Icd::findOrFail($comporatationDiagnosis->icd_id)->code;
$admissionDate = $historyCareHospital->admission_date;
$dischargeDate = $historyCareHospital->discharge_date;
$serviceCode = $historyCareHospital->service_code;
} else {
$hospital = '-';
$hospital = '-';
$mainDianosis = '-';
$mainDianosisCode = '-';
$comporatationDiagnosisName = '-';
$comporatationDiagnosisCode = '-';
$admissionDate = '-';
$dischargeDate = '-';
$serviceCode = '-';
}
$dailyMonitoring = DailyMonitoring::where('claim_id', $claim_request->claim_id)->get()->toArray();
$laboratoriumResult = LaboratoriumResult::where('claim_id', $claim_request->claim_id)->get()->toArray();
// Handle Daily Monitoring
$dataDailyMonitoring = [];
if (count($dailyMonitoring) > 0){
$temp = [];
foreach($dailyMonitoring as $data){
$temp['date'] = Helper::formatDateOnly($data['created_at']);
$temp['time'] = Helper::formatTimeOnly($data['created_at']);
$temp['status'] = 'Done';
$temp['subject_title'] = $data['subject'];
$temp['body_temperature'] = $data['body_temperature']. 'mm[Hg]';
$temp['sistole'] = $data['sistole']. 'mm[Hg]';
$temp['diastole'] = $data['diastole']. 'mm[Hg]';
$temp['respiration_rate'] = $data['respiration_rate']. 'mm[Hg]';
$temp['analisis_title'] = $data['analysis'];
$medicalPlan = MedicalPlan::where('claim_daily_monitoring_id', $data['id'])->get('plan')->toArray();
if (count( $medicalPlan) > 0){
$temp['Perencanaan'] = [];
foreach($medicalPlan as $item){
array_push($temp['Perencanaan'], $item['plan']);
}
} else {
$temp['Perencanaan'] = [];
}
array_push($dataDailyMonitoring, $temp);
}
}
// Handle Laboratorium Result
$dataLaboratoruiumResult = [];
if (count($laboratoriumResult) > 0){
$tempLab = [];
foreach($laboratoriumResult as $data){
$tempLab['datetime'] = $data['date'];
$tempLab['reimbursement_code'] = "RE-0" . $data['id'];
$tempLab['examination'] = $data['examination'];
$tempLab['location'] = $data['location'];
if (count($data['lab_result_file']) > 0){
$tempLab['file'] = $data['lab_result_file'][0]['lab_result_file_obj']->path; // masih dumy untuk download nya belum bisa multiple
}
array_push($dataLaboratoruiumResult, $tempLab);
}
}
$data = [
"id" => $this->id,
"company_name" => $member->currentCorporate->name,
@@ -41,82 +125,56 @@ class DataServiceMonitoring extends JsonResource
"phone" => $member->person->phone,
"email" => $member->email,
"birth_date" => $member->birth_date,
"symptoms" => "Nyeri dada",
"sign" => "Sesak Nafas",
"main_diagnose" => "Chest pain on breathing",
"main_diagnose_code" => "R07.1",
"comparative_diagnosis" => "Abnormalities of breathing",
"comparative_diagnosis_code" => "R06",
"medical_evacuation" => "Land Transportation",
"symptoms" => $historyCareHospital->symptoms ? $historyCareHospital->symptoms : '-' ,
"sign" => $historyCareHospital->sign ? $historyCareHospital->sign : '-',
"main_diagnose" => $mainDianosis,
"main_diagnose_code" => $mainDianosisCode,
"comparative_diagnosis" => $comporatationDiagnosisName,
"comparative_diagnosis_code" => $comporatationDiagnosisCode,
"service_name" => $serviceCode,
"benefit_name" => "Konsultasi Dokter",
"hospital" => $hospital,
"admission_date" => $claim_request->submission_date,
"discharge_date" => $claim_request->submission_date,
"dialy_monitoring" => [
"0" => [
"date" => "2023-10-05",
"time" => "09:10",
"status" => "Done",
"subject_title" => "Pasien mengalami sesak napas dan nyeri dada",
"body_temperature" => "36.5",
"sistole" => "110 mm[Hg]",
"diastole" => "110 mm[Hg]",
"respiration_rate" => "20/min",
"analisis_title" => "Asthma bronkial dengan perbaikan",
"Perencanaan" => [
"O2 4L/min", "IVDL RL 2 kolf/6 jam", "Rencana tes sputum"
]
],
"1" => [
"date" => "2023-10-04",
"time" => "09:10",
"status" => "Done",
"subject_title" => "Pasien mengalami sesak napas dan nyeri dada",
"body_temperature" => "36.5",
"sistole" => "110 mm[Hg]",
"diastole" => "110 mm[Hg]",
"respiration_rate" => "20/min",
"analisis_title" => "Asthma bronkial dengan perbaikan",
"Perencanaan" => [
"O2 4L/min", "IVDL RL 2 kolf/6 jam", "Rencana tes sputum"
]
]
],
"laboratorium_result" => [
"0" => [
[
"datetime" => "2023-10-05 10:00",
"reimbursement_code" => "RE-011",
"examination" => "SGOT",
"location" => "Pramita Jakarta Ragunan",
"files" => "https:://test.com"
],
[
"datetime" => "2023-10-05 09:00",
"reimbursement_code" => "RE-010",
"examination" => "SGOT",
"location" => "Pramita Jakarta Ragunan",
"files" => "https:://test.com"
],
],
"1" => [
[
"datetime" => "2023-10-04 10:00",
"reimbursement_code" => "RE-09",
"examination" => "Hematologi Lengkap",
"location" => "Pramita Jakarta Ragunan",
"files" => "https:://test.com"
],
[
"datetime" => "2023-10-04 09:00",
"reimbursement_code" => "RE-08",
"examination" => "Hematologi Lengkap",
"location" => "Pramita Jakarta Ragunan",
"files" => "https:://test.com"
]
]
"admission_date" => $admissionDate,
"discharge_date" => $dischargeDate,
"dialy_monitoring" => $dataDailyMonitoring,
// "laboratorium_result" => [
// "0" => [
// [
// "datetime" => "2023-10-05 10:00",
// "reimbursement_code" => "RE-011",
// "examination" => "SGOT",
// "location" => "Pramita Jakarta Ragunan",
// "files" => "https:://test.com"
// ],
// [
// "datetime" => "2023-10-05 09:00",
// "reimbursement_code" => "RE-010",
// "examination" => "SGOT",
// "location" => "Pramita Jakarta Ragunan",
// "files" => "https:://test.com"
// ],
// ],
// "1" => [
// [
// "datetime" => "2023-10-04 10:00",
// "reimbursement_code" => "RE-09",
// "examination" => "Hematologi Lengkap",
// "location" => "Pramita Jakarta Ragunan",
// "files" => "https:://test.com"
// ],
// [
// "datetime" => "2023-10-04 09:00",
// "reimbursement_code" => "RE-08",
// "examination" => "Hematologi Lengkap",
// "location" => "Pramita Jakarta Ragunan",
// "files" => "https:://test.com"
// ]
// ]
]
// ],
"laboratorium_result" => [$dataLaboratoruiumResult], //
];

View File

@@ -69,6 +69,7 @@ class DailyMonitoringController extends Controller
->leftJoin('members', 'claims.member_id', '=', 'members.id')
->select('claims.id AS claim_id','claim_history_cares.admission_date','claim_history_cares.discharge_date','claim_requests.code AS claim_code','services.name AS service_type','claims.status AS claim_status','members.member_id',)
->where("claims.member_id", "=", $memberDetail->id)
->where("claim_requests.claim_id", "!=",null)
->orderBy("claims.created_at", "desc")
->get();
@@ -116,7 +117,7 @@ class DailyMonitoringController extends Controller
public function AddDetailMonitoringList(Request $request, $claim_code)
{
$request->merge(['claim_code' => $claim_code]);
// validation rule
$validator = Validator::make($request->all(),[
'claim_code' => 'required|exists:claim_requests,code',
@@ -143,15 +144,13 @@ class DailyMonitoringController extends Controller
->select('id')
->where('code', $claim_code)
->first();
// get claim
$claim = DB::table('claims')
->select('id')
->where('claim_request_id', $claim_request->id)
->first();
DB::beginTransaction();
try {
// insert claim daily monitoring
$db_response = DailyMonitoring::create([
@@ -165,6 +164,7 @@ class DailyMonitoringController extends Controller
'complaints' => $request->complaints,
]);
// cek medical plan
$num_medical_plan = 0;
@@ -204,7 +204,6 @@ class DailyMonitoringController extends Controller
}
catch (Exception $e) {
DB::rollBack();
return response()->json([
'error' => true,
'message' => $e->getMessage(),

View File

@@ -5,126 +5,126 @@ namespace Modules\Linksehat\Http\Controllers\Api;
use App\Helpers\Helper;
use App\Http\Controllers\Controller;
use App\Models\Person;
use App\Models\User;
use App\Models\OLDLMS\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Laravel\Socialite\Facades\Socialite;
use Modules\Linksehat\Transformers\UserProfileResource;
use Symfony\Component\HttpFoundation\Response;
use Illuminate\Support\Facades\Http;
use Validator;
class AuthController extends Controller
{
public function otpRequest(Request $request)
{
$request->validate([
// 'phone' => 'required'
'phone_or_email' => 'required'
]);
private $url;
if (filter_var($request->phone_or_email, FILTER_VALIDATE_EMAIL)) {
$user = User::updateOrCreate([
'email' => $request->phone_or_email
], [
'email' => $request->phone_or_email,
'otp' => rand(1000, 9999),
'otp_created_at' => now()
]);
$person = Person::query()->create([
'owner_user_id' => $user->id,
'email' => $request->phone_or_email,
'created_by' => $user->id,
]);
User::query()->find($user->id)->update([
'person_id' => $person->id
]);
} else {
$user = User::updateOrCreate([
'phone' => $request->phone_or_email
], [
'phone' => $request->phone_or_email,
'otp' => rand(1000, 9999),
'otp_created_at' => now()
]);
$person = Person::query()->create([
'owner_user_id' => $user->id,
'phone' => $request->phone_or_email,
'created_by' => $user->id,
]);
User::query()->find($user->id)->update([
'person_id' => $person->id
]);
}
if (!$user) {
$message = filter_var($request->phone_or_email, FILTER_VALIDATE_EMAIL) ? "User dengan alamat email " . $request->phone_or_email . " tidak ditemukan" : "User dengan nomor telepon " . $request->phone_or_email . " tidak ditemukan";
return Helper::responseJson(statusCode: Response::HTTP_NOT_FOUND, message: $message);
}
// TODO Send the OTP
if (filter_var($request->phone_or_email, FILTER_VALIDATE_EMAIL)) {
// Send Email
} else {
// Send Whatsapp
}
return Helper::responseJson(message: 'OTP Terkirim');
public function __construct() {
$this->url = $_ENV['LMS_APP_URL'];
}
public function login(Request $request)
{
{
$request->validate([
// 'email' => 'email',
// 'password' => 'required_with:email',
'phone_or_email' => 'required',
// 'phone' => '',
// 'otp' => 'required_with:phone',
'phone_or_email' => 'required',
'otp' => 'required'
'password' => 'required',
// 'otp' => 'required'
]);
$loginType = filter_var($request->phone_or_email, FILTER_VALIDATE_EMAIL) ? 'email' : 'phone';
// Login hit ke API linksehat, karena encrypt nya pake CI
$response = Http::post($this->url.'login', [
'sEmail' => $request->phone_or_email,
'sPassword' => $request->password,
'sRemember' => $request->remember
]);
if ($loginType == 'email') {
$user = User::query()
->where('email', $request->phone_or_email)
->first();
}
if ($loginType == 'phone') {
$user = User::query()
->where('phone', $request->phone_or_email)
->first();
}
if (!isset($user) || empty($user)) {
return response(['message' => 'User Tidak Ditemukan'], 404);
}
if ($loginType == 'email') {
if ($request->otp != $user->otp) {
return response(['message' => 'OTP Salah, Silahkan Cek Kembali Email Anda'], 403);
}
} else if ($loginType == 'phone') {
if ($request->otp != $user->otp) {
return response(['message' => 'OTP Salah'], 403);
}
$response = $response->json();
if ($response['success']){
$user = User::with('detail')
->where('sEmail', $request->phone_or_email)
->first();
return Helper::responseJson(
data: [
'token' => $user->createToken('app')->plainTextToken,
'user' => UserProfileResource::make($user),
],
message: 'Selamat Datang'
);
} else {
return response(['message' => 'Mode Login Tidak Dikenal'], 403);
return response(['message' => 'Email atau Password salah, Silahkan Cek Kembali'], 403);
};
}
public function loginPhone(Request $request)
{
$request->validate([
'phone_or_email' => 'required',
'otp' => 'required',
]);
$user = User::with('detail')
->where([
'sPhone' => $request->phone_or_email,
'sVerificationCode' => $request->otp
])
->first();
if ($user){
$updateVericationCode = User::with('detail')
->where([
'sPhone' => $request->phone_or_email,
'sVerificationCode' => $request->otp
])->update([
'sVerificationCode' => null,
]);
return Helper::responseJson(
data: [
'token' => $user->createToken('app')->plainTextToken,
'user' => UserProfileResource::make($user),
],
message: 'Selamat Datang'
);
} else {
return response(['message' => 'Email atau Password salah, Silahkan Cek Kembali'], 403);
};
}
public function otpRequest(Request $request)
{
$user = User::with('detail')
->where('sPhone', $request->phone_or_email)
->first();
if ($user){
// Request OTP ke API linksehat
$response = Http::post($this->url.'generate_code', [
'sPhone' => $request->phone_or_email
]);
$response = $response->json();
return Helper::responseJson(
data: [
'otp' => $response['message'],
],
message: 'Kode OTP'
);
} else {
return Helper::responseJson(
data: [
'otp' => null,
],
message: 'Nomor tidak ditemukan'
);
}
return Helper::responseJson(
data: [
'token' => $user->createToken('app')->plainTextToken,
'user' => UserProfileResource::make($user),
],
message: 'Selamat Datang'
);
}
public function register(Request $request)
@@ -163,6 +163,7 @@ class AuthController extends Controller
return Helper::responseJson(message: 'Behasil Logout.');
}
public function mockOtp(Request $request)
{
$request->validate([

View File

@@ -3,7 +3,7 @@
namespace Modules\Linksehat\Http\Controllers\Api;
use App\Helpers\Helper;
use App\Models\User;
use App\Models\OLDLMS\User;
use Illuminate\Contracts\Support\Renderable;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
@@ -16,9 +16,11 @@ class ProfileController extends Controller
* Display a listing of the resource.
* @return Renderable
*/
public function index()
public function index(Request $request, $id)
{
$user = Auth::user()->load('person');
$user = User::where('nID', $id);
dd($user);
return Helper::responseJson(new UserProfileResource($user));
}

View File

@@ -35,6 +35,7 @@ Route::prefix('linksehat')->group(function () {
Route::post('otp-request', 'otpRequest');
Route::post('mock-otp', 'mockOtp');
Route::post('login', 'login');
Route::post('login-phone', 'loginPhone');
Route::post('register', 'register');
Route::get('social-login/{provider}', 'redirectSocialLogin');
Route::get('social-login/{provider}/callback', 'handleSocialLoginCallback');
@@ -59,7 +60,7 @@ Route::prefix('linksehat')->group(function () {
Route::middleware('auth:sanctum')->group(function () {
Route::get('profile', [ProfileController::class, 'index'])->name('profile');
Route::get('profile/{id}', [ProfileController::class, 'index'])->name('profile');
Route::post('profile', [ProfileController::class, 'update'])->name('profile.update');
Route::post('notification-tokens/delete/{id}', [NotificationTokenController::class, 'destroy'])->name('profile.delete.token');
Route::post('notification-tokens', [NotificationTokenController::class, 'store'])->name('profile.store.token');

View File

@@ -3,6 +3,10 @@
namespace Modules\Linksehat\Transformers;
use Illuminate\Http\Resources\Json\JsonResource;
use App\Models\OLDLMS\User;
use App\Models\OLDLMS\UserDetail;
use DB;
class UserProfileResource extends JsonResource
{
@@ -12,25 +16,44 @@ class UserProfileResource extends JsonResource
* @param \Illuminate\Http\Request
* @return array
*/
protected $connection = 'oldlms';
public function toArray($request)
{
$memberProfile = User::with('detail')->where('nIDUser', $this->nID)->get()->toArray();
$dataMemberProfile = [];
if (count($memberProfile) > 0){
foreach($memberProfile as $m){
$urlAvatarDefault = $m['detail']['nIDJenisKelamin'] == 1 ? 'https://linksehat.dev/assets/img/users/male-avatar.png' : 'https://linksehat.dev/assets/img/users/male-avatar.png';
$avatarMember = $m['detail']['sImage'] ?? $urlAvatarDefault;
$relationship = DB::connection('oldlms')->table('tm_hubungan_keluarga')->where('nID', $m['nIDHubunganKeluarga'])->first('sHubunganKeluarga');
$data = [
'id' => $m['nID'],
'name' => $m['full_name'],
'relationship' => $relationship->sHubunganKeluarga,
'avatar' => $avatarMember,
];
array_push( $dataMemberProfile, $data);
}
}
// Principal
$urlAvatarDefault = $this->detail->nIDJenisKelamin == 1 ? 'https://linksehat.dev/assets/img/users/male-avatar.png' : 'https://linksehat.dev/assets/img/users/male-avatar.png';
$avatar = $this->detail->sImage ?? $urlAvatarDefault;
return [
'id' => $this->id,
'email' => $this->email,
'phone' => $this->phone,
'email_verified_at' => $this->email_verified_at,
'nik' => $this->person->nik ?? null,
'name_prefix' => $this->person->name_prefix ?? null,
'name' => $this->person->name ?? null,
'name_suffix' => $this->person->name_suffix ?? null,
'full_name' => $this->person->full_name ?? null,
'gender' => $this->person->gender ?? null,
'birth_date' => $this->person->birth_date ?? null,
'age' => $this->person->age ?? null,
'is_deceased' => $this->person->is_deceased ?? null,
'deceased_at' => $this->person->deceased_at ?? null,
'marital_status' => $this->person->marital_status ?? null,
'preferred_lang' => $this->meta->preferred_lang ?? 'id',
'id' => $this->nID,
'full_name' => $this->sFirstName . ' '. $this->sLastName,
'avatar' => $avatar,
'member_type' => $this->nIDUser ? 'Dependent' : 'Principal',
'member_profile' => $dataMemberProfile,
];
}
}

View File

@@ -222,4 +222,26 @@ class Helper
}
public static function formatDateOnly($date){
// Membuat objek Carbon dengan tanggal asli dan zona waktu UTC
$carbonDate = Carbon::createFromFormat('Y-m-d\TH:i:s.u\Z', $date, 'UTC');
// Mengonversi tanggal ke zona waktu yang diinginkan
$carbonDate->setTimezone('Asia/Jakarta');
$convertedDate = $carbonDate->toDateString();
return $convertedDate;
}
public static function formatTimeOnly($date){
// Membuat objek Carbon dengan tanggal asli dan zona waktu UTC
$carbonDate = Carbon::createFromFormat('Y-m-d\TH:i:s.u\Z', $date, 'UTC');
// Mengonversi tanggal ke zona waktu yang diinginkan
$carbonDate->setTimezone('Asia/Jakarta');
$convertedDate = $carbonDate->toTimeString();
return $convertedDate;
}
}

View File

@@ -0,0 +1,18 @@
<?php
namespace App\Models\OLDLMS;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Laravel\Sanctum\PersonalAccessToken as SanctumPersonalAccessToken;
class PersonalAccessToken extends SanctumPersonalAccessToken
{
use HasFactory;
protected $table = 'personal_access_tokens';
protected $connection = 'oldlms';
}

View File

@@ -2,14 +2,20 @@
namespace App\Models\OLDLMS;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Laravel\Sanctum\HasApiTokens;
use Spatie\Permission\Traits\HasRoles;
use Illuminate\Notifications\Notifiable;
class User extends Model
{
use HasFactory, SoftDeletes;
use HasFactory, SoftDeletes, HasApiTokens, HasRoles, Notifiable;
const CREATED_AT = 'dCreateOn';
const UPDATED_AT = 'dUpdateOn';
@@ -55,7 +61,7 @@ class User extends Model
{
return $this->hasOne(UserDetail::class, 'nIDUser', 'nID');
}
public function insurances()
{
return $this->hasMany(UserInsurance::class, 'nIDUser', 'nID');

View File

@@ -26,6 +26,7 @@ class UserDetail extends Model
'nIDJenisKelamin',
'sCreateBy',
'sKTP',
'sImages',
];

View File

@@ -18,6 +18,8 @@ class User extends Authenticatable
*
* @var array<int, string>
*/
protected $connection = 'mysql';
protected $fillable = [
'person_id',
'name',

View File

@@ -20,6 +20,10 @@ use App\Models\IcdTemplate;
use App\Models\FormulariumTemplate;
use App\Models\AuditTrail;
use Illuminate\Support\Facades\Auth;
use App\Models\OLDLMS\PersonalAccessToken;
use Laravel\Sanctum\Sanctum;
use Str;
class AppServiceProvider extends ServiceProvider
@@ -163,6 +167,8 @@ class AppServiceProvider extends ServiceProvider
$this->logAuditTrail($model, 'deleted');
});
Sanctum::usePersonalAccessTokenModel(PersonalAccessToken::class);
}

View File

@@ -0,0 +1,39 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('claim_daily_monitoring', function (Blueprint $table) {
$table->id();
$table->integer('claim_id');
$table->text('subject');
$table->decimal('body_temperature', 11, 2);
$table->decimal('respiration_rate', 11, 2);
$table->decimal('sistole', 11, 2);
$table->decimal('diastole', 11, 2);
$table->text('analysis');
$table->text('complaints');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('claim_daily_monitoring');
}
};

View File

@@ -14,7 +14,7 @@ return new class extends Migration
public function up()
{
Schema::create('medical_plan', function (Blueprint $table) {
$table->bigIncrements('id');
$table->id();
$table->bigInteger('claim_daily_monitoring_id');
$table->text('plan');
$table->timestamps();

View File

@@ -14,7 +14,7 @@ return new class extends Migration
public function up()
{
Schema::create('laboratorium_result', function (Blueprint $table) {
$table->bigIncrements('id');
$table->id();
$table->integer('claim_id');
$table->string('date');
$table->text('location');

View File

@@ -317,7 +317,7 @@ export default function Table<T>({
{exportReport && exportReport.useExport ? (
<Grid item xs={12} lg={2} xl={2}>
<FormControl fullWidth>
<Button variant='contained' sx={{p:2}}>
<Button variant='contained' sx={{p:2}} onClick={exportReport.handleExportReport}>
<Download />
<Typography variant='inherit' sx={{marginLeft: 1}}>Export</Typography>
</Button>

View File

@@ -38,6 +38,7 @@ import { useSearchParams, useNavigate, Link } from 'react-router-dom';
import { fDateSuffix } from '../../utils/formatTime';
import TableMoreMenu from '../../components/table/TableMoreMenu';
import VisibilityOutlinedIcon from '@mui/icons-material/VisibilityOutlined';
import { enqueueSnackbar } from 'notistack';
import DetailDataMember from './ListMember';
import Label from '../../components/Label';
@@ -313,9 +314,26 @@ export default function List() {
};
/* -------------------------------- handle export --------------------------- */
const handleExportReport = {
const handleExportReport = async () => {
var filter = Object.fromEntries([...searchParams.entries()]);
}
await axios
.get(corporateValue + '/claims/export', { params: filter })
.then((res) => {
enqueueSnackbar('Data berhasil di Export', {
variant: 'success',
anchorOrigin: { horizontal: 'right', vertical: 'top' },
});
document.location.href = res.data.data.file_url;
})
.catch((err) =>
enqueueSnackbar('Data Gagal di Export', {
variant: 'error',
anchorOrigin: { horizontal: 'right', vertical: 'top' },
})
);
};
const exportReport = {
useExport: true,
startDate: startDateValue,

View File

@@ -319,9 +319,27 @@ export default function List() {
};
/* -------------------------------- handle export --------------------------- */
const handleExportReport = {
const handleExportReport = async () => {
var filter = Object.fromEntries([...searchParams.entries()]);
}
await axios
.get('claims/export', { params: filter })
.then((res) => {
enqueueSnackbar('Data berhasil di Export', {
variant: 'success',
anchorOrigin: { horizontal: 'right', vertical: 'top' },
});
document.location.href = res.data.data.file_url;
})
.catch((err) =>
enqueueSnackbar('Data Gagal di Export', {
variant: 'error',
anchorOrigin: { horizontal: 'right', vertical: 'top' },
})
);
};
const exportReport = {
useExport: false,
startDate: startDateValue,

View File

@@ -14,6 +14,7 @@ import {
TableBody,
Table,
TableRow,
Link,
} from '@mui/material';
import { styled } from '@mui/material/styles';
import DownloadIcon from '@mui/icons-material/Download';
@@ -135,7 +136,7 @@ type Data = {
main_diagnose_code: string,
comparative_diagnosis: string,
comparative_diagnosis_code: string,
medical_evacuation: string,
service_name: string,
benefit_name: string,
hospital: string,
admission_date: string,
@@ -193,7 +194,16 @@ export default function ServiceMonitoring() {
})();
}, [corporateValue]);
console.log(data?.laboratorium_result)
function handleDownloadClick(fileUrl: string) {
const tempLink = document.createElement('a');
tempLink.href = fileUrl;
tempLink.setAttribute('download', 'nama-file-yang-diunduh.pdf'); // Ganti 'nama-file-yang-diunduh.pdf' sesuai kebutuhan
tempLink.style.display = 'none';
document.body.appendChild(tempLink);
tempLink.click();
document.body.removeChild(tempLink);
}
return (
<Page title="Service Monitoring">
<Grid container spacing={3} paddingX={2} sx={{ marginBottom: 5, marginTop: 1 }} >
@@ -244,7 +254,7 @@ export default function ServiceMonitoring() {
<Grid item xs={6} lg={6} md={6}>
<Stack>
<Typography variant="inherit">Date of Birth</Typography>
<Typography variant="h6">{data?.birth_date || 'Loading...'}</Typography>
<Typography variant="h6">{data?.birth_date ? fDateSuffix(data?.birth_date) : '-' || 'Loading...'}</Typography>
</Stack>
</Grid>
</Stack>
@@ -331,8 +341,8 @@ export default function ServiceMonitoring() {
<Stack spacing={3} sx={{ paddingY: 2, paddingX: 2 }}>
<Grid item xs={12} lg={12} md={12}>
<Stack spacing={1}>
<Typography variant="inherit">Medical Evacuation</Typography>
<Typography variant="h6">{data?.medical_evacuation}</Typography>
<Typography variant="inherit">Code</Typography>
<Typography variant="h6">{data?.service_name}</Typography>
</Stack>
</Grid>
<Grid item xs={12} lg={12} md={12}>
@@ -390,7 +400,7 @@ export default function ServiceMonitoring() {
<TimelineConnector sx={{border: '0.5px dashed rgba(145, 158, 171, 0.32)', backgrounSize: '4px 4px' }} />
</TimelineSeparator>
<TimelineContent>
<Typography variant='h5' sx={{marginBottom: 2}}> { fDateSuffix(row.date)}</Typography>
<Typography variant='h5' sx={{marginBottom: 2}}> {fDateSuffix(row.date)}</Typography>
<Card sx={{paddinX:2, paddingY:2}} >
<Stack direction={'row'} sx={{ alignItems: 'center', padding: 2, justifyContent: 'space-between' }}>
<Label> {row.time} </Label>
@@ -473,9 +483,9 @@ export default function ServiceMonitoring() {
<Grid item xs={12} lg={12} md={12}>
<Stack marginLeft={5}>
<ul>
{/* {data.} */}
<li>test</li>
<li>test</li>
{row.Perencanaan.length > 0 ? row.Perencanaan.map((r, index) => (
<li key={index}>{r}</li>
)) : <li>-</li>}
</ul>
</Stack>
</Grid>
@@ -496,13 +506,14 @@ export default function ServiceMonitoring() {
</Grid>
</TabPanel>
<TabPanel value={value} index={1}>
<Grid container>
<Grid item xs={12} md={12}>
{data?.laboratorium_result.length > 0 ? data?.laboratorium_result.map((row, index) => (
<Card sx={{paddinX:2, paddingY:2, paddingX:1, marginTop:2 }} key={index} >
<Stack paddingX={5}>
<Typography variant='subtitle1'>{fDateSuffix(row[index].datetime)}</Typography>
<Typography variant='subtitle1'>{row[index]?.datetime ? fDateSuffix(row[index].datetime) : ''}</Typography>
{row.length > 0 ? row.map((list, i) => (
<Card key={i} sx={{marginTop:2, paddingX:2, paddingY:2}}>
<Label> {list.reimbursement_code}
@@ -525,7 +536,7 @@ export default function ServiceMonitoring() {
<TableCell>{list.location}</TableCell>
<TableMoreMenu actions={
<>
<MenuItem onClick={() => navigate(`${list.files}` )}>
<MenuItem onClick={() => handleDownloadClick(list.file)} >
<DownloadIcon />
Download
</MenuItem>

View File

@@ -54,7 +54,7 @@ const navConfig = [
{ title: 'Corporate', path: '/corporates' },
// { title: 'Corporate Create', path: '/corporates/create' },
{ title: 'Formularium', path: '/master/formularium-template-v2' },
{ title: 'Master ICD-10 Diagnosis', path: '/master/diagnosis-template' },
{ title: 'Master ICD-10 Diagnosis', path: '/master/diagnosis' },
{ title: 'Hospitals', path: '/hospitals' },
],
},

View File

@@ -75,7 +75,7 @@ export default function ClaimListRow ({ ...props }: Props) {
</MenuItem>
<MenuItem onClick={() => navigate(`/case_management/laboratorium_result/${props.row.member_id}/claims/${props.row.claim_code}/add_lab_result`)}>
<AddIcon />
Daily Monitoring
Laboratorium Result
</MenuItem>
</>
} />

View File

@@ -219,7 +219,7 @@ export default function DetailMonitoringList() {
<Grid item xs={12} md={12}>
<Box display="flex" justifyContent={'flex-end'}>
<Box display="flex" gap={1}>
<Button variant="outlined" color="inherit" onClick={() => navigate(`/case_management/daily_monitoring/${member_id}/claims`)}>
<Button variant="outlined" color="inherit" onClick={() => navigate(`/case_management/laboratorium_result/${member_id}/claims`)}>
Cancel
</Button>
<LoadingButton disabled={!isDirty} type="submit" variant="contained" loading={isSubmitting}>