Bug 16610 - Regression in SIP2 user password handling
[koha.git] / C4 / Budgets.pm
blobcd7198a8c5f948c24f43d6a015bd8eb5ab727dd8
1 package C4::Budgets;
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
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
20 use strict;
21 #use warnings; FIXME - Bug 2505
22 use C4::Context;
23 use Koha::Database;
24 use C4::Debug;
25 use vars qw($VERSION @ISA @EXPORT);
27 BEGIN {
28 # set the version for version checking
29 $VERSION = 3.07.00.049;
30 require Exporter;
31 @ISA = qw(Exporter);
32 @EXPORT = qw(
34 &GetBudget
35 &GetBudgetByOrderNumber
36 &GetBudgetByCode
37 &GetBudgets
38 &GetBudgetHierarchy
39 &AddBudget
40 &ModBudget
41 &DelBudget
42 &GetBudgetSpent
43 &GetBudgetOrdered
44 &GetBudgetName
45 &GetPeriodsCount
46 GetBudgetHierarchySpent
47 GetBudgetHierarchyOrdered
49 &GetBudgetUsers
50 &ModBudgetUsers
51 &CanUserUseBudget
52 &CanUserModifyBudget
54 &GetBudgetPeriod
55 &GetBudgetPeriods
56 &ModBudgetPeriod
57 &AddBudgetPeriod
58 &DelBudgetPeriod
60 &ModBudgetPlan
62 &GetCurrency
63 &GetCurrencies
64 &ConvertCurrency
66 &GetBudgetsPlanCell
67 &AddBudgetPlanValue
68 &GetBudgetAuthCats
69 &BudgetHasChildren
70 &CheckBudgetParent
71 &CheckBudgetParentPerm
73 &HideCols
74 &GetCols
78 # ----------------------------BUDGETS.PM-----------------------------";
81 =head1 FUNCTIONS ABOUT BUDGETS
83 =cut
85 sub HideCols {
86 my ( $authcat, @hide_cols ) = @_;
87 my $dbh = C4::Context->dbh;
89 my $sth1 = $dbh->prepare(
90 qq|
91 UPDATE aqbudgets_planning SET display = 0
92 WHERE authcat = ?
93 AND authvalue = ? |
95 foreach my $authvalue (@hide_cols) {
96 # $sth1->{TraceLevel} = 3;
97 $sth1->execute( $authcat, $authvalue );
101 sub GetCols {
102 my ( $authcat, $authvalue ) = @_;
104 my $dbh = C4::Context->dbh;
105 my $sth = $dbh->prepare(
107 SELECT count(display) as cnt from aqbudgets_planning
108 WHERE authcat = ?
109 AND authvalue = ? and display = 0 |
112 # $sth->{TraceLevel} = 3;
113 $sth->execute( $authcat, $authvalue );
114 my $res = $sth->fetchrow_hashref;
116 return $res->{cnt} > 0 ? 0: 1
120 sub CheckBudgetParentPerm {
121 my ( $budget, $borrower_id ) = @_;
122 my $depth = $budget->{depth};
123 my $parent_id = $budget->{budget_parent_id};
124 while ($depth) {
125 my $parent = GetBudget($parent_id);
126 $parent_id = $parent->{budget_parent_id};
127 if ( $parent->{budget_owner_id} == $borrower_id ) {
128 return 1;
130 $depth--
132 return 0;
135 sub AddBudgetPeriod {
136 my ($budgetperiod) = @_;
137 return unless($budgetperiod->{budget_period_startdate} && $budgetperiod->{budget_period_enddate});
139 my $resultset = Koha::Database->new()->schema->resultset('Aqbudgetperiod');
140 return $resultset->create($budgetperiod)->id;
142 # -------------------------------------------------------------------
143 sub GetPeriodsCount {
144 my $dbh = C4::Context->dbh;
145 my $sth = $dbh->prepare("
146 SELECT COUNT(*) AS sum FROM aqbudgetperiods ");
147 $sth->execute();
148 my $res = $sth->fetchrow_hashref;
149 return $res->{'sum'};
152 # -------------------------------------------------------------------
153 sub CheckBudgetParent {
154 my ( $new_parent, $budget ) = @_;
155 my $new_parent_id = $new_parent->{'budget_id'};
156 my $budget_id = $budget->{'budget_id'};
157 my $dbh = C4::Context->dbh;
158 my $parent_id_tmp = $new_parent_id;
160 # check new-parent is not a child (or a child's child ;)
161 my $sth = $dbh->prepare(qq|
162 SELECT budget_parent_id FROM
163 aqbudgets where budget_id = ? | );
164 while (1) {
165 $sth->execute($parent_id_tmp);
166 my $res = $sth->fetchrow_hashref;
167 if ( $res->{'budget_parent_id'} == $budget_id ) {
168 return 1;
170 if ( not defined $res->{'budget_parent_id'} ) {
171 return 0;
173 $parent_id_tmp = $res->{'budget_parent_id'};
177 # -------------------------------------------------------------------
178 sub BudgetHasChildren {
179 my ( $budget_id ) = @_;
180 my $dbh = C4::Context->dbh;
181 my $sth = $dbh->prepare(qq|
182 SELECT count(*) as sum FROM aqbudgets
183 WHERE budget_parent_id = ? | );
184 $sth->execute( $budget_id );
185 my $sum = $sth->fetchrow_hashref;
186 return $sum->{'sum'};
189 sub GetBudgetChildren {
190 my ( $budget_id ) = @_;
191 my $dbh = C4::Context->dbh;
192 return $dbh->selectall_arrayref(q|
193 SELECT * FROM aqbudgets
194 WHERE budget_parent_id = ?
195 |, { Slice => {} }, $budget_id );
198 sub SetOwnerToFundHierarchy {
199 my ( $budget_id, $borrowernumber ) = @_;
201 my $budget = GetBudget( $budget_id );
202 $budget->{budget_owner_id} = $borrowernumber;
203 ModBudget( $budget );
204 my $children = GetBudgetChildren( $budget_id );
205 for my $child ( @$children ) {
206 SetOwnerToFundHierarchy( $child->{budget_id}, $borrowernumber );
210 # -------------------------------------------------------------------
211 sub GetBudgetsPlanCell {
212 my ( $cell, $period, $budget ) = @_;
213 my ($actual, $sth);
214 my $dbh = C4::Context->dbh;
215 if ( $cell->{'authcat'} eq 'MONTHS' ) {
216 # get the actual amount
217 $sth = $dbh->prepare( qq|
219 SELECT SUM(ecost) AS actual FROM aqorders
220 WHERE budget_id = ? AND
221 entrydate like "$cell->{'authvalue'}%" |
223 $sth->execute( $cell->{'budget_id'} );
224 } elsif ( $cell->{'authcat'} eq 'BRANCHES' ) {
225 # get the actual amount
226 $sth = $dbh->prepare( qq|
228 SELECT SUM(ecost) FROM aqorders
229 LEFT JOIN aqorders_items
230 ON (aqorders.ordernumber = aqorders_items.ordernumber)
231 LEFT JOIN items
232 ON (aqorders_items.itemnumber = items.itemnumber)
233 WHERE budget_id = ? AND homebranch = ? | );
235 $sth->execute( $cell->{'budget_id'}, $cell->{'authvalue'} );
236 } elsif ( $cell->{'authcat'} eq 'ITEMTYPES' ) {
237 # get the actual amount
238 $sth = $dbh->prepare( qq|
240 SELECT SUM( ecost * quantity) AS actual
241 FROM aqorders JOIN biblioitems
242 ON (biblioitems.biblionumber = aqorders.biblionumber )
243 WHERE aqorders.budget_id = ? and itemtype = ? |
245 $sth->execute( $cell->{'budget_id'},
246 $cell->{'authvalue'} );
248 # ELSE GENERIC ORDERS SORT1/SORT2 STAT COUNT.
249 else {
250 # get the actual amount
251 $sth = $dbh->prepare( qq|
253 SELECT SUM(ecost * quantity) AS actual
254 FROM aqorders
255 JOIN aqbudgets ON (aqbudgets.budget_id = aqorders.budget_id )
256 WHERE aqorders.budget_id = ? AND
257 ((aqbudgets.sort1_authcat = ? AND sort1 =?) OR
258 (aqbudgets.sort2_authcat = ? AND sort2 =?)) |
260 $sth->execute( $cell->{'budget_id'},
261 $budget->{'sort1_authcat'},
262 $cell->{'authvalue'},
263 $budget->{'sort2_authcat'},
264 $cell->{'authvalue'}
267 $actual = $sth->fetchrow_array;
269 # get the estimated amount
270 $sth = $dbh->prepare( qq|
272 SELECT estimated_amount AS estimated, display FROM aqbudgets_planning
273 WHERE budget_period_id = ? AND
274 budget_id = ? AND
275 authvalue = ? AND
276 authcat = ? |
278 $sth->execute( $cell->{'budget_period_id'},
279 $cell->{'budget_id'},
280 $cell->{'authvalue'},
281 $cell->{'authcat'},
285 my $res = $sth->fetchrow_hashref;
286 # my $display = $res->{'display'};
287 my $estimated = $res->{'estimated'};
290 return $actual, $estimated;
293 # -------------------------------------------------------------------
294 sub ModBudgetPlan {
295 my ( $budget_plan, $budget_period_id, $authcat ) = @_;
296 my $dbh = C4::Context->dbh;
297 foreach my $buds (@$budget_plan) {
298 my $lines = $buds->{lines};
299 my $sth = $dbh->prepare( qq|
300 DELETE FROM aqbudgets_planning
301 WHERE budget_period_id = ? AND
302 budget_id = ? AND
303 authcat = ? |
305 #delete a aqplan line of cells, then insert new cells,
306 # these could be UPDATES rather than DEL/INSERTS...
307 $sth->execute( $budget_period_id, $lines->[0]{budget_id} , $authcat );
309 foreach my $cell (@$lines) {
310 my $sth = $dbh->prepare( qq|
312 INSERT INTO aqbudgets_planning
313 SET budget_id = ?,
314 budget_period_id = ?,
315 authcat = ?,
316 estimated_amount = ?,
317 authvalue = ? |
319 $sth->execute(
320 $cell->{'budget_id'},
321 $cell->{'budget_period_id'},
322 $cell->{'authcat'},
323 $cell->{'estimated_amount'},
324 $cell->{'authvalue'},
330 # -------------------------------------------------------------------
331 sub GetBudgetSpent {
332 my ($budget_id) = @_;
333 my $dbh = C4::Context->dbh;
334 my $sth = $dbh->prepare(qq|
335 SELECT SUM( COALESCE(unitprice, ecost) * quantity ) AS sum FROM aqorders
336 WHERE budget_id = ? AND
337 quantityreceived > 0 AND
338 datecancellationprinted IS NULL
340 $sth->execute($budget_id);
341 my $sum = $sth->fetchrow_array;
343 $sth = $dbh->prepare(qq|
344 SELECT SUM(shipmentcost) AS sum
345 FROM aqinvoices
346 WHERE shipmentcost_budgetid = ?
347 AND closedate IS NOT NULL
349 $sth->execute($budget_id);
350 my ($shipmentcost_sum) = $sth->fetchrow_array;
351 $sum += $shipmentcost_sum;
353 return $sum;
356 # -------------------------------------------------------------------
357 sub GetBudgetOrdered {
358 my ($budget_id) = @_;
359 my $dbh = C4::Context->dbh;
360 my $sth = $dbh->prepare(qq|
361 SELECT SUM(ecost * quantity) AS sum FROM aqorders
362 WHERE budget_id = ? AND
363 quantityreceived = 0 AND
364 datecancellationprinted IS NULL
366 $sth->execute($budget_id);
367 my $sum = $sth->fetchrow_array;
369 $sth = $dbh->prepare(qq|
370 SELECT SUM(shipmentcost) AS sum
371 FROM aqinvoices
372 WHERE shipmentcost_budgetid = ?
373 AND closedate IS NULL
375 $sth->execute($budget_id);
376 my ($shipmentcost_sum) = $sth->fetchrow_array;
377 $sum += $shipmentcost_sum;
379 return $sum;
382 =head2 GetBudgetName
384 my $budget_name = &GetBudgetName($budget_id);
386 get the budget_name for a given budget_id
388 =cut
390 sub GetBudgetName {
391 my ( $budget_id ) = @_;
392 my $dbh = C4::Context->dbh;
393 my $sth = $dbh->prepare(
395 SELECT budget_name
396 FROM aqbudgets
397 WHERE budget_id = ?
400 $sth->execute($budget_id);
401 return $sth->fetchrow_array;
404 =head2 GetBudgetAuthCats
406 my $auth_cats = &GetBudgetAuthCats($budget_period_id);
408 Return the list of authcat for a given budget_period_id
410 =cut
412 sub GetBudgetAuthCats {
413 my ($budget_period_id) = shift;
414 # now, populate the auth_cats_loop used in the budget planning button
415 # we must retrieve all auth values used by at least one budget
416 my $dbh = C4::Context->dbh;
417 my $sth=$dbh->prepare("SELECT sort1_authcat,sort2_authcat FROM aqbudgets WHERE budget_period_id=?");
418 $sth->execute($budget_period_id);
419 my %authcats;
420 while (my ($sort1_authcat,$sort2_authcat) = $sth->fetchrow) {
421 $authcats{$sort1_authcat}=1 if $sort1_authcat;
422 $authcats{$sort2_authcat}=1 if $sort2_authcat;
424 return [ sort keys %authcats ];
427 # -------------------------------------------------------------------
428 sub GetBudgetPeriods {
429 my ($filters,$orderby) = @_;
431 my $rs = Koha::Database->new()->schema->resultset('Aqbudgetperiod');
432 $rs = $rs->search( $filters, { order_by => $orderby } );
433 $rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
434 return [ $rs->all ];
436 # -------------------------------------------------------------------
437 sub GetBudgetPeriod {
438 my ($budget_period_id) = @_;
439 my $dbh = C4::Context->dbh;
440 ## $total = number of records linked to the record that must be deleted
441 my $total = 0;
442 ## get information about the record that will be deleted
443 my $sth;
444 if ($budget_period_id) {
445 $sth = $dbh->prepare( qq|
446 SELECT *
447 FROM aqbudgetperiods
448 WHERE budget_period_id=? |
450 $sth->execute($budget_period_id);
451 } else { # ACTIVE BUDGET
452 $sth = $dbh->prepare(qq|
453 SELECT *
454 FROM aqbudgetperiods
455 WHERE budget_period_active=1 |
457 $sth->execute();
459 my $data = $sth->fetchrow_hashref;
460 return $data;
463 # -------------------------------------------------------------------
464 sub DelBudgetPeriod{
465 my ($budget_period_id) = @_;
466 my $dbh = C4::Context->dbh;
467 ; ## $total = number of records linked to the record that must be deleted
468 my $total = 0;
470 ## get information about the record that will be deleted
471 my $sth = $dbh->prepare(qq|
472 DELETE
473 FROM aqbudgetperiods
474 WHERE budget_period_id=? |
476 return $sth->execute($budget_period_id);
479 # -------------------------------------------------------------------
480 sub ModBudgetPeriod {
481 my ($budget_period) = @_;
482 my $result = Koha::Database->new()->schema->resultset('Aqbudgetperiod')->find($budget_period);
483 return unless($result);
485 $result = $result->update($budget_period);
486 return $result->in_storage;
489 # -------------------------------------------------------------------
490 sub GetBudgetHierarchy {
491 my ( $budget_period_id, $branchcode, $owner ) = @_;
492 my @bind_params;
493 my $dbh = C4::Context->dbh;
494 my $query = qq|
495 SELECT aqbudgets.*, aqbudgetperiods.budget_period_active, aqbudgetperiods.budget_period_description
496 FROM aqbudgets
497 JOIN aqbudgetperiods USING (budget_period_id)|;
499 my @where_strings;
500 # show only period X if requested
501 if ($budget_period_id) {
502 push @where_strings," aqbudgets.budget_period_id = ?";
503 push @bind_params, $budget_period_id;
505 # show only budgets owned by me, my branch or everyone
506 if ($owner) {
507 if ($branchcode) {
508 push @where_strings,
509 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="")))};
510 push @bind_params, ( $owner, $branchcode );
511 } else {
512 push @where_strings, ' (budget_owner_id = ? OR budget_owner_id IS NULL or budget_owner_id ="") ';
513 push @bind_params, $owner;
515 } else {
516 if ($branchcode) {
517 push @where_strings," (budget_branchcode =? or budget_branchcode is NULL)";
518 push @bind_params, $branchcode;
521 $query.=" WHERE ".join(' AND ', @where_strings) if @where_strings;
522 $debug && warn $query,join(",",@bind_params);
523 my $sth = $dbh->prepare($query);
524 $sth->execute(@bind_params);
526 my %links;
527 # create hash with budget_id has key
528 while ( my $data = $sth->fetchrow_hashref ) {
529 $links{ $data->{'budget_id'} } = $data;
532 # link child to parent
533 my @first_parents;
534 foreach my $budget ( sort { $a->{budget_code} cmp $b->{budget_code} } values %links ) {
535 my $child = $links{$budget->{budget_id}};
536 if ( $child->{'budget_parent_id'} ) {
537 my $parent = $links{ $child->{'budget_parent_id'} };
538 if ($parent) {
539 unless ( $parent->{'children'} ) {
540 # init child arrayref
541 $parent->{'children'} = [];
543 # add as child
544 push @{ $parent->{'children'} }, $child;
546 } else {
547 push @first_parents, $child;
551 my @sort = ();
552 foreach my $first_parent (@first_parents) {
553 _add_budget_children(\@sort, $first_parent);
556 foreach my $budget (@sort) {
557 $budget->{budget_spent} = GetBudgetSpent( $budget->{budget_id} );
558 $budget->{budget_ordered} = GetBudgetOrdered( $budget->{budget_id} );
559 $budget->{total_spent} = GetBudgetHierarchySpent( $budget->{budget_id} );
560 $budget->{total_ordered} = GetBudgetHierarchyOrdered( $budget->{budget_id} );
562 return \@sort;
565 # Recursive method to add a budget and its chidren to an array
566 sub _add_budget_children {
567 my $res = shift;
568 my $budget = shift;
569 push @$res, $budget;
570 my $children = $budget->{'children'} || [];
571 return unless @$children; # break recursivity
572 foreach my $child (@$children) {
573 _add_budget_children($res, $child);
577 # -------------------------------------------------------------------
579 sub AddBudget {
580 my ($budget) = @_;
581 return unless ($budget);
583 my $resultset = Koha::Database->new()->schema->resultset('Aqbudget');
584 return $resultset->create($budget)->id;
587 # -------------------------------------------------------------------
588 sub ModBudget {
589 my ($budget) = @_;
590 my $result = Koha::Database->new()->schema->resultset('Aqbudget')->find($budget);
591 return unless($result);
593 $result = $result->update($budget);
594 return $result->in_storage;
597 # -------------------------------------------------------------------
598 sub DelBudget {
599 my ($budget_id) = @_;
600 my $dbh = C4::Context->dbh;
601 my $sth = $dbh->prepare("delete from aqbudgets where budget_id=?");
602 my $rc = $sth->execute($budget_id);
603 return $rc;
607 =head2 GetBudget
609 &GetBudget($budget_id);
611 get a specific budget
613 =cut
615 # -------------------------------------------------------------------
616 sub GetBudget {
617 my ( $budget_id ) = @_;
618 my $dbh = C4::Context->dbh;
619 my $query = "
620 SELECT *
621 FROM aqbudgets
622 WHERE budget_id=?
624 my $sth = $dbh->prepare($query);
625 $sth->execute( $budget_id );
626 my $result = $sth->fetchrow_hashref;
627 return $result;
630 =head2 GetBudgetByOrderNumber
632 &GetBudgetByOrderNumber($ordernumber);
634 get a specific budget by order number
636 =cut
638 # -------------------------------------------------------------------
639 sub GetBudgetByOrderNumber {
640 my ( $ordernumber ) = @_;
641 my $dbh = C4::Context->dbh;
642 my $query = "
643 SELECT aqbudgets.*
644 FROM aqbudgets, aqorders
645 WHERE ordernumber=?
646 AND aqorders.budget_id = aqbudgets.budget_id
648 my $sth = $dbh->prepare($query);
649 $sth->execute( $ordernumber );
650 my $result = $sth->fetchrow_hashref;
651 return $result;
654 =head2 GetBudgetByCode
656 my $budget = &GetBudgetByCode($budget_code);
658 Retrieve all aqbudgets fields as a hashref for the budget that has
659 given budget_code
661 =cut
663 sub GetBudgetByCode {
664 my ( $budget_code ) = @_;
666 my $dbh = C4::Context->dbh;
667 my $query = qq{
668 SELECT *
669 FROM aqbudgets
670 WHERE budget_code = ?
671 ORDER BY budget_id DESC
672 LIMIT 1
674 my $sth = $dbh->prepare( $query );
675 $sth->execute( $budget_code );
676 return $sth->fetchrow_hashref;
679 =head2 GetBudgetHierarchySpent
681 my $spent = GetBudgetHierarchySpent( $budget_id );
683 Gets the total spent of the level and sublevels of $budget_id
685 =cut
687 sub GetBudgetHierarchySpent {
688 my ( $budget_id ) = @_;
689 my $dbh = C4::Context->dbh;
690 my $children_ids = $dbh->selectcol_arrayref(q|
691 SELECT budget_id
692 FROM aqbudgets
693 WHERE budget_parent_id = ?
694 |, {}, $budget_id );
696 my $total_spent = GetBudgetSpent( $budget_id );
697 for my $child_id ( @$children_ids ) {
698 $total_spent += GetBudgetHierarchySpent( $child_id );
700 return $total_spent;
703 =head2 GetBudgetHierarchyOrdered
705 my $ordered = GetBudgetHierarchyOrdered( $budget_id );
707 Gets the total ordered of the level and sublevels of $budget_id
709 =cut
711 sub GetBudgetHierarchyOrdered {
712 my ( $budget_id ) = @_;
713 my $dbh = C4::Context->dbh;
714 my $children_ids = $dbh->selectcol_arrayref(q|
715 SELECT budget_id
716 FROM aqbudgets
717 WHERE budget_parent_id = ?
718 |, {}, $budget_id );
720 my $total_ordered = GetBudgetOrdered( $budget_id );
721 for my $child_id ( @$children_ids ) {
722 $total_ordered += GetBudgetHierarchyOrdered( $child_id );
724 return $total_ordered;
727 =head2 GetBudgets
729 &GetBudgets($filter, $order_by);
731 gets all budgets
733 =cut
735 # -------------------------------------------------------------------
736 sub GetBudgets {
737 my ($filters, $orderby) = @_;
738 $orderby = 'budget_name' unless($orderby);
740 my $rs = Koha::Database->new()->schema->resultset('Aqbudget');
741 $rs = $rs->search( $filters, { order_by => $orderby } );
742 $rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
743 return [ $rs->all ];
746 =head2 GetBudgetUsers
748 my @borrowernumbers = &GetBudgetUsers($budget_id);
750 Return the list of borrowernumbers linked to a budget
752 =cut
754 sub GetBudgetUsers {
755 my ($budget_id) = @_;
757 my $dbh = C4::Context->dbh;
758 my $query = qq{
759 SELECT borrowernumber
760 FROM aqbudgetborrowers
761 WHERE budget_id = ?
763 my $sth = $dbh->prepare($query);
764 $sth->execute($budget_id);
766 my @borrowernumbers;
767 while (my ($borrowernumber) = $sth->fetchrow_array) {
768 push @borrowernumbers, $borrowernumber
771 return @borrowernumbers;
774 =head2 ModBudgetUsers
776 &ModBudgetUsers($budget_id, @borrowernumbers);
778 Modify the list of borrowernumbers linked to a budget
780 =cut
782 sub ModBudgetUsers {
783 my ($budget_id, @budget_users_id) = @_;
785 return unless $budget_id;
787 my $dbh = C4::Context->dbh;
788 my $query = "DELETE FROM aqbudgetborrowers WHERE budget_id = ?";
789 my $sth = $dbh->prepare($query);
790 $sth->execute($budget_id);
792 $query = qq{
793 INSERT INTO aqbudgetborrowers (budget_id, borrowernumber)
794 VALUES (?,?)
796 $sth = $dbh->prepare($query);
797 foreach my $borrowernumber (@budget_users_id) {
798 next unless $borrowernumber;
799 $sth->execute($budget_id, $borrowernumber);
803 sub CanUserUseBudget {
804 my ($borrower, $budget, $userflags) = @_;
806 if (not ref $borrower) {
807 $borrower = C4::Members::GetMember(borrowernumber => $borrower);
809 if (not ref $budget) {
810 $budget = GetBudget($budget);
813 return 0 unless ($borrower and $budget);
815 if (not defined $userflags) {
816 $userflags = C4::Auth::getuserflags($borrower->{flags},
817 $borrower->{userid});
820 unless ($userflags->{superlibrarian}
821 || (ref $userflags->{acquisition}
822 && $userflags->{acquisition}->{budget_manage_all})
823 || (!ref $userflags->{acquisition} && $userflags->{acquisition}))
825 if (not exists $userflags->{acquisition}) {
826 return 0;
829 if (!ref $userflags->{acquisition} && !$userflags->{acquisition}) {
830 return 0;
833 # Budget restricted to owner
834 if ( $budget->{budget_permission} == 1 ) {
835 if ( $budget->{budget_owner_id}
836 and $budget->{budget_owner_id} != $borrower->{borrowernumber} )
838 return 0;
842 # Budget restricted to owner, users and library
843 elsif ( $budget->{budget_permission} == 2 ) {
844 my @budget_users = GetBudgetUsers( $budget->{budget_id} );
846 if (
848 $budget->{budget_owner_id}
849 and $budget->{budget_owner_id} !=
850 $borrower->{borrowernumber}
851 or not $budget->{budget_owner_id}
853 and ( 0 == grep { $borrower->{borrowernumber} == $_ }
854 @budget_users )
855 and defined $budget->{budget_branchcode}
856 and $budget->{budget_branchcode} ne
857 C4::Context->userenv->{branch}
860 return 0;
864 # Budget restricted to owner and users
865 elsif ( $budget->{budget_permission} == 3 ) {
866 my @budget_users = GetBudgetUsers( $budget->{budget_id} );
867 if (
869 $budget->{budget_owner_id}
870 and $budget->{budget_owner_id} !=
871 $borrower->{borrowernumber}
872 or not $budget->{budget_owner_id}
874 and ( 0 == grep { $borrower->{borrowernumber} == $_ }
875 @budget_users )
878 return 0;
883 return 1;
886 sub CanUserModifyBudget {
887 my ($borrower, $budget, $userflags) = @_;
889 if (not ref $borrower) {
890 $borrower = C4::Members::GetMember(borrowernumber => $borrower);
892 if (not ref $budget) {
893 $budget = GetBudget($budget);
896 return 0 unless ($borrower and $budget);
898 if (not defined $userflags) {
899 $userflags = C4::Auth::getuserflags($borrower->{flags},
900 $borrower->{userid});
903 unless ($userflags->{superlibrarian}
904 || (ref $userflags->{acquisition}
905 && $userflags->{acquisition}->{budget_manage_all})
906 || (!ref $userflags->{acquisition} && $userflags->{acquisition}))
908 if (!CanUserUseBudget($borrower, $budget, $userflags)) {
909 return 0;
912 if (ref $userflags->{acquisition}
913 && !$userflags->{acquisition}->{budget_modify}) {
914 return 0;
918 return 1;
921 # -------------------------------------------------------------------
923 =head2 GetCurrencies
925 @currencies = &GetCurrencies;
927 Returns the list of all known currencies.
929 C<$currencies> is a array; its elements are references-to-hash, whose
930 keys are the fields from the currency table in the Koha database.
932 =cut
934 sub GetCurrencies {
935 my $dbh = C4::Context->dbh;
936 my $query = "
937 SELECT *
938 FROM currency
940 my $sth = $dbh->prepare($query);
941 $sth->execute;
942 my @results = ();
943 while ( my $data = $sth->fetchrow_hashref ) {
944 push( @results, $data );
946 return @results;
949 # -------------------------------------------------------------------
951 sub GetCurrency {
952 my $dbh = C4::Context->dbh;
953 my $query = "
954 SELECT * FROM currency where active = '1' ";
955 my $sth = $dbh->prepare($query);
956 $sth->execute;
957 my $r = $sth->fetchrow_hashref;
958 return $r;
961 # -------------------------------------------------------------------
963 =head2 ConvertCurrency
965 $foreignprice = &ConvertCurrency($currency, $localprice);
967 Converts the price C<$localprice> to foreign currency C<$currency> by
968 dividing by the exchange rate, and returns the result.
970 If no exchange rate is found, e is one to one.
972 =cut
974 sub ConvertCurrency {
975 my ( $currency, $price ) = @_;
976 my $dbh = C4::Context->dbh;
977 my $query = "
978 SELECT rate
979 FROM currency
980 WHERE currency=?
982 my $sth = $dbh->prepare($query);
983 $sth->execute($currency);
984 my $cur = ( $sth->fetchrow_array() )[0];
985 unless ($cur) {
986 $cur = 1;
988 return ( $price / $cur );
992 =head2 CloneBudgetPeriod
994 my $new_budget_period_id = CloneBudgetPeriod({
995 budget_period_id => $budget_period_id,
996 budget_period_startdate => $budget_period_startdate,
997 budget_period_enddate => $budget_period_enddate,
998 mark_original_budget_as_inactive => 1n
999 reset_all_budgets => 1,
1002 Clone a budget period with all budgets.
1003 If the mark_origin_budget_as_inactive is set (0 by default),
1004 the original budget will be marked as inactive.
1006 If the reset_all_budgets is set (0 by default), all budget (fund)
1007 amounts will be reset.
1009 =cut
1011 sub CloneBudgetPeriod {
1012 my ($params) = @_;
1013 my $budget_period_id = $params->{budget_period_id};
1014 my $budget_period_startdate = $params->{budget_period_startdate};
1015 my $budget_period_enddate = $params->{budget_period_enddate};
1016 my $budget_period_description = $params->{budget_period_description};
1017 my $mark_original_budget_as_inactive =
1018 $params->{mark_original_budget_as_inactive} || 0;
1019 my $reset_all_budgets = $params->{reset_all_budgets} || 0;
1021 my $budget_period = GetBudgetPeriod($budget_period_id);
1023 $budget_period->{budget_period_startdate} = $budget_period_startdate;
1024 $budget_period->{budget_period_enddate} = $budget_period_enddate;
1025 $budget_period->{budget_period_description} = $budget_period_description;
1026 # The new budget (budget_period) should be active by default
1027 $budget_period->{budget_period_active} = 1;
1028 my $original_budget_period_id = $budget_period->{budget_period_id};
1029 delete $budget_period->{budget_period_id};
1030 my $new_budget_period_id = AddBudgetPeriod( $budget_period );
1032 my $budgets = GetBudgetHierarchy($budget_period_id);
1033 CloneBudgetHierarchy(
1035 budgets => $budgets,
1036 new_budget_period_id => $new_budget_period_id
1040 if ($mark_original_budget_as_inactive) {
1041 ModBudgetPeriod(
1043 budget_period_id => $budget_period_id,
1044 budget_period_active => 0,
1049 if ( $reset_all_budgets ) {
1050 my $budgets = GetBudgets({ budget_period_id => $new_budget_period_id });
1051 for my $budget ( @$budgets ) {
1052 $budget->{budget_amount} = 0;
1053 ModBudget( $budget );
1057 return $new_budget_period_id;
1060 =head2 CloneBudgetHierarchy
1062 CloneBudgetHierarchy({
1063 budgets => $budgets,
1064 new_budget_period_id => $new_budget_period_id;
1067 Clone a budget hierarchy.
1069 =cut
1071 sub CloneBudgetHierarchy {
1072 my ($params) = @_;
1073 my $budgets = $params->{budgets};
1074 my $new_budget_period_id = $params->{new_budget_period_id};
1075 next unless @$budgets or $new_budget_period_id;
1077 my $children_of = $params->{children_of};
1078 my $new_parent_id = $params->{new_parent_id};
1080 my @first_level_budgets =
1081 ( not defined $children_of )
1082 ? map { ( not $_->{budget_parent_id} ) ? $_ : () } @$budgets
1083 : map { ( $_->{budget_parent_id} == $children_of ) ? $_ : () } @$budgets;
1085 # get only the columns of aqbudgets
1086 my @columns = Koha::Database->new()->schema->source('Aqbudget')->columns;
1088 for my $budget ( sort { $a->{budget_id} <=> $b->{budget_id} }
1089 @first_level_budgets )
1092 my $tidy_budget =
1093 { map { join( ' ', @columns ) =~ /$_/ ? ( $_ => $budget->{$_} ) : () }
1094 keys %$budget };
1095 my $new_budget_id = AddBudget(
1097 %$tidy_budget,
1098 budget_id => undef,
1099 budget_parent_id => $new_parent_id,
1100 budget_period_id => $new_budget_period_id
1103 CloneBudgetHierarchy(
1105 budgets => $budgets,
1106 new_budget_period_id => $new_budget_period_id,
1107 children_of => $budget->{budget_id},
1108 new_parent_id => $new_budget_id
1114 =head2 MoveOrders
1116 my $report = MoveOrders({
1117 from_budget_period_id => $from_budget_period_id,
1118 to_budget_period_id => $to_budget_period_id,
1121 Move orders from one budget period to another.
1123 =cut
1125 sub MoveOrders {
1126 my ($params) = @_;
1127 my $from_budget_period_id = $params->{from_budget_period_id};
1128 my $to_budget_period_id = $params->{to_budget_period_id};
1129 my $move_remaining_unspent = $params->{move_remaining_unspent};
1130 return
1131 if not $from_budget_period_id
1132 or not $to_budget_period_id
1133 or $from_budget_period_id == $to_budget_period_id;
1135 # Can't move orders to an inactive budget (budgetperiod)
1136 my $budget_period = GetBudgetPeriod($to_budget_period_id);
1137 return unless $budget_period->{budget_period_active};
1139 my @report;
1140 my $dbh = C4::Context->dbh;
1141 my $sth_update_aqorders = $dbh->prepare(
1143 UPDATE aqorders
1144 SET budget_id = ?
1145 WHERE ordernumber = ?
1148 my $sth_update_budget_amount = $dbh->prepare(
1150 UPDATE aqbudgets
1151 SET budget_amount = ?
1152 WHERE budget_id = ?
1155 my $from_budgets = GetBudgetHierarchy($from_budget_period_id);
1156 for my $from_budget (@$from_budgets) {
1157 my $new_budget_id = $dbh->selectcol_arrayref(
1159 SELECT budget_id
1160 FROM aqbudgets
1161 WHERE budget_period_id = ?
1162 AND budget_code = ?
1163 |, {}, $to_budget_period_id, $from_budget->{budget_code}
1165 $new_budget_id = $new_budget_id->[0];
1166 my $new_budget = GetBudget( $new_budget_id );
1167 unless ( $new_budget ) {
1168 push @report,
1170 moved => 0,
1171 budget => $from_budget,
1172 error => 'budget_code_not_exists',
1174 next;
1176 my $orders_to_move = C4::Acquisition::SearchOrders(
1178 budget_id => $from_budget->{budget_id},
1179 pending => 1,
1183 my @orders_moved;
1184 for my $order (@$orders_to_move) {
1185 $sth_update_aqorders->execute( $new_budget->{budget_id}, $order->{ordernumber} );
1186 push @orders_moved, $order;
1189 my $unspent_moved = 0;
1190 if ($move_remaining_unspent) {
1191 my $spent = GetBudgetHierarchySpent( $from_budget->{budget_id} );
1192 my $unspent = $from_budget->{budget_amount} - $spent;
1193 my $new_budget_amount = $new_budget->{budget_amount};
1194 if ( $unspent > 0 ) {
1195 $new_budget_amount += $unspent;
1196 $unspent_moved = $unspent;
1198 $new_budget->{budget_amount} = $new_budget_amount;
1199 $sth_update_budget_amount->execute( $new_budget_amount,
1200 $new_budget->{budget_id} );
1203 push @report,
1205 budget => $new_budget,
1206 orders_moved => \@orders_moved,
1207 moved => 1,
1208 unspent_moved => $unspent_moved,
1211 return \@report;
1214 END { } # module clean-up code here (global destructor)
1217 __END__
1219 =head1 AUTHOR
1221 Koha Development Team <http://koha-community.org/>
1223 =cut