File: /mnt/data/ghayatcom/ghayatcom-api/app/Http/Controllers/Api/FhirController.php
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use DCarbone\PHPFHIRGenerated\R4\FHIRResource\FHIRDomainResource\FHIRPatient;
use DCarbone\PHPFHIRGenerated\R4\FHIRElement\FHIRString;
use App\User;
use App\Appointment;
use App\HealthProfileMeasurePatient;
use Carbon\Carbon;
use App\Services\FhirService;
use Illuminate\Database\QueryException;
use Validator;
use Exception;
use Throwable;
class FhirController extends Controller
{
protected $baseUrl;
protected $fhirService;
public function __construct(FhirService $fhirService)
{
$this->fhirService = $fhirService;
}
public function index(Request $request)
{
$searchParams = $request->only(['name', 'birthdate', 'gender', 'identifier']);
$fhirResponse = $this->fhirService->searchResource('Patient', $searchParams);
if (!$fhirResponse) {
return response()->json(['error' => 'Failed to fetch patients'], 500);
}
// $patients = [];
// foreach ($fhirResponse['entry'] ?? [] as $entry) {
// $patients[] = FhirPatient::fromFhir($entry['resource']);
// }
return response()->json($fhirResponse);
}
public function show($id)
{
$fhirResponse = $this->fhirService->getResource('Patient', $id);
if (!$fhirResponse) {
return response()->json(['error' => 'Patient not found'], 404);
}
$patient = FhirPatient::fromFhir($fhirResponse);
return response()->json($patient);
}
public function store(Request $request)
{
// $validated = $this->validatePatient($request);
$appointment = Appointment::with(['patientDetails', 'diagnosisDetails', 'prescriptions.prescriptionDetails'])->find(765);
$healthProfile = HealthProfileMeasurePatient::with(['health_profile_master'])->where('patient_id', $appointment->patient_id)->latest()->first();
return $fhirPatientResponse = $this->fhirService->getPatientEverything('51aa6b20-d3e9-4e07-a0fd-8879d38777d3');
// echo "<pre>";
print_r($fhirPatientResponse);die();
$user = User::findOrFail($appointment->patient_id);
$patient = $this->fhirService->generatePatient($user);
$fhirPatientResponse = $this->fhirService->createResource('Patient', $patient);
if (!$fhirPatientResponse) {
return response()->json(['error' => 'Failed to create patient'], 500);
}
$response = [
'patient' => $fhirPatientResponse,
];
// echo "<pre>";
// print_r($fhirPatientResponse['id']);die();
if(!empty($appointment)) {
$allergyRequest = $this->fhirService->generateAllergy($fhirPatientResponse['id'], $appointment);
$fhirAllergyResponse = $this->fhirService->createResource('AllergyIntolerance', $allergyRequest);
if (!$fhirAllergyResponse) {
return response()->json(['error' => 'Failed to create allergy'], 500);
}
array_push($response, ['allergy' => $fhirAllergyResponse]);
}
if(!empty($appointment)) {
$procedureRequest = $this->fhirService->generateProcedure($fhirPatientResponse['id'], $appointment);
$fhirProcedureResponse = $this->fhirService->createResource('Procedure', $procedureRequest);
if (!$fhirProcedureResponse) {
return response()->json(['error' => 'Failed to create procedure'], 500);
}
array_push($response, ['procedure' => $fhirProcedureResponse]);
}
if(!empty($appointment->diagnosisDetails)) {
$condition = $this->fhirService->generateCondition($fhirPatientResponse['id'], $appointment->diagnosisDetails->name);
$fhirConditionResponse = $this->fhirService->createResource('Condition', $condition);
if (!$fhirConditionResponse) {
return response()->json(['error' => 'Failed to create condition'], 500);
}
array_push($response, ['condition' => $fhirConditionResponse]);
}
if(!empty($appointment->prescriptions)) {
$pres = [];
$medicationRequestId = $patientId;
foreach($appointment->prescriptions as $data) {
$presText = $data->prescriptionDetails->product_name.' medicine '.$data->prescriptionDetails->frequency.' ('.$data->prescriptionDetails->timing.') upto '.$data->prescriptionDetails->duration.' days';
array_push($pres, $presText);
}
$prescriptions = implode(', ', $pres);
$medicationRequest = $this->fhirService->generateMedicationRequest($fhirPatientResponse['id'], $prescriptions);
$fhirMedicationResponse = $this->fhirService->createResource('MedicationRequest', $medicationRequest);
if (!$fhirMedicationResponse) {
return response()->json(['error' => 'Failed to create medication'], 500);
}
array_push($response, ['prescription' => $fhirMedicationResponse]);
}
// if(!empty($healthProfile)) {
// $observationRequest = $this->fhirService->generateObservation($fhirPatientResponse['id'], $healthProfile);
// $fhirObservationResponse = $this->fhirService->createResource('Observation', $observationRequest);
// if (!$fhirObservationResponse) {
// return response()->json(['error' => 'Failed to create observation'], 500);
// }
// array_push($response, ['observation' => $fhirObservationResponse]);
// }
return response()->json($response, 201);
}
public function update(Request $request, $id)
{
$validated = $this->validatePatient($request);
$fhirResponse = $this->fhirService->updateResource('Patient', $id, $validated);
if (!$fhirResponse) {
return response()->json(['error' => 'Failed to update patient'], 500);
}
$patient = FhirPatient::updateOrCreate(
['fhir_id' => $id],
FhirPatient::fromFhir($fhirResponse)->toArray()
);
return response()->json($patient);
}
public function destroy($id)
{
$success = $this->fhirService->deleteResource('Patient', $id);
if (!$success) {
return response()->json(['error' => 'Failed to delete patient'], 500);
}
FhirPatient::where('fhir_id', $id)->delete();
return response()->json(null, 204);
}
public function everything($patientId)
{
$fhirResponse = $this->fhirService->getPatientEverything($patientId);
if (!$fhirResponse) {
return response()->json(['error' => 'Failed to fetch patient data'], 500);
}
return response()->json($fhirResponse);
}
protected function validatePatient(Request $request)
{
return $request->validate([
'active' => 'boolean',
'name' => 'required|array',
'name.*.given' => 'required|array',
'name.*.family' => 'required|string',
'gender' => 'required|in:male,female,other,unknown',
'birthDate' => 'required|date',
'telecom' => 'array',
'telecom.*.system' => 'required|in:phone,email,url',
'telecom.*.value' => 'required|string',
'address' => 'array',
'address.*.line' => 'array',
'address.*.city' => 'string',
'address.*.state' => 'string',
'address.*.postalCode' => 'string',
'address.*.country' => 'string',
]);
}
public function createPatient(Request $request)
{
try {
$user = User::findOrFail($request->patient_id);
if(!empty($user->fhir_id)) {
$fhirPatientResponse = $this->fhirService->getResource('Patient', $user->fhir_id);
} else {
$patient = $this->fhirService->generatePatient($user);
$fhirPatientResponse = $this->fhirService->createResource('Patient', $patient);
if (!$fhirPatientResponse) {
return self::sentResponse(500, [], 'Failed to create patient');
}
$user->fhir_id = $fhirPatientResponse['id'];
$user->save();
}
return self::sentResponse(200, ['patient' => $fhirPatientResponse], __('digimed_validation.success_response.data_store_success'));
} catch(Exception | Throwable | QueryException $e) {
return self::sentResponse(500, [], $e->getMessage());
}
}
public function createObservation(Request $request)
{
try {
$user = User::findOrFail($request->patient_id);
if(!empty($user->fhir_id)) {
$observation = $this->fhirService->generateObservation($user->fhir_id, $request->observation);
$fhirObservationResponse = $this->fhirService->createResource('Observation', $observation);
if (!$fhirObservationResponse) {
return response()->json(['error' => 'Failed to create observation'], 500);
}
return self::sentResponse(200, ['observation' => $fhirObservationResponse], __('digimed_validation.success_response.data_store_success'));
} else {
return self::sentResponse(500, [], 'FHIR ID is not Found!');
}
} catch(Exception | Throwable | QueryException $e) {
return self::sentResponse(500, [], $e->getMessage());
}
}
public function createCondition(Request $request)
{
try {
$user = User::findOrFail($request->patient_id);
if(!empty($user->fhir_id)) {
$condition = $this->fhirService->generateCondition($user->fhir_id, $request->condition);
$fhirConditionResponse = $this->fhirService->createResource('Condition', $condition);
if (!$fhirConditionResponse) {
return response()->json(['error' => 'Failed to create condition'], 500);
}
return self::sentResponse(200, ['condition' => $fhirConditionResponse], __('digimed_validation.success_response.data_store_success'));
} else {
return self::sentResponse(500, [], 'FHIR ID is not Found!');
}
} catch(Exception | Throwable | QueryException $e) {
return self::sentResponse(500, [], $e->getMessage());
}
}
public function createMedication(Request $request)
{
try {
$user = User::findOrFail($request->patient_id);
if(!empty($user->fhir_id)) {
$medication = $this->fhirService->generateMedicationRequest($user->fhir_id, $request->medication);
$fhirMedicationResponse = $this->fhirService->createResource('MedicationRequest', $medication);
if (!$fhirMedicationResponse) {
return response()->json(['error' => 'Failed to create medication'], 500);
}
return self::sentResponse(200, ['medication' => $fhirMedicationResponse], __('digimed_validation.success_response.data_store_success'));
} else {
return self::sentResponse(500, [], 'FHIR ID is not Found!');
}
} catch(Exception | Throwable | QueryException $e) {
return self::sentResponse(500, [], $e->getMessage());
}
}
public function createProcedure(Request $request)
{
try {
$user = User::findOrFail($request->patient_id);
if(!empty($user->fhir_id)) {
$procedure = $this->fhirService->generateProcedure($user->fhir_id, $request->procedure);
$fhirProcedureResponse = $this->fhirService->createResource('Procedure', $procedure);
if (!$fhirProcedureResponse) {
return response()->json(['error' => 'Failed to create procedure'], 500);
}
return self::sentResponse(200, ['procedure' => $fhirProcedureResponse], __('digimed_validation.success_response.data_store_success'));
} else {
return self::sentResponse(500, [], 'FHIR ID is not Found!');
}
} catch(Exception | Throwable | QueryException $e) {
return self::sentResponse(500, [], $e->getMessage());
}
}
public function createAllergy(Request $request)
{
try {
$user = User::findOrFail($request->patient_id);
if(!empty($user->fhir_id)) {
$allergy = $this->fhirService->generateAllergy($user->fhir_id, $request->allergy);
$fhirAllergyResponse = $this->fhirService->createResource('AllergyIntolerance', $allergy);
if (!$fhirAllergyResponse) {
return response()->json(['error' => 'Failed to create allergy'], 500);
}
return self::sentResponse(200, ['allergy' => $fhirAllergyResponse], __('digimed_validation.success_response.data_store_success'));
} else {
return self::sentResponse(500, [], 'FHIR ID is not Found!');
}
} catch(Exception | Throwable | QueryException $e) {
return self::sentResponse(500, [], $e->getMessage());
}
}
}
// public function __construct()
// {
// $this->baseUrl = 'https://hapi.fhir.org/baseR4/';
// }
// public function create(Request $request)
// {
// // // Create a new Patient resource
// // $patient = new FHIRPatient($patient = [
// // 'resourceType' => 'Patient',
// // 'name' => [[
// // 'use' => 'official',
// // 'family' => 'kumar',
// // 'given' => ['Naveen']
// // ]],
// // 'gender' => 'male',
// // 'birthDate' => '1999-01-01'
// // ]);
// // // Serialize to JSON
// // $payload = json_encode($patient->jsonSerialize(), JSON_PRETTY_PRINT);
// // $response = Http::withHeaders([
// // 'Content-Type' => 'application/fhir+json',
// // 'Accept' => 'application/fhir+json',
// // ])
// // ->withBody($payload, 'application/fhir+json')
// // ->post($this->baseUrl.'Patient');
// $appointment = Appointment::with(['patientDetails', 'diagnosisDetails', 'prescriptions.prescriptionDetails'])->find(765);
// echo "<pre>";
// // print_r($appointment->prescriptions);
// // die();
// // Example IDs for local reference inside the bundle
// $patientId = 'patient-'.$appointment->patientDetails->id;
// $entry = [];
// $patient = [
// 'fullUrl' => "urn:uuid:$patientId",
// 'resource' => [
// 'resourceType' => 'Patient',
// 'id' => $patientId,
// 'name' => [[
// 'family' => $appointment->patientDetails->last_name,
// 'given' => [$appointment->patientDetails->first_name]
// ]],
// 'gender' => !empty($appointment->patientDetails->gender) ? strtolower($appointment->patientDetails->gender) : 'male',
// 'birthDate' => !empty($appointment->patientDetails->dob) ? $appointment->patientDetails->dob : '1980-01-01'
// ],
// 'request' => [
// 'method' => 'POST',
// 'url' => 'Patient'
// ]
// ];
// array_push($entry, $patient);
// if(!empty($appointment->diagnosisDetails)) {
// $conditionId = 'condition-'.$appointment->diagnosisDetails->id;
// $diagnosis = [
// 'fullUrl' => "urn:uuid:$conditionId",
// 'resource' => [
// 'resourceType' => 'Condition',
// 'subject' => [
// 'reference' => "urn:uuid:$patientId"
// ],
// 'code' => [
// 'text' => $appointment->diagnosisDetails->name
// ],
// 'clinicalStatus' => [
// 'coding' => [[
// 'system' => 'http://terminology.hl7.org/CodeSystem/condition-clinical',
// 'code' => 'active'
// ]]
// ],
// 'verificationStatus' => [
// 'coding' => [[
// 'system' => 'http://terminology.hl7.org/CodeSystem/condition-ver-status',
// 'code' => 'confirmed'
// ]]
// ]
// ],
// 'request' => [
// 'method' => 'POST',
// 'url' => 'Condition'
// ]
// ];
// array_push($entry, $diagnosis);
// }
// if(!empty($appointment->prescriptions)) {
// $pres = [];
// $medicationRequestId = $appointment->id;
// foreach($appointment->prescriptions as $data) {
// $presText = $data->prescriptionDetails->product_name.' medicine '.$data->prescriptionDetails->frequency.' ('.$data->prescriptionDetails->timing.') upto '.$data->prescriptionDetails->duration.' days';
// array_push($pres, $presText);
// }
// if(!empty($pres)) {
// $prescription = [
// 'fullUrl' => "urn:uuid:$medicationRequestId",
// 'resource' => [
// 'resourceType' => 'MedicationRequest',
// 'subject' => [
// 'reference' => "urn:uuid:$patientId"
// ],
// 'medicationCodeableConcept' => [
// 'text' => implode(', ', $pres)
// ],
// 'dosageInstruction' => [[
// 'text' => implode(', ', $pres)
// ]],
// 'intent' => 'order',
// 'status' => 'active'
// ],
// 'request' => [
// 'method' => 'POST',
// 'url' => 'MedicationRequest'
// ]
// ];
// array_push($entry, $prescription);
// }
// }
// print_r($entry);
// // die();
// // Build FHIR Bundle
// $bundle = [
// 'resourceType' => 'Bundle',
// 'type' => 'transaction',
// 'entry' => [
// // Patient Resource
// $patient,
// // Condition (Diagnosis)
// $diagnosis,
// // AllergyIntolerance
// [
// 'resource' => [
// 'resourceType' => 'AllergyIntolerance',
// 'patient' => [
// 'reference' => "urn:uuid:$patientId"
// ],
// 'code' => [
// 'text' => 'Peanut allergy'
// ],
// 'clinicalStatus' => [
// 'coding' => [[
// 'system' => 'http://terminology.hl7.org/CodeSystem/allergyintolerance-clinical',
// 'code' => 'active'
// ]]
// ],
// ],
// 'request' => [
// 'method' => 'POST',
// 'url' => 'AllergyIntolerance'
// ]
// ],
// // MedicationRequest (Prescription)
// $diagnosis,
// // Observation (Health Record — e.g., blood pressure)
// [
// 'resource' => [
// 'resourceType' => 'Observation',
// 'subject' => [
// 'reference' => "urn:uuid:$patientId"
// ],
// 'status' => 'final',
// 'code' => [
// 'text' => 'Blood Pressure'
// ],
// 'valueQuantity' => [
// 'value' => 140,
// 'unit' => 'mmHg'
// ]
// ],
// 'request' => [
// 'method' => 'POST',
// 'url' => 'Observation'
// ]
// ],
// // Procedure (Treatment — optional)
// [
// 'resource' => [
// 'resourceType' => 'Procedure',
// 'subject' => [
// 'reference' => "urn:uuid:$patientId"
// ],
// 'status' => 'completed',
// 'code' => [
// 'text' => 'Blood test'
// ],
// 'performedDateTime' => now()->toDateString()
// ],
// 'request' => [
// 'method' => 'POST',
// 'url' => 'Procedure'
// ]
// ],
// ]
// ];
// $response = Http::withHeaders([
// 'Content-Type' => 'application/fhir+json',
// 'Accept' => 'application/fhir+json',
// ])
// // ->withBody($payload, 'application/fhir+json')
// ->post($this->baseUrl, $bundle);
// return response($response->body(), $response->status())
// ->header('Content-Type', 'application/fhir+json');
// }
// public function update($patient_id)
// {
// //46914598
// $patientId = $patient_id;
// // Create a new Patient resource
// $patient = new FHIRPatient([
// 'id' => $patientId,
// 'name' => [[
// 'family' => 'Naveen',
// 'given' => ['Kumar']
// ]],
// 'gender' => 'male',
// 'birthDate' => '1999-05-01'
// ]);
// // Serialize to JSON
// $payload = json_encode($patient->jsonSerialize(), JSON_PRETTY_PRINT);
// $response = Http::withHeaders([
// 'Content-Type' => 'application/fhir+json',
// 'Accept' => 'application/fhir+json',
// ])
// ->withBody($payload, 'application/fhir+json')
// ->put($this->baseUrl.'Patient/'.$patientId);
// return response($response->body(), $response->status())
// ->header('Content-Type', 'application/fhir+json');
// }
// public function show($patient_id)
// {
// //46899288
// $patientId = $patient_id;
// // $response = Http::withHeaders([
// // 'Content-Type' => 'application/fhir+json',
// // 'Accept' => 'application/fhir+json',
// // ])
// // ->get($this->baseUrl.'Patient/'.$patientId);
// $response = Http::withHeaders([
// 'Accept' => 'application/fhir+json',
// ])->get($this->baseUrl . 'Patient?_id=' . $patientId .
// '&_revinclude=Condition:subject' .
// '&_revinclude=AllergyIntolerance:patient' .
// '&_revinclude=MedicationRequest:subject' .
// '&_revinclude=Observation:subject' .
// '&_revinclude=Procedure:subject');
// return response($response->body(), $response->status())
// ->header('Content-Type', 'application/fhir+json');
// }
// public function destroy($patient_id)
// {
// //46914598
// $patientId = $patient_id;
// $response = Http::delete($this->baseUrl.'Patient/'.$patientId);
// return response($response->body(), $response->status());
// }
// }
// // Build FHIR Bundle
// // $bundle = [
// // 'resourceType' => 'Bundle',
// // 'type' => 'transaction',
// // 'entry' => [
// // // Patient Resource
// // $patient,
// // // Condition (Diagnosis)
// // $diagnosis,
// // // AllergyIntolerance
// // [
// // 'resource' => [
// // 'resourceType' => 'AllergyIntolerance',
// // 'patient' => [
// // 'reference' => "urn:uuid:$patientId"
// // ],
// // 'code' => [
// // 'text' => 'Peanut allergy'
// // ],
// // 'clinicalStatus' => [
// // 'coding' => [[
// // 'system' => 'http://terminology.hl7.org/CodeSystem/allergyintolerance-clinical',
// // 'code' => 'active'
// // ]]
// // ],
// // ],
// // 'request' => [
// // 'method' => 'POST',
// // 'url' => 'AllergyIntolerance'
// // ]
// // ],
// // // MedicationRequest (Prescription)
// // $diagnosis,
// // // Observation (Health Record — e.g., blood pressure)
// // [
// // 'resource' => [
// // 'resourceType' => 'Observation',
// // 'subject' => [
// // 'reference' => "urn:uuid:$patientId"
// // ],
// // 'status' => 'final',
// // 'code' => [
// // 'text' => 'Blood Pressure'
// // ],
// // 'valueQuantity' => [
// // 'value' => 140,
// // 'unit' => 'mmHg'
// // ]
// // ],
// // 'request' => [
// // 'method' => 'POST',
// // 'url' => 'Observation'
// // ]
// // ],
// // // Procedure (Treatment — optional)
// // [
// // 'resource' => [
// // 'resourceType' => 'Procedure',
// // 'subject' => [
// // 'reference' => "urn:uuid:$patientId"
// // ],
// // 'status' => 'completed',
// // 'code' => [
// // 'text' => 'Blood test'
// // ],
// // 'performedDateTime' => now()->toDateString()
// // ],
// // 'request' => [
// // 'method' => 'POST',
// // 'url' => 'Procedure'
// // ]
// // ],
// // ]
// // ];