From 78c23af7e5e4c3985a587ba7831c4763124a34b2 Mon Sep 17 00:00:00 2001
From: DevSoftTech Server
Date: Sat, 30 May 2026 06:32:30 +0530
Subject: [PATCH] Checkpoint: pathology panel modal workflow, gateway component
search, and ABDM-style component/print editors
---
app/Commands/ExportLabTemplates.php | 34 +-
app/Commands/SyncPathologyLoinc.php | 403 ++
app/Config/Routes.php | 12 +
app/Controllers/AbdmGateway.php | 234 +-
app/Controllers/Setting/Template.php | 1463 ++++-
...0605_AddConsentIdsToAbdmConsentRecords.php | 75 +
...05-28-000606_AddLoincToPathologyTables.php | 160 +
.../Seeds/LabOemData/01_lab_rgroups.sql | 29 +-
app/Database/Seeds/LabOemData/03_lab_repo.sql | 4947 +----------------
.../Seeds/LabOemData/04_lab_tests.sql | 211 +-
.../Seeds/LabOemData/05_lab_tests_option.sql | 194 +-
.../Seeds/LabOemData/06_lab_repotests.sql | 334 +-
app/Libraries/Abdm/EAtriaBridgeConnector.php | 68 +-
app/Views/PathLab_Report/lab_report_edit.php | 484 +-
.../PathLab_Report/lab_report_item_edit.php | 595 +-
app/Views/PathLab_Report/lab_report_list.php | 1313 ++++-
.../PathLab_Report/lab_report_test_list.php | 530 +-
app/Views/PathLab_Report/loinc_panel.php | 231 +
app/Views/Setting/Template/index.php | 2 +-
app/Views/abdm/task_board.php | 16 +-
app/Views/welcome_message.php | 248 +-
21 files changed, 5424 insertions(+), 6159 deletions(-)
create mode 100644 app/Commands/SyncPathologyLoinc.php
create mode 100644 app/Database/Migrations/2026-05-27-000605_AddConsentIdsToAbdmConsentRecords.php
create mode 100644 app/Database/Migrations/2026-05-28-000606_AddLoincToPathologyTables.php
create mode 100644 app/Views/PathLab_Report/loinc_panel.php
diff --git a/app/Commands/ExportLabTemplates.php b/app/Commands/ExportLabTemplates.php
index 958c945..7aa8942 100644
--- a/app/Commands/ExportLabTemplates.php
+++ b/app/Commands/ExportLabTemplates.php
@@ -65,11 +65,28 @@ class ExportLabTemplates extends BaseCommand
orderBy: 'id ASC',
);
+ // Include loinc_code only if the column exists (migration may not have run on all environments)
+ $repoFields = $this->db->getFieldNames('lab_repo') ?? [];
+ $testFields = $this->db->getFieldNames('lab_tests') ?? [];
+
+ $labRepoCols = ['mstRepoKey', 'Title', 'RTFData', 'HTMLData', 'GrpKey',
+ 'IncludeHeader', 'IncludeFooter', 'charge_id'];
+ if (in_array('loinc_code', $repoFields, true)) {
+ $labRepoCols[] = 'loinc_code';
+ }
+
+ $labTestsCols = ['mstTestKey', 'Test', 'TestID', 'Result', 'Options', 'Formula',
+ 'VRule', 'VMsg', 'Unit', 'FixedNormals', 'isGenderSpecific', 'FixedNormalsWomen'];
+ foreach (['loinc_code', 'loinc_property', 'loinc_system', 'loinc_scale'] as $col) {
+ if (in_array($col, $testFields, true)) {
+ $labTestsCols[] = $col;
+ }
+ }
+
$this->exportTable(
filename: '03_lab_repo.sql',
table: 'lab_repo',
- columns: ['mstRepoKey', 'Title', 'RTFData', 'HTMLData', 'GrpKey',
- 'IncludeHeader', 'IncludeFooter', 'charge_id'],
+ columns: $labRepoCols,
schema: $this->schemaLabRepo(),
orderBy: 'mstRepoKey ASC',
);
@@ -77,8 +94,7 @@ class ExportLabTemplates extends BaseCommand
$this->exportTable(
filename: '04_lab_tests.sql',
table: 'lab_tests',
- columns: ['mstTestKey', 'Test', 'TestID', 'Result', 'Options', 'Formula',
- 'VRule', 'VMsg', 'Unit', 'FixedNormals', 'isGenderSpecific', 'FixedNormalsWomen'],
+ columns: $labTestsCols,
schema: $this->schemaLabTests(),
orderBy: 'mstTestKey ASC',
);
@@ -244,6 +260,8 @@ CREATE TABLE IF NOT EXISTS `lab_repo` (
`IncludeHeader` tinyint(1) DEFAULT '1',
`IncludeFooter` tinyint(1) DEFAULT '1',
`charge_id` int DEFAULT '0',
+ `loinc_code` varchar(20) DEFAULT NULL,
+ `loinc_synced_at` datetime DEFAULT NULL,
PRIMARY KEY (`mstRepoKey`),
UNIQUE KEY `Title` (`Title`),
KEY `GrpKey` (`GrpKey`),
@@ -268,9 +286,15 @@ CREATE TABLE IF NOT EXISTS `lab_tests` (
`FixedNormals` varchar(30) NOT NULL DEFAULT '0',
`isGenderSpecific` int NOT NULL DEFAULT '0',
`FixedNormalsWomen` varchar(30) NOT NULL,
+ `loinc_code` varchar(20) DEFAULT NULL,
+ `loinc_property` varchar(50) DEFAULT NULL,
+ `loinc_system` varchar(50) DEFAULT NULL,
+ `loinc_scale` varchar(20) DEFAULT NULL,
+ `loinc_synced_at` datetime DEFAULT NULL,
PRIMARY KEY (`mstTestKey`),
UNIQUE KEY `TestID` (`TestID`),
- KEY `Test` (`Test`)
+ KEY `Test` (`Test`),
+ KEY `idx_lab_tests_loinc` (`loinc_code`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb3;
SQL;
}
diff --git a/app/Commands/SyncPathologyLoinc.php b/app/Commands/SyncPathologyLoinc.php
new file mode 100644
index 0000000..c34f001
--- /dev/null
+++ b/app/Commands/SyncPathologyLoinc.php
@@ -0,0 +1,403 @@
+ 'Print matches without updating the database.',
+ '--since' => 'ISO-8601 datetime for incremental sync (e.g. 2025-01-01T00:00:00Z).',
+ '--category' => 'Filter bridge masters by sub_category (PATHOLOGY|BIOPSY). Default: all.',
+ '--limit' => 'Items per API page request. Default: 200.',
+ ];
+
+ /** @var \CodeIgniter\Database\BaseConnection */
+ private $db;
+
+ /** @var bool */
+ private bool $dryRun = false;
+
+ /** @var int */
+ private int $masterMatched = 0;
+ private int $masterSkipped = 0;
+ private int $compMatched = 0;
+ private int $compSkipped = 0;
+
+ public function run(array $params): void
+ {
+ $this->dryRun = (bool) CLI::getOption('dry-run');
+ $since = (string) (CLI::getOption('since') ?? '');
+ $category = (string) (CLI::getOption('category') ?? '');
+ $limit = (int) (CLI::getOption('limit') ?? 200);
+
+ if ($limit <= 0) {
+ $limit = 200;
+ }
+
+ $this->db = \Config\Database::connect();
+
+ if ($this->dryRun) {
+ CLI::write('[DRY-RUN] No database changes will be made.', 'yellow');
+ }
+
+ CLI::write('=== Syncing Bridge Pathology LOINC Codes ===', 'cyan');
+
+ try {
+ $connector = new EAtriaBridgeConnector();
+ } catch (\Throwable $e) {
+ CLI::error('Failed to initialise Bridge connector: ' . $e->getMessage());
+
+ return;
+ }
+
+ // Load local tables once
+ $localRepos = $this->loadLocalRepos();
+ $localTests = $this->loadLocalTests();
+
+ CLI::write('Local lab_repo records : ' . count($localRepos));
+ CLI::write('Local lab_tests records: ' . count($localTests));
+ CLI::write('');
+
+ // --- Step 1: Fetch all panel masters and match to lab_repo ---
+ CLI::write('--- Phase 1: Panel Masters → lab_repo ---', 'yellow');
+ $masters = $this->fetchAllPages(
+ $connector,
+ 'masters',
+ ['category' => $category, 'since' => $since, 'limit' => $limit]
+ );
+ CLI::write('Bridge masters fetched: ' . count($masters));
+
+ // Build lookup: normalised name → master item
+ $masterByName = [];
+ foreach ($masters as $item) {
+ $key = $this->normalise((string) ($item['test_name'] ?? ''));
+ if ($key !== '') {
+ $masterByName[$key] = $item;
+ }
+ }
+
+ foreach ($localRepos as $repo) {
+ $this->matchAndUpdateRepo($repo, $masterByName);
+ }
+
+ CLI::write("Panel matches: {$this->masterMatched} | skipped (no match): {$this->masterSkipped}");
+ CLI::write('');
+
+ // --- Step 2: For each matched panel, fetch components → lab_tests ---
+ CLI::write('--- Phase 2: Components → lab_tests ---', 'yellow');
+
+ // Group local tests by repo id for fast lookup
+ $testsByRepo = [];
+ foreach ($localTests as $test) {
+ $rid = (int) ($test['mstRepoKey'] ?? 0);
+ $testsByRepo[$rid][] = $test;
+ }
+
+ foreach ($localRepos as $repo) {
+ $panelName = (string) ($repo['Title'] ?? '');
+ if ($panelName === '') {
+ continue;
+ }
+
+ $components = $this->fetchAllPages(
+ $connector,
+ 'components',
+ ['parent_test' => $panelName, 'since' => $since, 'limit' => $limit]
+ );
+
+ if (empty($components)) {
+ // Try with the bridge display_name if we synced one
+ $bridgeName = (string) ($repo['_bridge_test_name'] ?? '');
+ if ($bridgeName !== '' && $bridgeName !== $panelName) {
+ $components = $this->fetchAllPages(
+ $connector,
+ 'components',
+ ['parent_test' => $bridgeName, 'since' => $since, 'limit' => $limit]
+ );
+ }
+ }
+
+ if (empty($components)) {
+ continue;
+ }
+
+ $repoTests = $testsByRepo[(int) $repo['mstRepoKey']] ?? [];
+ if (empty($repoTests)) {
+ continue;
+ }
+
+ // Build lookup by normalised component name
+ $compByName = [];
+ foreach ($components as $comp) {
+ $key = $this->normalise((string) ($comp['component_test_name'] ?? ''));
+ if ($key !== '') {
+ $compByName[$key] = $comp;
+ }
+ }
+
+ foreach ($repoTests as $test) {
+ $this->matchAndUpdateTest($test, $compByName);
+ }
+ }
+
+ CLI::write("Component matches: {$this->compMatched} | skipped (no match): {$this->compSkipped}");
+ CLI::write('');
+ CLI::write('Done.', 'green');
+ }
+
+ // -------------------------------------------------------------------------
+ // Match + Update helpers
+ // -------------------------------------------------------------------------
+
+ /** @param array $repo */
+ private function matchAndUpdateRepo(array $repo, array $masterByName): void
+ {
+ $title = (string) ($repo['Title'] ?? '');
+ if ($title === '') {
+ return;
+ }
+
+ $key = $this->normalise($title);
+ $item = $masterByName[$key] ?? null;
+
+ // Fuzzy fallback: try partial word match
+ if ($item === null) {
+ $item = $this->fuzzyMatch($title, $masterByName);
+ }
+
+ if ($item === null) {
+ $this->masterSkipped++;
+
+ return;
+ }
+
+ $loincCode = (string) ($item['code'] ?? '');
+ $bridgeTestName = (string) ($item['test_name'] ?? '');
+
+ // Stash bridge name so phase 2 can reuse it
+ $repo['_bridge_test_name'] = $bridgeTestName;
+
+ if ($this->dryRun) {
+ CLI::write(" [DRY] lab_repo #{$repo['mstRepoKey']} '{$title}' → LOINC: {$loincCode} (bridge: '{$bridgeTestName}')");
+ } else {
+ $this->db->table('lab_repo')->where('mstRepoKey', $repo['mstRepoKey'])->update([
+ 'loinc_code' => $loincCode,
+ 'loinc_synced_at' => date('Y-m-d H:i:s'),
+ ]);
+ }
+
+ $this->masterMatched++;
+ }
+
+ /** @param array $test */
+ private function matchAndUpdateTest(array $test, array $compByName): void
+ {
+ $testName = (string) ($test['Test'] ?? '');
+ if ($testName === '') {
+ return;
+ }
+
+ $key = $this->normalise($testName);
+ $comp = $compByName[$key] ?? null;
+
+ if ($comp === null) {
+ $comp = $this->fuzzyMatch($testName, $compByName);
+ }
+
+ if ($comp === null) {
+ $this->compSkipped++;
+
+ return;
+ }
+
+ $loincCode = (string) ($comp['component_code'] ?? '');
+ $loincProperty = (string) ($comp['component_property'] ?? '');
+ $loincSystem = (string) ($comp['component_system'] ?? '');
+ $loincScale = (string) ($comp['component_scale'] ?? '');
+
+ if ($this->dryRun) {
+ CLI::write(
+ " [DRY] lab_tests #{$test['mstTestKey']} '{$testName}' → " .
+ "LOINC: {$loincCode} | prop: {$loincProperty} | sys: {$loincSystem} | scale: {$loincScale}"
+ );
+ } else {
+ $this->db->table('lab_tests')->where('mstTestKey', $test['mstTestKey'])->update([
+ 'loinc_code' => $loincCode,
+ 'loinc_property' => $loincProperty,
+ 'loinc_system' => $loincSystem,
+ 'loinc_scale' => $loincScale,
+ 'loinc_synced_at' => date('Y-m-d H:i:s'),
+ ]);
+ }
+
+ $this->compMatched++;
+ }
+
+ // -------------------------------------------------------------------------
+ // API pagination
+ // -------------------------------------------------------------------------
+
+ /**
+ * Fetch all pages from the Bridge API for either 'masters' or 'components'.
+ *
+ * @param array $opts
+ * @return array>
+ */
+ private function fetchAllPages(EAtriaBridgeConnector $connector, string $type, array $opts): array
+ {
+ $limit = (int) ($opts['limit'] ?? 200);
+ $since = (string) ($opts['since'] ?? '');
+ $all = [];
+ $offset = 0;
+
+ do {
+ try {
+ if ($type === 'masters') {
+ $resp = $connector->pathologyMasters(
+ (string) ($opts['category'] ?? ''),
+ $limit,
+ $offset,
+ $since
+ );
+ } else {
+ $resp = $connector->pathologyComponents(
+ (string) ($opts['parent_test'] ?? ''),
+ $limit,
+ $offset,
+ $since
+ );
+ }
+ } catch (\Throwable $e) {
+ CLI::error("API error ({$type}, offset={$offset}): " . $e->getMessage());
+ break;
+ }
+
+ if (! empty($resp['error']) || (isset($resp['success']) && $resp['success'] === false)) {
+ CLI::write(' API error response: ' . json_encode($resp), 'red');
+ break;
+ }
+
+ $items = $resp['items'] ?? $resp['data'] ?? [];
+ if (! is_array($items) || $items === []) {
+ break;
+ }
+
+ $all = array_merge($all, $items);
+ $offset += count($items);
+
+ // If fewer items returned than limit, we've reached the end
+ if (count($items) < $limit) {
+ break;
+ }
+ } while (true);
+
+ return $all;
+ }
+
+ // -------------------------------------------------------------------------
+ // Local DB loaders
+ // -------------------------------------------------------------------------
+
+ /** @return array> */
+ private function loadLocalRepos(): array
+ {
+ return $this->db->table('lab_repo')
+ ->select('mstRepoKey, Title, loinc_code')
+ ->get()
+ ->getResultArray();
+ }
+
+ /** @return array> */
+ private function loadLocalTests(): array
+ {
+ // Join via lab_repotests to know which repo each test belongs to.
+ // A test may appear in multiple repos; we update it once (last-wins is fine).
+ return $this->db->table('lab_tests lt')
+ ->select('lt.mstTestKey, lt.Test, lt.loinc_code, lrt.mstRepoKey')
+ ->join('lab_repotests lrt', 'lrt.mstTestKey = lt.mstTestKey', 'left')
+ ->get()
+ ->getResultArray();
+ }
+
+ // -------------------------------------------------------------------------
+ // Name matching helpers
+ // -------------------------------------------------------------------------
+
+ private function normalise(string $name): string
+ {
+ $name = strtolower($name);
+ // Remove parenthetical suffixes like "(CBC)" or "[Panel]"
+ $name = preg_replace('/[\(\[\{][^\)\]\}]*[\)\]\}]/', '', $name);
+ // Strip punctuation except hyphen
+ $name = preg_replace('/[^a-z0-9\- ]/', '', $name);
+ // Collapse multiple spaces
+ $name = preg_replace('/\s+/', ' ', $name);
+
+ return trim($name);
+ }
+
+ /**
+ * Fuzzy match: find the entry in $candidates whose normalised key shares
+ * the highest proportion of words with the $name.
+ *
+ * @param array> $candidates [normalisedKey => item]
+ * @return array|null
+ */
+ private function fuzzyMatch(string $name, array $candidates): ?array
+ {
+ $words = array_filter(explode(' ', $this->normalise($name)));
+ if (empty($words)) {
+ return null;
+ }
+
+ $best = null;
+ $bestScore = 0.0;
+
+ foreach ($candidates as $key => $item) {
+ $keyWords = array_filter(explode(' ', $key));
+ if (empty($keyWords)) {
+ continue;
+ }
+
+ $common = count(array_intersect($words, $keyWords));
+ $total = count(array_unique(array_merge($words, $keyWords)));
+ $score = $total > 0 ? $common / $total : 0.0;
+
+ if ($score > $bestScore) {
+ $bestScore = $score;
+ $best = $item;
+ }
+ }
+
+ // Require at least 50% Jaccard similarity
+ return $bestScore >= 0.5 ? $best : null;
+ }
+}
diff --git a/app/Config/Routes.php b/app/Config/Routes.php
index e6cad84..0e1ffdf 100644
--- a/app/Config/Routes.php
+++ b/app/Config/Routes.php
@@ -825,12 +825,24 @@ $routes->get('Lab_Admin/print_pdf_create/(:num)/(:num)/(:num)', 'Diagnosis::prin
$routes->get('Lab_Admin/print_pdf_create/(:num)/(:num)/(:num)/(:num)', 'Diagnosis::printPdfCreate/$1/$2/$3/$4');
$routes->post('Lab_Admin/report_update', 'Setting\Template::report_update');
$routes->post('Lab_Admin/report_insert', 'Setting\Template::report_insert');
+$routes->post('Lab_Admin/report_delete/(:num)', 'Setting\Template::report_delete/$1');
$routes->post('Lab_Admin/report_ultrasound_insert/(:num)', 'Setting\Template::report_ultrasound_insert/$1');
$routes->post('Lab_Admin/report_ultrasound_update/(:num)', 'Setting\Template::report_ultrasound_update/$1');
$routes->post('Lab_Admin/add_test_repo/(:num)/(:num)', 'Setting\Template::add_test_repo/$1/$2');
$routes->post('Lab_Admin/remove_test_item/(:num)/(:num)', 'Setting\Template::remove_test_item/$1/$2');
$routes->post('Lab_Admin/test_item_search', 'Setting\Template::test_item_search');
+// LOINC Mapping Admin
+$routes->get('Lab_Admin/loinc_panel', 'Setting\Template::loincPanel');
+$routes->post('Lab_Admin/loinc_sync', 'Setting\Template::loincSync');
+$routes->post('Lab_Admin/loinc_update', 'Setting\Template::loincUpdate');
+$routes->get('Lab_Admin/pathology_masters_search', 'Setting\Template::pathologyMastersSearch');
+$routes->get('Lab_Admin/pathology_component_masters_search', 'Setting\Template::pathologyComponentMastersSearch');
+$routes->get('Lab_Admin/pathology_master_template', 'Setting\Template::pathologyMasterTemplate');
+$routes->post('Lab_Admin/pathology_master_apply_panel', 'Setting\Template::pathologyMasterApplyPanel');
+$routes->post('Lab_Admin/pathology_master_add_component', 'Setting\Template::pathologyMasterAddComponent');
+$routes->get('Lab_Admin/pathology_bridge_debug', 'Setting\Template::pathologyBridgeDebug');
+
$routes->match(['get', 'post'], 'setting/template/discharge_templates', 'Setting\Template::discharge_templates');
$routes->get('setting/template/discharge_templates/delete/(:num)', 'Setting\Template::discharge_template_delete/$1');
$routes->match(['get', 'post'], 'setting/template/ipd_document_templates', 'Setting\Template::ipd_document_templates');
diff --git a/app/Controllers/AbdmGateway.php b/app/Controllers/AbdmGateway.php
index a00f8d9..533a962 100644
--- a/app/Controllers/AbdmGateway.php
+++ b/app/Controllers/AbdmGateway.php
@@ -144,15 +144,39 @@ class AbdmGateway extends BaseController
]);
$queueId = null;
+ $gatewayConsentId = '';
try {
$result = $this->connector->requestConsent($patientId, $abhaId, $purposeCode, $expiresAt, $consentHandle, $rawPayload);
$queueId = $result['queue_id'] ?? null;
+ $gatewayConsentId = trim((string) ($result['gateway_consent_id'] ?? $result['consent_id'] ?? ''));
+
+ if ($gatewayConsentId !== '') {
+ $tableFields = $this->db->getFieldNames('abdm_consent_records') ?? [];
+ $updateData = [
+ 'updated_at' => Time::now('Asia/Kolkata')->toDateTimeString(),
+ ];
+
+ // Persist gateway consent id when a compatible column exists.
+ if (in_array('consent_id', $tableFields, true)) {
+ $updateData['consent_id'] = $gatewayConsentId;
+ } elseif (in_array('gateway_consent_id', $tableFields, true)) {
+ $updateData['gateway_consent_id'] = $gatewayConsentId;
+ }
+
+ $rawPayload['gateway_consent_id'] = $gatewayConsentId;
+ $updateData['raw_payload_json'] = (string) json_encode($rawPayload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
+
+ $this->db->table('abdm_consent_records')
+ ->where('consent_handle', $consentHandle)
+ ->update($updateData);
+ }
} catch (\Throwable $e) {
}
return $this->response->setJSON([
'ok' => 1,
'consent_handle' => $consentHandle,
+ 'gateway_consent_id' => $gatewayConsentId !== '' ? $gatewayConsentId : null,
'queue_id' => $queueId,
'status' => 'requested',
]);
@@ -177,6 +201,7 @@ class AbdmGateway extends BaseController
$handle = trim((string) $payload['consent_handle']);
$status = trim((string) ($payload['consent_status'] ?? 'approved'));
$expiresAt = trim((string) ($payload['expires_at'] ?? ''));
+ $incomingConsentId = trim((string) ($payload['consent_id'] ?? $payload['gateway_consent_id'] ?? ''));
$now = Time::now('Asia/Kolkata')->toDateTimeString();
$existing = $this->db->table('abdm_consent_records')
@@ -229,11 +254,25 @@ class AbdmGateway extends BaseController
'updated_at' => $now,
];
+ if ($incomingConsentId !== '') {
+ $tableFields = $this->db->getFieldNames('abdm_consent_records') ?? [];
+ if (in_array('consent_id', $tableFields, true)) {
+ $update['consent_id'] = $incomingConsentId;
+ } elseif (in_array('gateway_consent_id', $tableFields, true)) {
+ $update['gateway_consent_id'] = $incomingConsentId;
+ }
+ }
+
$this->db->table('abdm_consent_records')
->where('consent_handle', $handle)
->update($update);
- return $this->response->setJSON(['ok' => 1, 'consent_handle' => $handle, 'status' => $incomingStatus]);
+ return $this->response->setJSON([
+ 'ok' => 1,
+ 'consent_handle' => $handle,
+ 'status' => $incomingStatus,
+ 'gateway_consent_id' => $incomingConsentId !== '' ? $incomingConsentId : null,
+ ]);
}
public function scanShareLookup()
@@ -589,6 +628,7 @@ class AbdmGateway extends BaseController
'patient_id' => $patientId,
'abha_id' => $abhaId,
'consent_handle' => (string) ($consent['consent_handle'] ?? ''),
+ 'consent_id' => $this->resolveConsentExternalId($consent),
'bundle_type' => (string) ($bundleRow['bundle_type'] ?? 'MedicationRequestBundle'),
'bundle' => $bundle,
];
@@ -634,6 +674,7 @@ class AbdmGateway extends BaseController
'ok' => 1,
'queue_id' => $queueId,
'consent_handle' => (string) ($consent['consent_handle'] ?? ''),
+ 'gateway_consent_id' => $this->resolveConsentExternalId($consent) !== '' ? $this->resolveConsentExternalId($consent) : null,
'status' => 'queued',
]);
}
@@ -896,6 +937,22 @@ class AbdmGateway extends BaseController
'report_html' => trim((string) ($labReq->Report_Data ?? '')),
];
+ // ── Load LOINC code for the panel from lab_repo ───────────────────────
+ $labRepoRow = $this->db->table('lab_request lr')
+ ->select('lr.lab_repo_id, repo.loinc_code AS repo_loinc_code, repo.Title')
+ ->join('lab_repo repo', 'repo.mstRepoKey = lr.lab_repo_id', 'left')
+ ->where('lr.id', $labReqId)
+ ->get(1)
+ ->getRowArray() ?? [];
+
+ $repoLoincCode = trim((string) ($labRepoRow['repo_loinc_code'] ?? ''));
+ if ($repoLoincCode !== '') {
+ $diagnosticReport['loinc_code'] = $repoLoincCode;
+ }
+
+ // ── Build structured observations from lab_request_item + lab_tests ───
+ $observations = $this->buildLabObservations($labReqId, (string) ($labReq->status ?? '0'));
+
$organization = $hospitalProfile['name'] !== ''
? ['name' => $hospitalProfile['name'], 'hfr_id' => $hospitalProfile['hfr_id']]
: null;
@@ -907,7 +964,7 @@ class AbdmGateway extends BaseController
'period_start' => $reportedAt,
];
- $bundle = $fhir->buildLabReportBundle($patient, $diagnosticReport, [], null, $organization, $encounter);
+ $bundle = $fhir->buildLabReportBundle($patient, $diagnosticReport, $observations, null, $organization, $encounter);
$bundleJson = (string) json_encode($bundle, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
// ── Store health_record ───────────────────────────────────────────────
@@ -1990,6 +2047,142 @@ class AbdmGateway extends BaseController
};
}
+ /**
+ * Load lab_request_item rows for a lab request and build the structured
+ * observations array expected by FhirR4Builder::buildLabReportBundle().
+ *
+ * Each element contains:
+ * test_name, loinc_code, value_type (quantity|string), value,
+ * unit, ucum_code, ref_low, ref_high, interpretation, status
+ *
+ * @param int $labReqId lab_request.id
+ * @param string $status raw status from lab_request.status
+ * @return array>
+ */
+ private function buildLabObservations(int $labReqId, string $status): array
+ {
+ if (! $this->db->tableExists('lab_request_item') || ! $this->db->tableExists('lab_tests')) {
+ return [];
+ }
+
+ $rows = $this->db->table('lab_request_item lri')
+ ->select(
+ 'lri.lab_test_id, lri.lab_test_value, lri.lab_test_remark,' .
+ ' lt.Test, lt.Unit, lt.FixedNormals, lt.FixedNormalsWomen,' .
+ ' lt.loinc_code, lt.loinc_scale, lt.loinc_system, lt.loinc_property,' .
+ ' lt.isGenderSpecific'
+ )
+ ->join('lab_tests lt', 'lt.mstTestKey = lri.lab_test_id', 'left')
+ ->where('lri.lab_request_id', $labReqId)
+ ->orderBy('lri.id', 'ASC')
+ ->get()
+ ->getResultArray();
+
+ if (empty($rows)) {
+ return [];
+ }
+
+ $obsStatus = ($status == '1') ? 'final' : 'preliminary';
+ $observations = [];
+
+ foreach ($rows as $row) {
+ $rawValue = trim((string) ($row['lab_test_value'] ?? ''));
+ if ($rawValue === '' || strtolower($rawValue) === 'n/a') {
+ continue;
+ }
+
+ $testName = trim((string) ($row['Test'] ?? ''));
+ $loincCode = trim((string) ($row['loinc_code'] ?? ''));
+ $unit = trim((string) ($row['Unit'] ?? ''));
+ $scale = strtolower(trim((string) ($row['loinc_scale'] ?? '')));
+
+ // Determine value type: Quantitative = numeric value
+ $isNumeric = is_numeric($rawValue) && $scale !== 'nom' && $scale !== 'ord';
+ $valueType = $isNumeric ? 'quantity' : 'string';
+
+ // Parse reference range from "low-high" format (e.g. "12.00-16.00")
+ $refLow = $refHigh = '';
+ $normals = trim((string) ($row['FixedNormals'] ?? ''));
+ if ($normals !== '' && str_contains($normals, '-')) {
+ $parts = explode('-', $normals, 2);
+ if (count($parts) === 2 && is_numeric(trim($parts[0])) && is_numeric(trim($parts[1]))) {
+ $refLow = trim($parts[0]);
+ $refHigh = trim($parts[1]);
+ }
+ }
+
+ // Interpretation: H/L/N based on value vs reference range
+ $interpretation = 'N';
+ if ($isNumeric && $refLow !== '' && $refHigh !== '') {
+ $fVal = (float) $rawValue;
+ if ($fVal < (float) $refLow) {
+ $interpretation = 'L';
+ } elseif ($fVal > (float) $refHigh) {
+ $interpretation = 'H';
+ }
+ }
+
+ $obs = [
+ 'test_name' => $testName !== '' ? $testName : ('Test-' . $row['lab_test_id']),
+ 'loinc_code' => $loincCode,
+ 'value_type' => $valueType,
+ 'value' => $rawValue,
+ 'unit' => $unit,
+ 'ucum_code' => $this->unitToUcum($unit),
+ 'ref_low' => $refLow,
+ 'ref_high' => $refHigh,
+ 'interpretation' => $interpretation,
+ 'status' => $obsStatus,
+ ];
+
+ if ($row['lab_test_remark'] !== '' && $row['lab_test_remark'] !== null) {
+ $obs['remark'] = trim((string) $row['lab_test_remark']);
+ }
+
+ $observations[] = $obs;
+ }
+
+ return $observations;
+ }
+
+ /**
+ * Best-effort map of common lab units to UCUM codes.
+ * Returns the original unit string when no UCUM equivalent is known.
+ */
+ private function unitToUcum(string $unit): string
+ {
+ $unit = trim($unit);
+ if ($unit === '') {
+ return '';
+ }
+
+ $map = [
+ 'g/dl' => 'g/dL',
+ 'g/dL' => 'g/dL',
+ 'mg/dl' => 'mg/dL',
+ 'mg/dL' => 'mg/dL',
+ 'mg/l' => 'mg/L',
+ 'mmol/l' => 'mmol/L',
+ 'umol/l' => 'umol/L',
+ 'u/l' => 'U/L',
+ 'iu/l' => 'IU/L',
+ 'iu/ml' => 'IU/mL',
+ 'cells/cumm'=> '10*3/uL',
+ 'cells/mm3' => '10*3/uL',
+ '10^9/l' => '10*9/L',
+ '10^3/ul' => '10*3/uL',
+ 'fl' => 'fL',
+ 'pg' => 'pg',
+ '%' => '%',
+ 'sec' => 's',
+ 'min' => 'min',
+ 'mmhg' => 'mm[Hg]',
+ 'meq/l' => 'meq/L',
+ ];
+
+ return $map[strtolower($unit)] ?? $unit;
+ }
+
/**
* Returns a lazily-constructed AbdmAuditService instance.
*/
@@ -2024,21 +2217,52 @@ class AbdmGateway extends BaseController
}
$now = Time::now('Asia/Kolkata')->toDateTimeString();
+ $consentFields = $this->db->getFieldNames('abdm_consent_records') ?? [];
$builder = $this->db->table('abdm_consent_records')
->where('patient_id', $patientId)
->where('abha_id', $abhaId)
- ->where('status', 'GRANTED')
- ->where('expiry_date >=', $now);
+ ->whereIn('consent_status', ['approved', 'granted'])
+ ->groupStart()
+ ->where('expires_at IS NULL', null, false)
+ ->orWhere('expires_at >=', $now)
+ ->groupEnd();
if ($consentHandle !== '') {
- $builder->where('consent_handle', $consentHandle);
+ $builder->groupStart()->where('consent_handle', $consentHandle);
+ if (in_array('consent_id', $consentFields, true)) {
+ $builder->orWhere('consent_id', $consentHandle);
+ }
+ if (in_array('gateway_consent_id', $consentFields, true)) {
+ $builder->orWhere('gateway_consent_id', $consentHandle);
+ }
+ $builder->groupEnd();
}
$row = $builder->orderBy('id', 'DESC')->get(1)->getRowArray();
return ! empty($row) ? $row : null;
}
+ /**
+ * Pick the consent id expected by gateway: consent_id/gateway_consent_id fallback to consent_handle.
+ *
+ * @param array $consent
+ */
+ private function resolveConsentExternalId(array $consent): string
+ {
+ $consentId = trim((string) ($consent['consent_id'] ?? ''));
+ if ($consentId !== '') {
+ return $consentId;
+ }
+
+ $gatewayConsentId = trim((string) ($consent['gateway_consent_id'] ?? ''));
+ if ($gatewayConsentId !== '') {
+ return $gatewayConsentId;
+ }
+
+ return trim((string) ($consent['consent_handle'] ?? ''));
+ }
+
// =========================================================================
// M1 ABHA OTP Flows
// Calls EAtriaBridgeConnector synchronously — requires eatria_bridge connector.
diff --git a/app/Controllers/Setting/Template.php b/app/Controllers/Setting/Template.php
index 037a3bb..7a864eb 100644
--- a/app/Controllers/Setting/Template.php
+++ b/app/Controllers/Setting/Template.php
@@ -144,6 +144,211 @@ HTML;
return $this->requirePermission($permission);
}
+ private function resolveBridgeGatewayConfig(): array
+ {
+ $gwUrl = '';
+ $gwToken = '';
+ $hfrId = '';
+
+ if ($this->db->tableExists('hospital_setting')) {
+ $hsRows = $this->db->table('hospital_setting')
+ ->select('s_name, s_value')
+ ->whereIn('s_name', ['EATRIA_BRIDGE_URL', 'EATRIA_BRIDGE_TOKEN', 'ABDM_HFR_ID'])
+ ->get()
+ ->getResultArray();
+
+ foreach ($hsRows as $hsRow) {
+ $sName = (string) ($hsRow['s_name'] ?? '');
+ $sValue = trim((string) ($hsRow['s_value'] ?? ''));
+
+ if ($sName === 'EATRIA_BRIDGE_URL') {
+ $gwUrl = $sValue;
+ }
+ if ($sName === 'EATRIA_BRIDGE_TOKEN') {
+ $gwToken = $sValue;
+ }
+ if ($sName === 'ABDM_HFR_ID') {
+ $hfrId = $sValue;
+ }
+ }
+ }
+
+ return [
+ 'url' => rtrim($gwUrl !== '' ? $gwUrl : 'https://abdm-bridge.e-atria.in/api', '/'),
+ 'token' => $gwToken,
+ 'hfr_id' => $hfrId,
+ ];
+ }
+
+ private function bridgeGet(string $baseUrl, string $token, string $path, array $query = []): array
+ {
+ $base = rtrim($baseUrl, '/');
+ $normalizedPath = '/' . ltrim($path, '/');
+
+ $baseHasApiSuffix = (bool) preg_match('#/api$#i', $base);
+ $pathHasApiPrefix = str_starts_with($normalizedPath, '/api/');
+
+ // Support both config styles:
+ // 1) baseUrl = https://host/api + path=/v3/...
+ // 2) baseUrl = https://host + path=/api/v3/...
+ if ($baseHasApiSuffix && $pathHasApiPrefix) {
+ $normalizedPath = substr($normalizedPath, 4); // drop leading /api
+ if ($normalizedPath === '') {
+ $normalizedPath = '/';
+ }
+ } elseif (! $baseHasApiSuffix && ! $pathHasApiPrefix) {
+ $normalizedPath = '/api' . $normalizedPath;
+ }
+
+ $url = $base . $normalizedPath;
+ if (! empty($query)) {
+ $url .= '?' . http_build_query($query);
+ }
+
+ $ch = curl_init();
+ curl_setopt_array($ch, [
+ CURLOPT_URL => $url,
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_TIMEOUT => 20,
+ CURLOPT_SSL_VERIFYPEER => true,
+ CURLOPT_HTTPHEADER => [
+ 'Accept: application/json',
+ 'Authorization: Bearer ' . $token,
+ ],
+ ]);
+
+ $raw = (string) curl_exec($ch);
+ $httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
+ $curlErr = (string) curl_error($ch);
+ curl_close($ch);
+
+ $decoded = json_decode($raw, true);
+
+ return [
+ 'url' => $url,
+ 'http_code' => $httpCode,
+ 'curl_error' => $curlErr,
+ 'raw' => $raw,
+ 'json' => is_array($decoded) ? $decoded : [],
+ ];
+ }
+
+ private function escHtmlValue(string $value): string
+ {
+ return htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
+ }
+
+ private function buildPathologyMasterTemplateHtml(string $panelName, array $components): string
+ {
+ $safePanel = $this->escHtmlValue(trim($panelName) !== '' ? $panelName : 'Pathology Panel');
+
+ if (empty($components)) {
+ return '' . $safePanel . '
'
+ . 'No component rows returned from gateway master mapping.
';
+ }
+
+ $rows = '';
+ foreach ($components as $component) {
+ $componentName = $this->escHtmlValue((string) ($component['component_test_name'] ?? ''));
+ $componentCode = $this->escHtmlValue((string) ($component['component_code'] ?? ''));
+ $unit = $this->escHtmlValue((string) ($component['unit'] ?? ''));
+ $property = $this->escHtmlValue((string) ($component['component_property'] ?? ''));
+ $system = $this->escHtmlValue((string) ($component['component_system'] ?? ''));
+ $scale = $this->escHtmlValue((string) ($component['component_scale'] ?? ''));
+
+ $metaBits = [];
+ if ($componentCode !== '') {
+ $metaBits[] = 'LOINC ' . $componentCode;
+ }
+ if ($property !== '') {
+ $metaBits[] = $property;
+ }
+ if ($system !== '') {
+ $metaBits[] = $system;
+ }
+ if ($scale !== '') {
+ $metaBits[] = $scale;
+ }
+
+ $metaText = $this->escHtmlValue(implode(' | ', $metaBits));
+
+ $rows .= ''
+ . '' . ($componentName !== '' ? $componentName : ' ') . ' '
+ . ' '
+ . '' . ($unit !== '' ? $unit : ' ') . ' '
+ . ' '
+ . '' . ($metaText !== '' ? $metaText : ' ') . ' '
+ . ' ';
+ }
+
+ return '' . $safePanel . '
'
+ . ''
+ . ''
+ . ''
+ . 'Investigation '
+ . 'Result '
+ . 'Unit '
+ . 'Reference Range '
+ . 'Code / Property '
+ . ' '
+ . ' '
+ . '' . $rows . ' '
+ . '
';
+ }
+
+ private function normalizePanelTokenCode(string $raw, int $fallbackIndex = 0): string
+ {
+ $code = strtoupper(trim($raw));
+ $code = preg_replace('/[^A-Z0-9]/', '', $code) ?? '';
+
+ if ($code === '') {
+ $code = 'T' . max(1, $fallbackIndex);
+ }
+
+ if (strlen($code) > 24) {
+ $code = substr($code, 0, 24);
+ }
+
+ return $code;
+ }
+
+ private function buildPathologyPanelTokenTemplateHtml(string $panelName, array $tests): string
+ {
+ $safePanel = $this->escHtmlValue(trim($panelName) !== '' ? $panelName : 'Pathology Panel');
+
+ $rows = '';
+ foreach ($tests as $row) {
+ $name = $this->escHtmlValue((string) ($row['test_name'] ?? ''));
+ $tokenCode = $this->normalizePanelTokenCode((string) ($row['test_code'] ?? ''));
+ $token = '{' . $tokenCode . '}';
+ $unit = $this->escHtmlValue((string) ($row['unit'] ?? ''));
+
+ $rows .= ''
+ . '' . ($name !== '' ? $name : ' ') . ' '
+ . '' . $this->escHtmlValue($token) . ' '
+ . '' . ($unit !== '' ? $unit : ' ') . ' '
+ . ' '
+ . ' ';
+ }
+
+ if ($rows === '') {
+ $rows = 'No panel components available. ';
+ }
+
+ return '' . $safePanel . '
'
+ . ''
+ . ''
+ . ''
+ . 'Test Name '
+ . 'Result '
+ . 'Unit '
+ . 'Bio. Ref. Interval '
+ . ' '
+ . ' '
+ . '' . $rows . ' '
+ . '
';
+ }
+
public function index()
{
if ($resp = $this->requireAnyPermission(self::PERMISSIONS)) {
@@ -159,16 +364,60 @@ HTML;
return $resp;
}
- $sql = "select COALESCE(g.RepoGrp, 'Unassigned') as RepoGrp, r.Title, r.mstRepoKey
- from lab_repo r
- left join hc_items i on r.charge_id = i.id
- left join lab_rgroups g on r.GrpKey = g.mstRGrpKey
- where r.mstRepoKey > 0
- and (i.id is null or i.itype in (5,6))
- order by r.mstRepoKey asc";
+ $repoColumnsRows = $this->db->query('SHOW COLUMNS FROM lab_repo')->getResultArray();
+ $itemColumnsRows = $this->db->query('SHOW COLUMNS FROM hc_items')->getResultArray();
+ $repoColumns = array_column($repoColumnsRows, 'Field');
+ $itemColumns = array_column($itemColumnsRows, 'Field');
+
+ $updatedExpr = 'NULL';
+ foreach (['updated_at', 'modified_at', 'loinc_synced_at', 'created_at'] as $column) {
+ if (in_array($column, $repoColumns, true)) {
+ $updatedExpr = 'r.' . $column;
+ break;
+ }
+ }
+
+ $activeExpr = '1';
+ if (in_array('active', $repoColumns, true)) {
+ $activeExpr = 'CASE WHEN COALESCE(r.active,1)=1 THEN 1 ELSE 0 END';
+ } elseif (in_array('status', $repoColumns, true)) {
+ $activeExpr = 'CASE WHEN COALESCE(r.status,1)=1 THEN 1 ELSE 0 END';
+ } elseif (in_array('active', $itemColumns, true)) {
+ $activeExpr = 'CASE WHEN COALESCE(i.active,1)=1 THEN 1 ELSE 0 END';
+ }
+
+ $sql = "select r.mstRepoKey as panel_id,
+ COALESCE(r.Title, '') as panel_name,
+ 'PANEL' as panel_type,
+ COALESCE(g.RepoGrp, 'General') as test_type,
+ COALESCE(r.Title, '') as description,
+ COALESCE(x.items_count, 0) as items_count,
+ {$activeExpr} as is_active,
+ {$updatedExpr} as updated_on
+ from lab_repo r
+ left join hc_items i on r.charge_id = i.id
+ left join lab_rgroups g on r.GrpKey = g.mstRGrpKey
+ left join (
+ select mstRepoKey, count(*) as items_count
+ from lab_repotests
+ group by mstRepoKey
+ ) x on x.mstRepoKey = r.mstRepoKey
+ where r.mstRepoKey > 0
+ and (i.id is null or i.itype in (5,6))
+ order by r.mstRepoKey asc";
$query = $this->db->query($sql);
$data['labReport_master'] = $query->getResult();
+ $groupQuery = $this->db->query('select mstRGrpKey, RepoGrp from lab_rgroups order by RepoGrp asc');
+ $data['lab_rgroups'] = $groupQuery->getResult();
+
+ $chargeQuery = $this->db->query("select id, idesc, amount
+ from hc_items
+ where itype in (5,6)
+ and id not in (select charge_id from lab_repo where charge_id > 0)
+ order by idesc asc");
+ $data['charge_items'] = $chargeQuery->getResult();
+
return view('PathLab_Report/lab_report_list', $data);
}
@@ -192,13 +441,33 @@ HTML;
return $resp;
}
- $sql = "select j.id, r.mstRepoKey, t.mstTestKey, t.Test, t.TestID, t.Result, j.EOrder
+ $testColumnsRows = $this->db->query('SHOW COLUMNS FROM lab_tests')->getResultArray();
+ $testColumns = array_column($testColumnsRows, 'Field');
+ $codeExpr = in_array('loinc_code', $testColumns, true) ? 'COALESCE(t.loinc_code, "")' : '""';
+
+ $sql = "select j.id,
+ r.mstRepoKey,
+ COALESCE(r.Title, '') as panel_name,
+ t.mstTestKey,
+ t.Test,
+ COALESCE(t.TestID, '') as short_name,
+ {$codeExpr} as component_code,
+ t.Result,
+ j.EOrder
from lab_repo r join lab_repotests j join lab_tests t
on r.mstRepoKey=j.mstRepoKey and j.mstTestKey=t.mstTestKey
where r.mstRepoKey=" . (int) $repoId . " order by j.EOrder";
$query = $this->db->query($sql);
$data['lab_Rep_Item_List'] = $query->getResult();
$data['mstRepoKey'] = $repoId;
+ $data['panel_name'] = count($data['lab_Rep_Item_List']) > 0
+ ? (string) ($data['lab_Rep_Item_List'][0]->panel_name ?? '')
+ : '';
+
+ if ($data['panel_name'] === '') {
+ $nameRow = $this->db->table('lab_repo')->select('Title')->where('mstRepoKey', $repoId)->get()->getRow();
+ $data['panel_name'] = (string) ($nameRow->Title ?? '');
+ }
return view('PathLab_Report/lab_report_test_list', $data);
}
@@ -290,6 +559,12 @@ HTML;
$data['repo_id'] = $repoId;
+ // Pass LOINC code for pre-filling the field
+ $data['repo_loinc_code'] = '';
+ if (! empty($data['labReport_master'])) {
+ $data['repo_loinc_code'] = (string) ($data['labReport_master'][0]->loinc_code ?? '');
+ }
+
return view('PathLab_Report/lab_report_edit', $data);
}
@@ -348,11 +623,12 @@ HTML;
$pathLab = new PathLabModel();
$pathLab->updateReport([
- 'Title' => $inputReportName,
- 'GrpKey' => $groupId,
- 'charge_id' => $chargeId,
- 'HTMLData' => $htmlData,
- 'RTFData' => $htmlData,
+ 'Title' => $inputReportName,
+ 'GrpKey' => $groupId,
+ 'charge_id' => $chargeId,
+ 'HTMLData' => $htmlData,
+ 'RTFData' => $htmlData,
+ 'loinc_code' => trim((string) $this->request->getPost('loinc_code')),
], $repoId);
return $this->response->setJSON([
@@ -395,11 +671,12 @@ HTML;
$pathLab = new PathLabModel();
$insertId = $pathLab->insertReport([
- 'Title' => $inputReportName,
- 'GrpKey' => $groupId,
- 'charge_id' => $chargeId,
- 'HTMLData' => $htmlData,
- 'RTFData' => $htmlData,
+ 'Title' => $inputReportName,
+ 'GrpKey' => $groupId,
+ 'charge_id' => $chargeId,
+ 'HTMLData' => $htmlData,
+ 'RTFData' => $htmlData,
+ 'loinc_code' => trim((string) $this->request->getPost('loinc_code')),
]);
return $this->response->setJSON([
@@ -408,6 +685,44 @@ HTML;
]);
}
+ public function report_delete(int $repoId = 0)
+ {
+ if ($resp = $this->requirePermission('template.pathology')) {
+ return $resp;
+ }
+
+ if (! $this->request->isAJAX()) {
+ return $this->response->setStatusCode(400)->setJSON([
+ 'ok' => 0,
+ 'error' => 'Invalid request',
+ ]);
+ }
+
+ if ($repoId <= 0) {
+ return $this->response->setStatusCode(400)->setJSON([
+ 'ok' => 0,
+ 'error' => 'Invalid report ID',
+ ]);
+ }
+
+ $this->db->transStart();
+ $this->db->table('lab_repotests')->where('mstRepoKey', $repoId)->delete();
+ $this->db->table('lab_repo')->where('mstRepoKey', $repoId)->delete();
+ $this->db->transComplete();
+
+ if (! $this->db->transStatus()) {
+ return $this->response->setStatusCode(500)->setJSON([
+ 'ok' => 0,
+ 'error' => 'Failed to delete panel',
+ ]);
+ }
+
+ return $this->response->setJSON([
+ 'ok' => 1,
+ 'message' => 'Panel deleted successfully',
+ ]);
+ }
+
public function report_ultrasound_insert(int $modality)
{
if ($resp = $this->requireModalityPermission($modality)) {
@@ -522,6 +837,19 @@ HTML;
'FixedNormalsWomen' => (string) $this->request->getPost('input_FixedNormalsWomen'),
];
+ if ($this->db->fieldExists('loinc_code', 'lab_tests')) {
+ $data['loinc_code'] = trim((string) $this->request->getPost('input_loinc_code'));
+ }
+ if ($this->db->fieldExists('loinc_property', 'lab_tests')) {
+ $data['loinc_property'] = trim((string) $this->request->getPost('input_loinc_property'));
+ }
+ if ($this->db->fieldExists('loinc_system', 'lab_tests')) {
+ $data['loinc_system'] = trim((string) $this->request->getPost('input_loinc_system'));
+ }
+ if ($this->db->fieldExists('loinc_scale', 'lab_tests')) {
+ $data['loinc_scale'] = trim((string) $this->request->getPost('input_loinc_scale'));
+ }
+
$pathLab->updateItemParameter($data, $mstTestKey);
return $this->response->setJSON([
@@ -555,6 +883,19 @@ HTML;
'FixedNormals' => (string) $this->request->getPost('input_Fixed'),
];
+ if ($this->db->fieldExists('loinc_code', 'lab_tests')) {
+ $data['loinc_code'] = trim((string) $this->request->getPost('input_loinc_code'));
+ }
+ if ($this->db->fieldExists('loinc_property', 'lab_tests')) {
+ $data['loinc_property'] = trim((string) $this->request->getPost('input_loinc_property'));
+ }
+ if ($this->db->fieldExists('loinc_system', 'lab_tests')) {
+ $data['loinc_system'] = trim((string) $this->request->getPost('input_loinc_system'));
+ }
+ if ($this->db->fieldExists('loinc_scale', 'lab_tests')) {
+ $data['loinc_scale'] = trim((string) $this->request->getPost('input_loinc_scale'));
+ }
+
$insertId = $pathLab->insertItemParameter($data);
return $this->response->setJSON([
@@ -722,6 +1063,1092 @@ HTML;
return $this->response->setBody($html);
}
+ // -------------------------------------------------------------------------
+ // LOINC Mapping Admin
+ // -------------------------------------------------------------------------
+
+ /**
+ * GET Lab_Admin/loinc_panel
+ * Show all lab panels (lab_repo) and their tests (lab_tests) with LOINC codes.
+ */
+ public function loincPanel()
+ {
+ if ($resp = $this->requirePermission('template.pathology')) {
+ return $resp;
+ }
+
+ $panels = $this->db->table('lab_repo')
+ ->select('mstRepoKey, Title, loinc_code, loinc_synced_at')
+ ->orderBy('Title', 'ASC')
+ ->get()
+ ->getResultArray();
+
+ $tests = $this->db->table('lab_tests lt')
+ ->select('lt.mstTestKey, lt.Test, lt.Unit, lt.loinc_code, lt.loinc_property, lt.loinc_system, lt.loinc_scale, lt.loinc_synced_at, lrt.mstRepoKey')
+ ->join('lab_repotests lrt', 'lrt.mstTestKey = lt.mstTestKey', 'left')
+ ->orderBy('lrt.mstRepoKey, lrt.EOrder', 'ASC')
+ ->get()
+ ->getResultArray();
+
+ // Group tests by repo id
+ $testsByRepo = [];
+ foreach ($tests as $t) {
+ $rid = (int) ($t['mstRepoKey'] ?? 0);
+ $testsByRepo[$rid][] = $t;
+ }
+
+ $data = [
+ 'title' => 'LOINC Mapping — Pathology',
+ 'panels' => $panels,
+ 'testsByRepo' => $testsByRepo,
+ ];
+
+ return view('PathLab_Report/loinc_panel', $data);
+ }
+
+ /**
+ * POST Lab_Admin/loinc_sync (AJAX)
+ * Trigger incremental LOINC sync from Bridge API via the Spark command.
+ * Runs synchronously for up to 60 s — suitable for admin-initiated syncs.
+ */
+ public function loincSync()
+ {
+ if (! $this->request->isAJAX()) {
+ return $this->response->setStatusCode(403)->setJSON(['ok' => 0, 'error' => 'AJAX only']);
+ }
+ if ($resp = $this->requirePermission('template.pathology')) {
+ return $resp;
+ }
+
+ $since = trim((string) ($this->request->getPost('since') ?? ''));
+
+ // Build command
+ $sparkPath = ROOTPATH . 'spark';
+ $cmd = PHP_BINARY . ' ' . escapeshellarg($sparkPath) . ' abdm:sync-pathology-loinc';
+ if ($since !== '') {
+ $cmd .= ' --since=' . escapeshellarg($since);
+ }
+
+ $output = [];
+ $exitCode = 0;
+ exec($cmd . ' 2>&1', $output, $exitCode);
+
+ return $this->response->setJSON([
+ 'ok' => $exitCode === 0 ? 1 : 0,
+ 'output' => implode("\n", $output),
+ 'exitCode' => $exitCode,
+ ]);
+ }
+
+ /**
+ * POST Lab_Admin/loinc_update (AJAX)
+ * Manually update LOINC code for a single lab_test or lab_repo record.
+ *
+ * POST params:
+ * type = 'test' | 'panel'
+ * id = mstTestKey | mstRepoKey
+ * loinc_code, loinc_property, loinc_system, loinc_scale (test only)
+ */
+ public function loincUpdate()
+ {
+ if (! $this->request->isAJAX()) {
+ return $this->response->setStatusCode(403)->setJSON(['ok' => 0, 'error' => 'AJAX only']);
+ }
+ if ($resp = $this->requirePermission('template.pathology')) {
+ return $resp;
+ }
+
+ $type = trim((string) ($this->request->getPost('type') ?? ''));
+ $id = (int) ($this->request->getPost('id') ?? 0);
+ $loincCode = trim((string) ($this->request->getPost('loinc_code') ?? ''));
+
+ if ($id <= 0 || ! in_array($type, ['test', 'panel'], true)) {
+ return $this->response->setJSON(['ok' => 0, 'error' => 'Invalid parameters']);
+ }
+
+ $now = date('Y-m-d H:i:s');
+
+ if ($type === 'panel') {
+ $this->db->table('lab_repo')->where('mstRepoKey', $id)->update([
+ 'loinc_code' => $loincCode,
+ 'loinc_synced_at' => $now,
+ ]);
+ } else {
+ $this->db->table('lab_tests')->where('mstTestKey', $id)->update([
+ 'loinc_code' => $loincCode,
+ 'loinc_property' => trim((string) ($this->request->getPost('loinc_property') ?? '')),
+ 'loinc_system' => trim((string) ($this->request->getPost('loinc_system') ?? '')),
+ 'loinc_scale' => trim((string) ($this->request->getPost('loinc_scale') ?? '')),
+ 'loinc_synced_at' => $now,
+ ]);
+ }
+
+ return $this->response->setJSON(['ok' => 1]);
+ }
+
+ /**
+ * GET Lab_Admin/pathology_masters_search?q=CBC
+ * Returns JSON list of matching panel names (+ LOINC codes).
+ * Uses the same direct-curl pattern as Medical::fetchAllGatewayDrugMasters().
+ * Falls back to local lab_repo search if Bridge API is unavailable/unconfigured.
+ */
+ public function pathologyMastersSearch()
+ {
+ if ($resp = $this->requirePermission('template.pathology')) {
+ return $resp;
+ }
+
+ $q = trim((string) ($this->request->getGet('q') ?? ''));
+ $subCategory = trim((string) ($this->request->getGet('sub_category') ?? ''));
+ $source = strtolower(trim((string) ($this->request->getGet('source') ?? '')));
+ $bridgeOnly = in_array($source, ['api', 'bridge', 'gateway', 'bridge_only'], true);
+ $panelOnly = in_array(strtolower(trim((string) ($this->request->getGet('panel_only') ?? ''))), ['1', 'true', 'yes'], true);
+ if (strlen($q) < 1) {
+ return $this->response->setJSON([]);
+ }
+
+ $results = [];
+ $bridgeAttempted = false;
+ $bridgeError = '';
+ $bridgeHttpCode = 0;
+ $bridgeUrl = '';
+ $bridgeRaw = '';
+ $mastersSucceeded = false;
+
+ $gw = $this->resolveBridgeGatewayConfig();
+ $gwUrl = (string) ($gw['url'] ?? '');
+ $gwToken = (string) ($gw['token'] ?? '');
+ $hfrId = (string) ($gw['hfr_id'] ?? '');
+
+ // ── Try Bridge API ────────────────────────────────────────────────────
+ if ($gwToken !== '') {
+ try {
+ $bridgeAttempted = true;
+ $query = [
+ 'q' => $q,
+ 'limit' => 20,
+ 'offset' => 0,
+ 'include_inactive' => 0,
+ ];
+ if ($subCategory !== '') {
+ $query['sub_category'] = $subCategory;
+ }
+ if ($hfrId !== '') {
+ $query['hfr_id'] = $hfrId;
+ }
+
+ if ($panelOnly) {
+ $query['panel_type'] = 'PANEL';
+ }
+
+ $resp = $this->bridgeGet($gwUrl, $gwToken, '/api/v3/pathology/panels', $query);
+ $code = (int) ($resp['http_code'] ?? 0);
+ $cerr = (string) ($resp['curl_error'] ?? '');
+ $raw = (string) ($resp['raw'] ?? '');
+ $body = (array) ($resp['json'] ?? []);
+ $bridgeHttpCode = $code;
+ $bridgeUrl = (string) ($resp['url'] ?? '');
+ $bridgeRaw = $raw;
+
+ if ($cerr === '' && $code >= 200 && $code < 300) {
+ if (is_array($body) && (int) ($body['ok'] ?? 0) === 1) {
+ $mastersSucceeded = true;
+ $panelNameSet = [];
+
+ $isLikelyPanelName = static function (string $name): bool {
+ $trim = trim($name);
+ if ($trim === '') {
+ return false;
+ }
+
+ // Exclude low-level analyte-style names commonly seen in component datasets.
+ if ((bool) preg_match('/-(mcnc|scnc|rto|srto|mrto|ccnc|arb|acnc)\b/i', $trim)) {
+ return false;
+ }
+
+ // Keep strong panel/meta-panel cues and common panel abbreviations.
+ if ((bool) preg_match('/\b(meta\s*panel|metapanel|panel|profile|screen|function|count|cbc|lft|kft|tft)\b/i', $trim)) {
+ return true;
+ }
+
+ // Names with explicit acronym in brackets are often panel labels.
+ if ((bool) preg_match('/\([A-Za-z0-9\-]{2,12}\)/', $trim)) {
+ return true;
+ }
+
+ return false;
+ };
+
+ foreach ((array) ($body['items'] ?? []) as $item) {
+ $name = trim((string) ($item['panel_name'] ?? $item['test_name'] ?? $item['display_name'] ?? $item['name'] ?? ''));
+ if ($name !== '') {
+ if ($panelOnly) {
+ $itemType = strtolower(trim((string) ($item['panel_type'] ?? $item['type'] ?? $item['test_type'] ?? $item['entity_type'] ?? $item['master_type'] ?? '')));
+ $isPanelType = in_array($itemType, ['panel', 'meta_panel', 'metapanel', 'meta-panel'], true);
+ $isPanelName = $isLikelyPanelName($name);
+ if (! $isPanelType && ! $isPanelName) {
+ continue;
+ }
+ $panelNameSet[$name] = [
+ 'name' => $name,
+ 'test_name' => (string) ($item['panel_name'] ?? $item['test_name'] ?? $name),
+ 'display_name' => (string) ($item['description'] ?? $item['display_name'] ?? ''),
+ 'loinc_code' => (string) ($item['code'] ?? $item['loinc_code'] ?? ''),
+ 'code_system' => (string) ($item['code_system'] ?? ''),
+ 'sub_category' => (string) ($item['sub_category'] ?? ''),
+ 'standard_rate' => (string) ($item['standard_rate'] ?? ''),
+ 'master_id' => (int) ($item['id'] ?? 0),
+ 'updated_at' => (string) ($item['updated_at'] ?? ''),
+ 'source' => 'bridge',
+ ];
+ continue;
+ }
+
+ $results[] = [
+ 'name' => $name,
+ 'test_name' => (string) ($item['panel_name'] ?? $item['test_name'] ?? $name),
+ 'display_name' => (string) ($item['description'] ?? $item['display_name'] ?? ''),
+ 'loinc_code' => (string) ($item['code'] ?? $item['loinc_code'] ?? ''),
+ 'code_system' => (string) ($item['code_system'] ?? ''),
+ 'sub_category' => (string) ($item['sub_category'] ?? ''),
+ 'standard_rate' => (string) ($item['standard_rate'] ?? ''),
+ 'master_id' => (int) ($item['id'] ?? 0),
+ 'updated_at' => (string) ($item['updated_at'] ?? ''),
+ 'source' => 'bridge',
+ ];
+ }
+ }
+
+ if ($panelOnly && !empty($panelNameSet)) {
+ $results = array_values($panelNameSet);
+ }
+ } else {
+ $bridgeError = trim((string) ($body['message'] ?? $body['error_code'] ?? 'Bridge returned ok=0'));
+ log_message('debug', '[pathologyMastersSearch] Bridge API ok=' . ($body['ok'] ?? '?') .
+ ' code=' . $code . ' body=' . substr($raw, 0, 300));
+ }
+ } else {
+ $bridgeError = $cerr !== '' ? $cerr : 'HTTP ' . $code;
+ log_message('warning', '[pathologyMastersSearch] Bridge API curl_err=' . $cerr . ' http=' . $code .
+ ' body=' . substr($raw, 0, 300));
+ }
+ } catch (\Throwable $e) {
+ $bridgeError = $e->getMessage();
+ log_message('warning', '[pathologyMastersSearch] Bridge API exception: ' . $e->getMessage());
+ }
+
+ // If panel lookup returned nothing, try dedicated component master search for non-panel contexts.
+ if (empty($results) && ! $panelOnly) {
+ try {
+ $compQuery = [
+ 'q' => $q,
+ 'limit' => 50,
+ 'offset' => 0,
+ 'include_inactive' => 0,
+ ];
+ if ($hfrId !== '') {
+ $compQuery['hfr_id'] = $hfrId;
+ }
+
+ $compResp = $this->bridgeGet($gwUrl, $gwToken, '/api/v3/pathology/component-masters', $compQuery);
+ $compCode = (int) ($compResp['http_code'] ?? 0);
+ $compErr = (string) ($compResp['curl_error'] ?? '');
+ $compRaw = (string) ($compResp['raw'] ?? '');
+ $compBody = (array) ($compResp['json'] ?? []);
+
+ if ($compErr === '' && $compCode >= 200 && $compCode < 300 && (int) ($compBody['ok'] ?? 0) === 1) {
+ $componentsByName = [];
+ foreach ((array) ($compBody['items'] ?? []) as $item) {
+ $componentName = trim((string) ($item['component_name'] ?? $item['test_name'] ?? $item['name'] ?? ''));
+ if ($componentName !== '') {
+ $componentsByName[$componentName] = [
+ 'name' => $componentName,
+ 'test_name' => $componentName,
+ 'display_name' => '',
+ 'loinc_code' => (string) ($item['code'] ?? ''),
+ 'code_system' => (string) ($item['code_system'] ?? ''),
+ 'sub_category' => (string) ($item['sub_category'] ?? 'PATHOLOGY'),
+ 'standard_rate' => '',
+ 'master_id' => (int) ($item['id'] ?? 0),
+ 'updated_at' => (string) ($item['updated_at'] ?? ''),
+ 'source' => 'bridge',
+ ];
+ }
+ }
+
+ $existingNames = [];
+ foreach ($results as $r) {
+ $existingNames[strtolower(trim((string) ($r['name'] ?? '')))] = true;
+ }
+
+ foreach ($componentsByName as $componentName => $row) {
+ $lk = strtolower($componentName);
+ if (isset($existingNames[$lk])) {
+ continue;
+ }
+ $results[] = $row;
+ }
+ } elseif ($bridgeError === '') {
+ $bridgeError = $compErr !== '' ? $compErr : ('HTTP ' . $compCode);
+ $bridgeHttpCode = $compCode;
+ $bridgeUrl = (string) ($compResp['url'] ?? $bridgeUrl);
+ $bridgeRaw = $compRaw;
+ }
+ } catch (\Throwable $e) {
+ if ($bridgeError === '') {
+ $bridgeError = $e->getMessage();
+ }
+ log_message('warning', '[pathologyMastersSearch] components fallback exception: ' . $e->getMessage());
+ }
+ }
+ } else {
+ $bridgeError = 'EATRIA_BRIDGE_TOKEN not configured';
+ }
+
+ // ── Fallback: local lab_repo search ───────────────────────────────────
+ if (empty($results) && ! $bridgeOnly) {
+ try {
+ $localRows = $this->db->table('lab_repo r')
+ ->select("r.mstRepoKey, r.Title, COALESCE(g.RepoGrp, '') AS sub_category, IFNULL(r.loinc_code, '') AS loinc_code")
+ ->join('lab_rgroups g', 'g.mstRGrpKey = r.GrpKey', 'left')
+ ->like('r.Title', $q)
+ ->orderBy('Title', 'ASC')
+ ->limit(20)
+ ->get()
+ ->getResultArray();
+ } catch (\Throwable $e) {
+ $localRows = $this->db->table('lab_repo r')
+ ->select("r.mstRepoKey, r.Title, COALESCE(g.RepoGrp, '') AS sub_category")
+ ->join('lab_rgroups g', 'g.mstRGrpKey = r.GrpKey', 'left')
+ ->like('r.Title', $q)
+ ->orderBy('Title', 'ASC')
+ ->limit(20)
+ ->get()
+ ->getResultArray();
+ }
+
+ foreach ($localRows as $row) {
+ $results[] = [
+ 'name' => (string) ($row['Title'] ?? ''),
+ 'test_name' => (string) ($row['Title'] ?? ''),
+ 'display_name' => '',
+ 'loinc_code' => (string) ($row['loinc_code'] ?? ''),
+ 'code_system' => '',
+ 'sub_category' => (string) ($row['sub_category'] ?? ''),
+ 'standard_rate' => '',
+ 'master_id' => 0,
+ 'updated_at' => '',
+ 'source' => 'local',
+ ];
+ }
+ }
+
+ if (empty($results) && $bridgeOnly) {
+ if ($panelOnly && $mastersSucceeded) {
+ return $this->response->setJSON([
+ 'ok' => 1,
+ 'items' => [],
+ 'source' => 'bridge',
+ ]);
+ }
+
+ if ($bridgeError !== '' || ! $bridgeAttempted) {
+ return $this->response->setStatusCode(502)->setJSON([
+ 'ok' => 0,
+ 'items' => [],
+ 'source' => 'bridge',
+ 'error' => $bridgeError !== '' ? $bridgeError : 'Bridge request not attempted',
+ 'http_code' => $bridgeHttpCode,
+ 'url' => $bridgeUrl,
+ 'details' => substr($bridgeRaw, 0, 300),
+ ]);
+ }
+
+ return $this->response->setJSON([
+ 'ok' => 1,
+ 'items' => [],
+ 'source' => 'bridge',
+ ]);
+ }
+
+ return $this->response->setJSON($results);
+ }
+
+ /**
+ * GET Lab_Admin/pathology_master_template?parent_test=CBC
+ * Fetches panel components from Bridge master data and returns generated HTML template.
+ */
+ public function pathologyMasterTemplate()
+ {
+ if ($resp = $this->requirePermission('template.pathology')) {
+ return $resp;
+ }
+
+ $parentTest = trim((string) ($this->request->getGet('parent_test') ?? ''));
+ if ($parentTest === '') {
+ return $this->response->setStatusCode(400)->setJSON([
+ 'ok' => 0,
+ 'error' => 'parent_test is required',
+ ]);
+ }
+
+ $gw = $this->resolveBridgeGatewayConfig();
+ $gwUrl = (string) ($gw['url'] ?? '');
+ $gwToken = (string) ($gw['token'] ?? '');
+ $hfrId = (string) ($gw['hfr_id'] ?? '');
+
+ if ($gwToken === '') {
+ return $this->response->setStatusCode(400)->setJSON([
+ 'ok' => 0,
+ 'error' => 'EATRIA_BRIDGE_TOKEN not configured',
+ ]);
+ }
+
+ $masterMeta = [
+ 'name' => $parentTest,
+ 'loinc_code' => '',
+ 'sub_category' => '',
+ 'code_system' => '',
+ 'standard_rate' => '',
+ 'master_id' => 0,
+ ];
+
+ try {
+ $masterQuery = [
+ 'q' => $parentTest,
+ 'limit' => 25,
+ 'offset' => 0,
+ 'include_inactive' => 0,
+ ];
+ if ($hfrId !== '') {
+ $masterQuery['hfr_id'] = $hfrId;
+ }
+
+ $masterQuery['panel_type'] = 'PANEL';
+ $masterResp = $this->bridgeGet($gwUrl, $gwToken, '/api/v3/pathology/panels', $masterQuery);
+ $masterBody = (array) ($masterResp['json'] ?? []);
+ if ((int) ($masterBody['ok'] ?? 0) === 1) {
+ foreach ((array) ($masterBody['items'] ?? []) as $item) {
+ $candidate = trim((string) ($item['panel_name'] ?? $item['test_name'] ?? $item['display_name'] ?? ''));
+ if ($candidate === '') {
+ continue;
+ }
+
+ $masterMeta = [
+ 'name' => $candidate,
+ 'loinc_code' => (string) ($item['code'] ?? $item['loinc_code'] ?? ''),
+ 'sub_category' => (string) ($item['sub_category'] ?? ''),
+ 'code_system' => (string) ($item['code_system'] ?? ''),
+ 'standard_rate' => (string) ($item['standard_rate'] ?? ''),
+ 'master_id' => (int) ($item['id'] ?? 0),
+ ];
+
+ if (strcasecmp($candidate, $parentTest) === 0) {
+ break;
+ }
+ }
+ }
+ } catch (\Throwable $e) {
+ log_message('warning', '[pathologyMasterTemplate] master lookup failed: ' . $e->getMessage());
+ }
+
+ $expandQuery = [
+ 'entity_type' => 'panel',
+ 'name' => $masterMeta['name'],
+ 'include_inactive' => 0,
+ 'max_depth' => 8,
+ ];
+ if ($hfrId !== '') {
+ $expandQuery['hfr_id'] = $hfrId;
+ }
+
+ $expandResp = $this->bridgeGet($gwUrl, $gwToken, '/api/v3/pathology/expand', $expandQuery);
+ $expandCode = (int) ($expandResp['http_code'] ?? 0);
+ $expandErr = (string) ($expandResp['curl_error'] ?? '');
+ $expandBody = (array) ($expandResp['json'] ?? []);
+
+ if ($expandErr !== '' || $expandCode < 200 || $expandCode >= 300 || (int) ($expandBody['ok'] ?? 0) !== 1) {
+ return $this->response->setStatusCode(502)->setJSON([
+ 'ok' => 0,
+ 'error' => 'Failed to expand pathology panel from gateway',
+ 'http_code' => $expandCode,
+ 'details' => substr((string) ($expandResp['raw'] ?? ''), 0, 300),
+ ]);
+ }
+
+ $components = [];
+ foreach ((array) ($expandBody['atomic_tests'] ?? []) as $atomic) {
+ $components[] = [
+ 'component_test_name' => (string) ($atomic['test_name'] ?? ''),
+ 'component_code' => (string) ($atomic['code'] ?? ''),
+ 'unit' => (string) ($atomic['unit'] ?? ''),
+ 'component_property' => (string) ($atomic['property'] ?? ''),
+ 'component_system' => (string) ($atomic['specimen_system'] ?? ''),
+ 'component_scale' => (string) ($atomic['scale_type'] ?? ''),
+ 'sort_order' => (int) ($atomic['sort_order'] ?? 0),
+ ];
+ }
+ usort($components, static function ($a, $b): int {
+ return (int) ($a['sort_order'] ?? 99999) <=> (int) ($b['sort_order'] ?? 99999);
+ });
+
+ $templateHtml = $this->buildPathologyMasterTemplateHtml((string) $masterMeta['name'], $components);
+
+ return $this->response->setJSON([
+ 'ok' => 1,
+ 'panel_name' => (string) $masterMeta['name'],
+ 'loinc_code' => (string) $masterMeta['loinc_code'],
+ 'sub_category' => (string) $masterMeta['sub_category'],
+ 'code_system' => (string) $masterMeta['code_system'],
+ 'standard_rate' => (string) $masterMeta['standard_rate'],
+ 'master_id' => (int) $masterMeta['master_id'],
+ 'components_count' => count($components),
+ 'components' => $components,
+ 'template_html' => $templateHtml,
+ 'request_id' => (string) ($expandBody['request_id'] ?? ''),
+ ]);
+ }
+
+ /**
+ * GET Lab_Admin/pathology_component_masters_search?q=hem
+ * Gateway-only component search for Add Component modal.
+ */
+ public function pathologyComponentMastersSearch()
+ {
+ if ($resp = $this->requirePermission('template.pathology')) {
+ return $resp;
+ }
+
+ $q = trim((string) ($this->request->getGet('q') ?? ''));
+ if (strlen($q) < 2) {
+ return $this->response->setJSON(['ok' => 1, 'items' => []]);
+ }
+
+ $gw = $this->resolveBridgeGatewayConfig();
+ $gwUrl = (string) ($gw['url'] ?? '');
+ $gwToken = (string) ($gw['token'] ?? '');
+ $hfrId = (string) ($gw['hfr_id'] ?? '');
+
+ if ($gwToken === '') {
+ return $this->response->setStatusCode(400)->setJSON([
+ 'ok' => 0,
+ 'error' => 'EATRIA_BRIDGE_TOKEN not configured',
+ 'items' => [],
+ ]);
+ }
+
+ $query = [
+ 'q' => $q,
+ 'limit' => 25,
+ 'offset' => 0,
+ 'include_inactive' => 0,
+ ];
+ if ($hfrId !== '') {
+ $query['hfr_id'] = $hfrId;
+ }
+
+ $resp = $this->bridgeGet($gwUrl, $gwToken, '/api/v3/pathology/component-masters', $query);
+ $code = (int) ($resp['http_code'] ?? 0);
+ $cerr = (string) ($resp['curl_error'] ?? '');
+ $body = (array) ($resp['json'] ?? []);
+
+ if ($cerr !== '' || $code < 200 || $code >= 300 || (int) ($body['ok'] ?? 0) !== 1) {
+ return $this->response->setStatusCode(502)->setJSON([
+ 'ok' => 0,
+ 'items' => [],
+ 'error' => $cerr !== '' ? $cerr : 'Gateway component search failed',
+ 'http_code' => $code,
+ 'details' => substr((string) ($resp['raw'] ?? ''), 0, 300),
+ ]);
+ }
+
+ $items = [];
+ foreach ((array) ($body['items'] ?? []) as $item) {
+ $name = trim((string) ($item['component_name'] ?? $item['test_name'] ?? $item['name'] ?? ''));
+ if ($name === '') {
+ continue;
+ }
+
+ $items[] = [
+ 'name' => $name,
+ 'short_name' => (string) ($item['short_name'] ?? $item['test_id'] ?? ''),
+ 'code' => (string) ($item['code'] ?? $item['loinc_code'] ?? ''),
+ 'unit' => (string) ($item['unit'] ?? ''),
+ 'property' => (string) ($item['property'] ?? $item['component_property'] ?? ''),
+ 'specimen_system' => (string) ($item['specimen_system'] ?? $item['component_system'] ?? ''),
+ 'scale_type' => (string) ($item['scale_type'] ?? $item['component_scale'] ?? ''),
+ 'sub_category' => (string) ($item['sub_category'] ?? ''),
+ 'master_id' => (int) ($item['id'] ?? 0),
+ ];
+ }
+
+ return $this->response->setJSON([
+ 'ok' => 1,
+ 'items' => $items,
+ 'source' => 'bridge',
+ 'request_id' => (string) ($body['request_id'] ?? ''),
+ ]);
+ }
+
+ /**
+ * POST Lab_Admin/pathology_master_add_component
+ * Adds one gateway component into local lab_tests and maps it to the selected panel.
+ */
+ public function pathologyMasterAddComponent()
+ {
+ if ($resp = $this->requirePermission('template.pathology')) {
+ return $resp;
+ }
+
+ if (! $this->request->isAJAX()) {
+ return $this->response->setStatusCode(400)->setJSON([
+ 'ok' => 0,
+ 'error' => 'Invalid request',
+ ]);
+ }
+
+ $repoId = (int) ($this->request->getPost('repo_id') ?? 0);
+ $name = trim((string) ($this->request->getPost('component_name') ?? ''));
+ $shortName = trim((string) ($this->request->getPost('short_name') ?? ''));
+ $code = trim((string) ($this->request->getPost('code') ?? ''));
+ $unit = trim((string) ($this->request->getPost('unit') ?? ''));
+ $property = trim((string) ($this->request->getPost('property') ?? ''));
+ $system = trim((string) ($this->request->getPost('specimen_system') ?? ''));
+ $scale = trim((string) ($this->request->getPost('scale_type') ?? ''));
+
+ if ($repoId <= 0 || $name === '') {
+ return $this->response->setStatusCode(400)->setJSON([
+ 'ok' => 0,
+ 'error' => 'repo_id and component_name are required',
+ ]);
+ }
+
+ $testColumnsRows = $this->db->query('SHOW COLUMNS FROM lab_tests')->getResultArray();
+ $testColumns = array_column($testColumnsRows, 'Field');
+
+ $find = $this->db->table('lab_tests')->select('mstTestKey');
+ $find->groupStart();
+ if ($code !== '' && in_array('loinc_code', $testColumns, true)) {
+ $find->orGroupStart()
+ ->where('loinc_code', $code)
+ ->where('loinc_code !=', '')
+ ->groupEnd();
+ }
+ if ($shortName !== '') {
+ $find->orWhere('TestID', $shortName);
+ }
+ $find->orWhere('Test', $name);
+ $find->groupEnd();
+
+ $existing = $find->orderBy('mstTestKey', 'ASC')->get()->getRowArray();
+ $mstTestKey = (int) ($existing['mstTestKey'] ?? 0);
+
+ $testData = [
+ 'Test' => $name,
+ 'TestID' => $shortName !== '' ? $shortName : ($code !== '' ? $code : ''),
+ 'Unit' => $unit,
+ ];
+
+ if (in_array('loinc_code', $testColumns, true)) {
+ $testData['loinc_code'] = $code;
+ }
+ if (in_array('loinc_property', $testColumns, true)) {
+ $testData['loinc_property'] = $property;
+ }
+ if (in_array('loinc_system', $testColumns, true)) {
+ $testData['loinc_system'] = $system;
+ }
+ if (in_array('loinc_scale', $testColumns, true)) {
+ $testData['loinc_scale'] = $scale;
+ }
+
+ $pathLab = new PathLabModel();
+
+ if ($mstTestKey > 0) {
+ $pathLab->updateItemParameter($testData, $mstTestKey);
+ } else {
+ $mstTestKey = $pathLab->insertItemParameter($testData);
+ }
+
+ if ($mstTestKey <= 0) {
+ return $this->response->setStatusCode(500)->setJSON([
+ 'ok' => 0,
+ 'error' => 'Unable to create component locally',
+ ]);
+ }
+
+ $exists = $this->db->table('lab_repotests')
+ ->where('mstRepoKey', $repoId)
+ ->where('mstTestKey', $mstTestKey)
+ ->countAllResults();
+
+ if ($exists <= 0) {
+ $row = $this->db->table('lab_repotests')
+ ->selectMax('EOrder', 'max_order')
+ ->where('mstRepoKey', $repoId)
+ ->get()
+ ->getRowArray();
+ $nextOrder = (int) ($row['max_order'] ?? 0) + 1;
+
+ $pathLab->insertItemSortorder([
+ 'mstRepoKey' => $repoId,
+ 'mstTestKey' => $mstTestKey,
+ 'EOrder' => $nextOrder,
+ ]);
+ }
+
+ return $this->response->setJSON([
+ 'ok' => 1,
+ 'mstTestKey' => $mstTestKey,
+ 'added' => $exists <= 0 ? 1 : 0,
+ 'message' => $exists <= 0 ? 'Component added' : 'Component already attached',
+ ]);
+ }
+
+ /**
+ * POST Lab_Admin/pathology_master_apply_panel
+ * Gateway-style panel mapping import:
+ * - expands panel to atomic tests (short/code aware)
+ * - upserts local lab_tests
+ * - maps tests to lab_repotests for the report template
+ * - regenerates HTMLData with token placeholders ({HB}, {TLC}, ...)
+ */
+ public function pathologyMasterApplyPanel()
+ {
+ if (! $this->request->isAJAX()) {
+ return $this->response->setStatusCode(403)->setJSON(['ok' => 0, 'error' => 'AJAX only']);
+ }
+ if ($resp = $this->requirePermission('template.pathology')) {
+ return $resp;
+ }
+
+ $repoId = (int) ($this->request->getPost('repo_id') ?? 0);
+ $panelName = trim((string) ($this->request->getPost('panel_name') ?? ''));
+ $replaceExisting = in_array(strtolower(trim((string) ($this->request->getPost('replace_existing') ?? '1'))), ['1', 'true', 'yes'], true);
+
+ if ($repoId <= 0) {
+ return $this->response->setStatusCode(400)->setJSON([
+ 'ok' => 0,
+ 'error' => 'Save report first, then import panel components.',
+ ]);
+ }
+
+ if ($panelName === '') {
+ return $this->response->setStatusCode(400)->setJSON([
+ 'ok' => 0,
+ 'error' => 'panel_name is required',
+ ]);
+ }
+
+ $gw = $this->resolveBridgeGatewayConfig();
+ $gwUrl = (string) ($gw['url'] ?? '');
+ $gwToken = (string) ($gw['token'] ?? '');
+ $hfrId = (string) ($gw['hfr_id'] ?? '');
+
+ if ($gwToken === '') {
+ return $this->response->setStatusCode(400)->setJSON([
+ 'ok' => 0,
+ 'error' => 'EATRIA_BRIDGE_TOKEN not configured',
+ ]);
+ }
+
+ // Resolve to canonical panel name from gateway so expand/components can match reliably.
+ try {
+ $panelQuery = [
+ 'q' => $panelName,
+ 'panel_type' => 'PANEL',
+ 'limit' => 50,
+ 'offset' => 0,
+ 'include_inactive' => 0,
+ ];
+ if ($hfrId !== '') {
+ $panelQuery['hfr_id'] = $hfrId;
+ }
+
+ $panelResp = $this->bridgeGet($gwUrl, $gwToken, '/api/v3/pathology/panels', $panelQuery);
+ $panelBody = (array) ($panelResp['json'] ?? []);
+ if ((int) ($panelBody['ok'] ?? 0) === 1) {
+ $panelItems = array_values((array) ($panelBody['items'] ?? []));
+ foreach ($panelItems as $item) {
+ $candidate = trim((string) ($item['panel_name'] ?? $item['test_name'] ?? $item['display_name'] ?? ''));
+ if ($candidate === '') {
+ continue;
+ }
+
+ if (strcasecmp($candidate, $panelName) === 0) {
+ $panelName = $candidate;
+ break;
+ }
+
+ if (stripos($candidate, $panelName) !== false || stripos($panelName, $candidate) !== false) {
+ $panelName = $candidate;
+ break;
+ }
+ }
+ }
+ } catch (\Throwable $e) {
+ log_message('warning', '[pathologyMasterApplyPanel] canonical panel resolve failed: ' . $e->getMessage());
+ }
+
+ $expandQuery = [
+ 'entity_type' => 'panel',
+ 'name' => $panelName,
+ 'include_inactive' => 0,
+ 'max_depth' => 8,
+ ];
+ if ($hfrId !== '') {
+ $expandQuery['hfr_id'] = $hfrId;
+ }
+
+ $expandResp = $this->bridgeGet($gwUrl, $gwToken, '/api/v3/pathology/expand', $expandQuery);
+ $expandCode = (int) ($expandResp['http_code'] ?? 0);
+ $expandErr = (string) ($expandResp['curl_error'] ?? '');
+ $expandBody = (array) ($expandResp['json'] ?? []);
+
+ $atomic = [];
+ if ($expandErr === '' && $expandCode >= 200 && $expandCode < 300 && (int) ($expandBody['ok'] ?? 0) === 1) {
+ $atomic = array_values((array) ($expandBody['atomic_tests'] ?? []));
+ } else {
+ $compQuery = [
+ 'parent_test' => $panelName,
+ 'limit' => 500,
+ 'offset' => 0,
+ 'include_inactive' => 0,
+ ];
+ if ($hfrId !== '') {
+ $compQuery['hfr_id'] = $hfrId;
+ }
+
+ $compResp = $this->bridgeGet($gwUrl, $gwToken, '/api/v3/pathology/components', $compQuery);
+ $compCode = (int) ($compResp['http_code'] ?? 0);
+ $compErr = (string) ($compResp['curl_error'] ?? '');
+ $compBody = (array) ($compResp['json'] ?? []);
+
+ if ($compErr !== '' || $compCode < 200 || $compCode >= 300 || (int) ($compBody['ok'] ?? 0) !== 1) {
+ return $this->response->setStatusCode(502)->setJSON([
+ 'ok' => 0,
+ 'error' => 'Failed to expand panel from gateway',
+ 'http_code' => $expandCode,
+ 'details' => substr((string) ($expandResp['raw'] ?? ''), 0, 300),
+ ]);
+ }
+
+ $components = array_values((array) ($compBody['items'] ?? []));
+ foreach ($components as $row) {
+ $atomic[] = [
+ 'test_name' => (string) ($row['component_test_name'] ?? ''),
+ 'short_name' => '',
+ 'code' => (string) ($row['component_code'] ?? ''),
+ 'property' => (string) ($row['component_property'] ?? ''),
+ 'specimen_system' => (string) ($row['component_system'] ?? ''),
+ 'scale_type' => (string) ($row['component_scale'] ?? ''),
+ 'unit' => (string) ($row['unit'] ?? ''),
+ 'sort_order' => (int) ($row['sort_order'] ?? 0),
+ ];
+ }
+ }
+
+ if ($atomic === []) {
+ return $this->response->setStatusCode(404)->setJSON([
+ 'ok' => 0,
+ 'error' => 'No atomic tests found for selected panel',
+ ]);
+ }
+
+ usort($atomic, static function ($a, $b): int {
+ return (int) ($a['sort_order'] ?? 99999) <=> (int) ($b['sort_order'] ?? 99999);
+ });
+
+ $testRowsForTemplate = [];
+ $linkedCount = 0;
+ $createdCount = 0;
+ $updatedCount = 0;
+
+ $this->db->transStart();
+
+ if ($replaceExisting) {
+ $this->db->table('lab_repotests')->where('mstRepoKey', $repoId)->delete();
+ }
+
+ $order = 10;
+ $seenCodes = [];
+
+ foreach ($atomic as $index => $item) {
+ $testName = trim((string) ($item['test_name'] ?? ''));
+ if ($testName === '') {
+ continue;
+ }
+
+ $short = trim((string) ($item['short_name'] ?? ''));
+ $code = trim((string) ($item['code'] ?? ''));
+ $testCode = $this->normalizePanelTokenCode($short !== '' ? $short : $code, $index + 1);
+
+ if (isset($seenCodes[$testCode])) {
+ $testCode = $this->normalizePanelTokenCode($testCode . ($index + 1), $index + 1);
+ }
+ $seenCodes[$testCode] = true;
+
+ $unit = trim((string) ($item['unit'] ?? ''));
+ $property = trim((string) ($item['property'] ?? ''));
+ $system = trim((string) ($item['specimen_system'] ?? ''));
+ $scale = trim((string) ($item['scale_type'] ?? ''));
+
+ $existing = $this->db->table('lab_tests')
+ ->select('mstTestKey')
+ ->groupStart()
+ ->where('TestID', $testCode)
+ ->orGroupStart()
+ ->where('loinc_code', $code)
+ ->where('loinc_code !=', '')
+ ->groupEnd()
+ ->orWhere('Test', $testName)
+ ->groupEnd()
+ ->orderBy('mstTestKey', 'ASC')
+ ->get(1)
+ ->getRowArray();
+
+ if (is_array($existing) && (int) ($existing['mstTestKey'] ?? 0) > 0) {
+ $mstTestKey = (int) $existing['mstTestKey'];
+ $this->db->table('lab_tests')->where('mstTestKey', $mstTestKey)->update([
+ 'Test' => $testName,
+ 'TestID' => $testCode,
+ 'Unit' => $unit,
+ 'loinc_code' => $code,
+ 'loinc_property' => $property,
+ 'loinc_system' => $system,
+ 'loinc_scale' => $scale,
+ 'loinc_synced_at' => date('Y-m-d H:i:s'),
+ ]);
+ $updatedCount++;
+ } else {
+ $this->db->table('lab_tests')->insert([
+ 'Test' => $testName,
+ 'TestID' => $testCode,
+ 'Result' => '',
+ 'Options' => null,
+ 'Formula' => '',
+ 'VRule' => '',
+ 'VMsg' => '',
+ 'Unit' => $unit,
+ 'FixedNormals' => '',
+ 'isGenderSpecific' => 0,
+ 'FixedNormalsWomen' => '',
+ 'loinc_code' => $code,
+ 'loinc_property' => $property,
+ 'loinc_system' => $system,
+ 'loinc_scale' => $scale,
+ 'loinc_synced_at' => date('Y-m-d H:i:s'),
+ ]);
+ $mstTestKey = (int) $this->db->insertID();
+ $createdCount++;
+ }
+
+ if ($mstTestKey <= 0) {
+ continue;
+ }
+
+ $mapExists = $this->db->table('lab_repotests')
+ ->where('mstRepoKey', $repoId)
+ ->where('mstTestKey', $mstTestKey)
+ ->countAllResults();
+
+ if ($mapExists <= 0) {
+ $this->db->table('lab_repotests')->insert([
+ 'mstRepoKey' => $repoId,
+ 'mstTestKey' => $mstTestKey,
+ 'EOrder' => $order,
+ ]);
+ $linkedCount++;
+ }
+
+ $order += 10;
+
+ $testRowsForTemplate[] = [
+ 'test_name' => $testName,
+ 'test_code' => $testCode,
+ 'unit' => $unit,
+ ];
+ }
+
+ $templateHtml = $this->buildPathologyPanelTokenTemplateHtml($panelName, $testRowsForTemplate);
+ $panelLoinc = trim((string) ($expandBody['resolved']['code'] ?? ''));
+
+ $updateData = [
+ 'Title' => $panelName,
+ 'HTMLData' => $templateHtml,
+ 'RTFData' => $templateHtml,
+ ];
+ if ($panelLoinc !== '') {
+ $updateData['loinc_code'] = $panelLoinc;
+ $updateData['loinc_synced_at'] = date('Y-m-d H:i:s');
+ }
+
+ $this->db->table('lab_repo')->where('mstRepoKey', $repoId)->update($updateData);
+
+ $this->db->transComplete();
+
+ if (! $this->db->transStatus()) {
+ return $this->response->setStatusCode(500)->setJSON([
+ 'ok' => 0,
+ 'error' => 'Failed to apply panel mapping in local database',
+ ]);
+ }
+
+ return $this->response->setJSON([
+ 'ok' => 1,
+ 'repo_id' => $repoId,
+ 'panel_name' => $panelName,
+ 'panel_loinc_code' => $panelLoinc,
+ 'components_count' => count($testRowsForTemplate),
+ 'created_tests' => $createdCount,
+ 'updated_tests' => $updatedCount,
+ 'linked_tests' => $linkedCount,
+ 'template_html' => $templateHtml,
+ ]);
+ }
+
+ /**
+ * GET Lab_Admin/pathology_bridge_debug
+ * DEV-ONLY: Shows raw Bridge API response for /api/v3/pathology/panels
+ * Remove this route from production!
+ */
+ public function pathologyBridgeDebug()
+ {
+ if ($resp = $this->requirePermission('template.pathology')) {
+ return $resp;
+ }
+
+ $gw = $this->resolveBridgeGatewayConfig();
+ $gwUrl = (string) ($gw['url'] ?? '');
+ $gwToken = (string) ($gw['token'] ?? '');
+ $hfrId = (string) ($gw['hfr_id'] ?? '');
+
+ if ($gwToken === '') {
+ return $this->response->setJSON(['error' => 'EATRIA_BRIDGE_TOKEN not configured', 'url' => $gwUrl]);
+ }
+
+ $query = ['limit' => 5, 'offset' => 0];
+ if ($hfrId !== '') {
+ $query['hfr_id'] = $hfrId;
+ }
+
+ $query['panel_type'] = 'PANEL';
+ $resp = $this->bridgeGet($gwUrl, $gwToken, '/api/v3/pathology/panels', $query);
+ $raw = (string) ($resp['raw'] ?? '');
+ $parsed = (array) ($resp['json'] ?? []);
+
+ return $this->response->setJSON([
+ 'url' => (string) ($resp['url'] ?? ''),
+ 'token_set' => $gwToken !== '' ? substr($gwToken, 0, 6) . '***' . substr($gwToken, -4) : '(empty)',
+ 'hfr_id_set' => $hfrId !== '',
+ 'http_code' => (int) ($resp['http_code'] ?? 0),
+ 'curl_error' => (string) ($resp['curl_error'] ?? ''),
+ 'raw_first_500' => substr($raw, 0, 500),
+ 'parsed' => $parsed,
+ ]);
+ }
+
+
public function diagnosis_print_settings(int $modality = 3)
{
if ($resp = $this->requireAnyPermission([
diff --git a/app/Database/Migrations/2026-05-27-000605_AddConsentIdsToAbdmConsentRecords.php b/app/Database/Migrations/2026-05-27-000605_AddConsentIdsToAbdmConsentRecords.php
new file mode 100644
index 0000000..eaa4b63
--- /dev/null
+++ b/app/Database/Migrations/2026-05-27-000605_AddConsentIdsToAbdmConsentRecords.php
@@ -0,0 +1,75 @@
+ gateway consent id.
+ */
+class AddConsentIdsToAbdmConsentRecords extends Migration
+{
+ public function up(): void
+ {
+ if (! $this->db->tableExists('abdm_consent_records')) {
+ return;
+ }
+
+ $fields = $this->db->getFieldNames('abdm_consent_records') ?? [];
+
+ if (! in_array('consent_id', $fields, true)) {
+ $this->forge->addColumn('abdm_consent_records', [
+ 'consent_id' => [
+ 'type' => 'VARCHAR',
+ 'constraint' => 120,
+ 'null' => true,
+ 'after' => 'consent_handle',
+ ],
+ ]);
+ }
+
+ $fields = $this->db->getFieldNames('abdm_consent_records') ?? [];
+ if (! in_array('gateway_consent_id', $fields, true)) {
+ $this->forge->addColumn('abdm_consent_records', [
+ 'gateway_consent_id' => [
+ 'type' => 'VARCHAR',
+ 'constraint' => 120,
+ 'null' => true,
+ 'after' => 'consent_id',
+ ],
+ ]);
+ }
+
+ $indexes = $this->db->getIndexData('abdm_consent_records') ?? [];
+ $indexNames = array_map(static fn ($i) => (string) ($i->name ?? ''), $indexes);
+
+ if (! in_array('idx_abdm_consent_id', $indexNames, true)) {
+ $this->db->query('CREATE INDEX idx_abdm_consent_id ON abdm_consent_records (consent_id)');
+ }
+
+ if (! in_array('idx_abdm_gateway_consent_id', $indexNames, true)) {
+ $this->db->query('CREATE INDEX idx_abdm_gateway_consent_id ON abdm_consent_records (gateway_consent_id)');
+ }
+ }
+
+ public function down(): void
+ {
+ if (! $this->db->tableExists('abdm_consent_records')) {
+ return;
+ }
+
+ $fields = $this->db->getFieldNames('abdm_consent_records') ?? [];
+
+ if (in_array('gateway_consent_id', $fields, true)) {
+ $this->forge->dropColumn('abdm_consent_records', 'gateway_consent_id');
+ }
+
+ $fields = $this->db->getFieldNames('abdm_consent_records') ?? [];
+ if (in_array('consent_id', $fields, true)) {
+ $this->forge->dropColumn('abdm_consent_records', 'consent_id');
+ }
+ }
+}
diff --git a/app/Database/Migrations/2026-05-28-000606_AddLoincToPathologyTables.php b/app/Database/Migrations/2026-05-28-000606_AddLoincToPathologyTables.php
new file mode 100644
index 0000000..9449ead
--- /dev/null
+++ b/app/Database/Migrations/2026-05-28-000606_AddLoincToPathologyTables.php
@@ -0,0 +1,160 @@
+addLabTestsLoincColumns();
+ $this->addLabRepoLoincColumn();
+ }
+
+ private function addLabTestsLoincColumns(): void
+ {
+ if (! $this->db->tableExists('lab_tests')) {
+ return;
+ }
+
+ $existing = $this->db->getFieldNames('lab_tests') ?? [];
+ $add = [];
+
+ if (! in_array('loinc_code', $existing, true)) {
+ $add['loinc_code'] = [
+ 'type' => 'VARCHAR',
+ 'constraint' => 20,
+ 'null' => true,
+ 'default' => null,
+ 'after' => 'Unit',
+ ];
+ }
+ if (! in_array('loinc_property', $existing, true)) {
+ $add['loinc_property'] = [
+ 'type' => 'VARCHAR',
+ 'constraint' => 50,
+ 'null' => true,
+ 'default' => null,
+ 'after' => 'loinc_code',
+ ];
+ }
+ if (! in_array('loinc_system', $existing, true)) {
+ $add['loinc_system'] = [
+ 'type' => 'VARCHAR',
+ 'constraint' => 50,
+ 'null' => true,
+ 'default' => null,
+ 'after' => 'loinc_property',
+ ];
+ }
+ if (! in_array('loinc_scale', $existing, true)) {
+ $add['loinc_scale'] = [
+ 'type' => 'VARCHAR',
+ 'constraint' => 20,
+ 'null' => true,
+ 'default' => null,
+ 'after' => 'loinc_system',
+ ];
+ }
+ if (! in_array('loinc_synced_at', $existing, true)) {
+ $add['loinc_synced_at'] = [
+ 'type' => 'DATETIME',
+ 'null' => true,
+ 'default' => null,
+ 'after' => 'loinc_scale',
+ ];
+ }
+
+ if ($add !== []) {
+ $this->forge->addColumn('lab_tests', $add);
+ }
+
+ // Index for fast LOINC lookup
+ try {
+ $indexes = $this->db->query('SHOW INDEX FROM lab_tests')->getResultArray();
+ $hasIdx = false;
+ foreach ($indexes as $idx) {
+ if (strcasecmp((string) ($idx['Key_name'] ?? ''), 'idx_lab_tests_loinc') === 0) {
+ $hasIdx = true;
+ break;
+ }
+ }
+ if (! $hasIdx && in_array('loinc_code', $this->db->getFieldNames('lab_tests') ?? [], true)) {
+ $this->db->query('ALTER TABLE lab_tests ADD INDEX idx_lab_tests_loinc (loinc_code)');
+ }
+ } catch (\Throwable $e) {
+ // Non-blocking index creation
+ }
+ }
+
+ private function addLabRepoLoincColumn(): void
+ {
+ if (! $this->db->tableExists('lab_repo')) {
+ return;
+ }
+
+ $existing = $this->db->getFieldNames('lab_repo') ?? [];
+
+ if (! in_array('loinc_code', $existing, true)) {
+ $this->forge->addColumn('lab_repo', [
+ 'loinc_code' => [
+ 'type' => 'VARCHAR',
+ 'constraint' => 20,
+ 'null' => true,
+ 'default' => null,
+ 'after' => 'Title',
+ ],
+ ]);
+ }
+ if (! in_array('loinc_synced_at', $existing, true)) {
+ $this->forge->addColumn('lab_repo', [
+ 'loinc_synced_at' => [
+ 'type' => 'DATETIME',
+ 'null' => true,
+ 'default' => null,
+ 'after' => 'loinc_code',
+ ],
+ ]);
+ }
+ }
+
+ public function down(): void
+ {
+ foreach (['loinc_code', 'loinc_property', 'loinc_system', 'loinc_scale', 'loinc_synced_at'] as $col) {
+ try {
+ if ($this->db->tableExists('lab_tests') &&
+ in_array($col, $this->db->getFieldNames('lab_tests') ?? [], true)) {
+ $this->forge->dropColumn('lab_tests', $col);
+ }
+ } catch (\Throwable $e) {
+ // no-op
+ }
+ }
+
+ foreach (['loinc_code', 'loinc_synced_at'] as $col) {
+ try {
+ if ($this->db->tableExists('lab_repo') &&
+ in_array($col, $this->db->getFieldNames('lab_repo') ?? [], true)) {
+ $this->forge->dropColumn('lab_repo', $col);
+ }
+ } catch (\Throwable $e) {
+ // no-op
+ }
+ }
+
+ try {
+ $this->db->query('ALTER TABLE lab_tests DROP INDEX idx_lab_tests_loinc');
+ } catch (\Throwable $e) {
+ // no-op
+ }
+ }
+}
diff --git a/app/Database/Seeds/LabOemData/01_lab_rgroups.sql b/app/Database/Seeds/LabOemData/01_lab_rgroups.sql
index 0927109..f2e0363 100644
--- a/app/Database/Seeds/LabOemData/01_lab_rgroups.sql
+++ b/app/Database/Seeds/LabOemData/01_lab_rgroups.sql
@@ -11,17 +11,18 @@ CREATE TABLE IF NOT EXISTS `lab_rgroups` (
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb3 ROW_FORMAT=DYNAMIC;
INSERT IGNORE INTO `lab_rgroups` (`mstRGrpKey`, `RepoGrp`, `PreFix`, `Suffix`, `LastNo`, `sort_order`, `Notes`) VALUES
-('1', 'BIO CHEMISTRY', 'BIO', '', '0', '2', ''),
-('2', 'Biopsy', 'BP', '', '0', '3', ''),
-('3', 'CLINICAL PATHOLOGY', 'CP', '', '0', '4', ''),
-('4', 'MICRO BIOLOGY', 'CUL', '', '0', '5', ''),
-('5', 'General', 'GEN', '', '1', '6', ''),
-('6', 'HAEMATOLOGY', 'HAE', '', '0', '1', ''),
-('8', 'Urine', 'US', '', '0', '8', ''),
-('9', 'Fluid Examination', 'FE', '0', '0', '9', '0'),
-('10', 'CYTO-PATHOLOGY', 'CYP', '0', '0', '10', '0'),
-('11', 'HISTOPATHOLOGY', 'HP', '0', '0', '11', '0'),
-('12', 'IMMUNOLOGY-SEROLOGY', 'IS', '0', '0', '12', '0'),
-('13', 'ENDOCRINOLOGY', 'ELO', '0', '0', '13', '0'),
-('15', '', '0', '0', '0', '14', '0');
-
+(1, 'Biochemistry', 'BCH', '', 0, 2, ''),
+(2, 'Biopsy', 'BP', '', 0, 3, ''),
+(3, 'Clinical Pathology', 'CP', '', 0, 4, ''),
+(4, 'Infectious Disease', 'INF', '', 0, 5, ''),
+(5, 'General', 'GEN', '', 1, 6, ''),
+(6, 'Hematology', 'HEM', '', 0, 1, ''),
+(8, 'Urine', 'US', '', 0, 8, ''),
+(9, 'Fluid Examination', 'FE', '0', 0, 9, '0'),
+(10, 'CYTO-PATHOLOGY', 'CYP', '0', 0, 10, '0'),
+(11, 'HISTOPATHOLOGY', 'HP', '0', 0, 11, '0'),
+(12, 'IMMUNOLOGY-SEROLOGY', 'IS', '0', 0, 12, '0'),
+(13, 'Endocrinology', 'END', '0', 0, 13, '0'),
+(16, 'Vitamins & Minerals', 'VTM', '', 0, 24, ''),
+(18, 'Inflammatory Markers', 'INM', '', 0, 26, ''),
+(19, 'Tumor Markers', 'TMR', '', 0, 27, '');
diff --git a/app/Database/Seeds/LabOemData/03_lab_repo.sql b/app/Database/Seeds/LabOemData/03_lab_repo.sql
index 2601fe4..56e30e8 100644
--- a/app/Database/Seeds/LabOemData/03_lab_repo.sql
+++ b/app/Database/Seeds/LabOemData/03_lab_repo.sql
@@ -7,4953 +7,12 @@ CREATE TABLE IF NOT EXISTS `lab_repo` (
`IncludeHeader` tinyint(1) DEFAULT '1',
`IncludeFooter` tinyint(1) DEFAULT '1',
`charge_id` int DEFAULT '0',
+ `loinc_code` varchar(20) DEFAULT NULL,
+ `loinc_synced_at` datetime DEFAULT NULL,
PRIMARY KEY (`mstRepoKey`),
UNIQUE KEY `Title` (`Title`),
KEY `GrpKey` (`GrpKey`),
KEY `charge_id` (`charge_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb3;
-INSERT IGNORE INTO `lab_repo` (`mstRepoKey`, `Title`, `RTFData`, `HTMLData`, `GrpKey`, `IncludeHeader`, `IncludeFooter`, `charge_id`) VALUES
-('0', 'Manual', NULL, NULL, '0', '1', '1', '0'),
-('1', 'COMPLETE BLOOD COUNT (CBC) ', NULL, '
-
-
- Test Name
- Result
- Unit
- Bio. Ref. Interval
-
-
- Haemoglobin
- {HB}
- gm%
- 12-16
-
-
- TLC
- {TLC}
- per cu mm
- 4000-11000
-
-
- DLC
-
-
-
-
-
- Neutrophils
- {NEU}
- %
- 45-70
-
-
- Lymphocytes
- {LYMP}
- %
- 20-45
-
-
- Eosinophils
- {EOSIN}
- %
- 1-8
-
-
- Monocytes
- {MONO}
- %
- 1-6
-
-
- Basophils
- {BASO}
- %
- < 1%
-
-
- RBC Count
- {RBC}
- Million/cm
- 4.2-5.5
-
-
- PCV
- {PCV}
- %
- 40 - 54
-
-
- MCV
- {MCV}
- fl
- 80-100
-
-
- MCH
- {mch}
- pg
- 28-35
-
-
- MCHC
- {MCHC}
- g/dl
- 30-38
-
-
- Platelet Count
- {PLATELET}
- Lakh per cu mm
- 1.5-4.5
-
-
- ESR
- {ESR1}
- Mm for 1st hr.
- < 9 >
-
-
-
-', '6', '1', '1', '382'),
-('2', 'LIVER FUNCTION TEST (LFT) ,SERUM', NULL, ' (Spectrophotometry)
-
-
-
-
- Test Name
- Result
- Unit
- Bio. Ref. Interval
-
-
- Bilirubin (Total)
- {SERBIL}
- mg/dl
- 0.3-1.2
-
-
- Bilirubin (Direct)
- {BD}
- mg/dl
- < 0.3
-
-
- Bilirubin (Indirect)
- {BI}
- mg/dl
- < 0.8
-
-
- SGOT / Aspartate Aminotransferase (AST)
- {SGOT}
- U/L
- < 35
-
-
- SGPT/ Alanine Aminotransferase (ALT)
- {SGPT}
- U/L
- < 40
-
-
- Alkaline Phosphatase (Total)
- {SALKALINE}
- U/L
- 25-140
-
-
- Protein(Total)
- {TOTPRO}
- gm/dl
- 6.2-8.0
-
-
- Albumin
- {ALBU}
- gm/dl
- 3.8-5.4
-
-
- Globulin
- {GLOB}
- gm/dl
- 1.8-3.6
-
-
- A:G Ratio
- {AGR}
-
- 1.1-2.0
-
-
-
-', '1', '1', '1', '286'),
-('3', 'RENAL FUNCTION TEST (KFT)', NULL, '
-
-
- Test Name
- Result
- Unit
- Bio. Ref. Interval
-
-
- Urea
- {BU}
- mg/dL
- 11-37
-
-
- Creatinine
- {SC}
- mg/dL
- 0.6-1.4
-
-
- Uric Acid
- {SUA}
- mg/dL
- 2.6-7.2
-
-
- Calcium
- {SCA}
- mg/dL
- 8.6-10.3
-
-
- Sodium
- {SS}
- m Mol /L
- 135-155
-
-
- Potassium
- {SP}
- m Mol /L
- 3.5-5.5
-
-
-
-', '1', '1', '1', '289'),
-('4', 'C-Reactive Protein(C.R.P.)', NULL, '
-
-
- Test Name
- Result
- Unit
- Bio.Ref. Interval
-
-
- C-Reactive Protein(C.R.P.)
-
- {CRP}
- {CRPSTATUS}
- mg/l
- Adults : < 6 mg/L
- New Bron Baby upto 3 weeks : <4.1 mg/L
- Infants and Children : <2.8 mg/L
-
-
-
-', '1', '1', '1', '387'),
-('5', 'F.N.A.C.', NULL, 'CYTOPATHOLOGY
-
-F.N.A.C.
-
-{BPART}
-
-REPORT :
-
-
-', '5', '1', '1', '351'),
-('6', 'Anti - HIV (I & II) ANTIBODIES', NULL, '
-
-
- Test Name
- Result
- Method
-
-
- Anti - HIV I & II
- ANTIBODIES
- {HIV1}
- IMMUNOCHROMATOGRAPHY
-
-
-
-
-INTERPRETATION :
-1.This is only a screening test.All reactive sample should be confirmatory test.
-2.A negative result implies that no Anti HIV – II antibodies have been detected in the sample by this method.
-3.A positive result suggests the possibilities of HIV-I and / or HIV-II infection.However these results must be verified by a confirmatory test (IFA / WESTERN BLOT I-II) before pronouncing the patient positive for HIV-I and / r HIV-II infection.
-', '12', '1', '1', '295'),
-('7', 'HBsAg', NULL, '
-
-
- Test Name
- Result
- Method
-
-
- HBsAg*
- (AUSTRALIA ANTIGEN)
-
- {HBsAG}
- IMMUNOCHROMATOGRAPHY
-
-
-
-
-Note: This is only a screening test. All reactive sample should be confirmatory test.Therefore for a definitive diagnosis, the patient’s clinical history, symptomatology as well as serological data,should be considered.Additional follow up testing using available clinical methods(along with repeat card test)is required,if card test is non-reactive with persisting clinical symptoms.False positive results can be obtained due to the presence of other antigens or elevated levels of RF factor.The presence of HBsAg in the serum indicates either a chronic or acute infection with virus,HBeAG may be advised for further evaluation.
-', '12', '1', '1', '336'),
-('8', 'Serum Prolactin', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- Serum Prolactin
- {SProlactin}
- ng/ml
- 5-35
-
-
-
-
-
-', '13', '1', '1', '225'),
-('9', 'Vitamin D', NULL, 'Bio-Chemistry
-
-
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- Vitamin D
- {VITD}
- ng/ml
- Reference Range:
- Deficent : < 20
- Insufficent : 20-29
- Sufficent : 30-100
- Potential Toxicity > 100
-
-
-
-
-
-', '13', '1', '1', '162'),
-('10', 'Glycosylated Hemoglobin (HbA1c)*,EDTA BLOOD', NULL, '
-
-
-
- Test Name
-
-
- Result
-
-
- Unit
-
-
- Bio.Ref.Interval
-
-
- Method
-
-
-
-
- GLYCOSYLATED HAEMOGLOBIN (HBA1C) * , EDTA BLOOD
- Glycosylated Haemoglobin (HbA1c)
-
-
- {HBA1C}
-
-
- %
-
-
- < 5.7 Non diabetic
- adults>=18 years
- 5.7-6.4 At risk
- (Prediabetes)
- >= 6.5 Diabetes
- (As per ADA)
-
-
- QUANTITATIVE TURBIDIMETRIC IMMUNOASSAY
-
-
-
-
-
-Interpretation:
- 1 HbA1c testing provides an index of any blood glucose over past 2 to 4 months.
-
- 2 Approx 50% of HbA1c determined by previous 1 month and 75% during previous 2 months.
-
-3 Hba1c levels are lowered by
-
-(a) shortened RBC survival or lower mean RBC are eg. hemolysis,transfusions,recovery from acure blood loss.
-
-(b) Hyperglycernia decreases erythrocyte survival on long term,so in poorly controlled patients may underestimate their mean plasma glucose concertration.
-
-(c) Accuracy also effected by hemoglobinopathies HbSS,HbSC,HbCC) associated with high cell turnovers chronic alcohol or opiate use,iron deficency and lead
-
- Poisoning and advanced chronic kidney disease.
-
-ADA criteria between HbA1c and plasma glucose levels.
-
-
-
-
- Hemoglobin a/c(%)
-
- Approximate mean plasma
-
- Glucose (mg/dl)
-
-
-
-
-
-
-
-
- 5
- 97
-
-
- 6
- 126
-
-
- 7
- 154
-
-
- 8
- 183
-
-
- 9
- 212
-
-
- 10
- 240
-
-
- 11
- 269
-
-
- 12
- 298
-
-
-
-
-Uncertainity in accuracy in children.
-
-
-
-
-', '1', '1', '1', '337'),
-('11', 'Semen Analaysis', NULL, 'PHYSICAL CHARACTERISTICS
-
-
-
-
- Volume
- {vol}
-
-
-
- Colour
- {sem_color}
- PEARLY WHITE
-
-
- Reaction
- {semen_reaction}
- ALKALINE
-
-
- Viscosity
- {Viscosity}
- VISCOUS
-
-
- Liquification Time
- {LIQTIME} min
- < 30 MIN
-
-
-
-
-MICROSCOPIC FEATURES
-
-
-
-
- Total Sperm Count
- {TOTSPCOUNT} millions /ml
- 15-200
-
-
- Active
- {semen_active} %
- >60 %
-
-
- Sluggish
- {SLUGGISH} %
- <30 %
-
-
- Non Motile
- {NONMOTILE} %
- <20 %
-
-
- Abnormal Forms
- {Abnormal} %
- <30 %
-
-
- Pus Cells
- {PUSCELL} /HPF
- NIL
-
-
- Epithelial cells
- {EPITH} /HPF
- NIL
-
-
- RBCs
- {sRBC} /HPF
- NIL
-
-
- Remarks
- {SEMENREMARKS}
-
-
-
-
-
-
-', '12', '1', '1', '243'),
-('12', 'ADA-MTB', NULL, 'ADA-MTB
-
-FOR THE DETERMINATION OF ADENOSINE DEAMINASE ACTIVITY IN SERUM, PLASMA & BIOLOGICAL FLUIDS
-
-{THEAD} :{THV}
-
-Reference Values :
-
-
-
-
- Serum,Plasma,Pleural,
- Pericadial & Ascitic Fluids
- Normal : <30 U/L
- Suspect : 30- 40 U/L
- Strong Suspect : 41 - 60 U/L
- Positive : >60 u/l
-
-
- CSF
- Normal : < 10 U/L
- Positive : > 10 U/L
-
-
-
-
-
-', '5', '1', '1', '422'),
-('13', 'Blood Glucose Random', NULL, '
-
-
- Test Name
- Result
- Unit
- Bio. Ref. Interval
-
-
-
-
-
-
-
-
-
-
- BLOOD GLUCOSE RANDOM
-
- {AGR1}
- mg/dL
- 70.00-140.00
-
-
-
-
-Note
-
-
- The diagnosis of Diabetes requires a fasting plasma glucose of > or = 126 mg/dL and/or a random / 2 hr post glucose value of > or = 200 mg/dL on at least 2 occasions.
- Very low glucose levels cause severe CNS dysfunction.
- Very high glucose levels (>450 mg/dL in adults) may result in Diabetic Ketoacidosis & is considered critical.
-
-
-
-
-
-', '1', '1', '1', '397'),
-('14', 'Prothrombin Time With INR', NULL, '
-
-
- Patients Prothombin Time Value
- {PPTV} sec.
-
-
- Control Prothombin Time Value
- (Normal Range is 11 to 16sec. )
- {CPTV} sec.
-
-
- Patient INR Value
- {PINRV}
-
-
- Oral Anticoauglant Therapeutic Range
- {OATR}
-
-
-
-
-
-', '1', '1', '1', '255'),
-('15', 'APTTY / PTTK', NULL, '
-
-
- Test Name
- Result
- Unit
- Bio.Ref. Interval
- Method
-
-
- Prothrombin Time (PT) *
- Sample:Plasma
- {PT}
- secs
- 11 - 16
- MACHANICAL CLOT DETECTION
-
-
-
-
-Interpretation:
-The test is used for the determination of the blood clotting factors II, V, VII and X (factors assays), for monitoring oral anticoagulant therapy, for diagnosis of acquired or inherited bleeding disorders.
-
-PTT (PARTIAL THROMBOPLASTIN TIME), ACTIVATED / APTT * , Plasma
-
-
-
-
- Test Name
- Result
- Unit
- Bio.Ref. Interval
- Method
-
-
- PTT (Partial Thromboplastin Time),Activated / APTT
- {PAPT}
- secs
- 30 - 40
- MACHANICAL CLOT DETECTION
-
-
- Control Value
- {CAPT}
- secs
- 30
- MACHANICAL CLOT DETECTION
-
-
-
-
-Interpretation:
-A P T T values within 5 seconds of control time should be considered normal, probably abnormal if results are 10-20 sec longer than control and a definite abnormality with result > 20 sec longer than control
-', '6', '1', '1', '411'),
-('16', 'Glucose Fasting*,Plasma', NULL, '
-
-
- Test Name
- Result
- Unit
- Bio. Ref. Interval
- Method
-
-
- Glucose Fasting*
- Sample:Plasma
- {BGF}
- mg/dl
- < 99 Normal
- 100-125 Near Normal
- I.G.T)
- > 126 Diabetic
- GOD POD
-
-
-
-
-
-', '1', '1', '1', '396'),
-('17', 'Glucose (PP)*,Plasma', NULL, '
-
-
- Test Name
- Result
- Unit
- Bio. Ref. Interval
- Method
-
-
- Glucose PP*
- Sample:Plasma after meal
- {BGPP}
- mg/dl
- 80-140
- GOD POD
-
-
-
-', '1', '1', '1', '398'),
-('18', 'C.S.F. Aspiration', NULL, 'Physical Examination
-
-
-
-
-
- Observed Value
- Normal Value
-
-
- Appearance
- {APP}
- CLEAR
-
-
- Colour
- {COLOUR}
- STRAW
-
-
- Coagulum
- {COALGU}
- ABSENT
-
-
-
-
-Chemical Examination
-
-
-
-
-
- Observed Value
- Normal Value
-
-
- Proteins
- {PROTEINS}
- 10 TO 40 mg/dl
-
-
- Sugar
- {SUGAR}
- 40-70 mg/dl
-
-
-
-
-Microscopic Examination
-Total Cell Count : {TCC} /cmm : Range Between (0 to 9)
-
-
-
-
- Differential Cell Count
-
-
-
- Polymorphs
- {Polymorphs}
-
-
-
- Lymphocytes
- {Lymphocyte}
-
-
-
- Monocytes
- {Monocytes}
-
-
-
- R.B.Cs
- {RBCS}
-
-
-
- Others
- {OTHER}
-
-
-
-
-
-
-
-
- Gram Stain
- {GRAMSTAIN}
-
-
-
- Stain For A.F.B
- {AFB}
-
-
-
-
-
-', '9', '1', '1', '386'),
-('19', 'T3,T4,TSH', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- Triiodothyronine [T3]
- {T3}
- ng/ml
- 0.00-1.51 ng/ml
-
-
- Thyroxine [T4]
- {T4}
- ug/dl
- 4.66-9.32 ug/dl
-
-
- Thyroid Stimulating Hormone (TSH)
- {TSH}
- ulU/mL
- 0.25-5.00 ulU/mL
-
-
-
-
-
-', '13', '1', '1', '207'),
-('20', 'Pleural Fluid Examination', NULL, 'Physical Examination
-
-
-
-
-
- Observed Value
- Normal Value
-
-
- Appearance
- {APP}
- CLEAR
-
-
- Colour
- {COLOUR}
- STRAW
-
-
- Coagulum
- {COALGU}
- ABSENT
-
-
-
-
-Chemical Examination
-
-
-
-
-
- Observed Value
-
-
- Proteins
- {PROTEINS}
-
-
- Sugar
- {SUGAR}
-
-
-
-
-Microscopic Examination
-Total Cell Count : {TCC} /cmm
-
-
-
-
-
-
- Differential Cell Count
-
-
-
- Polymorphs
- {Polymorphs}
-
-
-
- Lymphocytes
- {Lymphocyte}
-
-
-
- Mesothelial
- {MESO}
-
-
-
- R.B.Cs
- {RBCS}
-
-
-
-
-
-
-
-
- Gram Stain
- {GRAMSTAIN}
-
-
-
- Stain For A.F.B
- {AFB}
-
-
-
-
-
-', '9', '1', '1', '258'),
-('21', 'Bilirubin*,Serum', NULL, '
-
-
- Test Name
- Result
- Unit
- Bio.Ref. Interval
- Method
-
-
-
- Bilirubin Total*
- Sample:Serum
-
-
- {BT}
-
-
- mg/dl
-
-
- 0.20-2.00
-
-
- DIAZO
-
-
-
-
- Bilirubin Direct*
- Sample:Serum
-
-
- {BD}
-
-
- mg/dl
-
-
- 0.7-1.3
-
-
- DIAZO
-
-
-
-
- Bilirubin Indirect*
- Sample:Serum
-
-
- {BI}
-
-
- mg/dl
-
-
- 0.00-0.70
-
-
- DIAZO
-
-
-
-
-
-
-', '1', '1', '1', '404'),
-('22', 'Troponin T (Trop T)', NULL, 'Troponin : {TROP}
-', '12', '1', '1', '190'),
-('23', 'Troponine I (Trop I)', NULL, 'Troponine I (Trop I) : {TROPI}
-', '12', '1', '1', '191'),
-('24', 'SERUM PROTEIN', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- SERUM PROTEIN
- {SPro}
- mg%
- 6-8mg%
-
-
-
-', '1', '1', '1', '224'),
-('25', 'SERUM BILIRUBIN [TOTAL]', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- SERUM BILIRUBIN TOTAL
- {SERBIL}
- mg%
- 0.20-2.00 mg%
-
-
-
-
-
-', '1', '1', '1', '240'),
-('26', 'SGOT / Aspartate Aminotransferase (AST)*,Serum ', NULL, '
-
-
- Test Name
- Result
- Unit
- Bio.Ref.Interval
- Method
-
-
- SGOT / Aspartate Aminotransferase (AST)*
- Sample:Serum
- {SGOT}
- U/L
- < 35
- IFCC
-
-
-
-
-', '1', '1', '1', '245'),
-('27', 'SGPT / Alanine Aminotransferase (ALT)*,Serum', NULL, '
-
-
- Test Name
- Result
- Unit
- Bio.Ref.Interval
- Method
-
-
- SGPT / Alanine Aminotransferase (ALT)*
- Sample:Serum
- {SGPT}
- U/L
- < 40
- IFCC
-
-
-
-', '1', '1', '1', '244'),
-('28', 'T.L.C.', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- TLC
- {TLC1}
- /cu mm
- 4000.00-11000.00 /cu mm
-
-
-
-', '6', '1', '1', '209'),
-('29', 'D.L.C.', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- D.L.C.
-
-
-
-
-
- NEUTROPHILS
- {NEU}
- %
- 45.00-70.00 %
-
-
- LYMPHOCYTES
- {LYMP}
- %
- 20.00-45.00 %
-
-
- EOSINOPHILS
- {EOSIN}
- %
- 1.00-8.00 %
-
-
- MONOCYTES
- {MONO}
- %
- 1.00-6.00 %
-
-
- BASOPHILES
- {BAND}
- %
-
-
-
-
-
-
-', '6', '1', '1', '367'),
-('30', 'NEUTROPHILS', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- NEUTROPHILS
- {NEU}
- %
- 45.00-70.00 U/L
-
-
-
-', '6', '1', '1', '425'),
-('31', 'LYMPHOCYTES', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- LYMPHOCYTES
- {LYMP}
- %
- 20.00-45.00 %
-
-
-
-', '6', '1', '1', '426'),
-('32', 'Absolute Eosinophil Count', NULL, '
-
-
- Test Name
- Result
- Unit
- Bio.Ref. Interval
- Method
-
-
- Absolute Eosinophil Count
- {AEOSIN}
- per cu mm
- 40-440
- MICROSCOPIC EXAMINATION
-
-
-
-', '6', '1', '1', '427'),
-('33', 'RBC', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- RBC
- {RBC}
- million/cm
- 3.50-5.00
-
-
-
-', '6', '1', '1', '250'),
-('34', 'PCV', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- PCV
- {PCV}
- %
- 34.00-47.00
-
-
-
-', '6', '1', '1', '261'),
-('35', 'MCV', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- MCV
- {MCV}
- pg
- 25.00-33.00
-
-
-
-', '6', '1', '1', '273'),
-('36', 'MCH', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- SGOT/ALT
- {SGPT}
- U/L
- 10.00-45.00 U/L
-
-
-
-', '6', '1', '1', '275'),
-('37', 'MCHC', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- MCHC
- {MCHC}
- g/dl
- 28.00-36.00
-
-
-
-', '6', '1', '1', '274'),
-('38', 'PLATELET COUNT', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- PLATELET COUNT
- {PLATELET}
- LAKH PER CU MM
- 150000-450000
-
-
-
-', '6', '1', '1', '259'),
-('39', 'Blood Urea*,Serum', NULL, '
-
-
- Test Name
- Result
- Unit
- Bio.Ref.Interval
- Method
-
-
- Blood Urea*
- Sample: Serum
- {BU}
- mg/dL
- 15-45
- GLDH
-
-
-
-
-
-', '1', '1', '1', '393'),
-('40', 'Creatinine*,Serum', NULL, '
-
-
- Test Name
- Result
- Unit
- Bio.Ref.Interval
- Method
-
-
- Creatinine*
- Samle:Serum
- {SC}
- mg/dl
- 0.7-1.3
- ALKALNIE PICRATE
-
-
-
-
-
-', '1', '1', '1', '237'),
-('41', ' Uric Acid,*Serum', NULL, '
-
-
- Test Name
- Result
- Unit
- Bio.Ref. Interval
- Method
-
-
- Uric Acid*
- Sample:Serum
- {SUA}
- mg/dl
- 2.6-7.2
- URICASE
-
-
-
-', '1', '1', '1', '221'),
-('42', 'SERUM SODIUM', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- SERUM SODIUM
- {SS}
- mmpl/L
- 135.00-148.00
-
-
-
-', '1', '1', '1', '223'),
-('43', 'Potassium*,Serum', NULL, '
-
-
- Test Name
- Result
- Unit
- Bio.Ref.Interval
- Method
-
-
- Potassium*
- Sample:Serum
- {SP}
- m Mol /L
- 3.8-5.4
- ISE
-
-
-
-
-
-', '1', '1', '1', '226'),
-('44', 'Calcium*,Serum', NULL, '
-
-
- Test Name
- Result
- Unit
- Bio. Ref. Interval
- Method
-
-
- Calcium*
- Sample:Serum
- {SCA}
- mg/dl
- 8.8-10.2
- ARSENAZO III
-
-
-
-
-(*) Test not done under NABL accredited Scope, (**) Test Performed at Apollo Diagnostics & Path Lab.
-
-This report is not for medico legal purpose. If clinical correlation is not established, kindly repeat the test at no additional cost within seven days.
-
-
-', '1', '1', '1', '239'),
-('45', 'SERUM ALBUMIN', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- SERUM ALBUMIN
- {SA}
- mg/dl
- 3.50-5.50
-
-
-
-', '1', '1', '1', '421'),
-('46', 'SERUM GLOBULIN', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- SERUM GLOBULIN
- {SG}
- mg/dl
- 2.00-3.50
-
-
-
-', '1', '1', '1', '344'),
-('47', 'ESR*,Blood', NULL, '
-
-
- Test Name
- Result
- Unit
- Bio.Ref.Interval
- Method
-
-
- ESR*, Blood
- {ESR1}
- mm in 1st hr.
- < 9
-
-
-
-
-(*) Test not done under NABL accredited Scope, (**) Test Performed at Apollo Diagnostics & Path Lab.
-
-This report is not for medico legal purpose. If clinical correlation is not established, kindly repeat the test at no additional cost within seven days.
-
-
-', '6', '1', '1', '358'),
-('48', 'S. ALKALINE PHOSPHATASE', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- S. ALKALINE PHOSPHATASE
- {SALKALINE}
- U/L
- 50.00-128.00
-
-
-
-', '1', '1', '1', '417'),
-('50', 'Gram Stain', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- Gram Stain
- {GRAMSTAIN}
-
-
-
-
-
-', '4', '1', '1', '3417'),
-('51', 'T3 (TRIIODOTHYROININE)', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- T3
- {T3}
- ng/ml
- 0.60-1.51
-
-
-
-', '13', '1', '1', '208'),
-('52', 'T4 (THYROXINE)', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- T4
- {T4}
- ug/dl
- 4.66-9.32
-
-
-
-', '13', '1', '1', '206'),
-('54', 'Hemoglobin*', NULL, '
-
-
- Test Name
- Result
- Unit
- Bio. Ref. Interval
- Method
-
-
- Haemoglobin*
- Sample:Blood
- {HB}
- g/dl
- 13.5 - 17.5
-
- PHOTOMETRIC
-
-
-
-
-', '6', '1', '1', '333'),
-('55', 'URINE EXAMINATION, ROUTINE * ,Urine', NULL, ' (Automated Strip Test, Microscopy)
-
-
-
-
- Test Name
- Result
- Unit
- Bio.Ref.Interval
-
-
- Physical Examination
-
-
-
-
-
- Colour
- {urine_colo}
-
- Pale Yellow
-
-
- Appearance
- {urine_tran}
-
- Clear
-
-
- Specific Gravity
- {usg}
-
- 1.003-1.035
-
-
- pH
- {urine_ph}
-
- 4.7-7.5
-
-
-
-
-
-
-
-
- Chemical Examination
-
-
-
-
-
- Protein
- {urine_albu}
- mg%
- NIL
-
-
- Glucose
- {urine_suga}
- gms%
- NIL
-
-
-
-
-
-
-
-
-
-
- Microscopic Examination
-
-
-
-
-
- Pus Cells
- {upuscells}
- /hpf
- 0-5
-
-
- Epithial Cells
- {uepithial}
- /hpf
- 0-5
-
-
- RBCs
- {urbc}
- /hpf
- 0-3
-
-
- Casts
- {urinecasts}
- /hpf
- Not Detected
-
-
- Crystals
- {urinecryst}
- /hpf
- Not Detected
-
-
- Bacteria flora few
- {BFF}
-
-
-
-
-
-
-
-', '3', '1', '1', '174'),
-('56', 'LIPID PROFILE', NULL, '
-
-
- Test Name
- Result
- Bio. Ref.Interval
-
-
- Cholesterol(Total)
- {l_Choleste} mg/dl
- <200 Desirable
- 200-239 Borderline High
- > 240 High
-
-
- Triglyceride
- {l_Triglyce} mg/dl
- < 150 Normal
- 150-199 Borderline High
- 200-499 High
- >500 Very High
-
-
- HDL Cholesterol ( Good Cholesterol )
- {l_hdl} mg/dl
- 30-70
-
-
- LDL Cholesterol ( Bad Cholesterol ) ( Direct )
- {l_ldl} mg/dl
- < 100 Optimal
- 100-129 Nr.
- Optimal/Above Optimal
- 130-159 Borderline High
- 160-189 High
- > 190 Very High
-
-
- VLDL
- {l_vldl} mg/dl
- 10-33
-
-
-
-', '1', '1', '1', '282'),
-('57', 'BT - CT', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- BLEEDING TIME
- {blood_bt}
- min.
- upto 7 min
-
-
- CLOTTING TIME
- {blood_ct}
- min.
- 4.00 - 12.00 min.
-
-
-
-
-
-', '6', '1', '1', '388'),
-('58', 'Anti - HCV', NULL, '
-
-
- Test Name
- Result
- Method
-
-
- Anti - HCV*
- (Hepatitis C Virus)
- Sample: Serum
- {hcv}
- IMMUNOCHROMATOGRAPHY
-
-
-
-
-Note: The hepatitis C virus HCV is now the cause of 90% post transfusion hepatitis it is also found in drug addicts and also contributes to sporadic acute viral hepatitis –HCV is a RNA flavi virus and the incubation period may be short (1-4 weeks ) or long ( 6-12 weeks . chronicity of infection is reported in > 10 % .The frequency of post transfusion hepatitis can be definitely reduced with help of serological assays available for HCV.
-', '12', '1', '1', '335'),
-('59', 'TSH', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- Thyroid Stimulating Hormone (TSH)
- {TSH}
- ulU/mL
- 0.25-5.00 ulU/mL
-
-
-
-
-
-', '13', '1', '1', '189'),
-('60', 'GENERAL BLOOD PICTURE(GBP)', NULL, 'RBC- shows moderate degree of anisopoikilocytosis. Dimorphic population of rbc's are present comprising of both microcytic hypochromic as well as normocytic normochromic cells along with some tear drop cells, pencil cells and few schistiocytes.
-
-WBC- TLC is within normal range and DLC shows normal distribution of cells.
-
-PLATELETS- are adequate with normal morphology.
-
-No Hemoparasite seen
-
-IMPRESSION- DIMORPHIC ANEMIA WITH PREDOMINANCE OF MICROCYTIC HYPOCHROMIC CELLS.
-
-
-', '6', '1', '1', '345'),
-('61', 'PAP SMEAR', NULL, '
-
-
- Speciman
- :
- Cervical / vaginal cytology
-
-
- Clinical History
- :
- Post menopausal
-
-
-
-
-
-
-
- Microscopy
- :
- By Bethesda system
-
-
-
- Adequacy
- :
- Adequate
-
-
-
- Microscopy
- :
- Smears shows superficial, intermediate squamous cells & parabasal cells with many polymorph
-
- No trichomonas or fungal organism seen
-
-
-
- Endocervical Cells
- :
- Present
-
-
-
- Koilocytotic Cells
- :
- Absent
-
-
-
- Dysplastic Cells
- :
- Absent
-
-
-
- Malignant Cells
- :
- Absent
-
-
-
-
-
-
-
-
-
-
-
-
- Impression
- :
- Negative for Intraepithelial lesion and malignancy
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-', '10', '1', '1', '262'),
-('62', 'Ra Factor', NULL, '
-
-
- Test Name
- Observed Value
- Unit
-
-
- R A Factor
- Negative
- IU/ml
-
-
-
-
-INTERPRETATION:
-
-<20 IU/ml = negative
-21-25 IU/ml = borderline
->25 IU/ml = positive
-
-COMMENTS
-
-Owing to the nature of RF, an all purpose cut-off value between a positive
-& negative result is considered impractical
-
-Highly elevated values are found mainly in rheumatoid arthritis, whereas nonspecific positive generally give low values.
-', '1', '1', '1', '251'),
-('63', 'Widal Test', NULL, ' WIDAL TEST
-
-Slide agglutination test for Salmonella group of organisms reveal following titers....
-
-
-
-
-
- Dilution
-
-
- 1/20
-
-
- 1/40
-
-
- 1/80
-
-
- 1/160
-
-
- 1/320
-
-
-
-
- S TYPHI " O "
-
-
- {STyphiO1}
-
-
- {STyphiO2}
-
-
- {STyphiO3}
-
-
- {STyphiO4}
-
-
- {STyphiO5}
-
-
-
-
- S TYPHI " H "
-
-
- {STyphiH1}
-
-
- {STyphiH2}
-
-
- {STyphiH3}
-
-
- {STyphiH4}
-
-
- {STyphiH5}
-
-
-
-
- S PARATYPHI " AH "
-
-
- {SParaTyphiAH1}
-
-
- {SParaTyphiAH2}
-
-
- {SParaTyphiAH3}
-
-
- {SParaTyphiAH4}
-
-
- {SParaTyphiAH5}
-
-
-
-
- S PARATYPHI " BH "
-
-
- {SParaTyphiBH1}
-
-
- {SParaTyphiBH2}
-
-
- {SParaTyphiBH3}
-
-
- {SParaTyphiBH4}
-
-
- {SParaTyphiBH5}
-
-
-
-
-
-COMMENT: WIDAL TEST IS “ NEGATIVE ”
-
-NOTE : Titers of agglutinins to Salmonella antigens , somatic (0) in values upto 40 and for Flagellar (H) in values up to 80 are the endemic titers. Agglutinins may also rise in the serum following Typhoid immunization, past Salmonella infections or infections due to Enterobacteriaceae sharing common antigens. Agglutinins on the other hand may not rise in patients receiving effective antibiotic therapy early in the course of Salmonellosis.
-Diagnostic value of Widal test is increased if rising titers are demonstrated in serial samples.
-', '12', '1', '1', '160'),
-('64', 'Serum Amylase', NULL, '
-
-
- Test Name
- Result
- Unit
- Normal Values
-
-
- Serum Amylase
- {AMYLASE}
- IU/L
- 20.00-80.00 IU/L
-
-
-
-
-
-', '1', '1', '1', '241'),
-('65', 'Serum Lipase', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- Serum Lipase
- {LIPASE}
- U/L
- 0-60 U/L
-
-
-
-', '1', '1', '1', '229'),
-('66', 'Serum Cholesterol', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- Serum Cholesterol
- {Cholestero}
- mg/dl
- 130-200 mg/dl
-
-
-
-', '1', '1', '1', '238'),
-('67', 'Serum Trigycerides', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- Serum Trigycerides
- {Trigycerides}
- mg/dl
- 45-160mg/dl
-
-
-
-', '1', '1', '1', '222'),
-('68', 'Blood Group RH', NULL, '
-
-
- Blood Group
- Rh ( Anti - D)
-
-
-
-
- {ABO}
- {RHF}
-
-
-
-', '6', '1', '1', '395'),
-('69', 'URINE PREGNANCY', NULL, 'URINE FOR PREGNANCY : {PREGNANCYT}
-', '8', '1', '1', '178'),
-('70', 'STOOL ROUTINE EXAMINATION', NULL, '
-
-
- Test Name
-
- Observed Values
-
-
- Physical Examination
-
-
-
-
- Colour
-
- {stool_colo}
-
-
- Consistency
-
- {Consistenc}
-
-
- Mucus
-
- {Mucus}
-
-
- PH
-
- {SPH}
-
-
-
-
-
-
-
- Chemical Examination
-
-
-
-
- Reducing Sugar
-
- {RSugar}
-
-
-
-
-
-
-
- Microscopic Examination
-
-
-
-
- Pus Cells
-
- {PCells}
-
-
- RBCs
-
- {sRBC}
-
-
- Ova
-
- {Ova}
-
-
- Cyst
-
- {Cyst}
-
-
- Fat Globules
-
- {FatGlobuli}
-
-
-
-
-
-', '3', '1', '1', '213'),
-('71', 'TYPHOID IgG & IgM*,Serum', NULL, '
-
-
- Test Name
- Result
- Unit
- Bio.Ref.Interval
- Method
-
-
- TYPHOID, IgG*
- Sample:Serum
- {IgG}
-
-
- IMMUNOCHROMATOGRAPHY
-
-
- TYPHOID, IgM*
- Sample:Serum
- {IgM}
-
-
- IMMUNOCHROMATOGRAPHY
-
-
-
-
-TEST RESULTS : RESULTS & CLINICAL INTERPRETATION
-IgM Positive only : Acute Typhoid Fever
-IgG & IgM Positive : Acute Typhoid fever(in the middle stage of infection)
-IgG Positive only : Relapse or reinfection or previous infection(Current fever may not be due to Typhoid)
-IgM & IgG Negative : No Typhoid fever
-
-This test is highly specific in detecting typhoid fever.The 95% sensitivity of the test is much more superior to either Culture or Widal test. Very high positive predictivity value and negative predictivity value of TYPHOID IgG & IgM is also far more superior to both Culture and Widal test. Dot EIA for typhoid fever is the first known qualitative antibody detection test against a specific antigen of Salmonella Typhi,the causative agent for typhoid fever. The test detects both IgG and IgM antibodies separately and simultaneously to indicate the status of acute infection or previous exposure and takes only 1 Hr to complete as compare to longer period in case of both culture and Widal Test.
-
-
-
-
-', '12', '1', '1', '188'),
-('72', 'MALARIA ANTIGEN', NULL, '
-
-
- Test Name
- Result
- Unit
- Bio.Ref.Interval
- Method
-
-
- Malarial Antigen
- P.Vivax *
- Sample:Blood
- {MALARIA}
-
-
- IMMUNOCHROMATOGRAPHY
-
-
- Malarial Antigen
- Falciparum*
- Sample:Blood
- {MALARIA}
-
-
- IMMUNOCHROMATOGRAPHY
-
-
-
-
-
-
- (*) Test not done under NABL accredited Scope
-
-', '6', '1', '1', '278'),
-('73', 'GAMA GT', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- GAMMA GT
- {GAMAGT}
- IU/L
- 9-52IU/L
-
-
-
-', '1', '1', '1', '346'),
-('74', 'CPK-NAC', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- CPK-NAC
- {CPNACK}
- IU/L
- 35-174IU/L
-
-
-
-', '1', '1', '1', '374'),
-('75', 'CPK-MB', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- CPK-MB
- {CPKMB}
- IU/L
- <24 IU/L
-
-
-
-', '1', '1', '1', '375'),
-('76', 'PSA(PROSTATIC SPECIFIC ANTIGEN)', NULL, 'PSA : {PSA} ng/ml
-
-
-
-
-
- NORMAL RANGE: <40Yrs - 0.21-1.72 40-49 Yrs - 0.27-2.19
-
- 50-59 Yrs - 0.27-3.42 60-69 Yrs - 0.22-6.17
-
- >60 Yrs - 0.21-6.77
-
- SERUM TESTING FOR PSA IS VERY IMPORTANT TOOL TO SCREEN FOR PROSTATE CANCER AND TO MONITOR THERAPY OF THIS DISEASE. PSA IS PROSTATE-SPECIFIC BUT NOT CANCER-SPECIFIC AND APART FROM PROSTATE CANCER INCREASED LEVELS MAY BE FOUND IN BENIGN PROSTATE HYPERTROPHY, PROSTATITIS, INCREASING AGE, ACUTE RETENTION OF URINE, INFECTION AND PROSTATE BIOPSY.
-
- PSA IS RARELY RAISED IN HEALTY MEN AND IS ABSENT IN NORMAL WOMEN. THERE IS NO PSA PRESENT IN ANYOTHER NORMAL TISSUE FROM MEN OR IN PATIENTS WITH OTHER CANCERS OF THE BREAST, LUNG, COLON, RECTUM, STOMACH PANCREAS OR THYROID.
-
-
-
-
-
-
-', '1', '1', '1', '254'),
-('77', 'RETICULOCYTE COUNT', NULL, '
-
-
- Test Name
- Value
- Unit
- Normal Value
-
-
- RETICULOCYTE COUNT
- {Reticount}
- %
- 0.20 - 2.00 %
-
-
-
-
-
-', '6', '1', '1', '249'),
-('78', 'ASO Titer', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- ASO
- {ASO}
- IU/mL
- <200IU/mL
-
-
-
-', '1', '1', '1', '409'),
-('79', 'DENGUE', NULL, '
-
-
- TEST
- RESULT
-
-
- Dengue Ns1
- {DNS1}
-
-
- Dengue IgM
- {DIGM}
-
-
- Dengue IgG
- {DIGG}
-
-
-
-
-Dengue viruses is a flavivirus found largely in areas of the tropic and sub-tropics. There are four distinct but antigeniclly related serotypes of dengue viruses, and transmission is by mosquito, principally Aedes aegypti and Aedes albopictus.
-
-Primary infection with dengue virus results in a self-limitig disease characterized by mild to high fever lasting 3 to 7 days, sever headache with pain behind the eyes, muscle and joint pain, rash and vomiting. Secondary infection is the more common from of the disease in many parts of Southeast Asia and South America; IgM antibodies are not detectable until 5-10 days in case of primary dengueinfection and until 4-5 days in secondary infection after the onset of illness. IgG appear after 14 days and persist for life in case primary infection and rise within 1-2 days after the onset of symptoms in secondary infection.
-
-Primary dengue virus infection is characterized by elevatons in specific NS1 antigen levels 0 to 9 days after the onset of symptoms; this generally presists upto 15 days. Earler diagnosis of Dengue reduces risk of compliation such as DHF or DSS, especially in countries where dengue is endemic.
-', '12', '1', '1', '366'),
-('80', 'Direct Coombs Test', NULL, 'DCT : {DCT}
-', '12', '1', '1', '362'),
-('81', 'Stool for Occult Blood', NULL, 'Stool for Occult Blood : {occult}
-', '3', '1', '1', '215'),
-('82', 'Bile Salt', NULL, '', '8', '1', '1', '0'),
-('83', 'BILE PIGMENT', NULL, '', '8', '1', '1', '0'),
-('84', 'Hepatitics A', NULL, '', '5', '1', '1', '0'),
-('85', 'Hepatitics E', NULL, '', '5', '1', '1', '0'),
-('86', 'V.D.R.L', NULL, 'V.D.R.L : {V.D.R.L}
-', '12', '1', '1', '168'),
-('87', 'G6PD', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- G6PD
- {G6PD}
- u/g HB
- 6.40-18.5
-
-
-
-', '6', '1', '1', '2976'),
-('88', 'MALIGNANT CELLS', NULL, '
-
-
- Test Name
-
- Value
-
-
- MALIGNANT CELLS
-
- {MC}
-
-
-
-
-
-', '9', '1', '1', '276'),
-('89', 'Serum Electrolyte', NULL, '
-
-
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- Na+
- {Na}
- mmol/L
- 135.0-148.0
-
-
- K+
- {K}
- mmol/L
- 3.50-5.30
-
-
-
-', '1', '1', '1', '236'),
-('90', '24 Hrs Urinary Albumin', NULL, 'Vol. of urine- 1000ml/24Hrs.
-
-Specific Gravity-1010
-
-Total Protein excreted – 200mg/24Hrs.
-
-Guideline for interpretation
-
-Reference Range
-
-21.3-119.6mg/24Hrs.
-
-0.02-0.11gm/24Hrs.
-', '3', '1', '1', '430'),
-('91', 'urine for Bence Jones protein', NULL, 'Urine for Bence Jones protein: {BanP}
-', '1', '1', '1', '180'),
-('92', 'Heamogram', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- HAEMOGLOBIN
- {HB}
- gm%
- 12.00-16.00 gm%
-
-
- T.L.C.
- {TLC}
- per cu mm
- 4000.00-11000.00 /cu mm
-
-
- D.L.C.
-
-
-
-
-
- NEUTROPHILS
- {NEU}
- %
- 45.00-70.00 %
-
-
- LYMPHOCYTES
- {LYMP}
- %
- 20.00-45.00 %
-
-
- EOSINOPHILS
- {EOSIN}
- %
- 1.00-8.00 %
-
-
- MONOCYTES
- {MONO}
- %
- 1.00-6.00 %
-
-
- BAND CELLS
- {BAND}
- %
-
-
-
- IMMATURE CELLS
- {IMMATURE}
- %
-
-
-
- RBC
- {RBC}
- Million/cm
- 3.50-5.00 Million/cm
-
-
- PCV
- {PCV}
- %
- 34.00 - 47.00 %
-
-
- MCV
- {MCV}
- fl
- 83.00-98.00 fl
-
-
- MCH
- {mch}
- pg
- 25.00-33.00 pg
-
-
- MCHC
- {MCHC}
- g/dl
- 28.00-36.00 g/dl
-
-
- PLATELET COUNT
- {PLATELET}
- per cu mm
- 150000-450000 per cu mm
-
-
- ESR
- {ESR1}
- mm
- 0.00-15.00 mm
-
-
-
-', '6', '1', '1', '3028'),
-('93', 'Indian link', NULL, '', '10', '1', '1', '2985'),
-('94', 'Indian Ink ', NULL, '', '10', '1', '1', '0'),
-('95', 'L.D.H.', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- LDH
- {LDH}
- IU/L
- 114-2240 IU/L
-
-
-
-', '1', '1', '1', '287'),
-('96', 'ORBIT', NULL, '', '4', '1', '1', '2897'),
-('97', 'ASCITIC FLUID EXAMINATION', NULL, 'Physical Examination
-
-
-
-
-
- Observed Value
- Normal Value
-
-
- Appearance
- {APP}
- CLEAR
-
-
- Colour
- {COLOUR}
- STRAW
-
-
- Coagulum
- {COALGU}
- ABSENT
-
-
-
-
-Chemical Examination
-
-
-
-
-
- Observed Value
-
-
- Proteins
- {PROTEINS}
-
-
- Sugar
- {SUGAR}
-
-
-
-
-Microscopic Examination
-Total Cell Count : {TCC} /cmm
-
-
-
-
-
-
- Differential Cell Count
-
-
-
- Polymorphs
- {Polymorphs}
-
-
-
- Lymphocytes
- {Lymphocyte}
-
-
-
- Mesothelial
- {MESO}
-
-
-
- R.B.Cs
- {RBCS}
-
-
-
-
-
-
-
-
- Gram Stain
- {GRAMSTAIN}
-
-
-
- Stain For A.F.B
- {AFB}
-
-
-
-
-
-', '9', '1', '1', '410'),
-('98', 'Indirect Coombs Test', NULL, 'Indirect Coombs Test : { ICT}
-', '12', '1', '1', '291'),
-('99', 'Urine for Ketone', NULL, 'Urine for ketone {UFK}
-', '8', '1', '1', '176'),
-('100', 'MALARIA PARASITE', NULL, 'MALARIA PARASITE: {MALARIAP}
-', '6', '1', '1', '277'),
-('101', 'BUN', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- Blood Urea Nitrogen
- {BUN}
- mg%
- 6-24 mg%
-
-
-
-', '1', '1', '1', '392');
-
-INSERT IGNORE INTO `lab_repo` (`mstRepoKey`, `Title`, `RTFData`, `HTMLData`, `GrpKey`, `IncludeHeader`, `IncludeFooter`, `charge_id`) VALUES
-('102', 'Urine For Protien', NULL, 'Urine for Protein {UFP}
-', '8', '1', '1', '177'),
-('103', 'Chikungunya IgM', NULL, 'Chikungunya IgM : {CIGM}
-', '1', '1', '1', '380'),
-('104', 'WHOLE ABDOMEN', NULL, 'LIVER: Is normal in size and echotexture. IHBR is normal. No Focal lesion is seen.
-
-GALL BLADDER: Normal Distention and wall thickness. No intraluminal echogenic with DAS is seen.
-
-C.B.D : Normal in Caliber. No obvious intraluminal echogenic mass is seen.
-
-PORTAL VEIN : WNL
-
-PANCREAS: Normal in size and echotexture MPD not dilated. No Focal lesion is seen.
-
-SPLEEN: Normal in size and echotexture. No focal lesion is seen.
-
-KIDNEYS: Left Kidney is normal in size, shape and echotexture. CMD maintained. No echogenic mass with DAS is seen.
-
-Right Kidney is normal in size, shape and echotexture. CMD maintained. No echogenic mass with DAS is seen.
-
-URINARY BLADDER: Normal Distention and wall thickness. No intra luminal mass is seen.
-
-PROSTATE: Is normal in volume. Capsule appears intact.
-
-UTERUS: Is normal in size and echotexture. Endometrial thickness is normal.
-
-Bilateral Ovaries are normal.
-
-No free fluid seen in upper peritoneal recesses and pelvis.
-
-No pre or para aortic lymphadenopathy is seen.
-
-IMPRESSION : - Normal Study.
-
- Kindly correlate clinically.
-', '15', '1', '1', '8'),
-('105', 'ULTRASOUND (OBST.)', NULL, '
- Single alive intra uterine fetus is seen with normal cardiac and somatic activity.( at the time of examination)
- Placenta is posterior and upper in position.
- Liquor is adequate.
- No Gross CVA is seen. Stomach Bubble, Fetal Kidneys and fetal UB normally seen.
-
-
-
- B.P.D. : 7.68 cm 30 weeks 6 days .(+/- 2 weeks)
-
-
-
- H.C : 27.87 cm 30 weeks 4 days. (+/- 2 weeks)
-
-
-
- A.C : 25.63 cm 29 weeks 6 days. (+/- 2 weeks)
-
-
-
- F.L. : 5.58 cm 29 weeks 3 days. (+/- 2 weeks)
-
-
-
-
-
- F.H.R. : 150 beats/ minutes.
-
-
-IMPRESSION: Single alive intra uterine fetus of 30 week’s 2 days is seen.
-
- Kindly correlate clinically.
-', '15', '1', '1', '9'),
-('106', 'DEDICATED (OBS) ULTRASOUND', NULL, '
- Single alive intra uterine fetus is seen with normal cardiac and somatic activity.( at the time of examination)
- Placenta is anterior and upper in position.
- Liquor is adequate.
-
-
-SKULL & SPINE : -
-
-
- Bilateral; cerebral hemispheres, basal ganglia, thalami, midbrain & cerebellar hemispheres are normal
- Bilateral nasal bone are normal
-
-
-
- No Gross CVA is seen.
-
-
-
- B.P.D. : 3.77 cm 17 weeks 4 days .(+/- 2 weeks)
-
-
-
- H.C : 13.34 cm 26weeks 6 days. (+/- 2 weeks)
- TRANS - CEREBELLAR DIAMETER : 1.75 cm
-
-
-
- TRANS - ORBITAL DIAMETER : 3.93cm
- CISTERNA MAGNA : 3.9 mm
- LATERAL VENTRICLE :- 6.3 mm
-
-
-CHEST ABDOMEN & LIMBS
-
-
- Stomach Bubble, Fetal Kidneys and fetal UB normally seen.
- 4 chamber view of the heart is normal.
-
-
-
- A.C : 11.62 cm 17 weeks 3 days. (+/- 2 weeks)
- F.L. : 2.19 cm 16 weeks 4 days. (+/- 2 weeks)
- F.W : 170 Gm.
- F.H.R. : 144 beats/ minutes.
- HUMEROUS LENGTH : 2.04 cm
- TIBIA LENGTH : 1.92 cm
- RADIUS/ULNA LENGTH : 1.75 cm
- UMBLICAL CORD : 3 vessel cord is seen with normal flow
-
-
-IMPRESSION: Single alive intra uterine fetus of 17 week’s 6 days is seen with grossly normal parameters.
-', '15', '1', '1', '10'),
-('107', 'DOPPLER (OBST.)', NULL, '
- Single alive intra uterine fetus is seen in Cephalic Presentation with normal cardiac and somatic activity. (at the time of examination)
- Placenta is posterior and upper.
- Liquor is adequate.
- No Gross CVA is seen. Stomach Bubble, Fetal Kidneys and fetal UB normally seen.
-
-
-
- B.P.D. : 9.28 cm 37 weeks 5 days .(+/- 2 weeks)
-
-
-
- F.L. : 7.01 cm 36 weeks 0 days. (+/- 2 weeks)
-
-
-
- H.C : 32.57 cm 36 weeks 6 day. (+/- 2 weeks)
-
-
-
- A.C : 28.90 cm 32 weeks 6 days. (+/- 2 weeks)
-
-
-
- F.H.R. : 144 beats/ minutes.
-
-
-
-
-
-
-
-
-
- The umbilical artery shows normal flow pattern with forward diastolic flow.
- The uterine arteries show normal flow pattern with forward diastolic flow.
- The MCA flow is normal.
- No cord is seen around the Neck.
-
-
-COLOUR DOPPLER PARAMETERS
-
-
-
-
-
- Vessels
-
-
- RI
-
-
- PI
-
-
- S/D ratio
-
-
-
-
- Umb Artery
-
-
- 0.47
-
-
- 0.54
-
-
- 1.9
-
-
-
-
- Ut. artery (Rt.)
-
-
- 0.25
-
-
- 0.32
-
-
- No Pre diastolic notch
-
-
-
-
- Ut. artery (Lt.)
-
-
- 0.45
-
-
- 0.70
-
-
- No Pre diastolic notch
-
-
-
-
- MCA :
-
-
- 0.74
-
-
- 1.42
-
-
- --
-
-
-
-
-
-
-
-Cerebro Placental Ratio – R.I MCA /R.I Umb = 0.74/0.47 (>1)
-
-IMPRESSION: Single alive intra uterine fetus with normal C.D Parameters of 33 weeks 4 days.
-
- Kindly correlate clinically.
-', '15', '1', '1', '11'),
-('108', 'ULTRASOUND (LOWER ABDOMEN)', NULL, 'URINARY BLADDER: Normal distention and wall thickness. No intra luminal echogenic mass with DAS is seen.
-
-UTERUS: Is normal in size, antiverted in position and normal in echotexture. Endometrial thickness is 20.4 mm. No intra uterine G- Sac is seen.
-
-OVARIES: Bilateral Ovaries are normal in size and echotexture.
-
-No free fluid seen in pelvis.
-
-IMPRESSION: USG findings S/O .
-
- Kindly correlate clinically.
-', '15', '1', '1', '12'),
-('109', 'ULTRASOUND (CHEST)', NULL, 'LIVER: Is normal in size and echotexture. IHBR is normal. No Focal lesion is seen.
-
-PANCREAS: Normal in size and echotexture MPD not dilated. No Focal lesion is seen.
-
-SPLEEN: Normal in size and echotexture. No focal lesion is seen.
-
-Moderate amount pleural effusion is seen on both sides.
-', '15', '1', '1', '14'),
-('110', 'ULTRASOUND (SCROTUM)', NULL, 'LEFT TESTIS
-
-
- Left testis measures 3.87 X 3.48 X 2.81 cm in size with a volume of 19.81 ml.
- Is normal in size and echotexture.
- No focal lesion seen.
- No signs of varicocele seen.
- No significant amount of fluid is seen in the Tunica Vaginalis.
- Lt. Epididymis is normal in size and echopattern.
-
-
-RIGHT TESTIS
-
-
- Right testis measures 3.87 X 3.48 X 2.81 cm in size with a volume of 19.81 ml.
- Is normal in size and echotexture.
- No focal lesion seen.
- No signs of varicocele seen.
- No significant amount of fluid is seen in the Tunica Vaginalis.
- Rt. Epididymis is normal in size and echopattern.
- Colour Doppler normal Flow of both Testis
-
-
-IMPRESSION: GROSSLY NORMAL STUDY.
-
- Kindly Correlate Clinically
-
-
-', '15', '1', '1', '15'),
-('111', 'ULTRASOUND (EYE)', NULL, 'High Resolution Sonography (12.5 MHz)
-
-Both Coronal and Transverse scan taken
-
-LT.EYE :
-
-
- Some settled echoes are seen within the post chamber .
- Anterior chamber is clear.
- Lens of Lt. Eye is normal.
- Retro Bulbar area is normal.
- Optic nerve is normal.
-
-
-RT.EYE:
-
-
- Both anterior and posterior chamber are normal.
- Lens of Rt. Eye is normal.
-
-
-
- Optic nerve is normal.
- Retro Bulbar area is normal.
-
-
-IMPRESSION : Small Left vitreous hemorrhage.
-
- Kindly correlate clinically.
-', '15', '1', '1', '16'),
-('112', 'ULTRASOUND (NECK)', NULL, ' (This Report is not valid for Medico Legal Purpose)
-
-
- Right lobe measures 2.87 X 1.37 X 1.52 cm with a volume 2.87 ml.
- Left lobe measures 2.61 X 1.34 X 1.29 cm with a volume 2.15 ml.
- Shows normal echotexture. No calcification, nodule or cystic area seen. Outline is normal.
- Isthmus measures AP dimension 0.30 cm.
-
-
-
- Strap muscles are normal.
-
-
-
- Visualized CCA and IJV are normal on both sides.
-
-
-
- Trachea is central and shows characteristic reverberation artifacts.
-
-
-
- No cervical lymphadenopathy is seen.
-
-
-IMPRESSION:
-
-
-
-', '15', '1', '1', '17'),
-('113', 'ULTRASOUND (FOLLICULAR MONITORING)', NULL, 'ULTRASOUND (FOLLICULAR MONITORING)
-
-
-
-
-
-
-
- S. No
-
-
- Date
-
-
- Day
-
-
- ETT
-
-
- Rt. Follicle
-
-
- Lt. Follicle
-
-
-
-
- 1)
-
-
- 01/11/2018
-
-
- 9th
-
-
- 5.1 mm
-
-
- 9.7 X 10.6 mm
-
-
- 6.8 X 6.4 mm
-
-
-
-
- 2)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 3)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 4)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 5)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-', '15', '1', '1', '18'),
-('114', 'SONO MAMOGRAPHY (BREAST)', NULL, 'RIGHT BREAST:
-
-
- Nipple including areola is normal.
- There is no solid or cystic mass on Rt. side.
- Retro mammary space is normal.
- Axillary area is normal.
-
-
-LEFT BREAST:
-
-
- There is no solid or cystic mass on Lt. Side.
- Nipple including areola is normal.
-
-
-
- Retro mammary space is normal.
- Axillary area is normal.
- No Lymphadenopathy is seen in Axillary region.
-
-
-IMPRESSION: Grossly normal study.
-
- Kindly correlate clinically.
-', '15', '1', '1', '20'),
-('115', 'ULTRASOUND GUIDED (ASPIRATION)', NULL, '
- Aspiration Right pleural effusion is done under L.A using all antiseptic precautions.
- About 500 ml of fluid is aspirated & sent for microscopy.
- Minimal amount pleural effusion is seen on Right side.
-
-', '15', '1', '1', '21'),
-('116', 'DUPLEX DOPPLER BILATERAL LOWER LIMBS', NULL, 'Colour flow and duplex scanning of the B/L lower limbs was performed using 10-12 mhz linear transducer.
-
-
- The common femoral and Femoral Veins are normally visualized. These are normal in caliber and show normal colour flow.
- These show normal response to Valsalva and Augmentation.
- These veins show normal compressibility and respiratory phasicity.
- No Thrombus is seen.
- Popliteal vein is normal in caliber and show normal response to Augmentation.
- No spontaneous flow is seen in the PTV & ATV.
- Normal flow is seen on augmentation.
- Distal veins could not be evaluated.
-
-
-IMPRESSION: NO EVIDENCE OF DVT.
-', '15', '1', '1', '22'),
-('117', 'DUPLEX DOPPLER RIGHT LOWER LIMB', NULL, 'Colour flow and duplex scanning of the RT. Lower limb was performed using 10-12 mhz linear transducer.
-
-
-
-
- The common femoral artery on real time shows normal branching into the superficial femoral and profunda femoral arteries vessel caliber is normal.
-
-
-
-
-
- No wall abnormality is seen.
-
-
-
-
-
- On the duplex mode normal triphasic flow is seen .This is consistent with a high peripheral resistance.
-
-
-
-
-
- Colour flow also reveals complete uniform filling with no evidence of any turbulence in CFA, SFA, and Popliteal Arteries.
-
-
-
-
-
- Anterior tibial, posterior tibial and peroneal arteries show decreased flow and can be traced up to ankle.
-
-
-
-
-IMPRESSION : COLOUR DOPPLER S/O GROSSLY NORMAL STUDY.
-
-
-', '15', '1', '1', '23'),
-('118', 'DOPPLER STUDY LEFT CAROTID', NULL, 'Colour flow and pulse Doppler was performed of Left the carotid arteries using a 5-7.5 MHz linear transducer in the longitudinal and transverse planes.
-
-
-
-
- On the B mode images the left common carotid, carotid bulb, internal and external carotid show normal luminal diameter with wall.
- Average IMT is 0.1cm.
- Colour flow studies demonstrate normal pulsatile laminar flow with no evidence of any turbulence.
- Pulse Doppler reveals a normal flow pattern. Peak systolic velocities are in the normal range.
-
-
-
- Lt. vertebral artery is normal.
- Due to high division of CCA only small part of ICA is visible.
-
-
-
-
-
-
-
-
- Artery
-
-
- Left
-
-
-
-
- PSV (cms/sec)
-
-
- EDV (cms/sec)
-
-
-
-
-
-
-
- 67.2
-
-
- 8.7
-
-
-
-
-
-
-
- 42
-
-
- 12.7
-
-
-
-
-
-
-
- 19.4
-
-
- 7
-
-
-
-
-
-IMPRESSION:
-
- Kindly Correlate Clinically.
-', '15', '1', '1', '24'),
-('119', 'ULTRASOUND SWELLING', NULL, 'Ultrasound swelling is done using 8MHz linear transducer .
-
-There is visualized a hetroechoic soft tissue swelling in the knee region. The swelling show vascularity. Soft tissue mass. ? Malignant
-
-The muscles & tendons of the visualized area are grossly normal.
-', '15', '1', '1', '26'),
-('120', 'ULTRASOUND (CRANIUM)', NULL, '
- Bilateral Cerebral Hemispheres are grossly normal in echogenicity. No focal lesion is seen.
- Bilateral lateral Ventricles and 3rd are grossly normal.
- Bilateral Thalami and Mid Brain are grossly normal.
- Visualized part of Cerebellum is normal.
- No area of altered echogenicity is seen.
-
-
- Kindly correlate clinically.
-
-
-', '15', '1', '1', '28'),
-('121', 'DOPPLER STUDY RIGHT CAROTID', NULL, 'Colour flow and pulse Doppler was performed of Right the carotid arteries using a 5-7.5 MHz linear transducer in the longitudinal and transverse planes.
-
-
-
-Right Carotid :
-
-
- On the B mode images the right common carotid, carotid bulb, internal and external carotid show normal luminal diameter .The IMT is 0.6 mm with wall. No plaque is noted.
- Colour flow studies demonstrate normal pulsatile laminar flow with no evidence of any turbulence.
- Pulse Doppler reveals a normal flow pattern; Peak systolic velocities are in the normal range.
- Rt. vertebral artery is normal in Caliber and shows normal colour flow.
-
-
-
-
-
-
- Artery
- RT
- LT
-
-
- PSV (cms/sec)
- EDV (cm/sec)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Rt. Vertebral
-
-
-
-
-
-
-
-IMPRESSION: Normal study.
-', '15', '1', '1', '3084'),
-('122', 'NCCT HEAD', NULL, '
-
-
-
-
- (This report is not valid for Medico Legal Purpose)
-
-
-
-
-
-
-7 mm contiguous axial sections were obtained of the entire skull from the base to vertex.
-
-Clinical history : Headache, vomiting, vertigo, head injury, RTA, LOC.
-
-
- No EDH, SDH, SAH or ICH is seen.
- Bilateral Cerebral Hemispheres are normal.
- Bilateral lateral Ventricles and 3rd Ventricle are normal.
- Bilateral Basal Ganglia and Thalami are normal.
- Mid brain and Pons are normal.
- 4th Ventricle is normal in size and midline in position.
- Bilateral Cerebellar Hemisphere is normal in size and Contour.
- Extra Axial fluid spaces and Basal Cisterns are normal.
- Bone window – No Obvious fracture is seen.
-
-', '15', '1', '1', '1'),
-('123', 'CECT ABDOMEN', NULL, '7 mm scans of the abdomen obtained before and after the administration of Oral & I/V contrast. Oral contrast given to opacify bowel loops.
-
-
-
-The study reveals:-
-
-
-
-LIVER: Measures 15.7 cm in cranio-caudal dimensions in mid clavicular line. No focal Parenchymal abnormality is seen. Hepatic vessels are normal.
-
-
-
-GALL BLADDER: No mass lesion is seen in Gall Bladder Fossa. Peri cholecystatic fat planes are maintained.
-
-
-
-C.B.D: Is within normal limit.
-
-
-
-PORTAL VEIN: Is normal in caliber and course. It shows normal enhancement. No Thrombus is seen. No Varices are seen at Porta.
-
-
-
-PANCREAS: Is normal in size and outline. Parenchymal enhancement is homogeneous with no evidence of any focal lesion or calcification. Pancreatic duct is not dilated. Peripancreatic fat planes are maintained. Spleno-portal axis is normal.
-
-
-
-SPLEEN: Spleen is normal in size and shows homogeneous contrast enhancement. No focal lesion is seen.
-
-
-
-KIDNEYS & ADRENAL: Bilateral kidneys are normal in size, shape and position. Normal enhancement of the parenchyma is seen. Pelvi-calyceal system is well opacified.
-
-No evidence of any filling defect or distortion on either Side.
-
-Both adrenals are normal.
-
-
-
-URINARY BLADDER: Is grossly normal. No Focal lesion is seen.
-
-
-
-PROSTATE: - It shows homogenous enhancement. Fat plains between Prostate, Urinary Bladder, Seminal Vesicles and Rectum are maintained.
-
-
- No Pre or Para aortic Lymphadenopathy is seen.
- Gut is normally Opacified by oral and rectal contrast.
- No free fluid is seen in all peritoneal recesses.
- No pleural effusion is seen.
-
-
-
-
-On Bone Window : - No Focal lytic / Sclerotic lesion is seen in the visualized part.
-
-
-
-IMPRESSION: - GROSSLY NORMAL STUDY
-
- Kindly Correlate Clinically.
-', '15', '1', '1', '71'),
-('124', 'CECT THORAX', NULL, '5 mm contiguous axial sections were obtained of the thorax from Apex to Adrenal region after I.V Contrast.
-
-
-
-C.E.C.T CHEST REVEALS:-
-
-
-
-
- Bilateral Lung fields are grossly normal.
- No area of collapse consolidation is seen.
- No evidence of Bronchiectasis is seen.
- No significant size Mediastinal lymphadenopathy is seen.
- Mediastinal vascular structures are normally opacified by I.V contrast.
- No pleural effusion is seen
- Visualized parts of upper abdominal Viscera are normal.
- On bone window- No focal- Lytic/ Sclerotic lesion is seen in the visualized part.
-
-
-
-
-IMPRESSION:
-
- Kindly Correlate Clinically.
-
-
-', '15', '1', '1', '38'),
-('125', 'NON-CONTRAST MRI OF THE BRAIN ', NULL, '
-
-
-
-
- NON-CONTRAST MRI OF THE BRAIN
-
-
-
-
-TECHNIQUE: Multiplanar T1, T2, FLAIR, ADC, DWI, SWI scans of the brain were performed.
-
-
-
-FINDINGS:-
-
-
-
-CEREBRAL PARENCHYMA: Normal.
-
-BASAL GANGLIA, THALAMI: Normal.
-
-INTERNAL CAPSULE: Normal.
-
-VENTRICLES: Normal.
-
-SULCI and BASAL CISTERNS: Normal.
-
-MIDLINE SHIFT/ MASS EFFECT: nil significant
-
-CEREBELLUM: Normal.
-
-MIDBRAIN, PONS, MEDULLA: Normal.
-
-CV JUNCTION: Normal.
-
-SELLA: Normal.
-
-ORBITS: Normal.
-
-DURAL VENOUS SINUSES: Normal.
-
-VISUALISED INTRACRANIAL ARTERIES: Normal.
-
-PARANASAL SINUSES and MASTOID AIR CELLS: Normal.
-
-BONES: Normal.
-
-
-
-IMPRESSION:
-
- Yrs old male with history of headache, vertigo, vomiting.
-
-
-
-Non-contrast MRI study of the brain.
-
-
-
-
- No significant radiological abnormality.
-
-
-
-
-Recommend clinical correlation.
-
-
-
-
-
-Investigations have their limitations. Solitary pathological/Radiological and other investigations never confirm the final diagnosis. They only help in diagnosing the disease in correlation to clinical symptoms and other related tests. Please interpret accordingly.
-
-This Report is not for Medico - Legal Purposes
-
-
-
-
-
-
-', '15', '1', '1', '3'),
-('126', 'NCCT FACE (AXIAL WITH 3D RECON)', NULL, '
-
-
- (This report is not valid for Medico Legal Purpose)
-
-
-
-
-Axial Plain Scan done with 1 mm Slice Thickness.
-
-
- Bilateral Ethmoid, Sphenoid and Maxillary Sinuses are clear.
- Bilateral OMCs are patent.
- Both Inferior and middle turbinates are grossly normal.
- Insignificant DNS is seen with convexity towards Lt.
- Bilateral uncinate processes are normal.
- Bilateral upper and lower alveolar margins are intact.
- Bilateral T.M joints are grossly normal.
- Visualized parts of bony orbits are normal.
- No Obvious Fracture is seen in the visualized part.
-
-', '15', '1', '1', '36'),
-('127', 'NCCT RT. SHOULDER', NULL, '(This report is not valid for Medico Legal Purpose)
-
-
-
-2 mm contiguous axial sections were obtained of the entire Rt. Shoulder.
-
-
-
-
- The head, surgical neck, anatomical neck, lesser tuberosity and greater tuberosity of humerus are normal.
- Visualized part of clavicle is normal.
- Visualized part of acromian process, coracoid process and body of Scapula are normal.
- The articular margins of Glenoid cavity are regular & smooth.
- The Gleno-humoral joint is normal.
- The shape of Humoral head is maintained with smooth articular surface.
-
-
-
-
-Kindly Correlate Clinically.
-
-
-
-
-
-
-', '15', '1', '1', '3027'),
-('128', 'OP', NULL, '
-
-INTERPRETATION
-
-
-
-
- Induration Less than 5 mm
- Negative
-
-
- Induration greater then 10 mm
- Positive
-
-
- Induration between 9-10 mm
- Birderline
-
-
-
-', '15', '1', '1', '270'),
-('129', 'SERUM PHOSPHORUS', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- SERUM PHOSPHORUS
- {SPHOSPHORUS}
- mg/dl
- 2.5-5.0
-
-
-
-', '1', '1', '1', '227'),
-('130', 'Ionized Calcium', NULL, '
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- Ionized Calcium
- {ICALCIUM}
- mg/dl
- 4.4-5.5
-
-
-
-', '1', '1', '1', '290'),
-('131', 'Glucose Random*', NULL, '
-
-
- Test Name
- Result
- Unit
- Bio.Ref. Interval
- Method
-
-
- Glucose Random*
- Sample: Plasma
- {GR}
- mg/dl
- 70-140
- GOD POD
-
-
-
-
-
-
-', '1', '1', '1', '343'),
-('132', 'Nirogi kaya Basic Package', NULL, 'COMPLETE BLOOD COUNT (CBC)
-
-
-
-
- Test Name
- Result
- Unit
- Bio. Ref. Interval
-
-
- Haemoglobin
- {HB}
- gm%
- 12-16
-
-
- TLC
- {TLC}
- per cu mm
- 4000-11000
-
-
- DLC
-
-
-
-
-
- Neutrophils
- {NEU}
- %
- 45-70
-
-
- Lymphocytes
- {LYMP}
- %
- 20-45
-
-
- Eosinophils
- {EOSIN}
- %
- 1-8
-
-
- Monocytes
- {MONO}
- %
- 1-6
-
-
- Basophiles
- {BASO}
- %
- < 1%
-
-
- RBC Count
- {RBC}
- Million/cm
- 4.2-5.5
-
-
- PCV
- {PCV}
- %
- 40 - 54
-
-
- MCV
- {MCV}
- fl
- 80-100
-
-
- MCH
- {mch}
- pg
- 28-35
-
-
- MCHC
- {MCHC}
- g/dl
- 30-38
-
-
- Platelet Count
- {PLATELET}
- per cu mm
- 1.5-4.5
-
-
- ESR
- {ESR1}
- Mm for 1st hr.
- < 9 >
-
-
-
-
-
-
-Glucose Fasting / PP
-
-
-
-
- Test Name
- Result
- Unit
- Bio. Ref. Interval
- Method
-
-
- Glucose Fasting*
- Sample:Plasma
- {BGF}
- mg/dl
- < 99 Normal
- 100-125 Near Normal
- I.G.T)
- > 126 Diabetic
- GOD POD
-
-
- Glucose PP*
- Sample:Plasma after meal
- {BGPP}
- mg/dl
- 0-140
- GOD POD
-
-
-
-
-
-
-
-
-
-
- Test Name
-
-
- Result
-
-
- Unit
-
-
- Bio.Ref.Interval
-
-
- Method
-
-
-
-
- GLYCOSYLATED HAEMOGLOBIN (HBA1C) * , EDTA BLOOD
- Glycosylated Haemoglobin (HbA1c)
-
-
- {HBA1C}
-
-
- %
-
-
- < 5.7 Non diabetic
- adults>=18 years
- 5.7-6.4 At risk
- (Prediabetes)
- >= 6.5 Diabetes
- (As per ADA)
-
-
- QUANTITATIVE TURBIDIMETRIC IMMUNOASSAY
-
-
-
-
-
-
-
-
-
-LIPID PROFILE
-
-
-
-
- Test Name
- Result
- Bio. Ref.Interval
-
-
- Cholesterol(Total)
- {l_Choleste} mg/dl
- <200 Desirable
- 200-239 Borderline High
- > 240 High
-
-
- Triglyceride
- {l_Triglyce} mg/dl
- < 150 Normal
- 150-199 Borderline High
- 200-499 High
- >500 Very High
-
-
- HDL Cholesterol ( Good Cholesterol )
- {l_hdl} mg/dl
- 30-70
-
-
- LDL Cholesterol ( Bad Cholesterol ) ( Direct )
- {l_ldl} mg/dl
- < 100 Optimal
- 100-129 Nr.
- Optimal/Above Optimal
- 130-159 Borderline High
- 160-189 High
- > 190 Very High
-
-
- VLDL
- {l_vldl} mg/dl
- 10-33
-
-
-
-
-
-
-T3,T4,TSH
-
-
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- Triiodothyronine [T3]
- {T3}
- ng/ml
- 0.00-1.51 ng/ml
-
-
- Thyroxine [T4]
- {T4}
- ug/dl
- 4.66-9.32 ug/dl
-
-
- Thyroid Stimulating Hormone (TSH)
- {TSH}
- ulU/mL
- 0.25-5.00 ulU/mL
-
-
-
-
-
-', '15', '1', '1', '3477'),
-('133', 'Nirogi kaya Advanced Package', NULL, 'COMPLETE BLOOD COUNT (CBC)
-
-
-
-
- Test Name
- Result
- Unit
- Bio. Ref. Interval
-
-
- Haemoglobin
- {HB}
- gm%
- 12-16
-
-
- TLC
- {TLC}
- per cu mm
- 4000-11000
-
-
- DLC
-
-
-
-
-
- Neutrophils
- {NEU}
- %
- 45-70
-
-
- Lymphocytes
- {LYMP}
- %
- 20-45
-
-
- Eosinophils
- {EOSIN}
- %
- 1-8
-
-
- Monocytes
- {MONO}
- %
- 1-6
-
-
- Basophiles
- {BASO}
- %
- < 1%
-
-
- RBC Count
- {RBC}
- Million/cm
- 4.2-5.5
-
-
- PCV
- {PCV}
- %
- 40 - 54
-
-
- MCV
- {MCV}
- fl
- 80-100
-
-
- MCH
- {mch}
- pg
- 28-35
-
-
- MCHC
- {MCHC}
- g/dl
- 30-38
-
-
- Platelet Count
- {PLATELET}
- per cu mm
- 1.5-4.5
-
-
- ESR
- {ESR1}
- Mm for 1st hr.
- < 9 >
-
-
-
-
-
-
-Glucose Fasting / PP
-
-
-
-
- Test Name
- Result
- Unit
- Bio. Ref. Interval
- Method
-
-
- Glucose Fasting*
- Sample:Plasma
- {BGF}
- mg/dl
- < 99 Normal
- 100-125 Near Normal
- I.G.T)
- > 126 Diabetic
- GOD POD
-
-
- Glucose PP*
- Sample:Plasma after meal
- {BGPP}
- mg/dl
- 0-140
- GOD POD
-
-
-
-
-
-
-
-
-
-
- Test Name
-
-
- Result
-
-
- Unit
-
-
- Bio.Ref.Interval
-
-
- Method
-
-
-
-
- GLYCOSYLATED HAEMOGLOBIN (HBA1C) * , EDTA BLOOD
- Glycosylated Haemoglobin (HbA1c)
-
-
- {HBA1C}
-
-
- %
-
-
- < 5.7 Non diabetic
- adults>=18 years
- 5.7-6.4 At risk
- (Prediabetes)
- >= 6.5 Diabetes
- (As per ADA)
-
-
- QUANTITATIVE TURBIDIMETRIC IMMUNOASSAY
-
-
-
-
-
-
-
-LIPID PROFILE
-
-
-
-
- Test Name
- Result
- Bio. Ref.Interval
-
-
- Cholesterol(Total)
- {l_Choleste} mg/dl
- <200 Desirable
- 200-239 Borderline High
- > 240 High
-
-
- Triglyceride
- {l_Triglyce} mg/dl
- < 150 Normal
- 150-199 Borderline High
- 200-499 High
- >500 Very High
-
-
- HDL Cholesterol ( Good Cholesterol )
- {l_hdl} mg/dl
- 30-70
-
-
- LDL Cholesterol ( Bad Cholesterol ) ( Direct )
- {l_ldl} mg/dl
- < 100 Optimal
- 100-129 Nr.
- Optimal/Above Optimal
- 130-159 Borderline High
- 160-189 High
- > 190 Very High
-
-
- VLDL
- {l_vldl} mg/dl
- 10-33
-
-
-
-
-
-
-T3,T4,TSH
-
-
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- Triiodothyronine [T3]
- {T3}
- ng/ml
- 0.00-1.51 ng/ml
-
-
- Thyroxine [T4]
- {T4}
- ug/dl
- 4.66-9.32 ug/dl
-
-
- Thyroid Stimulating Hormone (TSH)
- {TSH}
- ulU/mL
- 0.25-5.00 ulU/mL
-
-
-
-
-
-
-LIVER FUNCTION TEST (LFT)
-
-
-
-
- Test Name
- Result
- Unit
- Bio. Ref. Interval
-
-
- Bilirubin (Total)
- {SERBIL}
- mg/dl
- 0.3-1.2
-
-
- Bilirubin (Direct)
- {BD}
- mg/dl
- < 0.3
-
-
- Bilirubin (Indirect)
- {BI}
- mg/dl
- < 0.8
-
-
- SGOT / Aspartate Aminotransferase (AST)
- {SGOT}
- U/L
- < 35
-
-
- SGPT/ Alanine Aminotransferase (ALT)
- {SGPT}
- U/L
- < 40
-
-
- Alkaline Phosphatase (Total)
- {SALKALINE}
- U/L
- 25-140
-
-
- Protein(Total)
- {TOTPRO}
- gm/dl
- 6.2-8.0
-
-
- Albumin
- {ALBU}
- gm/dl
- 3.8-5.4
-
-
- Globulin
- {GLOB}
- gm/dl
- 1.8-3.6
-
-
- A:G Ratio
- {AGR}
-
- 1.1-2.0
-
-
-
-
-
-
-RENAL FUNCTION TEST (KFT)
-
-
-
-
- Test Name
- Result
- Unit
- Bio. Ref. Interval
-
-
- Urea
- {BU}
- mg/dL
- 11-37
-
-
- Creatinine
- {SC}
- mg/dL
- 0.6-1.4
-
-
- Uric Acid
- {SUA}
- mg/dL
- 2.6-7.2
-
-
- Calcium
- {SCA}
- mg/dL
- 8.6-10.3
-
-
- Sodium
- {SS}
- m Mol /L
- 135-155
-
-
- Potassium
- {SP}
- m Mol /L
- 3.5-5.5
-
-
-
-
-
-
-Vitamin D
-
-
-
-
- Test Name
- Observed Values
- Unit
- Normal Values
-
-
- Vitamin D
- {VITD}
- ng/ml
- Reference Range:
- Deficent : < 20
- Insufficent : 20-29
- Sufficent : 30-100
- Potential Toxicity > 100
-
-
-
-
-
-
-VITAMIN B-12
-
-
-
-
- TEST NAME
- TECHNOLOGY
- VALUE
- UNITS
- NORMAL RANGE
-
-
- VITAMIN B-12
- C.L.I.A
- {VITAMIN12}
- pg/ml
- 211-911 pg/ml
-
-
-
-', '15', '1', '1', '3478'),
-('134', 'VITAMIN B-12', NULL, '
-
-
- TEST NAME
- TECHNOLOGY
- VALUE
- UNITS
- NORMAL RANGE
-
-
- VITAMIN B-12
- C.L.I.A
- {VITAMIN12}
- pg/ml
- 211-911 pg/ml
-
-
-
-', '15', '1', '1', '163'),
-('135', 'D-Dimer', NULL, '
-
-
- Test Name
- Result
- Unit
- Bio.Ref. Interval
- Method
-
-
- *D-Dimer
- QUATITATIVE
- {DIMER}
- mg/L
- 0.00-0.5
- Turbidimetric Immunoassay
-
-
-
-
-
-
-
-
- Comments:
-
-
- The formation of D-Dimer requires three hemostatic stages: formation of clot, Factor XIII a cross linking and clot breakdown of Fibrin
- Several studies have shown a correlation of Increased D-dimer levels with clinical conditions that relate to the formation of Fibrin, mirroring an in-vivo lysis of formed cross-linker Fibrin.
- These conditions include Deep Venous Thrombosis , disseminated intra-vascular coagulation, pulmonary Embolism, postoperative states, malignancy, trauma and pre-eclampsia. Signs and symptoms of Deep Venous Thrombosis are non-specific and present in a myriad of non-thrombotic disorders.
- Sample Collected in citrate vial.
- Increased levels have high risk for venons thromboembolism (VTE).
- Lipemia falsely decreases D-dimer levels (intralipid value>250 mg/dl).
-
-
-
-
-
-
-
-', '1', '1', '1', '368'),
-('136', 'Beta- Human ChorionicGonodotropin Hormone', NULL, '
-
-
- Test Name
- Result
- Unit
- Bio.Ref. Interval
- Method
-
-
- Beta- Human ChorionicGonodotropin Hormone
- {BHCG}
- mIU/mL
- (Age/Gender specific)
- CMIA
-
-
-
-
- Comments:
-
-
- Human Chorionic Gonadotropin (hCG) is a glycoprotein with two covalently bound subunits. The alpha subunit is similar to those of Luteinizing Hormone (LH),Follicle Stimulating Hormone (FSH), and Thyroid Stimulating hormone (TSH).
- In pregnancy the levels of hCG increases exponentially for about 8 to 10 weeks after the last menstrual cycle.
- Later in pregnancy about 12 weeks after conception, the concentration of hCG begins to fall as the placenta begins to produce steroid hormones. Other sourcesof elevated hCG values are ectopic pregnancy, threatened abortion, and recent termination of pregnancy.
-
-
-Biological Reference Ranges :
-
-
-
-
- GA in Wks
- Reference Range
- GA in Wks
- Reference Range
- GA in Wks
- Reference Range
-
-
- 1 - 3
- 16 - 4870
- 3 - 4
- 1110 - 31500
- 4-5
- 2560 - 82300
-
-
- 5 - 6
- 23100 - 151000
- 6 - 7
- 27300 - 233000
- 7 - 11
- 20900 - 291000
-
-
- 11 - 16
- 6140 - 103000
- 16 - 39
- 2700 - 78100
-
-
-
-
- Non pregnant Female and Male
- < 5.3
-
-
-
-
-
-
-
-', '13', '1', '1', '407'),
-('137', 'COVID -19 Antigen Test', NULL, '
-
-
- Test Name
- Result
-
-
- COVID-19 Antigen
- (Immunochromatogrphy)
- {covid_antigen_test}
-
-
-
-
-
-Note :
-
-
- Test Results must be evalvated in conjunction with other clinical date available to the phusician.
- Negative tests results do not rule out possible other non-covid-19 viral infection.
-
-', '15', '1', '1', '3493'),
-('138', 'PCOS. PROFILE', NULL, 'Test Name Result Unit Bio Ref. Interval
-
-PCOS PANEL
-
-( Hexokinase CLIA,CMIA
-
-Glucose Fasting
-
-FSH
-
-LH
-
-LH,FSH Ratio < 2.50
-
-Prolactin Serum
-
-Testosterone Total
-
-TSH
-
-Note-
-
-1.Ratio of LH to FSH >2.50 Indicates the presence ofpcos
-
-2.Test conducted on Plasma ( Glucose) and serum ( remainingtests)
-
-3.TSH levels are subject to circadian variation reaching peak levels between 2-4 a.m. and at a
-
- minimum between 6-10 pm. The variation is of the order of 50%.Hence time of the day has influence
-
- on the measured serum TSH concentrations.
-
-4.TSH values <0.03 ulU/mL. need to be clinically correlated due to presence of a rare TSH variant in
-
-some individuals.
-
-Interpretation.
-
-
-
-
-
-
- TANNER STAGE
- AGE IN YEARS
- FSH
- LH
- PROLACTIN
- TESTOSTERONE TOTAL
-
-
- 1.
- < 9.2
- 1.00-4.00
- 0.02-0.18
- 3.6-12.0
- 2-10
-
-
- 2.
- 9.2-13.7
- 1.00-10.80
- 0.02-4.70
- 2.6-18.0
- 5-30
-
-
- 3.
- 10.0-14.4
- 1.50-12.80
- 0.10-12.00
- 2.60-18.0
- 10-30
-
-
- 4.
- 10.7-15.6
- 1.50-11.70
- 0.40-11.70
- 3.2-20.0
-
- 15-40
-
-
-
- 5.
- 11.8-18.6
- 1.00-9.20
- 0.40-11.70
- 3.2-20.0
- 10-40
-
-
-
-
-
-
-Comments
-
-polycystic Ovarian Syndrome is a clinically entity associated with enlarged ovaries Infertility hirsutism obesity
-
-and amenorrhoea. PCOS is clinically defined by hyperandrogenism with chronic anovulation in females
-
-without underlying disease of adrenal of pituitary glands. This syndrome is characterized by normal/ low
-
-levels of FSH with elevated levels of LH & testostterone. Females with PCOD have a greater frequency of
-
-hyperinsulinemia and insulin resistance.
-', '1', '1', '1', '0'),
-('139', 'OGTT', NULL, 'TEST NAME RESULT UNIT BIO REF INTERVAL
-
-Fasting Glucose mg/dl 60.00-110.00
-
-Blood Glucose ( pp) after 75 gm mg/dl 80.00-140.00
-
-Glucose
-', '1', '1', '1', '0'),
-('140', 'Urine for protein creatinine Ratio', NULL, 'PROTEIN CREATININE RATIO ,URINE
-
-(Spectrophotometry)
-
-
-
-
- Test Name
- Result
- Bio Ref. Interval
-
-
- Protein,Total
- mg/dl
- <14.00
-
-
- Creatinine
- mg/dl
- Link with age
-
-
- Protein Creatinine Ratio
-
- <0.20
-
-
-
-
-
-
-Interpretation
-
-
-
-
- Protein Creatinine Ratio
- Remark
-
-
- < 0.20
- Normal
-
-
- 0.20-1.00
- Low grade Prteinuria
-
-
- 1.00-5.00
- Moderate Proteinuria
-
-
- > 5.00
- Nephrosis
-
-
-
-
-
-
-Comments
-
-Urinary total proteins are nearly negligible in healthy adults. The Protein Creatinine ratio is a simple
-
-and convenient method to quantitate and monitor proteinuria in adults with chronic kidney disease.
-
-Patients With 2 or more positive results within a period of 1-2 week should be labeled as having
-
-persistent proteinuria and investigated Further.
-', '1', '1', '1', '0'),
-('141', 'Mantoux test', NULL, 'INDURATION MEASURED IS - MM
-
-RESULT INTERPRETATION LESS THAN 5- NEGATIVE
-
-5-9 MM EQUIVOCAL
-
-GREATER THAN 10 MM POSITIVE
-', '1', '1', '1', '0'),
-('142', 'serum fsh', NULL, '', '13', '1', '1', '234'),
-('143', 'LARGE BIOPSY', NULL, '', '11', '1', '1', '0');
-
+-- No rows found in `lab_repo`
diff --git a/app/Database/Seeds/LabOemData/04_lab_tests.sql b/app/Database/Seeds/LabOemData/04_lab_tests.sql
index 927d894..5e71d02 100644
--- a/app/Database/Seeds/LabOemData/04_lab_tests.sql
+++ b/app/Database/Seeds/LabOemData/04_lab_tests.sql
@@ -11,210 +11,15 @@ CREATE TABLE IF NOT EXISTS `lab_tests` (
`FixedNormals` varchar(30) NOT NULL DEFAULT '0',
`isGenderSpecific` int NOT NULL DEFAULT '0',
`FixedNormalsWomen` varchar(30) NOT NULL,
+ `loinc_code` varchar(20) DEFAULT NULL,
+ `loinc_property` varchar(50) DEFAULT NULL,
+ `loinc_system` varchar(50) DEFAULT NULL,
+ `loinc_scale` varchar(20) DEFAULT NULL,
+ `loinc_synced_at` datetime DEFAULT NULL,
PRIMARY KEY (`mstTestKey`),
UNIQUE KEY `TestID` (`TestID`),
- KEY `Test` (`Test`)
+ KEY `Test` (`Test`),
+ KEY `idx_lab_tests_loinc` (`loinc_code`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb3;
-INSERT IGNORE INTO `lab_tests` (`mstTestKey`, `Test`, `TestID`, `Result`, `Options`, `Formula`, `VRule`, `VMsg`, `Unit`, `FixedNormals`, `isGenderSpecific`, `FixedNormalsWomen`) VALUES
-('1', 'HAEMOGLOBIN(Hb)', 'HB', '', NULL, '', '', '', 'gm%', '12.00-16.00', '0', ''),
-('2', 'T.L.C.', 'TLC', '', NULL, '', '', '', 'per cu mm', '4000-11000', '0', ''),
-('3', 'D.L.C.', 'DLC', '', NULL, '', '', '', '', '', '0', ''),
-('4', 'NEUTROPHILS', 'NEU', '', NULL, '', '', '', '%', '45.00-70.00', '0', ''),
-('5', 'LYMPHOCYTES', 'LYMP', '', NULL, '', '', '', '%', '20.00-45.00', '0', ''),
-('6', 'Absolute EOSINOPHILS', 'AEOSIN', '', NULL, '', '', '', 'per cu mm', '40-440', '0', ''),
-('7', 'MONOCYTES', 'MONO', '', NULL, '', '', '', '%', '1.00-6.00', '0', ''),
-('8', 'BAND CELLS', 'BAND', '', NULL, '', '', '', '%', '1.00-6.00', '0', ''),
-('9', 'IMMATURE CELLS', 'IMMATURE', '', NULL, '', '', '', '%', '', '0', ''),
-('10', 'RBC', 'RBC', '', NULL, '', '', '', 'million/cm', '4.2-5.5', '0', ''),
-('11', 'PCV', 'PCV', '', NULL, '', '', '', '%', '40.00-54.00', '0', ''),
-('12', 'MCV', 'MCV', '', NULL, '', '', '', 'fl', '80.00-100.00', '0', ''),
-('13', 'MCH', 'mch', '', NULL, '', '', '', 'pg', '25.00-35.00', '0', ''),
-('14', 'MCHC', 'MCHC', '', NULL, '', '', '', 'g/dl', '28.00-38.00', '0', ''),
-('15', 'PLATELET COUNT', 'PLATELET', '', NULL, '', '', '', 'Lakhs per ', '1.5-4.5', '0', ''),
-('16', 'SERUM BILIRUBIN', 'SERBIL', '', NULL, '', '', '', 'mg%', '0.20-1.20', '0', ''),
-('17', 'BLOOD UREA', 'BU', '', NULL, '', '', '', 'mg%', '11.00-37.00', '0', ''),
-('18', 'SERUM CREATININE', 'SC', '', NULL, '', '', '', 'mg%', '0.60-1.40', '0', ''),
-('19', 'SERUM URIC ACID', 'SUA', '', NULL, '', '', '', 'mg%', '2.6-7.2', '0', ''),
-('20', 'SERUM SODIUM', 'SS', '', NULL, '', '', '', 'mmol/L', '135.00-155.00', '0', ''),
-('21', 'SERUM POTASSIUM', 'SP', '', NULL, '', '', '', 'mmol/L', '3.50-5.50', '0', ''),
-('22', 'SERUM CALCIUM', 'SCA', '', NULL, '', '', '', 'mg%', '8.60-10.3', '0', ''),
-('23', 'TOTAL PROTEIN', 'TP', '', NULL, '', '', '', 'gm/dl', '6.4-8.3', '0', ''),
-('24', 'SERUM ALBUMIN', 'SA', '', NULL, '', '', '', 'mg/dl', '3.50-5.2', '0', ''),
-('25', 'SERUM GLOBULIN', 'SG', '', NULL, '', '', '', 'mg/dl', '2.4-4.0', '0', ''),
-('26', 'ESR ', 'ESR1', '', NULL, '', '', '', 'MM', '0.00-9.00', '0', ''),
-('27', 'SGOT/AST', 'SGOT', '', NULL, '', '', '', 'U/L', '5.00-35.00', '0', ''),
-('28', 'SGPT/ALT', 'SGPT', '', NULL, '', '', '', 'U/L', '10.00-40.00', '0', ''),
-('29', 'S. ALKALINE PHOSPHATASE', 'SALKALINE', '', NULL, '', '', '', 'U/L', '50.00-128.00', '0', ''),
-('30', 'TOTAL PROTEIN', 'TOTPRO', '', NULL, '', '', '', 'mg%', '6.2-8.0', '0', ''),
-('31', 'ALBUMIN', 'ALBU', '', NULL, '', '', '', 'mg%', '3.50-5.2', '0', ''),
-('32', 'GLOBULIN', 'GLOB', '', NULL, '', '', '', 'mg%', '1.8-3.6', '0', ''),
-('33', 'CRP Value', 'CRP', '', NULL, '', '', '', 'mg/l', '1-6', '0', ''),
-('34', 'Body Part', 'BPART', '', NULL, '', '', '', '', '', '0', ''),
-('35', 'HIV I', 'HIV1', '', NULL, '', '', '', '', 'NON-REACTIVE', '0', ''),
-('36', 'HIV II', 'HIV2', '', NULL, '', '', '', '', 'NON-REACTIVE', '0', ''),
-('37', 'Serum Prolectin', 'SProlectin', '', NULL, '', '', '', 'ng/ml', '5-35', '0', ''),
-('38', 'Vitamin D', 'VITD', '', NULL, '', '', '', 'ng/ml', '20-100', '0', ''),
-('39', 'HbA1c', 'HBA1C', '', NULL, '', '', '', '', '', '0', ''),
-('40', 'Volume', 'vol', '', NULL, '', '', '', '', '', '0', ''),
-('41', 'Colour', 'sem_color', 'Milky White', NULL, '', '', '', '', '', '0', ''),
-('42', 'Viscosity', 'Viscosity', 'Viscous', NULL, '', '', '', '', '', '0', ''),
-('43', 'Liquification Time', 'LIQTIME', '30', NULL, '', '', '', '', '0-30', '0', ''),
-('44', 'Total Sperm Count', 'TOTSPCOUNT', '', NULL, '', '', '', 'millions p', '40-150', '0', ''),
-('45', 'Motility', 'MOTILITY', '', NULL, '', '', '', '%', '', '0', ''),
-('46', 'Non Motile', 'NONMOTILE', '', NULL, '', '', '', '', '0-20', '0', ''),
-('47', 'Abnormal Forms', 'Abnormal', '', NULL, '', '', '', '', '0-30', '0', ''),
-('48', 'Pus Cells', 'PUSCELL', '', NULL, '', '', '', 'per HPF', '1-2', '0', ''),
-('49', 'Epithelial cells', 'EPITH', 'NIL', NULL, '', '', '', '', '', '0', ''),
-('50', 'Test Head', 'THEAD', '', NULL, '', '', '', '', '', '0', ''),
-('51', 'Test Head Value', 'THV', '', NULL, '', '', '', '', '', '0', ''),
-('52', 'Glucose , Fasting (F)', 'BGR', '', NULL, '', '', '', 'mg%', '70.00-100.00', '0', ''),
-('53', 'Patients Prothombin', 'PPTV', '', NULL, '', '', '', 'sec', '', '0', ''),
-('54', 'Control Prothombin', 'CPTV', '18.0', NULL, '', '', '', '', '', '0', ''),
-('55', 'Patient INR Value', 'PINRV', '', NULL, '', '', '', '', '', '0', ''),
-('56', 'ORAL ANTICOAUGLANT THERAPEUTIC', 'OATR', '', NULL, '', '', '', '', '', '0', ''),
-('57', 'Control APT', 'CAPT', '', NULL, '', '', '', '', '', '0', ''),
-('58', 'Patient APT', 'PAPT', '', NULL, '', '', '', '', '', '0', ''),
-('59', 'Blood Gluose Fasting', 'BGF', '', NULL, '', '', '', 'mg%', '60.00-110.00', '0', ''),
-('61', 'Blood Glucose (PP)', 'BGPP', '', NULL, '', '', '', 'mg%', '80.00-140.00', '0', ''),
-('62', 'Appearance', 'APP', '', NULL, '', '', '', '', '', '0', ''),
-('63', 'Colour', 'COLOUR', '', NULL, '', '', '', '', '', '0', ''),
-('64', 'Coagulum', 'COALGU', '', NULL, '', '', '', '', '', '0', ''),
-('65', 'Proteins', 'PROTEINS', '', NULL, '', '', '', 'mg/dl', '', '0', ''),
-('66', 'Sugar', 'SUGAR', '', NULL, '', '', '', 'mg/dl', '', '0', ''),
-('67', 'Total Cell Count', 'TCC', '', NULL, '', '', '', 'per cmm', '', '0', ''),
-('68', 'Polymorphs', 'Polymorphs', '', NULL, '', '', '', '', '', '0', ''),
-('69', 'Lymphocytes', 'Lymphocyte', '', NULL, '', '', '', '', '', '0', ''),
-('70', 'Monocytes', 'Monocytes', '', NULL, '', '', '', '', '', '0', ''),
-('71', 'R.B.Cs', 'RBCS', '', NULL, '', '', '', '', '', '0', ''),
-('72', 'Others', 'OTHER', '', NULL, '', '', '', '', '', '0', ''),
-('73', 'Gram Stain', 'GRAMSTAIN', '', NULL, '', '', '', '', '', '0', ''),
-('74', 'Stain For A.F.B.', 'AFB', '', NULL, '', '', '', '', '', '0', ''),
-('75', 'Mesothelial', 'MESO', '', NULL, '', '', '', '', '', '0', ''),
-('76', 'Triiodothyronine', 'T3', '', NULL, '', '', '', 'ng/ml', '0.60-1.51', '0', ''),
-('77', 'Thyroxine', 'T4', '', NULL, '', '', '', 'ug/dl', '4.66-9.32', '0', ''),
-('78', 'Thyroid Stimulating Hormone', 'TSH', '', NULL, '', '', '', 'ulU/mL', '0.25-5.00', '0', ''),
-('79', 'Bilirubin Total', 'BT', '', NULL, '', '', '', '', '0.20-2.00', '0', ''),
-('80', 'Bilirubin Direct', 'BD', '', NULL, '', '', '', '', '0-0.3', '0', ''),
-('81', 'Bilirubin Indirect', 'BI', '', NULL, '', '', '', '', '0.00-0.70', '0', ''),
-('82', 'Troponin', 'TROP', '', NULL, '', '', '', '', '', '0', ''),
-('83', 'Troponine I (Trop I)', 'TROPI', '', NULL, '', '', '', '', '', '0', ''),
-('84', 'SERUM PROTEIN', 'SPro', '', NULL, '', '', '', 'mg', '6.4-8.3', '0', ''),
-('85', 'Colour', 'urine_colo', '', NULL, '', '', '', '', '', '0', ''),
-('86', 'Transparency', 'urine_tran', '', NULL, '', '', '', '', '', '0', ''),
-('87', 'PH', 'urine_ph', '', NULL, '', '', '', '', '4.7-7.5', '0', ''),
-('88', 'Albumin', 'urine_albu', '', NULL, '', '', '', '', '', '0', ''),
-('89', 'Sugar', 'urine_suga', '', NULL, '', '', '', '', '', '0', ''),
-('90', 'Bile Salt', 'ub_salt', '', NULL, '', '', '', '', '', '0', ''),
-('91', 'Bile Pigment', 'upigment', '', NULL, '', '', '', '', '', '0', ''),
-('92', 'Pus Cells', 'u_puscell', '', NULL, '', '', '', '', '', '0', ''),
-('93', 'Pus Cells', 'upuscells', '', NULL, '', '', '', '', '0-5', '0', ''),
-('94', 'Epithial Cells', 'uepithial', '', NULL, '', '', '', '', '0-5', '0', ''),
-('95', 'RBCs', 'urbc', '', NULL, '', '', '', '', '0-3', '0', ''),
-('96', 'crystals', 'urinecryst', '', NULL, '', '', '', '', '', '0', ''),
-('97', 'Specific Gravity', 'usg', 'QNS', NULL, '', '', '', '', '', '0', ''),
-('98', 'Crystals', 'ucrystals', '', NULL, '', '', '', '', '', '0', ''),
-('99', 'Cats', 'urinecasts', '', NULL, '', '', '', '', '', '0', ''),
-('100', 'Cholesterol', 'l_Choleste', '', NULL, '', '', '', '', '130-200', '0', ''),
-('101', 'Triglyceride', 'l_Triglyce', '', NULL, '', '', '', '', '45-160', '0', '');
-
-INSERT IGNORE INTO `lab_tests` (`mstTestKey`, `Test`, `TestID`, `Result`, `Options`, `Formula`, `VRule`, `VMsg`, `Unit`, `FixedNormals`, `isGenderSpecific`, `FixedNormalsWomen`) VALUES
-('102', 'HDL', 'l_hdl', '', NULL, '', '', '', '', '35-79', '0', ''),
-('103', 'LDL', 'l_ldl', '', NULL, '', '', '', '', '60-140', '0', ''),
-('104', 'VLDL', 'l_vldl', '', NULL, '', '', '', '', '10-35', '0', ''),
-('105', 'Bleeding Time', 'blood_bt', '', NULL, '', '', '', 'min', '0-7', '0', ''),
-('106', 'Clotting Time', 'blood_ct', '', NULL, '', '', '', 'min', '4.00-12.00', '0', ''),
-('107', 'HCV', 'hcv', '', NULL, '', '', '', '', '', '0', ''),
-('108', 'HBsAG', 'HBsAG', '', NULL, '', '', '', '', '', '0', ''),
-('109', 'Serum Amylase', 'AMYLASE', '', NULL, '', '', '', '', '20-80', '0', ''),
-('110', 'Serum Lipase', 'LIPASE', '', NULL, '', '', '', '', '0-60', '0', ''),
-('111', 'R A Factor', 'RAFACTOR', '', NULL, '', '', '', '', '0-25', '0', ''),
-('112', 'TLC Value', 'TLC1', '', NULL, '', '', '', '', '4000-11000', '0', ''),
-('113', 'Serum Cholesterol', 'Cholestero', '', NULL, '', '', '', '', '130-200', '0', ''),
-('114', 'Serum Trigycerides', 'Trigycerid', '', NULL, '', '', '', '', '45-160', '0', ''),
-('115', 'ABO', 'ABO', '', NULL, '', '', '', '', '', '0', ''),
-('116', 'Rh Factor', 'RHF', '', NULL, '', '', '', '', '', '0', ''),
-('117', 'PREGNANCY Test', 'PREGNANCYT', '', NULL, '', '', '', '', '', '0', ''),
-('118', 'TYPHOID IgM', 'lgm', '', NULL, '', '', '', '', '', '0', ''),
-('119', 'MALARIA ANTIGEN', 'MALARIA', '', NULL, '', '', '', '', '', '0', ''),
-('120', 'TYPHOID IgG', 'IgG', '', NULL, '', '', '', '', '', '0', ''),
-('121', 'TYPHOID IgM', 'IgM', '', NULL, '', '', '', '', '', '0', ''),
-('122', 'GAMMA GT', 'GAMAGT', '', NULL, '', '', '', '', '09-45', '0', ''),
-('123', 'CPK MB', 'CPKMB', '', NULL, '', '', '', '', '0-24', '0', ''),
-('124', 'CPK-NAC', 'CPNACK', '', NULL, '', '', '', '', '35-174', '0', ''),
-('125', 'PSA(PROSTATIC SPE. ANTIGEN)', 'PSA', '', NULL, '', '', '', '', '', '0', ''),
-('126', 'ASO', 'ASO', '', NULL, '', '', '', '', '0-200', '0', ''),
-('127', 'Dengue Ns1', 'DNS1', '', NULL, '', '', '', '', '', '0', ''),
-('128', 'Dengue IgM', 'DIGM', '', NULL, '', '', '', '', '', '0', ''),
-('129', 'Dengue IgG ', 'DIGG', '', NULL, '', '', '', '', '', '0', ''),
-('130', 'DCT', 'DCT', '', NULL, '', '', '', '', '', '0', ''),
-('131', 'Stool for Occult Blood', 'occult', 'Stool for Occult Blood', NULL, '', '', '', '', '', '0', ''),
-('132', 'RETICULOCYTE COUNT', 'Reticount', 'RETICULOCYTE COUNT', NULL, '', '', '', '%', '0.20-2.00', '0', ''),
-('133', 'BILE SALT', 'BS', '', NULL, '', '', '', '', '', '0', ''),
-('134', 'BILE PIGMENT', 'BP', '', NULL, '', '', '', '', '', '0', ''),
-('135', 'V.D.R.L', 'V.D.R.L', '', NULL, '', '', '', '', '', '0', ''),
-('136', 'G6PD', '{g6pd}', 'G6PD', NULL, '', '', '', '', '', '0', ''),
-('137', 'G6PD', 'G6PD', '', NULL, '', '', '', '', '6.40-18.7', '0', ''),
-('138', 'Indian Link', 'India Link', '', NULL, '', '', '', '', '', '0', ''),
-('139', 'LDH', 'LDH', '', NULL, '', '', '', '', '114-240', '0', ''),
-('140', 'SAFB', 'SAFB', '', NULL, '', '', '', '', '', '0', ''),
-('141', 'MALIGNANT CELLS', 'MC', '', NULL, '', '', '', '', '', '0', ''),
-('142', 'Color', 'stool_colo', '', NULL, '', '', '', '', '', '0', ''),
-('143', 'Consistency', 'Consistenc', '', NULL, '', '', '', '', '', '0', ''),
-('144', 'Mucus', 'Mucus', '', NULL, '', '', '', '', '', '0', ''),
-('145', 'PH', 'SPH', '', NULL, '', '', '', '', '', '0', ''),
-('146', 'Reducing Sugar', 'RSugar', '', NULL, '', '', '', '', '', '0', ''),
-('147', 'Pus Cells', 'PCells', '', NULL, '', '', '', '', '', '0', ''),
-('148', 'RBCs', 'sRBC', 'NIL', NULL, '', '', '', '', '', '0', ''),
-('149', 'Ova', 'Ova', '', NULL, '', '', '', '', '', '0', ''),
-('150', 'Cyst', 'Cyst', '', NULL, '', '', '', '', '', '0', ''),
-('151', 'Fat Globules', 'FatGlobuli', '', NULL, '', '', '', '', '', '0', ''),
-('152', 'S Typhi O 1:20', 'STyphiO1', '', NULL, '', '', '', '', '', '0', ''),
-('153', 'S Typhi O 1 :40', 'STyphiO2', '', NULL, '', '', '', '', '', '0', ''),
-('154', 'S Typhi O 1:80', 'STyphiO3', '', NULL, '', '', '', '', '', '0', ''),
-('155', 'S Typhi O 1:160', 'STyphiO4', '', NULL, '', '', '', '', '', '0', ''),
-('156', 'S Typhi O 1:320', 'STyphiO5', '', NULL, '', '', '', '', '', '0', ''),
-('157', 'S Typhi H 1:20', 'STyphiH1', '', NULL, '', '', '', '', '', '0', ''),
-('158', 'S Typhi H 1:40', 'STyphiH2', '', NULL, '', '', '', '', '', '0', ''),
-('159', 'S Typhi H 1:80', 'STyphiH3', '', NULL, '', '', '', '', '', '0', ''),
-('160', 'S Typhi H 1:320', 'STyphiH5', '', NULL, '', '', '', '', '', '0', ''),
-('161', 'S Para Typhi AH 1:20', 'SParaTyphiAH1', '', NULL, '', '', '', '', '', '0', ''),
-('162', 'S Para Typhi AH 1:40', 'SParaTyphiAH2', '', NULL, '', '', '', '', '', '0', ''),
-('163', 'S Para Typhi AH 1:80', 'SParaTyphiAH3', '', NULL, '', '', '', '', '', '0', ''),
-('164', 'S Para Typhi AH 1:160', 'SParaTyphiAH4', '', NULL, '', '', '', '', '', '0', ''),
-('165', 'S Para Typhi AH 1:320', 'SParaTyphiAH5', '', NULL, '', '', '', '', '', '0', ''),
-('166', 'S Para Typhi BH 1:20', 'SParaTyphiBH1', '', NULL, '', '', '', '', '', '0', ''),
-('167', 'S Para Typhi BH 1:40', 'SParaTyphiBH2', '', NULL, '', '', '', '', '', '0', ''),
-('168', 'S Para Typhi BH 1:80', 'SParaTyphiBH3', '', NULL, '', '', '', '', '', '0', ''),
-('169', 'S Para Typhi BH 1:160', 'SParaTyphiBH4', '', NULL, '', '', '', '', '', '0', ''),
-('170', 'S Para Typhi BH 1:320', 'SParaTyphiBH5', '', NULL, '', '', '', '', '', '0', ''),
-('171', 'Indirect Coombs Test', 'ICT', '', NULL, '', '', '', '', '', '0', ''),
-('172', 'Urine for Ketone', 'UFK', '', NULL, '', '', '', '', '', '0', ''),
-('173', 'MP', 'MALARIAP', '', NULL, '', '', '', '', '', '0', ''),
-('174', 'Blood Urea Nitrogen', 'BUN', '', NULL, '', '', '', '', '6-24', '0', ''),
-('175', 'Banejone Protein', 'BanP', '', NULL, '', '', '', '', '', '0', ''),
-('176', 'Urine For Protien', 'UFP', '', NULL, '', '', '', '', '', '0', ''),
-('177', 'Chikungunya IgM', 'CIGM', '', NULL, '', '', '', '', '', '0', ''),
-('178', 'P.P.D Given', 'PPDG', '', NULL, '', '', '', '', '', '0', ''),
-('179', 'Montoux Reading On', 'READON', '', NULL, '', '', '', '', '', '0', ''),
-('180', 'Montoux Induration', 'INDURATION', '', NULL, '', '', '', '', '', '0', ''),
-('181', 'Montoux Result', 'MONTEST', '', NULL, '', '', '', '', '', '0', ''),
-('182', 'EOSINOPHILS', 'EOSIN', '', NULL, '', '', '', '', '1-8', '0', ''),
-('183', 'SERUM PHOSPHORUS', 'SPHOSPHORUS', '', NULL, '', '', '', 'mg/dl', '2.5-5.0', '0', ''),
-('184', 'Ionised Calcium', 'ICALCIUM', '', NULL, '', '', '', 'mg/dl', '4.4-5.5', '0', ''),
-('185', 'Prothrombin Time ', 'PT', '', NULL, '', '', '', 'secs', '11-16', '0', ''),
-('186', 'Glucose Random', 'GR', '', NULL, '', '', '', 'mg/dl', '70-140', '0', ''),
-('187', 'A:G Ratio', 'AGR', '', NULL, '', '', '', '', '1.1-2.0', '0', ''),
-('188', 'BASOPHILES', 'BASO', '', NULL, '', '', '', '%', '0-1', '0', ''),
-('190', 'Bacteria flora few ', 'BFF', '', NULL, '', '', '', '', '', '0', ''),
-('191', 'Semen Reaction', 'semen_reaction', '', NULL, '', '', '', '', 'ALKALINE', '0', ''),
-('192', 'SEMENREMARKS', 'SEMENREMARKS', '', NULL, '', '', '', '', '', '0', ''),
-('193', 'Semen Active', 'semen_active', '', NULL, '', '', '', '', '0-60', '0', ''),
-('194', 'Sluggish', 'SLUGGISH', '', NULL, '', '', '', '%', '0-30', '0', ''),
-('195', 'CRP Status', 'CRPSTATUS', '', NULL, '', '', '', '', '', '0', ''),
-('196', 'VITAMIN12', 'VITAMIN12', '', NULL, '', '', '', 'ng/ml', '211-911', '0', ''),
-('197', 'DIMER', 'DIMER', '0', NULL, '', '', '', 'ug/ml', '0.0-0.5', '0', ''),
-('198', 'Beta HCG', 'BHCG', '', NULL, '', '', '', 'mIU/mL', '0-5.3', '0', ''),
-('199', 'Covid-19 Antgen Test', 'covid_antigen_t', '', NULL, '', '', '', '', '', '0', ''),
-('200', 'Glucose, Post Prandial (PP)', 'AGR1', '', NULL, '', '', '', '', '70.00-140.00', '0', '');
-
+-- No rows found in `lab_tests`
diff --git a/app/Database/Seeds/LabOemData/05_lab_tests_option.sql b/app/Database/Seeds/LabOemData/05_lab_tests_option.sql
index 7a8796e..2ab9673 100644
--- a/app/Database/Seeds/LabOemData/05_lab_tests_option.sql
+++ b/app/Database/Seeds/LabOemData/05_lab_tests_option.sql
@@ -11,196 +11,4 @@ CREATE TABLE IF NOT EXISTS `lab_tests_option` (
KEY `option_value` (`option_value`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
-INSERT IGNORE INTO `lab_tests_option` (`id`, `mstTestKey`, `sort_id`, `option_value`, `option_text`, `option_bold`) VALUES
-('74', '35', '1', 'NON-REACTIVE', 'NON-REACTIVE', '0'),
-('75', '35', '2', 'REACTIVE', 'REACTIVE', '0'),
-('76', '36', '1', 'NON-REACTIVE', 'NON-REACTIVE', '0'),
-('77', '36', '2', 'REACTIVE', 'REACTIVE', '0'),
-('22', '41', '1', 'Milky_White', 'Milky_White', '0'),
-('206', '41', '4', 'brownish or red', 'brownish or red', '0'),
-('208', '41', '5', 'Reddish in color ', 'Reddish in color ', '0'),
-('209', '41', '6', 'grey in color ', 'grey in color ', '0'),
-('23', '42', '1', 'Viscous', 'Viscous', '0'),
-('210', '42', '2', 'Thin ', 'Thin ', '0'),
-('211', '42', '3', 'Thick', 'Thick', '0'),
-('24', '50', '1', 'Serum', 'Serum', '0'),
-('25', '50', '2', 'Plasma', 'Plasma', '0'),
-('26', '50', '3', 'Pleural', 'Pleural', '0'),
-('27', '50', '4', 'Pericadial & Ascitic Fluids', 'Pericadial', '0'),
-('28', '62', '1', 'CLEAR', 'CLEAR', '0'),
-('219', '62', '3', 'Semi_Turbid', 'Semi_Turbid', '0'),
-('201', '62', '4', 'Turbid', 'Turbid', '0'),
-('29', '64', '1', 'ABSENT', 'ABSENT', '0'),
-('30', '64', '2', 'PRESENT', 'PRESENT', '0'),
-('31', '73', '1', 'No_Organism_Seen', 'No_Organism_Seen', '0'),
-('32', '73', '2', 'Positive', 'Positive', '0'),
-('33', '74', '1', 'Not-Detected', 'Not-Detected', '0'),
-('34', '74', '2', 'Postive_1', '+1', '0'),
-('35', '74', '3', 'Postive_2', '+2', '0'),
-('36', '74', '4', 'Postive_3', '+3', '0'),
-('37', '74', '5', 'Postive_4', '+4', '0'),
-('38', '82', '1', 'Positive', 'Positive', '0'),
-('39', '82', '2', 'Negative', 'Negative', '0'),
-('40', '83', '1', 'Positive', 'Positive', '0'),
-('41', '83', '2', 'Negative', 'Negative', '0'),
-('42', '85', '1', 'Yellow', 'Yellow', '0'),
-('43', '85', '2', 'Pale-Yellow', 'Pale-Yellow', '0'),
-('44', '85', '3', 'Reddish_Deep_Yellow', 'Reddish_Deep_Yellow', '0'),
-('93', '85', '4', 'Reddish', 'Reddish', '0'),
-('94', '85', '5', 'Deep-Yellow', 'Deep-Yellow', '0'),
-('45', '86', '1', 'Clear', 'Clear', '0'),
-('46', '86', '2', 'Turbid', 'Turbid', '0'),
-('49', '88', '1', 'NIL', 'NIL', '0'),
-('88', '88', '2', 'Trace', 'Trace', '0'),
-('50', '88', '3', 'Present +', 'Present+', '0'),
-('51', '88', '4', 'Present++', 'Present++', '0'),
-('52', '88', '5', 'Present+++', 'Present+++', '0'),
-('53', '88', '6', 'Present++++', 'Present++++', '0'),
-('54', '89', '1', 'Nil', 'Nil', '0'),
-('99', '89', '2', 'Trace', 'Trace', '0'),
-('55', '89', '3', 'Present+', 'Present+', '0'),
-('56', '89', '4', 'Present++', 'Present++', '0'),
-('57', '89', '5', 'Present+++', 'Present+++', '0'),
-('58', '89', '6', 'Present++++', 'Present++++', '0'),
-('59', '90', '1', 'Nil', 'Nil', '0'),
-('60', '90', '2', 'Present', 'Present', '0'),
-('61', '91', '1', 'Nil', 'Nil', '0'),
-('62', '91', '2', 'Present', 'Present', '0'),
-('63', '92', '1', '0-1', '0-1', '0'),
-('64', '92', '2', '1-2', '1-2', '0'),
-('65', '96', '1', 'Nil', 'NIL', '0'),
-('66', '96', '2', 'Calcium-Oxalate', 'Calcium-Oxalate', '0'),
-('67', '96', '3', 'Phosphate', 'Phosphate', '0'),
-('68', '96', '4', 'UricAcid', 'UricAcid', '0'),
-('116', '97', '1', 'Qns', 'Qns', '0'),
-('69', '99', '1', 'Nil', 'Nil', '0'),
-('70', '99', '2', 'Present Hyaline', 'Present Hyaline', '0'),
-('71', '99', '3', 'Granular', 'Granular', '0'),
-('72', '107', '1', 'Non-Reactive', 'Non-Reactive', '0'),
-('73', '107', '2', 'Reactive', 'Reactive', '0'),
-('78', '108', '1', 'NON-REACTIVE', 'NON-REACTIVE', '0'),
-('79', '108', '2', 'REACTIVE', 'REACTIVE', '0'),
-('80', '115', '1', 'A', 'A', '0'),
-('81', '115', '2', 'B', 'B', '0'),
-('82', '115', '3', 'AB', 'AB', '0'),
-('83', '115', '4', 'O', 'O', '0'),
-('84', '116', '1', 'POSITIVE', 'POSITIVE', '0'),
-('85', '116', '2', 'NEGATIVE', 'NEGATIVE', '0'),
-('86', '117', '1', 'Positive', 'Positive', '0'),
-('87', '117', '2', 'Negative', 'Negative', '0'),
-('89', '118', '1', 'Non-Reactive', 'Non-Reactive', '0'),
-('90', '118', '2', 'Reactive', 'Reactive', '0'),
-('91', '119', '1', 'NON-REACTIVE', 'NON-REACTIVE', '0'),
-('92', '119', '2', 'REACTIVE', 'REACTIVE', '0'),
-('95', '120', '1', 'Negative', 'Negative', '0'),
-('96', '120', '2', 'Positive', 'Positive', '0'),
-('97', '121', '1', 'Negative', 'Negative', '0'),
-('98', '121', '2', 'Positive', 'Positive', '0'),
-('101', '127', '1', 'NON-REACTIVE', 'NON-REACTIVE', '0'),
-('100', '127', '2', 'REACTIVE', 'REACTIVE', '0'),
-('103', '128', '1', 'NON-REACTIVE', 'NON-REACTIVE', '0'),
-('102', '128', '2', 'REACTIVE', 'REACTIVE', '0'),
-('105', '129', '1', 'NON-REACTIVE', 'NON-REACTIVE', '0'),
-('104', '129', '2', 'REACTIVE', 'REACTIVE', '0'),
-('106', '130', '1', 'NEGATIVE', 'NEGATIVE', '0'),
-('107', '130', '2', 'POSITIVE', 'POSITIVE', '0'),
-('108', '131', '1', 'Negative', 'Negative', '0'),
-('109', '131', '2', 'Positive', 'Positive', '0'),
-('110', '133', '1', 'NEGATIVE', 'NEGATIVE', '0'),
-('111', '133', '2', 'POSITIVE', 'POSITIVE', '0'),
-('112', '134', '1', 'NEGATIVE', 'NEGATIVE', '0'),
-('113', '134', '2', 'POSITIVE', 'POSITIVE', '0'),
-('178', '135', '3', 'Non-Reactive', 'Non-Reactive', '0'),
-('179', '135', '4', 'Reactive', 'Reactive', '0');
-
-INSERT IGNORE INTO `lab_tests_option` (`id`, `mstTestKey`, `sort_id`, `option_value`, `option_text`, `option_bold`) VALUES
-('117', '138', '1', 'Negative', 'Negative', '0'),
-('118', '138', '2', 'Positive', 'Positive', '0'),
-('119', '140', '1', 'Negative', 'Negative', '0'),
-('120', '140', '2', 'Postive+', 'Postive', '0'),
-('121', '140', '3', 'Postive++', 'Postive++', '0'),
-('122', '140', '4', 'Postive+++', 'Postive+++', '0'),
-('123', '140', '5', 'Postive++++', 'Postive++++', '0'),
-('124', '141', '1', 'Seen', 'Seen', '0'),
-('125', '141', '2', 'Not Seen', 'Not Seen', '0'),
-('126', '142', '1', 'Brownish', 'Brownish', '0'),
-('127', '142', '2', 'Yellow', 'Yellow', '0'),
-('128', '142', '3', 'Greenish', 'Greenish', '0'),
-('129', '143', '1', 'Loose', 'Loose', '0'),
-('130', '143', '2', 'Semi Formed', 'Semi Formed', '0'),
-('131', '143', '3', 'Fully Formed', 'Fully Formed', '0'),
-('132', '144', '1', 'Absent', 'Absent', '0'),
-('133', '144', '2', 'Present', 'Present', '0'),
-('134', '146', '1', 'Postive', 'Postive', '0'),
-('135', '146', '2', 'Negative', 'Negative', '0'),
-('136', '151', '1', 'Present', 'Present', '0'),
-('137', '151', '2', 'NIL', 'NIL', '0'),
-('139', '152', '1', '-', '-', '0'),
-('138', '152', '2', '+', '+', '0'),
-('140', '153', '1', '-', '-', '0'),
-('141', '153', '2', '+', '+', '0'),
-('142', '154', '1', '-', '-', '0'),
-('143', '154', '2', '+', '+', '0'),
-('144', '155', '1', '-', '-', '0'),
-('145', '155', '2', '+', '+', '0'),
-('146', '156', '1', '-', '-', '0'),
-('147', '156', '2', '+', '+', '0'),
-('148', '157', '1', '-', '-', '0'),
-('149', '157', '2', '+', '+', '0'),
-('150', '158', '1', '-', '-', '0'),
-('151', '158', '2', '+', '+', '0'),
-('152', '159', '1', '-', '-', '0'),
-('153', '159', '2', '+', '+', '0'),
-('154', '160', '1', '-', '-', '0'),
-('155', '160', '2', '+', '+', '0'),
-('156', '161', '1', '-', '-', '0'),
-('157', '161', '2', '+', '+', '0'),
-('158', '162', '1', '-', '-', '0'),
-('159', '162', '2', '+', '+', '0'),
-('160', '163', '1', '-', '-', '0'),
-('161', '163', '2', '+', '+', '0'),
-('162', '164', '1', '-', '-', '0'),
-('163', '164', '2', '+', '+', '0'),
-('164', '165', '1', '-', '-', '0'),
-('165', '165', '2', '+', '+', '0'),
-('166', '166', '1', '-', '-', '0'),
-('167', '166', '2', '+', '+', '0'),
-('168', '167', '1', '-', '-', '0'),
-('169', '167', '2', '+', '+', '0'),
-('170', '168', '1', '-', '-', '0'),
-('171', '168', '2', '+', '+', '0'),
-('172', '169', '1', '-', '-', '0'),
-('173', '169', '2', '+', '+', '0'),
-('174', '170', '1', '-', '-', '0'),
-('175', '170', '2', '+', '+', '0'),
-('176', '171', '1', 'Negative', 'Negative', '0'),
-('177', '171', '2', 'Positive', 'Positive', '0'),
-('180', '172', '1', 'Absent', 'Absent', '0'),
-('181', '172', '2', 'Present +', 'Present +', '0'),
-('182', '172', '3', 'Present ++', 'Present ++', '0'),
-('183', '172', '4', 'Present +++', 'Present +++', '0'),
-('184', '172', '5', 'Present ++++', 'Present ++++', '0'),
-('185', '173', '1', 'Not-Seen', 'Not-Seen', '0'),
-('186', '173', '2', 'Seen', 'Seen', '1'),
-('187', '175', '1', 'Negative', 'Negative', '0'),
-('188', '175', '2', 'Positive', 'Positive', '1'),
-('189', '176', '1', 'Absent', 'Absent', '0'),
-('190', '176', '2', 'Present', 'Present', '1'),
-('191', '177', '1', 'Negative', 'Negative', '0'),
-('192', '177', '2', 'Positive', 'Positive', '1'),
-('193', '181', '1', 'Negative', 'Negative', '0'),
-('194', '181', '2', 'Positive', 'Positive', '0'),
-('199', '190', '1', 'Nil', 'Nil', '0'),
-('195', '190', '2', '+', '+', '0'),
-('196', '190', '3', '+ +', '+ +', '0'),
-('197', '190', '4', '+ + +', '+ + +', '0'),
-('198', '190', '5', '+ + + +', '+ + + +', '0'),
-('202', '191', '1', 'ALKALINE', 'ALKALINE', '0'),
-('212', '191', '3', 'Acidic', 'Acidic', '0'),
-('213', '192', '1', 'Normal', 'Normal', '0'),
-('214', '192', '2', ' Abnormal', ' Abnormal', '0'),
-('217', '195', '1', 'Negative', 'Negative', '0'),
-('218', '195', '2', 'Positive', 'Positive', '1'),
-('220', '199', '1', 'Negative', 'Negative', '0'),
-('221', '199', '2', 'Positive', 'Positive', '1');
-
+-- No rows found in `lab_tests_option`
diff --git a/app/Database/Seeds/LabOemData/06_lab_repotests.sql b/app/Database/Seeds/LabOemData/06_lab_repotests.sql
index b3a1e7f..a2138a6 100644
--- a/app/Database/Seeds/LabOemData/06_lab_repotests.sql
+++ b/app/Database/Seeds/LabOemData/06_lab_repotests.sql
@@ -8,336 +8,4 @@ CREATE TABLE IF NOT EXISTS `lab_repotests` (
UNIQUE KEY `mstRepoKey_EOrder` (`mstRepoKey`,`EOrder`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb3;
-INSERT IGNORE INTO `lab_repotests` (`id`, `mstRepoKey`, `mstTestKey`, `EOrder`) VALUES
-('1', '1', '1', '1'),
-('2', '1', '2', '2'),
-('4', '1', '4', '4'),
-('5', '1', '5', '5'),
-('270', '1', '182', '7'),
-('7', '1', '7', '8'),
-('276', '1', '188', '11'),
-('10', '1', '10', '12'),
-('15', '1', '15', '13'),
-('12', '1', '12', '14'),
-('13', '1', '13', '15'),
-('14', '1', '14', '16'),
-('11', '1', '11', '17'),
-('278', '1', '26', '18'),
-('16', '2', '16', '1'),
-('180', '2', '80', '2'),
-('181', '2', '81', '3'),
-('27', '2', '27', '4'),
-('28', '2', '28', '5'),
-('29', '2', '29', '6'),
-('30', '2', '30', '7'),
-('31', '2', '31', '8'),
-('32', '2', '32', '9'),
-('275', '2', '187', '10'),
-('17', '3', '17', '1'),
-('18', '3', '18', '2'),
-('19', '3', '19', '3'),
-('22', '3', '22', '4'),
-('20', '3', '20', '5'),
-('21', '3', '21', '6'),
-('33', '4', '33', '1'),
-('286', '4', '195', '2'),
-('34', '5', '34', '1'),
-('35', '6', '35', '1'),
-('36', '6', '36', '2'),
-('160', '7', '108', '1'),
-('37', '8', '37', '1'),
-('38', '9', '38', '1'),
-('39', '10', '39', '1'),
-('40', '11', '40', '1'),
-('41', '11', '41', '2'),
-('280', '11', '191', '3'),
-('42', '11', '42', '4'),
-('43', '11', '43', '5'),
-('44', '11', '44', '6'),
-('282', '11', '193', '7'),
-('283', '11', '194', '9'),
-('46', '11', '46', '10'),
-('47', '11', '47', '11'),
-('48', '11', '48', '12'),
-('49', '11', '49', '13'),
-('285', '11', '148', '14'),
-('281', '11', '192', '15'),
-('50', '12', '50', '1'),
-('51', '12', '51', '2'),
-('52', '13', '52', '1'),
-('451', '13', '200', '2'),
-('53', '14', '53', '1'),
-('54', '14', '54', '2'),
-('55', '14', '55', '3'),
-('56', '14', '56', '4'),
-('273', '15', '185', '1'),
-('58', '15', '58', '2'),
-('57', '15', '57', '3'),
-('59', '16', '59', '1'),
-('60', '16', '60', '2'),
-('61', '17', '61', '1'),
-('62', '18', '62', '1'),
-('63', '18', '63', '2'),
-('64', '18', '64', '3'),
-('65', '18', '65', '4'),
-('66', '18', '66', '5'),
-('67', '18', '67', '6'),
-('68', '18', '68', '7'),
-('69', '18', '69', '8'),
-('70', '18', '70', '9'),
-('71', '18', '71', '10'),
-('72', '18', '72', '11'),
-('73', '18', '73', '12'),
-('74', '18', '74', '13'),
-('89', '19', '76', '1'),
-('90', '19', '77', '2'),
-('91', '19', '78', '3'),
-('75', '20', '62', '1'),
-('76', '20', '63', '2'),
-('77', '20', '64', '3'),
-('78', '20', '65', '4'),
-('79', '20', '66', '5'),
-('80', '20', '67', '6'),
-('81', '20', '68', '7'),
-('82', '20', '69', '8'),
-('88', '20', '75', '10'),
-('84', '20', '71', '12'),
-('86', '20', '73', '13'),
-('87', '20', '74', '14'),
-('92', '21', '79', '1'),
-('93', '21', '80', '2'),
-('94', '21', '81', '3'),
-('95', '22', '82', '1'),
-('96', '23', '83', '1');
-
-INSERT IGNORE INTO `lab_repotests` (`id`, `mstRepoKey`, `mstTestKey`, `EOrder`) VALUES
-('97', '24', '84', '1'),
-('98', '25', '16', '1'),
-('99', '26', '27', '1'),
-('100', '27', '28', '1'),
-('165', '28', '112', '1'),
-('102', '29', '4', '2'),
-('103', '29', '5', '3'),
-('269', '29', '182', '5'),
-('105', '29', '7', '6'),
-('106', '29', '8', '7'),
-('107', '29', '9', '8'),
-('113', '30', '4', '1'),
-('114', '31', '5', '1'),
-('116', '33', '10', '1'),
-('117', '34', '11', '1'),
-('118', '35', '12', '1'),
-('119', '36', '13', '1'),
-('120', '37', '14', '1'),
-('121', '38', '15', '1'),
-('122', '39', '17', '1'),
-('123', '40', '18', '1'),
-('124', '41', '19', '1'),
-('125', '42', '20', '1'),
-('126', '43', '21', '1'),
-('127', '44', '22', '1'),
-('128', '45', '24', '1'),
-('129', '46', '25', '1'),
-('130', '47', '26', '1'),
-('131', '48', '29', '1'),
-('133', '50', '73', '1'),
-('134', '51', '76', '1'),
-('135', '52', '77', '1'),
-('136', '54', '1', '1'),
-('137', '55', '85', '1'),
-('138', '55', '86', '2'),
-('149', '55', '97', '3'),
-('139', '55', '87', '4'),
-('140', '55', '88', '5'),
-('141', '55', '89', '6'),
-('145', '55', '93', '9'),
-('146', '55', '94', '10'),
-('147', '55', '95', '11'),
-('151', '55', '99', '12'),
-('148', '55', '96', '13'),
-('279', '55', '190', '14'),
-('152', '56', '100', '1'),
-('154', '56', '102', '2'),
-('155', '56', '103', '3'),
-('156', '56', '104', '4'),
-('153', '56', '101', '5'),
-('157', '57', '105', '1'),
-('158', '57', '106', '2'),
-('159', '58', '107', '1'),
-('161', '59', '78', '1'),
-('164', '62', '111', '1'),
-('234', '63', '152', '1'),
-('235', '63', '153', '2'),
-('236', '63', '154', '3'),
-('237', '63', '155', '4'),
-('238', '63', '156', '5'),
-('239', '63', '157', '6'),
-('240', '63', '158', '7'),
-('241', '63', '159', '8'),
-('242', '63', '160', '9'),
-('243', '63', '161', '10'),
-('244', '63', '162', '11'),
-('245', '63', '163', '12'),
-('246', '63', '164', '13'),
-('247', '63', '165', '14'),
-('248', '63', '166', '15'),
-('249', '63', '167', '16'),
-('250', '63', '168', '17'),
-('251', '63', '169', '18'),
-('252', '63', '170', '19'),
-('162', '64', '109', '1'),
-('163', '65', '110', '1'),
-('166', '66', '113', '1'),
-('167', '67', '114', '1'),
-('168', '68', '115', '1'),
-('169', '68', '116', '2'),
-('170', '69', '117', '1'),
-('224', '70', '142', '1'),
-('225', '70', '143', '2'),
-('226', '70', '144', '3'),
-('227', '70', '145', '4'),
-('228', '70', '146', '5'),
-('229', '70', '147', '6'),
-('230', '70', '148', '7'),
-('231', '70', '149', '8'),
-('232', '70', '150', '9'),
-('233', '70', '151', '10'),
-('174', '71', '121', '2'),
-('173', '71', '120', '3'),
-('172', '72', '119', '1'),
-('175', '73', '122', '1'),
-('177', '74', '124', '1'),
-('176', '75', '123', '1'),
-('178', '76', '125', '1'),
-('187', '77', '132', '1'),
-('179', '78', '126', '1');
-
-INSERT IGNORE INTO `lab_repotests` (`id`, `mstRepoKey`, `mstTestKey`, `EOrder`) VALUES
-('182', '79', '127', '1'),
-('183', '79', '128', '2'),
-('184', '79', '129', '3'),
-('185', '80', '130', '1'),
-('186', '81', '131', '1'),
-('188', '82', '133', '1'),
-('189', '83', '134', '1'),
-('190', '86', '135', '1'),
-('192', '87', '137', '1'),
-('223', '88', '141', '1'),
-('257', '91', '175', '1'),
-('193', '92', '1', '1'),
-('194', '92', '2', '2'),
-('195', '92', '4', '3'),
-('196', '92', '5', '4'),
-('197', '92', '6', '5'),
-('198', '92', '7', '6'),
-('199', '92', '8', '7'),
-('200', '92', '9', '8'),
-('201', '92', '10', '9'),
-('202', '92', '11', '10'),
-('203', '92', '12', '11'),
-('204', '92', '13', '12'),
-('205', '92', '14', '13'),
-('206', '92', '15', '14'),
-('207', '92', '26', '15'),
-('208', '93', '138', '1'),
-('209', '95', '139', '1'),
-('211', '97', '62', '1'),
-('212', '97', '63', '2'),
-('213', '97', '64', '3'),
-('214', '97', '65', '4'),
-('215', '97', '66', '5'),
-('216', '97', '67', '6'),
-('217', '97', '68', '7'),
-('218', '97', '69', '8'),
-('219', '97', '75', '9'),
-('220', '97', '71', '10'),
-('221', '97', '73', '11'),
-('222', '97', '74', '12'),
-('253', '98', '171', '1'),
-('254', '99', '172', '1'),
-('255', '100', '173', '1'),
-('256', '101', '174', '1'),
-('258', '102', '176', '1'),
-('259', '103', '177', '1'),
-('264', '128', '178', '1'),
-('265', '128', '179', '2'),
-('266', '128', '180', '3'),
-('267', '128', '181', '4'),
-('271', '129', '183', '1'),
-('272', '130', '184', '1'),
-('274', '131', '186', '1'),
-('421', '132', '1', '1'),
-('422', '132', '2', '2'),
-('423', '132', '4', '3'),
-('424', '132', '5', '4'),
-('425', '132', '182', '5'),
-('426', '132', '7', '6'),
-('427', '132', '188', '7'),
-('428', '132', '10', '8'),
-('429', '132', '15', '9'),
-('430', '132', '12', '10'),
-('431', '132', '13', '11'),
-('432', '132', '14', '12'),
-('433', '132', '11', '13'),
-('434', '132', '26', '14'),
-('435', '132', '59', '15'),
-('436', '132', '60', '16'),
-('437', '132', '39', '17'),
-('438', '132', '100', '18'),
-('439', '132', '102', '19'),
-('440', '132', '103', '20'),
-('441', '132', '104', '21'),
-('442', '132', '101', '22'),
-('443', '132', '76', '23'),
-('444', '132', '77', '24'),
-('445', '132', '78', '25'),
-('379', '133', '1', '1'),
-('380', '133', '2', '2'),
-('381', '133', '4', '3'),
-('382', '133', '5', '4'),
-('383', '133', '182', '5'),
-('384', '133', '7', '6'),
-('385', '133', '188', '7'),
-('386', '133', '10', '8'),
-('387', '133', '15', '9'),
-('388', '133', '12', '10'),
-('389', '133', '13', '11'),
-('390', '133', '14', '12'),
-('391', '133', '11', '13'),
-('392', '133', '26', '14'),
-('393', '133', '59', '15'),
-('394', '133', '61', '16'),
-('395', '133', '39', '17'),
-('396', '133', '100', '18'),
-('397', '133', '102', '19'),
-('398', '133', '103', '20'),
-('399', '133', '104', '21'),
-('400', '133', '101', '22');
-
-INSERT IGNORE INTO `lab_repotests` (`id`, `mstRepoKey`, `mstTestKey`, `EOrder`) VALUES
-('401', '133', '76', '23'),
-('402', '133', '77', '24'),
-('403', '133', '78', '25'),
-('404', '133', '16', '26'),
-('405', '133', '80', '27'),
-('406', '133', '81', '28'),
-('407', '133', '27', '29'),
-('408', '133', '28', '30'),
-('409', '133', '29', '31'),
-('410', '133', '30', '32'),
-('411', '133', '31', '33'),
-('412', '133', '32', '34'),
-('413', '133', '187', '35'),
-('414', '133', '17', '36'),
-('415', '133', '18', '37'),
-('416', '133', '19', '38'),
-('417', '133', '22', '39'),
-('418', '133', '20', '40'),
-('419', '133', '21', '41'),
-('420', '133', '38', '42'),
-('447', '133', '196', '43'),
-('446', '134', '196', '1'),
-('448', '135', '197', '1'),
-('449', '136', '198', '1'),
-('450', '137', '199', '1');
-
+-- No rows found in `lab_repotests`
diff --git a/app/Libraries/Abdm/EAtriaBridgeConnector.php b/app/Libraries/Abdm/EAtriaBridgeConnector.php
index 29ce4ed..51da195 100644
--- a/app/Libraries/Abdm/EAtriaBridgeConnector.php
+++ b/app/Libraries/Abdm/EAtriaBridgeConnector.php
@@ -308,7 +308,7 @@ class EAtriaBridgeConnector implements AbdmConnectorInterface
public function sharePrescriptionBundle(array $payload, string $entityId = ''): array
{
return $this->post('/v3/bundle/push', [
- 'consent_id' => (string) ($payload['consent_handle'] ?? $payload['consent_id'] ?? ''),
+ 'consent_id' => (string) ($payload['consent_id'] ?? $payload['consent_handle'] ?? ''),
'hi_type' => (string) ($payload['hi_type'] ?? 'OPConsultation'),
'fhir_bundle' => $payload['bundle'] ?? $payload['fhir_bundle'] ?? [],
]);
@@ -317,7 +317,7 @@ class EAtriaBridgeConnector implements AbdmConnectorInterface
public function shareIpdDischargeBundle(array $payload, string $entityId = ''): array
{
return $this->post('/v3/bundle/push', [
- 'consent_id' => (string) ($payload['consent_handle'] ?? $payload['consent_id'] ?? ''),
+ 'consent_id' => (string) ($payload['consent_id'] ?? $payload['consent_handle'] ?? ''),
'hi_type' => 'DischargeSummary',
'fhir_bundle' => $payload['bundle'] ?? $payload['fhir_bundle'] ?? [],
]);
@@ -326,7 +326,7 @@ class EAtriaBridgeConnector implements AbdmConnectorInterface
public function shareDiagnosisReportBundle(array $payload, string $entityId = ''): array
{
return $this->post('/v3/bundle/push', [
- 'consent_id' => (string) ($payload['consent_handle'] ?? $payload['consent_id'] ?? ''),
+ 'consent_id' => (string) ($payload['consent_id'] ?? $payload['consent_handle'] ?? ''),
'hi_type' => 'DiagnosticReport',
'fhir_bundle' => $payload['bundle'] ?? $payload['fhir_bundle'] ?? [],
]);
@@ -582,4 +582,66 @@ class EAtriaBridgeConnector implements AbdmConnectorInterface
return $this->get('/v3/drugs/version', $query);
}
+
+ // -------------------------------------------------------------------------
+ // Pathology Terminology (LOINC)
+ // -------------------------------------------------------------------------
+
+ /**
+ * Fetch pathology panel masters from the Bridge API.
+ *
+ * @param string $subCategory 'PATHOLOGY' | 'BIOPSY' | '' for all
+ * @param int $limit items per page (max 500)
+ * @param int $offset pagination offset
+ * @param string $updatedSince ISO-8601 datetime for incremental sync
+ * @return array
+ */
+ public function pathologyMasters(
+ string $subCategory = '',
+ int $limit = 200,
+ int $offset = 0,
+ string $updatedSince = ''
+ ): array {
+ $query = ['limit' => max(1, min(500, $limit)), 'offset' => $offset];
+ if ($subCategory !== '') {
+ $query['sub_category'] = strtoupper($subCategory);
+ }
+ if ($updatedSince !== '') {
+ $query['updated_since'] = $updatedSince;
+ }
+ if ($this->hfrId !== '') {
+ $query['hfr_id'] = $this->hfrId;
+ }
+
+ return $this->get('/v3/pathology/masters', $query);
+ }
+
+ /**
+ * Fetch LOINC component details for a specific pathology panel.
+ *
+ * @param string $parentTest Exact panel name (e.g. 'Complete Blood Count Panel')
+ * @param int $limit items per page
+ * @param int $offset pagination offset
+ * @param string $updatedSince ISO-8601 datetime for incremental sync
+ * @return array
+ */
+ public function pathologyComponents(
+ string $parentTest = '',
+ int $limit = 200,
+ int $offset = 0,
+ string $updatedSince = ''
+ ): array {
+ $query = ['limit' => max(1, min(500, $limit)), 'offset' => $offset];
+ if ($parentTest !== '') {
+ $query['parent_test'] = $parentTest;
+ }
+ if ($updatedSince !== '') {
+ $query['updated_since'] = $updatedSince;
+ }
+ if ($this->hfrId !== '') {
+ $query['hfr_id'] = $this->hfrId;
+ }
+
+ return $this->get('/v3/pathology/components', $query);
+ }
}
diff --git a/app/Views/PathLab_Report/lab_report_edit.php b/app/Views/PathLab_Report/lab_report_edit.php
index 8597cf2..7757da8 100644
--- a/app/Views/PathLab_Report/lab_report_edit.php
+++ b/app/Views/PathLab_Report/lab_report_edit.php
@@ -6,22 +6,61 @@
-
- Report Name
- 0) {
- $repo_name = $labReport_master[0]->Title ?? '';
- $repo_id = $labReport_master[0]->mstRepoKey ?? '0';
- $HTMLData = $labReport_master[0]->HTMLData ?? '';
- }
- ?>
-
-
+ 0) {
+ $repo_name = $labReport_master[0]->Title ?? '';
+ $repo_id = $labReport_master[0]->mstRepoKey ?? '0';
+ $HTMLData = $labReport_master[0]->HTMLData ?? '';
+ $repo_loinc_code = $labReport_master[0]->loinc_code ?? $repo_loinc_code;
+ }
+ ?>
+
+
+
+
+
+
+
+
+
Attach Charge Name
@@ -96,40 +135,401 @@
= form_close() ?>
diff --git a/app/Views/PathLab_Report/lab_report_item_edit.php b/app/Views/PathLab_Report/lab_report_item_edit.php
index bc67384..2c56be6 100644
--- a/app/Views/PathLab_Report/lab_report_item_edit.php
+++ b/app/Views/PathLab_Report/lab_report_item_edit.php
@@ -10,7 +10,10 @@ $Unit = '';
$FixedNormals = '';
$isGenderSpecific = 0;
$FixedNormalsWomen = '';
-$checkbox_checked = '';
+$loincCode = '';
+$loincProperty = '';
+$loincSystem = '';
+$loincScale = '';
if (count($lab_test_parameter ?? []) > 0) {
$mstTestKey = $lab_test_parameter[0]->mstTestKey ?? 0;
@@ -24,241 +27,407 @@ if (count($lab_test_parameter ?? []) > 0) {
$FixedNormals = $lab_test_parameter[0]->FixedNormals ?? '';
$isGenderSpecific = (int) ($lab_test_parameter[0]->isGenderSpecific ?? 0);
$FixedNormalsWomen = $lab_test_parameter[0]->FixedNormalsWomen ?? '';
+ $loincCode = $lab_test_parameter[0]->loinc_code ?? '';
+ $loincProperty = $lab_test_parameter[0]->loinc_property ?? '';
+ $loincSystem = $lab_test_parameter[0]->loinc_system ?? '';
+ $loincScale = $lab_test_parameter[0]->loinc_scale ?? '';
+}
- if ($isGenderSpecific == 1) {
- $checkbox_checked = 'checked';
- }
+$normalMin = '';
+$normalMax = '';
+if (strpos((string) $FixedNormals, '-') !== false) {
+ [$normalMin, $normalMax] = array_pad(explode('-', (string) $FixedNormals, 2), 2, '');
+}
+
+$femaleNormalMin = '';
+$femaleNormalMax = '';
+if (strpos((string) $FixedNormalsWomen, '-') !== false) {
+ [$femaleNormalMin, $femaleNormalMax] = array_pad(explode('-', (string) $FixedNormalsWomen, 2), 2, '');
+}
+
+$valueType = 'TEXT';
+if ($Formula !== '') {
+ $valueType = 'FORMULA';
+} elseif ($VRule !== '' || ($normalMin !== '' || $normalMax !== '')) {
+ $valueType = 'NUMERIC';
}
?>
= form_open() ?>
-
+
+
+
-
-
-
- Name of Test
-
-
-
-
-
-
-
= form_close() ?>
diff --git a/app/Views/PathLab_Report/lab_report_list.php b/app/Views/PathLab_Report/lab_report_list.php
index 1995c99..166159d 100644
--- a/app/Views/PathLab_Report/lab_report_list.php
+++ b/app/Views/PathLab_Report/lab_report_list.php
@@ -1,135 +1,1248 @@
-= form_open() ?>