2 // Copyright (C) 2006-2010 Rod Roark <rod@sunsetsystems.com>
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (at your option) any later version.
9 require_once("../globals.php");
10 require_once("$srcdir/acl.inc");
11 require_once("$srcdir/patient.inc");
12 require_once("$srcdir/forms.inc");
13 require_once("$srcdir/sl_eob.inc.php");
14 require_once("$srcdir/invoice_summary.inc.php");
15 require_once("../../custom/code_types.inc.php");
16 require_once("$srcdir/formatting.inc.php");
18 $INTEGRATED_AR = $GLOBALS['oer_config']['ws_accounting']['enabled'] === 2;
22 <?php
html_header_show();?
>
23 <link rel
='stylesheet' href
='<?php echo $css_header ?>' type
='text/css'>
26 // Format dollars for display.
28 function bucks($amount) {
30 $amount = oeFormatMoney($amount);
36 function rawbucks($amount) {
38 $amount = sprintf("%.2f", $amount);
44 // Get the co-pay amount that is effective on the given date.
45 // Or if no insurance on that date, return -1.
47 function getCopay($patient_id, $encdate) {
48 $tmp = sqlQuery("SELECT provider, copay FROM insurance_data " .
49 "WHERE pid = '$patient_id' AND type = 'primary' " .
50 "AND date <= '$encdate' ORDER BY date DESC LIMIT 1");
51 if ($tmp['provider']) return sprintf('%01.2f', 0 +
$tmp['copay']);
55 // Display a row of data for an encounter.
57 function echoLine($iname, $date, $charges, $ptpaid, $inspaid, $duept) {
58 $balance = bucks($charges - $ptpaid - $inspaid);
59 $getfrompt = ($duept > 0) ?
$duept : 0;
61 echo " <td class='detail'>" . oeFormatShortDate($date) . "</td>\n";
62 echo " <td class='detail' align='right'>" . bucks($charges) . "</td>\n";
63 echo " <td class='detail' align='right'>" . bucks($ptpaid) . "</td>\n";
64 echo " <td class='detail' align='right'>" . bucks($inspaid) . "</td>\n";
65 echo " <td class='detail' align='right'>$balance</td>\n";
66 echo " <td class='detail' align='right'>" . bucks($duept) . "</td>\n";
67 echo " <td class='detail' align='right'><input type='text' name='$iname' " .
68 "size='6' value='" . rawbucks($getfrompt) . "' onchange='calctotal()' " .
69 "onkeyup='calctotal()' /></td>\n";
73 // Post a payment to the payments table.
75 function frontPayment($patient_id, $encounter, $method, $source, $amount1, $amount2) {
77 $payid = sqlInsert("INSERT INTO payments ( " .
78 "pid, encounter, dtime, user, method, source, amount1, amount2 " .
83 "'" . $_SESSION['authUser'] . "', " .
92 // Get the patient's encounter ID for today, creating it if there is none.
93 // In the case of more than one encounter today, pick the last one.
95 function todaysEncounter($patient_id) {
98 $tmprow = sqlQuery("SELECT encounter FROM form_encounter WHERE " .
99 "pid = '$patient_id' AND date = '$today 00:00:00' " .
100 "ORDER BY encounter DESC LIMIT 1");
102 if (!empty($tmprow['encounter'])) return $tmprow['encounter'];
104 $tmprow = sqlQuery("SELECT username, facility, facility_id FROM users " .
105 "WHERE id = '" . $_SESSION["authUserID"] . "'");
106 $username = $tmprow['username'];
107 $facility = $tmprow['facility'];
108 $facility_id = $tmprow['facility_id'];
109 $conn = $GLOBALS['adodb']['db'];
110 $encounter = $conn->GenID("sequences");
111 addForm($encounter, "New Patient Encounter",
112 sqlInsert("INSERT INTO form_encounter SET " .
113 "date = '$today', " .
114 "onset_date = '$today', " .
115 "reason = 'Please indicate visit reason', " .
116 "facility = '$facility', " .
117 "facility_id = '$facility_id', " .
118 "pid = '$patient_id', " .
119 "encounter = '$encounter'"
121 "newpatient", $patient_id, "1", "NOW()", $username
126 // We use this to put dashes, colons, etc. back into a timestamp.
128 function decorateString($fmt, $str) {
131 $fc = substr($fmt, 0, 1);
132 $fmt = substr($fmt, 1);
134 $res .= substr($str, 0, 1);
135 $str = substr($str, 1);
143 // Compute taxes from a tax rate string and a possibly taxable amount.
145 function calcTaxes($row, $amount) {
147 if (empty($row['taxrates'])) return $total;
148 $arates = explode(':', $row['taxrates']);
149 if (empty($arates)) return $total;
150 foreach ($arates as $value) {
151 if (empty($value)) continue;
152 $trow = sqlQuery("SELECT option_value FROM list_options WHERE " .
153 "list_id = 'taxrate' AND option_id = '$value' LIMIT 1");
154 if (empty($trow['option_value'])) {
155 echo "<!-- Missing tax rate '$value'! -->\n";
158 $tax = sprintf("%01.2f", $amount * $trow['option_value']);
159 // echo "<!-- Rate = '$value', amount = '$amount', tax = '$tax' -->\n";
165 $payment_methods = array(
175 $today = date('Y-m-d', $now);
176 $timestamp = date('Y-m-d H:i:s', $now);
178 if (!$INTEGRATED_AR) slInitialize();
180 // $patdata = getPatientData($pid, 'fname,lname,pubpid');
182 $patdata = sqlQuery("SELECT " .
183 "p.fname, p.mname, p.lname, p.pubpid, i.copay " .
184 "FROM patient_data AS p " .
185 "LEFT OUTER JOIN insurance_data AS i ON " .
186 "i.pid = p.pid AND i.type = 'primary' " .
187 "WHERE p.pid = '$pid' ORDER BY i.date DESC LIMIT 1");
189 $alertmsg = ''; // anything here pops up in an alert box
191 // If the Save button was clicked...
192 if ($_POST['form_save']) {
193 $form_pid = $_POST['form_pid'];
194 $form_method = trim($_POST['form_method']);
195 $form_source = trim($_POST['form_source']);
197 // Post payments for unbilled encounters. These go into the billing table.
198 if ($_POST['form_upay']) {
199 foreach ($_POST['form_upay'] as $enc => $payment) {
200 if ($amount = 0 +
$payment) {
201 if (!$enc) $enc = todaysEncounter($form_pid);
202 addBilling($enc, 'COPAY', sprintf('%.2f', $amount),
203 $form_method, $form_pid, 1, $_SESSION["authUserID"],
204 '', 1, 0 - $amount, '', '');
205 frontPayment($form_pid, $enc, $form_method, $form_source, $amount, 0);
210 // Post payments for previously billed encounters. These go to A/R.
211 if ($_POST['form_bpay']) {
212 foreach ($_POST['form_bpay'] as $enc => $payment) {
213 if ($amount = 0 +
$payment) {
214 if ($INTEGRATED_AR) {
217 $thissrc .= $form_method;
218 if ($form_source) $thissrc .= " $form_source";
220 $session_id = 0; // Is this OK?
221 arPostPayment($form_pid, $enc, $session_id, $amount, '', 0, $thissrc, 0);
226 $thissrc .= $form_method;
227 if ($form_source) $thissrc .= " $form_source";
229 $trans_id = SLQueryValue("SELECT id FROM ar WHERE " .
230 "ar.invnumber = '$form_pid.$enc' LIMIT 1");
231 if (! $trans_id) die("Cannot find invoice '$form_pid.$enc'!");
232 slPostPayment($trans_id, $amount, date('Y-m-d'), $thissrc,
235 frontPayment($form_pid, $enc, $form_method, $form_source, 0, $amount);
243 if ($_POST['form_save'] ||
$_REQUEST['receipt']) {
245 if ($_REQUEST['receipt']) {
246 $form_pid = $_GET['patient'];
247 $timestamp = decorateString('....-..-.. ..:..:..', $_GET['time']);
250 // Get details for what we guess is the primary facility.
251 $frow = sqlQuery("SELECT * FROM facility " .
252 "ORDER BY billing_location DESC, accepts_assignment DESC, id LIMIT 1");
254 // Get the patient's name and chart number.
255 $patdata = getPatientData($form_pid, 'fname,mname,lname,pubpid');
257 // Re-fetch payment info.
258 $payrow = sqlQuery("SELECT " .
259 "SUM(amount1) AS amount1, " .
260 "SUM(amount2) AS amount2, " .
261 "MAX(method) AS method, " .
262 "MAX(source) AS source, " .
263 "MAX(dtime) AS dtime, " .
264 // "MAX(user) AS user " .
265 "MAX(user) AS user, " .
266 "MAX(encounter) as encounter ".
267 "FROM payments WHERE " .
268 "pid = '$form_pid' AND dtime = '$timestamp'");
270 // Create key for deleting, just in case.
271 $payment_key = $form_pid . '.' . preg_replace('/[^0-9]/', '', $timestamp);
273 // get facility from encounter
274 $tmprow = sqlQuery(sprintf("
277 WHERE encounter = '%s'",
280 $frow = sqlQuery(sprintf("SELECT * FROM facility " .
281 " WHERE id = '%s'",$tmprow['facility_id']));
283 // Now proceed with printing the receipt.
286 <title
><?php
xl('Receipt for Payment','e'); ?
></title
>
287 <script type
="text/javascript" src
="../../library/dialog.js"></script
>
288 <script language
="JavaScript">
290 <?php
require($GLOBALS['srcdir'] . "/restoreSession.php"); ?
>
292 // Process click on Print button.
294 var divstyle
= document
.getElementById('hideonprint').style
;
295 divstyle
.display
= 'none';
297 // divstyle.display = 'block';
299 // Process click on Delete button.
300 function deleteme() {
301 dlgopen('deleter.php?payment=<?php echo $payment_key ?>', '_blank', 500, 450);
304 // Called by the deleteme.php window on a successful delete.
305 function imdeleted() {
311 <body bgcolor
='#ffffff'>
314 <p
><h2
><?php
xl('Receipt for Payment','e'); ?
></h2
>
316 <p
><?php
echo htmlentities($frow['name']) ?
>
317 <br
><?php
echo htmlentities($frow['street']) ?
>
318 <br
><?php
echo htmlentities($frow['city'] . ', ' . $frow['state']) . ' ' .
319 $frow['postal_code'] ?
>
320 <br
><?php
echo htmlentities($frow['phone']) ?
>
323 <table border
='0' cellspacing
='8'>
325 <td
><?php
xl('Date','e'); ?
>:</td
>
326 <td
><?php
echo oeFormatSDFT(strtotime($payrow['dtime'])) ?
></td
>
329 <td
><?php
xl('Patient','e'); ?
>:</td
>
330 <td
><?php
echo $patdata['fname'] . " " . $patdata['mname'] . " " .
331 $patdata['lname'] . " (" . $patdata['pubpid'] . ")" ?
></td
>
334 <td
><?php
xl('Paid Via','e'); ?
>:</td
>
335 <td
><?php
echo $payrow['method'] ?
></td
>
338 <td
><?php
xl('Check/Ref Number','e'); ?
>:</td
>
339 <td
><?php
echo $payrow['source'] ?
></td
>
342 <td
><?php
xl('Amount for This Visit','e'); ?
>:</td
>
343 <td
><?php
echo oeFormatMoney($payrow['amount1']) ?
></td
>
346 <td
><?php
xl('Amount for Past Balance','e'); ?
>:</td
>
347 <td
><?php
echo oeFormatMoney($payrow['amount2']) ?
></td
>
350 <td
><?php
xl('Received By','e'); ?
>:</td
>
351 <td
><?php
echo $payrow['user'] ?
></td
>
355 <div id
='hideonprint'>
357 <input type
='button' value
='<?php xl('Print','e
'); ?>' onclick
='printme()' />
359 <?php
if (acl_check('admin', 'super')) { ?
>
361 <input type
='button' value
='<?php xl('Delete
','e
'); ?>' style
='color:red' onclick
='deleteme()' />
370 // End of receipt printing logic.
374 // Here we display the form for data entry.
377 <title
><?php
xl('Record Payment','e'); ?
></title
>
379 <style type
="text/css">
380 body
{ font
-family
:sans
-serif
; font
-size
:10pt
; font
-weight
:normal
}
381 .dehead
{ color
:#000000; font-family:sans-serif; font-size:10pt; font-weight:bold }
382 .detail
{ color
:#000000; font-family:sans-serif; font-size:10pt; font-weight:normal }
385 <script type
="text/javascript" src
="../../library/topdialog.js"></script
>
386 <script type
="text/javascript" src
="../../library/dialog.js"></script
>
388 <script language
="JavaScript">
389 <?php
require($GLOBALS['srcdir'] . "/restoreSession.php"); ?
>
391 function calctotal() {
392 var f
= document
.forms
[0];
394 for (var i
= 0; i
< f
.elements
.length
; ++i
) {
395 var elem
= f
.elements
[i
];
396 var ename
= elem
.name
;
397 if (ename
.indexOf('form_upay[') == 0 || ename
.indexOf('form_bpay[') == 0) {
398 if (elem
.value
.length
> 0) total +
= Number(elem
.value
);
401 f
.form_paytotal
.value
= Number(total
).toFixed(2);
409 <body
class="body_top" onunload
='imclosing()'>
411 <form method
='post' action
='front_payment.php<?php if ($payid) echo "?payid=$payid"; ?>'
412 onsubmit
='return top.restoreSession()'>
413 <input type
='hidden' name
='form_pid' value
='<?php echo $pid ?>' />
417 <table border
='0' cellspacing
='8'>
420 <td colspan
='2' align
='center'>
422 <b
><?php
xl('Accept Payment for ','e','',' '); ?
><?php
echo $patdata['fname'] . " " .
423 $patdata['lname'] . " (" . $patdata['pubpid'] . ")" ?
></b
>
430 <?php
xl('Payment Method','e'); ?
>:
433 <select name
='form_method'>
435 foreach ($payment_methods as $value) {
436 echo " <option value='$value'";
437 if ($value == $payrow['method']) echo " selected";
438 echo ">$value</option>\n";
447 <?php
xl('Check/Reference Number','e'); ?
>:
450 <input type
='text' name
='form_source' size
='10' value
='<?php echo $payrow['source
'] ?>'>
456 <table border
='0' cellpadding
='2' cellspacing
='0' width
='98%'>
457 <tr bgcolor
="#cccccc">
459 <?php
xl('DOS','e')?
>
461 <td
class="dehead" align
="right">
462 <?php
xl('Charges','e')?
>
464 <td
class="dehead" align
="right">
465 <?php
xl('Pt Paid','e')?
> 
;
467 <td
class="dehead" align
="right">
468 <?php
xl('Insurance','e')?
>
470 <td
class="dehead" align
="right">
471 <?php
xl('Balance','e')?
>
473 <td
class="dehead" align
="right">
474 <?php
xl('Due Pt','e')?
>
476 <td
class="dehead" align
="right">
477 <?php
xl('Paying','e')?
>
484 // Get the unbilled service charges and payments by encounter for this patient.
486 $query = "SELECT b.encounter, b.code_type, b.code, b.modifier, b.fee, " .
487 "LEFT(fe.date, 10) AS encdate " .
488 "FROM billing AS b, form_encounter AS fe WHERE " .
489 "b.pid = '$pid' AND b.activity = 1 AND b.billed = 0 AND " .
490 "b.code_type != 'TAX' AND b.fee != 0 " .
491 "AND fe.pid = b.pid AND fe.encounter = b.encounter " .
492 "ORDER BY b.encounter";
493 $bres = sqlStatement($query);
495 while ($brow = sqlFetchArray($bres)) {
496 $key = 0 - $brow['encounter'];
497 if (empty($encs[$key])) {
499 'encounter' => $brow['encounter'],
500 'date' => $brow['encdate'],
504 if ($brow['code_type'] === 'COPAY') {
505 $encs[$key]['payments'] -= $brow['fee'];
507 $encs[$key]['charges'] +
= $brow['fee'];
509 $query = "SELECT taxrates FROM codes WHERE " .
510 "code_type = '" . $code_types[$brow['code_type']]['id'] . "' AND " .
511 "code = '" . $brow['code'] . "' AND ";
512 if ($brow['modifier']) {
513 $query .= "modifier = '" . $brow['modifier'] . "'";
515 $query .= "(modifier IS NULL OR modifier = '')";
517 $query .= " LIMIT 1";
518 $trow = sqlQuery($query);
519 $encs[$key]['charges'] +
= calcTaxes($trow, $brow['fee']);
523 // Do the same for unbilled product sales.
525 $query = "SELECT s.encounter, s.drug_id, s.fee, " .
526 "LEFT(fe.date, 10) AS encdate " .
527 "FROM drug_sales AS s, form_encounter AS fe " .
528 "WHERE s.pid = '$pid' AND s.billed = 0 AND s.fee != 0 " .
529 "AND fe.pid = s.pid AND fe.encounter = s.encounter " .
530 "ORDER BY s.encounter";
531 $dres = sqlStatement($query);
533 while ($drow = sqlFetchArray($dres)) {
534 $key = 0 - $drow['encounter'];
535 if (empty($encs[$key])) {
537 'encounter' => $drow['encounter'],
538 'date' => $drow['encdate'],
542 $encs[$key]['charges'] +
= $drow['fee'];
544 $trow = sqlQuery("SELECT taxrates FROM drug_templates WHERE drug_id = '" .
545 $drow['drug_id'] . "' ORDER BY selector LIMIT 1");
546 $encs[$key]['charges'] +
= calcTaxes($trow, $drow['fee']);
549 ksort($encs, SORT_NUMERIC
);
551 foreach ($encs as $key => $value) {
552 $enc = $value['encounter'];
553 $dispdate = $value['date'];
554 if (strcmp($dispdate, $today) == 0 && !$gottoday) {
555 $dispdate = xl('Today');
558 $inscopay = getCopay($pid, $value['date']);
559 $balance = rawbucks($value['charges'] - $value['payments']);
560 $duept = (($inscopay >= 0) ?
$inscopay : $value['charges']) - $value['payments'];
561 echoLine("form_upay[$enc]", $dispdate, $value['charges'],
562 $value['payments'], 0, $duept);
565 // If no billing was entered yet for today, then generate a line for
566 // entering today's co-pay.
569 $inscopay = getCopay($pid, $today);
570 $duept = ($inscopay >= 0) ?
$inscopay : 0;
571 echoLine("form_upay[0]", xl('Today'), 0, 0, 0, $duept);
574 // Now list previously billed visits.
576 if ($INTEGRATED_AR) {
577 $query = "SELECT f.id, f.pid, f.encounter, f.date, " .
578 "f.last_level_billed, f.last_level_closed, f.stmt_count, " .
579 "p.fname, p.mname, p.lname, p.pubpid, p.genericname2, p.genericval2, " .
580 "( SELECT SUM(s.fee) FROM drug_sales AS s WHERE " .
581 "s.pid = f.pid AND s.encounter = f.encounter AND s.billed != 0 ) AS sales, " .
582 "( SELECT SUM(b.fee) FROM billing AS b WHERE " .
583 "b.pid = f.pid AND b.encounter = f.encounter AND " .
584 "b.activity = 1 AND b.code_type != 'COPAY' AND b.billed != 0 ) AS charges, " .
585 "( SELECT SUM(b.fee) FROM billing AS b WHERE " .
586 "b.pid = f.pid AND b.encounter = f.encounter AND " .
587 "b.activity = 1 AND b.code_type = 'COPAY' AND b.billed != 0 ) AS copays, " .
588 "( SELECT SUM(a.pay_amount) FROM ar_activity AS a WHERE " .
589 "a.pid = f.pid AND a.encounter = f.encounter AND " .
590 "a.payer_type = 0 ) AS ptpaid, " .
591 "( SELECT SUM(a.pay_amount) FROM ar_activity AS a WHERE " .
592 "a.pid = f.pid AND a.encounter = f.encounter AND " .
593 "a.payer_type != 0 ) AS inspaid, " .
594 "( SELECT SUM(a.adj_amount) FROM ar_activity AS a WHERE " .
595 "a.pid = f.pid AND a.encounter = f.encounter ) AS adjustments " .
596 "FROM form_encounter AS f " .
597 "JOIN patient_data AS p ON p.pid = f.pid " .
598 "WHERE f.pid = '$pid' " .
599 "ORDER BY f.pid, f.encounter";
601 // Note that unlike the SQL-Ledger case, this query does not weed
602 // out encounters that are paid up. Also the use of sub-selects
603 // will require MySQL 4.1 or greater.
605 $ires = sqlStatement($query);
606 $num_invoices = mysql_num_rows($ires);
608 while ($irow = sqlFetchArray($ires)) {
609 $balance = $irow['charges'] +
$irow['sales'] +
$irow['copays']
610 - $irow['ptpaid'] - $irow['inspaid'] - $irow['adjustments'];
611 if (!$balance) continue;
613 $patient_id = $irow['pid'];
614 $enc = $irow['encounter'];
615 $svcdate = substr($irow['date'], 0, 10);
616 $duncount = $irow['stmt_count'];
618 for ($i = 1; $i <= 3 && arGetPayerID($irow['pid'], $irow['date'], $i); ++
$i) ;
619 $duncount = $irow['last_level_closed'] +
1 - $i;
622 $inspaid = $irow['inspaid'] +
$irow['adjustments'];
623 $ptpaid = $irow['ptpaid'] - $irow['copays'];
624 $duept = ($duncount < 0) ?
0 : $balance;
626 echoLine("form_bpay[$enc]", $svcdate, $irow['charges'] +
$irow['sales'],
627 $ptpaid, $inspaid, $duept);
629 } // end $INTEGRATED_AR
631 // Query for all open invoices.
632 $query = "SELECT ar.id, ar.invnumber, ar.amount, ar.paid, " .
633 "ar.intnotes, ar.notes, ar.shipvia, " .
634 "(SELECT SUM(invoice.sellprice * invoice.qty) FROM invoice WHERE " .
635 "invoice.trans_id = ar.id AND invoice.sellprice > 0) AS charges, " .
636 "(SELECT SUM(invoice.sellprice * invoice.qty) FROM invoice WHERE " .
637 "invoice.trans_id = ar.id AND invoice.sellprice < 0) AS adjustments, " .
638 "(SELECT SUM(acc_trans.amount) FROM acc_trans WHERE " .
639 "acc_trans.trans_id = ar.id AND acc_trans.chart_id = $chart_id_cash " .
640 "AND acc_trans.source NOT LIKE 'Ins%') AS ptpayments " .
641 "FROM ar WHERE ar.invnumber LIKE '$pid.%' AND " .
642 "ar.amount != ar.paid " .
643 "ORDER BY ar.invnumber";
644 $ires = SLQuery($query);
645 if ($sl_err) die($sl_err);
646 $num_invoices = SLRowCount($ires);
648 for ($ix = 0; $ix < $num_invoices; ++
$ix) {
649 $irow = SLGetRow($ires, $ix);
651 // Get encounter ID and date of service.
652 list($patient_id, $enc) = explode(".", $irow['invnumber']);
653 $tmp = sqlQuery("SELECT LEFT(date, 10) AS encdate FROM form_encounter " .
654 "WHERE encounter = '$enc'");
655 $svcdate = $tmp['encdate'];
657 // Compute $duncount as in sl_eob_search.php to determine if
658 // this invoice is at patient responsibility.
659 $duncount = substr_count(strtolower($irow['intnotes']), "statement sent");
661 $insgot = strtolower($irow['notes']);
662 $inseobs = strtolower($irow['shipvia']);
663 foreach (array('ins1', 'ins2', 'ins3') as $value) {
664 if (strpos($insgot, $value) !== false &&
665 strpos($inseobs, $value) === false)
670 $inspaid = $irow['paid'] +
$irow['ptpayments'] - $irow['adjustments'];
671 $balance = $irow['amount'] - $irow['paid'];
672 $duept = ($duncount < 0) ?
0 : $balance;
674 echoLine("form_bpay[$enc]", $svcdate, $irow['charges'],
675 0 - $irow['ptpayments'], $inspaid, $duept);
677 } // end not $INTEGRATED_AR
679 // Continue with display of the data entry form.
682 <tr bgcolor
="#cccccc">
683 <td
class="dehead" colspan
="6">
684 <?php
xl('Total Amount Paid','e')?
>
686 <td
class="dehead" align
="right">
687 <input type
='text' name
='form_paytotal' size
='6' value
=''
688 style
='color:#00aa00' readonly
/>
695 <input type
='submit' name
='form_save' value
='<?php xl('Save
','e
'); ?>' />  
;
696 <input type
='button' value
='<?php xl('Cancel
','e
'); ?>' onclick
='window.close()' />
700 <script language
="JavaScript">
707 if (!$INTEGRATED_AR) SLClose();