chore: add php 8.4-dev to ci and insane dev environment (#7121)
[openemr.git] / custom / qrda_category1_functions.php
blobfc466eeffdb2c660c286a3321122ffed95c59c58
1 <?php
3 /**
5 * QRDA Functions
7 * Copyright (C) 2015 Ensoftek, Inc
9 * LICENSE: This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://opensource.org/licenses/gpl-license.php>;.
20 * @package OpenEMR
21 * @author Ensoftek
22 * @link http://www.open-emr.org
24 // This program exports report to QRDA Category I 2014 XML format.
27 function mainQrdaCatOneGenerate($xml, $patient_id, $rule_id, $provider_id)
29 //Open Main Clinical Document
30 $xml->open_clinicaldocument();
32 //Header Function
33 getHeaderQRDA1($xml, $patient_id, $provider_id);
35 //Component Function
36 getComponentQRDA1($xml, $patient_id, $rule_id);
38 //Close Main Clinical Document
39 $xml->close_clinicaldocument();
41 //Downloaded XML
42 $xmlDynFileName = downloadQRDACat1($xml, $patient_id, $rule_id);
44 return $xmlDynFileName;
47 //Main Header Function
48 function getHeaderQRDA1($xml, $patient_id, $provider_id)
50 global $mainQrdaRaceCodeArr, $mainEthiCodeArr, $from_date, $to_date;
52 //Patient Info
53 if ($patient_id != "") {
54 $patientRow = getPatData($patient_id);
57 //User Info
58 $userRow = getUsrDataCheck($provider_id);
59 $facility_name = $userRow['facility'];
60 $facility_id = $userRow['facility_id'];
62 //Facility Info
63 if ($facility_id != "") {
64 $facilResRow = getFacilDataChk($facility_id);
67 ####################### HEADER ELEMENTS START ##########################################
69 $xml->self_realmcode();
71 $xml->self_typeid();
73 $tempId = '2.16.840.1.113883.10.20.22.1.1';
74 $xml->self_templateid($tempId);
76 $tempId = '2.16.840.1.113883.10.20.24.1.1';
77 $xml->self_templateid($tempId);
79 $tempId = '2.16.840.1.113883.10.20.24.1.2';
80 $xml->self_templateid($tempId);
82 $tempId = '2.16.840.1.113883.10.20.24.1.3';
83 $xml->self_templateid($tempId);
85 $xml->unique_id = getUuid();
86 $xml->self_id();
88 $arr = array('code' => '55182-0', 'displayName' => 'Quality Measure Report', 'codeSystem' => '2.16.840.1.113883.6.1', 'codeSystemName' => 'LOINC');
89 $xml->self_codeCustom($arr);
91 //Main Title Display to XML
92 $main_title = "QRDA Category-I Report";
93 $xml->add_title($main_title);
95 //Effective date and time
96 $eff_datetime = date('Ymdhis', strtotime($from_date));
97 $xml->self_efftime($eff_datetime);
99 $xml->self_confidentcode();
101 //Language
102 $xml->self_lang();
104 //Record Target Elements
105 $xml->open_recordTarget();
107 //patientRole Open
108 $xml->open_customTag('patientRole');
110 $xml->self_customTag('id', array('root' => '2.16.840.1.113883.4.572', 'extension' => '112233'));
112 $xml->add_patientAddress($patientRow);
114 if ($patientRow['phone_home'] != "") {
115 $xml->self_customTag('telecom', array('value' => $patientRow['phone_home'], 'use' => 'HP'));
116 } else {
117 $xml->self_customTag('telecom', array('nullFlavor' => "UNK"));
120 $xml->open_customTag('patient');
122 $patNameArr = array('fname' => $patientRow['fname'], 'lname' => $patientRow['lname']);
123 $xml->add_patName($patNameArr);
125 if ($patientRow['sex'] == "Male") {
126 $gender = "M";
127 } elseif ($patientRow['sex'] == "Female") {
128 $gender = "F";
131 $xml->self_customTag('administrativeGenderCode', array('codeSystem' => '2.16.840.1.113883.18.2', 'code' => $gender));
133 $xml->self_customTag('birthTime', array('value' => date('Ymd', strtotime($patientRow['DOB']))));
135 if ($mainQrdaRaceCodeArr[$patientRow['race']] == "") {
136 $mainQrdaRaceCodeArr[$patientRow['race']] = "2131-1";
139 $xml->self_customTag('raceCode', array('codeSystem' => '2.16.840.1.113883.6.238', 'code' => $mainQrdaRaceCodeArr[$patientRow['race']]));
140 $xml->self_customTag('ethnicGroupCode', array('codeSystem' => '2.16.840.1.113883.6.238', 'code' => $mainEthiCodeArr[$patientRow['ethnicity']]));
142 //patient Close
143 $xml->close_customTag();
145 //patientRole Close
146 $xml->close_customTag();
148 $xml->close_recordTarget();
150 ############### Author Info Start#######################
151 $xml->open_author();
153 //Author time
154 $auth_dtime = date('Ymdhis');
155 $xml->self_authorTime($auth_dtime);
157 //Assigned Author
158 $xml->open_assignAuthor();
159 $npi_provider = empty($userRow['npi']) ? "FakeNPI" : $userRow['npi'];
160 $xml->self_customTag('id', array('root' => '2.16.840.1.113883.4.6', 'extension' => $npi_provider));
161 $xml->add_patientAddress($facilResRow);
162 if (!empty($userRow['phone'])) {
163 $xml->self_customTag('telecom', array('value' => $userRow['phone'], 'use' => 'WP'));
164 } else {
165 $xml->self_customTag('telecom', array("nullFlavor" => "UNK"));
171 //assignedAuthoringDevice Start
172 $xml->open_customTag('assignedAuthoringDevice');
173 $xml->element('manufacturerModelName', 'DrCloudEMR');
174 $xml->element('softwareName', 'DrCloudEMR');
175 //assignedAuthoringDevice Close
176 $xml->close_customTag();
178 $xml->close_assignAuthor();
179 ################## Author Info End ##########################
181 $xml->close_author();
182 ############### Author Info End#######################
184 ############### Custodian Info Start #######################
185 $xml->open_custodian();
186 $xml->open_assgnCustodian();
187 $xml->add_represtCustodianOrginisation($facilResRow);
188 $xml->close_assgnCustodian();
189 $xml->close_custodian();
190 ############### Custodian Info End #######################
192 ############### Legal Authenticator Start#######################
193 $xml->open_legalAuthenticator();
194 $auth_dtime = date('Ymdhis');
195 $xml->self_authorTime($auth_dtime);
196 $xml->self_legalSignCode();
198 $xml->open_assignedEntity();
199 $assignedEntityId = getUuid();
200 $xml->self_customId($assignedEntityId);
201 $xml->add_facilAddress($facilResRow);
202 if (!empty($facilResRow['phone'])) {
203 $xml->self_customTag('telecom', array('value' => $facilResRow['phone'], 'use' => 'WP'));
204 } else {
205 $xml->self_customTag('telecom', array("nullFlavor" => "UNK"));
208 $xml->open_customTag('assignedPerson');
210 //Provider Name
211 $userNameArr = array('fname' => $userRow['fname'], 'lname' => $userRow['lname']);
212 $xml->add_providerName($userNameArr);
214 //assignedPerson Close
215 $xml->close_customTag();
217 //Represent Origination Name
218 $xml->add_authReprestOrginisation($facilResRow);
219 $xml->close_assignedEntity();
221 $xml->close_legalAuthenticator();
222 ############### Legal Authenticator End#######################
224 ############### documentationOf START #######################
225 $xml->open_customTag('documentationOf');
227 $xml->open_customTag('serviceEvent', array('classCode' => 'PCPR'));
229 $timeArr = array('low' => date('Ymdhis', strtotime($from_date)), 'high' => date('Ymdhis', strtotime($to_date)));
230 $xml->add_entryEffectTime($timeArr);
232 $xml->open_customTag('performer', array('typeCode' => 'PRF'));
234 $timeArr = array('low' => date('Ymdhis', strtotime($from_date)), 'high' => date('Ymdhis', strtotime($to_date)));
235 $xml->add_entryTime($timeArr);
237 $xml->open_customTag('assignedEntity');
239 $npi_provider = empty($userRow['npi']) ? "FakeNPI" : $userRow['npi'] ;
240 $xml->self_customTag('id', array('root' => '2.16.840.1.113883.4.6', 'extension' => $npi_provider));
242 if ($userRow['phone'] != "") {
243 $xml->self_customTag('telecom', array('value' => $userRow['phone'], 'use' => 'WP'));
244 } else {
245 $xml->self_customTag('telecom', array("nullFlavor" => "UNK"));
248 $xml->open_customTag('assignedPerson');
250 //Provider Name
251 $userNameArr = array('fname' => $userRow['fname'], 'lname' => $userRow['lname']);
252 $xml->add_providerName($userNameArr);
254 //assignedPerson Close
255 $xml->close_customTag();
257 $xml->open_customTag('representedOrganization');
259 $tin_provider = $userRow['federaltaxid'];
260 if ($tin_provider != "") {
261 $xml->self_customTag('id', array('root' => '2.16.840.1.113883.4.2', 'extension' => $tin_provider));
264 $xml->add_facilName($facility_name);
266 $xml->add_facilAddress($facilResRow);
268 //representedOrganization Close
269 $xml->close_customTag();
271 //assignedEntity Close
272 $xml->close_customTag();
274 //performer Close
275 $xml->close_customTag();
277 //serviceEvent Close
278 $xml->close_customTag();
280 //documentationOf Close
281 $xml->close_customTag();
282 ############### documentationOf END #######################
283 ####################### HEADER ELEMENTS END #########################################
286 //Component Function
287 function getComponentQRDA1($xml, $patient_id, $rule_id)
289 //Component Open
290 $xml->open_mainComponent();
292 //structuredBody Open
293 $xml->open_structuredBody();
295 //Measure Section
296 getMeasureSection($xml, $rule_id);
298 //Reporting Parameters
299 getReportingParam($xml);
301 //Patient Data
302 getQRDACat1PatientData($xml, $patient_id);
304 //structuredBody Close
305 $xml->close_structuredBody();
307 //Component Close
308 $xml->close_mainComponent();
311 //Patient Data
312 function getQRDACat1PatientData($xml, $patient_id)
314 $xml->open_loopComponent();
315 $xml->open_section();
317 $tempID = '2.16.840.1.113883.10.20.17.2.4';
318 $xml->self_templateid($tempID);
320 $tempID = '2.16.840.1.113883.10.20.24.2.1';
321 $xml->self_templateid($tempID);
323 $arr = array('code' => '55188-7', 'codeSystem' => '2.16.840.1.113883.6.1');
324 $xml->self_codeCustom($arr);
326 $title = "Patient Data";
327 $xml->add_title($title);
329 $xml->element('text', "Patient Data");
331 //Insurance(Payer) Info
332 payerQRDA($xml, $patient_id);
334 //Patient History Info
335 patCharactersticQRDA($xml, $patient_id);
337 //Encounter Section
338 getAllPatientEncounters($xml, $patient_id);
340 //Physical Exams(vitals)
341 getAllPhysicalExams($xml, $patient_id);
343 //Diagnosis (Medical Problems)
344 getAllMedicalProbs($xml, $patient_id);
346 //Ordered Medications
347 getAllOrderMedications($xml, $patient_id);
349 // Active Medications
350 getAllActiveMedications($xml, $patient_id);
352 //Immunization
353 getAllImmunization($xml, $patient_id);
355 //Procedures
356 getAllProcedures($xml, $patient_id);
358 //Lab Tests
359 getAllLabTests($xml, $patient_id);
361 //Interventions
362 getAllInterventionProcedures($xml, $patient_id);
364 //Risk Category Assessment
365 getAllRiskCatAssessment($xml, $patient_id);
367 $xml->close_section();
368 $xml->close_loopComponent();
371 //Immunization
372 function getAllImmunization($xml, $patient_id)
374 global $from_date, $to_date;
375 $medArr = allImmuPat($patient_id, $from_date, $to_date);
377 foreach ($medArr as $medRow) {
378 $vset = sqlStatement("select * from valueset where code =? and code_type = 'cvx' and nqf_code =?", array($medRow['cvx_code'], $xml->nqf_code));
379 foreach ($vset as $v) {
380 if (!empty($v['valueset'])) {
381 //Entry open
382 $xml->open_entry();
384 //act open
385 $xml->open_customTag('act', array('classCode' => 'ACT', 'moodCode' => 'EVN'));
387 $tempID = "2.16.840.1.113883.10.20.24.3.42";
388 $xml->self_templateid($tempID);
390 $refID = getUuid();
391 $xml->self_customId($refID);
393 $arr = array('code' => '416118004', 'codeSystemName' => 'SNOMED CT', 'codeSystem' => '2.16.840.1.113883.6.96', 'displayName' => 'Administration');
394 $xml->self_codeCustom($arr);
396 if ($medRow['status'] == "" || $medRow['status'] == "not_completed") {
397 $statusChk = "active";
398 } else {
399 $statusChk = "completed";
402 $arr = array('code' => "completed");
403 $xml->self_customTag('statusCode', $arr);
405 $timeArr = array('low' => date('Ymdhis', strtotime($medRow['administered_date'])), 'high' => date('Ymdhis', strtotime($medRow['administered_date'])));
406 $xml->add_entryEffectTimeQRDAMed($timeArr);
408 $xml->open_customTag('entryRelationship', array('typeCode' => 'COMP'));
410 //substanceAdministration Open
411 $xml->open_customTag('substanceAdministration', array('classCode' => 'SBADM', 'moodCode' => 'EVN'));
413 $tempID = "2.16.840.1.113883.10.20.22.4.16";
414 $xml->self_templateid($tempID);
416 //$tempID = "2.16.840.1.113883.10.20.24.3.41";
417 //$xml->self_templateid($tempID);
419 $refID = getUuid();
420 $xml->self_customId($refID);
422 $arr = array('code' => $statusChk);
423 $xml->self_customTag('statusCode', $arr);
425 $timeArr = array('low' => date('Ymdhis', strtotime($medRow['administered_date'])), 'high' => date('Ymdhis', strtotime($medRow['administered_date'])));
426 $xml->add_entryEffectTimeQRDAMed($timeArr);
428 //consumable open
429 $xml->open_customTag('consumable');
431 //manufacturedProduct Open
432 $xml->open_customTag('manufacturedProduct', array('classCode' => 'MANU'));
434 $tempID = "2.16.840.1.113883.10.20.22.4.23";
435 $xml->self_templateid($tempID);
437 $actId = getUuid();
438 $xml->self_customId($actId);
440 //manufacturedMaterial open
441 $xml->open_customTag('manufacturedMaterial');
443 $arr = array('code' => $v['code'], 'codeSystem' => $v['code_system'],'sdtc:valueSet' => $v['valueset']);
444 $xml->self_codeCustom($arr);
446 //manufacturerOrganization open
447 /*$xml->open_customTag('manufacturerOrganization');
449 $xml->element('name', 'Medication, Administered Vaccine');
451 //manufacturerOrganization Close
452 $xml->close_customTag();*/
454 //manufacturedMaterial Close
455 $xml->close_customTag();
457 //manufacturedProduct Close
458 $xml->close_customTag();
460 //consumable Close
461 $xml->close_customTag();
463 //substanceAdministration Close
464 $xml->close_customTag();
466 //entryRelationship Close
467 $xml->close_customTag();
469 //act Close
470 $xml->close_customTag();
472 //Entry close
473 $xml->close_entry();
479 function getAllPhysicalExams($xml, $patient_id)
481 global $encCheckUniqId, $from_date, $to_date;
483 $vitArr = allVitalsPat($patient_id, $from_date, $to_date);
484 $measures = array('bps' => array('name' => 'Blood Pressure Systolic','category' => 'Blood Pressure','unit' => 'mmHg','code' => '8480-6'),
485 'bpd' => array('name' => 'Blood Pressure Diastolic','category' => 'Blood Pressure','unit' => 'mmHg','code' => '8462-4'),
486 'bmi' => array('name' => 'Body Mass Index','category' => 'Body Mass Index', 'unit' => 'kg/m2','code' => '39156-5'));
488 foreach ($vitArr as $vitRow) {
489 //Entry open
490 foreach ($measures as $measure_key => $measure) {
491 $vset = sqlQuery("select * from valueset where code = ? and nqf_code = ?", array($measure['code'],$xml->nqf_code));
492 if (!empty($vset['valueset'])) {
493 $xml->open_entry();
495 //observation Open
496 $xml->open_customTag('observation', array('classCode' => 'OBS', 'moodCode' => 'EVN'));
498 $tempID = "2.16.840.1.113883.10.20.22.4.2";
499 $xml->self_templateid($tempID);
501 $tempID = "2.16.840.1.113883.10.20.24.3.57";
502 $xml->self_templateid($tempID);
504 //$refID = getUuid();
505 $refID = $encCheckUniqId[$vitRow['encounter']];
506 $xml->self_customId($refID);
508 $arr = array('code' => $measure['code'], 'codeSystem' => $vset['code_system'],'sdtc:valueSet' => $vset['valueset']);
510 //code Open
511 $xml->open_customTag('code', $arr);
512 $xml->element('originalText', "Physical Exam, Finding: " . $measure['measure']);
513 //code Close
514 $xml->close_customTag();
516 $xml->element('text', "Physical Exam, Finding: " . $measure['category']);
518 $arr = array('code' => 'completed');
519 $xml->self_customTag('statusCode', $arr);
521 $timeArr = array('low' => date('Ymdhis', strtotime($vitRow['date'])), 'high' => date('Ymdhis', strtotime($vitRow['date'])));
522 $xml->add_entryEffectTimeQRDA($timeArr);
524 $xml->self_customTag('value', array('xsi:type' => 'PQ', 'value' => $vitRow[$measure_key], 'unit' => $measure['unit']));
526 //observation Close
527 $xml->close_customTag();
529 //Entry close
530 $xml->close_entry();
536 function getAllRiskCatAssessment($xml, $patient_id)
538 global $encCheckUniqId, $from_date, $to_date;
539 $procArr = allProcPat("risk_category", $patient_id, $from_date, $to_date);
540 foreach ($procArr as $procRow) {
541 $vset = sqlQuery("select * from valueset where code = ? and nqf_code = ?", array($procRow['procedure_code'],$xml->nqf_code));
542 if (!empty($vset['valueset'])) {
543 //Entry open
544 $xml->open_entry();
546 //observation Open
547 $xml->open_customTag('observation', array('classCode' => 'OBS', 'moodCode' => 'EVN'));
549 $tempID = "2.16.840.1.113883.10.20.22.4.69";
550 $xml->self_templateid($tempID);
552 $tempID = "2.16.840.1.113883.10.20.24.3.69";
553 $xml->self_templateid($tempID);
555 //$refID = getUuid();
556 $refID = $encCheckUniqId[$procRow['encounter']];
557 $xml->self_customId($refID);
559 $arr = array('code' => $vset['code'], 'codeSystem' => $vset['code_system'],'sdtc:valueSet' => $vset['valueset']);
560 //code Open
561 $xml->open_customTag('code', $arr);
562 $xml->element('originalText', $procRow['procedure_name']);
563 //code Close
564 $xml->close_customTag();
566 $xml->element('text', $procRow['procedure_name']);
568 $arr = array('code' => 'completed');
569 $xml->self_customTag('statusCode', $arr);
571 $timeArr = array('low' => date('Ymdhis', strtotime($procRow['date_ordered'])), 'high' => date('Ymdhis', strtotime($procRow['date_ordered'])));
572 $xml->add_entryEffectTimeQRDA($timeArr);
574 $xml->self_customTag('value', array('xsi:type' => 'CD', 'nullFlavor' => 'UNK'));
576 //observation Close
577 $xml->close_customTag();
579 //Entry close
580 $xml->close_entry();
585 function getAllProcedures($xml, $patient_id)
587 global $encCheckUniqId, $from_date, $to_date;
588 $procArr = allProcPat("Procedure", $patient_id, $from_date, $to_date);
589 foreach ($procArr as $procRow) {
590 $vset = sqlQuery("select * from valueset where code = ? and nqf_code = ? ", array($procRow['procedure_code'],$xml->nqf_code));
591 if (!empty($vset['valueset'])) {
592 //Entry open
593 $xml->open_entry();
595 //procedure Open
596 $xml->open_customTag('procedure', array('classCode' => 'PROC', 'moodCode' => 'EVN'));
598 $tempID = "2.16.840.1.113883.10.20.24.3.64";
599 $xml->self_templateid($tempID);
601 $tempID = "2.16.840.1.113883.10.20.22.4.14";
602 $xml->self_templateid($tempID);
604 $tempID = "2.16.840.1.113883.10.20.24.3.38";
605 $xml->self_templateid($tempID);
607 $tempID = "2.16.840.1.113883.10.20.24.3.40";
608 $xml->self_templateid($tempID);
610 //$refID = getUuid();
611 $refID = $encCheckUniqId[$procRow['encounter']];
612 $xml->self_customId($refID);
615 $arr = array('code' => $procRow['procedure_code'], 'codeSystem' => $vset['code_system'],'sdtc:valueSet' => $vset['valueset']);
616 //code Open
617 $xml->open_customTag('code', $arr);
618 $xml->element('originalText', $procRow['procedure_name']);
619 //code Close
620 $xml->close_customTag();
622 $xml->element('text', $procRow['procedure_name']);
624 $arr = array('code' => 'completed');
625 $xml->self_customTag('statusCode', $arr);
627 $timeArr = array('low' => date('Ymdhis', strtotime($procRow['date_ordered'])), 'high' => date('Ymdhis', strtotime($procRow['date_ordered'])));
628 $xml->add_entryEffectTimeQRDA($timeArr);
630 //procedure Close
631 $xml->close_customTag();
633 //Entry close
634 $xml->close_entry();
639 function getAllLabTests($xml, $patient_id)
641 global $encCheckUniqId, $from_date, $to_date;
642 $procArr = allProcPat("laboratory_test", $patient_id, $from_date, $to_date);
643 foreach ($procArr as $procRow) {
644 $vset = sqlQuery("select * from valueset where code = ? and nqf_code = ? ", array($procRow['procedure_code'],$xml->nqf_code));
645 if (!empty($vset['valueset'])) {
646 //Entry open
647 $xml->open_entry();
649 //procedure Open
650 $xml->open_customTag('procedure', array('classCode' => 'PROC', 'moodCode' => 'EVN'));
652 $tempID = "2.16.840.1.113883.10.20.24.3.38";
653 $xml->self_templateid($tempID);
655 //$refID = getUuid();
656 $refID = $encCheckUniqId[$procRow['encounter']];
657 $xml->self_customId($refID);
660 $arr = array('code' => $procRow['procedure_code'], 'codeSystem' => $vset['code_system'],'sdtc:valueSet' => $vset['valueset']);
661 //code Open
662 $xml->open_customTag('code', $arr);
663 $xml->element('originalText', $procRow['procedure_name']);
664 //code Close
665 $xml->close_customTag();
667 $xml->element('text', $procRow['procedure_name']);
669 $arr = array('code' => 'completed');
670 $xml->self_customTag('statusCode', $arr);
672 $timeArr = array('low' => date('Ymdhis', strtotime($procRow['date_ordered'])), 'high' => date('Ymdhis', strtotime($procRow['date_ordered'])));
673 $xml->add_entryEffectTimeQRDA($timeArr);
675 //procedure Close
676 $xml->close_customTag();
678 //Entry close
679 $xml->close_entry();
685 function getAllInterventionProcedures($xml, $patient_id)
687 global $encCheckUniqId, $from_date, $to_date;
688 $procArr = allProcPat("intervention", $patient_id, $from_date, $to_date);
689 foreach ($procArr as $procRow) {
690 $vset = sqlQuery("select * from valueset where code = ? and nqf_code = ? ", array($procRow['procedure_code'],$xml->nqf_code));
691 if (!empty($vset['valueset'])) {
692 //Entry open
693 $xml->open_entry();
695 //act Open
696 $xml->open_customTag('act', array('classCode' => 'ACT', 'moodCode' => 'EVN'));
698 $tempID = "2.16.840.1.113883.10.20.22.4.12";
699 $xml->self_templateid($tempID);
701 $tempID = "2.16.840.1.113883.10.20.24.3.32";
702 $xml->self_templateid($tempID);
704 //$refID = getUuid();
705 $refID = $encCheckUniqId[$procRow['encounter']];
706 $xml->self_customId($refID);
709 $arr = array('code' => $procRow['procedure_code'], 'codeSystem' => $vset['code_system'],'sdtc:valueSet' => $vset['valueset']);
710 //code Open
711 $xml->open_customTag('code', $arr);
712 $xml->element('originalText', $procRow['procedure_name']);
713 //code Close
714 $xml->close_customTag();
716 $xml->element('text', $procRow['procedure_name']);
718 $arr = array('code' => 'completed');
719 $xml->self_customTag('statusCode', $arr);
721 $timeArr = array('low' => date('Ymdhis', strtotime($procRow['date_ordered'])), 'high' => date('Ymdhis', strtotime($procRow['date_ordered'])));
722 $xml->add_entryEffectTimeQRDA($timeArr);
724 //act Close
725 $xml->close_customTag();
727 //Entry close
728 $xml->close_entry();
733 function getAllOrderMedications($xml, $patient_id)
735 global $from_date, $to_date;
736 $medArr = allOrderMedsPat($patient_id, $from_date, $to_date);
738 foreach ($medArr as $medRow) {
739 $vset = sqlQuery("select * from valueset where code = ? and nqf_code = ? ", array($medRow['rxnorm_drugcode'],$xml->nqf_code));
740 if (!empty($vset['valueset'])) {
741 //Entry open
742 $xml->open_entry();
744 //substanceAdministration Open
745 $xml->open_customTag('substanceAdministration', array('classCode' => 'SBADM', 'moodCode' => 'RQO'));
747 $tempID = "2.16.840.1.113883.10.20.22.4.42";
748 $xml->self_templateid($tempID);
750 $tempID = "2.16.840.1.113883.10.20.24.3.47";
751 $xml->self_templateid($tempID);
753 $refID = getUuid();
754 $xml->self_customId($refID);
757 $arr = array('code' => 'new');
758 $xml->self_customTag('statusCode', $arr);
760 $timeArr = array('low' => date('Ymdhis', strtotime($medRow['start_date'])), 'high' => date('Ymdhis', strtotime($medRow['end_date'])));
761 $xml->add_entryEffectTimeQRDAMed($timeArr);
763 /*if($medRow['enddate'] == ""){
764 if($medRow['drug_interval'] != "" && $medRow['drug_interval'] != "0")
765 $xml->emptyelement('repeatNumber', array('value'=>$medRow['drug_interval']));
767 if($medRow['quantity'] != "")
768 $xml->emptyelement('doseQuantity', array('value'=>$medRow['quantity']));
770 if($medRow['units'] != "" && $medRow['size_type'] != "")
771 $xml->emptyelement('rateQuantity', array('units'=>$medRow['size_type'], 'value'=>$medRow['units']));
774 //consumable open
775 $xml->open_customTag('consumable');
777 //manufacturedProduct Open
778 $xml->open_customTag('manufacturedProduct', array('classCode' => 'MANU'));
780 $tempID = "2.16.840.1.113883.10.20.22.4.23";
781 $xml->self_templateid($tempID);
783 $actId = getUuid();
784 $xml->self_customId($actId);
786 //manufacturedMaterial open
787 $xml->open_customTag('manufacturedMaterial');
789 $arr = array('code' => $vset['code'], 'codeSystem' => $vset['code_system'],'sdtc:valueSet' => $vset['valueset']);
790 $xml->self_codeCustom($arr);
792 //manufacturerOrganization open
793 /*$xml->open_customTag('manufacturerOrganization');
795 $xml->element('name', 'Medication Factory Inc.');
797 //manufacturerOrganization Close
798 $xml->close_customTag();*/
800 //manufacturedMaterial Close
801 $xml->close_customTag();
803 //manufacturedProduct Close
804 $xml->close_customTag();
806 //consumable Close
807 $xml->close_customTag();
809 //substanceAdministration Close
810 $xml->close_customTag();
812 //Entry close
813 $xml->close_entry();
818 function getAllActiveMedications($xml, $patient_id)
820 global $from_date, $to_date;
821 $medArr = allActiveMedsPat($patient_id, $from_date, $to_date);
823 foreach ($medArr as $medRow) {
824 $vset = sqlQuery("select * from valueset where code = ? and nqf_code = ? ", array($medRow['rxnorm_drugcode'],$xml->nqf_code));
825 if (!empty($vset['valueset'])) {
826 //Entry open
827 $xml->open_entry();
829 //substanceAdministration Open
830 $xml->open_customTag('substanceAdministration', array('classCode' => 'SBADM', 'moodCode' => 'EVN'));
832 $tempID = "2.16.840.1.113883.10.20.22.4.16";
833 $xml->self_templateid($tempID);
835 $tempID = "2.16.840.1.113883.10.20.24.3.41";
836 $xml->self_templateid($tempID);
838 $refID = getUuid();
839 $xml->self_customId($refID);
842 $arr = array('code' => 'active');
843 $xml->self_customTag('statusCode', $arr);
845 $timeArr = array('low' => date('Ymdhis', strtotime($medRow['start_date'])), 'high' => date('Ymdhis', strtotime($medRow['end_date'])));
846 $xml->add_entryEffectTimeQRDAMed($timeArr);
848 /*if($medRow['enddate'] == ""){
849 if($medRow['drug_interval'] != "" && $medRow['drug_interval'] != "0")
850 $xml->emptyelement('repeatNumber', array('value'=>$medRow['drug_interval']));
852 if($medRow['quantity'] != "")
853 $xml->emptyelement('doseQuantity', array('value'=>$medRow['quantity']));
855 if($medRow['units'] != "" && $medRow['size_type'] != "")
856 $xml->emptyelement('rateQuantity', array('units'=>$medRow['size_type'], 'value'=>$medRow['units']));
859 //consumable open
860 $xml->open_customTag('consumable');
862 //manufacturedProduct Open
863 $xml->open_customTag('manufacturedProduct', array('classCode' => 'MANU'));
865 $tempID = "2.16.840.1.113883.10.20.22.4.23";
866 $xml->self_templateid($tempID);
868 $actId = getUuid();
869 $xml->self_customId($actId);
871 //manufacturedMaterial open
872 $xml->open_customTag('manufacturedMaterial');
874 $arr = array('code' => $vset['code'], 'codeSystem' => $vset['code_system'],'sdtc:valueSet' => $vset['valueset']);
875 $xml->self_codeCustom($arr);
877 //manufacturerOrganization open
878 /*$xml->open_customTag('manufacturerOrganization');
880 $xml->element('name', 'Medication Factory Inc.');
882 //manufacturerOrganization Close
883 $xml->close_customTag();*/
885 //manufacturedMaterial Close
886 $xml->close_customTag();
888 //manufacturedProduct Close
889 $xml->close_customTag();
891 //consumable Close
892 $xml->close_customTag();
894 //substanceAdministration Close
895 $xml->close_customTag();
897 //Entry close
898 $xml->close_entry();
903 //Medical problems
904 function getAllMedicalProbs($xml, $patient_id)
906 global $from_date, $to_date;
907 $diagArr = allListsPat('medical_problem', $patient_id, $from_date, $to_date);
909 foreach ($diagArr as $diagRow) {
910 $diagExpArr = explode(";", $diagRow['diagnosis']);
911 /*foreach($diagExpArr as $diagExpVal){
912 $diagDisp = explode(":", $diagExpVal);
913 if($diagDisp[0] == "ICD9" || $diagDisp[0] == "ICD10") continue;
914 $diagDispCode = $diagDisp[1];
917 $diagDisp = explode(":", $diagExpArr[0]);
918 $diagDispCode = str_replace(".", "", $diagDisp[1]);
920 $vset = sqlQuery("select * from valueset where code = ? and nqf_code = ?", array($diagDispCode,$xml->nqf_code));
921 if (!empty($vset['valueset'])) {
922 //Entry open
923 $xml->open_entry();
925 //observation Open
926 $xml->open_customTag('observation', array('classCode' => 'OBS', 'moodCode' => 'EVN'));
928 $tempID = "2.16.840.1.113883.10.20.22.4.4";
929 $xml->self_templateid($tempID);
931 $tempID = "2.16.840.1.113883.10.20.24.3.11";
932 $xml->self_templateid($tempID);
934 $refID = getUuid();
935 $xml->self_customId($refID);
937 $arr = array('code' => '282291009', 'codeSystemName' => 'SNOMED-CT', 'codeSystem' => '2.16.840.1.113883.6.96', 'displayName' => 'diagnosis');
938 $xml->self_codeCustom($arr);
940 $xml->textDispContent($diagRow['title']);
942 $activeChk = "active";
943 $endate = $diagRow['begdate'];
944 if ($diagRow['enddate'] != "") {
945 $activeChk = "completed";
946 $endate = $diagRow['enddate'];
949 //$arr = array('code'=>$activeChk);
950 $arr = array('code' => "completed");
951 $xml->self_customTag('statusCode', $arr);
953 $timeArr = array('low' => date('Ymdhis', strtotime($diagRow['begdate'])), 'high' => date('Ymdhis', strtotime($endate)));
954 $xml->add_entryEffectTime($timeArr);
957 $xml->self_customTag('value', array('xsi:type' => 'CD', 'code' => $diagDispCode, 'codeSystem' => '2.16.840.1.113883.6.96', 'sdtc:valueSet' => $vset['valueset']));
959 //entryRelationship Open
960 $xml->open_customTag('entryRelationship', array('typeCode' => 'REFR'));
962 //observation Open
963 $xml->open_customTag('observation', array('classCode' => 'OBS', 'moodCode' => 'EVN'));
965 $tempID = "2.16.840.1.113883.10.20.22.4.6";
966 $xml->self_templateid($tempID);
968 $tempID = "2.16.840.1.113883.10.20.24.3.94";
969 $xml->self_templateid($tempID);
971 $refID = getUuid();
972 $xml->self_customId($refID);
974 $arr = array('code' => '33999-4', 'codeSystem' => '2.16.840.1.113883.6.1', 'codeSystemName' => 'LOINC', 'displayName' => 'status');
975 $xml->self_codeCustom($arr);
977 //$arr = array('code'=>$activeChk);
978 $arr = array('code' => "completed");
979 $xml->self_customTag('statusCode', $arr);
981 $xml->self_customTag('value', array('xsi:type' => 'CD', 'code' => '55561003', 'displayName' => 'active', 'codeSystem' => '2.16.840.1.113883.6.96', 'codeSystemName' => 'SNOMED CT'));
983 //observation Close
984 $xml->close_customTag();
986 //entryRelationship Close
987 $xml->close_customTag();
989 //observation Close
990 $xml->close_customTag();
992 //Entry close
993 $xml->close_entry();
998 //Encounters function
999 function getAllPatientEncounters($xml, $patient_id)
1001 global $encCheckUniqId, $from_date, $to_date,$EncounterCptCodes;
1002 $encArr = allEncPat($patient_id, $from_date, $to_date);
1004 foreach ($encArr as $encRow) {
1005 $encRow['encounter'];
1006 $cpt_code = $EncounterCptCodes[str_replace(' ', '_', strtolower($encRow['pc_catname']))];
1007 $cpt_code = empty($cpt_code) ? '99201' : $cpt_code;
1008 $vset = sqlStatement("select * from valueset where code = ? and nqf_code = ?", array('99201',$xml->nqf_code));
1009 foreach ($vset as $v) {
1010 //Entry open
1011 $xml->open_entry();
1013 //Encounter Open
1014 $xml->open_customTag('encounter', array('classCode' => 'ENC', 'moodCode' => 'EVN'));
1016 $tempID = "2.16.840.1.113883.10.20.22.4.49";
1017 $xml->self_templateid($tempID);
1019 $tempID = "2.16.840.1.113883.10.20.24.3.23";
1020 $xml->self_templateid($tempID);
1022 $refID = getUuid();
1023 $xml->self_customId($refID);
1024 $encCheckUniqId[$encRow['encounter']] = $refID;
1027 $arr = array('code' => $cpt_code, 'codeSystem' => $v['code_system'],'sdtc:valueSet' => $v['valueset']);
1028 $xml->self_codeCustom($arr);
1030 $arr = array('code' => 'completed');
1031 $xml->self_customTag('statusCode', $arr);
1033 $timeArr = array('low' => date('Ymdhis', strtotime($encRow['date'])), 'high' => date('Ymdhis', strtotime($encRow['date'])));
1034 $xml->add_entryEffectTime($timeArr);
1036 //Encounter Close
1037 $xml->close_customTag();
1039 //Entry close
1040 $xml->close_entry();
1044 $encArr = allProcPat("enc_checkup_procedure", $patient_id, $from_date, $to_date);
1045 foreach ($encArr as $encRow) {
1046 $encRow['encounter'];
1047 $vset = sqlStatement("select * from valueset where code = ? and nqf_code = ?", array($encRow['procedure_code'],$xml->nqf_code));
1048 foreach ($vset as $v) {
1049 //Entry open
1050 $xml->open_entry();
1052 //Encounter Open
1053 $xml->open_customTag('encounter', array('classCode' => 'ENC', 'moodCode' => 'EVN'));
1055 $tempID = "2.16.840.1.113883.10.20.22.4.49";
1056 $xml->self_templateid($tempID);
1058 $tempID = "2.16.840.1.113883.10.20.24.3.23";
1059 $xml->self_templateid($tempID);
1061 $refID = getUuid();
1062 $xml->self_customId($refID);
1063 $encCheckUniqId[$encRow['encounter']] = $refID;
1066 $arr = array('code' => $v['code'], 'codeSystem' => $v['code_system'],'sdtc:valueSet' => $v['valueset']);
1067 $xml->self_codeCustom($arr);
1069 $arr = array('code' => 'completed');
1070 $xml->self_customTag('statusCode', $arr);
1072 $timeArr = array('low' => date('Ymdhis', strtotime($encRow['date'])), 'high' => date('Ymdhis', strtotime($encRow['date'])));
1073 $xml->add_entryEffectTime($timeArr);
1075 //Encounter Close
1076 $xml->close_customTag();
1078 //Entry close
1079 $xml->close_entry();
1084 //Patient Data Sub Function for Payer Data
1085 function payerQRDA($xml, $patient_id)
1087 global $mainQrdaPayerCodeSendArr, $from_date, $to_date;
1089 //Insurance getting
1090 $payer = payerPatient($patient_id);
1092 //Entry open
1093 $xml->open_entry();
1095 //observation Open
1096 $xml->open_customTag('observation', array('classCode' => 'OBS', 'moodCode' => 'EVN'));
1098 $tempID = "2.16.840.1.113883.10.20.24.3.55";
1099 $xml->self_templateid($tempID);
1101 $actId = getUuid();
1102 $xml->self_customId($actId);
1104 $arr = array('code' => '48768-6', 'displayName' => 'Payment source', 'codeSystem' => '2.16.840.1.113883.6.1', 'codeSystemName' => 'LOINC');
1105 $xml->self_codeCustom($arr);
1107 $arr = array('code' => 'completed');
1108 $xml->self_customTag('statusCode', $arr);
1110 $timeArr = array('low' => date('Ymdhis', strtotime($from_date)), 'high' => date('Ymdhis', strtotime($to_date)));
1111 $xml->add_entryEffectTime($timeArr);
1113 $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));
1115 //observation Close
1116 $xml->close_customTag();
1118 //Entry close
1119 $xml->close_entry();
1122 //Reporting Parameters function
1123 function getReportingParam($xml)
1125 global $from_date, $to_date;
1127 $xml->open_loopComponent();
1128 $xml->open_section();
1130 $tempID = '2.16.840.1.113883.10.20.17.2.1';
1131 $xml->self_templateid($tempID);
1133 $arr = array('code' => '55187-9', 'codeSystem' => '2.16.840.1.113883.6.1');
1134 $xml->self_codeCustom($arr);
1136 $title = "Reporting Parameters";
1137 $xml->add_title($title);
1139 //Main Reporting Parameters display
1140 $xml->open_text();
1141 $xml->open_list();
1142 $item_title = "Reporting period: " . date('d M Y', strtotime($from_date)) . " - " . date('d M Y', strtotime($to_date));
1143 $xml->add_item($item_title);
1144 $xml->close_list();
1145 $xml->close_text();
1147 $typeCode = 'DRIV';
1148 $xml->open_entry($typeCode);
1149 $arr = array('classCode' => 'ACT', 'moodCode' => 'EVN');
1150 $xml->open_act($arr);
1152 $tempID = '2.16.840.1.113883.10.20.17.3.8';
1153 $xml->self_templateid($tempID);
1155 $arr = array('extension' => getUuid());
1156 $xml->self_customTag('id', $arr);
1158 $arr = array('code' => '252116004', 'codeSystem' => '2.16.840.1.113883.6.96', 'displayName' => 'Observation Parameters');
1159 $xml->self_codeCustom($arr);
1161 $timeArr = array('low' => date('Ymdhis', strtotime($from_date)), 'high' => date('Ymdhis', strtotime($to_date)));
1162 $xml->add_entryEffectTime($timeArr);
1164 $xml->close_act();
1165 $xml->close_entry();
1167 $xml->close_section();
1168 $xml->close_loopComponent();
1171 //Measure Section
1172 function getMeasureSection($xml, $rule_id)
1174 global $preDefinedUniqIDRules;
1176 $xml->open_loopComponent();
1177 $xml->open_section();
1179 $tempID = '2.16.840.1.113883.10.20.24.2.2';
1180 $xml->self_templateid($tempID);
1182 $tempID = '2.16.840.1.113883.10.20.24.2.3';
1183 $xml->self_templateid($tempID);
1185 $arr = array('code' => '55186-1', 'codeSystem' => '2.16.840.1.113883.6.1');
1186 $xml->self_codeCustom($arr);
1188 $title = "Measure Section";
1189 $xml->add_title($title);
1191 //Main Measure display
1192 $xml->open_text();
1194 //Table Start
1195 $xml->open_customTag('table', $tabArr);
1196 //THEAD Start
1197 $xml->open_customTag('thead');
1198 //TR Start
1199 $xml->open_customTag('tr');
1201 $xml->add_trElementsTitles();
1203 //TR close
1204 $xml->close_customTag();
1206 //THEAD close
1207 $xml->close_customTag();
1208 //TBOBY START
1209 $xml->open_customTag('tbody');
1210 $xml->open_customTag('tr');
1212 if (!empty($rule_id)) {
1213 $tdTitle = "NQF:" . $rule_id;
1216 $tdVersionNeutral = getUuid();
1217 $tdVersionSpecific = $preDefinedUniqIDRules[$rule_id];
1218 $uniqIdArr[] = $tdVersionSpecific;
1220 $dataArr = array(0 => $tdTitle, 1 => $tdVersionNeutral, 2 => $tdVersionSpecific);
1221 $xml->add_trElementsValues($dataArr);
1223 //TR close
1224 $xml->close_customTag();
1225 //TBODY close
1226 $xml->close_customTag();
1227 //Table Close
1228 $xml->close_customTag();
1230 $xml->close_text();
1232 //Entry open
1233 $xml->open_entry();
1235 //Organizer Start
1236 $arr = array('classCode' => 'CLUSTER', 'moodCode' => 'EVN');
1237 $xml->open_customTag('organizer', $arr);
1239 $tempID = "2.16.840.1.113883.10.20.24.3.98";
1240 $xml->self_templateid($tempID);
1242 $tempID = "2.16.840.1.113883.10.20.24.3.97";
1243 $xml->self_templateid($tempID);
1245 $arr = array('extension' => $uniqIdArr[0]);
1246 $xml->self_customTag('id', $arr);
1248 $arr = array('code' => 'completed');
1249 $xml->self_customTag('statusCode', $arr);
1251 //reference Start
1252 $arr = array('typeCode' => 'REFR');
1253 $xml->open_customTag('reference', $arr);
1255 //externalDocument Start
1256 $arr = array('classCode' => 'DOC', 'moodCode' => 'EVN');
1257 $xml->open_customTag('externalDocument', $arr);
1259 $exDocID = $uniqIdArr[0];
1260 $xml->self_customTag('id', array('root' => '2.16.840.1.113883.4.738', 'extension' => $exDocID));
1262 $xml->element('text', "NQF# " . $rule_id);
1264 $setidVal = getUuid();
1265 $xml->self_setid($setidVal);
1267 $arr = array('value' => '3');
1268 $xml->self_customTag('versionNumber', $arr);
1270 //externalDocument Close
1271 $xml->close_customTag();
1273 //reference Close
1274 $xml->close_customTag();
1276 //Organizer Close
1277 $xml->close_customTag();
1279 //Entry Close
1280 $xml->close_entry();
1282 $xml->close_section();
1283 $xml->close_loopComponent();
1286 //Download QRDA Category I
1287 function downloadQRDACat1($xml, $patient_id, $rule_id)
1289 //Patient Info
1290 if ($patient_id != "") {
1291 $patientRow = getPatData($patient_id);
1292 $patFname = $patientRow['fname'];
1293 $patLname = $patientRow['lname'];
1296 //QRDA File Download Folder in site/cqm_qrda folder
1297 $qrda_fname = $patFname . "_" . $patLname . "_NQF_" . $rule_id . ".xml";
1298 global $qrda_file_path;
1299 if (!file_exists($qrda_file_path)) {
1300 mkdir($qrda_file_path, 0777, true);
1303 $qrda_file_name = $qrda_file_path . $qrda_fname;
1304 $fileQRDAOPen = fopen($qrda_file_name, "w");
1305 fwrite($fileQRDAOPen, trim($xml->getXml()));
1306 fclose($fileQRDAOPen);
1307 return $qrda_fname;
1310 //Patient History Info
1311 function patCharactersticQRDA($xml, $patient_id)
1314 //Patient History
1315 $patHist = patientQRDAHistory($patient_id);
1317 $tobaccoArr = explode('|', $patHist['tobacco']);
1319 $query = sqlQuery("select codes from list_options where list_id ='smoking_status' and option_id = ?", array($tobaccoArr[3]));
1320 $tobacco = explode(':', $query['codes']);
1321 $tobacco_code = $tobacco[1];
1322 $vset = sqlQuery("select * from valueset where code = ? and nqf_code = ?", array($tobacco_code,$xml->nqf_code));
1323 if (!empty($vset['valueset'])) {
1324 //Entry open
1325 $xml->open_entry();
1327 //observation Open
1328 $xml->open_customTag('observation', array('classCode' => 'OBS', 'moodCode' => 'EVN'));
1330 $tempID = "2.16.840.1.113883.10.20.22.4.85";
1331 $xml->self_templateid($tempID);
1333 $actId = getUuid();
1334 $xml->self_customId($actId);
1336 $arr = array('code' => 'ASSERTION', 'displayName' => 'Assertion', 'codeSystem' => '2.16.840.1.113883.5.4', 'codeSystemName' => 'ActCode');
1337 $xml->self_codeCustom($arr);
1339 $arr = array('code' => 'completed');
1340 $xml->self_customTag('statusCode', $arr);
1342 $timeArr = array('low' => date('Ymdhis', strtotime($patHist['date'])), 'high' => date('Ymdhis', strtotime($patHist['date'])));
1343 $xml->add_entryEffectTime($timeArr);
1345 $xml->self_customTag('value', array('xsi:type' => 'CD', 'code' => $vset['code'], 'codeSystem' => $vset['code_system'],'sdtc:valueSet' => $vset['valueset']));
1347 //observation Close
1348 $xml->close_customTag();
1350 //Entry close
1351 $xml->close_entry();