Bug 766: Move GetAuthvalueDropbox to C4::Koha
[koha.git] / C4 / Budgets.pm
1 package C4::Budgets;
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
17 # with Koha; if not, write to the Free Software Foundation, Inc.,
18 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20 use strict;
21 #use warnings; FIXME - Bug 2505
22 use C4::Context;
23 use C4::Dates qw(format_date format_date_in_iso);
24 use C4::SQLHelper qw<:all>;
25 use C4::Debug;
26
27 use vars qw($VERSION @ISA @EXPORT);
28
29 BEGIN {
30         # set the version for version checking
31     $VERSION = 3.07.00.049;
32         require Exporter;
33         @ISA    = qw(Exporter);
34         @EXPORT = qw(
35
36         &GetBudget
37         &GetBudgetByOrderNumber
38         &GetBudgetByCode
39         &GetBudgets
40         &GetBudgetHierarchy
41             &AddBudget
42         &ModBudget
43         &DelBudget
44         &GetBudgetSpent
45         &GetBudgetOrdered
46         &GetBudgetName
47         &GetPeriodsCount
48         &GetChildBudgetsSpent
49
50         &GetBudgetUsers
51         &ModBudgetUsers
52         &CanUserUseBudget
53         &CanUserModifyBudget
54
55             &GetBudgetPeriod
56         &GetBudgetPeriods
57         &ModBudgetPeriod
58         &AddBudgetPeriod
59             &DelBudgetPeriod
60
61         &ModBudgetPlan
62
63         &GetCurrency
64         &GetCurrencies
65         &ModCurrencies
66         &ConvertCurrency
67         
68                 &GetBudgetsPlanCell
69         &AddBudgetPlanValue
70         &GetBudgetAuthCats
71         &BudgetHasChildren
72         &CheckBudgetParent
73         &CheckBudgetParentPerm
74
75         &HideCols
76         &GetCols
77         );
78 }
79
80 # ----------------------------BUDGETS.PM-----------------------------";
81
82
83 =head1 FUNCTIONS ABOUT BUDGETS
84
85 =cut
86
87 sub HideCols {
88     my ( $authcat, @hide_cols ) = @_;
89     my $dbh = C4::Context->dbh;
90
91     my $sth1 = $dbh->prepare(
92         qq|
93         UPDATE aqbudgets_planning SET display = 0 
94         WHERE authcat = ? 
95         AND  authvalue = ? |
96     );
97     foreach my $authvalue (@hide_cols) {
98 #        $sth1->{TraceLevel} = 3;
99         $sth1->execute(  $authcat, $authvalue );
100     }
101 }
102
103 sub GetCols {
104     my ( $authcat, $authvalue ) = @_;
105
106     my $dbh = C4::Context->dbh;
107     my $sth = $dbh->prepare(
108         qq|
109         SELECT count(display) as cnt from aqbudgets_planning
110         WHERE  authcat = ? 
111         AND authvalue = ? and display  = 0   |
112     );
113
114 #    $sth->{TraceLevel} = 3;
115     $sth->execute( $authcat, $authvalue );
116     my $res  = $sth->fetchrow_hashref;
117
118     return  $res->{cnt} > 0 ? 0: 1
119
120 }
121
122 sub CheckBudgetParentPerm {
123     my ( $budget, $borrower_id ) = @_;
124     my $depth = $budget->{depth};
125     my $parent_id = $budget->{budget_parent_id};
126     while ($depth) {
127         my $parent = GetBudget($parent_id);
128         $parent_id = $parent->{budget_parent_id};
129         if ( $parent->{budget_owner_id} == $borrower_id ) {
130             return 1;
131         }
132         $depth--
133     }
134     return 0;
135 }
136
137 sub AddBudgetPeriod {
138     my ($budgetperiod) = @_;
139         return InsertInTable("aqbudgetperiods",$budgetperiod);
140 }
141 # -------------------------------------------------------------------
142 sub GetPeriodsCount {
143     my $dbh = C4::Context->dbh;
144     my $sth = $dbh->prepare("
145         SELECT COUNT(*) AS sum FROM aqbudgetperiods ");
146     $sth->execute();
147     my $res = $sth->fetchrow_hashref;
148     return $res->{'sum'};
149 }
150
151 # -------------------------------------------------------------------
152 sub CheckBudgetParent {
153     my ( $new_parent, $budget ) = @_;
154     my $new_parent_id = $new_parent->{'budget_id'};
155     my $budget_id     = $budget->{'budget_id'};
156     my $dbh           = C4::Context->dbh;
157     my $parent_id_tmp = $new_parent_id;
158
159     # check new-parent is not a child (or a child's child ;)
160     my $sth = $dbh->prepare(qq|
161         SELECT budget_parent_id FROM
162             aqbudgets where budget_id = ? | );
163     while (1) {
164         $sth->execute($parent_id_tmp);
165         my $res = $sth->fetchrow_hashref;
166         if ( $res->{'budget_parent_id'} == $budget_id ) {
167             return 1;
168         }
169         if ( not defined $res->{'budget_parent_id'} ) {
170             return 0;
171         }
172         $parent_id_tmp = $res->{'budget_parent_id'};
173     }
174 }
175
176 # -------------------------------------------------------------------
177 sub BudgetHasChildren {
178     my ( $budget_id  ) = @_;
179     my $dbh = C4::Context->dbh;
180     my $sth = $dbh->prepare(qq|
181        SELECT count(*) as sum FROM  aqbudgets
182         WHERE budget_parent_id = ?   | );
183     $sth->execute( $budget_id );
184     my $sum = $sth->fetchrow_hashref;
185     return $sum->{'sum'};
186 }
187
188 # -------------------------------------------------------------------
189 sub GetBudgetsPlanCell {
190     my ( $cell, $period, $budget ) = @_;
191     my ($actual, $sth);
192     my $dbh = C4::Context->dbh;
193     if ( $cell->{'authcat'} eq 'MONTHS' ) {
194         # get the actual amount
195         $sth = $dbh->prepare( qq|
196
197             SELECT SUM(ecost) AS actual FROM aqorders
198                 WHERE    budget_id = ? AND
199                 entrydate like "$cell->{'authvalue'}%"  |
200         );
201         $sth->execute( $cell->{'budget_id'} );
202     } elsif ( $cell->{'authcat'} eq 'BRANCHES' ) {
203         # get the actual amount
204         $sth = $dbh->prepare( qq|
205
206             SELECT SUM(ecost) FROM aqorders
207                 LEFT JOIN aqorders_items
208                 ON (aqorders.ordernumber = aqorders_items.ordernumber)
209                 LEFT JOIN items
210                 ON (aqorders_items.itemnumber = items.itemnumber)
211                 WHERE budget_id = ? AND homebranch = ? |          );
212
213         $sth->execute( $cell->{'budget_id'}, $cell->{'authvalue'} );
214     } elsif ( $cell->{'authcat'} eq 'ITEMTYPES' ) {
215         # get the actual amount
216         $sth = $dbh->prepare(  qq|
217
218             SELECT SUM( ecost *  quantity) AS actual
219                 FROM aqorders JOIN biblioitems
220                 ON (biblioitems.biblionumber = aqorders.biblionumber )
221                 WHERE aqorders.budget_id = ? and itemtype  = ? |
222         );
223         $sth->execute(  $cell->{'budget_id'},
224                         $cell->{'authvalue'} );
225     }
226     # ELSE GENERIC ORDERS SORT1/SORT2 STAT COUNT.
227     else {
228         # get the actual amount
229         $sth = $dbh->prepare( qq|
230
231         SELECT  SUM(ecost * quantity) AS actual
232             FROM aqorders
233             JOIN aqbudgets ON (aqbudgets.budget_id = aqorders.budget_id )
234             WHERE  aqorders.budget_id = ? AND
235                 ((aqbudgets.sort1_authcat = ? AND sort1 =?) OR
236                 (aqbudgets.sort2_authcat = ? AND sort2 =?))    |
237         );
238         $sth->execute(  $cell->{'budget_id'},
239                         $budget->{'sort1_authcat'},
240                         $cell->{'authvalue'},
241                         $budget->{'sort2_authcat'},
242                         $cell->{'authvalue'}
243         );
244     }
245     $actual = $sth->fetchrow_array;
246
247     # get the estimated amount
248     $sth = $dbh->prepare( qq|
249
250         SELECT estimated_amount AS estimated, display FROM aqbudgets_planning
251             WHERE budget_period_id = ? AND
252                 budget_id = ? AND
253                 authvalue = ? AND
254                 authcat = ?         |
255     );
256     $sth->execute(  $cell->{'budget_period_id'},
257                     $cell->{'budget_id'},
258                     $cell->{'authvalue'},
259                     $cell->{'authcat'},
260     );
261
262
263     my $res  = $sth->fetchrow_hashref;
264   #  my $display = $res->{'display'};
265     my $estimated = $res->{'estimated'};
266
267
268     return $actual, $estimated;
269 }
270
271 # -------------------------------------------------------------------
272 sub ModBudgetPlan {
273     my ( $budget_plan, $budget_period_id, $authcat ) = @_;
274     my $dbh = C4::Context->dbh;
275     foreach my $buds (@$budget_plan) {
276         my $lines = $buds->{lines};
277         my $sth = $dbh->prepare( qq|
278                 DELETE FROM aqbudgets_planning
279                     WHERE   budget_period_id   = ? AND
280                             budget_id   = ? AND
281                             authcat            = ? |
282         );
283     #delete a aqplan line of cells, then insert new cells, 
284     # these could be UPDATES rather than DEL/INSERTS...
285         $sth->execute( $budget_period_id,  $lines->[0]{budget_id}   , $authcat );
286
287         foreach my $cell (@$lines) {
288             my $sth = $dbh->prepare( qq|
289
290                 INSERT INTO aqbudgets_planning
291                      SET   budget_id     = ?,
292                      budget_period_id  = ?,
293                      authcat          = ?,
294                      estimated_amount  = ?,
295                      authvalue       = ?  |
296             );
297             $sth->execute(
298                             $cell->{'budget_id'},
299                             $cell->{'budget_period_id'},
300                             $cell->{'authcat'},
301                             $cell->{'estimated_amount'},
302                             $cell->{'authvalue'},
303             );
304         }
305     }
306 }
307
308 # -------------------------------------------------------------------
309 sub GetBudgetSpent {
310         my ($budget_id) = @_;
311         my $dbh = C4::Context->dbh;
312         my $sth = $dbh->prepare(qq|
313         SELECT SUM( COALESCE(unitprice, ecost) * quantity ) AS sum FROM aqorders
314             WHERE budget_id = ? AND
315             quantityreceived > 0 AND
316             datecancellationprinted IS NULL
317     |);
318         $sth->execute($budget_id);
319         my $sum =  $sth->fetchrow_array;
320
321     $sth = $dbh->prepare(qq|
322         SELECT SUM(shipmentcost) AS sum
323         FROM aqinvoices
324         WHERE shipmentcost_budgetid = ?
325           AND closedate IS NOT NULL
326     |);
327     $sth->execute($budget_id);
328     my ($shipmentcost_sum) = $sth->fetchrow_array;
329     $sum += $shipmentcost_sum;
330
331         return $sum;
332 }
333
334 # -------------------------------------------------------------------
335 sub GetBudgetOrdered {
336         my ($budget_id) = @_;
337         my $dbh = C4::Context->dbh;
338         my $sth = $dbh->prepare(qq|
339         SELECT SUM(ecost *  quantity) AS sum FROM aqorders
340             WHERE budget_id = ? AND
341             quantityreceived = 0 AND
342             datecancellationprinted IS NULL
343     |);
344         $sth->execute($budget_id);
345         my $sum =  $sth->fetchrow_array;
346
347     $sth = $dbh->prepare(qq|
348         SELECT SUM(shipmentcost) AS sum
349         FROM aqinvoices
350         WHERE shipmentcost_budgetid = ?
351           AND closedate IS NULL
352     |);
353     $sth->execute($budget_id);
354     my ($shipmentcost_sum) = $sth->fetchrow_array;
355     $sum += $shipmentcost_sum;
356
357         return $sum;
358 }
359
360 =head2 GetBudgetName
361
362   my $budget_name = &GetBudgetName($budget_id);
363
364 get the budget_name for a given budget_id
365
366 =cut
367
368 sub GetBudgetName {
369     my ( $budget_id ) = @_;
370     my $dbh         = C4::Context->dbh;
371     my $sth         = $dbh->prepare(
372         qq|
373         SELECT budget_name
374         FROM aqbudgets
375         WHERE budget_id = ?
376     |);
377
378     $sth->execute($budget_id);
379     return $sth->fetchrow_array;
380 }
381
382 # -------------------------------------------------------------------
383 sub GetBudgetAuthCats  {
384     my ($budget_period_id) = shift;
385     # now, populate the auth_cats_loop used in the budget planning button
386     # we must retrieve all auth values used by at least one budget
387     my $dbh = C4::Context->dbh;
388     my $sth=$dbh->prepare("SELECT sort1_authcat,sort2_authcat FROM aqbudgets WHERE budget_period_id=?");
389     $sth->execute($budget_period_id);
390     my %authcats;
391     while (my ($sort1_authcat,$sort2_authcat) = $sth->fetchrow) {
392         $authcats{$sort1_authcat}=1;
393         $authcats{$sort2_authcat}=1;
394     }
395     my @auth_cats_loop;
396     foreach (sort keys %authcats) {
397         push @auth_cats_loop,{ authcat => $_ };
398     }
399     return \@auth_cats_loop;
400 }
401
402 # -------------------------------------------------------------------
403 sub GetBudgetPeriods {
404         my ($filters,$orderby) = @_;
405     return SearchInTable("aqbudgetperiods",$filters, $orderby, undef,undef, undef, "wide");
406 }
407 # -------------------------------------------------------------------
408 sub GetBudgetPeriod {
409         my ($budget_period_id) = @_;
410         my $dbh = C4::Context->dbh;
411         ## $total = number of records linked to the record that must be deleted
412         my $total = 0;
413         ## get information about the record that will be deleted
414         my $sth;
415         if ($budget_period_id) {
416                 $sth = $dbh->prepare( qq|
417               SELECT      *
418                 FROM aqbudgetperiods
419                 WHERE budget_period_id=? |
420                 );
421                 $sth->execute($budget_period_id);
422         } else {         # ACTIVE BUDGET
423                 $sth = $dbh->prepare(qq|
424                           SELECT      *
425                 FROM aqbudgetperiods
426                 WHERE budget_period_active=1 |
427                 );
428                 $sth->execute();
429         }
430         my $data = $sth->fetchrow_hashref;
431         return $data;
432 }
433
434 # -------------------------------------------------------------------
435 sub DelBudgetPeriod{
436         my ($budget_period_id) = @_;
437         my $dbh = C4::Context->dbh;
438           ; ## $total = number of records linked to the record that must be deleted
439     my $total = 0;
440
441         ## get information about the record that will be deleted
442         my $sth = $dbh->prepare(qq|
443                 DELETE 
444          FROM aqbudgetperiods
445          WHERE budget_period_id=? |
446         );
447         return $sth->execute($budget_period_id);
448 }
449
450 # -------------------------------------------------------------------
451 sub ModBudgetPeriod {
452         my ($budget_period_information) = @_;
453         return UpdateInTable("aqbudgetperiods",$budget_period_information);
454 }
455
456 # -------------------------------------------------------------------
457 sub GetBudgetHierarchy {
458     my ( $budget_period_id, $branchcode, $owner ) = @_;
459     my @bind_params;
460     my $dbh   = C4::Context->dbh;
461     my $query = qq|
462                     SELECT aqbudgets.*, aqbudgetperiods.budget_period_active, aqbudgetperiods.budget_period_description
463                     FROM aqbudgets 
464                     JOIN aqbudgetperiods USING (budget_period_id)|;
465                         
466         my @where_strings;
467     # show only period X if requested
468     if ($budget_period_id) {
469         push @where_strings," aqbudgets.budget_period_id = ?";
470         push @bind_params, $budget_period_id;
471     }
472         # show only budgets owned by me, my branch or everyone
473     if ($owner) {
474         if ($branchcode) {
475             push @where_strings,
476             qq{ (budget_owner_id = ? OR budget_branchcode = ? OR ((budget_branchcode IS NULL or budget_branchcode="") AND (budget_owner_id IS NULL OR budget_owner_id="")))};
477             push @bind_params, ( $owner, $branchcode );
478         } else {
479             push @where_strings, ' (budget_owner_id = ? OR budget_owner_id IS NULL or budget_owner_id ="") ';
480             push @bind_params, $owner;
481         }
482     } else {
483         if ($branchcode) {
484             push @where_strings," (budget_branchcode =? or budget_branchcode is NULL)";
485             push @bind_params, $branchcode;
486         }
487     }
488         $query.=" WHERE ".join(' AND ', @where_strings) if @where_strings;
489         $debug && warn $query,join(",",@bind_params);
490         my $sth = $dbh->prepare($query);
491         $sth->execute(@bind_params);
492         my $results = $sth->fetchall_arrayref({});
493         my @res     = @$results;
494         my $i = 0;
495         while (1) {
496                 my $depth_cnt = 0;
497                 foreach my $r (@res) {
498                         my @child;
499                         # look for children
500                         $r->{depth} = '0' if !defined $r->{budget_parent_id};
501                         foreach my $r2 (@res) {
502                                 if (defined $r2->{budget_parent_id}
503                                         && $r2->{budget_parent_id} == $r->{budget_id}) {
504                                         push @child, $r2->{budget_id};
505                                         $r2->{depth} = ($r->{depth} + 1) if defined $r->{depth};
506                                 }
507                         }
508                         $r->{child} = \@child if scalar @child > 0;    # add the child
509                         $depth_cnt++ if !defined $r->{'depth'};
510                 }
511                 last if ($depth_cnt == 0 || $i == 100);
512                 $i++;
513         }
514
515         # look for top parents 1st
516         my (@sort, $depth_count);
517         ($i, $depth_count) = 0;
518         while (1) {
519                 my $children = 0;
520                 foreach my $r (@res) {
521                         if ($r->{depth} == $depth_count) {
522                                 $children++ if (ref $r->{child} eq 'ARRAY');
523
524                                 # find the parent id element_id and insert it after
525                                 my $i2 = 0;
526                                 my $parent;
527                                 if ($depth_count > 0) {
528
529                                         # add indent
530                                         my $depth = $r->{depth} * 2;
531                                         $r->{budget_code_indent} = $r->{budget_code};
532                                         $r->{budget_name_indent} = $r->{budget_name};
533                                         foreach my $r3 (@sort) {
534                                                 if ($r3->{budget_id} == $r->{budget_parent_id}) {
535                                                         $parent = $i2;
536                                                         last;
537                                                 }
538                                                 $i2++;
539                                         }
540                                 } else {
541                                         $r->{budget_code_indent} = $r->{budget_code};
542                                         $r->{budget_name_indent} = $r->{budget_name};
543                                 }
544                 
545                                 if (defined $parent) {
546                                         splice @sort, ($parent + 1), 0, $r;
547                                 } else {
548                                         push @sort, $r;
549                                 }
550                         }
551
552                         $i++;
553                 }    # --------------foreach
554                 $depth_count++;
555                 last if $children == 0;
556         }
557
558 # add budget-percent and allocation, and flags for html-template
559         foreach my $r (@sort) {
560                 my $subs_href = $r->{'child'};
561         my @subs_arr = ();
562         if ( defined $subs_href ) {
563             @subs_arr = @{$subs_href};
564         }
565
566         my $moo = $r->{'budget_code_indent'};
567         $moo =~ s/\ /\&nbsp\;/g;
568         $r->{'budget_code_indent'} =  $moo;
569
570         $moo = $r->{'budget_name_indent'};
571         $moo =~ s/\ /\&nbsp\;/g;
572         $r->{'budget_name_indent'} = $moo;
573
574         $r->{'budget_spent'}       = GetBudgetSpent( $r->{'budget_id'} );
575         $r->{budget_ordered} = GetBudgetOrdered( $r->{budget_id} );
576
577         $r->{budget_spent_sublevels} = 0;
578         $r->{budget_ordered_sublevels} = 0;
579         # foreach sub-levels
580                 foreach my $sub (@subs_arr) {
581                         my $sub_budget = GetBudget($sub);
582             $r->{budget_spent_sublevels} += GetBudgetSpent( $sub_budget->{'budget_id'} );
583             $r->{budget_ordered_sublevels} += GetBudgetOrdered($sub);
584                 }
585         }
586         return \@sort;
587 }
588
589 # -------------------------------------------------------------------
590
591 sub AddBudget {
592     my ($budget) = @_;
593         return InsertInTable("aqbudgets",$budget);
594 }
595
596 # -------------------------------------------------------------------
597 sub ModBudget {
598     my ($budget) = @_;
599         return UpdateInTable("aqbudgets",$budget);
600 }
601
602 # -------------------------------------------------------------------
603 sub DelBudget {
604         my ($budget_id) = @_;
605         my $dbh         = C4::Context->dbh;
606         my $sth         = $dbh->prepare("delete from aqbudgets where budget_id=?");
607         my $rc          = $sth->execute($budget_id);
608         return $rc;
609 }
610
611
612 =head2 GetBudget
613
614   &GetBudget($budget_id);
615
616 get a specific budget
617
618 =cut
619
620 # -------------------------------------------------------------------
621 sub GetBudget {
622     my ( $budget_id ) = @_;
623     my $dbh = C4::Context->dbh;
624     my $query = "
625         SELECT *
626         FROM   aqbudgets
627         WHERE  budget_id=?
628         ";
629     my $sth = $dbh->prepare($query);
630     $sth->execute( $budget_id );
631     my $result = $sth->fetchrow_hashref;
632     return $result;
633 }
634
635 =head2 GetBudgetByOrderNumber
636
637   &GetBudgetByOrderNumber($ordernumber);
638
639 get a specific budget by order number
640
641 =cut
642
643 # -------------------------------------------------------------------
644 sub GetBudgetByOrderNumber {
645     my ( $ordernumber ) = @_;
646     my $dbh = C4::Context->dbh;
647     my $query = "
648         SELECT aqbudgets.*
649         FROM   aqbudgets, aqorders
650         WHERE  ordernumber=?
651         AND    aqorders.budget_id = aqbudgets.budget_id
652         ";
653     my $sth = $dbh->prepare($query);
654     $sth->execute( $ordernumber );
655     my $result = $sth->fetchrow_hashref;
656     return $result;
657 }
658
659 =head2 GetBudgetByCode
660
661     my $budget = &GetBudgetByCode($budget_code);
662
663 Retrieve all aqbudgets fields as a hashref for the budget that has
664 given budget_code
665
666 =cut
667
668 sub GetBudgetByCode {
669     my ( $budget_code ) = @_;
670
671     my $dbh = C4::Context->dbh;
672     my $query = qq{
673         SELECT *
674         FROM aqbudgets
675         WHERE budget_code = ?
676         ORDER BY budget_id DESC
677         LIMIT 1
678     };
679     my $sth = $dbh->prepare( $query );
680     $sth->execute( $budget_code );
681     return $sth->fetchrow_hashref;
682 }
683
684 =head2 GetChildBudgetsSpent
685
686   &GetChildBudgetsSpent($budget-id);
687
688 gets the total spent of the level and sublevels of $budget_id
689
690 =cut
691
692 # -------------------------------------------------------------------
693 sub GetChildBudgetsSpent {
694     my ( $budget_id ) = @_;
695     my $dbh = C4::Context->dbh;
696     my $query = "
697         SELECT *
698         FROM   aqbudgets
699         WHERE  budget_parent_id=?
700         ";
701     my $sth = $dbh->prepare($query);
702     $sth->execute( $budget_id );
703     my $result = $sth->fetchall_arrayref({});
704     my $total_spent = GetBudgetSpent($budget_id);
705     if ($result){
706         $total_spent += GetChildBudgetsSpent($_->{"budget_id"}) foreach @$result;    
707     }
708     return $total_spent;
709 }
710
711 =head2 GetBudgets
712
713   &GetBudgets($filter, $order_by);
714
715 gets all budgets
716
717 =cut
718
719 # -------------------------------------------------------------------
720 sub GetBudgets {
721     my $filters = shift;
722     my $orderby = shift || 'budget_name';
723     return SearchInTable("aqbudgets",$filters, $orderby, undef,undef, undef, "wide");
724 }
725
726 =head2 GetBudgetUsers
727
728     my @borrowernumbers = &GetBudgetUsers($budget_id);
729
730 Return the list of borrowernumbers linked to a budget
731
732 =cut
733
734 sub GetBudgetUsers {
735     my ($budget_id) = @_;
736
737     my $dbh = C4::Context->dbh;
738     my $query = qq{
739         SELECT borrowernumber
740         FROM aqbudgetborrowers
741         WHERE budget_id = ?
742     };
743     my $sth = $dbh->prepare($query);
744     $sth->execute($budget_id);
745
746     my @borrowernumbers;
747     while (my ($borrowernumber) = $sth->fetchrow_array) {
748         push @borrowernumbers, $borrowernumber
749     }
750
751     return @borrowernumbers;
752 }
753
754 =head2 ModBudgetUsers
755
756     &ModBudgetUsers($budget_id, @borrowernumbers);
757
758 Modify the list of borrowernumbers linked to a budget
759
760 =cut
761
762 sub ModBudgetUsers {
763     my ($budget_id, @budget_users_id) = @_;
764
765     return unless $budget_id;
766
767     my $dbh = C4::Context->dbh;
768     my $query = "DELETE FROM aqbudgetborrowers WHERE budget_id = ?";
769     my $sth = $dbh->prepare($query);
770     $sth->execute($budget_id);
771
772     $query = qq{
773         INSERT INTO aqbudgetborrowers (budget_id, borrowernumber)
774         VALUES (?,?)
775     };
776     $sth = $dbh->prepare($query);
777     foreach my $borrowernumber (@budget_users_id) {
778         next unless $borrowernumber;
779         $sth->execute($budget_id, $borrowernumber);
780     }
781 }
782
783 sub CanUserUseBudget {
784     my ($borrower, $budget, $userflags) = @_;
785
786     if (not ref $borrower) {
787         $borrower = C4::Members::GetMember(borrowernumber => $borrower);
788     }
789     if (not ref $budget) {
790         $budget = GetBudget($budget);
791     }
792
793     return 0 unless ($borrower and $budget);
794
795     if (not defined $userflags) {
796         $userflags = C4::Auth::getuserflags($borrower->{flags},
797             $borrower->{userid});
798     }
799
800     unless ($userflags->{superlibrarian}
801     || (ref $userflags->{acquisition}
802         && $userflags->{acquisition}->{budget_manage_all})
803     || (!ref $userflags->{acquisition} && $userflags->{acquisition}))
804     {
805         if (not exists $userflags->{acquisition}) {
806             return 0;
807         }
808
809         if (!ref $userflags->{acquisition} && !$userflags->{acquisition}) {
810             return 0;
811         }
812
813         # Budget restricted to owner
814         if ( $budget->{budget_permission} == 1 ) {
815             if (    $budget->{budget_owner_id}
816                 and $budget->{budget_owner_id} != $borrower->{borrowernumber} )
817             {
818                 return 0;
819             }
820         }
821
822         # Budget restricted to owner, users and library
823         elsif ( $budget->{budget_permission} == 2 ) {
824             my @budget_users = GetBudgetUsers( $budget->{budget_id} );
825
826             if (
827                 (
828                         $budget->{budget_owner_id}
829                     and $budget->{budget_owner_id} !=
830                     $borrower->{borrowernumber}
831                     or not $budget->{budget_owner_id}
832                 )
833                 and ( 0 == grep { $borrower->{borrowernumber} == $_ }
834                     @budget_users )
835                 and defined $budget->{budget_branchcode}
836                 and $budget->{budget_branchcode} ne
837                 C4::Context->userenv->{branch}
838               )
839             {
840                 return 0;
841             }
842         }
843
844         # Budget restricted to owner and users
845         elsif ( $budget->{budget_permission} == 3 ) {
846             my @budget_users = GetBudgetUsers( $budget->{budget_id} );
847             if (
848                 (
849                         $budget->{budget_owner_id}
850                     and $budget->{budget_owner_id} !=
851                     $borrower->{borrowernumber}
852                     or not $budget->{budget_owner_id}
853                 )
854                 and ( 0 == grep { $borrower->{borrowernumber} == $_ }
855                     @budget_users )
856               )
857             {
858                 return 0;
859             }
860         }
861     }
862
863     return 1;
864 }
865
866 sub CanUserModifyBudget {
867     my ($borrower, $budget, $userflags) = @_;
868
869     if (not ref $borrower) {
870         $borrower = C4::Members::GetMember(borrowernumber => $borrower);
871     }
872     if (not ref $budget) {
873         $budget = GetBudget($budget);
874     }
875
876     return 0 unless ($borrower and $budget);
877
878     if (not defined $userflags) {
879         $userflags = C4::Auth::getuserflags($borrower->{flags},
880             $borrower->{userid});
881     }
882
883     unless ($userflags->{superlibrarian}
884     || (ref $userflags->{acquisition}
885         && $userflags->{acquisition}->{budget_manage_all})
886     || (!ref $userflags->{acquisition} && $userflags->{acquisition}))
887     {
888         if (!CanUserUseBudget($borrower, $budget, $userflags)) {
889             return 0;
890         }
891
892         if (ref $userflags->{acquisition}
893         && !$userflags->{acquisition}->{budget_modify}) {
894             return 0;
895         }
896     }
897
898     return 1;
899 }
900
901 # -------------------------------------------------------------------
902
903 =head2 GetCurrencies
904
905   @currencies = &GetCurrencies;
906
907 Returns the list of all known currencies.
908
909 C<$currencies> is a array; its elements are references-to-hash, whose
910 keys are the fields from the currency table in the Koha database.
911
912 =cut
913
914 sub GetCurrencies {
915     my $dbh   = C4::Context->dbh;
916     my $query = "
917         SELECT *
918         FROM   currency
919     ";
920     my $sth = $dbh->prepare($query);
921     $sth->execute;
922     my @results = ();
923     while ( my $data = $sth->fetchrow_hashref ) {
924         push( @results, $data );
925     }
926     return @results;
927 }
928
929 # -------------------------------------------------------------------
930
931 sub GetCurrency {
932     my $dbh   = C4::Context->dbh;
933     my $query = "
934         SELECT * FROM currency where active = '1'    ";
935     my $sth = $dbh->prepare($query);
936     $sth->execute;
937     my $r = $sth->fetchrow_hashref;
938     return $r;
939 }
940
941 =head2 ModCurrencies
942
943 &ModCurrencies($currency, $newrate);
944
945 Sets the exchange rate for C<$currency> to be C<$newrate>.
946
947 =cut
948
949 sub ModCurrencies {
950     my ( $currency, $rate ) = @_;
951     my $dbh   = C4::Context->dbh;
952     my $query = qq|
953         UPDATE currency
954         SET    rate=?
955         WHERE  currency=? |;
956     my $sth = $dbh->prepare($query);
957     $sth->execute( $rate, $currency );
958 }
959
960 # -------------------------------------------------------------------
961
962 =head2 ConvertCurrency
963
964   $foreignprice = &ConvertCurrency($currency, $localprice);
965
966 Converts the price C<$localprice> to foreign currency C<$currency> by
967 dividing by the exchange rate, and returns the result.
968
969 If no exchange rate is found, e is one to one.
970
971 =cut
972
973 sub ConvertCurrency {
974     my ( $currency, $price ) = @_;
975     my $dbh   = C4::Context->dbh;
976     my $query = "
977         SELECT rate
978         FROM   currency
979         WHERE  currency=?
980     ";
981     my $sth = $dbh->prepare($query);
982     $sth->execute($currency);
983     my $cur = ( $sth->fetchrow_array() )[0];
984     unless ($cur) {
985         $cur = 1;
986     }
987     return ( $price / $cur );
988 }
989
990 END { }    # module clean-up code here (global destructor)
991
992 1;
993 __END__
994
995 =head1 AUTHOR
996
997 Koha Development Team <http://koha-community.org/>
998
999 =cut