FDBPGController.php 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. <?php
  2. namespace App\Http\Controllers;
  3. use Illuminate\Http\Request;
  4. use Illuminate\Support\Facades\DB;
  5. class FDBPGController extends Controller
  6. {
  7. public function rx(Request $request)
  8. {
  9. return view('app.fdb-pg.fdb-rx');
  10. }
  11. // 1. medication suggest
  12. public function medSuggest(Request $request)
  13. {
  14. $term = $request->input('term') ? trim($request->input('term')) : '';
  15. if (empty($term)) return '';
  16. $matches = DB::connection('pgsql_fdb')->select(
  17. "SELECT med_name_id, med_name FROM rminmid1_med_name WHERE med_status_cd = '0' AND med_name ILIKE :term ORDER BY med_name",
  18. ['term' => '%' . $term . '%']
  19. );
  20. return view('app.fdb-pg.fdb-med-suggest', compact('matches'));
  21. }
  22. // 2. routed meds from men name
  23. public function routedMeds(Request $request)
  24. {
  25. $medNameID = $request->input('med-name-id') ? trim($request->input('med-name-id')) : '';
  26. if (empty($medNameID)) return '';
  27. $matches = DB::connection('pgsql_fdb')->select(
  28. "SELECT routed_med_id, med_routed_med_id_desc FROM rmirmid1_routed_med WHERE med_status_cd = '0' AND med_name_id = :medNameID ORDER BY med_routed_med_id_desc",
  29. ['medNameID' => $medNameID]
  30. );
  31. return json_encode($matches);
  32. }
  33. // 3. routed dosage from routed med
  34. public function routedDosages(Request $request)
  35. {
  36. $routedMedID = $request->input('routed-med-id') ? trim($request->input('routed-med-id')) : '';
  37. if (empty($routedMedID)) return '';
  38. $matches = DB::connection('pgsql_fdb')->select(
  39. "SELECT routed_dosage_form_med_id, med_routed_df_med_id_desc FROM rmidfid1_routed_dose_form_med WHERE med_status_cd = '0' AND routed_med_id = :routedMedID ORDER BY med_routed_df_med_id_desc",
  40. ['routedMedID' => $routedMedID]
  41. );
  42. return json_encode($matches);
  43. }
  44. // 4. strengths from routed med
  45. public function meds(Request $request)
  46. {
  47. $dosageFormMedId = $request->input('dosage-form-med-id') ? trim($request->input('dosage-form-med-id')) : '';
  48. if (empty($dosageFormMedId)) return '';
  49. $matches = DB::connection('pgsql_fdb')->select(
  50. "SELECT medid, med_medid_desc, gcn_seqno FROM rmiid1_med WHERE med_status_cd = '0' AND routed_dosage_form_med_id = :dosageFormMedId ORDER BY med_medid_desc",
  51. ['dosageFormMedId' => $dosageFormMedId]
  52. );
  53. return json_encode($matches);
  54. }
  55. // side effects for a given rx
  56. public function sideEffects(Request $request)
  57. {
  58. $gcnSeqNo = $request->input('gcn-seq-no') ? trim($request->input('gcn-seq-no')) : '';
  59. if (empty($gcnSeqNo)) return '';
  60. $sides = DB::connection('pgsql_fdb')->select("
  61. SELECT r1.side, sm.side_freq, sm.side_sev, sm.dxid, dx.dxid_desc56
  62. FROM rsidegc0_gcnseqno_link r1
  63. JOIN rsidema3_mstr sm ON r1.side = sm.side
  64. JOIN rfmldx0_dxid dx ON sm.dxid = dx.dxid
  65. WHERE r1.gcn_seqno = :gcnSeqNo
  66. ORDER BY sm.side_sev DESC, sm.side_freq ASC
  67. ",
  68. ['gcnSeqNo' => $gcnSeqNo]
  69. );
  70. return view('app.fdb-pg.fdb-side-effects', compact('sides'));
  71. }
  72. // ger prec for a given rx
  73. public function geriatricPrecautions(Request $request)
  74. {
  75. $gcnSeqNo = $request->input('gcn-seq-no') ? trim($request->input('gcn-seq-no')) : '';
  76. if (empty($gcnSeqNo)) return '';
  77. $precautions = DB::connection('pgsql_fdb')->select("
  78. SELECT r1.geri_code, gm.geri_sl, gm.geri_desc, gm.geri_narrative
  79. FROM rgerigc0_geri_gcnseqno_link r1
  80. JOIN rgerima1_geri_mstr gm ON r1.geri_code = gm.geri_code
  81. WHERE r1.gcn_seqno = :gcnSeqNo
  82. ORDER BY gm.geri_desc
  83. ",
  84. ['gcnSeqNo' => $gcnSeqNo]
  85. );
  86. return view('app.fdb-pg.fdb-geriatric-precautions', compact('precautions'));
  87. }
  88. // indication of a given rx
  89. public function indications(Request $request)
  90. {
  91. $gcnSeqNo = $request->input('gcn-seq-no') ? trim($request->input('gcn-seq-no')) : '';
  92. if (empty($gcnSeqNo)) return '';
  93. $indications = DB::connection('pgsql_fdb')->select("
  94. SELECT r1.indcts, r2.indcts_sn, r2.indcts_lbl, r2.dxid, r2.proxy_ind, r3.dxid_desc56
  95. FROM rindmgc0_indcts_gcnseqno_link r1
  96. JOIN rindmma2_indcts_mstr r2 ON r1.indcts = r2.indcts
  97. JOIN rfmldx0_dxid r3 ON r2.dxid = r3.dxid
  98. WHERE r1.gcn_seqno = :gcnSeqNo
  99. ORDER BY r3.dxid_desc56
  100. ",
  101. ['gcnSeqNo' => $gcnSeqNo]
  102. );
  103. return view('app.fdb-pg.fdb-indications', compact('indications'));
  104. }
  105. // contra-indications of a given rx
  106. public function contraindications(Request $request)
  107. {
  108. $routedMedID = $request->input('routed-med-id') ? trim($request->input('routed-med-id')) : '';
  109. if (empty($routedMedID)) return '';
  110. $contraindications = DB::connection('pgsql_fdb')->select("
  111. SELECT r1.ddxcn, r2.dxid, r2.ddxcn_sl, r3.dxid_desc56
  112. FROM rddcmrm0_routed_med_link r1
  113. JOIN rddcmma1_contra_mstr r2 ON r1.ddxcn = r2.ddxcn
  114. JOIN rfmldx0_dxid r3 ON r2.dxid = r3.dxid
  115. WHERE r1.routed_med_id = :routedMedID
  116. ORDER BY r2.ddxcn_sl
  117. ",
  118. ['routedMedID' => $routedMedID]
  119. );
  120. return view('app.fdb-pg.fdb-contraindications', compact('contraindications'));
  121. }
  122. // dx suggest
  123. public function dxSuggest(Request $request)
  124. {
  125. $term = $request->input('term') ? trim($request->input('term')) : '';
  126. if (empty($term)) return '';
  127. $matches = DB::connection('pgsql_fdb')->select("
  128. SELECT distinct(r1.dxid), r1.dxid_desc56
  129. FROM rfmldx0_dxid r1
  130. JOIN rfmlsyn0_dxid_syn r2 ON r1.dxid = r2.dxid
  131. WHERE (r1.dxid_desc56 ILIKE :term OR r1.dxid_desc100 ILIKE :term OR r2.dxid_syn_desc56 ILIKE :term OR r2.dxid_syn_desc100 ILIKE :term)
  132. ORDER BY r1.dxid_desc56
  133. ",
  134. ['term' => '%' . $term . '%']
  135. );
  136. return view('app.fdb-pg.fdb-dx-suggest', compact('matches'));
  137. }
  138. // allergy suggest
  139. public function allergySuggest(Request $request)
  140. {
  141. $term = $request->input('term') ? trim($request->input('term')) : '';
  142. if (empty($term)) return '';
  143. $matches = DB::connection('pgsql_fdb')->select("
  144. SELECT r1.dam_concept_id, r1.dam_concept_id_typ, r1.dam_concept_id_desc
  145. FROM rdamca0_concept r1
  146. WHERE (r1.dam_concept_id_desc ILIKE :term)
  147. ORDER BY r1.dam_concept_id_desc
  148. ",
  149. ['term' => '%' . $term . '%']
  150. );
  151. return view('app.fdb-pg.fdb-allergy-suggest', compact('matches'));
  152. }
  153. // drug <-> allergy match making
  154. public function drugAllergies(Request $request) {
  155. // override
  156. if($request->input('test')) {
  157. $x = new \stdClass();
  158. $x->allergen = 'Pollen';
  159. $x->dam_concept_id_typ = 6;
  160. $allergies = [$x];
  161. $y = new \stdClass();
  162. $y->rx = 'Brufen';
  163. $rx = [$y];
  164. }
  165. else {
  166. $input = json_decode($request->input('data'));
  167. $allergies = $input->allergies;
  168. $rx = $input->rx;
  169. }
  170. $output = [];
  171. /*
  172. for each allergy
  173. if dam_concept_id_typ = 1 // allergen-group-id
  174. // https://docs.fdbhealth.com/display/MKDOCUS/Screening+an+NDC+for+a+DAM_ALRGN_GRP+Allergen+-+Illustration+of+Scenario+C
  175. ...
  176. elseif dam_concept_id_typ = 2 // medication-name-id
  177. // https://docs.fdbhealth.com/display/MKDOCUS/Screening+an+NDC+for+a+MED_NAME_ID+Allergen+-+Illustration+of+Scenario+B
  178. ...
  179. elseif dam_concept_id_typ = 6 // base-ingredient-id
  180. // https://docs.fdbhealth.com/display/MKDOCUS/Screening+an+NDC+for+an+Ingredient+Allergen+-+Illustration+of+Scenario+A
  181. ...
  182. endif
  183. endfor
  184. */
  185. foreach ($allergies as $allergy) {
  186. foreach ($rx as $rxItem) {
  187. if($allergy->dam_concept_id_typ == 6) { // ingredient
  188. if ($this->drugAllergyIngredientAllergenVsSingleRx($allergy, $rxItem)) {
  189. $output[] = "<b>{$rxItem->rx}</b> can cause allergic reactions since the patient is allergic to <b>{$allergy->allergen}</b>.";
  190. }
  191. }
  192. else if($allergy->dam_concept_id_typ == 2) { // medication
  193. if ($this->drugAllergyMedicationAllergenVsSingleRx($allergy, $rxItem)) {
  194. $output[] = "<b>{$rxItem->rx}</b> can cause allergic reactions since the patient is allergic to <b>{$allergy->allergen}</b>.";
  195. }
  196. }
  197. else if($allergy->dam_concept_id_typ == 1) { // allergen group
  198. if ($this->drugAllergyGroupAllergenVsSingleRx($allergy, $rxItem)) {
  199. $output[] = "<b>{$rxItem->rx}</b> can cause allergic reactions since the patient is allergic to <b>{$allergy->allergen}</b>.";
  200. }
  201. }
  202. }
  203. }
  204. return implode("<br>", $output);
  205. }
  206. private function drugAllergyIngredientAllergenVsSingleRx($_allergen, $_rx) {
  207. $matches = DB::connection('pgsql_fdb')->select("
  208. (
  209. -- ingredients from medication
  210. SELECT R1.related_hic_seqn as hic_seqn, R2.hic_desc
  211. FROM RHICHCR0_HIC_HIC_LINK R1
  212. JOIN RHICD5_HIC_DESC R2 ON R1.related_hic_seqn = R2.hic_seqn
  213. WHERE R1.hic_seqn IN (
  214. SELECT S2.dam_alrgn_hic_seqn
  215. FROM RMEDMHL0_MED_HICLSEQNO_LINK S1
  216. JOIN RDAMHHA0_HIC_HICL_ALG_LINK S2 ON S1.hicl_seqno = S2.hicl_seqno
  217. WHERE S1.med_concept_id = :medid
  218. AND S1.med_concept_id_typ = 3
  219. )
  220. )
  221. INTERSECT
  222. (
  223. -- all ingredients directly and related from allergens
  224. (
  225. SELECT R1.related_hic_seqn as hic_seqn, R2.hic_desc
  226. FROM RHICHCR0_HIC_HIC_LINK R1
  227. JOIN RHICD5_HIC_DESC R2 ON R1.related_hic_seqn = R2.hic_seqn
  228. WHERE R1.hic_seqn = :allergenConceptID
  229. )
  230. UNION
  231. -- all ingredients via related dam allergen groups
  232. (
  233. SELECT r3.hic_seqn, r4.hic_desc
  234. FROM RDAMGHC0_HIC_ALRGN_GRP_LINK R1
  235. JOIN rdamagd1_alrgn_grp_desc R2 on R1.dam_alrgn_grp = R2.dam_alrgn_grp
  236. JOIN RDAMGHC0_HIC_ALRGN_GRP_LINK R3 on R1.dam_alrgn_grp = R3.dam_alrgn_grp
  237. JOIN RHICD5_HIC_DESC R4 on r3.hic_seqn = r4.hic_seqn
  238. WHERE R1.hic_seqn = :allergenConceptID
  239. AND R2.dam_alrgn_grp_status_cd = 0
  240. ORDER BY r3.hic_seqn
  241. )
  242. )
  243. ",
  244. ['medid' => $_rx->medid, 'allergenConceptID' => $_allergen->dam_concept_id]
  245. );
  246. return !!count($matches);
  247. }
  248. private function drugAllergyMedicationAllergenVsSingleRx($_allergen, $_rx) {
  249. $matches = DB::connection('pgsql_fdb')->select("
  250. (
  251. -- ingredients from medication
  252. SELECT R1.related_hic_seqn as hic_seqn
  253. FROM RHICHCR0_HIC_HIC_LINK R1
  254. JOIN RHICD5_HIC_DESC R2 ON R1.related_hic_seqn = R2.hic_seqn
  255. WHERE R1.hic_seqn IN (
  256. SELECT S2.dam_alrgn_hic_seqn
  257. FROM RMEDMHL0_MED_HICLSEQNO_LINK S1
  258. JOIN RDAMHHA0_HIC_HICL_ALG_LINK S2 ON S1.hicl_seqno = S2.hicl_seqno
  259. WHERE S1.med_concept_id = :medid
  260. AND S1.med_concept_id_typ = 3
  261. )
  262. )
  263. INTERSECT
  264. (
  265. -- all ingredients directly and related from allergens
  266. SELECT R1.dam_alrgn_hic_seqn as hic_seqn
  267. FROM RDAMHHA0_HIC_HICL_ALG_LINK R1
  268. WHERE R1.hicl_seqno IN (
  269. SELECT R1.hicl_seqno
  270. FROM RMEDMHL0_MED_HICLSEQNO_LINK R1
  271. WHERE R1.med_concept_id_typ = 1
  272. AND R1.med_concept_id = :allergenConceptID
  273. AND MED_CONCEPT_HICL_SRC_CD = 0
  274. )
  275. )
  276. ",
  277. ['medid' => $_rx->medid, 'allergenConceptID' => $_allergen->dam_concept_id]
  278. );
  279. return !!count($matches);
  280. }
  281. private function drugAllergyGroupAllergenVsSingleRx($_allergen, $_rx) {
  282. $matches = DB::connection('pgsql_fdb')->select("
  283. (
  284. -- ingredients from medication
  285. SELECT R1.related_hic_seqn as hic_seqn
  286. FROM RHICHCR0_HIC_HIC_LINK R1
  287. JOIN RHICD5_HIC_DESC R2 ON R1.related_hic_seqn = R2.hic_seqn
  288. WHERE R1.hic_seqn IN (
  289. SELECT S2.dam_alrgn_hic_seqn
  290. FROM RMEDMHL0_MED_HICLSEQNO_LINK S1
  291. JOIN RDAMHHA0_HIC_HICL_ALG_LINK S2 ON S1.hicl_seqno = S2.hicl_seqno
  292. WHERE S1.med_concept_id = :medid
  293. AND S1.med_concept_id_typ = 3
  294. )
  295. )
  296. INTERSECT
  297. (
  298. -- ingredients from medication allergen
  299. (
  300. SELECT R1.hic_seqn as hic_seqn
  301. FROM RDAMGHC0_HIC_ALRGN_GRP_LINK R1
  302. WHERE R1.DAM_ALRGN_GRP = :allergenConceptID
  303. )
  304. UNION
  305. (
  306. SELECT distinct s1.hic_seqn
  307. FROM RDAMXHC0_HIC_ALRGN_XSENSE_LINK S1
  308. WHERE S1.dam_alrgn_xsense IN (
  309. SELECT R1.dam_alrgn_xsense
  310. FROM RDAMGX0_ALRGN_GRP_XSENSE_LINK R1
  311. JOIN RDAMCSD1_XSENSIT_ALLERGY_DESC R2 on R1.dam_alrgn_xsense = R2.dam_alrgn_xsense
  312. WHERE R1.dam_alrgn_grp = :allergenConceptID
  313. AND R2.dam_alrgn_xsense_status_cd = 0
  314. )
  315. )
  316. )
  317. ",
  318. ['medid' => $_rx->medid, 'allergenConceptID' => $_allergen->dam_concept_id]
  319. );
  320. return !!count($matches);
  321. }
  322. // drug <-> drug match making
  323. public function drugDrugInteraction(Request $request) {
  324. if($request->input('test')) {
  325. // override
  326. $rx = json_decode(json_encode([
  327. [
  328. "gcn_seqno" => "45190",
  329. "med_name_id" => "18604",
  330. "medid" => "234539",
  331. "routed_dosage_form_med_id" => "95130",
  332. "routed_med_id" => "19876",
  333. "rx" => "Zyprexa Zydis",
  334. ],
  335. [
  336. "gcn_seqno" => "49853",
  337. "med_name_id" => "26164",
  338. "medid" => "400058",
  339. "routed_dosage_form_med_id" => "36194",
  340. "routed_med_id" => "32562",
  341. "rx" => "Orfadin",
  342. ],
  343. ]));
  344. }
  345. else {
  346. $input = json_decode($request->input('data'));
  347. $rx = $input->rx;
  348. }
  349. if(count($rx) < 2) return "";
  350. $leftIndex = 0;
  351. $output = [];
  352. for ($i=$leftIndex; $i<count($rx) - 1; $i++) {
  353. for ($j=$i + 1; $j<count($rx); $j++) {
  354. $output[] = $this->drugDrugInteractionSinglePair($rx[$i], $rx[$j]);
  355. }
  356. }
  357. $output = array_filter($output, function($_x) {
  358. return !!$_x;
  359. });
  360. return implode("<br>", $output);
  361. }
  362. private function drugDrugInteractionSinglePair($_rx1, $_rx2) {
  363. $output = [];
  364. // get active ingredient DDI_CODEX values for drug 1 and 2
  365. $rx1ActiveDdiCodex = $this->getActiveDdiCodexFromGcnSeqNo($_rx1->gcn_seqno);
  366. $rx2ActiveDdiCodex = $this->getActiveDdiCodexFromGcnSeqNo($_rx2->gcn_seqno);
  367. if(!$rx1ActiveDdiCodex || !$rx2ActiveDdiCodex || !count($rx1ActiveDdiCodex) || !count($rx2ActiveDdiCodex)) return "";
  368. // dump($rx1_DDI_CODEX);
  369. // dump($rx2_DDI_CODEX);
  370. // get inactive ingredient DDI_CODEX values for drug 1 and 2
  371. // to get this we need to first get the NDCs of the drugs
  372. $rx1Ndc = $this->getNdcFromMedId($_rx1->medid);
  373. $rx2Ndc = $this->getNdcFromMedId($_rx2->medid);
  374. // dump($rx1Ndc);
  375. // dump($rx2Ndc);
  376. $rx1InactiveDdiCodex = $this->getInactiveDdiCodexFromNdc($rx1Ndc);
  377. $rx2InactiveDdiCodex = $this->getInactiveDdiCodexFromNdc($rx2Ndc);
  378. // if(!$rx1InactiveDdiCodex || !$rx2InactiveDdiCodex || !count($rx1InactiveDdiCodex) || !count($rx2InactiveDdiCodex)) return "";
  379. // dump($rx1InactiveDdiCodex);
  380. // dump($rx2InactiveDdiCodex);
  381. // get ddi codex - monox pairs for drug 1 & 2
  382. $rx1ActiveDdiCodexMonoxPairs = $this->getDdiCodexMonoxPairs($rx1ActiveDdiCodex);
  383. $rx1InactiveDdiCodexMonoxPairs = $this->getDdiCodexMonoxPairs($rx1InactiveDdiCodex);
  384. $rx2ActiveDdiCodexMonoxPairs = $this->getDdiCodexMonoxPairs($rx2ActiveDdiCodex);
  385. $rx2InactiveDdiCodexMonoxPairs = $this->getDdiCodexMonoxPairs($rx2InactiveDdiCodex);
  386. // dump($rx1ActiveDdiCodexMonoxPairs);
  387. // dump($rx1InactiveDdiCodexMonoxPairs);
  388. // dump($rx2ActiveDdiCodexMonoxPairs);
  389. // dump($rx2InactiveDdiCodexMonoxPairs);
  390. // compare 1-active to 2-active and 2-inactive
  391. $activeCatches = [];
  392. foreach ($rx1ActiveDdiCodexMonoxPairs as $compareLeft) {
  393. foreach ($rx2ActiveDdiCodexMonoxPairs as $compareRight) {
  394. if($compareLeft->ddi_monox == $compareRight->ddi_monox && $compareLeft->ddi_codex != $compareRight->ddi_codex) {
  395. $activeCatches[] = $compareLeft->ddi_codex;
  396. }
  397. }
  398. foreach ($rx2InactiveDdiCodexMonoxPairs as $compareRight) {
  399. if($compareLeft->ddi_monox == $compareRight->ddi_monox && $compareLeft->ddi_codex != $compareRight->ddi_codex) {
  400. $activeCatches[] = $compareLeft->ddi_codex;
  401. }
  402. }
  403. }
  404. // compare 1-inactive to 2-active and 2-inactive
  405. $inactiveCatches = [];
  406. foreach ($rx1InactiveDdiCodexMonoxPairs as $compareLeft) {
  407. foreach ($rx2ActiveDdiCodexMonoxPairs as $compareRight) {
  408. if($compareLeft->ddi_monox == $compareRight->ddi_monox && $compareLeft->ddi_codex != $compareRight->ddi_codex) {
  409. $inactiveCatches[] = $compareLeft->ddi_codex;
  410. }
  411. }
  412. foreach ($rx2InactiveDdiCodexMonoxPairs as $compareRight) {
  413. if($compareLeft->ddi_monox == $compareRight->ddi_monox && $compareLeft->ddi_codex != $compareRight->ddi_codex) {
  414. $inactiveCatches[] = $compareLeft->ddi_codex;
  415. }
  416. }
  417. }
  418. if(count($activeCatches)) {
  419. $output[] = "<b>{$_rx2->rx}</b> interacts with one or more active ingredients in <b>{$_rx1->rx}</b>.";
  420. }
  421. if(count($inactiveCatches)) {
  422. $output[] = "<b>{$_rx2->rx}</b> interacts with one or more inactive ingredients in <b>{$_rx1->rx}</b>.";
  423. }
  424. // TODO: find out and show the names of the actual ingredients causing interaction
  425. return implode("<br>", $output);
  426. }
  427. private function getActiveDdiCodexFromGcnSeqNo($_gcnSeqNo) {
  428. $ddiCodexArray = [];
  429. $query = DB::connection('pgsql_fdb')->select("
  430. SELECT r1.ddi_codex
  431. FROM RADIMGC4_GCNSEQNO_LINK r1
  432. WHERE r1.gcn_seqno = :gcnSeqNo
  433. ",
  434. ['gcnSeqNo' => $_gcnSeqNo]
  435. );
  436. if(count($query)) {
  437. $ddiCodexArray = array_map(function($_x) {
  438. return $_x->ddi_codex;
  439. }, $query);
  440. }
  441. return $ddiCodexArray;
  442. }
  443. private function getNdcFromMedId($_medId) {
  444. $ndcArray = [];
  445. $query = DB::connection('pgsql_fdb')->select("
  446. select ndc from rmindc1_ndc_medid where medid = :medId
  447. ",
  448. ['medId' => $_medId]
  449. );
  450. if(count($query)) {
  451. $ndcArray = array_map(function($_x) {
  452. return $_x->ndc;
  453. }, $query);
  454. }
  455. return $ndcArray;
  456. }
  457. private function getInactiveDdiCodexFromNdc($_ndc) {
  458. $ddiCodexArray = [];
  459. $query = DB::connection('pgsql_fdb')->select("
  460. SELECT distinct r1.ddi_codex
  461. FROM RDDIMIN0_NDC_INACTV_DDIM_LINK r1
  462. WHERE r1.ddi_ndc IN (" . implode(',', array_map(function($_x) {return "'" . $_x . "'";}, $_ndc)) . ")
  463. "
  464. );
  465. if(count($query)) {
  466. $ddiCodexArray = array_map(function($_x) {
  467. return $_x->ddi_codex;
  468. }, $query);
  469. }
  470. return $ddiCodexArray;
  471. }
  472. private function getDdiCodexMonoxPairs($_ddiCodexArray) {
  473. $ddiCodexMonoxPairsArray = [];
  474. if(count($_ddiCodexArray)) {
  475. $ddiCodexMonoxPairsArray = DB::connection('pgsql_fdb')->select("
  476. SELECT r1.ddi_codex, r1.ddi_monox
  477. FROM RADIMMA5_MSTR r1
  478. WHERE r1.ddi_codex IN (" . implode(',', array_map(function($_x) {return "'" . $_x . "'";}, $_ddiCodexArray)) . ")
  479. "
  480. );
  481. }
  482. return $ddiCodexMonoxPairsArray;
  483. }
  484. // drug <-> drug coadministration notes
  485. public function drugCoadministration(Request $request) {
  486. $gcnSeqnos = $request->input('gcn-seqnos') ? trim($request->input('gcn-seqnos')) : '';
  487. if (empty($gcnSeqnos)) return '';
  488. //$gcnSeqnos = explode(",", $gcnSeqnos);
  489. $coadministration = DB::connection('pgsql_fdb')->select("
  490. SELECT distinct r1.coadmin_dosing_text
  491. FROM radige0_ddi_gcnseqno_except r1
  492. WHERE r1.side_a_gcn_seqno in ($gcnSeqnos) AND r1.side_b_gcn_seqno in ($gcnSeqnos)
  493. "
  494. );
  495. return view('app.fdb-pg.fdb-coadministration', compact('coadministration'));
  496. }
  497. // duplicate therapy indications
  498. public function duplicateTherapy(Request $request) {
  499. if($request->input('test')) {
  500. // override
  501. $rx = json_decode(json_encode([
  502. [
  503. "gcn_seqno" => "4376",
  504. "med_name_id" => "1076",
  505. "medid" => "172480",
  506. "routed_dosage_form_med_id" => "5870",
  507. "routed_med_id" => "1082",
  508. "rx" => "aspirin 325",
  509. ],
  510. [
  511. "gcn_seqno" => "4377",
  512. "med_name_id" => "1076",
  513. "medid" => "216092",
  514. "routed_dosage_form_med_id" => "5870",
  515. "routed_med_id" => "1082",
  516. "rx" => "aspirin 500",
  517. ],
  518. ]));
  519. }
  520. else {
  521. $input = json_decode($request->input('data'));
  522. $rx = $input->rx;
  523. }
  524. $dptClasses = [];
  525. foreach ($rx as $rxItem) {
  526. $rxItem->dpt = $this->getDptClassFromGcnSeqNo($rxItem->gcn_seqno);
  527. }
  528. // dd($rx);
  529. $leftIndex = 0;
  530. $matches = [];
  531. for ($i=$leftIndex; $i<count($rx) - 1; $i++) {
  532. for ($j=$i + 1; $j<count($rx); $j++) {
  533. $compareResult = $this->compareDPTs($rx[$i]->dpt, $rx[$j]->dpt);
  534. foreach ($compareResult as $c) {
  535. $matches[] = "<b>{$rx[$i]->rx}</b> and <b>{$rx[$j]->rx}</b> both participate in the duplicate therapy class <b>{$c->dpt_class_desc}</b> (duplicates allowed: {$c->dpt_allowance})";
  536. }
  537. }
  538. }
  539. return "<ol class='pl-0 ml-3'>" . implode("", array_map(function($_x) {
  540. return "<li class='mb-2'>" . $_x . "</li>";
  541. }, $matches)) . "</ol>";
  542. }
  543. private function getDptClassFromGcnSeqNo($_gcnSeqNo) {
  544. return DB::connection('pgsql_fdb')->select("
  545. SELECT distinct r1.dpt_class_id, r2.dpt_allowance, r2.dpt_class_desc
  546. FROM RDPTGC0_GCNSEQNO_LINK r1
  547. JOIN RDPTCL0_CLASS_ID r2 on r1.dpt_class_id = r2.dpt_class_id
  548. WHERE r1.gcn_seqno = :gcnSeqNo
  549. ",
  550. ['gcnSeqNo' => $_gcnSeqNo]
  551. );
  552. }
  553. private function compareDPTs($_dptArray1, $_dptArray2) {
  554. $output = [];
  555. for ($i=0; $i<count($_dptArray1); $i++) {
  556. for ($j=0; $j<count($_dptArray2); $j++) {
  557. if($_dptArray1[$i]->dpt_class_id == $_dptArray2[$j]->dpt_class_id) {
  558. $output[] = json_decode(json_encode([
  559. "dpt_allowance" => $_dptArray1[$i]->dpt_allowance,
  560. "dpt_class_desc" => $_dptArray1[$i]->dpt_class_desc
  561. ]));
  562. }
  563. }
  564. }
  565. return $output;
  566. }
  567. }