示例#1
0
         if ($fldtype == 'G') {
             if ($_POST["G1_{$prefix}{$qcode}"]) {
                 $data = $_POST["G1_{$prefix}{$qcode}"] * 7 + $_POST["G2_{$prefix}{$qcode}"];
             }
         } else {
             $data = $_POST["{$prefix}{$qcode}"];
         }
         if (!isset($data) || $data === '') {
             continue;
         }
         if (!is_array($data)) {
             $data = array($data);
         }
         foreach ($data as $datum) {
             // Note this will auto-assign the seq value.
             sqlBeginTrans();
             $answer_seq = sqlQuery("SELECT IFNULL(MAX(answer_seq),0) + 1 AS increment FROM procedure_answers WHERE procedure_order_id = ? AND procedure_order_seq = ? AND question_code = ? ", array($formid, $poseq, $qcode));
             sqlStatement("INSERT INTO procedure_answers SET " . "procedure_order_id = ?, " . "procedure_order_seq = ?, " . "question_code = ?, " . "answer_seq = ?, " . "answer = ?", array($formid, $poseq, $qcode, $answer_seq['increment'], strip_escape_custom($datum)));
             sqlCommitTrans();
         }
     }
 }
 $alertmsg = '';
 if ($_POST['bn_xmit']) {
     $hl7 = '';
     $alertmsg = gen_hl7_order($formid, $hl7);
     if (empty($alertmsg)) {
         $alertmsg = send_hl7_order($ppid, $hl7);
     }
     if (empty($alertmsg)) {
         sqlStatement("UPDATE procedure_order SET date_transmitted = NOW() WHERE " . "procedure_order_id = ?", array($formid));
/**
 * Parse and save.
 *
 * @param  string  &$hl7      The input HL7 text
 * @param  string  &$matchreq Array of shared patient matching requests
 * @param  int     $lab_id    Lab ID
 * @param  char    $direction B=Bidirectional, R=Results-only
 * @param  bool    $dryrun    True = do not update anything, just report errors
 * @param  array   $matchresp Array of responses to match requests; key is relative segment number,
 *                            value is an existing pid or 0 to specify creating a patient
 * @return array              Array of errors and match requests, if any
 */
function receive_hl7_results(&$hl7, &$matchreq, $lab_id = 0, $direction = 'B', $dryrun = false, $matchresp = NULL)
{
    global $rhl7_return;
    // This will hold returned error messages and related variables.
    $rhl7_return = array();
    $rhl7_return['mssgs'] = array();
    $rhl7_return['needmatch'] = false;
    // indicates if this file is pending a match request
    $rhl7_segnum = 0;
    if (substr($hl7, 0, 3) != 'MSH') {
        return rhl7LogMsg(xl('Input does not begin with a MSH segment'), true);
    }
    // This array holds everything to be written to the database.
    // We save and postpone these writes in case of errors while processing the message,
    // so we can look up data from parent results when child results are encountered,
    // and for other logic simplification.
    // Each element of this array is another array containing the following possible keys:
    // 'rep' - row of data to write to procedure_report
    // 'res' - array of rows to write to procedure_result for this procedure_report
    // 'fid' - unique lab-provided identifier for this report
    //
    $amain = array();
    // End-of-line delimiter for text in procedure_result.comments and other multi-line notes.
    $commentdelim = "\n";
    // Ensoftek: Different labs seem to send different EOLs. Edit HL7 input to a character we know.
    $hl7 = (string) str_replace(array("\r\n", "\r", "\n"), "\r", $hl7);
    $today = time();
    $in_message_id = '';
    $in_ssn = '';
    $in_dob = '';
    $in_lname = '';
    $in_fname = '';
    $in_orderid = 0;
    $in_procedure_code = '';
    $in_report_status = '';
    $in_encounter = 0;
    $patient_id = 0;
    // for results-only patient matching logic
    $porow = false;
    $pcrow = false;
    $oprow = false;
    $code_seq_array = array();
    // tracks sequence numbers of order codes
    $results_category_id = 0;
    // document category ID for lab results
    // This is so we know where we are if a segment like NTE that can appear in
    // different places is encountered.
    $context = '';
    // This will be "ORU" or "MDM".
    $msgtype = '';
    // Stuff collected for MDM documents.
    $mdm_datetime = '';
    $mdm_docname = '';
    $mdm_text = '';
    // Delimiters
    $d0 = "\r";
    $d1 = substr($hl7, 3, 1);
    // typically |
    $d2 = substr($hl7, 4, 1);
    // typically ^
    $d3 = substr($hl7, 5, 1);
    // typically ~
    $d4 = substr($hl7, 6, 1);
    // typically \
    $d5 = substr($hl7, 7, 1);
    // typically &
    // We'll need the document category IDs for any embedded documents.
    $catrow = sqlQuery("SELECT id FROM categories WHERE name = ?", array($GLOBALS['lab_results_category_name']));
    if (empty($catrow['id'])) {
        return rhl7LogMsg(xl('Document category for lab results does not exist') . ': ' . $GLOBALS['lab_results_category_name'], true);
    } else {
        $results_category_id = $catrow['id'];
        $mdm_category_id = $results_category_id;
        $catrow = sqlQuery("SELECT id FROM categories WHERE name = ?", array($GLOBALS['gbl_mdm_category_name']));
        if (!empty($catrow['id'])) {
            $mdm_category_id = $catrow['id'];
        }
    }
    $segs = explode($d0, $hl7);
    foreach ($segs as $seg) {
        if (empty($seg)) {
            continue;
        }
        // echo "<!-- $dryrun $seg -->\n"; // debugging
        ++$rhl7_segnum;
        $a = explode($d1, $seg);
        if ($a[0] == 'MSH') {
            if (!$dryrun) {
                rhl7FlushMain($amain, $commentdelim);
            }
            $amain = array();
            if ('MDM' == $msgtype && !$dryrun) {
                $rc = rhl7FlushMDM($patient_id, $mdm_docname, $mdm_datetime, $mdm_text, $mdm_category_id, $oprow ? $oprow['username'] : 0);
                if ($rc) {
                    return rhl7LogMsg($rc);
                }
                $patient_id = 0;
            }
            $context = $a[0];
            // Ensoftek: Could come is as 'ORU^R01^ORU_R01'. Handle all cases when 'ORU^R01' is seen.
            if (strstr($a[8], "ORU^R01")) {
                $msgtype = 'ORU';
            } else {
                if ($a[8] == 'MDM^T02' || $a[8] == 'MDM^T04' || $a[8] == 'MDM^T08') {
                    $msgtype = 'MDM';
                    $mdm_datetime = '';
                    $mdm_docname = '';
                    $mdm_text = '';
                } else {
                    return rhl7LogMsg(xl('MSH.8 message type is not supported') . ": '" . $a[8] . "'", true);
                }
            }
            $in_message_id = $a[9];
        } else {
            if ($a[0] == 'PID') {
                $context = $a[0];
                if ('MDM' == $msgtype && !$dryrun) {
                    $rc = rhl7FlushMDM($patient_id, $mdm_docname, $mdm_datetime, $mdm_text, $mdm_category_id, $oprow ? $oprow['username'] : 0);
                    if ($rc) {
                        return rhl7LogMsg($rc);
                    }
                }
                $porow = false;
                $pcrow = false;
                $oprow = false;
                $in_orderid = 0;
                $in_ssn = preg_replace('/[^0-9]/', '', $a[4]);
                $in_dob = rhl7Date($a[7]);
                $tmp = explode($d2, $a[5]);
                $in_lname = rhl7Text($tmp[0]);
                $in_fname = rhl7Text($tmp[1]);
                $in_mname = rhl7Text($tmp[2]);
                $patient_id = 0;
                // Patient matching is needed for a results-only interface or MDM message type.
                if ('R' == $direction || 'MDM' == $msgtype) {
                    $ptarr = array('ss' => strtoupper($in_ss), 'fname' => strtoupper($in_fname), 'lname' => strtoupper($in_lname), 'mname' => strtoupper($in_mname), 'DOB' => strtoupper($in_dob));
                    $patient_id = match_patient($ptarr);
                    if ($patient_id == -1) {
                        // Result is indeterminate.
                        // Make a stringified form of $ptarr to use as a key.
                        $ptstring = serialize($ptarr);
                        // Check if the user has specified the patient.
                        if (isset($matchresp[$ptstring])) {
                            // This will be an existing pid, or 0 to specify creating a patient.
                            $patient_id = intval($matchresp[$ptstring]);
                        } else {
                            if ($dryrun) {
                                // Nope, ask the user to match.
                                $matchreq[$ptstring] = true;
                                $rhl7_return['needmatch'] = true;
                            } else {
                                // Should not happen, but it would be bad to abort now.  Create the patient.
                                $patient_id = 0;
                                rhl7LogMsg(xl('Unexpected non-match, creating new patient for segment') . ' ' . $rhl7_segnum, false);
                            }
                        }
                    }
                    if ($patient_id == 0 && !$dryrun) {
                        // We must create the patient.
                        $patient_id = create_skeleton_patient($ptarr);
                    }
                    if ($patient_id == -1) {
                        $patient_id = 0;
                    }
                }
                // end results-only/MDM logic
            } else {
                if ('PD1' == $a[0]) {
                    // TBD: Save primary care provider name ($a[4]) somewhere?
                } else {
                    if ('PV1' == $a[0]) {
                        if ('ORU' == $msgtype) {
                            // Save placer encounter number if present.
                            if ($direction != 'R' && !empty($a[19])) {
                                $tmp = explode($d2, $a[19]);
                                $in_encounter = intval($tmp[0]);
                            }
                        } else {
                            if ('MDM' == $msgtype) {
                                // For documents we want the ordering provider.
                                // Try Referring Provider first.
                                $oprow = match_provider(explode($d2, $a[8]));
                                // If no match, try Other Provider.
                                if (empty($oprow)) {
                                    $oprow = match_provider(explode($d2, $a[52]));
                                }
                            }
                        }
                    } else {
                        if ('ORC' == $a[0] && 'ORU' == $msgtype) {
                            $context = $a[0];
                            $arep = array();
                            $porow = false;
                            $pcrow = false;
                            if ($direction != 'R' && $a[2]) {
                                $in_orderid = intval($a[2]);
                            }
                        } else {
                            if ('TXA' == $a[0] && 'MDM' == $msgtype) {
                                $context = $a[0];
                                $mdm_datetime = rhl7DateTime($a[4]);
                                $mdm_docname = rhl7Text($a[12]);
                            } else {
                                if ($a[0] == 'NTE' && ($context == 'ORC' || $context == 'TXA')) {
                                    // Is this ever used?
                                } else {
                                    if ('OBR' == $a[0] && 'ORU' == $msgtype) {
                                        $context = $a[0];
                                        $arep = array();
                                        if ($direction != 'R' && $a[2]) {
                                            $in_orderid = intval($a[2]);
                                            $porow = false;
                                            $pcrow = false;
                                        }
                                        $tmp = explode($d2, $a[4]);
                                        $in_procedure_code = $tmp[0];
                                        $in_procedure_name = $tmp[1];
                                        $in_report_status = rhl7ReportStatus($a[25]);
                                        // Filler identifier is supposed to be unique for each incoming report.
                                        $in_filler_id = $a[3];
                                        // Child results will have these pointers to their parent.
                                        $in_parent_obrkey = '';
                                        $in_parent_obxkey = '';
                                        $parent_arep = false;
                                        // parent report, if any
                                        $parent_ares = false;
                                        // parent result, if any
                                        if (!empty($a[29])) {
                                            // This is a child so there should be a parent.
                                            $tmp = explode($d2, $a[29]);
                                            $in_parent_obrkey = str_replace($d5, $d2, $tmp[1]);
                                            $tmp = explode($d2, $a[26]);
                                            $in_parent_obxkey = str_replace($d5, $d2, $tmp[0]) . $d1 . $tmp[1];
                                            // Look for the parent report.
                                            foreach ($amain as $arr) {
                                                if (isset($arr['fid']) && $arr['fid'] == $in_parent_obrkey) {
                                                    $parent_arep = $arr['rep'];
                                                    // Now look for the parent result within that report.
                                                    foreach ($arr['res'] as $tmpres) {
                                                        if (isset($tmpres['obxkey']) && $tmpres['obxkey'] == $in_parent_obxkey) {
                                                            $parent_ares = $tmpres;
                                                            break;
                                                        }
                                                    }
                                                    break;
                                                }
                                            }
                                        }
                                        if ($parent_arep) {
                                            $in_orderid = $parent_arep['procedure_order_id'];
                                        }
                                        if ($direction == 'R') {
                                            // Save their order ID to procedure_order.control_id.
                                            // Look for an existing order using that plus lab_id.
                                            // Ordering provider is OBR.16 (NPI^Last^First).
                                            // Might not need to create a dummy encounter.
                                            // Need also provider_id (probably), patient_id, date_ordered, lab_id.
                                            // We have observation date/time in OBR.7.
                                            // We have report date/time in OBR.22.
                                            // We do not have an order date.
                                            $external_order_id = empty($a[2]) ? $a[3] : $a[2];
                                            $porow = false;
                                            if (!$in_orderid && $external_order_id) {
                                                $porow = sqlQuery("SELECT * FROM procedure_order " . "WHERE lab_id = ? AND control_id = ? " . "ORDER BY procedure_order_id DESC LIMIT 1", array($lab_id, $external_order_id));
                                            }
                                            if (!empty($porow)) {
                                                $in_orderid = intval($porow['procedure_order_id']);
                                            }
                                            if (!$in_orderid) {
                                                // Create order.
                                                // Need to identify the ordering provider and, if possible, a recent encounter.
                                                $datetime_report = rhl7DateTime($a[22]);
                                                $date_report = substr($datetime_report, 0, 10) . ' 00:00:00';
                                                $encounter_id = 0;
                                                $provider_id = 0;
                                                // Look for the most recent encounter within 30 days of the report date.
                                                $encrow = sqlQuery("SELECT encounter FROM form_encounter WHERE " . "pid = ? AND date <= ? AND DATE_ADD(date, INTERVAL 30 DAY) > ? " . "ORDER BY date DESC, encounter DESC LIMIT 1", array($patient_id, $date_report, $date_report));
                                                if (!empty($encrow)) {
                                                    $encounter_id = intval($encrow['encounter']);
                                                    $provider_id = intval($encrow['provider_id']);
                                                }
                                                if (!$provider_id) {
                                                    // Attempt ordering provider matching by name or NPI.
                                                    $oprow = match_provider(explode($d2, $a[16]));
                                                    if (!empty($oprow)) {
                                                        $provider_id = intval($oprow['id']);
                                                    }
                                                }
                                                if (!$dryrun) {
                                                    // Now create the procedure order.
                                                    $in_orderid = sqlInsert("INSERT INTO procedure_order SET " . "date_ordered   = ?, " . "provider_id    = ?, " . "lab_id         = ?, " . "date_collected = ?, " . "date_transmitted = ?, " . "patient_id     = ?, " . "encounter_id   = ?, " . "control_id     = ?", array($datetime_report, $provider_id, $lab_id, rhl7DateTime($a[22]), rhl7DateTime($a[7]), $patient_id, $encounter_id, $external_order_id));
                                                    // If an encounter was identified then link the order to it.
                                                    if ($encounter_id && $in_orderid) {
                                                        addForm($encounter_id, "Procedure Order", $in_orderid, "procedure_order", $patient_id);
                                                    }
                                                }
                                            }
                                            // end no $porow
                                        }
                                        // end results-only
                                        if (empty($porow)) {
                                            $porow = sqlQuery("SELECT * FROM procedure_order WHERE " . "procedure_order_id = ?", array($in_orderid));
                                            // The order must already exist. Currently we do not handle electronic
                                            // results returned for manual orders.
                                            if (empty($porow) && !($dryrun && $direction == 'R')) {
                                                return rhl7LogMsg(xl('Procedure order not found') . ": {$in_orderid}", true);
                                            }
                                            if ($in_encounter) {
                                                if ($direction != 'R' && $porow['encounter_id'] != $in_encounter) {
                                                    return rhl7LogMsg(xl('Encounter ID') . " '" . $porow['encounter_id'] . "' " . xl('for OBR placer order number') . " '{$in_orderid}' " . xl('does not match the PV1 encounter number') . " '{$in_encounter}'");
                                                }
                                            } else {
                                                // They did not return an encounter number to verify, so more checking
                                                // might be done here to make sure the patient seems to match.
                                            }
                                            // Save the lab's control ID if there is one.
                                            $tmp = explode($d2, $a[3]);
                                            $control_id = $tmp[0];
                                            if ($control_id && empty($porow['control_id'])) {
                                                sqlStatement("UPDATE procedure_order SET control_id = ? WHERE " . "procedure_order_id = ?", array($control_id, $in_orderid));
                                            }
                                            $code_seq_array = array();
                                        }
                                        // Find the order line item (procedure code) that matches this result.
                                        // If there is more than one, then we select the one whose sequence number
                                        // is next after the last sequence number encountered for this procedure
                                        // code; this assumes that result OBRs are returned in the same sequence
                                        // as the corresponding OBRs in the order.
                                        if (!isset($code_seq_array[$in_procedure_code])) {
                                            $code_seq_array[$in_procedure_code] = 0;
                                        }
                                        $pcquery = "SELECT pc.* FROM procedure_order_code AS pc " . "WHERE pc.procedure_order_id = ? AND pc.procedure_code = ? " . "ORDER BY (procedure_order_seq <= ?), procedure_order_seq LIMIT 1";
                                        $pcqueryargs = array($in_orderid, $in_procedure_code, $code_seq_array[$in_procedure_code]);
                                        $pcrow = sqlQuery($pcquery, $pcqueryargs);
                                        if (empty($pcrow)) {
                                            // There is no matching procedure in the order, so it must have been
                                            // added after the original order was sent, either as a manual request
                                            // from the physician or as a "reflex" from the lab.
                                            // procedure_source = '2' indicates this.
                                            if (!$dryrun) {
                                                sqlBeginTrans();
                                                $procedure_order_seq = sqlQuery("SELECT IFNULL(MAX(procedure_order_seq),0) + 1 AS increment FROM procedure_order_code WHERE procedure_order_id = ? ", array($in_orderid));
                                                sqlInsert("INSERT INTO procedure_order_code SET " . "procedure_order_id = ?, " . "procedure_order_seq = ?, " . "procedure_code = ?, " . "procedure_name = ?, " . "procedure_source = '2'", array($in_orderid, $procedure_order_seq['increment'], $in_procedure_code, $in_procedure_name));
                                                $pcrow = sqlQuery($pcquery, $pcqueryargs);
                                                sqlCommitTrans();
                                            } else {
                                                // Dry run, make a dummy procedure_order_code row.
                                                $pcrow = array('procedure_order_id' => $in_orderid, 'procedure_order_seq' => 0);
                                            }
                                        }
                                        $code_seq_array[$in_procedure_code] = 0 + $pcrow['procedure_order_seq'];
                                        $arep = array();
                                        $arep['procedure_order_id'] = $in_orderid;
                                        $arep['procedure_order_seq'] = $pcrow['procedure_order_seq'];
                                        $arep['date_collected'] = rhl7DateTime($a[7]);
                                        $arep['date_collected_tz'] = rhl7DateTimeZone($a[7]);
                                        $arep['date_report'] = rhl7DateTime($a[22]);
                                        $arep['date_report_tz'] = rhl7DateTimeZone($a[22]);
                                        $arep['report_status'] = $in_report_status;
                                        $arep['report_notes'] = '';
                                        $arep['specimen_num'] = '';
                                        // If this is a child report, add some info from the parent.
                                        if (!empty($parent_ares)) {
                                            $arep['report_notes'] .= xl('This is a child of result') . ' ' . $parent_ares['result_code'] . ' ' . xl('with value') . ' "' . $parent_ares['result'] . '".' . "\n";
                                        }
                                        if (!empty($parent_arep)) {
                                            $arep['report_notes'] .= $parent_arep['report_notes'];
                                            $arep['specimen_num'] = $parent_arep['specimen_num'];
                                        }
                                        // Create the main array entry for this report and its results.
                                        $i = count($amain);
                                        $amain[$i] = array();
                                        $amain[$i]['rep'] = $arep;
                                        $amain[$i]['fid'] = $in_filler_id;
                                        $amain[$i]['res'] = array();
                                    } else {
                                        if ($a[0] == 'NTE' && $context == 'OBR') {
                                            // Append this note to those for the most recent report.
                                            $amain[count($amain) - 1]['rep']['report_notes'] .= rhl7Text($a[3], true) . "\n";
                                        } else {
                                            if ('OBX' == $a[0] && 'ORU' == $msgtype) {
                                                $tmp = explode($d2, $a[3]);
                                                $result_code = rhl7Text($tmp[0]);
                                                $result_text = rhl7Text($tmp[1]);
                                                // If this is a text result that duplicates the previous result except
                                                // for its value, then treat it as an extension of that result's value.
                                                $i = count($amain) - 1;
                                                $j = count($amain[$i]['res']) - 1;
                                                if ($j >= 0 && $context == 'OBX' && $a[2] == 'TX' && $amain[$i]['res'][$j]['result_data_type'] == 'L' && $amain[$i]['res'][$j]['result_code'] == $result_code && $amain[$i]['res'][$j]['date'] == rhl7DateTime($a[14]) && $amain[$i]['res'][$j]['facility'] == rhl7Text($a[15]) && $amain[$i]['res'][$j]['abnormal'] == rhl7Abnormal($a[8]) && $amain[$i]['res'][$j]['result_status'] == rhl7ReportStatus($a[11])) {
                                                    $amain[$i]['res'][$j]['comments'] = substr($amain[$i]['res'][$j]['comments'], 0, strlen($amain[$i]['res'][$j]['comments']) - 1) . '~' . rhl7Text($a[5]) . $commentdelim;
                                                    continue;
                                                }
                                                $context = $a[0];
                                                $ares = array();
                                                $ares['result_data_type'] = substr($a[2], 0, 1);
                                                // N, S, F or E
                                                $ares['comments'] = $commentdelim;
                                                if ($a[2] == 'ED') {
                                                    // This is the case of results as an embedded document. We will create
                                                    // a normal patient document in the assigned category for lab results.
                                                    $tmp = explode($d2, $a[5]);
                                                    $fileext = strtolower($tmp[0]);
                                                    $filename = date("Ymd_His") . '.' . $fileext;
                                                    $data = rhl7DecodeData($tmp[3], $tmp[4]);
                                                    if ($data === FALSE) {
                                                        return rhl7LogMsg(xl('Invalid encapsulated data encoding type') . ': ' . $tmp[3]);
                                                    }
                                                    if (!$dryrun) {
                                                        $d = new Document();
                                                        $rc = $d->createDocument($porow['patient_id'], $results_category_id, $filename, rhl7MimeType($fileext), $data);
                                                        if ($rc) {
                                                            return rhl7LogMsg($rc);
                                                        }
                                                        $ares['document_id'] = $d->get_id();
                                                    }
                                                } else {
                                                    if ($a[2] == 'CWE') {
                                                        $ares['result'] = rhl7CWE($a[5], $d2);
                                                    } else {
                                                        if ($a[2] == 'SN') {
                                                            $ares['result'] = trim(str_replace($d2, ' ', $a[5]));
                                                        } else {
                                                            if ($a[2] == 'TX' || strlen($a[5]) > 200) {
                                                                // OBX-5 can be a very long string of text with "~" as line separators.
                                                                // The first line of comments is reserved for such things.
                                                                $ares['result_data_type'] = 'L';
                                                                $ares['result'] = '';
                                                                $ares['comments'] = rhl7Text($a[5]) . $commentdelim;
                                                            } else {
                                                                $ares['result'] = rhl7Text($a[5]);
                                                            }
                                                        }
                                                    }
                                                }
                                                $ares['result_code'] = $result_code;
                                                $ares['result_text'] = $result_text;
                                                $ares['date'] = rhl7DateTime($a[14]);
                                                $ares['facility'] = rhl7Text($a[15]);
                                                // Ensoftek: Units may have mutiple segments(as seen in MU2 samples), parse and take just first segment.
                                                $tmp = explode($d2, $a[6]);
                                                $ares['units'] = rhl7Text($tmp[0]);
                                                $ares['range'] = rhl7Text($a[7]);
                                                $ares['abnormal'] = rhl7Abnormal($a[8]);
                                                // values are lab dependent
                                                $ares['result_status'] = rhl7ReportStatus($a[11]);
                                                // Ensoftek: Performing Organization Details. Goes into "Pending Review/Patient Results--->Notes--->Facility" section.
                                                $performingOrganization = getPerformingOrganizationDetails($a[23], $a[24], $a[25], $d2, $commentdelim);
                                                if (!empty($performingOrganization)) {
                                                    $ares['facility'] .= $performingOrganization . $commentdelim;
                                                }
                                                /****
                                                   // Probably need a better way to report this, if it matters.
                                                   if (!empty($a[19])) {
                                                     $ares['comments'] .= xl('Analyzed') . ' ' . rhl7DateTime($a[19]) . '.' . $commentdelim;
                                                   }
                                                   ****/
                                                // obxkey is to allow matching this as a parent result.
                                                $ares['obxkey'] = $a[3] . $d1 . $a[4];
                                                // Append this result to those for the most recent report.
                                                // Note the 'procedure_report_id' item is not yet present.
                                                $amain[count($amain) - 1]['res'][] = $ares;
                                            } else {
                                                if ('OBX' == $a[0] && 'MDM' == $msgtype) {
                                                    $context = $a[0];
                                                    if ($a[2] == 'TX') {
                                                        if ($mdm_text !== '') {
                                                            $mdm_text .= "\r\n";
                                                        }
                                                        $mdm_text .= rhl7Text($a[5]);
                                                    } else {
                                                        return rhl7LogMsg(xl('Unsupported MDM OBX result type') . ': ' . $a[2]);
                                                    }
                                                } else {
                                                    if ('ZEF' == $a[0] && 'ORU' == $msgtype) {
                                                        // ZEF segment is treated like an OBX with an embedded Base64-encoded PDF.
                                                        $context = 'OBX';
                                                        $ares = array();
                                                        $ares['result_data_type'] = 'E';
                                                        $ares['comments'] = $commentdelim;
                                                        //
                                                        $fileext = 'pdf';
                                                        $filename = date("Ymd_His") . '.' . $fileext;
                                                        $data = rhl7DecodeData('Base64', $a[2]);
                                                        if ($data === FALSE) {
                                                            return rhl7LogMsg(xl('ZEF segment internal error'));
                                                        }
                                                        if (!$dryrun) {
                                                            $d = new Document();
                                                            $rc = $d->createDocument($porow['patient_id'], $results_category_id, $filename, rhl7MimeType($fileext), $data);
                                                            if ($rc) {
                                                                return rhl7LogMsg($rc);
                                                            }
                                                            $ares['document_id'] = $d->get_id();
                                                        }
                                                        $ares['date'] = $arep['date_report'];
                                                        // $arep is left over from the OBR logic.
                                                        // Append this result to those for the most recent report.
                                                        // Note the 'procedure_report_id' item is not yet present.
                                                        $amain[count($amain) - 1]['res'][] = $ares;
                                                    } else {
                                                        if ('NTE' == $a[0] && 'OBX' == $context && 'ORU' == $msgtype) {
                                                            // Append this note to the most recent result item's comments.
                                                            $alast = count($amain) - 1;
                                                            $rlast = count($amain[$alast]['res']) - 1;
                                                            $amain[$alast]['res'][$rlast]['comments'] .= rhl7Text($a[3], true) . $commentdelim;
                                                        } else {
                                                            if ('SPM' == $a[0] && 'ORU' == $msgtype) {
                                                                rhl7UpdateReportWithSpecimen($amain, $a, $d2);
                                                            } else {
                                                                if ('TQ1' == $a[0] && 'ORU' == $msgtype) {
                                                                    // Ignore and do nothing.
                                                                } else {
                                                                    return rhl7LogMsg(xl('Segment name') . " '{$a[0]}' " . xl('is misplaced or unknown'));
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    // Write all reports and their results to the database.
    // This will do nothing if a dry run or MDM message type.
    if ('ORU' == $msgtype && !$dryrun) {
        rhl7FlushMain($amain, $commentdelim);
    }
    if ('MDM' == $msgtype && !$dryrun) {
        // Write documents.
        $rc = rhl7FlushMDM($patient_id, $mdm_docname, $mdm_datetime, $mdm_text, $mdm_category_id, $oprow ? $oprow['username'] : 0);
        if ($rc) {
            return rhl7LogMsg($rc);
        }
    }
    return $rhl7_return;
}
示例#3
0
 public function save(&$bill, &$prod, $main_provid = NULL, $main_supid = NULL, $default_warehouse = NULL, $mark_as_closed = false)
 {
     global $code_types;
     if (isset($main_provid) && $main_supid == $main_provid) {
         $main_supid = 0;
     }
     $copay_update = FALSE;
     $update_session_id = '';
     $ct0 = '';
     // takes the code type of the first fee type code type entry from the fee sheet, against which the copay is posted
     $cod0 = '';
     // takes the code of the first fee type code type entry from the fee sheet, against which the copay is posted
     $mod0 = '';
     // takes the modifier of the first fee type code type entry from the fee sheet, against which the copay is posted
     if (is_array($bill)) {
         foreach ($bill as $iter) {
             // Skip disabled (billed) line items.
             if (!empty($iter['billed'])) {
                 continue;
             }
             $id = $iter['id'];
             $code_type = $iter['code_type'];
             $code = $iter['code'];
             $del = !empty($iter['del']);
             $units = empty($iter['units']) ? 1 : intval($iter['units']);
             $price = empty($iter['price']) ? 0 : 0 + trim($iter['price']);
             $pricelevel = empty($iter['pricelevel']) ? '' : $iter['pricelevel'];
             $modifier = empty($iter['mod']) ? '' : trim($iter['mod']);
             $justify = empty($iter['justify']) ? '' : trim($iter['justify']);
             $notecodes = empty($iter['notecodes']) ? '' : trim($iter['notecodes']);
             $provid = empty($iter['provid']) ? 0 : intval($iter['provid']);
             $fee = sprintf('%01.2f', $price * $units);
             if (!$cod0 && $code_types[$code_type]['fee'] == 1) {
                 $mod0 = $modifier;
                 $cod0 = $code;
                 $ct0 = $code_type;
             }
             if ($code_type == 'COPAY') {
                 if ($fee < 0) {
                     $fee = $fee * -1;
                 }
                 if (!$id) {
                     // adding new copay from fee sheet into ar_session and ar_activity tables
                     $session_id = idSqlStatement("INSERT INTO ar_session " . "(payer_id, user_id, pay_total, payment_type, description, patient_id, payment_method, " . "adjustment_code, post_to_date) " . "VALUES ('0',?,?,'patient','COPAY',?,'','patient_payment',now())", array($_SESSION['authId'], $fee, $this->pid));
                     sqlBeginTrans();
                     $sequence_no = sqlQuery("SELECT IFNULL(MAX(sequence_no),0) + 1 AS increment FROM ar_activity WHERE " . "pid = ? AND encounter = ?", array($this->pid, $this->encounter));
                     SqlStatement("INSERT INTO ar_activity (pid, encounter, sequence_no, code_type, code, modifier, " . "payer_type, post_time, post_user, session_id, " . "pay_amount, account_code) VALUES (?,?,?,?,?,?,0,now(),?,?,?,'PCP')", array($this->pid, $this->encounter, $sequence_no['increment'], $ct0, $cod0, $mod0, $_SESSION['authId'], $session_id, $fee));
                     sqlCommitTrans();
                 } else {
                     // editing copay saved to ar_session and ar_activity
                     $session_id = $id;
                     $res_amount = sqlQuery("SELECT pay_amount FROM ar_activity WHERE pid=? AND encounter=? AND session_id=?", array($this->pid, $this->encounter, $session_id));
                     if ($fee != $res_amount['pay_amount']) {
                         sqlStatement("UPDATE ar_session SET user_id=?,pay_total=?,modified_time=now(),post_to_date=now() WHERE session_id=?", array($_SESSION['authId'], $fee, $session_id));
                         sqlStatement("UPDATE ar_activity SET code_type=?, code=?, modifier=?, post_user=?, post_time=now()," . "pay_amount=?, modified_time=now() WHERE pid=? AND encounter=? AND account_code='PCP' AND session_id=?", array($ct0, $cod0, $mod0, $_SESSION['authId'], $fee, $this->pid, $this->encounter, $session_id));
                     }
                 }
                 if (!$cod0) {
                     $copay_update = TRUE;
                     $update_session_id = $session_id;
                 }
                 continue;
             }
             # Code to create justification for all codes based on first justification
             if ($GLOBALS['replicate_justification'] == '1') {
                 if ($justify != '') {
                     $autojustify = $justify;
                 }
             }
             if ($GLOBALS['replicate_justification'] == '1' && $justify == '' && check_is_code_type_justify($code_type)) {
                 $justify = $autojustify;
             }
             if ($justify) {
                 $justify = str_replace(',', ':', $justify) . ':';
             }
             $auth = "1";
             $ndc_info = '';
             if (!empty($iter['ndcnum'])) {
                 $ndc_info = 'N4' . trim($iter['ndcnum']) . '   ' . $iter['ndcuom'] . trim($iter['ndcqty']);
             }
             // If the item is already in the database...
             if ($id) {
                 if ($del) {
                     $this->logFSMessage(xl('Service deleted'));
                     deleteBilling($id);
                 } else {
                     $tmp = sqlQuery("SELECT * FROM billing WHERE id = ? AND (billed = 0 or billed is NULL) AND activity = 1", array($id));
                     if (!empty($tmp)) {
                         $tmparr = array('code' => $code, 'authorized' => $auth);
                         if (isset($iter['units'])) {
                             $tmparr['units'] = $units;
                         }
                         if (isset($iter['price'])) {
                             $tmparr['fee'] = $fee;
                         }
                         if (isset($iter['pricelevel'])) {
                             $tmparr['pricelevel'] = $pricelevel;
                         }
                         if (isset($iter['mod'])) {
                             $tmparr['modifier'] = $modifier;
                         }
                         if (isset($iter['provid'])) {
                             $tmparr['provider_id'] = $provid;
                         }
                         if (isset($iter['ndcnum'])) {
                             $tmparr['ndc_info'] = $ndc_info;
                         }
                         if (isset($iter['justify'])) {
                             $tmparr['justify'] = $justify;
                         }
                         if (isset($iter['notecodes'])) {
                             $tmparr['notecodes'] = $notecodes;
                         }
                         foreach ($tmparr as $key => $value) {
                             if ($tmp[$key] != $value) {
                                 if ('fee' == $key) {
                                     $this->logFSMessage(xl('Price changed'));
                                 }
                                 if ('units' == $key) {
                                     $this->logFSMessage(xl('Quantity changed'));
                                 }
                                 if ('provider_id' == $key) {
                                     $this->logFSMessage(xl('Service provider changed'));
                                 }
                                 sqlStatement("UPDATE billing SET `{$key}` = ? WHERE id = ?", array($value, $id));
                             }
                         }
                     }
                 }
             } else {
                 if (!$del) {
                     $this->logFSMessage(xl('Service added'));
                     $code_text = lookup_code_descriptions($code_type . ":" . $code);
                     addBilling($this->encounter, $code_type, $code, $code_text, $this->pid, $auth, $provid, $modifier, $units, $fee, $ndc_info, $justify, 0, $notecodes, $pricelevel);
                 }
             }
         }
     }
     // end for
     // if modifier is not inserted during loop update the record using the first
     // non-empty modifier and code
     if ($copay_update == TRUE && $update_session_id != '' && $mod0 != '') {
         sqlStatement("UPDATE ar_activity SET code_type = ?, code = ?, modifier = ?" . " WHERE pid = ? AND encounter = ? AND account_code = 'PCP' AND session_id = ?", array($ct0, $cod0, $mod0, $this->pid, $this->encounter, $update_session_id));
     }
     // Doing similarly to the above but for products.
     if (is_array($prod)) {
         foreach ($prod as $iter) {
             // Skip disabled (billed) line items.
             if (!empty($iter['billed'])) {
                 continue;
             }
             $drug_id = $iter['drug_id'];
             $selector = empty($iter['selector']) ? '' : $iter['selector'];
             $sale_id = $iter['sale_id'];
             // present only if already saved
             $units = max(1, intval(trim($iter['units'])));
             $price = empty($iter['price']) ? 0 : 0 + trim($iter['price']);
             $pricelevel = empty($iter['pricelevel']) ? '' : $iter['pricelevel'];
             $fee = sprintf('%01.2f', $price * $units);
             $del = !empty($iter['del']);
             $rxid = 0;
             $warehouse_id = empty($iter['warehouse']) ? '' : $iter['warehouse'];
             $somechange = false;
             // If the item is already in the database...
             if ($sale_id) {
                 $tmprow = sqlQuery("SELECT ds.prescription_id, ds.quantity, ds.inventory_id, ds.fee, " . "ds.sale_date, di.warehouse_id " . "FROM drug_sales AS ds " . "LEFT JOIN drug_inventory AS di ON di.inventory_id = ds.inventory_id " . "WHERE ds.sale_id = ?", array($sale_id));
                 $rxid = 0 + $tmprow['prescription_id'];
                 if ($del) {
                     if (!empty($tmprow)) {
                         // Delete this sale and reverse its inventory update.
                         $this->logFSMessage(xl('Product deleted'));
                         sqlStatement("DELETE FROM drug_sales WHERE sale_id = ?", array($sale_id));
                         if (!empty($tmprow['inventory_id'])) {
                             sqlStatement("UPDATE drug_inventory SET on_hand = on_hand + ? WHERE inventory_id = ?", array($tmprow['quantity'], $tmprow['inventory_id']));
                         }
                     }
                     if ($rxid) {
                         sqlStatement("DELETE FROM prescriptions WHERE id = ?", array($rxid));
                     }
                 } else {
                     // Modify the sale and adjust inventory accordingly.
                     if (!empty($tmprow)) {
                         foreach (array('quantity' => $units, 'fee' => $fee, 'pricelevel' => $pricelevel, 'selector' => $selector, 'sale_date' => $this->visit_date) as $key => $value) {
                             if ($tmprow[$key] != $value) {
                                 $somechange = true;
                                 if ('fee' == $key) {
                                     $this->logFSMessage(xl('Price changed'));
                                 }
                                 if ('pricelevel' == $key) {
                                     $this->logFSMessage(xl('Price level changed'));
                                 }
                                 if ('selector' == $key) {
                                     $this->logFSMessage(xl('Template selector changed'));
                                 }
                                 if ('quantity' == $key) {
                                     $this->logFSMessage(xl('Quantity changed'));
                                 }
                                 sqlStatement("UPDATE drug_sales SET `{$key}` = ? WHERE sale_id = ?", array($value, $sale_id));
                                 if ($key == 'quantity' && $tmprow['inventory_id']) {
                                     sqlStatement("UPDATE drug_inventory SET on_hand = on_hand - ? WHERE inventory_id = ?", array($units - $tmprow['quantity'], $tmprow['inventory_id']));
                                 }
                             }
                         }
                         if ($tmprow['inventory_id'] && $warehouse_id && $warehouse_id != $tmprow['warehouse_id']) {
                             // Changing warehouse.  Requires deleting and re-adding the sale.
                             // Not setting $somechange because this alone does not affect a prescription.
                             $this->logFSMessage(xl('Warehouse changed'));
                             sqlStatement("DELETE FROM drug_sales WHERE sale_id = ?", array($sale_id));
                             sqlStatement("UPDATE drug_inventory SET on_hand = on_hand + ? WHERE inventory_id = ?", array($units, $tmprow['inventory_id']));
                             $tmpnull = null;
                             $sale_id = sellDrug($drug_id, $units, $fee, $this->pid, $this->encounter, empty($iter['rx']) ? 0 : $rxid, $this->visit_date, '', $warehouse_id, false, $tmpnull, $pricelevel, $selector);
                         }
                     }
                     // Delete Rx if $rxid and flag not set.
                     if ($GLOBALS['gbl_auto_create_rx'] && $rxid && empty($iter['rx'])) {
                         sqlStatement("UPDATE drug_sales SET prescription_id = 0 WHERE sale_id = ?", array($sale_id));
                         sqlStatement("DELETE FROM prescriptions WHERE id = ?", array($rxid));
                     }
                 }
             } else {
                 if (!$del) {
                     $somechange = true;
                     $this->logFSMessage(xl('Product added'));
                     $tmpnull = null;
                     $sale_id = sellDrug($drug_id, $units, $fee, $this->pid, $this->encounter, 0, $this->visit_date, '', $warehouse_id, false, $tmpnull, $pricelevel, $selector);
                     if (!$sale_id) {
                         die(xlt("Insufficient inventory for product ID") . " \"" . text($drug_id) . "\".");
                     }
                 }
             }
             // If a prescription applies, create or update it.
             if (!empty($iter['rx']) && !$del && ($somechange || empty($rxid))) {
                 // If an active rx already exists for this drug and date we will
                 // replace it, otherwise we'll make a new one.
                 if (empty($rxid)) {
                     $rxid = '';
                 }
                 // Get default drug attributes; prefer the template with the matching selector.
                 $drow = sqlQuery("SELECT dt.*, " . "d.name, d.form, d.size, d.unit, d.route, d.substitute " . "FROM drugs AS d, drug_templates AS dt WHERE " . "d.drug_id = ? AND dt.drug_id = d.drug_id " . "ORDER BY (dt.selector = ?) DESC, dt.quantity, dt.dosage, dt.selector LIMIT 1", array($drug_id, $selector));
                 if (!empty($drow)) {
                     $rxobj = new Prescription($rxid);
                     $rxobj->set_patient_id($this->pid);
                     $rxobj->set_provider_id(isset($main_provid) ? $main_provid : $this->provider_id);
                     $rxobj->set_drug_id($drug_id);
                     $rxobj->set_quantity($units);
                     $rxobj->set_per_refill($units);
                     $rxobj->set_start_date_y(substr($this->visit_date, 0, 4));
                     $rxobj->set_start_date_m(substr($this->visit_date, 5, 2));
                     $rxobj->set_start_date_d(substr($this->visit_date, 8, 2));
                     $rxobj->set_date_added($this->visit_date);
                     // Remaining attributes are the drug and template defaults.
                     $rxobj->set_drug($drow['name']);
                     $rxobj->set_unit($drow['unit']);
                     $rxobj->set_dosage($drow['dosage']);
                     $rxobj->set_form($drow['form']);
                     $rxobj->set_refills($drow['refills']);
                     $rxobj->set_size($drow['size']);
                     $rxobj->set_route($drow['route']);
                     $rxobj->set_interval($drow['period']);
                     $rxobj->set_substitute($drow['substitute']);
                     //
                     $rxobj->persist();
                     // Set drug_sales.prescription_id to $rxobj->get_id().
                     $oldrxid = $rxid;
                     $rxid = 0 + $rxobj->get_id();
                     if ($rxid != $oldrxid) {
                         sqlStatement("UPDATE drug_sales SET prescription_id = ? WHERE sale_id = ?", array($rxid, $sale_id));
                     }
                 }
             }
         }
     }
     // end for
     // Set default and/or supervising provider for the encounter.
     if (isset($main_provid) && $main_provid != $this->provider_id) {
         $this->logFSMessage(xl('Default provider changed'));
         sqlStatement("UPDATE form_encounter SET provider_id = ? WHERE pid = ? AND encounter = ?", array($main_provid, $this->pid, $this->encounter));
         $this->provider_id = $main_provid;
     }
     if (isset($main_supid) && $main_supid != $this->supervisor_id) {
         sqlStatement("UPDATE form_encounter SET supervisor_id = ? WHERE pid = ? AND encounter = ?", array($main_supid, $this->pid, $this->encounter));
         $this->supervisor_id = $main_supid;
     }
     // Save-and-Close is currently specific to Family Planning but might be more
     // generally useful.  It provides the ability to mark an encounter as billed
     // directly from the Fee Sheet, if there are no charges.
     if ($mark_as_closed) {
         $tmp1 = sqlQuery("SELECT SUM(ABS(fee)) AS sum FROM drug_sales WHERE " . "pid = ? AND encounter = ? AND billed = 0", array($this->pid, $this->encounter));
         $tmp2 = sqlQuery("SELECT SUM(ABS(fee)) AS sum FROM billing WHERE " . "pid = ? AND encounter = ? AND billed = 0 AND activity = 1", array($this->pid, $this->encounter));
         if ($tmp1['sum'] + $tmp2['sum'] == 0) {
             sqlStatement("update drug_sales SET billed = 1 WHERE " . "pid = ? AND encounter = ? AND billed = 0", array($this->pid, $this->encounter));
             sqlStatement("UPDATE billing SET billed = 1, bill_date = NOW() WHERE " . "pid = ? AND encounter = ? AND billed = 0 AND activity = 1", array($this->pid, $this->encounter));
         } else {
             // Would be good to display an error message here... they clicked
             // Save and Close but the close could not be done.  However the
             // framework does not provide an easy way to do that.
         }
     }
 }
示例#4
0
function arPostAdjustment($patient_id, $encounter_id, $session_id, $amount, $code, $payer_type, $reason, $debug, $time = '', $codetype = '')
{
    $codeonly = $code;
    $modifier = '';
    $tmp = strpos($code, ':');
    if ($tmp) {
        $codeonly = substr($code, 0, $tmp);
        $modifier = substr($code, $tmp + 1);
    }
    if (empty($time)) {
        $time = date('Y-m-d H:i:s');
    }
    sqlBeginTrans();
    $sequence_no = sqlQuery("SELECT IFNULL(MAX(sequence_no),0) + 1 AS increment FROM ar_activity WHERE pid = ? AND encounter = ?", array($patient_id, $encounter_id));
    $query = "INSERT INTO ar_activity ( " . "pid, encounter, sequence_no, code_type, code, modifier, payer_type, post_user, post_time, " . "session_id, memo, adj_amount " . ") VALUES ( " . "'{$patient_id}', " . "'{$encounter_id}', " . "'{$sequence_no['increment']}', " . "'{$codetype}', " . "'{$codeonly}', " . "'{$modifier}', " . "'{$payer_type}', " . "'" . $_SESSION['authUserID'] . "', " . "'{$time}', " . "'{$session_id}', " . "'{$reason}', " . "'{$amount}' " . ")";
    sqlStatement($query);
    sqlCommitTrans();
    return;
}
示例#5
0
function DistributionInsert($CountRow,$created_time,$user_id)
 {//Function inserts the distribution.Payment,Adjustment,Deductible,Takeback & Follow up reasons are inserted as seperate rows.
 //It automatically pushes to next insurance for billing.
 //In the screen a drop down of Ins1,Ins2,Ins3,Pat are given.The posting can be done for any level.
	$Affected='no';
  if (isset($_POST["Payment$CountRow"]) && $_POST["Payment$CountRow"]*1>0)
   {
		if(trim(formData('type_name'   ))=='insurance')
		 {
		  if(trim(formData("HiddenIns$CountRow"   ))==1)
		   {
			  $AccountCode="IPP";
		   }
		  if(trim(formData("HiddenIns$CountRow"   ))==2)
		   {
			  $AccountCode="ISP";
		   }
		  if(trim(formData("HiddenIns$CountRow"   ))==3)
		   {
			  $AccountCode="ITP";
		   }
		 }
		elseif(trim(formData('type_name'   ))=='patient')
		 {
		  $AccountCode="PP";
		 }

	  sqlBeginTrans();
	  $sequence_no = sqlQuery( "SELECT IFNULL(MAX(sequence_no),0) + 1 AS increment FROM ar_activity WHERE pid = ? AND encounter = ?", array(trim(formData('hidden_patient_code' )), trim(formData("HiddenEncounter$CountRow"   ))));
	  sqlStatement("insert into ar_activity set "    .
		"pid = '"       . trim(formData('hidden_patient_code' )) .
		"', encounter = '"     . trim(formData("HiddenEncounter$CountRow"   ))  .
		"', sequence_no = '" . $sequence_no['increment'] .
                "', code_type = '"      . trim(formData("HiddenCodetype$CountRow"   ))  .
		"', code = '"      . trim(formData("HiddenCode$CountRow"   ))  .
		"', modifier = '"      . trim(formData("HiddenModifier$CountRow"   ))  .
		"', payer_type = '"   . trim(formData("HiddenIns$CountRow"   )) .
		"', post_time = '"  . trim($created_time					) .
		"', post_user = '******', session_id = '"    . trim(formData('payment_id')) .
		"', modified_time = '"  . trim($created_time					) .
		"', pay_amount = '" . trim(formData("Payment$CountRow"   ))  .
		"', adj_amount = '"    . 0 .
		"', account_code = '" . "$AccountCode"  .
		"'");
	  sqlCommitTrans();
	  $Affected='yes';
   }
  if (isset($_POST["AdjAmount$CountRow"]) && $_POST["AdjAmount$CountRow"]*1!=0)
   {
		if(trim(formData('type_name'   ))=='insurance')
		 {
		  $AdjustString="Ins adjust Ins".trim(formData("HiddenIns$CountRow"   ));
		  $AccountCode="IA";
		 }
		elseif(trim(formData('type_name'   ))=='patient')
		 {
		  $AdjustString="Pt adjust";
		  $AccountCode="PA";
		 }

	  sqlBeginTrans();
	  $sequence_no = sqlQuery( "SELECT IFNULL(MAX(sequence_no),0) + 1 AS increment FROM ar_activity WHERE pid = ? AND encounter = ?", array(trim(formData('hidden_patient_code' )), trim(formData("HiddenEncounter$CountRow"   ))));
	  sqlInsert("insert into ar_activity set "    .
		"pid = '"       . trim(formData('hidden_patient_code' )) .
		"', encounter = '"     . trim(formData("HiddenEncounter$CountRow"   ))  .
		"', sequence_no = '"     . $sequence_no['increment']  .
                "', code_type = '"      . trim(formData("HiddenCodetype$CountRow"   ))  .
		"', code = '"      . trim(formData("HiddenCode$CountRow"   ))  .
		"', modifier = '"      . trim(formData("HiddenModifier$CountRow"   ))  .
		"', payer_type = '"   . trim(formData("HiddenIns$CountRow"   )) .
		"', post_time = '"  . trim($created_time					) .
		"', post_user = '******', session_id = '"    . trim(formData('payment_id')) .
		"', modified_time = '"  . trim($created_time					) .
		"', pay_amount = '" . 0  .
		"', adj_amount = '"    . trim(formData("AdjAmount$CountRow"   )) .
		"', memo = '" . "$AdjustString"  .
		"', account_code = '" . "$AccountCode"  .
		"'");
	   sqlCommitTrans();
	  $Affected='yes';
   }
  if (isset($_POST["Deductible$CountRow"]) && $_POST["Deductible$CountRow"]*1>0)
   {
	   sqlBeginTrans();
	   $sequence_no = sqlQuery( "SELECT IFNULL(MAX(sequence_no),0) + 1 AS increment FROM ar_activity WHERE pid = ? AND encounter = ?", array(trim(formData('hidden_patient_code' )), trim(formData("HiddenEncounter$CountRow"   ))));
	   sqlInsert("insert into ar_activity set "    .
		"pid = '"       . trim(formData('hidden_patient_code' )) .
		"', encounter = '"     . trim(formData("HiddenEncounter$CountRow"   ))  .
		"', sequence_no = '"     . $sequence_no['increment']  .
                "', code_type = '"      . trim(formData("HiddenCodetype$CountRow"   ))  .
		"', code = '"      . trim(formData("HiddenCode$CountRow"   ))  .
		"', modifier = '"      . trim(formData("HiddenModifier$CountRow"   ))  .
		"', payer_type = '"   . trim(formData("HiddenIns$CountRow"   )) .
		"', post_time = '"  . trim($created_time					) .
		"', post_user = '******', session_id = '"    . trim(formData('payment_id')) .
		"', modified_time = '"  . trim($created_time					) .
		"', pay_amount = '" . 0  .
		"', adj_amount = '"    . 0 .
		"', memo = '"    . "Deductible $".trim(formData("Deductible$CountRow"   )) .
		"', account_code = '" . "Deduct"  .
		"'");
	   sqlCommitTrans();
	  $Affected='yes';
   }
  if (isset($_POST["Takeback$CountRow"]) && $_POST["Takeback$CountRow"]*1>0)
   {
	   sqlBeginTrans();
	   $sequence_no = sqlQuery( "SELECT IFNULL(MAX(sequence_no),0) + 1 AS increment FROM ar_activity WHERE pid = ? AND encounter = ?", array(trim(formData('hidden_patient_code' )), trim(formData("HiddenEncounter$CountRow"   ))));
	   sqlInsert("insert into ar_activity set "    .
		"pid = '"       . trim(formData('hidden_patient_code' )) .
		"', encounter = '"     . trim(formData("HiddenEncounter$CountRow"   ))  .
		"', sequence_no = '"     . $sequence_no['increment']  .
                "', code_type = '"      . trim(formData("HiddenCodetype$CountRow"   ))  .
		"', code = '"      . trim(formData("HiddenCode$CountRow"   ))  .
		"', modifier = '"      . trim(formData("HiddenModifier$CountRow"   ))  .
		"', payer_type = '"   . trim(formData("HiddenIns$CountRow"   )) .
		"', post_time = '"  . trim($created_time					) .
		"', post_user = '******', session_id = '"    . trim(formData('payment_id')) .
		"', modified_time = '"  . trim($created_time					) .
		"', pay_amount = '" . trim(formData("Takeback$CountRow"   ))*-1  .
		"', adj_amount = '"    . 0 .
		"', account_code = '" . "Takeback"  .
		"'");
	   sqlCommitTrans();
	  $Affected='yes';
   }
  if (isset($_POST["FollowUp$CountRow"]) && $_POST["FollowUp$CountRow"]=='y')
   {
	   sqlBeginTrans();
	   $sequence_no = sqlQuery( "SELECT IFNULL(MAX(sequence_no),0) + 1 AS increment FROM ar_activity WHERE pid = ? AND encounter = ?", array(trim(formData('hidden_patient_code' )), trim(formData("HiddenEncounter$CountRow"   ))));
	   sqlInsert("insert into ar_activity set "    .
		"pid = '"       . trim(formData('hidden_patient_code' )) .
		"', encounter = '"     . trim(formData("HiddenEncounter$CountRow"   ))  .
		"', sequence_no = '"     . $sequence_no['increment']  .
                "', code_type = '"      . trim(formData("HiddenCodetype$CountRow"   ))  .
		"', code = '"      . trim(formData("HiddenCode$CountRow"   ))  .
		"', modifier = '"      . trim(formData("HiddenModifier$CountRow"   ))  .
		"', payer_type = '"   . trim(formData("HiddenIns$CountRow"   )) .
		"', post_time = '"  . trim($created_time					) .
		"', post_user = '******', session_id = '"    . trim(formData('payment_id')) .
		"', modified_time = '"  . trim($created_time					) .
		"', pay_amount = '" . 0  .
		"', adj_amount = '"    . 0 .
		"', follow_up = '"    . "y" .
		"', follow_up_note = '"    . trim(formData("FollowUpReason$CountRow"   )) .
		"'");
	   sqlCommitTrans();
	  $Affected='yes';
   }
  if($Affected=='yes')
   {
	if(trim(formData('type_name'   ))!='patient')
	 {
		$ferow = sqlQuery("select last_level_closed from form_encounter  where
		pid ='".trim(formData('hidden_patient_code' ))."' and encounter='".trim(formData("HiddenEncounter$CountRow" ))."'");
		//multiple charges can come.
		if($ferow['last_level_closed']<trim(formData("HiddenIns$CountRow"   )))
		 {
			sqlStatement("update form_encounter set last_level_closed='".trim(formData("HiddenIns$CountRow"   ))."' where
			pid ='".trim(formData('hidden_patient_code' ))."' and encounter='".trim(formData("HiddenEncounter$CountRow" ))."'");
			//last_level_closed gets increased.
			//-----------------------------------
			// Determine the next insurance level to be billed.
			$ferow = sqlQuery("SELECT date, last_level_closed " .
			  "FROM form_encounter WHERE " .
			  "pid = '".trim(formData('hidden_patient_code' ))."' AND encounter = '".trim(formData("HiddenEncounter$CountRow" ))."'");
			$date_of_service = substr($ferow['date'], 0, 10);
			$new_payer_type = 0 + $ferow['last_level_closed'];
			if ($new_payer_type <= 3 && !empty($ferow['last_level_closed']) || $new_payer_type == 0)
			  ++$new_payer_type;
			$new_payer_id = arGetPayerID(trim(formData('hidden_patient_code' )), $date_of_service, $new_payer_type);
			if($new_payer_id>0)
			 {
			arSetupSecondary(trim(formData('hidden_patient_code' )), trim(formData("HiddenEncounter$CountRow" )),0);
			 }
			//-----------------------------------
		 }
	 }
   }
}