diff --git a/app/Controllers/Medical.php b/app/Controllers/Medical.php index 3d2dd0d..b1afe78 100644 --- a/app/Controllers/Medical.php +++ b/app/Controllers/Medical.php @@ -6252,7 +6252,7 @@ class Medical extends BaseController $limit = 10; } - $cacheKey = 'abdm_drug_ac_' . md5($type . '_' . strtolower($q) . '_' . $limit); + $cacheKey = 'abdm_drug_ac_v2_' . md5($type . '_' . strtolower($q) . '_' . $limit); $cached = cache($cacheKey); if (is_array($cached) && ! empty($cached) && ($cached['ok'] ?? 0) === 1) { return $this->response->setJSON($cached); @@ -6282,7 +6282,7 @@ class Medical extends BaseController ]); $brandName = $this->extractDrugText($row, ['brand_name', 'trade_name']); $label = $this->extractDrugText($row, [ - 'label', 'name', 'display', 'term', 'title', 'drug_name', 'product_name', + 'label', 'display_name', 'name', 'display', 'term', 'title', 'drug_name', 'product_name', 'medicine_name', 'brand_name', 'trade_name', ]); $identifier = $this->extractDrugText($row, ['identifier', 'id', 'code', 'concept_id', 'value']); @@ -6292,33 +6292,36 @@ class Medical extends BaseController $itemType = $type; } - if ($itemType === 'brand' && $brandName !== '') { - $label = $brandName; - } - - if ($this->isDrugIdentifierLike($label) && $displayName !== '' && ! $this->isDrugIdentifierLike($displayName)) { + if ($displayName !== '') { $label = $displayName; + } elseif ($brandName !== '') { + $label = $brandName; + } elseif ($label === '' || $this->isDrugIdentifierLike($label)) { + $label = $identifier; } if ($label === '' && $identifier === '') { continue; } - if ($label === '' && $displayName !== '') { - $label = $displayName; - } - - if ($label === '') { - $label = $identifier; - } + $dosageForm = $this->extractDrugText($row, ['dosage_form', 'formulation', 'short_formulation', 'drug_form']); + $route = $this->extractDrugText($row, ['route', 'administration_route']); + $manufacturer = $this->extractDrugText($row, ['manufacturer_name', 'manufacturer', 'company_name', 'company']); + $strength = $this->extractDrugText($row, ['strength_text', 'strength']); + $packSize = $this->extractDrugText($row, ['pack_size_text', 'pack_size', 'package', 'packing']); $suggestions[] = [ - 'label' => $label, - 'display_name' => $displayName, - 'brand_name' => $brandName, - 'generic_name' => $generic, - 'identifier' => $identifier, - 'type' => $itemType, + 'label' => $label, + 'display_name' => $displayName, + 'brand_name' => $brandName, + 'generic_name' => $generic, + 'identifier' => $identifier, + 'type' => $itemType, + 'dosage_form' => $dosageForm, + 'route' => $route, + 'manufacturer_name' => $manufacturer, + 'strength_text' => $strength, + 'pack_size_text' => $packSize, ]; } @@ -6351,7 +6354,7 @@ class Medical extends BaseController ]); } - $cacheKey = 'abdm_drug_dt_' . md5($type . '_' . $identifier); + $cacheKey = 'abdm_drug_dt_v2_' . md5($type . '_' . $identifier); $cached = cache($cacheKey); if (is_array($cached) && ! empty($cached) && ($cached['ok'] ?? 0) === 1) { return $this->response->setJSON($cached); @@ -6375,7 +6378,7 @@ class Medical extends BaseController ]); $brandName = $this->extractDrugText($record, ['brand_name', 'trade_name']); $label = $this->extractDrugText($record, [ - 'label', 'name', 'display', 'term', 'title', 'drug_name', 'product_name', + 'label', 'display_name', 'name', 'display', 'term', 'title', 'drug_name', 'product_name', 'medicine_name', 'brand_name', 'trade_name', ]); $generic = $this->extractDrugText($record, ['generic_name', 'genericname', 'generic', 'salt', 'molecule']); @@ -6392,17 +6395,11 @@ class Medical extends BaseController $canonicalId = $identifier; } - if ($itemType === 'brand' && $brandName !== '') { + if ($displayName !== '') { + $label = $displayName; + } elseif ($brandName !== '') { $label = $brandName; - } - - if ($this->isDrugIdentifierLike($label) && $displayName !== '' && ! $this->isDrugIdentifierLike($displayName)) { - $label = $displayName; - } - if ($label === '' && $displayName !== '') { - $label = $displayName; - } - if ($label === '') { + } elseif ($label === '' || $this->isDrugIdentifierLike($label)) { $label = $canonicalId; } diff --git a/app/Views/medical/product_edit.php b/app/Views/medical/product_edit.php index 92f6e46..5c1b130 100644 --- a/app/Views/medical/product_edit.php +++ b/app/Views/medical/product_edit.php @@ -553,16 +553,26 @@ window.closeDrugMasterSubView = window.closeDrugMasterSubView || function () { after = normalizeSpace(m[3]); } - if (before) { - result.productName = before; - } - - var formRegex = /\b(tablet|capsule|syrup|suspension|injection|cream|ointment|gel|drops?|solution|powder|lotion|spray|respules?|inhaler|patch|suppository|lozenge|granules?)\b/i; + var formRegex = /\b(tablet|capsule|syrup|suspension|injection|cream|ointment|gel|drops?|solution\s+for\s+(?:infusion|injection)|solution|powder|lotion|spray|respules?|inhaler|patch|suppository|lozenge|granules?)\b/i; var formMatch = formRegex.exec(after || label); if (formMatch) { result.formulation = normalizeSpace(formMatch[1]); } + if (before) { + var cleanAfter = after ? normalizeSpace(after.replace(/\b(oral|route|for\s+oral\s+use)\b/gi, '')) : ''; + if (result.formulation && cleanAfter) { + var reForm = new RegExp('\\b' + result.formulation.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&') + '\\b', 'i'); + var capForm = result.formulation.charAt(0).toUpperCase() + result.formulation.slice(1); + cleanAfter = cleanAfter.replace(reForm, capForm); + } + if (cleanAfter) { + result.productName = normalizeSpace(before + ' ' + cleanAfter); + } else { + result.productName = before; + } + } + if (inside) { var genericTail = after; if (formMatch && after) { @@ -708,25 +718,25 @@ window.closeDrugMasterSubView = window.closeDrugMasterSubView || function () { } function deriveDrugName(detail, parsed) { + var productName = normalizeSpace(parsed && parsed.productName ? parsed.productName : ''); + var displayName = normalizeSpace(detail.display_name || ''); + var label = normalizeSpace(detail.label || ''); var brandName = normalizeSpace(detail.brand_name || ''); var manufacturerName = normalizeSpace(detail.manufacturer_name || ''); - var label = normalizeSpace(detail.label || ''); - var displayName = normalizeSpace(detail.display_name || ''); - var productName = normalizeSpace(parsed && parsed.productName ? parsed.productName : ''); - if (brandName) { - return brandName; + if (productName && !isIdentifierLike(productName)) { + return productName; } - if (manufacturerName && !isIdentifierLike(manufacturerName)) { - return manufacturerName; + if (displayName && !isIdentifierLike(displayName)) { + return displayName; } if (label && !isIdentifierLike(label)) { return label; } - if (displayName && !isIdentifierLike(displayName)) { - return parsed && parsed.productName ? productName : displayName; + if (brandName && !isIdentifierLike(brandName)) { + return brandName; } - return productName || displayName || label; + return productName || displayName || label || ''; } function deriveGenericName(detail, parsed, flatMeta) { @@ -1100,28 +1110,43 @@ window.closeDrugMasterSubView = window.closeDrugMasterSubView || function () { var genericName = item.generic_name || ''; var type = item.type || ''; var identifier = item.identifier || ''; + var dosageForm = item.dosage_form || ''; + var manufacturerName = item.manufacturer_name || ''; clearSuggestionBox(); - // Apply parsed fields immediately so user sees direct form fill. - applyParsedLabelToForm(label); + // Use the rich displayName (contains brand, generic, strength, route, and formulation) + var richLabel = displayName || label; + var parsed = parseDrugLabel(richLabel); - if (type === 'brand' && brandName && !isIdentifierLike(brandName)) { - $('#input_item_name').val(brandName); - } else if (displayName && !isIdentifierLike(displayName)) { - $('#input_item_name').val(displayName); + // Derive clean product name (e.g. "Dolo 650 mg Tablet") + var derivedName = parsed.productName || brandName || richLabel; + if (derivedName && !isIdentifierLike(derivedName)) { + $('#input_item_name').val(derivedName); } - if (genericName) { + if (parsed.genericName) { + $('#input_genericname').val(parsed.genericName); + } else if (genericName) { $('#input_genericname').val(genericName); } + if (parsed.formulation) { + setFormulationValue(parsed.formulation); + setFormulationByCode(parsed.formulation); + } else if (dosageForm) { + setFormulationValue(dosageForm); + setFormulationByCode(dosageForm); + } + if (manufacturerName) { + setCompanyByName(manufacturerName); + } - $('#abdm_drug_display').val((type === 'brand' && brandName) ? brandName : label); + $('#abdm_drug_display').val(richLabel); $('#abdm_drug_type').val(type); $('#abdm_drug_identifier').val(identifier); $('#abdm_drug_last_synced_at').val(new Date().toISOString().slice(0, 19).replace('T', ' ')); showSelectedDrugSummary(); - // Fetch canonical details for richer metadata autofill. + // Fetch canonical details for richer metadata autofill (company code, HSN, tax, schedules, etc.) fetchDrugDetail(type, identifier); } @@ -1144,24 +1169,47 @@ window.closeDrugMasterSubView = window.closeDrugMasterSubView || function () { var genericName = item.generic_name || ''; var type = item.type || ''; var identifier = item.identifier || ''; - if (!label && !identifier) { + var dosageForm = item.dosage_form || ''; + var manufacturerName = item.manufacturer_name || ''; + var strengthText = item.strength_text || ''; + + if (!label && !identifier && !displayName) { return; } - var $a = $(''); + var fullTitle = displayName || label || brandName || identifier; + + var $a = $(''); $a.attr('data-idx', String(idx)); - var mainText = (type === 'brand' ? (brandName || label) : '') || displayName || label || identifier; + var detailParts = []; - if (genericName && genericName.toLowerCase() !== String(mainText).toLowerCase()) { - detailParts.push('Generic: ' + genericName); + if (genericName) { + detailParts.push('Generic: ' + $('
').text(genericName).html() + ''); } - if (type) { - detailParts.push('Type: ' + type); + if (dosageForm) { + detailParts.push('Form: ' + $('
').text(dosageForm).html()); } - if (identifier && identifier !== mainText) { - detailParts.push('ID: ' + identifier); + if (strengthText) { + detailParts.push('Strength: ' + $('
').text(strengthText).html()); } - $a.text(mainText + (detailParts.length ? ' | ' + detailParts.join(' | ') : '')); + if (identifier) { + detailParts.push('CDCI ID: ' + $('
').text(identifier).html()); + } + + var html = '
' + + '
' + $('
').text(fullTitle).html() + '
'; + if (manufacturerName) { + html += ' ' + + $('
').text(manufacturerName).html() + + ' '; + } + html += '
'; + + if (detailParts.length) { + html += '
' + detailParts.join('  |  ') + '
'; + } + + $a.html(html); $a.on('click', function (e) { e.preventDefault(); chooseSuggestion(idx);