2 // Copyright (C) 2007, 2008 Rod Roark <rod@sunsetsystems.com>
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (at your option) any later version.
9 /////////////////////////////////////////////////////////////////////
10 // This script imports encounters from a custom XML format. It
11 // implements a form, and the processing of that form.
13 // When initially presented to the user, the form contains just a file
14 // upload field and its associated Browse button, and an OK button.
16 // Selecting a file to upload and clicking OK will upload the file,
17 // and redisplay a superset of the initial form which contains one or
18 // more uploaded encounters. Each encounter uploaded will appear in
19 // its own section of the form, and each such section will display the
20 // imported data for its encounter. Some of the displayed data items
21 // will be editable at this time. In addition some error messages
22 // might appear indicating that some fields must be corrected.
24 // Once the user is satisfied with the contents of the form, clicking
25 // OK again will cause the data items to be recorded into the
26 // appropriate database areas of OpenEMR. In addition if a new file
27 // to upload was also selected, then the form will redisplay as before
28 // but for the new file.
29 /////////////////////////////////////////////////////////////////////
31 include_once("../interface/globals.php");
32 include_once("$srcdir/patient.inc");
33 include_once("$srcdir/forms.inc");
34 include_once("$srcdir/acl.inc");
37 'patient' => array('Patient', array(
38 'insured_id' => array('Patient ID' , '2'),
39 'ssn' => array('SSN' , '2'),
40 'lname' => array('Last Name' , '2'),
41 'mname' => array('Middle Name' , '2'),
42 'fname' => array('First Name' , '2'),
43 'sex' => array('Sex' , '2'),
44 'dob' => array('Birth Date' , '2'),
45 'ethnicity' => array('Ethnicity' , '2'),
46 'street' => array('Street Address', '2'),
47 'street2' => array('Street Address', '2'),
48 'city' => array('City' , '2'),
49 'state' => array('State' , '2'),
50 'zip' => array('Zip Code' , '2'),
51 'phone_home' => array('Home Phone' , '2'),
52 'phone_alternate' => array('Other Phone', '2'),
53 'pcp' => array('Primary Physician', array(
54 'id' => array('Billing ID', '2'),
55 'lname' => array('Last Name' , '2'),
56 'fname' => array('First Name' , '2'),
58 'xcp' => array('Rendering Provider', array(
59 'id' => array('Billing ID', '2'),
60 'lname' => array('Last Name' , '2'),
61 'fname' => array('First Name', '2'),
62 'notes' => array('Notes' , '2'),
64 'familyinformation' => array('Family Information', array(
65 'father' => array('Father' , '2'),
66 'mother' => array('Mother' , '2'),
67 'spouse' => array('Spouse' , '2'),
68 'siblings' => array('Siblings' , '2'),
69 'offspring' => array('Offspring', '2'),
70 )), // end familyinformation
71 'medical' => array('Medical Information', array(
72 'relativesexperience' => array('Relatives Experience', array(
73 'cancer' => array('Cancer' , '2'),
74 'tuberculosis' => array('Tuberculosis' , '2'),
75 'diabetes' => array('Diabetes' , '2'),
76 'highbloodpressure' => array('Hypertension' , '2'),
77 'heartproblems' => array('Heart Problems', '2'),
78 'stroke' => array('Stroke' , '2'),
79 'epilepsy' => array('Epilepsy' , '2'),
80 'mentalillness' => array('Mental Illness', '2'),
81 'suicide' => array('Suicide' , '2'),
83 'lifestyleusage' => array('Lifestyle/Usage', array(
84 'coffee' => array('Coffee' , '2'),
85 'tobacco' => array('Tobacco' , '2'),
86 'alcohol' => array('Alcohol' , '2'),
87 'sleep' => array('Sleep' , '2'),
88 'exercise' => array('Exercise' , '2'),
89 'seatbelt' => array('Seat Belt' , '2'),
90 'counseling' => array('Counseling' , '2'),
91 'hazardactivities' => array('Hazardous Activities', '2'),
93 'medications' => array('Medications', array(
94 'medication*' => array('Medication', array(
95 'name' => array('Name' , '2'),
96 'dosage' => array('Dosage' , '2'),
97 'frequency' => array('Frequency', '2'),
98 'duration' => array('Duration' , '2'),
101 'medicalhistory' => array('Medical History', array(
102 'medicationnotes' => array('Medication Notes', '2'),
103 'allergies' => array('Allergies' , '2'),
104 'history' => array('History' , '2'),
105 'surgicalhistory' => array('Surgical History', '2'),
107 'preventatives' => array('Preventatives', array(
108 'breastexamination' => array('Breast Exam', array(
109 'date' => array('Date' , '2'),
110 'result' => array('Result', '2'),
112 'cardiacecho' => array('Cardiac Echo', array(
113 'date' => array('Date' , '2'),
114 'result' => array('Result', '2'),
116 'ecg' => array('ECG', array(
117 'date' => array('Date' , '2'),
118 'result' => array('Result', '2'),
120 'gyn' => array('Gyn Exam', array(
121 'date' => array('Date' , '2'),
122 'result' => array('Result', '2'),
124 'mammogram' => array('Mammogram', array(
125 'date' => array('Date' , '2'),
126 'result' => array('Result', '2'),
128 'physicalexam' => array('Physical Exam', array(
129 'date' => array('Date' , '2'),
130 'result' => array('Result', '2'),
132 'prostateexam' => array('Prostate Exam', array(
133 'date' => array('Date' , '2'),
134 'result' => array('Result', '2'),
136 'rectalexam' => array('Rectal Exam', array(
137 'date' => array('Date' , '2'),
138 'result' => array('Result', '2'),
140 'sigmoid' => array('Sigmoid', array(
141 'date' => array('Date' , '2'),
142 'result' => array('Result', '2'),
144 'retinal' => array('Retinal Exam', array(
145 'date' => array('Date' , '2'),
146 'result' => array('Result', '2'),
148 'fluvax' => array('Flu Vaccination', array(
149 'date' => array('Date' , '2'),
150 'result' => array('Result', '2'),
152 'pneuvax' => array('Pnuemonia Vaccination', array(
153 'date' => array('Date' , '2'),
154 'result' => array('Result', '2'),
156 'ldl' => array('LDL', array(
157 'date' => array('Date' , '2'),
158 'result' => array('Result', '2'),
160 'hemoglobin' => array('Hemoglobin', array(
161 'date' => array('Date' , '2'),
162 'result' => array('Result', '2'),
164 'psa' => array('PSA', array(
165 'date' => array('Date' , '2'),
166 'result' => array('Result', '2'),
168 'other' => array('Other', array(
169 'name' => array('Name' , '2'),
170 'date' => array('Date' , '2'),
171 'result' => array('Result', '2'),
173 )), // end preventatives
174 'subjective' => array('Subjective', array(
175 'general' => array('General' , '2'),
176 'neurological' => array('Neurological', '2'),
177 'heent' => array('HEENT' , '2'),
178 'respiratory' => array('Respiratory' , '2'),
179 'cardio' => array('Cardio' , '2'),
180 'gastro' => array('Gastro' , '2'),
181 'skin' => array('Skin' , '2'),
182 'extremities' => array('Extremities' , '2'),
183 )), // end subjective
184 'physicalexamsvitals' => array('Physical Exams/Vitals', array(
185 'mentalstatus' => array('Mental Status', '2'),
186 'bps' => array('BPS' , '2'),
187 'bpd' => array('BPD' , '2'),
188 'weight' => array('Weight' , '2'),
189 'height' => array('Height' , '2'),
190 'temperature' => array('Temperature' , '2'),
191 'tempmethods' => array('Temp Method' , '2'),
192 'pulse' => array('Pulse' , '2'),
193 'respiration' => array('Respiration' , '2'),
194 'bmi' => array('BMI' , '2'),
195 'waistcirc' => array('Waist Circ' , '2'),
196 'headcirc' => array('Head Circ' , '2'),
197 'o2' => array('Oxygen' , '2'),
198 )), // end physicalexamsvitals
199 'systems' => array('Systems', array(
200 'assessment' => array('Assessment' , '2'),
201 'treatmentplan' => array('Treatment Plan', '2'),
202 'diagnosis*' => array('Diagnosis', array(
203 'code' => array('Diagnosis Code', '2'),
204 'codestatus' => array('Code Status' , '2'),
205 'codenote' => array('Code Note' , '2'),
208 'billable' => array('Billing', array(
209 'fromdate' => array('From Date', '2'),
210 'thrudate' => array('Thru Date', '2'),
211 'notes' => array('Notes', '2'),
212 'service*' => array('Service', array(
213 'code' => array('Service Code', '2'),
214 'codenote' => array('Code Note' , '2'),
216 'clinic' => array('Clinic', array(
217 'id' => array('Billing ID' , '2'),
218 'name' => array('Name' , '2'),
219 'street' => array('Street Address', '2'),
220 'street2' => array('Street Address', '2'),
221 'city' => array('City' , '2'),
222 'state' => array('State' , '2'),
223 'zip' => array('Zip Code' , '2'),
224 'phone' => array('Phone' , '2'),
231 // This recursively initializes the array that will hold imported data values
234 function init_patient(&$sarr, &$darr) {
235 foreach ($sarr as $key => $value) {
236 if (is_array($value[1])) {
237 // Tags ending in * are those that are repeated. They will be
238 // inserted elsewhere.
239 if (substr($key, -1) == '*') continue;
240 $darr[$key] = array();
241 init_patient($value[1], $darr[$key]);
249 // This recursively writes the tree of HTML data for one patient.
250 // $sarr contains logical keys, verbose names and field types.
251 // $darr contains physical keys and data values.
252 // $probearr maintains the heirarchy of physical key names.
254 function write_html(&$sarr, &$darr) {
255 global $probearr, $ptsequence;
257 // echo '<p>$darr = '; print_r($darr); // debugging
259 foreach ($darr as $dkey => $dvalue) {
260 if (!is_array($dvalue)) {
261 // Write leaf name and value. We are copying our same physical
262 // keys into the HTML field names so that PHP will parse them back
263 // into the same familiar format.
264 echo "<li>" . $sarr[$dkey][0] . ": ";
265 echo "<input type='text' size='80' name='pt$ptsequence";
266 foreach ($probearr as $pvalue) echo "[$pvalue]";
267 echo "[$dkey]' class='indata' value='" . $dvalue . "'></li>\n";
271 foreach ($darr as $dkey => $dvalue) {
272 if (is_array($dvalue)) {
273 $array_depth = array_push($probearr, $dkey);
275 $i = strpos($skey, '*');
277 // If the physical key has an asterisk then the logical key is only
278 // the part up to and including the asterisk.
279 $skey = substr($skey, 0, $i+
1);
281 // Write the verbose name corresponding to this logical key.
282 if ($array_depth > 1) echo "<li>" . $sarr[$skey][0] . "</li>\n";
283 // Recursively process this array's contents.
285 write_html($sarr[$skey][1], $dvalue);
287 array_pop($probearr);
292 // Encode a string from a form field for database writing.
294 function form2db($fldval) {
295 $fldval = trim($fldval);
296 if (!get_magic_quotes_gpc()) $fldval = addslashes($fldval);
300 // Encode sex for OpenEMR compatibility.
302 function sex($insex) {
303 if (!empty($insex)) {
304 $insex = strtoupper(substr($insex, 0, 1));
305 if ($insex == 'M') return 'Male';
306 if ($insex == 'F') return 'Female';
311 // Compute the digit corresponding to a test/exam result.
312 // 0 = unassigned, 1 = normal, 2 = abnormal.
314 function exam_result(&$pta, $key) {
315 if (!empty($pta['medical']['preventatives'][$key])) {
316 if (trim($pta['medical']['preventatives'][$key]['date'])) {
317 $res = strtoupper(trim($pta['medical']['preventatives'][$key]['result']));
318 if (strpos($res, 'ABN' ) !== false) return '2';
319 if (strpos($res, 'WNL' ) !== false) return '1';
320 if (strpos($res, 'NORMAL') !== false) return '1';
327 // Create a new issue in the lists table.
329 function create_issue($pid, $type, $title) {
330 sqlInsert("INSERT INTO lists ( " .
331 "date, pid, type, title, activity, user, groupname " .
338 "'" . $
$_SESSION['authUser'] . "', " .
339 "'" . $
$_SESSION['authProvider'] . "' " .
343 // Write a row to the billing table.
345 function add_billing($pid, $encounter, $provider, $codetype, $code,
346 $description, $justify='', $modifier='', $units=1)
348 global $insurance_company_id;
350 // Get the fee from the codes table.
352 if ($codetype == 'CPT4') {
353 $query = "SELECT fee FROM codes WHERE code_type = 1 AND code = '$code' AND ";
354 if (empty($modifier))
355 $query .= "( modifier IS NULL OR modifier = '')";
357 $query .= "modifier = '$modifier'";
358 $row = sqlQuery($query);
359 if ($row['fee']) $fee = $row['fee'] * $units;
362 sqlInsert("INSERT INTO billing ( " .
363 "date, code_type, code, pid, provider_id, user, groupname, authorized, " .
364 "encounter, code_text, billed, activity, payer_id, modifier, units, " .
372 "'" . $
$_SESSION['authUser'] . "', " .
373 "'" . $
$_SESSION['authProvider'] . "', " .
379 "'$insurance_company_id', " .
387 // Check permission to run this. We might want more here.
389 $thisauth = acl_check('patients', 'demo');
390 if ($thisauth != 'write')
391 die("Updating demographics is not authorized.");
395 <?php
if (function_exists('html_header_show')) html_header_show(); ?
>
396 <link rel
="stylesheet" href
="<?php echo $css_header;?>" type
="text/css">
398 <style type
="text/css">
401 font
-family
:sans
-serif
;
405 font
-family
:monospace
;
410 border
-top
-width
:0px
;
411 border
-bottom
-width
:0px
;
412 border
-left
-width
:0px
;
413 border
-right
-width
:0px
;
414 border
-color
: #aaaaaa;
415 background
-color
:transparent
;
420 <title
>Import Encounters
</title
>
422 <body
class="body_top">
423 <form method
='post' action
='import.php' enctype
='multipart/form-data'>
426 // echo '<p>$_POST = '; print_r($_POST); // debugging
428 // Should be just one insurance company, assume the first one we find is it.
430 $row = sqlQuery("SELECT id FROM insurance_companies ORDER BY id LIMIT 1");
431 $insurance_company_id = $row['id'];
432 if (!$insurance_company_id) die('No insurance company found!');
434 // For each set of POSTed patient data, store it to the database.
436 while (!empty($_POST['pt' . ++
$ptsequence])) {
437 $pta = &$_POST["pt$ptsequence"]['patient'];
439 // echo '<p>$pta = '; print_r($pta); // debugging
441 // Check if $pta[insured_id] matches any pubpid. If so, we will skip everything
442 // except the encounter.
444 $pubpid = $pta['insured_id'];
445 if (empty($pubpid)) {
446 $alertmsg .= "Patient ID missing, patient skipped! ";
450 $query = "SELECT pid FROM patient_data WHERE pubpid LIKE '$pubpid'";
451 $res = sqlStatement($query);
452 $row = sqlFetchArray($res);
454 $patient_pid = $row['pid'];
455 if (sqlFetchArray($res)) {
456 $alertmsg .= "Patient ID \\'$pubpid\\' is ambiguous, patient skipped! ";
459 $alertmsg .= "Patient ID \\'$pubpid\\' already exists, will create encounter only. ";
463 // Find xcp (rendering provider), failure is an error.
464 // $pta[xcp][id] matches up with the insurance number.
466 $tmp = $pta['xcp']['id'];
468 $query = "SELECT n.provider_id, u.username " .
469 "FROM insurance_numbers AS n, users AS u WHERE " .
470 "n.provider_number LIKE '$tmp' AND " .
471 "n.insurance_company_id IS NOT NULL AND " .
472 "n.insurance_company_id = $insurance_company_id AND " .
473 "u.id = n.provider_id";
474 $row = sqlQuery($query);
475 if (!$row['provider_id']) {
476 $alertmsg .= "Provider \\'$tmp\\' not found, patient skipped! ";
479 $patient_provider_id = $row['provider_id'];
480 $patient_provider_name = $row['username'];
482 $query = "SELECT id, username FROM users WHERE npi like '$tmp' LIMIT 1";
483 $row = sqlQuery($query);
485 $alertmsg .= "Provider \\'$tmp\\' not found, patient skipped! ";
488 $patient_provider_id = $row['id'];
489 $patient_provider_name = $row['username'];
491 // Find facility, failure is an error.
492 // $pta[medical][billable][clinic][id] matches up with ... npi?
494 $tmp = $pta['medical']['billable']['clinic']['id'];
495 $row = sqlQuery("SELECT id, name FROM facility WHERE " .
496 "facility_npi LIKE '$tmp'");
498 $alertmsg .= "Facility \\'$tmp\\' not found, patient skipped! ";
501 $patient_facility_id = $row['id'];
502 $patient_facility_name = $row['name'];
506 // Insert into patient_data.
508 $row = sqlQuery("SELECT max(pid)+1 AS pid FROM patient_data");
509 $patient_pid = $row['pid'] ?
$row['pid'] : 1;
514 form2db($pta['fname']), // fname
515 form2db($pta['lname']), // lname
516 form2db($pta['mname']), // mname
517 sex($pta['sex']), // sex
518 form2db($pta['dob']), // dob
519 form2db($pta['street']), // street
520 form2db($pta['zip']), // zip
521 form2db($pta['city']), // city
522 form2db($pta['state']), // state
524 form2db($pta['ssn']), // ss
526 form2db($pta['phone_home']), // phone_home
527 form2db($pta['phone_alternate']), // phone_biz
530 '', // contact_relationship
531 form2db($pta['pcp']['id'] . ',' . $pta['pcp']['lname'] . ',' . $pta['pcp']['fname']), // referrer
535 form2db($pta['ethnicity']), // ethnoracial
537 '', // migrantseasonal
539 '', // monthly_income
541 '0000-00-00 00:00:00', // financial_review
555 // Insert dummy row for employer_data.
556 newEmployerData($patient_pid);
558 // Encode exam results as needed for history_data.
560 exam_result($pta, 'breastexamination') .
561 exam_result($pta, 'mammogram' ) .
562 exam_result($pta, 'gyn' ) .
563 exam_result($pta, 'rectalexam' ) .
564 exam_result($pta, 'prostateexam' ) .
565 exam_result($pta, 'physicalexam' ) .
566 exam_result($pta, 'sigmoid' ) .
567 exam_result($pta, 'ecg' ) .
568 exam_result($pta, 'cardiacecho' ) .
569 exam_result($pta, 'retinal' ) .
570 exam_result($pta, 'fluvax' ) .
571 exam_result($pta, 'pneuvax' ) .
572 exam_result($pta, 'ldl' ) .
573 exam_result($pta, 'hemoglobin' ) .
574 exam_result($pta, 'psa' ) .
577 // TBD: The above is obsolete in 2.8.4. Fill in history_data.exams instead.
578 // However this does not apply to the client's production installation.
580 // Insert into history_data.
581 newHistoryData($patient_pid, array(
582 'history_father' => form2db($pta['familyinformation']['father']),
583 'history_mother' => form2db($pta['familyinformation']['mother']),
584 'history_spouse' => form2db($pta['familyinformation']['spouse']),
585 'history_siblings' => form2db($pta['familyinformation']['siblings']),
586 'history_offspring' => form2db($pta['familyinformation']['offspring']),
587 'relatives_cancer' => form2db($pta['medical']['relativesexperience']['cancer']),
588 'relatives_tuberculosis' => form2db($pta['medical']['relativesexperience']['tuberculosis']),
589 'relatives_diabetes' => form2db($pta['medical']['relativesexperience']['diabetes']),
590 'relatives_high_blood_pressure' => form2db($pta['medical']['relativesexperience']['highbloodpressure']),
591 'relatives_heart_problems' => form2db($pta['medical']['relativesexperience']['heartproblems']),
592 'relatives_stroke' => form2db($pta['medical']['relativesexperience']['stroke']),
593 'relatives_epilepsy' => form2db($pta['medical']['relativesexperience']['epilepsy']),
594 'relatives_mental_illness' => form2db($pta['medical']['relativesexperience']['mentalillness']),
595 'relatives_suicide' => form2db($pta['medical']['relativesexperience']['suicide']),
596 'coffee' => form2db($pta['medical']['lifestyleusage']['coffee']),
597 'tobacco' => form2db($pta['medical']['lifestyleusage']['tobacco']),
598 'alcohol' => form2db($pta['medical']['lifestyleusage']['alcohol']),
599 'sleep_patterns' => form2db($pta['medical']['lifestyleusage']['sleep']),
600 'exercise_patterns' => form2db($pta['medical']['lifestyleusage']['exercise']),
601 'seatbelt_use' => form2db($pta['medical']['lifestyleusage']['seatbelt']),
602 'counseling' => form2db($pta['medical']['lifestyleusage']['counseling']),
603 'hazardous_activities' => form2db($pta['medical']['lifestyleusage']['hazardactivities']),
604 'last_breast_exam' => form2db($pta['medical']['preventatives']['breastexamination']['date']),
605 'last_cardiac_echo' => form2db($pta['medical']['preventatives']['cardiacecho']['date']),
606 'last_ecg' => form2db($pta['medical']['preventatives']['ecg']['date']),
607 'last_gynocological_exam' => form2db($pta['medical']['preventatives']['gyn']['date']),
608 'last_mammogram' => form2db($pta['medical']['preventatives']['mammogram']['date']),
609 'last_physical_exam' => form2db($pta['medical']['preventatives']['physicalexam']['date']),
610 'last_prostate_exam' => form2db($pta['medical']['preventatives']['prostateexam']['date']),
611 'last_rectal_exam' => form2db($pta['medical']['preventatives']['rectalexam']['date']),
612 'last_sigmoidoscopy_colonoscopy'=> form2db($pta['medical']['preventatives']['sigmoid']['date']),
613 'last_retinal' => form2db($pta['medical']['preventatives']['retinal']['date']),
614 'last_fluvax' => form2db($pta['medical']['preventatives']['fluvax']['date']),
615 'last_pneuvax' => form2db($pta['medical']['preventatives']['pneuvax']['date']),
616 'last_ldl' => form2db($pta['medical']['preventatives']['ldl']['date']),
617 'last_hemoglobin' => form2db($pta['medical']['preventatives']['hemoglobin']['date']),
618 'last_psa' => form2db($pta['medical']['preventatives']['psa']['date']),
619 'name_1' => form2db($pta['medical']['preventatives']['other']['name']),
620 'value_1' => form2db($pta['medical']['preventatives']['other']['date']) . ':' .
621 form2db($pta['medical']['preventatives']['other']['result']),
622 'last_exam_results' => $last_exam_results,
628 $insurance_company_id, // (insurance) provider
629 $pubpid, // policy_number - same as pt identifier?
630 '', // group_number - anything special here?
631 '', // plan_name - anything special here?
632 form2db($pta['lname']), // subscriber_lname
633 form2db($pta['mname']), // subscriber_mname
634 form2db($pta['fname']), // subscriber_fname
635 'self', // subscriber_relationship
636 form2db($pta['ssn']), // subscriber_ss
637 fixDate($pta['dob']), // subscriber_DOB
638 form2db($pta['street']), // subscriber_street
639 form2db($pta['zip']), // subscriber_postal_code
640 form2db($pta['city']), // subscriber_city
641 form2db($pta['state']), // subscriber_state
642 '', // subscriber_country
643 form2db($pta['phone_home']), // subscriber_phone
644 '', // subscriber_employer
645 '', // subscriber_employer_street
646 '', // subscriber_employer_city
647 '', // subscriber_employer_postal_code
648 '', // subscriber_employer_state
649 '', // subscriber_employer_country
651 sex($pta['sex']) // subscriber_sex
653 newInsuranceData($patient_pid, 'secondary');
654 newInsuranceData($patient_pid, 'tertiary');
656 // Create an issue for each medication. Cram details into the title.
658 if (!empty($pta['medical']['medications'])) {
659 foreach ($pta['medical']['medications'] as $key => $value) {
660 if (empty($value['name'])) continue;
661 create_issue($patient_pid, 'medication',
662 form2db($value['name'] ) . '/' .
663 form2db($value['dosage'] ) . '/' .
664 form2db($value['frequency']) . '/' .
665 form2db($value['duration'] )
670 if (!empty($pta['medical']['medicalhistory']['medicationnotes'])) {
671 create_issue($patient_pid, 'medication',
672 form2db($pta['medical']['medicalhistory']['medicationnotes']));
675 if (!empty($pta['medical']['medicalhistory']['allergies'])) {
676 create_issue($patient_pid, 'allergy',
677 form2db($pta['medical']['medicalhistory']['allergies']));
680 if (!empty($pta['medical']['medicalhistory']['history'])) {
681 create_issue($patient_pid, 'medical_problem',
682 form2db($pta['medical']['medicalhistory']['history']));
685 if (!empty($pta['medical']['medicalhistory']['surgicalhistory'])) {
686 create_issue($patient_pid, 'surgery',
687 form2db($pta['medical']['medicalhistory']['surgicalhistory']));
689 } // end if ($patient_is_new)
691 // TBD: Check encounter DOS. If it already exists, generate error message
692 // and continue (this can happen if they rerun an input file).
694 // TBD: Create new encounter.
695 $dos = fixDate($pta['medical']['billable']['fromdate']);
696 $encounter_id = $GLOBALS['adodb']['db']->GenID('sequences');
697 $encounter_reason = form2db($pta['medical']['billable']['notes']);
698 addForm($encounter_id, "New Patient Encounter",
699 sqlInsert("INSERT INTO form_encounter SET " .
701 "onset_date = '$dos', " .
702 "reason = '$encounter_reason', " .
703 "facility = '$patient_facility_name', " .
704 "facility_id = '$patient_facility_id', " .
705 "sensitivity = 'normal', " .
706 "pid = '$patient_pid', " .
707 "encounter = '$encounter_id'"
709 "newpatient", $patient_pid, 1, $dos
712 // Create SOAP2 form.
713 addForm($encounter_id, "SOAP",
714 sqlInsert("INSERT INTO form_soap2 SET " .
716 "pid = '$patient_pid', " .
719 "general = '" . form2db($pta['medical']['subjective']['general']) . "', " .
720 "neurological = '" . form2db($pta['medical']['subjective']['neurological']) . "', " .
721 "heent = '" . form2db($pta['medical']['subjective']['heent']) . "', " .
722 "respiratory = '" . form2db($pta['medical']['subjective']['respiratory']) . "', " .
723 "cardio = '" . form2db($pta['medical']['subjective']['cardio']) . "', " .
724 "gastro = '" . form2db($pta['medical']['subjective']['gastro']) . "', " .
725 "skin = '" . form2db($pta['medical']['subjective']['skin']) . "', " .
726 "extremities = '" . form2db($pta['medical']['subjective']['extremities']) . "', " .
727 "mentalstatus = '" . form2db($pta['medical']['physicalexamsvitals']['mentalstatus']) . "', " .
728 "assessment = '" . form2db($pta['medical']['systems']['assessment']) . "', " .
729 "plan = '" . form2db($pta['medical']['systems']['treatmentplan']) . "'"
731 "soap2", $patient_pid, 1, $dos
734 // Create Vitals form.
735 if (!empty($pta['medical']['physicalexamsvitals'])) {
736 addForm($encounter_id, "Vitals",
737 sqlInsert("INSERT INTO form_vitals SET " .
739 "pid = '$patient_pid', " .
742 "bps = '" . form2db($pta['medical']['physicalexamsvitals']['bps']) . "', " .
743 "bpd = '" . form2db($pta['medical']['physicalexamsvitals']['bpd']) . "', " .
744 "weight = '" . form2db($pta['medical']['physicalexamsvitals']['weight']) . "', " .
745 "height = '" . form2db($pta['medical']['physicalexamsvitals']['height']) . "', " .
746 "temperature = '" . form2db($pta['medical']['physicalexamsvitals']['temperature']) . "', " .
747 "temp_method = '" . form2db($pta['medical']['physicalexamsvitals']['tempmethods']) . "', " .
748 "pulse = '" . form2db($pta['medical']['physicalexamsvitals']['pulse']) . "', " .
749 "respiration = '" . form2db($pta['medical']['physicalexamsvitals']['respiration']) . "', " .
750 "BMI = '" . form2db($pta['medical']['physicalexamsvitals']['bmi']) . "', " .
751 "waist_circ = '" . form2db($pta['medical']['physicalexamsvitals']['waistcirc']) . "', " .
752 "head_circ = '" . form2db($pta['medical']['physicalexamsvitals']['headcirc']) . "', " .
753 "oxygen_saturation = '" . form2db($pta['medical']['physicalexamsvitals']['o2']) . "'"
755 "vitals", $patient_pid, 1, $dos
760 if (!empty($pta['medical']['systems'])) {
761 foreach ($pta['medical']['systems'] as $key => $value) {
762 if (strpos($key, 'diagnosis*') === 0) {
763 if (empty($value['code'])) continue;
764 $diags[] = $value['code'];
765 add_billing($patient_pid, $encounter_id, $patient_provider_id,
766 'ICD9', $value['code'],
767 $value['codenote'] . ' (' . $value['codestatus'] . ')');
772 if (!empty($pta['medical']['billable'])) {
774 foreach ($pta['medical']['billable'] as $key => $value) {
775 if (strpos($key, 'service*') === 0) {
776 if (empty($value['code'])) continue;
777 // add_billing($patient_pid, $encounter_id, $patient_provider_id,
778 // 'CPT4', $value['code'], $value['codenote'], $diags[$i++] . ':');
779 for ($justify = '', $j = 0; $j < 4 && $j < count($diags); ++
$j)
780 $justify .= $diags[$j] . ':';
781 add_billing($patient_pid, $encounter_id, $patient_provider_id,
782 'CPT4', $value['code'], $value['codenote'], $justify);
791 // echo "<p>Upload file size = " . $_FILES['form_xmlfile']['size'] . "</p>\n"; // debugging
793 if ($_FILES['form_xmlfile']['size']) {
794 $tmp_name = $_FILES['form_xmlfile']['tmp_name'];
796 // Handle .zip extension if present. Probably won't work on Windows.
797 if (strtolower(substr($_FILES['form_xmlfile']['name'], -4)) == '.zip') {
798 rename($tmp_name, "$tmp_name.zip");
799 exec("unzip -p $tmp_name.zip > $tmp_name");
800 unlink("$tmp_name.zip");
803 $parser = xml_parser_create();
804 xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE
, 1);
807 $indata = trim(file_get_contents($tmp_name));
808 if (strpos($indata, '<?xml') === 0) {
809 $indata = substr($indata, strpos($indata, '?>') +
2);
812 if (xml_parse_into_struct($parser, '<stuff>' . $indata . '</stuff>', $xml)) {
813 // echo '<p>$xml = '; print_r($xml); // debugging
817 foreach ($xml as $taginfo) {
818 $tag = strtolower($taginfo['tag']);
819 $tagtype = $taginfo['type'];
820 $taglevel = $taginfo['level'] - 2;
821 $tagval = addslashes($taginfo['value']);
823 if ($taglevel < 0) continue; // ignoring the top level
825 if ($tagtype == 'open') {
826 if ($taglevel == 0) {
834 $medication_index = 0;
835 $diagnosis_index = 0;
837 init_patient($x, $a);
839 else if ($taglevel == 3 && $tag == 'medication') {
840 $tag .= '*' . $medication_index;
841 $a['patient']['medical']['medications'][$tag] = array();
844 else if ($taglevel == 3 && $tag == 'diagnosis') {
845 $tag .= '*' . $diagnosis_index;
846 $a['patient']['medical']['systems'][$tag] = array();
849 else if ($taglevel == 3 && $tag == 'service') {
850 $tag .= '*' . $service_index;
851 $a['patient']['medical']['billable'][$tag] = array();
854 $probearr[$taglevel] = $tag;
857 if ($tagtype == 'close') {
860 if ($tagtype != 'complete') die("Unhandled tag type '$tagtype'");
862 // Create key/value pair for this leaf item.
863 // Note that init_patient() already created the branch nodes.
865 for ($i = 0; $i < $taglevel; ++
$i) $aref = &$aref[$probearr[$i]];
866 $aref[$tag] = $tagval;
875 $alertmsg = "Invalid import data!";
877 xml_parser_free($parser);
883 <?php
xl('Upload import file:','e') ?
>
884 <input type
="hidden" name
="MAX_FILE_SIZE" value
="5000000" />
885 <input name
="form_xmlfile" type
="file" />
887 <input type
='submit' name
='form_import' value
='Save and/or Upload' />  
;
892 echo "<script language='JavaScript'>\n";
893 echo " alert('$alertmsg');\n";