a pretty comprehensive xml import module
[openemr.git] / custom / import_medics.php
blobed3892f0b3e71d4fab45deb6601b339ef8331460
1 <?php
2 // Copyright (C) 2007 Rod Roark <rod@sunsetsystems.com>
3 //
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");
36 $x = array(
37 'patient' => array('Patient', array(
38 'pid' => array('Patient ID' , '2'),
39 'lname' => array('Last Name' , '2'),
40 'mname' => array('Middle Name' , '2'),
41 'fname' => array('First Name' , '2'),
42 'sex' => array('Sex' , '2'),
43 'dob' => array('Birth Date' , '2'),
44 'ethnicity' => array('Ethnicity' , '2'),
45 'street' => array('Street Address', '2'),
46 'street2' => array('Street Address', '2'),
47 'city' => array('City' , '2'),
48 'state' => array('State' , '2'),
49 'zip' => array('Zip Code' , '2'),
50 'phone_home' => array('Home Phone' , '2'),
51 'phone_alternate' => array('Other Phone', '2'),
52 'pcp' => array('Primary Physician', array(
53 'id' => array('Billing ID', '2'),
54 'lname' => array('Last Name' , '2'),
55 'fname' => array('First Name' , '2'),
56 )), // end pcp
57 'xcp' => array('Rendering Provider', array(
58 'id' => array('Billing ID', '2'),
59 'lname' => array('Last Name' , '2'),
60 'fname' => array('First Name', '2'),
61 'notes' => array('Notes' , '2'),
62 )), // end xcp
63 'familyinformation' => array('Family Information', array(
64 'father' => array('Father' , '2'),
65 'mother' => array('Mother' , '2'),
66 'spouse' => array('Spouse' , '2'),
67 'siblings' => array('Siblings' , '2'),
68 'offspring' => array('Offspring', '2'),
69 )), // end familyinformation
70 'medical' => array('Medical Information', array(
71 'relativesexperience' => array('Relatives Experience', array(
72 'cancer' => array('Cancer' , '2'),
73 'tuberculosis' => array('Tuberculosis' , '2'),
74 'diabetes' => array('Diabetes' , '2'),
75 'highbloodpressure' => array('Hypertension' , '2'),
76 'heartproblems' => array('Heart Problems', '2'),
77 'stroke' => array('Stroke' , '2'),
78 'epilepsy' => array('Epilepsy' , '2'),
79 'mentalillness' => array('Mental Illness', '2'),
80 'suicide' => array('Suicide' , '2'),
81 )),
82 'lifestyleusage' => array('Lifestyle/Usage', array(
83 'coffee' => array('Coffee' , '2'),
84 'tobacco' => array('Tobacco' , '2'),
85 'alcohol' => array('Alcohol' , '2'),
86 'sleep' => array('Sleep' , '2'),
87 'exercise' => array('Exercise' , '2'),
88 'seatbelt' => array('Seat Belt' , '2'),
89 'counseling' => array('Counseling' , '2'),
90 'hazardactivities' => array('Hazardous Activities', '2'),
91 )),
92 'medications' => array('Medications', array(
93 'medication*' => array('Medication', array(
94 'name' => array('Name' , '2'),
95 'dosage' => array('Dosage' , '2'),
96 'frequency' => array('Frequency', '2'),
97 'duration' => array('Duration' , '2'),
98 )),
99 )),
100 'medicalhistory' => array('Medical History', array(
101 'medicationnotes' => array('Medication Notes', '2'),
102 'allergies' => array('Allergies' , '2'),
103 'history' => array('History' , '2'),
104 'surgicalhistory' => array('Surgical History', '2'),
106 'preventatives' => array('Preventatives', array(
107 'breastexamination' => array('Breast Exam', array(
108 'date' => array('Date' , '2'),
109 'result' => array('Result', '2'),
111 'cardiacecho' => array('Cardiac Echo', array(
112 'date' => array('Date' , '2'),
113 'result' => array('Result', '2'),
115 'ecg' => array('ECG', array(
116 'date' => array('Date' , '2'),
117 'result' => array('Result', '2'),
119 'gyn' => array('Gyn Exam', array(
120 'date' => array('Date' , '2'),
121 'result' => array('Result', '2'),
123 'mammogram' => array('Mammogram', array(
124 'date' => array('Date' , '2'),
125 'result' => array('Result', '2'),
127 'physicalexam' => array('Physical Exam', array(
128 'date' => array('Date' , '2'),
129 'result' => array('Result', '2'),
131 'prostateexam' => array('Prostate Exam', array(
132 'date' => array('Date' , '2'),
133 'result' => array('Result', '2'),
135 'rectalexam' => array('Rectal Exam', array(
136 'date' => array('Date' , '2'),
137 'result' => array('Result', '2'),
139 'sigmoid' => array('Sigmoid', array(
140 'date' => array('Date' , '2'),
141 'result' => array('Result', '2'),
143 'retinal' => array('Retinal Exam', array(
144 'date' => array('Date' , '2'),
145 'result' => array('Result', '2'),
147 'fluvax' => array('Flu Vaccination', array(
148 'date' => array('Date' , '2'),
149 'result' => array('Result', '2'),
151 'pneuvax' => array('Pnuemonia Vaccination', array(
152 'date' => array('Date' , '2'),
153 'result' => array('Result', '2'),
155 'ldl' => array('LDL', array(
156 'date' => array('Date' , '2'),
157 'result' => array('Result', '2'),
159 'hemoglobin' => array('Hemoglobin', array(
160 'date' => array('Date' , '2'),
161 'result' => array('Result', '2'),
163 'psa' => array('PSA', array(
164 'date' => array('Date' , '2'),
165 'result' => array('Result', '2'),
167 'other' => array('Other', array(
168 'name' => array('Name' , '2'),
169 'date' => array('Date' , '2'),
170 'result' => array('Result', '2'),
172 )), // end preventatives
173 'subjective' => array('Subjective', array(
174 'general' => array('General' , '2'),
175 'neurological' => array('Neurological', '2'),
176 'heent' => array('HEENT' , '2'),
177 'respiratory' => array('Respiratory' , '2'),
178 'cardio' => array('Cardio' , '2'),
179 'gastro' => array('Gastro' , '2'),
180 'skin' => array('Skin' , '2'),
181 'extremities' => array('Extremities' , '2'),
182 )), // end subjective
183 'physicalexamsvitals' => array('Physical Exams/Vitals', array(
184 'mentalstatus' => array('Mental Status', '2'),
185 'bps' => array('BPS' , '2'),
186 'bpd' => array('BPD' , '2'),
187 'weight' => array('Weight' , '2'),
188 'height' => array('Height' , '2'),
189 'temperature' => array('Temperature' , '2'),
190 'tempmethods' => array('Temp Method' , '2'),
191 'pulse' => array('Pulse' , '2'),
192 'respiration' => array('Respiration' , '2'),
193 'bmi' => array('BMI' , '2'),
194 'waistcirc' => array('Waist Circ' , '2'),
195 'headcirc' => array('Head Circ' , '2'),
196 'o2' => array('Oxygen' , '2'),
197 )), // end physicalexamsvitals
198 'systems' => array('Systems', array(
199 'assessment' => array('Assessment' , '2'),
200 'treatmentplan' => array('Treatment Plan', '2'),
201 'diagnosis*' => array('Diagnosis', array(
202 'code' => array('Diagnosis Code', '2'),
203 'codestatus' => array('Code Status' , '2'),
204 'codenote' => array('Code Note' , '2'),
206 )), // end systems
207 'billable' => array('Billing', array(
208 'fromdate' => array('From Date', '2'),
209 'thrudate' => array('Thru Date', '2'),
210 'notes' => array('Notes', '2'),
211 'service*' => array('Service', array(
212 'code' => array('Service Code', '2'),
213 'codenote' => array('Code Note' , '2'),
215 'clinic' => array('Clinic', array(
216 'id' => array('Billing ID' , '2'),
217 'name' => array('Name' , '2'),
218 'street' => array('Street Address', '2'),
219 'street2' => array('Street Address', '2'),
220 'city' => array('City' , '2'),
221 'state' => array('State' , '2'),
222 'zip' => array('Zip Code' , '2'),
223 'phone' => array('Phone' , '2'),
225 )), // end billable
226 )), // end medical
227 )), // end patient
228 ); // end $x
230 // This recursively initializes the array that will hold imported data values
231 // for one patient.
233 function init_patient(&$sarr, &$darr) {
234 foreach ($sarr as $key => $value) {
235 if (is_array($value[1])) {
236 // Tags ending in * are those that are repeated. They will be
237 // inserted elsewhere.
238 if (substr($key, -1) == '*') continue;
239 $darr[$key] = array();
240 init_patient($value[1], $darr[$key]);
245 $ptsequence = 0;
246 $probearr = array();
248 // This recursively writes the tree of HTML data for one patient.
249 // $sarr contains logical keys, verbose names and field types.
250 // $darr contains physical keys and data values.
251 // $probearr maintains the heirarchy of physical key names.
253 function write_html(&$sarr, &$darr) {
254 global $probearr, $ptsequence;
256 // echo '<p>$darr = '; print_r($darr); // debugging
258 foreach ($darr as $dkey => $dvalue) {
259 if (!is_array($dvalue)) {
260 // Write leaf name and value. We are copying our same physical
261 // keys into the HTML field names so that PHP will parse them back
262 // into the same familiar format.
263 echo "<li>" . $sarr[$dkey][0] . ": ";
264 echo "<input type='text' name='pt$ptsequence";
265 foreach ($probearr as $pvalue) echo "[$pvalue]";
266 echo "[$dkey]' class='indata' value='" . $dvalue . "'></li>\n";
268 } // end foreach
270 foreach ($darr as $dkey => $dvalue) {
271 if (is_array($dvalue)) {
272 $array_depth = array_push($probearr, $dkey);
273 $skey = $dkey;
274 $i = strpos($skey, '*');
275 if ($i) {
276 // If the physical key has an asterisk then the logical key is only
277 // the part up to and including the asterisk.
278 $skey = substr($skey, 0, $i+1);
280 // Write the verbose name corresponding to this logical key.
281 if ($array_depth > 1) echo "<li>" . $sarr[$skey][0] . "</li>\n";
282 // Recursively process this array's contents.
283 echo "<ul>\n";
284 write_html($sarr[$skey][1], $dvalue);
285 echo "</ul>";
286 array_pop($probearr);
288 } // end foreach
291 // Encode a string from a form field for database writing.
293 function form2db($fldval) {
294 $fldval = trim($fldval);
295 if (!get_magic_quotes_gpc()) $fldval = addslashes($fldval);
296 return $fldval;
299 // Encode sex for OpenEMR compatibility.
301 function sex($insex) {
302 if (!empty($insex)) {
303 $insex = strtoupper(substr($insex, 0, 1));
304 if ($insex == 'M') return 'Male';
305 if ($insex == 'F') return 'Female';
307 return '';
310 // Compute the digit corresponding to a test/exam result.
311 // 0 = unassigned, 1 = normal, 2 = abnormal.
313 function exam_result(&$pta, $key) {
314 if (!empty($pta['medical']['preventatives'][$key])) {
315 if (trim($pta['medical']['preventatives'][$key]['date'])) {
316 $res = strtoupper(trim($pta['medical']['preventatives'][$key]['result']));
317 if (strpos($res, 'ABN' ) !== false) return '2';
318 if (strpos($res, 'WNL' ) !== false) return '1';
319 if (strpos($res, 'NORMAL') !== false) return '1';
320 return '2';
323 return '0';
326 // Create a new issue in the lists table.
328 function create_issue($pid, $type, $title) {
329 sqlInsert("INSERT INTO lists ( " .
330 "date, pid, type, title, activity, user, groupname " .
331 ") VALUES ( " .
332 "NOW(), " .
333 "'$pid', " .
334 "'$type', " .
335 "'$title', " .
336 "1, " .
337 "'" . $$_SESSION['authUser'] . "', " .
338 "'" . $$_SESSION['authProvider'] . "' " .
339 ")");
342 // Write a row to the billing table.
344 function add_billing($pid, $encounter, $provider, $codetype, $code,
345 $description, $justify='', $modifier='', $units=1)
347 global $insurance_company_id;
349 // Get the fee from the codes table.
350 $fee = 0;
351 if ($codetype == 'CPT4') {
352 $query = "SELECT fee FROM codes WHERE code_type = 1 AND code = '$code' AND ";
353 if (empty($modifier))
354 $query .= "( modifier IS NULL OR modifier = '')";
355 else
356 $query .= "modifier = '$modifier'";
357 $row = sqlQuery($query);
358 if ($row['fee']) $fee = $row['fee'] * $units;
361 sqlInsert("INSERT INTO billing ( " .
362 "date, code_type, code, pid, provider_id, user, groupname, authorized, " .
363 "encounter, code_text, billed, activity, payer_id, modifier, units, " .
364 "fee, justify " .
365 ") VALUES ( " .
366 "NOW(), " .
367 "'$codetype', " .
368 "'$code', " .
369 "'$pid', " .
370 "'$provider', " .
371 "'" . $$_SESSION['authUser'] . "', " .
372 "'" . $$_SESSION['authProvider'] . "', " .
373 "1, " .
374 "'$encounter', " .
375 "'$description', " .
376 "0, " .
377 "1, " .
378 "'$insurance_company_id', " .
379 "'$modifier', " .
380 "'$units', " .
381 "'$fee', " .
382 "'$justify'" .
383 ")");
386 // Check permission to run this. We might want more here.
388 $thisauth = acl_check('patients', 'demo');
389 if ($thisauth != 'write')
390 die("Updating demographics is not authorized.");
392 <html>
393 <head>
394 <link rel=stylesheet href="<?echo $css_header;?>" type="text/css">
396 <style type="text/css">
397 body {
398 font-family:sans-serif;
400 .indata {
401 font-family:monospace;
402 font-size:11pt;
403 font-weight:normal;
404 color:#ff0000;
405 border-style:solid;
406 border-top-width:0px;
407 border-bottom-width:0px;
408 border-left-width:0px;
409 border-right-width:0px;
410 border-color: #aaaaaa;
411 background-color:transparent;
414 </style>
416 <title>Import Encounters</title>
417 </head>
418 <body <? echo $top_bg_line ?>>
419 <form method='post' action='import_medics.php' enctype='multipart/form-data'>
420 <?php
422 // echo '<p>$_POST = '; print_r($_POST); // debugging
424 // Should be just one insurance company, assume the first one we find is it.
426 $row = sqlQuery("SELECT id FROM insurance_companies ORDER BY id LIMIT 1");
427 $insurance_company_id = $row['id'];
428 if (!$insurance_company_id) die('No insurance company found!');
430 // For each set of POSTed patient data, store it to the database.
432 while (!empty($_POST['pt' . ++$ptsequence])) {
433 $pta = &$_POST["pt$ptsequence"]['patient'];
435 // echo '<p>$pta = '; print_r($pta); // debugging
437 // Check if $pta[pid] matches any pubpid. If so, we will skip everything
438 // except the encounter.
440 $pubpid = $pta['pid'];
441 if (empty($pubpid)) {
442 $alertmsg .= "Patient ID missing, patient skipped! ";
443 continue;
445 $patient_pid = 0;
446 $query = "SELECT pid FROM patient_data WHERE pubpid LIKE '$pubpid'";
447 $res = sqlStatement($query);
448 $row = sqlFetchArray($res);
449 if ($row) {
450 $patient_pid = $row['pid'];
451 if (sqlFetchArray($res)) {
452 $alertmsg .= "Patient ID \\'$pubpid\\' is ambiguous, patient skipped! ";
453 continue;
454 } else {
455 $alertmsg .= "Patient ID \\'$pubpid\\' already exists, will create encounter only. ";
459 // Find xcp (rendering provider), failure is an error.
460 // $pta[xcp][id] matches up with the insurance number.
462 $tmp = $pta['xcp']['id'];
463 /****
464 $query = "SELECT n.provider_id, u.username " .
465 "FROM insurance_numbers AS n, users AS u WHERE " .
466 "n.provider_number LIKE '$tmp' AND " .
467 "n.insurance_company_id IS NOT NULL AND " .
468 "n.insurance_company_id = $insurance_company_id AND " .
469 "u.id = n.provider_id";
470 $row = sqlQuery($query);
471 if (!$row['provider_id']) {
472 $alertmsg .= "Provider \\'$tmp\\' not found, patient skipped! ";
473 continue;
475 $patient_provider_id = $row['provider_id'];
476 $patient_provider_name = $row['username'];
477 ****/
478 $query = "SELECT id, username FROM users WHERE npi like '$tmp' LIMIT 1";
479 $row = sqlQuery($query);
480 if (!$row['id']) {
481 $alertmsg .= "Provider \\'$tmp\\' not found, patient skipped! ";
482 continue;
484 $patient_provider_id = $row['id'];
485 $patient_provider_name = $row['username'];
487 // Find facility, failure is an error.
488 // $pta[medical][billable][clinic][id] matches up with ... npi?
490 $tmp = $pta['medical']['billable']['clinic']['id'];
491 $row = sqlQuery("SELECT id, name FROM facility WHERE " .
492 "facility_npi LIKE '$tmp'");
493 if (!$row['id']) {
494 $alertmsg .= "Facility \\'$tmp\\' not found, patient skipped! ";
495 continue;
497 $patient_facility_name = $row['name'];
499 if (!$patient_pid) {
501 // Insert into patient_data.
503 $row = sqlQuery("SELECT max(pid)+1 AS pid FROM patient_data");
504 $patient_pid = $row['pid'] ? $row['pid'] : 1;
506 newPatientData(
507 '', // id
508 '', // title
509 form2db($pta['fname']), // fname
510 form2db($pta['lname']), // lname
511 form2db($pta['mname']), // mname
512 sex($pta['sex']), // sex
513 form2db($pta['dob']), // dob
514 form2db($pta['street']), // street
515 form2db($pta['zip']), // zip
516 form2db($pta['city']), // city
517 form2db($pta['state']), // state
518 '', // country
519 form2db($pta['ssn']), // ss
520 '', // occupation
521 form2db($pta['phone_home']), // phone_home
522 form2db($pta['phone_alternate']), // phone_biz
523 '', // phone_contact
524 '', // status
525 '', // contact_relationship
526 form2db($pta['pcp']['id'] . ',' . $pta['pcp']['lname'] . ',' . $pta['pcp']['fname']), // referrer
527 '', // referrerID
528 '', // email
529 '', // language
530 form2db($pta['ethnicity']), // ethnoracial
531 '', // interpreter
532 '', // migrantseasonal
533 '', // family_size
534 '', // monthly_income
535 '', // homeless
536 '0000-00-00 00:00:00', // financial_review
537 $pubpid, // pubpid
538 $patient_pid, // pid
539 '', // providerID
540 '', // genericname1
541 '', // genericval1
542 '', // genericname2
543 '', // genericval2
544 '', // phone_cell
545 '', // hipaa_mail
546 '', // hipaa_voice
547 '' // squad
550 // Insert dummy row for employer_data.
551 newEmployerData($patient_pid);
553 // Encode exam results as needed for history_data.
554 $last_exam_results =
555 exam_result($pta, 'breastexamination') .
556 exam_result($pta, 'mammogram' ) .
557 exam_result($pta, 'gyn' ) .
558 exam_result($pta, 'rectalexam' ) .
559 exam_result($pta, 'prostateexam' ) .
560 exam_result($pta, 'physicalexam' ) .
561 exam_result($pta, 'sigmoid' ) .
562 exam_result($pta, 'ecg' ) .
563 exam_result($pta, 'cardiacecho' ) .
564 exam_result($pta, 'retinal' ) .
565 exam_result($pta, 'fluvax' ) .
566 exam_result($pta, 'pneuvax' ) .
567 exam_result($pta, 'ldl' ) .
568 exam_result($pta, 'hemoglobin' ) .
569 exam_result($pta, 'psa' ) .
570 '0';
572 // Insert into history_data.
573 newHistoryData($patient_pid, array(
574 'history_father' => form2db($pta['familyinformation']['father']),
575 'history_mother' => form2db($pta['familyinformation']['mother']),
576 'history_spouse' => form2db($pta['familyinformation']['spouse']),
577 'history_siblings' => form2db($pta['familyinformation']['siblings']),
578 'history_offspring' => form2db($pta['familyinformation']['offspring']),
579 'relatives_cancer' => form2db($pta['medical']['relativesexperience']['cancer']),
580 'relatives_tuberculosis' => form2db($pta['medical']['relativesexperience']['tuberculosis']),
581 'relatives_diabetes' => form2db($pta['medical']['relativesexperience']['diabetes']),
582 'relatives_high_blood_pressure' => form2db($pta['medical']['relativesexperience']['highbloodpressure']),
583 'relatives_heart_problems' => form2db($pta['medical']['relativesexperience']['heartproblems']),
584 'relatives_stroke' => form2db($pta['medical']['relativesexperience']['stroke']),
585 'relatives_epilepsy' => form2db($pta['medical']['relativesexperience']['epilepsy']),
586 'relatives_mental_illness' => form2db($pta['medical']['relativesexperience']['mentalillness']),
587 'relatives_suicide' => form2db($pta['medical']['relativesexperience']['suicide']),
588 'coffee' => form2db($pta['medical']['lifestyleusage']['coffee']),
589 'tobacco' => form2db($pta['medical']['lifestyleusage']['tobacco']),
590 'alcohol' => form2db($pta['medical']['lifestyleusage']['alcohol']),
591 'sleep_patterns' => form2db($pta['medical']['lifestyleusage']['sleep']),
592 'exercise_patterns' => form2db($pta['medical']['lifestyleusage']['exercise']),
593 'seatbelt_use' => form2db($pta['medical']['lifestyleusage']['seatbelt']),
594 'counseling' => form2db($pta['medical']['lifestyleusage']['counseling']),
595 'hazardous_activities' => form2db($pta['medical']['lifestyleusage']['hazardactivities']),
596 'last_breast_exam' => form2db($pta['medical']['preventatives']['breastexamination']['date']),
597 'last_cardiac_echo' => form2db($pta['medical']['preventatives']['cardiacecho']['date']),
598 'last_ecg' => form2db($pta['medical']['preventatives']['ecg']['date']),
599 'last_gynocological_exam' => form2db($pta['medical']['preventatives']['gyn']['date']),
600 'last_mammogram' => form2db($pta['medical']['preventatives']['mammogram']['date']),
601 'last_physical_exam' => form2db($pta['medical']['preventatives']['physicalexam']['date']),
602 'last_prostate_exam' => form2db($pta['medical']['preventatives']['prostateexam']['date']),
603 'last_rectal_exam' => form2db($pta['medical']['preventatives']['rectalexam']['date']),
604 'last_sigmoidoscopy_colonoscopy'=> form2db($pta['medical']['preventatives']['sigmoid']['date']),
605 'last_retinal' => form2db($pta['medical']['preventatives']['retinal']['date']),
606 'last_fluvax' => form2db($pta['medical']['preventatives']['fluvax']['date']),
607 'last_pneuvax' => form2db($pta['medical']['preventatives']['pneuvax']['date']),
608 'last_ldl' => form2db($pta['medical']['preventatives']['ldl']['date']),
609 'last_hemoglobin' => form2db($pta['medical']['preventatives']['hemoglobin']['date']),
610 'last_psa' => form2db($pta['medical']['preventatives']['psa']['date']),
611 'name_1' => form2db($pta['medical']['preventatives']['other']['name']),
612 'value_1' => form2db($pta['medical']['preventatives']['other']['date']) . ':' .
613 form2db($pta['medical']['preventatives']['other']['result']),
614 'last_exam_results' => $last_exam_results,
617 newInsuranceData(
618 $patient_pid,
619 'primary',
620 $insurance_company_id, // (insurance) provider
621 $pubpid, // policy_number - same as pt identifier?
622 '', // group_number - anything special here?
623 '', // plan_name - anything special here?
624 form2db($pta['lname']), // subscriber_lname
625 form2db($pta['mname']), // subscriber_mname
626 form2db($pta['fname']), // subscriber_fname
627 'self', // subscriber_relationship
628 form2db($pta['ssn']), // subscriber_ss
629 fixDate($pta['dob']), // subscriber_DOB
630 form2db($pta['street']), // subscriber_street
631 form2db($pta['zip']), // subscriber_postal_code
632 form2db($pta['city']), // subscriber_city
633 form2db($pta['state']), // subscriber_state
634 '', // subscriber_country
635 form2db($pta['phone_home']), // subscriber_phone
636 '', // subscriber_employer
637 '', // subscriber_employer_street
638 '', // subscriber_employer_city
639 '', // subscriber_employer_postal_code
640 '', // subscriber_employer_state
641 '', // subscriber_employer_country
642 '', // copay
643 sex($pta['sex']) // subscriber_sex
645 newInsuranceData($patient_pid, 'secondary');
646 newInsuranceData($patient_pid, 'tertiary');
648 // Create an issue for each medication. Cram details into the title.
650 if (!empty($pta['medical']['medications'])) {
651 foreach ($pta['medical']['medications'] as $key => $value) {
652 if (empty($value['name'])) continue;
653 create_issue($patient_pid, 'medication',
654 form2db($value['name'] ) . '/' .
655 form2db($value['dosage'] ) . '/' .
656 form2db($value['frequency']) . '/' .
657 form2db($value['duration'] )
662 if (!empty($pta['medical']['medicalhistory']['medicationnotes'])) {
663 create_issue($patient_pid, 'medication',
664 form2db($pta['medical']['medicalhistory']['medicationnotes']));
667 if (!empty($pta['medical']['medicalhistory']['allergies'])) {
668 create_issue($patient_pid, 'allergy',
669 form2db($pta['medical']['medicalhistory']['allergies']));
672 if (!empty($pta['medical']['medicalhistory']['history'])) {
673 create_issue($patient_pid, 'medical_problem',
674 form2db($pta['medical']['medicalhistory']['history']));
677 if (!empty($pta['medical']['medicalhistory']['surgicalhistory'])) {
678 create_issue($patient_pid, 'surgery',
679 form2db($pta['medical']['medicalhistory']['surgicalhistory']));
681 } // end if ($patient_is_new)
683 // TBD: Check encounter DOS. If it already exists, generate error message
684 // and continue (this can happen if they rerun an input file).
686 // TBD: Create new encounter.
687 $dos = fixDate($pta['medical']['billable']['fromdate']);
688 $encounter_id = $GLOBALS['adodb']['db']->GenID('sequences');
689 $encounter_reason = form2db($pta['medical']['billable']['notes']);
690 addForm($encounter_id, "New Patient Encounter",
691 sqlInsert("INSERT INTO form_encounter SET " .
692 "date = '$dos', " .
693 "onset_date = '$dos', " .
694 "reason = '$encounter_reason', " .
695 "facility = '$patient_facility_name', " .
696 "sensitivity = 'normal', " .
697 "pid = '$patient_pid', " .
698 "encounter = '$encounter_id'"
700 "newpatient", $patient_pid, 1, $dos
703 // Create SOAP2 form.
704 addForm($encounter_id, "SOAP",
705 sqlInsert("INSERT INTO form_soap2 SET " .
706 "date = '$dos', " .
707 "pid = '$patient_pid', " .
708 "authorized = 1, " .
709 "activity = 1, " .
710 "general = '" . form2db($pta['medical']['subjective']['general']) . "', " .
711 "neurological = '" . form2db($pta['medical']['subjective']['neurological']) . "', " .
712 "heent = '" . form2db($pta['medical']['subjective']['heent']) . "', " .
713 "respiratory = '" . form2db($pta['medical']['subjective']['respiratory']) . "', " .
714 "cardio = '" . form2db($pta['medical']['subjective']['cardio']) . "', " .
715 "gastro = '" . form2db($pta['medical']['subjective']['gastro']) . "', " .
716 "skin = '" . form2db($pta['medical']['subjective']['skin']) . "', " .
717 "extremities = '" . form2db($pta['medical']['subjective']['extremities']) . "', " .
718 "mentalstatus = '" . form2db($pta['medical']['physicalexamsvitals']['mentalstatus']) . "', " .
719 "assessment = '" . form2db($pta['medical']['systems']['assessment']) . "', " .
720 "plan = '" . form2db($pta['medical']['systems']['treatmentplan']) . "'"
722 "soap2", $patient_pid, 1, $dos
725 // Create Vitals form.
726 if (!empty($pta['medical']['physicalexamsvitals'])) {
727 addForm($encounter_id, "Vitals",
728 sqlInsert("INSERT INTO form_vitals SET " .
729 "date = '$dos', " .
730 "pid = '$patient_pid', " .
731 "authorized = 1, " .
732 "activity = 1, " .
733 "bps = '" . form2db($pta['medical']['physicalexamsvitals']['bps']) . "', " .
734 "bpd = '" . form2db($pta['medical']['physicalexamsvitals']['bpd']) . "', " .
735 "weight = '" . form2db($pta['medical']['physicalexamsvitals']['weight']) . "', " .
736 "height = '" . form2db($pta['medical']['physicalexamsvitals']['height']) . "', " .
737 "temperature = '" . form2db($pta['medical']['physicalexamsvitals']['temperature']) . "', " .
738 "temp_method = '" . form2db($pta['medical']['physicalexamsvitals']['tempmethods']) . "', " .
739 "pulse = '" . form2db($pta['medical']['physicalexamsvitals']['pulse']) . "', " .
740 "respiration = '" . form2db($pta['medical']['physicalexamsvitals']['respiration']) . "', " .
741 "BMI = '" . form2db($pta['medical']['physicalexamsvitals']['bmi']) . "', " .
742 "waist_circ = '" . form2db($pta['medical']['physicalexamsvitals']['waistcirc']) . "', " .
743 "head_circ = '" . form2db($pta['medical']['physicalexamsvitals']['headcirc']) . "', " .
744 "oxygen_saturation = '" . form2db($pta['medical']['physicalexamsvitals']['o2']) . "'"
746 "vitals", $patient_pid, 1, $dos
750 $diags = array();
751 if (!empty($pta['medical']['systems'])) {
752 foreach ($pta['medical']['systems'] as $key => $value) {
753 if (strpos($key, 'diagnosis*') === 0) {
754 if (empty($value['code'])) continue;
755 $diags[] = $value['code'];
756 add_billing($patient_pid, $encounter_id, $patient_provider_id,
757 'ICD9', $value['code'],
758 $value['codenote'] . ' (' . $value['codestatus'] . ')');
763 if (!empty($pta['medical']['billable'])) {
764 $i = 0;
765 foreach ($pta['medical']['billable'] as $key => $value) {
766 if (strpos($key, 'service*') === 0) {
767 if (empty($value['code'])) continue;
768 add_billing($patient_pid, $encounter_id, $patient_provider_id,
769 'CPT4', $value['code'], $value['codenote'], $diags[$i++] . ':');
776 $ptsequence = 0;
778 // echo "<p>Upload file size = " . $_FILES['form_xmlfile']['size'] . "</p>\n"; // debugging
780 if ($_FILES['form_xmlfile']['size']) {
781 $tmp_name = $_FILES['form_xmlfile']['tmp_name'];
783 // Handle .zip extension if present. Probably won't work on Windows.
784 if (strtolower(substr($_FILES['form_xmlfile']['name'], -4)) == '.zip') {
785 rename($tmp_name, "$tmp_name.zip");
786 exec("unzip -p $tmp_name.zip > $tmp_name");
787 unlink("$tmp_name.zip");
790 $parser = xml_parser_create();
791 xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
792 $xml = array();
794 $indata = trim(file_get_contents($tmp_name));
795 if (strpos($indata, '<?xml') === 0) {
796 $indata = substr($indata, strpos($indata, '?>') + 2);
799 if (xml_parse_into_struct($parser, '<stuff>' . $indata . '</stuff>', $xml)) {
800 // echo '<p>$xml = '; print_r($xml); // debugging
802 $a = false;
804 foreach ($xml as $taginfo) {
805 $tag = strtolower($taginfo['tag']);
806 $tagtype = $taginfo['type'];
807 $taglevel = $taginfo['level'] - 2;
808 $tagval = addslashes($taginfo['value']);
810 if ($taglevel < 0) continue; // ignoring the top level
812 if ($tagtype == 'open') {
813 if ($taglevel == 0) {
814 if ($ptsequence) {
815 $probearr = array();
816 write_html($x, $a);
818 ++$ptsequence;
819 $probearr = array();
820 $a = array();
821 $medication_index = 0;
822 $diagnosis_index = 0;
823 $service_index = 0;
824 init_patient($x, $a);
826 else if ($taglevel == 3 && $tag == 'medication') {
827 $tag .= '*' . $medication_index;
828 $a['patient']['medical']['medications'][$tag] = array();
829 ++$medication_index;
831 else if ($taglevel == 3 && $tag == 'diagnosis') {
832 $tag .= '*' . $diagnosis_index;
833 $a['patient']['medical']['systems'][$tag] = array();
834 ++$diagnosis_index;
836 else if ($taglevel == 3 && $tag == 'service') {
837 $tag .= '*' . $service_index;
838 $a['patient']['medical']['billable'][$tag] = array();
839 ++$service_index;
841 $probearr[$taglevel] = $tag;
842 continue;
844 if ($tagtype == 'close') {
845 continue;
847 if ($tagtype != 'complete') die("Unhandled tag type '$tagtype'");
849 // Create key/value pair for this leaf item.
850 // Note that init_patient() already created the branch nodes.
851 $aref = &$a;
852 for ($i = 0; $i < $taglevel; ++$i) $aref = &$aref[$probearr[$i]];
853 $aref[$tag] = $tagval;
854 } // end foreach
856 if ($ptsequence) {
857 $probearr = array();
858 write_html($x, $a);
861 else {
862 $alertmsg = "Invalid import data!";
864 xml_parser_free($parser);
865 unlink($tmp_name);
869 <center>
870 <?php xl('Upload import file:','e') ?>
871 <input type="hidden" name="MAX_FILE_SIZE" value="5000000" />
872 <input name="form_xmlfile" type="file" />
873 &nbsp; &nbsp; &nbsp;
874 <input type='submit' name='form_import' value='Save and/or Upload' /> &nbsp;
875 </center>
876 </form>
877 <?php
878 if ($alertmsg) {
879 echo "<script language='JavaScript'>\n";
880 echo " alert('$alertmsg');\n";
881 echo "</script>\n";
884 </body>
885 </html>