quick minor path updates (#1968)
[openemr.git] / custom / qrda_category1_functions.php
bloba5470ea4c2007307ee4474e24f9789005c098ce3
1 <?php
2 /**
4 * QRDA Functions
6 * Copyright (C) 2015 Ensoftek, Inc
8 * LICENSE: This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://opensource.org/licenses/gpl-license.php>;.
19 * @package OpenEMR
20 * @author Ensoftek
21 * @link http://www.open-emr.org
23 // This program exports report to QRDA Category I 2014 XML format.
26 function mainQrdaCatOneGenerate($xml, $patient_id, $rule_id, $provider_id)
28 //Open Main Clinical Document
29 $xml->open_clinicaldocument();
31 //Header Function
32 getHeaderQRDA1($xml, $patient_id, $provider_id);
34 //Component Function
35 getComponentQRDA1($xml, $patient_id, $rule_id);
37 //Close Main Clinical Document
38 $xml->close_clinicaldocument();
40 //Downloaded XML
41 $xmlDynFileName = downloadQRDACat1($xml, $patient_id, $rule_id);
43 return $xmlDynFileName;
46 //Main Header Function
47 function getHeaderQRDA1($xml, $patient_id, $provider_id)
49 global $mainQrdaRaceCodeArr, $mainEthiCodeArr, $from_date, $to_date;
51 //Patient Info
52 if ($patient_id != "") {
53 $patientRow = getPatData($patient_id);
56 //User Info
57 $userRow = getUsrDataCheck($provider_id);
58 $facility_name = $userRow['facility'];
59 $facility_id = $userRow['facility_id'];
61 //Facility Info
62 if ($facility_id != "") {
63 $facilResRow = getFacilDataChk($facility_id);
66 ####################### HEADER ELEMENTS START ##########################################
68 $xml->self_realmcode();
70 $xml->self_typeid();
72 $tempId = '2.16.840.1.113883.10.20.22.1.1';
73 $xml->self_templateid($tempId);
75 $tempId = '2.16.840.1.113883.10.20.24.1.1';
76 $xml->self_templateid($tempId);
78 $tempId = '2.16.840.1.113883.10.20.24.1.2';
79 $xml->self_templateid($tempId);
81 $tempId = '2.16.840.1.113883.10.20.24.1.3';
82 $xml->self_templateid($tempId);
84 $xml->unique_id = getUuid();
85 $xml->self_id();
87 $arr = array('code'=>'55182-0', 'displayName'=>'Quality Measure Report', 'codeSystem'=>'2.16.840.1.113883.6.1', 'codeSystemName'=>'LOINC');
88 $xml->self_codeCustom($arr);
90 //Main Title Display to XML
91 $main_title = "QRDA Category-I Report";
92 $xml->add_title($main_title);
94 //Effective date and time
95 $eff_datetime = date('Ymdhis', strtotime($from_date));
96 $xml->self_efftime($eff_datetime);
98 $xml->self_confidentcode();
100 //Language
101 $xml->self_lang();
103 //Record Target Elements
104 $xml->open_recordTarget();
106 //patientRole Open
107 $xml->open_customTag('patientRole');
109 $xml->self_customTag('id', array('root' => '2.16.840.1.113883.4.572', 'extension' =>'112233'));
111 $xml->add_patientAddress($patientRow);
113 if ($patientRow['phone_home'] != "") {
114 $xml->self_customTag('telecom', array('value' => $patientRow['phone_home'], 'use'=>'HP'));
115 } else {
116 $xml->self_customTag('telecom', array('nullFlavor' => "UNK"));
119 $xml->open_customTag('patient');
121 $patNameArr = array('fname' =>$patientRow['fname'], 'lname'=>$patientRow['lname']);
122 $xml->add_patName($patNameArr);
124 if ($patientRow['sex'] == "Male") {
125 $gender = "M";
126 } else if ($patientRow['sex'] == "Female") {
127 $gender = "F";
130 $xml->self_customTag('administrativeGenderCode', array('codeSystem' => '2.16.840.1.113883.18.2', 'code' =>$gender));
132 $xml->self_customTag('birthTime', array('value' =>date('Ymd', strtotime($patientRow['DOB']))));
134 if ($mainQrdaRaceCodeArr[$patientRow['race']] == "") {
135 $mainQrdaRaceCodeArr[$patientRow['race']] = "2131-1";
138 $xml->self_customTag('raceCode', array('codeSystem' =>'2.16.840.1.113883.6.238', 'code' => $mainQrdaRaceCodeArr[$patientRow['race']]));
139 $xml->self_customTag('ethnicGroupCode', array('codeSystem' =>'2.16.840.1.113883.6.238', 'code' => $mainEthiCodeArr[$patientRow['ethnicity']]));
141 //patient Close
142 $xml->close_customTag();
144 //patientRole Close
145 $xml->close_customTag();
147 $xml->close_recordTarget();
149 ############### Author Info Start#######################
150 $xml->open_author();
152 //Author time
153 $auth_dtime = date('Ymdhis');
154 $xml->self_authorTime($auth_dtime);
156 //Assigned Author
157 $xml->open_assignAuthor();
158 $npi_provider = empty($userRow['npi']) ? "FakeNPI" : $userRow['npi'];
159 $xml->self_customTag('id', array('root' =>'2.16.840.1.113883.4.6', 'extension' => $npi_provider));
160 $xml->add_patientAddress($facilResRow);
161 if (!empty($userRow['phone'])) {
162 $xml->self_customTag('telecom', array('value' => $userRow['phone'], 'use'=>'WP'));
163 } else {
164 $xml->self_customTag('telecom', array("nullFlavor" => "UNK"));
170 //assignedAuthoringDevice Start
171 $xml->open_customTag('assignedAuthoringDevice');
172 $xml->element('manufacturerModelName', 'DrCloudEMR');
173 $xml->element('softwareName', 'DrCloudEMR');
174 //assignedAuthoringDevice Close
175 $xml->close_customTag();
177 $xml->close_assignAuthor();
178 ################## Author Info End ##########################
180 $xml->close_author();
181 ############### Author Info End#######################
183 ############### Custodian Info Start #######################
184 $xml->open_custodian();
185 $xml->open_assgnCustodian();
186 $xml->add_represtCustodianOrginisation($facilResRow);
187 $xml->close_assgnCustodian();
188 $xml->close_custodian();
189 ############### Custodian Info End #######################
191 ############### Legal Authenticator Start#######################
192 $xml->open_legalAuthenticator();
193 $auth_dtime = date('Ymdhis');
194 $xml->self_authorTime($auth_dtime);
195 $xml->self_legalSignCode();
197 $xml->open_assignedEntity();
198 $assignedEntityId = getUuid();
199 $xml->self_customId($assignedEntityId);
200 $xml->add_facilAddress($facilResRow);
201 if (!empty($facilResRow['phone'])) {
202 $xml->self_customTag('telecom', array('value' => $facilResRow['phone'], 'use'=>'WP'));
203 } else {
204 $xml->self_customTag('telecom', array("nullFlavor" => "UNK"));
207 $xml->open_customTag('assignedPerson');
209 //Provider Name
210 $userNameArr = array('fname' =>$userRow['fname'], 'lname'=>$userRow['lname']);
211 $xml->add_providerName($userNameArr);
213 //assignedPerson Close
214 $xml->close_customTag();
216 //Represent Origination Name
217 $xml->add_authReprestOrginisation($facilResRow);
218 $xml->close_assignedEntity();
220 $xml->close_legalAuthenticator();
221 ############### Legal Authenticator End#######################
223 ############### documentationOf START #######################
224 $xml->open_customTag('documentationOf');
226 $xml->open_customTag('serviceEvent', array('classCode'=>'PCPR'));
228 $timeArr = array('low'=>date('Ymdhis', strtotime($from_date)), 'high'=>date('Ymdhis', strtotime($to_date)));
229 $xml->add_entryEffectTime($timeArr);
231 $xml->open_customTag('performer', array('typeCode'=>'PRF'));
233 $timeArr = array('low'=>date('Ymdhis', strtotime($from_date)), 'high'=>date('Ymdhis', strtotime($to_date)));
234 $xml->add_entryTime($timeArr);
236 $xml->open_customTag('assignedEntity');
238 $npi_provider = empty($userRow['npi']) ? "FakeNPI" :$userRow['npi'] ;
239 $xml->self_customTag('id', array('root' => '2.16.840.1.113883.4.6', 'extension' =>$npi_provider));
241 if ($userRow['phone'] != "") {
242 $xml->self_customTag('telecom', array('value' => $userRow['phone'], 'use'=>'WP'));
243 } else {
244 $xml->self_customTag('telecom', array("nullFlavor" => "UNK"));
247 $xml->open_customTag('assignedPerson');
249 //Provider Name
250 $userNameArr = array('fname' =>$userRow['fname'], 'lname'=>$userRow['lname']);
251 $xml->add_providerName($userNameArr);
253 //assignedPerson Close
254 $xml->close_customTag();
256 $xml->open_customTag('representedOrganization');
258 $tin_provider = $userRow['federaltaxid'];
259 if ($tin_provider != "") {
260 $xml->self_customTag('id', array('root' => '2.16.840.1.113883.4.2', 'extension' =>$tin_provider));
263 $xml->add_facilName($facility_name);
265 $xml->add_facilAddress($facilResRow);
267 //representedOrganization Close
268 $xml->close_customTag();
270 //assignedEntity Close
271 $xml->close_customTag();
273 //performer Close
274 $xml->close_customTag();
276 //serviceEvent Close
277 $xml->close_customTag();
279 //documentationOf Close
280 $xml->close_customTag();
281 ############### documentationOf END #######################
282 ####################### HEADER ELEMENTS END #########################################
285 //Component Function
286 function getComponentQRDA1($xml, $patient_id, $rule_id)
288 //Component Open
289 $xml->open_mainComponent();
291 //structuredBody Open
292 $xml->open_structuredBody();
294 //Measure Section
295 getMeasureSection($xml, $rule_id);
297 //Reporting Parameters
298 getReportingParam($xml);
300 //Patient Data
301 getQRDACat1PatientData($xml, $patient_id);
303 //structuredBody Close
304 $xml->close_structuredBody();
306 //Component Close
307 $xml->close_mainComponent();
310 //Patient Data
311 function getQRDACat1PatientData($xml, $patient_id)
313 $xml->open_loopComponent();
314 $xml->open_section();
316 $tempID = '2.16.840.1.113883.10.20.17.2.4';
317 $xml->self_templateid($tempID);
319 $tempID = '2.16.840.1.113883.10.20.24.2.1';
320 $xml->self_templateid($tempID);
322 $arr = array('code'=>'55188-7', 'codeSystem'=>'2.16.840.1.113883.6.1');
323 $xml->self_codeCustom($arr);
325 $title = "Patient Data";
326 $xml->add_title($title);
328 $xml->element('text', "Patient Data");
330 //Insurance(Payer) Info
331 payerQRDA($xml, $patient_id);
333 //Patient History Info
334 patCharactersticQRDA($xml, $patient_id);
336 //Encounter Section
337 getAllPatientEncounters($xml, $patient_id);
339 //Physical Exams(vitals)
340 getAllPhysicalExams($xml, $patient_id);
342 //Diagnosis (Medical Problems)
343 getAllMedicalProbs($xml, $patient_id);
345 //Ordered Medications
346 getAllOrderMedications($xml, $patient_id);
348 // Active Medications
349 getAllActiveMedications($xml, $patient_id);
351 //Immunization
352 getAllImmunization($xml, $patient_id);
354 //Procedures
355 getAllProcedures($xml, $patient_id);
357 //Lab Tests
358 getAllLabTests($xml, $patient_id);
360 //Interventions
361 getAllInterventionProcedures($xml, $patient_id);
363 //Risk Category Assessment
364 getAllRiskCatAssessment($xml, $patient_id);
366 $xml->close_section();
367 $xml->close_loopComponent();
370 //Immunization
371 function getAllImmunization($xml, $patient_id)
373 global $from_date, $to_date;
374 $medArr = allImmuPat($patient_id, $from_date, $to_date);
376 foreach ($medArr as $medRow) {
377 $vset = sqlStatement("select * from valueset where code =? and code_type = 'cvx' and nqf_code =?", array($medRow['cvx_code'], $xml->nqf_code));
378 foreach ($vset as $v) {
379 if (!empty($v['valueset'])) {
380 //Entry open
381 $xml->open_entry();
383 //act open
384 $xml->open_customTag('act', array('classCode'=>'ACT', 'moodCode'=>'EVN'));
386 $tempID = "2.16.840.1.113883.10.20.24.3.42";
387 $xml->self_templateid($tempID);
389 $refID = getUuid();
390 $xml->self_customId($refID);
392 $arr = array('code'=>'416118004', 'codeSystemName'=>'SNOMED CT', 'codeSystem'=>'2.16.840.1.113883.6.96', 'displayName' => 'Administration');
393 $xml->self_codeCustom($arr);
395 if ($medRow['status'] == "" || $medRow['status'] == "not_completed") {
396 $statusChk = "active";
397 } else {
398 $statusChk = "completed";
401 $arr = array('code'=>"completed");
402 $xml->self_customTag('statusCode', $arr);
404 $timeArr = array('low'=>date('Ymdhis', strtotime($medRow['administered_date'])), 'high'=>date('Ymdhis', strtotime($medRow['administered_date'])));
405 $xml->add_entryEffectTimeQRDAMed($timeArr);
407 $xml->open_customTag('entryRelationship', array('typeCode'=>'COMP'));
409 //substanceAdministration Open
410 $xml->open_customTag('substanceAdministration', array('classCode'=>'SBADM', 'moodCode'=>'EVN'));
412 $tempID = "2.16.840.1.113883.10.20.22.4.16";
413 $xml->self_templateid($tempID);
415 //$tempID = "2.16.840.1.113883.10.20.24.3.41";
416 //$xml->self_templateid($tempID);
418 $refID = getUuid();
419 $xml->self_customId($refID);
421 $arr = array('code'=>$statusChk);
422 $xml->self_customTag('statusCode', $arr);
424 $timeArr = array('low'=>date('Ymdhis', strtotime($medRow['administered_date'])), 'high'=>date('Ymdhis', strtotime($medRow['administered_date'])));
425 $xml->add_entryEffectTimeQRDAMed($timeArr);
427 //consumable open
428 $xml->open_customTag('consumable');
430 //manufacturedProduct Open
431 $xml->open_customTag('manufacturedProduct', array('classCode'=>'MANU'));
433 $tempID = "2.16.840.1.113883.10.20.22.4.23";
434 $xml->self_templateid($tempID);
436 $actId = getUuid();
437 $xml->self_customId($actId);
439 //manufacturedMaterial open
440 $xml->open_customTag('manufacturedMaterial');
442 $arr = array('code'=>$v['code'], 'codeSystem'=>$v['code_system'],'sdtc:valueSet' => $v['valueset']);
443 $xml->self_codeCustom($arr);
445 //manufacturerOrganization open
446 /*$xml->open_customTag('manufacturerOrganization');
448 $xml->element('name', 'Medication, Administered Vaccine');
450 //manufacturerOrganization Close
451 $xml->close_customTag();*/
453 //manufacturedMaterial Close
454 $xml->close_customTag();
456 //manufacturedProduct Close
457 $xml->close_customTag();
459 //consumable Close
460 $xml->close_customTag();
462 //substanceAdministration Close
463 $xml->close_customTag();
465 //entryRelationship Close
466 $xml->close_customTag();
468 //act Close
469 $xml->close_customTag();
471 //Entry close
472 $xml->close_entry();
478 function getAllPhysicalExams($xml, $patient_id)
480 global $encCheckUniqId, $from_date, $to_date;
482 $vitArr = allVitalsPat($patient_id, $from_date, $to_date);
483 $measures = array('bps' => array('name' => 'Blood Pressure Systolic','category' => 'Blood Pressure','unit' => 'mmHg','code' => '8480-6'),
484 'bpd' => array('name' => 'Blood Pressure Diastolic','category'=> 'Blood Pressure','unit' => 'mmHg','code' => '8462-4'),
485 'bmi' => array('name' => 'Body Mass Index','category' => 'Body Mass Index', 'unit' => 'kg/m2','code' => '39156-5'));
487 foreach ($vitArr as $vitRow) {
488 //Entry open
489 foreach ($measures as $measure_key => $measure) {
490 $vset = sqlQuery("select * from valueset where code = ? and nqf_code = ?", array($measure['code'],$xml->nqf_code));
491 if (!empty($vset['valueset'])) {
492 $xml->open_entry();
494 //observation Open
495 $xml->open_customTag('observation', array('classCode'=>'OBS', 'moodCode'=>'EVN'));
497 $tempID = "2.16.840.1.113883.10.20.22.4.2";
498 $xml->self_templateid($tempID);
500 $tempID = "2.16.840.1.113883.10.20.24.3.57";
501 $xml->self_templateid($tempID);
503 //$refID = getUuid();
504 $refID = $encCheckUniqId[$vitRow['encounter']];
505 $xml->self_customId($refID);
507 $arr = array('code'=>$measure['code'], 'codeSystem'=>$vset['code_system'],'sdtc:valueSet' => $vset['valueset']);
509 //code Open
510 $xml->open_customTag('code', $arr);
511 $xml->element('originalText', "Physical Exam, Finding: ".$measure['measure']);
512 //code Close
513 $xml->close_customTag();
515 $xml->element('text', "Physical Exam, Finding: ".$measure['category']);
517 $arr = array('code'=>'completed');
518 $xml->self_customTag('statusCode', $arr);
520 $timeArr = array('low'=>date('Ymdhis', strtotime($vitRow['date'])), 'high'=>date('Ymdhis', strtotime($vitRow['date'])));
521 $xml->add_entryEffectTimeQRDA($timeArr);
523 $xml->self_customTag('value', array('xsi:type'=>'PQ', 'value'=>$vitRow[$measure_key], 'unit' => $measure['unit']));
525 //observation Close
526 $xml->close_customTag();
528 //Entry close
529 $xml->close_entry();
535 function getAllRiskCatAssessment($xml, $patient_id)
537 global $encCheckUniqId, $from_date, $to_date;
538 $procArr = allProcPat("risk_category", $patient_id, $from_date, $to_date);
539 foreach ($procArr as $procRow) {
540 $vset = sqlQuery("select * from valueset where code = ? and nqf_code = ?", array($procRow['procedure_code'],$xml->nqf_code));
541 if (!empty($vset['valueset'])) {
542 //Entry open
543 $xml->open_entry();
545 //observation Open
546 $xml->open_customTag('observation', array('classCode'=>'OBS', 'moodCode'=>'EVN'));
548 $tempID = "2.16.840.1.113883.10.20.22.4.69";
549 $xml->self_templateid($tempID);
551 $tempID = "2.16.840.1.113883.10.20.24.3.69";
552 $xml->self_templateid($tempID);
554 //$refID = getUuid();
555 $refID = $encCheckUniqId[$procRow['encounter']];
556 $xml->self_customId($refID);
558 $arr = array('code'=>$vset['code'], 'codeSystem'=>$vset['code_system'],'sdtc:valueSet' => $vset['valueset']);
559 //code Open
560 $xml->open_customTag('code', $arr);
561 $xml->element('originalText', $procRow['procedure_name']);
562 //code Close
563 $xml->close_customTag();
565 $xml->element('text', $procRow['procedure_name']);
567 $arr = array('code'=>'completed');
568 $xml->self_customTag('statusCode', $arr);
570 $timeArr = array('low'=>date('Ymdhis', strtotime($procRow['date_ordered'])), 'high'=>date('Ymdhis', strtotime($procRow['date_ordered'])));
571 $xml->add_entryEffectTimeQRDA($timeArr);
573 $xml->self_customTag('value', array('xsi:type'=>'CD', 'nullFlavor'=>'UNK'));
575 //observation Close
576 $xml->close_customTag();
578 //Entry close
579 $xml->close_entry();
584 function getAllProcedures($xml, $patient_id)
586 global $encCheckUniqId, $from_date, $to_date;
587 $procArr = allProcPat("Procedure", $patient_id, $from_date, $to_date);
588 foreach ($procArr as $procRow) {
589 $vset = sqlQuery("select * from valueset where code = ? and nqf_code = ? ", array($procRow['procedure_code'],$xml->nqf_code));
590 if (!empty($vset['valueset'])) {
591 //Entry open
592 $xml->open_entry();
594 //procedure Open
595 $xml->open_customTag('procedure', array('classCode'=>'PROC', 'moodCode'=>'EVN'));
597 $tempID = "2.16.840.1.113883.10.20.24.3.64";
598 $xml->self_templateid($tempID);
600 $tempID = "2.16.840.1.113883.10.20.22.4.14";
601 $xml->self_templateid($tempID);
603 $tempID = "2.16.840.1.113883.10.20.24.3.38";
604 $xml->self_templateid($tempID);
606 $tempID = "2.16.840.1.113883.10.20.24.3.40";
607 $xml->self_templateid($tempID);
609 //$refID = getUuid();
610 $refID = $encCheckUniqId[$procRow['encounter']];
611 $xml->self_customId($refID);
614 $arr = array('code'=>$procRow['procedure_code'], 'codeSystem'=> $vset['code_system'],'sdtc:valueSet' => $vset['valueset']);
615 //code Open
616 $xml->open_customTag('code', $arr);
617 $xml->element('originalText', $procRow['procedure_name']);
618 //code Close
619 $xml->close_customTag();
621 $xml->element('text', $procRow['procedure_name']);
623 $arr = array('code'=>'completed');
624 $xml->self_customTag('statusCode', $arr);
626 $timeArr = array('low'=>date('Ymdhis', strtotime($procRow['date_ordered'])), 'high'=>date('Ymdhis', strtotime($procRow['date_ordered'])));
627 $xml->add_entryEffectTimeQRDA($timeArr);
629 //procedure Close
630 $xml->close_customTag();
632 //Entry close
633 $xml->close_entry();
638 function getAllLabTests($xml, $patient_id)
640 global $encCheckUniqId, $from_date, $to_date;
641 $procArr = allProcPat("laboratory_test", $patient_id, $from_date, $to_date);
642 foreach ($procArr as $procRow) {
643 $vset = sqlQuery("select * from valueset where code = ? and nqf_code = ? ", array($procRow['procedure_code'],$xml->nqf_code));
644 if (!empty($vset['valueset'])) {
645 //Entry open
646 $xml->open_entry();
648 //procedure Open
649 $xml->open_customTag('procedure', array('classCode'=>'PROC', 'moodCode'=>'EVN'));
651 $tempID = "2.16.840.1.113883.10.20.24.3.38";
652 $xml->self_templateid($tempID);
654 //$refID = getUuid();
655 $refID = $encCheckUniqId[$procRow['encounter']];
656 $xml->self_customId($refID);
659 $arr = array('code'=>$procRow['procedure_code'], 'codeSystem'=> $vset['code_system'],'sdtc:valueSet' => $vset['valueset']);
660 //code Open
661 $xml->open_customTag('code', $arr);
662 $xml->element('originalText', $procRow['procedure_name']);
663 //code Close
664 $xml->close_customTag();
666 $xml->element('text', $procRow['procedure_name']);
668 $arr = array('code'=>'completed');
669 $xml->self_customTag('statusCode', $arr);
671 $timeArr = array('low'=>date('Ymdhis', strtotime($procRow['date_ordered'])), 'high'=>date('Ymdhis', strtotime($procRow['date_ordered'])));
672 $xml->add_entryEffectTimeQRDA($timeArr);
674 //procedure Close
675 $xml->close_customTag();
677 //Entry close
678 $xml->close_entry();
684 function getAllInterventionProcedures($xml, $patient_id)
686 global $encCheckUniqId, $from_date, $to_date;
687 $procArr = allProcPat("intervention", $patient_id, $from_date, $to_date);
688 foreach ($procArr as $procRow) {
689 $vset = sqlQuery("select * from valueset where code = ? and nqf_code = ? ", array($procRow['procedure_code'],$xml->nqf_code));
690 if (!empty($vset['valueset'])) {
691 //Entry open
692 $xml->open_entry();
694 //act Open
695 $xml->open_customTag('act', array('classCode'=>'ACT', 'moodCode'=>'EVN'));
697 $tempID = "2.16.840.1.113883.10.20.22.4.12";
698 $xml->self_templateid($tempID);
700 $tempID = "2.16.840.1.113883.10.20.24.3.32";
701 $xml->self_templateid($tempID);
703 //$refID = getUuid();
704 $refID = $encCheckUniqId[$procRow['encounter']];
705 $xml->self_customId($refID);
708 $arr = array('code'=>$procRow['procedure_code'], 'codeSystem'=> $vset['code_system'],'sdtc:valueSet' => $vset['valueset']);
709 //code Open
710 $xml->open_customTag('code', $arr);
711 $xml->element('originalText', $procRow['procedure_name']);
712 //code Close
713 $xml->close_customTag();
715 $xml->element('text', $procRow['procedure_name']);
717 $arr = array('code'=>'completed');
718 $xml->self_customTag('statusCode', $arr);
720 $timeArr = array('low'=>date('Ymdhis', strtotime($procRow['date_ordered'])), 'high'=>date('Ymdhis', strtotime($procRow['date_ordered'])));
721 $xml->add_entryEffectTimeQRDA($timeArr);
723 //act Close
724 $xml->close_customTag();
726 //Entry close
727 $xml->close_entry();
732 function getAllOrderMedications($xml, $patient_id)
734 global $from_date, $to_date;
735 $medArr = allOrderMedsPat($patient_id, $from_date, $to_date);
737 foreach ($medArr as $medRow) {
738 $vset = sqlQuery("select * from valueset where code = ? and nqf_code = ? ", array($medRow['rxnorm_drugcode'],$xml->nqf_code));
739 if (!empty($vset['valueset'])) {
740 //Entry open
741 $xml->open_entry();
743 //substanceAdministration Open
744 $xml->open_customTag('substanceAdministration', array('classCode'=>'SBADM', 'moodCode'=>'RQO'));
746 $tempID = "2.16.840.1.113883.10.20.22.4.42";
747 $xml->self_templateid($tempID);
749 $tempID = "2.16.840.1.113883.10.20.24.3.47";
750 $xml->self_templateid($tempID);
752 $refID = getUuid();
753 $xml->self_customId($refID);
756 $arr = array('code'=>'new');
757 $xml->self_customTag('statusCode', $arr);
759 $timeArr = array('low'=>date('Ymdhis', strtotime($medRow['start_date'])), 'high'=>date('Ymdhis', strtotime($medRow['end_date'])));
760 $xml->add_entryEffectTimeQRDAMed($timeArr);
762 /*if($medRow['enddate'] == ""){
763 if($medRow['drug_interval'] != "" && $medRow['drug_interval'] != "0")
764 $xml->emptyelement('repeatNumber', array('value'=>$medRow['drug_interval']));
766 if($medRow['quantity'] != "")
767 $xml->emptyelement('doseQuantity', array('value'=>$medRow['quantity']));
769 if($medRow['units'] != "" && $medRow['size_type'] != "")
770 $xml->emptyelement('rateQuantity', array('units'=>$medRow['size_type'], 'value'=>$medRow['units']));
773 //consumable open
774 $xml->open_customTag('consumable');
776 //manufacturedProduct Open
777 $xml->open_customTag('manufacturedProduct', array('classCode'=>'MANU'));
779 $tempID = "2.16.840.1.113883.10.20.22.4.23";
780 $xml->self_templateid($tempID);
782 $actId = getUuid();
783 $xml->self_customId($actId);
785 //manufacturedMaterial open
786 $xml->open_customTag('manufacturedMaterial');
788 $arr = array('code'=>$vset['code'], 'codeSystem'=>$vset['code_system'],'sdtc:valueSet' => $vset['valueset']);
789 $xml->self_codeCustom($arr);
791 //manufacturerOrganization open
792 /*$xml->open_customTag('manufacturerOrganization');
794 $xml->element('name', 'Medication Factory Inc.');
796 //manufacturerOrganization Close
797 $xml->close_customTag();*/
799 //manufacturedMaterial Close
800 $xml->close_customTag();
802 //manufacturedProduct Close
803 $xml->close_customTag();
805 //consumable Close
806 $xml->close_customTag();
808 //substanceAdministration Close
809 $xml->close_customTag();
811 //Entry close
812 $xml->close_entry();
817 function getAllActiveMedications($xml, $patient_id)
819 global $from_date, $to_date;
820 $medArr = allActiveMedsPat($patient_id, $from_date, $to_date);
822 foreach ($medArr as $medRow) {
823 $vset = sqlQuery("select * from valueset where code = ? and nqf_code = ? ", array($medRow['rxnorm_drugcode'],$xml->nqf_code));
824 if (!empty($vset['valueset'])) {
825 //Entry open
826 $xml->open_entry();
828 //substanceAdministration Open
829 $xml->open_customTag('substanceAdministration', array('classCode'=>'SBADM', 'moodCode'=>'EVN'));
831 $tempID = "2.16.840.1.113883.10.20.22.4.16";
832 $xml->self_templateid($tempID);
834 $tempID = "2.16.840.1.113883.10.20.24.3.41";
835 $xml->self_templateid($tempID);
837 $refID = getUuid();
838 $xml->self_customId($refID);
841 $arr = array('code'=>'active');
842 $xml->self_customTag('statusCode', $arr);
844 $timeArr = array('low'=>date('Ymdhis', strtotime($medRow['start_date'])), 'high'=>date('Ymdhis', strtotime($medRow['end_date'])));
845 $xml->add_entryEffectTimeQRDAMed($timeArr);
847 /*if($medRow['enddate'] == ""){
848 if($medRow['drug_interval'] != "" && $medRow['drug_interval'] != "0")
849 $xml->emptyelement('repeatNumber', array('value'=>$medRow['drug_interval']));
851 if($medRow['quantity'] != "")
852 $xml->emptyelement('doseQuantity', array('value'=>$medRow['quantity']));
854 if($medRow['units'] != "" && $medRow['size_type'] != "")
855 $xml->emptyelement('rateQuantity', array('units'=>$medRow['size_type'], 'value'=>$medRow['units']));
858 //consumable open
859 $xml->open_customTag('consumable');
861 //manufacturedProduct Open
862 $xml->open_customTag('manufacturedProduct', array('classCode'=>'MANU'));
864 $tempID = "2.16.840.1.113883.10.20.22.4.23";
865 $xml->self_templateid($tempID);
867 $actId = getUuid();
868 $xml->self_customId($actId);
870 //manufacturedMaterial open
871 $xml->open_customTag('manufacturedMaterial');
873 $arr = array('code'=>$vset['code'], 'codeSystem'=>$vset['code_system'],'sdtc:valueSet' => $vset['valueset']);
874 $xml->self_codeCustom($arr);
876 //manufacturerOrganization open
877 /*$xml->open_customTag('manufacturerOrganization');
879 $xml->element('name', 'Medication Factory Inc.');
881 //manufacturerOrganization Close
882 $xml->close_customTag();*/
884 //manufacturedMaterial Close
885 $xml->close_customTag();
887 //manufacturedProduct Close
888 $xml->close_customTag();
890 //consumable Close
891 $xml->close_customTag();
893 //substanceAdministration Close
894 $xml->close_customTag();
896 //Entry close
897 $xml->close_entry();
902 //Medical problems
903 function getAllMedicalProbs($xml, $patient_id)
905 global $from_date, $to_date;
906 $diagArr = allListsPat('medical_problem', $patient_id, $from_date, $to_date);
908 foreach ($diagArr as $diagRow) {
909 $diagExpArr = explode(";", $diagRow['diagnosis']);
910 /*foreach($diagExpArr as $diagExpVal){
911 $diagDisp = explode(":", $diagExpVal);
912 if($diagDisp[0] == "ICD9" || $diagDisp[0] == "ICD10") continue;
913 $diagDispCode = $diagDisp[1];
916 $diagDisp = explode(":", $diagExpArr[0]);
917 $diagDispCode = str_replace(".", "", $diagDisp[1]);
919 $vset = sqlQuery("select * from valueset where code = ? and nqf_code = ?", array($diagDispCode,$xml->nqf_code));
920 if (!empty($vset['valueset'])) {
921 //Entry open
922 $xml->open_entry();
924 //observation Open
925 $xml->open_customTag('observation', array('classCode'=>'OBS', 'moodCode'=>'EVN'));
927 $tempID = "2.16.840.1.113883.10.20.22.4.4";
928 $xml->self_templateid($tempID);
930 $tempID = "2.16.840.1.113883.10.20.24.3.11";
931 $xml->self_templateid($tempID);
933 $refID = getUuid();
934 $xml->self_customId($refID);
936 $arr = array('code'=>'282291009', 'codeSystemName'=>'SNOMED-CT', 'codeSystem'=>'2.16.840.1.113883.6.96', 'displayName' => 'diagnosis');
937 $xml->self_codeCustom($arr);
939 $xml->textDispContent($diagRow['title']);
941 $activeChk = "active";
942 $endate = $diagRow['begdate'];
943 if ($diagRow['enddate']!= "") {
944 $activeChk = "completed";
945 $endate = $diagRow['enddate'];
948 //$arr = array('code'=>$activeChk);
949 $arr = array('code'=> "completed");
950 $xml->self_customTag('statusCode', $arr);
952 $timeArr = array('low'=>date('Ymdhis', strtotime($diagRow['begdate'])), 'high'=>date('Ymdhis', strtotime($endate)));
953 $xml->add_entryEffectTime($timeArr);
956 $xml->self_customTag('value', array('xsi:type'=>'CD', 'code'=>$diagDispCode, 'codeSystem'=>'2.16.840.1.113883.6.96', 'sdtc:valueSet' => $vset['valueset']));
958 //entryRelationship Open
959 $xml->open_customTag('entryRelationship', array('typeCode'=>'REFR'));
961 //observation Open
962 $xml->open_customTag('observation', array('classCode'=>'OBS', 'moodCode'=>'EVN'));
964 $tempID = "2.16.840.1.113883.10.20.22.4.6";
965 $xml->self_templateid($tempID);
967 $tempID = "2.16.840.1.113883.10.20.24.3.94";
968 $xml->self_templateid($tempID);
970 $refID = getUuid();
971 $xml->self_customId($refID);
973 $arr = array('code'=>'33999-4', 'codeSystem'=>'2.16.840.1.113883.6.1', 'codeSystemName' => 'LOINC', 'displayName' => 'status');
974 $xml->self_codeCustom($arr);
976 //$arr = array('code'=>$activeChk);
977 $arr = array('code'=> "completed");
978 $xml->self_customTag('statusCode', $arr);
980 $xml->self_customTag('value', array('xsi:type'=>'CD', 'code'=>'55561003', 'displayName' => 'active', 'codeSystem' => '2.16.840.1.113883.6.96', 'codeSystemName' => 'SNOMED CT'));
982 //observation Close
983 $xml->close_customTag();
985 //entryRelationship Close
986 $xml->close_customTag();
988 //observation Close
989 $xml->close_customTag();
991 //Entry close
992 $xml->close_entry();
997 //Encounters function
998 function getAllPatientEncounters($xml, $patient_id)
1000 global $encCheckUniqId, $from_date, $to_date,$EncounterCptCodes;
1001 $encArr = allEncPat($patient_id, $from_date, $to_date);
1003 foreach ($encArr as $encRow) {
1004 $encRow['encounter'];
1005 $cpt_code = $EncounterCptCodes[str_replace(' ', '_', strtolower($encRow['pc_catname']))];
1006 $cpt_code = empty($cpt_code) ? '99201' : $cpt_code;
1007 $vset = sqlStatement("select * from valueset where code = ? and nqf_code = ?", array('99201',$xml->nqf_code));
1008 foreach ($vset as $v) {
1009 //Entry open
1010 $xml->open_entry();
1012 //Encounter Open
1013 $xml->open_customTag('encounter', array('classCode'=>'ENC', 'moodCode'=>'EVN'));
1015 $tempID = "2.16.840.1.113883.10.20.22.4.49";
1016 $xml->self_templateid($tempID);
1018 $tempID = "2.16.840.1.113883.10.20.24.3.23";
1019 $xml->self_templateid($tempID);
1021 $refID = getUuid();
1022 $xml->self_customId($refID);
1023 $encCheckUniqId[$encRow['encounter']] = $refID;
1026 $arr = array('code'=>$cpt_code, 'codeSystem'=>$v['code_system'],'sdtc:valueSet' => $v['valueset']);
1027 $xml->self_codeCustom($arr);
1029 $arr = array('code'=>'completed');
1030 $xml->self_customTag('statusCode', $arr);
1032 $timeArr = array('low'=>date('Ymdhis', strtotime($encRow['date'])), 'high'=>date('Ymdhis', strtotime($encRow['date'])));
1033 $xml->add_entryEffectTime($timeArr);
1035 //Encounter Close
1036 $xml->close_customTag();
1038 //Entry close
1039 $xml->close_entry();
1043 $encArr = allProcPat("enc_checkup_procedure", $patient_id, $from_date, $to_date);
1044 foreach ($encArr as $encRow) {
1045 $encRow['encounter'];
1046 $vset = sqlStatement("select * from valueset where code = ? and nqf_code = ?", array($encRow['procedure_code'],$xml->nqf_code));
1047 foreach ($vset as $v) {
1048 //Entry open
1049 $xml->open_entry();
1051 //Encounter Open
1052 $xml->open_customTag('encounter', array('classCode'=>'ENC', 'moodCode'=>'EVN'));
1054 $tempID = "2.16.840.1.113883.10.20.22.4.49";
1055 $xml->self_templateid($tempID);
1057 $tempID = "2.16.840.1.113883.10.20.24.3.23";
1058 $xml->self_templateid($tempID);
1060 $refID = getUuid();
1061 $xml->self_customId($refID);
1062 $encCheckUniqId[$encRow['encounter']] = $refID;
1065 $arr = array('code'=>$v['code'], 'codeSystem'=>$v['code_system'],'sdtc:valueSet' => $v['valueset']);
1066 $xml->self_codeCustom($arr);
1068 $arr = array('code'=>'completed');
1069 $xml->self_customTag('statusCode', $arr);
1071 $timeArr = array('low'=>date('Ymdhis', strtotime($encRow['date'])), 'high'=>date('Ymdhis', strtotime($encRow['date'])));
1072 $xml->add_entryEffectTime($timeArr);
1074 //Encounter Close
1075 $xml->close_customTag();
1077 //Entry close
1078 $xml->close_entry();
1083 //Patient Data Sub Function for Payer Data
1084 function payerQRDA($xml, $patient_id)
1086 global $mainQrdaPayerCodeSendArr, $from_date, $to_date;
1088 //Insurance getting
1089 $payer = payerPatient($patient_id);
1091 //Entry open
1092 $xml->open_entry();
1094 //observation Open
1095 $xml->open_customTag('observation', array('classCode'=>'OBS', 'moodCode'=>'EVN'));
1097 $tempID = "2.16.840.1.113883.10.20.24.3.55";
1098 $xml->self_templateid($tempID);
1100 $actId = getUuid();
1101 $xml->self_customId($actId);
1103 $arr = array('code'=>'48768-6', 'displayName'=>'Payment source', 'codeSystem'=>'2.16.840.1.113883.6.1', 'codeSystemName'=>'LOINC');
1104 $xml->self_codeCustom($arr);
1106 $arr = array('code'=>'completed');
1107 $xml->self_customTag('statusCode', $arr);
1109 $timeArr = array('low'=>date('Ymdhis', strtotime($from_date)), 'high'=>date('Ymdhis', strtotime($to_date)));
1110 $xml->add_entryEffectTime($timeArr);
1112 $xml->self_customTag('value', array('xsi:type'=>'CD', 'code'=>$mainQrdaPayerCodeSendArr[$payer], 'codeSystem'=>'2.16.840.1.113883.3.221.5' , 'codeSystemName'=>'Source of Payment Typology', 'displayName'=>$payer));
1114 //observation Close
1115 $xml->close_customTag();
1117 //Entry close
1118 $xml->close_entry();
1121 //Reporting Parameters function
1122 function getReportingParam($xml)
1124 global $from_date, $to_date;
1126 $xml->open_loopComponent();
1127 $xml->open_section();
1129 $tempID = '2.16.840.1.113883.10.20.17.2.1';
1130 $xml->self_templateid($tempID);
1132 $arr = array('code'=>'55187-9', 'codeSystem'=>'2.16.840.1.113883.6.1');
1133 $xml->self_codeCustom($arr);
1135 $title = "Reporting Parameters";
1136 $xml->add_title($title);
1138 //Main Reporting Parameters display
1139 $xml->open_text();
1140 $xml->open_list();
1141 $item_title = "Reporting period: ".date('d M Y', strtotime($from_date))." - ".date('d M Y', strtotime($to_date));
1142 $xml->add_item($item_title);
1143 $xml->close_list();
1144 $xml->close_text();
1146 $typeCode = 'DRIV';
1147 $xml->open_entry($typeCode);
1148 $arr = array('classCode'=>'ACT', 'moodCode'=>'EVN');
1149 $xml->open_act($arr);
1151 $tempID = '2.16.840.1.113883.10.20.17.3.8';
1152 $xml->self_templateid($tempID);
1154 $arr = array('extension'=>getUuid());
1155 $xml->self_customTag('id', $arr);
1157 $arr = array('code'=>'252116004', 'codeSystem'=>'2.16.840.1.113883.6.96', 'displayName'=>'Observation Parameters');
1158 $xml->self_codeCustom($arr);
1160 $timeArr = array('low'=>date('Ymdhis', strtotime($from_date)), 'high'=>date('Ymdhis', strtotime($to_date)));
1161 $xml->add_entryEffectTime($timeArr);
1163 $xml->close_act();
1164 $xml->close_entry();
1166 $xml->close_section();
1167 $xml->close_loopComponent();
1170 //Measure Section
1171 function getMeasureSection($xml, $rule_id)
1173 global $preDefinedUniqIDRules;
1175 $xml->open_loopComponent();
1176 $xml->open_section();
1178 $tempID = '2.16.840.1.113883.10.20.24.2.2';
1179 $xml->self_templateid($tempID);
1181 $tempID = '2.16.840.1.113883.10.20.24.2.3';
1182 $xml->self_templateid($tempID);
1184 $arr = array('code'=>'55186-1', 'codeSystem'=>'2.16.840.1.113883.6.1');
1185 $xml->self_codeCustom($arr);
1187 $title = "Measure Section";
1188 $xml->add_title($title);
1190 //Main Measure display
1191 $xml->open_text();
1193 //Table Start
1194 $xml->open_customTag('table', $tabArr);
1195 //THEAD Start
1196 $xml->open_customTag('thead');
1197 //TR Start
1198 $xml->open_customTag('tr');
1200 $xml->add_trElementsTitles();
1202 //TR close
1203 $xml->close_customTag();
1205 //THEAD close
1206 $xml->close_customTag();
1207 //TBOBY START
1208 $xml->open_customTag('tbody');
1209 $xml->open_customTag('tr');
1211 if (!empty($rule_id)) {
1212 $tdTitle = "NQF:". $rule_id;
1215 $tdVersionNeutral = getUuid();
1216 $tdVersionSpecific = $preDefinedUniqIDRules[$rule_id];
1217 $uniqIdArr[] = $tdVersionSpecific;
1219 $dataArr = array(0=>$tdTitle, 1=>$tdVersionNeutral, 2=>$tdVersionSpecific);
1220 $xml->add_trElementsValues($dataArr);
1222 //TR close
1223 $xml->close_customTag();
1224 //TBODY close
1225 $xml->close_customTag();
1226 //Table Close
1227 $xml->close_customTag();
1229 $xml->close_text();
1231 //Entry open
1232 $xml->open_entry();
1234 //Organizer Start
1235 $arr = array('classCode'=>'CLUSTER', 'moodCode'=>'EVN');
1236 $xml->open_customTag('organizer', $arr);
1238 $tempID = "2.16.840.1.113883.10.20.24.3.98";
1239 $xml->self_templateid($tempID);
1241 $tempID = "2.16.840.1.113883.10.20.24.3.97";
1242 $xml->self_templateid($tempID);
1244 $arr = array('extension'=>$uniqIdArr[0]);
1245 $xml->self_customTag('id', $arr);
1247 $arr = array('code'=>'completed');
1248 $xml->self_customTag('statusCode', $arr);
1250 //reference Start
1251 $arr = array('typeCode'=>'REFR');
1252 $xml->open_customTag('reference', $arr);
1254 //externalDocument Start
1255 $arr = array('classCode'=>'DOC', 'moodCode'=>'EVN');
1256 $xml->open_customTag('externalDocument', $arr);
1258 $exDocID = $uniqIdArr[0];
1259 $xml->self_customTag('id', array('root' => '2.16.840.1.113883.4.738', 'extension' =>$exDocID));
1261 $xml->element('text', "NQF# ".$rule_id);
1263 $setidVal =getUuid();
1264 $xml->self_setid($setidVal);
1266 $arr = array('value'=>'3');
1267 $xml->self_customTag('versionNumber', $arr);
1269 //externalDocument Close
1270 $xml->close_customTag();
1272 //reference Close
1273 $xml->close_customTag();
1275 //Organizer Close
1276 $xml->close_customTag();
1278 //Entry Close
1279 $xml->close_entry();
1281 $xml->close_section();
1282 $xml->close_loopComponent();
1285 //Download QRDA Category I
1286 function downloadQRDACat1($xml, $patient_id, $rule_id)
1288 //Patient Info
1289 if ($patient_id != "") {
1290 $patientRow = getPatData($patient_id);
1291 $patFname = $patientRow['fname'];
1292 $patLname = $patientRow['lname'];
1295 //QRDA File Download Folder in site/cqm_qrda folder
1296 $qrda_fname = $patFname."_".$patLname."_NQF_".$rule_id.".xml";
1297 global $qrda_file_path;
1298 if (!file_exists($qrda_file_path)) {
1299 mkdir($qrda_file_path, 0777, true);
1302 $qrda_file_name = $qrda_file_path.$qrda_fname;
1303 $fileQRDAOPen = fopen($qrda_file_name, "w");
1304 fwrite($fileQRDAOPen, trim($xml->getXml()));
1305 fclose($fileQRDAOPen);
1306 return $qrda_fname;
1309 //Patient History Info
1310 function patCharactersticQRDA($xml, $patient_id)
1313 //Patient History
1314 $patHist = patientQRDAHistory($patient_id);
1316 $tobaccoArr = explode('|', $patHist['tobacco']);
1318 $query = sqlQuery("select codes from list_options where list_id ='smoking_status' and option_id = ?", array($tobaccoArr[3]));
1319 $tobacco = explode(':', $query['codes']);
1320 $tobacco_code = $tobacco[1];
1321 $vset = sqlQuery("select * from valueset where code = ? and nqf_code = ?", array($tobacco_code,$xml->nqf_code));
1322 if (!empty($vset['valueset'])) {
1323 //Entry open
1324 $xml->open_entry();
1326 //observation Open
1327 $xml->open_customTag('observation', array('classCode'=>'OBS', 'moodCode'=>'EVN'));
1329 $tempID = "2.16.840.1.113883.10.20.22.4.85";
1330 $xml->self_templateid($tempID);
1332 $actId = getUuid();
1333 $xml->self_customId($actId);
1335 $arr = array('code'=>'ASSERTION', 'displayName'=>'Assertion', 'codeSystem'=>'2.16.840.1.113883.5.4', 'codeSystemName'=>'ActCode');
1336 $xml->self_codeCustom($arr);
1338 $arr = array('code'=>'completed');
1339 $xml->self_customTag('statusCode', $arr);
1341 $timeArr = array('low'=>date('Ymdhis', strtotime($patHist['date'])), 'high'=>date('Ymdhis', strtotime($patHist['date'])));
1342 $xml->add_entryEffectTime($timeArr);
1344 $xml->self_customTag('value', array('xsi:type'=>'CD', 'code'=> $vset['code'], 'codeSystem'=>$vset['code_system'],'sdtc:valueSet' => $vset['valueset']));
1346 //observation Close
1347 $xml->close_customTag();
1349 //Entry close
1350 $xml->close_entry();