rearranging the gcac issue form layout
[openemr.git] / custom / import_medics.php
blobbb01d15865b131816134177edeed85d929bef54f
1 <?php
2 // Copyright (C) 2007, 2008 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 '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'),
57 )), // end pcp
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'),
63 )), // end xcp
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'),
82 )),
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'),
92 )),
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'),
99 )),
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'),
207 )), // end systems
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'),
226 )), // end billable
227 )), // end medical
228 )), // end patient
229 ); // end $x
231 // This recursively initializes the array that will hold imported data values
232 // for one patient.
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]);
246 $ptsequence = 0;
247 $probearr = array();
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";
269 } // end foreach
271 foreach ($darr as $dkey => $dvalue) {
272 if (is_array($dvalue)) {
273 $array_depth = array_push($probearr, $dkey);
274 $skey = $dkey;
275 $i = strpos($skey, '*');
276 if ($i) {
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.
284 echo "<ul>\n";
285 write_html($sarr[$skey][1], $dvalue);
286 echo "</ul>";
287 array_pop($probearr);
289 } // end foreach
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);
297 return $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';
308 return '';
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';
321 return '2';
324 return '0';
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 " .
332 ") VALUES ( " .
333 "NOW(), " .
334 "'$pid', " .
335 "'$type', " .
336 "'$title', " .
337 "1, " .
338 "'" . $$_SESSION['authUser'] . "', " .
339 "'" . $$_SESSION['authProvider'] . "' " .
340 ")");
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.
351 $fee = 0;
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 = '')";
356 else
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, " .
365 "fee, justify " .
366 ") VALUES ( " .
367 "NOW(), " .
368 "'$codetype', " .
369 "'$code', " .
370 "'$pid', " .
371 "'$provider', " .
372 "'" . $$_SESSION['authUser'] . "', " .
373 "'" . $$_SESSION['authProvider'] . "', " .
374 "1, " .
375 "'$encounter', " .
376 "'$description', " .
377 "0, " .
378 "1, " .
379 "'$insurance_company_id', " .
380 "'$modifier', " .
381 "'$units', " .
382 "'$fee', " .
383 "'$justify'" .
384 ")");
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.");
393 <html>
394 <head>
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">
400 body {
401 font-family:sans-serif;
404 .indata {
405 font-family:monospace;
406 font-size:11pt;
407 font-weight:normal;
408 color:#ff0000;
409 border-style:solid;
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;
418 </style>
420 <title>Import Encounters</title>
421 </head>
422 <body class="body_top">
423 <form method='post' action='import.php' enctype='multipart/form-data'>
424 <?php
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! ";
447 continue;
449 $patient_pid = 0;
450 $query = "SELECT pid FROM patient_data WHERE pubpid LIKE '$pubpid'";
451 $res = sqlStatement($query);
452 $row = sqlFetchArray($res);
453 if ($row) {
454 $patient_pid = $row['pid'];
455 if (sqlFetchArray($res)) {
456 $alertmsg .= "Patient ID \\'$pubpid\\' is ambiguous, patient skipped! ";
457 continue;
458 } else {
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'];
467 /****
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! ";
477 continue;
479 $patient_provider_id = $row['provider_id'];
480 $patient_provider_name = $row['username'];
481 ****/
482 $query = "SELECT id, username FROM users WHERE npi like '$tmp' LIMIT 1";
483 $row = sqlQuery($query);
484 if (!$row['id']) {
485 $alertmsg .= "Provider \\'$tmp\\' not found, patient skipped! ";
486 continue;
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'");
497 if (!$row['id']) {
498 $alertmsg .= "Facility \\'$tmp\\' not found, patient skipped! ";
499 continue;
501 $patient_facility_id = $row['id'];
502 $patient_facility_name = $row['name'];
504 if (!$patient_pid) {
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;
511 newPatientData(
512 '', // id
513 '', // title
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
523 '', // country
524 form2db($pta['ssn']), // ss
525 '', // occupation
526 form2db($pta['phone_home']), // phone_home
527 form2db($pta['phone_alternate']), // phone_biz
528 '', // phone_contact
529 '', // status
530 '', // contact_relationship
531 form2db($pta['pcp']['id'] . ',' . $pta['pcp']['lname'] . ',' . $pta['pcp']['fname']), // referrer
532 '', // referrerID
533 '', // email
534 '', // language
535 form2db($pta['ethnicity']), // ethnoracial
536 '', // interpreter
537 '', // migrantseasonal
538 '', // family_size
539 '', // monthly_income
540 '', // homeless
541 '0000-00-00 00:00:00', // financial_review
542 $pubpid, // pubpid
543 $patient_pid, // pid
544 '', // providerID
545 '', // genericname1
546 '', // genericval1
547 '', // genericname2
548 '', // genericval2
549 '', // phone_cell
550 '', // hipaa_mail
551 '', // hipaa_voice
552 '' // squad
555 // Insert dummy row for employer_data.
556 newEmployerData($patient_pid);
558 // Encode exam results as needed for history_data.
559 $last_exam_results =
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' ) .
575 '0';
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,
625 newInsuranceData(
626 $patient_pid,
627 'primary',
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
650 '', // copay
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 " .
700 "date = '$dos', " .
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 " .
715 "date = '$dos', " .
716 "pid = '$patient_pid', " .
717 "authorized = 1, " .
718 "activity = 1, " .
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 " .
738 "date = '$dos', " .
739 "pid = '$patient_pid', " .
740 "authorized = 1, " .
741 "activity = 1, " .
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
759 $diags = array();
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'])) {
773 // $i = 0;
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);
789 $ptsequence = 0;
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);
805 $xml = array();
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
815 $a = false;
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) {
827 if ($ptsequence) {
828 $probearr = array();
829 write_html($x, $a);
831 ++$ptsequence;
832 $probearr = array();
833 $a = array();
834 $medication_index = 0;
835 $diagnosis_index = 0;
836 $service_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();
842 ++$medication_index;
844 else if ($taglevel == 3 && $tag == 'diagnosis') {
845 $tag .= '*' . $diagnosis_index;
846 $a['patient']['medical']['systems'][$tag] = array();
847 ++$diagnosis_index;
849 else if ($taglevel == 3 && $tag == 'service') {
850 $tag .= '*' . $service_index;
851 $a['patient']['medical']['billable'][$tag] = array();
852 ++$service_index;
854 $probearr[$taglevel] = $tag;
855 continue;
857 if ($tagtype == 'close') {
858 continue;
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.
864 $aref = &$a;
865 for ($i = 0; $i < $taglevel; ++$i) $aref = &$aref[$probearr[$i]];
866 $aref[$tag] = $tagval;
867 } // end foreach
869 if ($ptsequence) {
870 $probearr = array();
871 write_html($x, $a);
874 else {
875 $alertmsg = "Invalid import data!";
877 xml_parser_free($parser);
878 unlink($tmp_name);
882 <center>
883 <?php xl('Upload import file:','e') ?>
884 <input type="hidden" name="MAX_FILE_SIZE" value="5000000" />
885 <input name="form_xmlfile" type="file" />
886 &nbsp; &nbsp; &nbsp;
887 <input type='submit' name='form_import' value='Save and/or Upload' /> &nbsp;
888 </center>
889 </form>
890 <?php
891 if ($alertmsg) {
892 echo "<script language='JavaScript'>\n";
893 echo " alert('$alertmsg');\n";
894 echo "</script>\n";
897 </body>
898 </html>