Compact css tweak
[openemr.git] / interface / patient_file / deleter.php
blob7ee601d8ef07b2d532887d659652497b97b0c83e
1 <?php
2 /**
3 * delete tool, for logging and removing patient data.
5 * Called from many different pages.
7 * Copyright (C) 2005-2016 Rod Roark <rod@sunsetsystems.com>
8 * Copyright (C) 2015 Roberto Vasquez <robertogagliotta@gmail.com>
10 * LICENSE: This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://opensource.org/licenses/gpl-license.php>;.
21 * @package OpenEMR
22 * @author Rod Roark <rod@sunsetsystems.com>
23 * @author Roberto Vasquez <robertogagliotta@gmail.com>
24 * @link http://www.open-emr.org
27 use OpenEMR\Core\Header;
29 require_once('../globals.php');
30 require_once($GLOBALS['srcdir'].'/log.inc');
31 require_once($GLOBALS['srcdir'].'/acl.inc');
32 require_once($GLOBALS['srcdir'].'/sl_eob.inc.php');
34 $patient = $_REQUEST['patient'];
35 $encounterid = $_REQUEST['encounterid'];
36 $formid = $_REQUEST['formid'];
37 $issue = $_REQUEST['issue'];
38 $document = $_REQUEST['document'];
39 $payment = $_REQUEST['payment'];
40 $billing = $_REQUEST['billing'];
41 $transaction = $_REQUEST['transaction'];
43 $info_msg = "";
45 // Delete rows, with logging, for the specified table using the
46 // specified WHERE clause.
48 function row_delete($table, $where)
50 $tres = sqlStatement("SELECT * FROM $table WHERE $where");
51 $count = 0;
52 while ($trow = sqlFetchArray($tres)) {
53 $logstring = "";
54 foreach ($trow as $key => $value) {
55 if (! $value || $value == '0000-00-00 00:00:00') {
56 continue;
59 if ($logstring) {
60 $logstring .= " ";
63 $logstring .= $key . "= '" . $value . "' ";
66 newEvent("delete", $_SESSION['authUser'], $_SESSION['authProvider'], 1, "$table: $logstring");
67 ++$count;
70 if ($count) {
71 $query = "DELETE FROM $table WHERE $where";
72 if (!$GLOBALS['sql_string_no_show_screen']) {
73 echo text($query) . "<br>\n";
76 sqlStatement($query);
80 // Deactivate rows, with logging, for the specified table using the
81 // specified SET and WHERE clauses.
83 function row_modify($table, $set, $where)
85 if (sqlQuery("SELECT * FROM $table WHERE $where")) {
86 newEvent("deactivate", $_SESSION['authUser'], $_SESSION['authProvider'], 1, "$table: $where");
87 $query = "UPDATE $table SET $set WHERE $where";
88 if (!$GLOBALS['sql_string_no_show_screen']) {
89 echo text($query) . "<br>\n";
92 sqlStatement($query);
96 // We use this to put dashes, colons, etc. back into a timestamp.
98 function decorateString($fmt, $str)
100 $res = '';
101 while ($fmt) {
102 $fc = substr($fmt, 0, 1);
103 $fmt = substr($fmt, 1);
104 if ($fc == '.') {
105 $res .= substr($str, 0, 1);
106 $str = substr($str, 1);
107 } else {
108 $res .= $fc;
112 return $res;
115 // Delete and undo product sales for a given patient or visit.
116 // This is special because it has to replace the inventory.
118 function delete_drug_sales($patient_id, $encounter_id = 0)
120 $where = $encounter_id ? "ds.encounter = '" . add_escape_custom($encounter_id) . "'" :
121 "ds.pid = '" . add_escape_custom($patient_id) . "' AND ds.encounter != 0";
122 sqlStatement("UPDATE drug_sales AS ds, drug_inventory AS di " .
123 "SET di.on_hand = di.on_hand + ds.quantity " .
124 "WHERE $where AND di.inventory_id = ds.inventory_id");
125 if ($encounter_id) {
126 row_delete("drug_sales", "encounter = '" . add_escape_custom($encounter_id) . "'");
127 } else {
128 row_delete("drug_sales", "pid = '" . add_escape_custom($patient_id) . "'");
132 // Delete a form's data that is specific to that form.
134 function form_delete($formdir, $formid, $patient_id, $encounter_id)
136 $formdir = ($formdir == 'newpatient') ? 'encounter' : $formdir;
137 $formdir = ($formdir == 'newGroupEncounter') ? 'groups_encounter' : $formdir;
138 if (substr($formdir, 0, 3) == 'LBF') {
139 row_delete("lbf_data", "form_id = '" . add_escape_custom($formid) . "'");
140 // Delete the visit's "source=visit" attributes that are not used by any other form.
141 $where = "pid = '" . add_escape_custom($patient_id) . "' AND encounter = '" .
142 add_escape_custom($encounter_id) . "' AND field_id NOT IN (" .
143 "SELECT lo.field_id FROM forms AS f, layout_options AS lo WHERE " .
144 "f.pid = '" . add_escape_custom($patient_id) . "' AND f.encounter = '" .
145 add_escape_custom($encounter_id) . "' AND f.formdir LIKE 'LBF%' AND " .
146 "f.deleted = 0 AND f.form_id != '" . add_escape_custom($formid) . "' AND " .
147 "lo.form_id = f.formdir AND lo.source = 'E' AND lo.uor > 0)";
148 // echo "<!-- $where -->\n"; // debugging
149 row_delete("shared_attributes", $where);
150 } else if ($formdir == 'procedure_order') {
151 $tres = sqlStatement("SELECT procedure_report_id FROM procedure_report " .
152 "WHERE procedure_order_id = ?", array($formid));
153 while ($trow = sqlFetchArray($tres)) {
154 $reportid = 0 + $trow['procedure_report_id'];
155 row_delete("procedure_result", "procedure_report_id = '" . add_escape_custom($reportid) . "'");
158 row_delete("procedure_report", "procedure_order_id = '" . add_escape_custom($formid) . "'");
159 row_delete("procedure_order_code", "procedure_order_id = '" . add_escape_custom($formid) . "'");
160 row_delete("procedure_order", "procedure_order_id = '" . add_escape_custom($formid) . "'");
161 } else if ($formdir == 'physical_exam') {
162 row_delete("form_$formdir", "forms_id = '" . add_escape_custom($formid) . "'");
163 } else if ($formdir == 'eye_mag') {
164 $tables = array('form_eye_base','form_eye_hpi','form_eye_ros','form_eye_vitals',
165 'form_eye_acuity','form_eye_refraction','form_eye_biometrics',
166 'form_eye_external', 'form_eye_antseg','form_eye_postseg',
167 'form_eye_neuro','form_eye_locking','form_eye_mag_orders');
168 foreach ($tables as $table_name) {
169 row_delete($table_name, "id = '" . add_escape_custom($formid) . "'");
171 row_delete("form_eye_mag_impplan", "form_id = '" . add_escape_custom($formid) . "'");
172 row_delete("form_eye_mag_wearing", "FORM_ID = '" . add_escape_custom($formid) . "'");
173 } else {
174 row_delete("form_$formdir", "id = '" . add_escape_custom($formid) . "'");
178 // Delete a specified document including its associated relations and file.
180 function delete_document($document)
182 $trow = sqlQuery("SELECT url, thumb_url, storagemethod, couch_docid, couch_revid FROM documents WHERE id = ?", array($document));
183 $url = $trow['url'];
184 $thumb_url = $trow['thumb_url'];
185 row_delete("categories_to_documents", "document_id = '" . add_escape_custom($document) . "'");
186 row_delete("documents", "id = '" . add_escape_custom($document) . "'");
187 row_delete("gprelations", "type1 = 1 AND id1 = '" . add_escape_custom($document) . "'");
189 switch ((int)$trow['storagemethod']) {
190 //for hard disk store
191 case 0:
192 @unlink(substr($url, 7));
194 if (!is_null($thumb_url)) {
195 @unlink(substr($thumb_url, 7));
197 break;
198 //for CouchDB store
199 case 1:
200 $couchDB = new CouchDB();
201 $couchDB->DeleteDoc($GLOBALS['couchdb_dbase'], $trow['couch_docid'], $trow['couch_revid']);
202 break;
206 <html>
207 <head>
208 <?php Header::setupHeader('opener'); ?>
209 <title><?php echo xlt('Delete Patient, Encounter, Form, Issue, Document, Payment, Billing or Transaction'); ?></title>
211 <script language="javascript">
212 function submit_form()
214 document.deletefrm.submit();
216 // Java script function for closing the popup
217 function popup_close() {
218 dlgclose();
220 </script>
221 </head>
223 <body class="body_top">
224 <?php
225 // If the delete is confirmed...
227 if ($_POST['form_submit']) {
228 if ($patient) {
229 if (!acl_check('admin', 'super') || !$GLOBALS['allow_pat_delete']) {
230 die("Not authorized!");
233 row_modify("billing", "activity = 0", "pid = '" . add_escape_custom($patient) . "'");
234 row_modify("pnotes", "deleted = 1", "pid = '" . add_escape_custom($patient) . "'");
235 // row_modify("prescriptions" , "active = 0" , "patient_id = '$patient'");
236 row_delete("prescriptions", "patient_id = '" . add_escape_custom($patient) . "'");
237 row_delete("claims", "patient_id = '" . add_escape_custom($patient) . "'");
238 delete_drug_sales($patient);
239 row_delete("payments", "pid = '" . add_escape_custom($patient) . "'");
240 row_delete("ar_activity", "pid = '" . add_escape_custom($patient) . "'");
241 row_delete("openemr_postcalendar_events", "pc_pid = '" . add_escape_custom($patient) . "'");
242 row_delete("immunizations", "patient_id = '" . add_escape_custom($patient) . "'");
243 row_delete("issue_encounter", "pid = '" . add_escape_custom($patient) . "'");
244 row_delete("lists", "pid = '" . add_escape_custom($patient) . "'");
245 row_delete("transactions", "pid = '" . add_escape_custom($patient) . "'");
246 row_delete("employer_data", "pid = '" . add_escape_custom($patient) . "'");
247 row_delete("history_data", "pid = '" . add_escape_custom($patient) . "'");
248 row_delete("insurance_data", "pid = '" . add_escape_custom($patient) . "'");
250 $res = sqlStatement("SELECT * FROM forms WHERE pid = ?", array($patient));
251 while ($row = sqlFetchArray($res)) {
252 form_delete($row['formdir'], $row['form_id'], $row['pid'], $row['encounter']);
255 row_delete("forms", "pid = '" . add_escape_custom($patient) . "'");
257 // Delete all documents for the patient.
258 $res = sqlStatement("SELECT id FROM documents WHERE foreign_id = ?", array($patient));
259 while ($row = sqlFetchArray($res)) {
260 delete_document($row['id']);
263 row_delete("patient_data", "pid = '" . add_escape_custom($patient) . "'");
264 } else if ($encounterid) {
265 if (!acl_check('admin', 'super')) {
266 die("Not authorized!");
269 row_modify("billing", "activity = 0", "encounter = '" . add_escape_custom($encounterid) . "'");
270 delete_drug_sales(0, $encounterid);
271 row_delete("ar_activity", "encounter = '" . add_escape_custom($encounterid) . "'");
272 row_delete("claims", "encounter_id = '" . add_escape_custom($encounterid) . "'");
273 row_delete("issue_encounter", "encounter = '" . add_escape_custom($encounterid) . "'");
274 $res = sqlStatement("SELECT * FROM forms WHERE encounter = ?", array($encounterid));
275 while ($row = sqlFetchArray($res)) {
276 form_delete($row['formdir'], $row['form_id'], $row['pid'], $row['encounter']);
279 row_delete("forms", "encounter = '" . add_escape_custom($encounterid) . "'");
280 } else if ($formid) {
281 if (!acl_check('admin', 'super')) {
282 die("Not authorized!");
285 $row = sqlQuery("SELECT * FROM forms WHERE id = ?", array($formid));
286 $formdir = $row['formdir'];
287 if (! $formdir) {
288 die("There is no form with id '" . text($formid) . "'");
290 form_delete($formdir, $row['form_id'], $row['pid'], $row['encounter']);
291 row_delete("forms", "id = '" . add_escape_custom($formid) . "'");
292 } else if ($issue) {
293 if (!acl_check('admin', 'super')) {
294 die("Not authorized!");
297 row_delete("issue_encounter", "list_id = '" . add_escape_custom($issue) ."'");
298 row_delete("lists", "id = '" . add_escape_custom($issue) ."'");
299 } else if ($document) {
300 if (!acl_check('patients', 'docs_rm')) {
301 die("Not authorized!");
304 delete_document($document);
305 } else if ($payment) {
306 if (!acl_check('admin', 'super')) {
307 die("Not authorized!");
310 list($patient_id, $timestamp, $ref_id) = explode(".", $payment);
311 // if (empty($ref_id)) $ref_id = -1;
312 $timestamp = decorateString('....-..-.. ..:..:..', $timestamp);
313 $payres = sqlStatement("SELECT * FROM payments WHERE " .
314 "pid = ? AND dtime = ?", array($patient_id, $timestamp));
315 while ($payrow = sqlFetchArray($payres)) {
316 if ($payrow['encounter']) {
317 $ref_id = -1;
318 // The session ID passed in is useless. Look for the most recent
319 // patient payment session with pay total matching pay amount and with
320 // no adjustments. The resulting session ID may be 0 (no session) which
321 // is why we start with -1.
322 $tpmt = $payrow['amount1'] + $payrow['amount2'];
323 $seres = sqlStatement("SELECT " .
324 "SUM(pay_amount) AS pay_amount, session_id " .
325 "FROM ar_activity WHERE " .
326 "pid = ? AND " .
327 "encounter = ? AND " .
328 "payer_type = 0 AND " .
329 "adj_amount = 0.00 " .
330 "GROUP BY session_id ORDER BY session_id DESC", array($patient_id, $payrow['encounter']));
331 while ($serow = sqlFetchArray($seres)) {
332 if (sprintf("%01.2f", $serow['adj_amount']) != 0.00) {
333 continue;
336 if (sprintf("%01.2f", $serow['pay_amount'] - $tpmt) == 0.00) {
337 $ref_id = $serow['session_id'];
338 break;
342 if ($ref_id == -1) {
343 die(xlt('Unable to match this payment in ar_activity') . ": " . text($tpmt));
346 // Delete the payment.
347 row_delete(
348 "ar_activity",
349 "pid = '" . add_escape_custom($patient_id) . "' AND " .
350 "encounter = '" . add_escape_custom($payrow['encounter']) . "' AND " .
351 "payer_type = 0 AND " .
352 "pay_amount != 0.00 AND " .
353 "adj_amount = 0.00 AND " .
354 "session_id = '" . add_escape_custom($ref_id) . "'"
356 if ($ref_id) {
357 row_delete(
358 "ar_session",
359 "patient_id = '" . add_escape_custom($patient_id) ."' AND " .
360 "session_id = '" . add_escape_custom($ref_id) . "'"
363 } else {
364 // Encounter is 0! Seems this happens for pre-payments.
365 $tpmt = sprintf("%01.2f", $payrow['amount1'] + $payrow['amount2']);
366 // Patched out 09/06/17- If this is prepayment can't see need for ar_activity when prepayments not stored there? In this case passed in session id is valid.
367 // Was causing delete of wrong prepayment session in the case of delete from checkout undo and/or front receipt delete if payment happens to be same
368 // amount of a previous prepayment. Much tested but look here if problems in postings.
370 /* row_delete("ar_session",
371 "patient_id = ' " . add_escape_custom($patient_id) . " ' AND " .
372 "payer_id = 0 AND " .
373 "reference = '" . add_escape_custom($payrow['source']) . "' AND " .
374 "pay_total = '" . add_escape_custom($tpmt) . "' AND " .
375 "(SELECT COUNT(*) FROM ar_activity where ar_activity.session_id = ar_session.session_id) = 0 " .
376 "ORDER BY session_id DESC LIMIT 1"); */
378 row_delete("ar_session", "session_id = '" . add_escape_custom($ref_id) . "'");
381 row_delete("payments", "id = '" . add_escape_custom($payrow['id']) . "'");
383 } else if ($billing) {
384 if (!acl_check('acct', 'disc')) {
385 die("Not authorized!");
388 list($patient_id, $encounter_id) = explode(".", $billing);
389 sqlStatement("DELETE FROM ar_activity WHERE " .
390 "pid = ? AND encounter = ? ", array($patient_id, $encounter_id));
391 sqlStatement("DELETE ar_session FROM ar_session LEFT JOIN " .
392 "ar_activity ON ar_session.session_id = ar_activity.session_id " .
393 "WHERE ar_activity.session_id IS NULL");
394 row_modify(
395 "billing",
396 "activity = 0",
397 "pid = '" . add_escape_custom($patient_id) . "' AND " .
398 "encounter = '" . add_escape_custom($encounter_id) . "' AND " .
399 "code_type = 'COPAY' AND " .
400 "activity = 1"
402 sqlStatement("UPDATE form_encounter SET last_level_billed = 0, " .
403 "last_level_closed = 0, stmt_count = 0, last_stmt_date = NULL " .
404 "WHERE pid = ? AND encounter = ?", array($patient_id, $encounter_id));
405 sqlStatement("UPDATE drug_sales SET billed = 0 WHERE " .
406 "pid = ? AND encounter = ?", array($patient_id, $encounter_id));
407 updateClaim(true, $patient_id, $encounter_id, -1, -1, 1, 0, ''); // clears for rebilling
408 } else if ($transaction) {
409 if (!acl_check('admin', 'super')) {
410 die("Not authorized!");
413 row_delete("transactions", "id = '" . add_escape_custom($transaction) . "'");
414 } else {
415 die("Nothing was recognized to delete!");
418 if (! $info_msg) {
419 $info_msg = xl('Delete successful.');
422 // Close this window and tell our opener that it's done.
423 // Not sure yet if the callback can be used universally.
424 echo "<script language='JavaScript'>\n";
425 if (!$encounterid) {
426 if ($info_msg) {
427 echo " alert('" . addslashes($info_msg) . "');\n";
429 echo " dlgclose('imdeleted',false);\n";
430 } else {
431 if ($GLOBALS['sql_string_no_show_screen']) {
432 echo " dlgclose('imdeleted', $encounterid);\n";
433 } else { // this allows dialog to stay open then close with button or X.
434 echo " opener.dlgSetCallBack('imdeleted', $encounterid);\n";
437 echo "</script></body></html>\n";
438 exit();
442 <form method='post' name="deletefrm" action='deleter.php?patient=<?php echo attr($patient) ?>&encounterid=<?php echo attr($encounterid) ?>&formid=<?php echo attr($formid) ?>&issue=<?php echo attr($issue) ?>&document=<?php echo attr($document) ?>&payment=<?php echo attr($payment) ?>&billing=<?php echo attr($billing) ?>&transaction=<?php echo attr($transaction) ?>' onsubmit="javascript:alert('1');document.deleform.submit();">
444 <p class="lead">&nbsp;<br><?php echo xlt('Do you really want to delete'); ?>
446 <?php
447 if ($patient) {
448 echo xlt('patient') . " " . text($patient);
449 } else if ($encounterid) {
450 echo xlt('encounter') . " " . text($encounterid);
451 } else if ($formid) {
452 echo xlt('form') . " " . text($formid);
453 } else if ($issue) {
454 echo xlt('issue') . " " .text($issue);
455 } else if ($document) {
456 echo xlt('document') . " " . text($document);
457 } else if ($payment) {
458 echo xlt('payment') . " " .text($payment);
459 } else if ($billing) {
460 echo xlt('invoice') . " " . text($billing);
461 } else if ($transaction) {
462 echo xlt('transaction') . " " . text($transaction);
464 ?> <?php echo xlt('and all subordinate data? This action will be logged'); ?>!</p>
465 <div class="btn-group">
466 <a href="#" onclick="submit_form()" class="btn btn-lg btn-save btn-default"><?php echo xlt('Yes, Delete and Log'); ?></a>
467 <a href='#' class="btn btn-lg btn-link btn-cancel" onclick="popup_close();"><?php echo xlt('No, Cancel');?></a>
468 </div>
469 <input type='hidden' name='form_submit' value='<?php echo xla('Yes, Delete and Log'); ?>'/>
470 </form>
471 </body>
472 </html>