Added facility to do a cash refund.
[koha.git] / C4 / Accounts2.pm
1 package C4::Accounts2; #asummes C4/Accounts2
2
3 #requires DBI.pm to be installed
4 #uses DBD:Pg
5
6 use strict;
7 require Exporter;
8 use DBI;
9 use C4::Database;
10 use C4::Stats;
11 use C4::Search;
12 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
13   
14 # set the version for version checking
15 $VERSION = 0.01;
16     
17 @ISA = qw(Exporter);
18 @EXPORT = qw(&recordpayment &fixaccounts &makepayment &manualinvoice
19 &getnextacctno);
20 %EXPORT_TAGS = ( );     # eg: TAG => [ qw!name1 name2! ],
21                   
22 # your exported package globals go here,
23 # as well as any optionally exported functions
24
25 @EXPORT_OK   = qw($Var1 %Hashit);
26
27
28 # non-exported package globals go here
29 use vars qw(@more $stuff);
30         
31 # initalize package globals, first exported ones
32
33 my $Var1   = '';
34 my %Hashit = ();
35                     
36 # then the others (which are still accessible as $Some::Module::stuff)
37 my $stuff  = '';
38 my @more   = ();
39         
40 # all file-scoped lexicals must be created before
41 # the functions below that use them.
42                 
43 # file-private lexicals go here
44 my $priv_var    = '';
45 my %secret_hash = ();
46                             
47 # here's a file-private function as a closure,
48 # callable as &$priv_func;  it cannot be prototyped.
49 my $priv_func = sub {
50   # stuff goes here.
51 };
52                                                     
53 # make all your functions, whether exported or not;
54
55 sub displayaccounts{
56   my ($env)=@_;
57 }
58
59 sub recordpayment{
60   #here we update both the accountoffsets and the account lines
61   my ($env,$bornumber,$data)=@_;
62   my $dbh=C4Connect;
63   my $updquery = "";
64   my $newamtos = 0;
65   my $accdata = "";
66   my $branch=$env->{'branchcode'};
67   my $amountleft = $data;
68   # begin transaction
69   my $nextaccntno = getnextacctno($env,$bornumber,$dbh);
70   # get lines with outstanding amounts to offset
71   my $query = "select * from accountlines 
72   where (borrowernumber = '$bornumber') and (amountoutstanding<>0)
73   order by date";
74   my $sth = $dbh->prepare($query);
75   $sth->execute;
76   # offset transactions
77   while (($accdata=$sth->fetchrow_hashref) and ($amountleft>0)){
78      if ($accdata->{'amountoutstanding'} < $amountleft) {
79         $newamtos = 0;
80         $amountleft = $amountleft - $accdata->{'amountoutstanding'};
81      }  else {
82         $newamtos = $accdata->{'amountoutstanding'} - $amountleft;
83         $amountleft = 0;
84      }
85      my $thisacct = $accdata->{accountno};
86      $updquery = "update accountlines set amountoutstanding= '$newamtos'
87      where (borrowernumber = '$bornumber') and (accountno='$thisacct')";
88      my $usth = $dbh->prepare($updquery);
89      $usth->execute;
90      $usth->finish;
91      $updquery = "insert into accountoffsets 
92      (borrowernumber, accountno, offsetaccount,  offsetamount)
93      values ($bornumber,$accdata->{'accountno'},$nextaccntno,$newamtos)";
94      my $usth = $dbh->prepare($updquery);
95      $usth->execute;
96      $usth->finish;
97   }
98   # create new line
99   $updquery = "insert into accountlines 
100   (borrowernumber, accountno,date,amount,description,accounttype,amountoutstanding)  
101   values ($bornumber,$nextaccntno,now(),0-$data,'Payment,thanks',
102   'Pay',0-$amountleft)";
103   my $usth = $dbh->prepare($updquery);
104   $usth->execute;
105   $usth->finish;
106   UpdateStats($env,$branch,'payment',$data,'','','',$bornumber);
107   $sth->finish;
108   $dbh->disconnect;
109 }
110
111 sub makepayment{
112   #here we update both the accountoffsets and the account lines
113   #updated to check, if they are paying off a lost item, we return the item 
114   # from their card, and put a note on the item record
115   my ($bornumber,$accountno,$amount,$user)=@_;
116   my $env;
117   my $dbh=C4Connect;
118   # begin transaction
119   my $nextaccntno = getnextacctno($env,$bornumber,$dbh);
120   my $newamtos=0;
121   my $sel="Select * from accountlines where  borrowernumber=$bornumber and
122   accountno=$accountno";
123   my $sth=$dbh->prepare($sel);
124   $sth->execute;
125   my $data=$sth->fetchrow_hashref;
126   $sth->finish;
127   my $updquery="Update accountlines set amountoutstanding=0 where
128   borrowernumber=$bornumber and accountno=$accountno";
129   $sth=$dbh->prepare($updquery);
130   $sth->execute;
131   $sth->finish;
132 #  print $updquery;
133   $updquery = "insert into accountoffsets 
134   (borrowernumber, accountno, offsetaccount,  offsetamount)
135   values ($bornumber,$accountno,$nextaccntno,$newamtos)";
136   my $usth = $dbh->prepare($updquery);
137   $usth->execute;
138   $usth->finish;  
139   # create new line
140   my $payment=0-$amount;
141   $updquery = "insert into accountlines 
142   (borrowernumber, accountno,date,amount,description,accounttype,amountoutstanding)  
143   values ($bornumber,$nextaccntno,now(),$payment,'Payment,thanks - $user', 'Pay',0)";
144   my $usth = $dbh->prepare($updquery);
145   $usth->execute;
146   $usth->finish;
147   UpdateStats($env,$user,'payment',$amount,'','','',$bornumber);
148   $sth->finish;
149   $dbh->disconnect;
150   #check to see what accounttype
151   if ($data->{'accounttype'} eq 'Rep' || $data->{'accounttype'} eq 'L'){
152     returnlost($bornumber,$data->{'itemnumber'});
153   }
154 }
155
156 sub getnextacctno {
157   my ($env,$bornumber,$dbh)=@_;
158   my $nextaccntno = 1;
159   my $query = "select * from accountlines
160   where (borrowernumber = '$bornumber')
161   order by accountno desc";
162   my $sth = $dbh->prepare($query);
163   $sth->execute;
164   if (my $accdata=$sth->fetchrow_hashref){
165     $nextaccntno = $accdata->{'accountno'} + 1;
166   }
167   $sth->finish;
168   return($nextaccntno);
169 }
170
171 sub fixaccounts {
172   my ($borrowernumber,$accountno,$amount)=@_;
173   my $dbh=C4Connect;
174   my $query="Select * from accountlines where borrowernumber=$borrowernumber
175      and accountno=$accountno";
176   my $sth=$dbh->prepare($query);
177   $sth->execute;
178   my $data=$sth->fetchrow_hashref;
179   my $diff=$amount-$data->{'amount'};
180   my $outstanding=$data->{'amountoutstanding'}+$diff;
181   $sth->finish;
182   $query="Update accountlines set amount='$amount',amountoutstanding='$outstanding' where
183           borrowernumber=$borrowernumber and accountno=$accountno";
184    $sth=$dbh->prepare($query);
185 #   print $query;
186    $sth->execute;
187    $sth->finish;
188    $dbh->disconnect;
189  }
190
191 sub returnlost{
192   my ($borrnum,$itemnum)=@_;
193   my $dbh=C4Connect;
194   my $borrower=borrdata('',$borrnum); #from C4::Search;
195   my $upiss="Update issues set returndate=now() where
196   borrowernumber='$borrnum' and itemnumber='$itemnum' and returndate is null";
197   my $sth=$dbh->prepare($upiss);
198   $sth->execute;
199   $sth->finish;
200   my @datearr = localtime(time);
201   my $date = (1900+$datearr[5])."-".($datearr[4]+1)."-".$datearr[3];
202   my $bor="$borrower->{'firstname'} $borrower->{'surname'} $borrower->{'cardnumber'}";
203   my $upitem="Update items set itemnotes='Paid for by $bor $date' where itemnumber='$itemnum'";
204   $sth=$dbh->prepare($upitem);
205   $sth->execute;
206   $sth->finish;
207   $dbh->disconnect;
208 }
209
210 sub manualinvoice{
211   my ($bornum,$itemnum,$desc,$type,$amount)=@_;
212   my $dbh=C4Connect;
213   my $insert;
214   $itemnum=~ s/ //g;
215   my $accountno=getnextacctno('',$bornum,$dbh);
216   my $amountleft=$amount;
217   
218   if ($type eq 'C' || $type eq 'BAY'){
219     my $amount2=$amount*-1;
220     $amountleft=fixcredit('',$bornum,$amount2);
221   }
222   if ($type eq 'N'){
223     $desc.="New Card";
224   }
225   if ($type eq 'L' && $desc eq ''){
226     $desc="Lost Item";
227   }
228   if ($type eq 'REF'){
229     $amountleft=refund('',$bornum,$amount);    
230   }
231   if ($itemnum ne ''){
232     my $sth=$dbh->prepare("Select * from items where barcode='$itemnum'");
233     $sth->execute;
234     my $data=$sth->fetchrow_hashref;
235     $sth->finish;
236     $desc.=" ".$itemnum;
237     $insert="insert into accountlines (borrowernumber,accountno,date,amount,description,accounttype,amountoutstanding,itemnumber)
238     values ($bornum,$accountno,now(),'$amount','$desc','$type','$amountleft','$data->{'itemnumber'}')";
239   } else {
240     $insert="insert into accountlines (borrowernumber,accountno,date,amount,description,accounttype,amountoutstanding)
241     values ($bornum,$accountno,now(),'$amount','$desc','$type','$amountleft')";
242   }
243   
244   my $sth=$dbh->prepare($insert);
245   $sth->execute;
246   $sth->finish;
247   
248   $dbh->disconnect;
249 }
250   
251 sub fixcredit{
252   #here we update both the accountoffsets and the account lines
253   my ($env,$bornumber,$data)=@_;
254   my $dbh=C4Connect;
255   my $updquery = "";
256   my $newamtos = 0;
257   my $accdata = "";
258 #  my $branch=$env->{'branchcode'};
259   my $amountleft = $data;
260   # begin transaction
261   my $nextaccntno = getnextacctno($env,$bornumber,$dbh);
262   # get lines with outstanding amounts to offset
263   my $query = "select * from accountlines 
264   where (borrowernumber = '$bornumber') and (amountoutstanding<>0)
265   order by date";
266   my $sth = $dbh->prepare($query);
267   $sth->execute;
268 #  print $query;
269   # offset transactions
270   while (($accdata=$sth->fetchrow_hashref) and ($amountleft>0)){
271      if ($accdata->{'amountoutstanding'} < $amountleft) {
272         $newamtos = 0;
273         $amountleft = $amountleft - $accdata->{'amountoutstanding'};
274      }  else {
275         $newamtos = $accdata->{'amountoutstanding'} + $amountleft;
276         $amountleft = 0;
277      }
278      my $thisacct = $accdata->{accountno};
279      $updquery = "update accountlines set amountoutstanding= '$newamtos'
280      where (borrowernumber = '$bornumber') and (accountno='$thisacct')";
281      my $usth = $dbh->prepare($updquery);
282      $usth->execute;
283      $usth->finish;
284      $updquery = "insert into accountoffsets 
285      (borrowernumber, accountno, offsetaccount,  offsetamount)
286      values ($bornumber,$accdata->{'accountno'},$nextaccntno,$newamtos)";
287      my $usth = $dbh->prepare($updquery);
288      $usth->execute;
289      $usth->finish;
290   }
291   $sth->finish;
292   $dbh->disconnect;
293   return($amountleft);
294 }
295
296 sub refund{
297   #here we update both the accountoffsets and the account lines
298   my ($env,$bornumber,$data)=@_;
299   my $dbh=C4Connect;
300   my $updquery = "";
301   my $newamtos = 0;
302   my $accdata = "";
303 #  my $branch=$env->{'branchcode'};
304   my $amountleft = $data *-1;
305   
306   # begin transaction
307   my $nextaccntno = getnextacctno($env,$bornumber,$dbh);
308   # get lines with outstanding amounts to offset
309   my $query = "select * from accountlines 
310   where (borrowernumber = '$bornumber') and (amountoutstanding<0)
311   order by date";
312   my $sth = $dbh->prepare($query);
313   $sth->execute;
314 #  print $query;
315 #  print $amountleft;
316   # offset transactions
317   while (($accdata=$sth->fetchrow_hashref) and ($amountleft<0)){
318      if ($accdata->{'amountoutstanding'} > $amountleft) {
319         $newamtos = 0;
320         $amountleft = $amountleft - $accdata->{'amountoutstanding'};
321      }  else {
322         $newamtos = $accdata->{'amountoutstanding'} - $amountleft;
323         $amountleft = 0;
324      }
325 #     print $amountleft;
326      my $thisacct = $accdata->{accountno};
327      $updquery = "update accountlines set amountoutstanding= '$newamtos'
328      where (borrowernumber = '$bornumber') and (accountno='$thisacct')";
329      my $usth = $dbh->prepare($updquery);
330      $usth->execute;
331      $usth->finish;
332      $updquery = "insert into accountoffsets 
333      (borrowernumber, accountno, offsetaccount,  offsetamount)
334      values ($bornumber,$accdata->{'accountno'},$nextaccntno,$newamtos)";
335      my $usth = $dbh->prepare($updquery);
336      $usth->execute;
337      $usth->finish;
338   }
339   $sth->finish;
340   $dbh->disconnect;
341   return($amountleft);
342 }
343 END { }       # module clean-up code here (global destructor)