3 // Copyright (C) 2005-2006 Rod Roark <rod@sunsetsystems.com>
5 // Windows compatibility mods 2009 Bill Cernansky [mi-squared.com]
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
12 // Updated by Medical Information Integration, LLC to support download
13 // and multi OS use - tony@mi-squared..com 12-2009
15 //////////////////////////////////////////////////////////////////////
16 // This is a template for printing patient statements and collection
17 // letters. You must customize it to suit your practice. If your
18 // needs are simple then you do not need programming experience to do
19 // this - just read the comments and make appropriate substitutions.
20 // All you really need to do is replace the [strings in brackets].
21 //////////////////////////////////////////////////////////////////////
23 // The location/name of a temporary file to hold printable statements.
26 $STMT_TEMP_FILE = $GLOBALS['temporary_files_dir'] . "/openemr_statements.txt";
27 $STMT_TEMP_FILE_PDF = $GLOBALS['temporary_files_dir'] . "/openemr_statements.pdf";
29 $STMT_PRINT_CMD = $GLOBALS['print_command'];
31 // This function builds a printable statement or collection letter from
32 // an associative array having the following keys:
34 // today = statement date yyyy-mm-dd
36 // patient = patient name
37 // amount = total amount due
38 // to = array of addressee name/address lines
39 // lines = array of lines, each with the following keys:
40 // dos = date of service yyyy-mm-dd
42 // amount = charge less adjustments
44 // notice = 1 for first notice, 2 for second, etc.
45 // detail = associative array of details
47 // Each detail array is keyed on a string beginning with a date in
48 // yyyy-mm-dd format, or blanks in the case of the original charge
49 // items. Its values are associative arrays like this:
51 // pmt - payment amount as a positive number, only for payments
52 // src - check number or other source, only for payments
53 // chg - invoice line item amount amount, only for charges or
54 // adjustments (adjustments may be zero)
55 // rsn - adjustment reason, only for adjustments
57 // The returned value is a string that can be sent to a printer.
58 // This example is plain text, but if you are a hotshot programmer
59 // then you could make a PDF or PostScript or whatever peels your
60 // banana. These strings are sent in succession, so append a form
61 // feed if that is appropriate.
64 // A sample of the text based format follows:
66 //[Your Clinic Name] Patient Name 2009-12-29
67 //[Your Clinic Address] Chart Number: 1848
68 //[City, State Zip] Insurance information on file
72 //Patient Name [Your Clinic Name]
73 //patient address [Your Clinic Address]
74 //city, state zipcode [City, State Zip]
75 // If paying by VISA/MC/AMEX/Dis
77 //Card_____________________ Exp______ Signature___________________
78 // Return above part with your payment
79 //-----------------------------------------------------------------
81 //_______________________ STATEMENT SUMMARY _______________________
83 //Visit Date Description Amount
85 //2009-08-20 Procedure 99345 198.90
86 // Paid 2009-12-15: -51.50
87 //... more details ...
90 // skipping blanks in example
93 //Name: Patient Name Date: 2009-12-29 Due: 147.40
94 //_________________________________________________________________
96 //Please call if any of the above information is incorrect
97 //We appreciate prompt payment of balances due
99 //[Your billing contact name]
100 // Billing Department
101 // [Your billing dept phone]
103 function create_statement($stmt) {
104 if (! $stmt['pid']) return ""; // get out if no data
106 // These are your clinics return address, contact etc. Edit them.
107 // TBD: read this from the facility table
109 // Facility (service location)
110 $atres = sqlStatement("select f.name,f.street,f.city,f.state,f.postal_code from facility f " .
111 " left join users u on f.id=u.facility_id " .
112 " left join billing b on b.provider_id=u.id and b.pid = '".$stmt['pid']."' " .
113 " where service_location=1");
114 $row = sqlFetchArray($atres);
116 // Facility (service location)
118 $clinic_name = "{$row['name']}";
119 $clinic_addr = "{$row['street']}";
120 $clinic_csz = "{$row['city']}, {$row['state']}, {$row['postal_code']}";
124 $remit_name = $clinic_name;
125 $remit_addr = $clinic_addr;
126 $remit_csz = $clinic_csz;
129 $atres = sqlStatement("select f.attn,f.phone from facility f " .
130 " left join users u on f.id=u.facility_id " .
131 " left join billing b on b.provider_id=u.id and b.pid = '".$stmt['pid']."' " .
132 " where billing_location=1");
133 $row = sqlFetchArray($atres);
134 $billing_contact = "{$row['attn']}";
135 $billing_phone = "{$row['phone']}";
139 $label_addressee = xl('ADDRESSEE');
140 $label_remitto = xl('REMIT TO');
141 $label_chartnum = xl('Chart Number');
142 $label_insinfo = xl('Insurance information on file');
143 $label_totaldue = xl('Total amount due');
144 $label_payby = xl('If paying by');
145 $label_cards = xl('VISA/MC/AMEX/Dis');
146 $label_cardnum = xl('Card');
147 $label_expiry = xl('Exp');
148 $label_sign = xl('Signature');
149 $label_retpay = xl('Return above part with your payment');
150 $label_pgbrk = xl('STATEMENT SUMMARY');
151 $label_visit = xl('Visit Date');
152 $label_desc = xl('Description');
153 $label_amt = xl('Amount');
155 // This is the text for the top part of the page, up to but not
156 // including the detail lines. Some examples of variable fields are:
157 // %s = string with no minimum width
158 // %9s = right-justified string of 9 characters padded with spaces
159 // %-25s = left-justified string of 25 characters padded with spaces
160 // Note that "\n" is a line feed (new line) character.
161 // reformatted to handle i8n by tony
163 $out = sprintf("%-30s %-23s %-s\n",$clinic_name,$stmt['patient'],$stmt['today']);
164 $out .= sprintf("%-30s %s: %-s\n",$clinic_addr,$label_chartnum,$stmt['pid']);
165 $out .= sprintf("%-30s %-s\n",$clinic_csz,$label_insinfo);
166 $out .= sprintf("%-30s %s: %-s\n",null,$label_totaldue);
168 $out .= sprintf("%-30s %-s\n",$label_addressee,$label_remitto);
169 $out .= sprintf("%-32s %s\n",$stmt['to'][0],$remit_name);
170 $out .= sprintf("%-32s %s\n",$stmt['to'][1],$remit_addr);
171 $out .= sprintf("%-32s %s\n",$stmt['to'][2],$remit_csz);
173 if($stmt['to'][3]!='')//to avoid double blank lines the if condition is put.
174 $out .= sprintf(" %-32s\n",$stmt['to'][3]);
175 $out .= sprintf("_________________________________________________________________\n");
177 $out .= sprintf("%-32s\n",$label_payby.' '.$label_cards);
179 $out .= sprintf("%s_____________________ %s______ %s___________________\n",
180 $label_cardnum,$label_expiry,$label_sign);
181 $out .= sprintf("%-20s %s\n",null,$label_retpay);
182 $out .= sprintf("-----------------------------------------------------------------\n");
184 $out .= sprintf("_______________________ %s _______________________\n",$label_pgbrk);
186 $out .= sprintf("%-11s %-46s %s\n",$label_visit,$label_desc,$label_amt);
189 // This must be set to the number of lines generated above.
193 // This generates the detail lines. Again, note that the values must
194 // be specified in the order used.
196 foreach ($stmt['lines'] as $line) {
197 $description = $line['desc'];
198 $tmp = substr($description, 0, 14);
199 if ($tmp == 'Procedure 9920' ||
$tmp == 'Procedure 9921')
200 $description = xl('Office Visit');
203 ksort($line['detail']);
205 foreach ($line['detail'] as $dkey => $ddata) {
206 $ddate = substr($dkey, 0, 10);
207 if (preg_match('/^(\d\d\d\d)(\d\d)(\d\d)\s*$/', $ddate, $matches)) {
208 $ddate = $matches[1] . '-' . $matches[2] . '-' . $matches[3];
213 $amount = sprintf("%.2f", 0 - $ddata['pmt']);
214 $desc = xl('Paid') .' '. $ddate .': '. $ddata['src'].' '. $ddata['insurance_company'];
215 } else if ($ddata['rsn']) {
217 $amount = sprintf("%.2f", $ddata['chg']);
218 $desc = xl('Adj') .' '. $ddate .': ' . $ddata['rsn'].' '. $ddata['insurance_company'];
220 $desc = xl('Note') .' '. $ddate .': '. $ddata['rsn'].' '. $ddata['insurance_company'];
222 } else if ($ddata['chg'] < 0) {
223 $amount = sprintf("%.2f", $ddata['chg']);
224 $desc = xl('Patient Payment');
226 $amount = sprintf("%.2f", $ddata['chg']);
227 $desc = $description;
230 $out .= sprintf("%-10s %-45s%8s\n", $dos, $desc, $amount);
236 // This generates blank lines until we are at line 42.
238 while ($count++
< 42) $out .= "\n";
241 $label_ptname = xl('Name');
242 $label_today = xl('Date');
243 $label_due = xl('Due');
244 $label_thanks = xl('Thank you for choosing');
245 $label_call = xl('Please call if any of the above information is incorrect');
246 $label_prompt = xl('We appreciate prompt payment of balances due');
247 $label_dept = xl('Billing Department');
249 // This is the bottom portion of the page.
251 $out .= sprintf("%-s: %-25s %-s: %-14s %-s: %8s\n",$label_ptname,$stmt['patient'],
252 $label_today,$stmt['today'],$label_due,$stmt['amount']);
253 $out .= sprintf("__________________________________________________________________\n");
255 $out .= sprintf("%-s\n",$label_call);
256 $out .= sprintf("%-s\n",$label_prompt);
258 $out .= sprintf("%-s\n",$billing_contact);
259 $out .= sprintf(" %-s\n",$label_dept);
260 $out .= sprintf(" %-s\n",$billing_phone);
261 $out .= "\014"; // this is a form feed