New features, including clone features. Documentation update to follow.
[openemr.git] / accounting / ws_server_26.pl
blob6e7e34d0f07d4ecfc7f3a6f1957d864423de1576
1 #!/usr/bin/perl
3 ######################################################################
4 # This module is compatible only with SQL-Ledger version 2.6.x.
5 # Copy it to your SQL-Ledger installation directory as ws_server.pl.
6 ######################################################################
8 use Frontier::Responder;
9 use DBI;
11 ######################################################################
12 # IMPORTANT - modify this to point to your SQL-Ledger installation!
13 ######################################################################
14 use lib qw (/var/www/sql-ledger);
16 use SL::User;
17 use SL::Form;
18 use SL::CT;
19 use SL::HR;
20 use SL::IS;
21 use SL::IC;
22 use SL::AA;
24 require "sql-ledger.conf";
26 my $add_customer = \&rpc_add_customer;
27 my $add_salesman = \&rpc_add_employee;
28 my $add_invoice = \&rpc_add_invoice;
29 my $customer_balance = \&rpc_customer_balance;
31 my $res = Frontier::Responder->new( methods => {
32 'ezybiz.add_invoice' => $add_invoice,
33 'ezybiz.add_salesman' => $add_salesman,
34 'ezybiz.customer_balance' =>$customer_balance,
35 'ezybiz.add_customer' => $add_customer
36 }, );
38 print $res->answer;
40 sub rpc_customer_balance {
41 my ($post_hash) = @_;
42 if ($$post_hash{id} > 0 ) {
43 my $myconfig = new User "$memberfile", "$oemr_username";
44 $myconfig->{dbpasswd} = unpack 'u', $myconfig->{dbpasswd};
45 my $form = new Form;
46 $form->{title} = "AR Outstanding";
47 $form->{outstanding} = "1";
48 $form->{customer_id} = $$post_hash{id};
49 $form->{sort} = "transdate" ;
50 $form->{l_due} = 1;
51 $form->{nextsub} = "transaction";
52 $form->{vc} = "customer" ;
53 $form->{action} = 'Continue';
55 AA::transactions("",\%$myconfig, \%$form);
57 my ($paid,$amount) = 0;
59 # Exclude invoices that are not yet due (i.e. waiting for insurance).
60 # We no longer use the due date for this; instead ar.notes identifies
61 # insurances used, and ar.shipvia indicates which of those are done.
62 # If all insurances are done, it's due.
64 foreach my $resref (@{$$form{transactions}}) {
65 my $inspending = 0;
66 foreach my $tmp ('Ins1','Ins2','Ins3') {
67 ++$inspending if ($$resref{notes} =~ /$tmp/ && $$resref{shipvia} !~ /$tmp/);
69 if ($inspending == 0) {
70 $paid += $$resref{paid};
71 $amount += $$resref{amount};
75 my $retval = $amount - $paid;
76 return($retval);
80 sub rpc_add_customer
82 use lib '/usr/lib/perl5/site_perl/5.8.3';
84 my ($post_hash) = @_;
86 #take struct of data and map to post data to create the customer, return the id
87 my $myconfig = new User "$memberfile", "$oemr_username";
88 $myconfig->{dbpasswd} = unpack 'u', $myconfig->{dbpasswd};
89 my $form = new Form;
90 $form->{name} = substr($$post_hash{'firstname'} . " " . $$post_hash{'lastname'}, 0, 64);
91 $form->{discount} = "";
92 $form->{terms} = "";
93 $form->{taxincluded} = "1";
94 $form->{creditlimit} = "0";
95 $form->{id} = $$post_hash{'foreign_id'};
96 $form->{login} = "";
97 $form->{employee} = "";
98 $form->{pricegroup} = "";
99 $form->{business} = "";
100 $form->{language} = "";
101 $form->{address1} = substr($$post_hash{'address'}, 0, 32);
102 $form->{address2} = substr($$post_hash{'address'}, 32, 32);
103 $form->{city} = substr($$post_hash{'suburb'}, 0, 32);
105 if($$post_hash{'state'}){
106 $form->{state} = substr($$post_hash{'state'}, 0, 32);
107 }else{
108 $form->{state} = substr($$post_hash{'geo_zone_id'}, 0, 32);
110 $form->{zipcode} = substr($$post_hash{'postcode'}, 0, 10);
111 $form->{country} = "";
112 $form->{contact} = "";
113 $form->{phone} = substr($$post_hash{'phone1'}, 0, 20);
114 $form->{fax} = "";
115 $form->{email} = $$post_hash{'email'};
116 $form->{taxnumber} = substr($$post_hash{'ssn'}, 0, 32);
117 $form->{curr} = "USD";
118 $form->{customernumber} = $$post_hash{'customernumber'};
119 @t = localtime(time);
120 $dd = $t[3];
121 $mm = $t[4] + 1;
122 $yy = $t[5] + 1900;
124 $form->{startdate} = "$mm-$dd-$yy";
126 CT::save_customer('', \%$myconfig, \%$form);
127 my $retVal = $form->{id};
129 return($retVal);
132 sub rpc_add_employee
134 my ($post_hash) = @_;
135 my $myconfig = new User "$memberfile", "$oemr_username";
136 $myconfig->{dbpasswd} = unpack 'u', $myconfig->{dbpasswd};
137 my $form = new Form;
138 $form->{id} = $$post_hash{'foreign_id'};
139 $form->{name} = $$post_hash{'fname'} . " " . $$post_hash{'lname'};
140 $form->{sales} = $$post_hash{'authorized'};
141 @t = localtime(time);
142 $dd = $t[3];
143 $mm = $t[4] + 1;
144 $yy = $t[5] + 1900;
146 $form->{startdate} = "$mm-$dd-$yy";
147 HR::save_employee("",\%$myconfig, \%$form);
148 my $retVal = $form->{id};
149 return($retVal);
152 sub rpc_add_invoice
154 my ($post_hash) = @_;
156 my $myconfig = new User "$memberfile", "$oemr_username";
157 $myconfig->{dbpasswd} = unpack 'u', $myconfig->{dbpasswd};
158 my $form = new Form;
159 $form->{id};
160 $form->{employee} = "--" . $$post_hash{'salesman'};
161 $form->{customer_id} = $$post_hash{'customerid'};
162 $form->{invnumber} = $$post_hash{'invoicenumber'};
163 $form->{amount} = $$post_hash{'total'};
164 $form->{netamount} = $$post_hash{'total'};
165 $form->{notes} = $$post_hash{'notes'};
166 $form->{department} = "";
167 $form->{currency} = "USD";
168 $form->{defaultcurrency} = "USD";
170 # This is the AR account number, needed by IS::post_invoice.
171 $form->{AR} = $oemr_ar_acc;
173 # This will use the posting date as the billing date
174 @t = localtime(time);
176 # $dd = $t[3];
177 # $mm = $t[4] + 1;
178 # $yy = $t[5] + 1900;
180 $form->{transdate} = sprintf("%02u-%02u-%04u", $t[4] + 1, $t[3], $t[5] + 1900);
182 # This overrides the above statement to use the date of service as the
183 # invoice date, which should be preferable for most practices. Comment
184 # out the following line if you really want the billing date instead.
186 $form->{transdate} = $$post_hash{'dosdate'};
188 # If there is insurance, set a future due date so we don't bother
189 # the patient for a while.
191 if ($$post_hash{'payer_id'}) {
192 @t = localtime(60 * 60 * 24 * $oemr_due_days + time);
193 $form->{duedate} = sprintf("%02u-%02u-%04u", $t[4] + 1, $t[3], $t[5] + 1900);
194 } else {
195 $form->{duedate} = $form->{transdate};
198 # Get out if the invoice already exists.
199 my $trans_id = 0;
200 my $dbh = $form->dbconnect($myconfig);
201 my $query = qq|SELECT id FROM ar WHERE invnumber = ?|;
202 my $eth = $dbh->prepare($query) || die "Failed to prepare ar query";
203 $eth->execute($$post_hash{'invoicenumber'}) || die "Failed to execute ar query";
204 ($trans_id) = $eth->fetchrow_array;
205 $eth->finish;
207 if ($trans_id) {
208 print STDERR "Skipping invoice $trans_id = " . $$post_hash{'invoicenumber'} . "\n";
209 $dbh->disconnect;
210 return 0;
213 #loop through line items and add them to invoice
214 my $i = 1;
215 my $j = 1; #this is for copays should only be one but who knows -j
216 my $count = 0;
217 my $items = $$post_hash{'items'};
219 foreach my $line_item (@$items)
221 if ($$line_item{'itemtext'} =~ /COPAY/) {
222 $form->{"datepaid_$j"} = $form->{transdate}; # "$mm-$dd-$yy";
223 # For copays we use a dummy procedure code because it may be applicable
224 # to multiple procedures during the visit.
225 $form->{"memo_$j"} = 'Co-pay';
226 # Put the payment method and check number in the source field if they are
227 # present (i.e. from pos_checkout.php).
228 if ($$line_item{'itemtext'} =~ /^COPAY:([A-Z].*)$/) {
229 $form->{"source_$j"} = $1;
230 } else {
231 $form->{"source_$j"} = 'Co-pay';
233 $form->{"paid_$j"} = abs($$line_item{'price'});
234 $form->{"AR_paid_$j"} = "$oemr_cash_acc" . "--";
235 $j++;
237 else{
238 my $chart_id = 0;
239 my $query = qq|SELECT id FROM chart WHERE accno = ?|;
240 my $eth = $dbh->prepare($query) || die "Failed to prepare chart query";
241 $eth->execute($$line_item{'glaccountid'}) || die "Failed to execute chart query";
242 ($chart_id) = $eth->fetchrow_array;
243 $eth->finish;
245 $form->{"qty_$i"} = $$line_item{'qty'};
246 $form->{"discount_$i"} = 0;
247 $form->{"sellprice_$i"} = $$line_item{'price'};
249 $form->{taxincluded} = 1;
250 $form->{"taxaccounts_$i"} = 0;
251 $form->{"income_accno_$i"} = $$line_item{'glaccountid'};
252 $form->{"income_accno_id_$i"} = $chart_id;
254 $form->{"id_$i"} = add_goodsandservices(\%$myconfig, \%$form, $oemr_services_partnumber,
255 'Medical Services', '');
257 $form->{"description_$i"} = $$line_item{'itemtext'};
258 $form->{"unit_$i"} = '';
259 $form->{"serialnumber_$i"} = $$line_item{'maincode'};
261 # Save the insurance company ID as the SL project ID. This gives us a way
262 # to associate each invoice item with its insurance payer. The clinic will
263 # probably want to write some reporting software taking advantage of this.
265 $form->{"projectnumber_$i"} = "--" . $$post_hash{'payer_id'}
266 if ($$post_hash{'payer_id'});
267 $i++;
271 $dbh->disconnect;
273 $form->{paidaccounts} = $j - 1;
274 $form->{rowcount} = $i - 1;
275 IS::post_invoice("", \%$myconfig, \%$form);
276 my $retVal = $form->{id};
277 return($retVal);
280 sub get_partid
282 my ($myconfig, $form, $number) = @_;
283 my $retval = 0;
284 # connect to database
285 my $dbh = $form->dbconnect($myconfig);
287 my $query = qq|SELECT id FROM parts WHERE partnumber = ?|;
288 my $eth = $dbh->prepare($query) || die "Failed to create select id from parts query";
289 $eth->execute($number) || die "Failed to execute select id from parts query";
290 ($retval) = $eth->fetchrow_array;
291 $eth->finish;
292 $dbh->disconnect;
293 return($retval);
296 sub add_goodsandservices
298 my ($myconfig, $form, $code, $desc, $price) = @_;
299 my $retval = 0;
300 $retval = get_partid($myconfig, $form, $code);
302 if($retval == 0)
304 # connect to database, turn off autocommit
305 my $dbh = $form->dbconnect_noauto($myconfig);
306 my $query = qq|insert into parts (partnumber,description,listprice,sellprice) values(?,?,?,?)|;
307 my $eth = $dbh->prepare($query) || die "failed to create insert into parts query" . $dbh->errstr;
308 $eth->execute($code,$desc,$price,$price) || die "failed to execute insert into parts query" . $dbh->errstr;
309 $dbh->commit || die $dbh->errstr;
310 $eth->finish || die "cannot finish " . $dbh->errstr;
311 $dbh->disconnect;
312 $retval = get_partid($myconfig, $form, $code);
315 return($retval);