3 # Copyright 2000-2002 Katipo Communications
5 # This file is part of Koha.
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
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.
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.
21 #use warnings; FIXME - Bug 2505
23 use C4
::Dates
qw(format_date format_date_in_iso);
24 use C4
::SQLHelper qw
<:all
>;
27 use vars
qw($VERSION @ISA @EXPORT);
30 # set the version for version checking
67 &CheckBudgetParentPerm
74 # ----------------------------BUDGETS.PM-----------------------------";
77 =head1 FUNCTIONS ABOUT BUDGETS
82 my ( $authcat, @hide_cols ) = @_;
83 my $dbh = C4
::Context
->dbh;
85 my $sth1 = $dbh->prepare(
87 UPDATE aqbudgets_planning SET display
= 0
91 foreach my $authvalue (@hide_cols) {
92 # $sth1->{TraceLevel} = 3;
93 $sth1->execute( $authcat, $authvalue );
98 my ( $authcat, $authvalue ) = @_;
100 my $dbh = C4
::Context
->dbh;
101 my $sth = $dbh->prepare(
103 SELECT count
(display
) as cnt from aqbudgets_planning
105 AND authvalue
= ?
and display
= 0 |
108 # $sth->{TraceLevel} = 3;
109 $sth->execute( $authcat, $authvalue );
110 my $res = $sth->fetchrow_hashref;
112 return $res->{cnt
} > 0 ?
0: 1
116 sub CheckBudgetParentPerm
{
117 my ( $budget, $borrower_id ) = @_;
118 my $depth = $budget->{depth
};
119 my $parent_id = $budget->{budget_parent_id
};
121 my $parent = GetBudget
($parent_id);
122 $parent_id = $parent->{budget_parent_id
};
123 if ( $parent->{budget_owner_id
} == $borrower_id ) {
131 sub AddBudgetPeriod
{
132 my ($budgetperiod) = @_;
133 return InsertInTable
("aqbudgetperiods",$budgetperiod);
135 # -------------------------------------------------------------------
136 sub GetPeriodsCount
{
137 my $dbh = C4
::Context
->dbh;
138 my $sth = $dbh->prepare("
139 SELECT COUNT(*) AS sum FROM aqbudgetperiods ");
141 my $res = $sth->fetchrow_hashref;
142 return $res->{'sum'};
145 # -------------------------------------------------------------------
146 sub CheckBudgetParent
{
147 my ( $new_parent, $budget ) = @_;
148 my $new_parent_id = $new_parent->{'budget_id'};
149 my $budget_id = $budget->{'budget_id'};
150 my $dbh = C4
::Context
->dbh;
151 my $parent_id_tmp = $new_parent_id;
153 # check new-parent is not a child (or a child's child ;)
154 my $sth = $dbh->prepare(qq|
155 SELECT budget_parent_id FROM
156 aqbudgets where budget_id
= ?
| );
158 $sth->execute($parent_id_tmp);
159 my $res = $sth->fetchrow_hashref;
160 if ( $res->{'budget_parent_id'} == $budget_id ) {
163 if ( not defined $res->{'budget_parent_id'} ) {
166 $parent_id_tmp = $res->{'budget_parent_id'};
170 # -------------------------------------------------------------------
171 sub BudgetHasChildren
{
172 my ( $budget_id ) = @_;
173 my $dbh = C4
::Context
->dbh;
174 my $sth = $dbh->prepare(qq|
175 SELECT count
(*) as sum FROM aqbudgets
176 WHERE budget_parent_id
= ?
| );
177 $sth->execute( $budget_id );
178 my $sum = $sth->fetchrow_hashref;
179 return $sum->{'sum'};
182 # -------------------------------------------------------------------
183 sub GetBudgetsPlanCell
{
184 my ( $cell, $period, $budget ) = @_;
186 my $dbh = C4
::Context
->dbh;
187 if ( $cell->{'authcat'} eq 'MONTHS' ) {
188 # get the actual amount
189 $sth = $dbh->prepare( qq|
191 SELECT SUM
(ecost
) AS actual FROM aqorders
192 WHERE budget_id
= ? AND
193 entrydate like
"$cell->{'authvalue'}%" |
195 $sth->execute( $cell->{'budget_id'} );
196 } elsif ( $cell->{'authcat'} eq 'BRANCHES' ) {
197 # get the actual amount
198 $sth = $dbh->prepare( qq|
200 SELECT SUM
(ecost
) FROM aqorders
201 LEFT JOIN aqorders_items
202 ON
(aqorders
.ordernumber
= aqorders_items
.ordernumber
)
204 ON
(aqorders_items
.itemnumber
= items
.itemnumber
)
205 WHERE budget_id
= ? AND homebranch
= ?
| );
207 $sth->execute( $cell->{'budget_id'}, $cell->{'authvalue'} );
208 } elsif ( $cell->{'authcat'} eq 'ITEMTYPES' ) {
209 # get the actual amount
210 $sth = $dbh->prepare( qq|
212 SELECT SUM
( ecost
* quantity
) AS actual
213 FROM aqorders JOIN biblioitems
214 ON
(biblioitems
.biblionumber
= aqorders
.biblionumber
)
215 WHERE aqorders
.budget_id
= ?
and itemtype
= ?
|
217 $sth->execute( $cell->{'budget_id'},
218 $cell->{'authvalue'} );
220 # ELSE GENERIC ORDERS SORT1/SORT2 STAT COUNT.
222 # get the actual amount
223 $sth = $dbh->prepare( qq|
225 SELECT SUM
(ecost
* quantity
) AS actual
227 JOIN aqbudgets ON
(aqbudgets
.budget_id
= aqorders
.budget_id
)
228 WHERE aqorders
.budget_id
= ? AND
229 ((aqbudgets
.sort1_authcat
= ? AND sort1
=?
) OR
230 (aqbudgets
.sort2_authcat
= ? AND sort2
=?
)) |
232 $sth->execute( $cell->{'budget_id'},
233 $budget->{'sort1_authcat'},
234 $cell->{'authvalue'},
235 $budget->{'sort2_authcat'},
239 $actual = $sth->fetchrow_array;
241 # get the estimated amount
242 $sth = $dbh->prepare( qq|
244 SELECT estimated_amount AS estimated
, display FROM aqbudgets_planning
245 WHERE budget_period_id
= ? AND
250 $sth->execute( $cell->{'budget_period_id'},
251 $cell->{'budget_id'},
252 $cell->{'authvalue'},
257 my $res = $sth->fetchrow_hashref;
258 # my $display = $res->{'display'};
259 my $estimated = $res->{'estimated'};
262 return $actual, $estimated;
265 # -------------------------------------------------------------------
267 my ( $budget_plan, $budget_period_id, $authcat ) = @_;
268 my $dbh = C4
::Context
->dbh;
269 foreach my $buds (@
$budget_plan) {
270 my $lines = $buds->{lines
};
271 my $sth = $dbh->prepare( qq|
272 DELETE FROM aqbudgets_planning
273 WHERE budget_period_id
= ? AND
277 #delete a aqplan line of cells, then insert new cells,
278 # these could be UPDATES rather than DEL/INSERTS...
279 $sth->execute( $budget_period_id, $lines->[0]{budget_id
} , $authcat );
281 foreach my $cell (@
$lines) {
282 my $sth = $dbh->prepare( qq|
284 INSERT INTO aqbudgets_planning
286 budget_period_id
= ?
,
288 estimated_amount
= ?
,
292 $cell->{'budget_id'},
293 $cell->{'budget_period_id'},
295 $cell->{'estimated_amount'},
296 $cell->{'authvalue'},
302 # -------------------------------------------------------------------
304 my ($budget_id) = @_;
305 my $dbh = C4
::Context
->dbh;
306 my $sth = $dbh->prepare(qq|
307 SELECT SUM
( COALESCE
(unitprice
, ecost
) * quantity
) AS sum FROM aqorders
308 WHERE budget_id
= ? AND
309 quantityreceived
> 0 AND
310 datecancellationprinted IS NULL
313 $sth->execute($budget_id);
314 my $sum = $sth->fetchrow_array;
318 # -------------------------------------------------------------------
319 sub GetBudgetOrdered
{
320 my ($budget_id) = @_;
321 my $dbh = C4
::Context
->dbh;
322 my $sth = $dbh->prepare(qq|
323 SELECT SUM
(ecost
* quantity
) AS sum FROM aqorders
324 WHERE budget_id
= ? AND
325 quantityreceived
= 0 AND
326 datecancellationprinted IS NULL
329 $sth->execute($budget_id);
330 my $sum = $sth->fetchrow_array;
334 # -------------------------------------------------------------------
335 sub GetBudgetAuthCats
{
336 my ($budget_period_id) = shift;
337 # now, populate the auth_cats_loop used in the budget planning button
338 # we must retrieve all auth values used by at least one budget
339 my $dbh = C4
::Context
->dbh;
340 my $sth=$dbh->prepare("SELECT sort1_authcat,sort2_authcat FROM aqbudgets WHERE budget_period_id=?");
341 $sth->execute($budget_period_id);
343 while (my ($sort1_authcat,$sort2_authcat) = $sth->fetchrow) {
344 $authcats{$sort1_authcat}=1;
345 $authcats{$sort2_authcat}=1;
348 foreach (sort keys %authcats) {
349 push @auth_cats_loop,{ authcat
=> $_ };
351 return \
@auth_cats_loop;
354 # -------------------------------------------------------------------
355 sub GetAuthvalueDropbox
{
356 my ( $authcat, $default ) = @_;
357 my $dbh = C4
::Context
->dbh;
358 my $sth = $dbh->prepare(
359 'SELECT authorised_value,lib FROM authorised_values
360 WHERE category = ? ORDER BY lib'
362 $sth->execute( $authcat );
363 my $option_list = [];
364 my @authorised_values = ( q{} );
365 while (my ($value, $lib) = $sth->fetchrow_array) {
366 push @
{$option_list}, {
369 default => ($default eq $value),
373 if ( @
{$option_list} ) {
379 # -------------------------------------------------------------------
380 sub GetBudgetPeriods
{
381 my ($filters,$orderby) = @_;
382 return SearchInTable
("aqbudgetperiods",$filters, $orderby, undef,undef, undef, "wide");
384 # -------------------------------------------------------------------
385 sub GetBudgetPeriod
{
386 my ($budget_period_id) = @_;
387 my $dbh = C4
::Context
->dbh;
388 ## $total = number of records linked to the record that must be deleted
390 ## get information about the record that will be deleted
392 if ($budget_period_id) {
393 $sth = $dbh->prepare( qq|
396 WHERE budget_period_id
=?
|
398 $sth->execute($budget_period_id);
399 } else { # ACTIVE BUDGET
400 $sth = $dbh->prepare(qq|
403 WHERE budget_period_active
=1 |
407 my $data = $sth->fetchrow_hashref;
411 # -------------------------------------------------------------------
413 my ($budget_period_id) = @_;
414 my $dbh = C4
::Context
->dbh;
415 ; ## $total = number of records linked to the record that must be deleted
418 ## get information about the record that will be deleted
419 my $sth = $dbh->prepare(qq|
422 WHERE budget_period_id
=?
|
424 return $sth->execute($budget_period_id);
427 # -------------------------------------------------------------------
428 sub ModBudgetPeriod
{
429 my ($budget_period_information) = @_;
430 return UpdateInTable
("aqbudgetperiods",$budget_period_information);
433 # -------------------------------------------------------------------
434 sub GetBudgetHierarchy
{
435 my ( $budget_period_id, $branchcode, $owner ) = @_;
437 my $dbh = C4
::Context
->dbh;
439 SELECT aqbudgets
.*, aqbudgetperiods
.budget_period_active
441 JOIN aqbudgetperiods USING
(budget_period_id
)|;
444 # show only period X if requested
445 if ($budget_period_id) {
446 push @where_strings," aqbudgets.budget_period_id = ?";
447 push @bind_params, $budget_period_id;
449 # show only budgets owned by me, my branch or everyone
453 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
="")))};
454 push @bind_params, ( $owner, $branchcode );
456 push @where_strings, ' (budget_owner_id = ? OR budget_owner_id IS NULL or budget_owner_id ="") ';
457 push @bind_params, $owner;
461 push @where_strings," (budget_branchcode =? or budget_branchcode is NULL)";
462 push @bind_params, $branchcode;
465 $query.=" WHERE ".join(' AND ', @where_strings) if @where_strings;
466 $debug && warn $query,join(",",@bind_params);
467 my $sth = $dbh->prepare($query);
468 $sth->execute(@bind_params);
469 my $results = $sth->fetchall_arrayref({});
474 foreach my $r (@res) {
477 $r->{depth
} = '0' if !defined $r->{budget_parent_id
};
478 foreach my $r2 (@res) {
479 if (defined $r2->{budget_parent_id
}
480 && $r2->{budget_parent_id
} == $r->{budget_id
}) {
481 push @child, $r2->{budget_id
};
482 $r2->{depth
} = ($r->{depth
} + 1) if defined $r->{depth
};
485 $r->{child
} = \
@child if scalar @child > 0; # add the child
486 $depth_cnt++ if !defined $r->{'depth'};
488 last if ($depth_cnt == 0 || $i == 100);
492 # look for top parents 1st
493 my (@sort, $depth_count);
494 ($i, $depth_count) = 0;
497 foreach my $r (@res) {
498 if ($r->{depth
} == $depth_count) {
499 $children++ if (ref $r->{child
} eq 'ARRAY');
501 # find the parent id element_id and insert it after
504 if ($depth_count > 0) {
507 my $depth = $r->{depth
} * 2;
508 $r->{budget_code_indent
} = $r->{budget_code
};
509 $r->{budget_name_indent
} = $r->{budget_name
};
510 foreach my $r3 (@sort) {
511 if ($r3->{budget_id
} == $r->{budget_parent_id
}) {
518 $r->{budget_code_indent
} = $r->{budget_code
};
519 $r->{budget_name_indent
} = $r->{budget_name
};
522 if (defined $parent) {
523 splice @sort, ($parent + 1), 0, $r;
530 } # --------------foreach
532 last if $children == 0;
535 # add budget-percent and allocation, and flags for html-template
536 foreach my $r (@sort) {
537 my $subs_href = $r->{'child'};
539 if ( defined $subs_href ) {
540 @subs_arr = @
{$subs_href};
543 my $moo = $r->{'budget_code_indent'};
544 $moo =~ s/\ /\ \;/g;
545 $r->{'budget_code_indent'} = $moo;
547 $moo = $r->{'budget_name_indent'};
548 $moo =~ s/\ /\ \;/g;
549 $r->{'budget_name_indent'} = $moo;
551 $r->{'budget_spent'} = GetBudgetSpent
( $r->{'budget_id'} );
553 $r->{'budget_amount_total'} = $r->{'budget_amount'};
558 foreach my $sub (@subs_arr) {
559 my $sub_budget = GetBudget
($sub);
561 $r->{budget_spent_sublevel
} += GetBudgetSpent
( $sub_budget->{'budget_id'} );
562 $unalloc_count += $sub_budget->{'budget_amount'};
568 # -------------------------------------------------------------------
572 return InsertInTable
("aqbudgets",$budget);
575 # -------------------------------------------------------------------
578 return UpdateInTable
("aqbudgets",$budget);
581 # -------------------------------------------------------------------
583 my ($budget_id) = @_;
584 my $dbh = C4
::Context
->dbh;
585 my $sth = $dbh->prepare("delete from aqbudgets where budget_id=?");
586 my $rc = $sth->execute($budget_id);
593 &GetBudget($budget_id);
595 get a specific budget
599 # -------------------------------------------------------------------
601 my ( $budget_id ) = @_;
602 my $dbh = C4
::Context
->dbh;
608 my $sth = $dbh->prepare($query);
609 $sth->execute( $budget_id );
610 my $result = $sth->fetchrow_hashref;
614 =head2 GetChildBudgetsSpent
616 &GetChildBudgetsSpent($budget-id);
618 gets the total spent of the level and sublevels of $budget_id
622 # -------------------------------------------------------------------
623 sub GetChildBudgetsSpent
{
624 my ( $budget_id ) = @_;
625 my $dbh = C4
::Context
->dbh;
629 WHERE budget_parent_id=?
631 my $sth = $dbh->prepare($query);
632 $sth->execute( $budget_id );
633 my $result = $sth->fetchall_arrayref({});
634 my $total_spent = GetBudgetSpent
($budget_id);
636 $total_spent += GetChildBudgetsSpent
($_->{"budget_id"}) foreach @
$result;
643 &GetBudgets($filter, $order_by);
649 # -------------------------------------------------------------------
651 my ($filters,$orderby) = @_;
652 return SearchInTable
("aqbudgets",$filters, $orderby, undef,undef, undef, "wide");
655 # -------------------------------------------------------------------
659 @currencies = &GetCurrencies;
661 Returns the list of all known currencies.
663 C<$currencies> is a array; its elements are references-to-hash, whose
664 keys are the fields from the currency table in the Koha database.
669 my $dbh = C4
::Context
->dbh;
674 my $sth = $dbh->prepare($query);
677 while ( my $data = $sth->fetchrow_hashref ) {
678 push( @results, $data );
683 # -------------------------------------------------------------------
686 my $dbh = C4
::Context
->dbh;
688 SELECT * FROM currency where active = '1' ";
689 my $sth = $dbh->prepare($query);
691 my $r = $sth->fetchrow_hashref;
697 &ModCurrencies($currency, $newrate);
699 Sets the exchange rate for C<$currency> to be C<$newrate>.
704 my ( $currency, $rate ) = @_;
705 my $dbh = C4
::Context
->dbh;
710 my $sth = $dbh->prepare($query);
711 $sth->execute( $rate, $currency );
714 # -------------------------------------------------------------------
716 =head2 ConvertCurrency
718 $foreignprice = &ConvertCurrency($currency, $localprice);
720 Converts the price C<$localprice> to foreign currency C<$currency> by
721 dividing by the exchange rate, and returns the result.
723 If no exchange rate is found, e is one to one.
727 sub ConvertCurrency
{
728 my ( $currency, $price ) = @_;
729 my $dbh = C4
::Context
->dbh;
735 my $sth = $dbh->prepare($query);
736 $sth->execute($currency);
737 my $cur = ( $sth->fetchrow_array() )[0];
741 return ( $price / $cur );
746 returns an array containing fieldname followed by PRI as value if PRIMARY Key
751 my $tablename=shift||"aqbudgets";
752 return @
{C4
::Context
->dbh->selectcol_arrayref("SHOW columns from $tablename",{Columns
=>[1,4]})};
760 my %columns= _columns
($tablename);
761 #Filter Primary Keys of table
762 my $elements=join "|",grep {$columns{$_} ne "PRI"} keys %columns;
763 foreach my $field (grep {/\b($elements)\b/} keys %$budget){
764 $$budget{$field}=format_date_in_iso
($$budget{$field}) if ($field=~/date/ && $$budget{$field} !~C4
::Dates
->regexp("iso"));
765 my $strkeys= " $field = ? ";
766 if ($field=~/branch/){
767 $strkeys="( $strkeys OR $field='' OR $field IS NULL) ";
769 push @values, $$budget{$field};
770 push @keys, $strkeys;
772 return (\
@keys,\
@values);
775 END { } # module clean-up code here (global destructor)
782 Koha Development Team <http://koha-community.org/>