BUG FIXING : Using LEFT JOIN in replacement of implicit inner joins. WARN NOT FULLY...
[koha.git] / C4 / Bookfund.pm
1 package C4::Bookfund;
2
3 # Copyright 2000-2002 Katipo Communications
4 #
5 # This file is part of Koha.
6 #
7 # Koha is free software; you can redistribute it and/or modify it under the
8 # terms of the GNU General Public License as published by the Free Software
9 # Foundation; either version 2 of the License, or (at your option) any later
10 # version.
11 #
12 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License along with
17 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
18 # Suite 330, Boston, MA  02111-1307 USA
19
20 # $Id$
21
22 use strict;
23
24
25 use vars qw($VERSION @ISA @EXPORT);
26
27 # set the version for version checking
28 $VERSION = do { my @v = '$Revision$' =~ /\d+/g; shift(@v) . "." . join( "_", map { sprintf "%03d", $_ } @v ); };
29
30 =head1 NAME
31
32 C4::Bookfund - Koha functions for dealing with bookfund, currency & money.
33
34 =head1 SYNOPSIS
35
36 use C4::Bookfund;
37
38 =head1 DESCRIPTION
39
40 the functions in this modules deal with bookfund, currency and money.
41 They allow to get and/or set some informations for a specific budget or currency.
42
43 =cut
44
45 @ISA    = qw(Exporter);
46 @EXPORT = qw(
47     &GetBookFund &GetBookFunds &GetBookFundsId &GetBookFundBreakdown &GetCurrencies
48     &NewBookFund
49     &ModBookFund &ModCurrencies
50     &SearchBookFund
51     &Countbookfund 
52     &ConvertCurrency
53     &DelBookFund
54 );
55
56 =head1 FUNCTIONS
57
58 =cut
59
60 #-------------------------------------------------------------#
61
62 =head2 GetBookFund
63
64 $dataaqbookfund = &GetBookFund($bookfundid);
65
66 this function get the bookfundid, bookfundname, the bookfundgroup,  the branchcode
67 from aqbookfund table for bookfundid given on input arg.
68 return: 
69 C<$dataaqbookfund> is a hashref full of bookfundid, bookfundname, bookfundgroup,
70 and branchcode.
71
72 =cut
73
74 sub GetBookFund {
75     my $bookfundid = shift;
76     my $branchcode = shift;
77     $branchcode=($branchcode?$branchcode:'');
78     my $dbh = C4::Context->dbh;
79     my $query = "
80         SELECT
81             bookfundid,
82             bookfundname,
83             bookfundgroup,
84             branchcode
85         FROM aqbookfund
86         WHERE bookfundid = ?
87         AND branchcode = ?";
88     my $sth=$dbh->prepare($query);
89     $sth->execute($bookfundid,$branchcode);
90     my $data=$sth->fetchrow_hashref;
91     return $data;
92 }
93
94
95 =head3 GetBookFundsId
96
97 $sth = &GetBookFundsId
98 Read on aqbookfund table and execute a simple SQL query.
99
100 return:
101 $sth->execute. Don't forget to fetch row from the database after using
102 this function by using, for example, $sth->fetchrow_hashref;
103
104 C<@results> is an array of id existing on the database.
105
106 =cut
107
108 sub GetBookFundsId {
109     my @bookfundids_loop;
110     my $dbh= C4::Context->dbh;
111     my $query = "
112         SELECT bookfundid,branchcode
113         FROM aqbookfund
114     ";
115     my $sth = $dbh->prepare($query);
116     $sth->execute;
117     return $sth;
118 }
119
120 #-------------------------------------------------------------#
121
122 =head3 GetBookFunds
123
124 @results = &GetBookFunds;
125
126 Returns a list of all book funds.
127
128 C<@results> is an array of references-to-hash, whose keys are fields from the aqbookfund and aqbudget tables of the Koha database. Results are ordered
129 alphabetically by book fund name.
130
131 =cut
132
133 sub GetBookFunds {
134     my ($branch) = @_;
135     my $dbh      = C4::Context->dbh;
136     my $userenv  = C4::Context->userenv;
137     my $strsth;
138
139     if ( $branch ne '' ) {
140         $strsth = "
141         SELECT *
142         FROM   aqbookfund
143         LEFT JOIN aqbudget ON aqbookfund.bookfundid=aqbudget.bookfundid
144         WHERE  startdate<now()
145             AND enddate>now()
146             AND (aqbookfund.branchcode='' OR aqbookfund.branchcode= ? )
147       GROUP BY aqbookfund.bookfundid ORDER BY bookfundname";
148     }
149     else {
150         $strsth = "
151             SELECT *
152             FROM   aqbookfund
153             LEFT JOIN aqbudget ON aqbookfund.bookfundid=aqbudget.bookfundid
154             WHERE startdate<now()
155                 AND enddate>now()
156             GROUP BY aqbookfund.bookfundid ORDER BY bookfundname
157         ";
158     }
159     my $sth = $dbh->prepare($strsth);
160     if ( $branch ne '' ) {
161         $sth->execute($branch);
162     }
163     else {
164         $sth->execute;
165     }
166     my @results = ();
167     while ( my $data = $sth->fetchrow_hashref ) {
168         push( @results, $data );
169     }
170     $sth->finish;
171     return @results;
172 }
173
174 #-------------------------------------------------------------#
175
176 =head3 GetCurrencies
177
178 @currencies = &GetCurrencies;
179
180 Returns the list of all known currencies.
181
182 C<$currencies> is a array; its elements are references-to-hash, whose
183 keys are the fields from the currency table in the Koha database.
184
185 =cut
186
187 sub GetCurrencies {
188     my $dbh = C4::Context->dbh;
189     my $query = "
190         SELECT *
191         FROM   currency
192     ";
193     my $sth = $dbh->prepare($query);
194     $sth->execute;
195     my @results = ();
196     while ( my $data = $sth->fetchrow_hashref ) {
197         push( @results, $data );
198     }
199     $sth->finish;
200     return @results;
201 }
202
203 #-------------------------------------------------------------#
204
205 =head3 GetBookFundBreakdown
206
207 ( $spent, $comtd ) = &GetBookFundBreakdown( $id, $start, $end );
208
209 returns the total comtd & spent for a given bookfund, and a given year
210 used in acqui-home.pl
211
212 =cut
213
214 sub GetBookFundBreakdown {
215     my ( $id, $start, $end ) = @_;
216     my $dbh = C4::Context->dbh;
217
218     # if no start/end dates given defaut to everything
219     if ( !$start ) {
220         $start = '0000-00-00';
221         $end   = 'now()';
222     }
223
224     # do a query for spent totals.
225     my $query = "
226         SELECT quantity,datereceived,freight,unitprice,listprice,ecost,
227                quantityreceived,subscription
228         FROM   aqorders
229         LEFT JOIN aqorderbreakdown ON aqorders.ordernumber=aqorderbreakdown.ordernumber
230         LEFT JOIN aqbookfund ON (aqorderbreakdown.bookfundid=aqbookfund.bookfundid and aqorderbreakdown.branchcode=aqbookfund.branchcode)
231         LEFT JOIN aqbudget ON (aqbudget.bookfundid=aqbookfund.bookfundid and aqbudget.branchcode=aqbudget.branchcode)
232         WHERE  aqorderbreakdown.bookfundid=?
233             AND (datecancellationprinted IS NULL OR datecancellationprinted='0000-00-00')
234             AND ((budgetdate >= ? and budgetdate < ?) OR (startdate>=? and enddate<=?))
235     ";
236     my $sth = $dbh->prepare($query);
237     $sth->execute( $id, $start, $end, $start, $end );
238
239     my ($spent) = 0;
240     while ( my $data = $sth->fetchrow_hashref ) {
241         if ( $data->{'subscription'} == 1 ) {
242             $spent += $data->{'quantity'} * $data->{'unitprice'};
243         }
244         else {
245             $spent += ( $data->{'unitprice'} ) * ($data->{'quantityreceived'}?$data->{'quantityreceived'}:0);
246
247         }
248     }
249
250     # then do a seperate query for commited totals, (pervious single query was
251     # returning incorrect comitted results.
252
253     $query = "
254         SELECT  quantity,datereceived,freight,unitprice,
255                 listprice,ecost,quantityreceived AS qrev,
256                 subscription,title,itemtype,aqorders.biblionumber,
257                 aqorders.booksellerinvoicenumber,
258                 quantity-quantityreceived AS tleft,
259                 aqorders.ordernumber AS ordnum,entrydate,budgetdate
260         FROM    aqorders
261         LEFT JOIN biblioitems ON biblioitems.biblioitemnumber=aqorders.biblioitemnumber
262         LEFT JOIN aqorderbreakdown ON aqorders.ordernumber=aqorderbreakdown.ordernumber
263         WHERE   bookfundid=?
264             AND (budgetdate >= ? AND budgetdate < ?)
265             AND (datecancellationprinted IS NULL OR datecancellationprinted='0000-00-00')
266     ";
267
268     $sth = $dbh->prepare($query);
269 #      warn "$start $end";     
270     $sth->execute( $id, $start, $end );
271
272     my $comtd=0;
273
274     while ( my $data = $sth->fetchrow_hashref ) {
275         my $left = $data->{'tleft'};
276         if ( (!$left && (!$data->{'datereceived'}||$data->{'datereceived'} eq '0000-00-00') ) || $left eq '' ) {
277             $left = $data->{'quantity'};
278         }
279         if ( $left && $left > 0 ) {
280             my $subtotal = $left * $data->{'ecost'};
281             $data->{subtotal} = $subtotal;
282             $data->{'left'} = $left;
283             $comtd += $subtotal;
284         }
285 #         use Data::Dumper; warn Dumper($data);    
286     }
287
288     $sth->finish;
289     return ( $spent, $comtd );
290 }
291
292 =head3 NewBookFund
293
294 &NewBookFund(bookfundid, bookfundname, branchcode);
295
296 this function create a new bookfund into the database.
297
298 =cut 
299
300 sub NewBookFund{
301     my ($bookfundid, $bookfundname, $branchcode) = @_;
302     $branchcode = undef unless $branchcode;
303     my $dbh = C4::Context->dbh;
304     my $query = "
305         INSERT
306         INTO aqbookfund
307             (bookfundid, bookfundname, branchcode)
308         VALUES
309             (?, ?, ?)
310     ";
311     my $sth=$dbh->prepare($query);
312     $sth->execute($bookfundid,$bookfundname,"$branchcode");
313 }
314
315 #-------------------------------------------------------------#
316
317 =head3 ModBookFund
318
319 &ModBookFund($bookfundname,$branchcode,$bookfundid);
320 this function update the bookfundname and the branchcode on aqbookfund table
321 on database.
322
323 =cut
324
325 sub ModBookFund {
326     my ($bookfundname,$bookfundid,$branchcode) = @_;
327     my $dbh = C4::Context->dbh;
328     my $query = "
329         UPDATE aqbookfund
330         SET    bookfundname = ?
331         WHERE  bookfundid = ?
332         AND branchcode= ?
333     ";
334     warn "name : $bookfundname";
335     my $sth=$dbh->prepare($query);
336     $sth->execute($bookfundname,$bookfundid,"$branchcode");
337 # budgets depending on a bookfund must have the same branchcode
338 # if the bookfund branchcode is set
339     if (defined $branchcode) {
340         $query = "
341             UPDATE aqbudget
342             SET branchcode = ?
343         ";
344         $sth=$dbh->prepare($query);
345         $sth->execute($branchcode);
346     }
347 }
348
349 #-------------------------------------------------------------#
350
351 =head3 SearchBookFund
352
353 @results = SearchBookFund(
354         $bookfundid,$filter,$filter_bookfundid,
355         $filter_bookfundname,$filter_branchcode);
356
357 this function searchs among the bookfunds corresponding to our filtering rules.
358
359 =cut
360
361 sub SearchBookFund {
362     my $dbh = C4::Context->dbh;
363     my ($filter,
364         $filter_bookfundid,
365         $filter_bookfundname,
366         $filter_branchcode
367        ) = @_;
368
369     my @bindings;
370
371     my $query = "
372         SELECT  bookfundid,
373                 bookfundname,
374                 bookfundgroup,
375                 branchcode
376         FROM aqbookfund
377         WHERE 1 ";
378
379     if ($filter) {
380         if ($filter_bookfundid) {
381             $query.= "AND bookfundid = ?";
382             push @bindings, $filter_bookfundid;
383         }
384         if ($filter_bookfundname) {
385             $query.= "AND bookfundname like ?";
386             push @bindings, '%'.$filter_bookfundname.'%';
387         }
388         if ($filter_branchcode) {
389             $query.= "AND branchcode = ?";
390             push @bindings, $filter_branchcode;
391         }
392     }
393     $query.= "ORDER BY bookfundid";
394
395     my $sth = $dbh->prepare($query);
396     $sth->execute(@bindings);
397     my @results;
398     while (my $row = $sth->fetchrow_hashref) {
399         push @results, $row;
400     }
401     return @results;
402 }
403
404 #-------------------------------------------------------------#
405
406 =head3 ModCurrencies
407
408 &ModCurrencies($currency, $newrate);
409
410 Sets the exchange rate for C<$currency> to be C<$newrate>.
411
412 =cut
413
414 sub ModCurrencies {
415     my ( $currency, $rate ) = @_;
416     my $dbh = C4::Context->dbh;
417     my $query = "
418         UPDATE currency
419         SET    rate=?
420         WHERE  currency=?
421     ";
422     my $sth = $dbh->prepare($query);
423     $sth->execute( $rate, $currency );
424 }
425
426 #-------------------------------------------------------------#
427
428 =head3 Countbookfund
429
430 $number = Countbookfund($bookfundid);
431
432 this function count the number of bookfund with id given on input arg.
433 return :
434 the result of the SQL query as a number.
435
436 =cut
437
438 sub Countbookfund {
439     my $bookfundid = shift;
440     my $branchcode = shift;
441     my $dbh = C4::Context->dbh;
442     my $query ="
443         SELECT COUNT(*)
444         FROM  aqbookfund
445         WHERE bookfundid = ?
446         AND   branchcode = ?
447     ";
448     my $sth = $dbh->prepare($query);
449     $sth->execute($bookfundid,$branchcode);
450     return $sth->fetchrow;
451 }
452
453
454 #-------------------------------------------------------------#
455
456 =head3 ConvertCurrency
457
458 $foreignprice = &ConvertCurrency($currency, $localprice);
459
460 Converts the price C<$localprice> to foreign currency C<$currency> by
461 dividing by the exchange rate, and returns the result.
462
463 If no exchange rate is found, C<&ConvertCurrency> assumes the rate is one
464 to one.
465
466 =cut
467
468 sub ConvertCurrency {
469     my ( $currency, $price ) = @_;
470     my $dbh = C4::Context->dbh;
471     my $query = "
472         SELECT rate
473         FROM   currency
474         WHERE  currency=?
475     ";
476     my $sth = $dbh->prepare($query);
477     $sth->execute($currency);
478     my $cur = ( $sth->fetchrow_array() )[0];
479     unless($cur) {
480         $cur = 1;
481     }
482     return ( $price / $cur );
483 }
484
485 #-------------------------------------------------------------#
486
487 =head3 DelBookFund
488
489 &DelBookFund($bookfundid);
490 this function delete a bookfund which has $bokfundid as parameter on aqbookfund table and delete the approriate budget.
491
492 =cut
493
494 sub DelBookFund {
495     my $bookfundid = shift;
496     my $branchcode=shift;
497     my $dbh = C4::Context->dbh;
498     my $query = "
499         DELETE FROM aqbookfund
500         WHERE bookfundid=?
501         AND branchcode=?
502     ";
503     my $sth=$dbh->prepare($query);
504     $sth->execute($bookfundid,$branchcode);
505     $sth->finish;
506     $query = "
507         DELETE FROM aqbudget where bookfundid=? and branchcode=?
508     ";
509     $sth=$dbh->prepare($query);
510     $sth->execute($bookfundid,$branchcode);
511     $sth->finish;
512 }
513
514 END { }    # module clean-up code here (global destructor)
515
516 1;
517
518 __END__
519
520 =head1 AUTHOR
521
522 Koha Developement team <info@koha.org>
523
524 =cut