2 use Test::More tests => 120;
11 use C4::Members qw( AddMember );
13 use Koha::Acquisition::Order;
17 my $dbh = C4::Context->dbh;
18 my $database = Koha::Database->new();
19 my $schema = $database->schema();
20 $schema->storage->txn_begin();
21 $dbh->{RaiseError} = 1;
23 $dbh->do(q|DELETE FROM aqbudgetperiods|);
24 $dbh->do(q|DELETE FROM aqbudgets|);
27 local $SIG{__WARN__} = sub { warn $_[0] unless $_[0] =~ /redefined/ };
29 *C4::Context::userenv = \&Mock_userenv;
30 $userenv = { flags => 1, id => 'my_userid', branch => 'CPL' };
36 is( AddBudgetPeriod(), undef, 'AddBugetPeriod without argument returns undef' );
37 is( AddBudgetPeriod( { } ), undef, 'AddBugetPeriod with an empty argument returns undef' );
38 my $bpid = AddBudgetPeriod({
39 budget_period_startdate => '2008-01-01',
41 is( $bpid, undef, 'AddBugetPeriod without end date returns undef' );
42 $bpid = AddBudgetPeriod({
43 budget_period_enddate => '2008-12-31',
45 is( $bpid, undef, 'AddBugetPeriod without start date returns undef' );
46 is( GetBudgetPeriod(0), undef ,'GetBudgetPeriod(0) returned undef : noactive BudgetPeriod' );
47 my $budgetperiods = GetBudgetPeriods();
48 is( @$budgetperiods, 0, 'GetBudgetPeriods returns the correct number of budget periods' );
50 my $my_budgetperiod = {
51 budget_period_startdate => '2008-01-01',
52 budget_period_enddate => '2008-12-31',
53 budget_period_description => 'MAPERI',
54 budget_period_active => 0,
56 $bpid = AddBudgetPeriod($my_budgetperiod);
57 isnt( $bpid, undef, 'AddBugetPeriod does not returns undef' );
58 my $budgetperiod = GetBudgetPeriod($bpid);
59 is( $budgetperiod->{budget_period_startdate}, $my_budgetperiod->{budget_period_startdate}, 'AddBudgetPeriod stores the start date correctly' );
60 is( $budgetperiod->{budget_period_enddate}, $my_budgetperiod->{budget_period_enddate}, 'AddBudgetPeriod stores the end date correctly' );
61 is( $budgetperiod->{budget_period_description}, $my_budgetperiod->{budget_period_description}, 'AddBudgetPeriod stores the description correctly' );
62 is( $budgetperiod->{budget_period_active}, $my_budgetperiod->{budget_period_active}, 'AddBudgetPeriod stores active correctly' );
63 is( GetBudgetPeriod(0), undef ,'GetBudgetPeriod(0) returned undef : noactive BudgetPeriod' );
67 budget_period_startdate => '2009-01-01',
68 budget_period_enddate => '2009-12-31',
69 budget_period_description => 'MODIF_MAPERI',
70 budget_period_active => 1,
72 my $mod_status = ModBudgetPeriod($my_budgetperiod);
73 is( $mod_status, undef, 'ModBudgetPeriod without id returns undef' );
75 $my_budgetperiod->{budget_period_id} = $bpid;
76 $mod_status = ModBudgetPeriod($my_budgetperiod);
77 is( $mod_status, 1, 'ModBudgetPeriod returnis true' );
78 $budgetperiod = GetBudgetPeriod($bpid);
79 is( $budgetperiod->{budget_period_startdate}, $my_budgetperiod->{budget_period_startdate}, 'ModBudgetPeriod updates the start date correctly' );
80 is( $budgetperiod->{budget_period_enddate}, $my_budgetperiod->{budget_period_enddate}, 'ModBudgetPeriod updates the end date correctly' );
81 is( $budgetperiod->{budget_period_description}, $my_budgetperiod->{budget_period_description}, 'ModBudgetPeriod updates the description correctly' );
82 is( $budgetperiod->{budget_period_active}, $my_budgetperiod->{budget_period_active}, 'ModBudgetPeriod upates active correctly' );
83 isnt( GetBudgetPeriod(0), undef, 'GetBugetPeriods functions correctly' );
86 $budgetperiods = GetBudgetPeriods();
87 is( @$budgetperiods, 1, 'GetBudgetPeriods returns the correct number of budget periods' );
88 is( $budgetperiods->[0]->{budget_period_id}, $my_budgetperiod->{budget_period_id}, 'GetBudgetPeriods returns the id correctly' );
89 is( $budgetperiods->[0]->{budget_period_startdate}, $my_budgetperiod->{budget_period_startdate}, 'GetBudgetPeriods returns the start date correctly' );
90 is( $budgetperiods->[0]->{budget_period_enddate}, $my_budgetperiod->{budget_period_enddate}, 'GetBudgetPeriods returns the end date correctly' );
91 is( $budgetperiods->[0]->{budget_period_description}, $my_budgetperiod->{budget_period_description}, 'GetBudgetPeriods returns the description correctly' );
92 is( $budgetperiods->[0]->{budget_period_active}, $my_budgetperiod->{budget_period_active}, 'GetBudgetPeriods returns active correctly' );
94 is( DelBudgetPeriod($bpid), 1, 'DelBudgetPeriod returns true' );
95 $budgetperiods = GetBudgetPeriods();
96 is( @$budgetperiods, 0, 'GetBudgetPeriods returns the correct number of budget periods' );
103 # The budget hierarchy will be:
111 is( AddBudget(), undef, 'AddBuget without argument returns undef' );
112 my $budgets = GetBudgets();
113 is( @$budgets, 0, 'GetBudgets returns the correct number of budgets' );
115 $bpid = AddBudgetPeriod($my_budgetperiod);
117 budget_code => 'ABCD',
118 budget_amount => '123.132000',
119 budget_name => 'Periodiques',
120 budget_notes => 'This is a note',
121 budget_period_id => $bpid,
123 my $budget_id = AddBudget($my_budget);
124 isnt( $budget_id, undef, 'AddBudget does not returns undef' );
125 my $budget = GetBudget($budget_id);
126 is( $budget->{budget_code}, $my_budget->{budget_code}, 'AddBudget stores the budget code correctly' );
127 is( $budget->{budget_amount}, $my_budget->{budget_amount}, 'AddBudget stores the budget amount correctly' );
128 is( $budget->{budget_name}, $my_budget->{budget_name}, 'AddBudget stores the budget name correctly' );
129 is( $budget->{budget_notes}, $my_budget->{budget_notes}, 'AddBudget stores the budget notes correctly' );
130 is( $budget->{budget_period_id}, $my_budget->{budget_period_id}, 'AddBudget stores the budget period id correctly' );
134 budget_code => 'EFG',
135 budget_amount => '321.231000',
136 budget_name => 'Modified name',
137 budget_notes => 'This is a modified note',
138 budget_period_id => $bpid,
140 $mod_status = ModBudget($my_budget);
141 is( $mod_status, undef, 'ModBudget without id returns undef' );
143 $my_budget->{budget_id} = $budget_id;
144 $mod_status = ModBudget($my_budget);
145 is( $mod_status, 1, 'ModBudget returns true' );
146 $budget = GetBudget($budget_id);
147 is( $budget->{budget_code}, $my_budget->{budget_code}, 'ModBudget updates the budget code correctly' );
148 is( $budget->{budget_amount}, $my_budget->{budget_amount}, 'ModBudget updates the budget amount correctly' );
149 is( $budget->{budget_name}, $my_budget->{budget_name}, 'ModBudget updates the budget name correctly' );
150 is( $budget->{budget_notes}, $my_budget->{budget_notes}, 'ModBudget updates the budget notes correctly' );
151 is( $budget->{budget_period_id}, $my_budget->{budget_period_id}, 'ModBudget updates the budget period id correctly' );
154 $budgets = GetBudgets();
155 is( @$budgets, 1, 'GetBudgets returns the correct number of budgets' );
156 is( $budgets->[0]->{budget_id}, $my_budget->{budget_id}, 'GetBudgets returns the budget id correctly' );
157 is( $budgets->[0]->{budget_code}, $my_budget->{budget_code}, 'GetBudgets returns the budget code correctly' );
158 is( $budgets->[0]->{budget_amount}, $my_budget->{budget_amount}, 'GetBudgets returns the budget amount correctly' );
159 is( $budgets->[0]->{budget_name}, $my_budget->{budget_name}, 'GetBudgets returns the budget name correctly' );
160 is( $budgets->[0]->{budget_notes}, $my_budget->{budget_notes}, 'GetBudgets returns the budget notes correctly' );
161 is( $budgets->[0]->{budget_period_id}, $my_budget->{budget_period_id}, 'GetBudgets returns the budget period id correctly' );
163 $budgets = GetBudgets( {budget_period_id => $bpid} );
164 is( @$budgets, 1, 'GetBudgets With Filter OK' );
165 $budgets = GetBudgets( {budget_period_id => $bpid}, {-asc => "budget_name"} );
166 is( @$budgets, 1, 'GetBudgets With Order OK' );
167 $budgets = GetBudgets( {budget_period_id => GetBudgetPeriod($bpid)->{budget_period_id}}, {-asc => "budget_name"} );
168 is( @$budgets, 1, 'GetBudgets With Order Getting Active budgetPeriod OK');
171 my $budget_name = GetBudgetName( $budget_id );
172 is($budget_name, $my_budget->{budget_name}, "Test the GetBudgetName routine");
174 my $budget_code = $my_budget->{budget_code};
175 my $budget_by_code = GetBudgetByCode( $budget_code );
176 is($budget_by_code->{budget_id}, $budget_id, "GetBudgetByCode, check id");
177 is($budget_by_code->{budget_notes}, $my_budget->{budget_notes}, "GetBudgetByCode, check notes");
179 my $second_budget_id = AddBudget({
180 budget_code => "ZZZZ",
181 budget_amount => "500.00",
182 budget_name => "Art",
183 budget_notes => "This is a note",
184 budget_period_id => $bpid,
186 isnt( $second_budget_id, undef, 'AddBudget does not returns undef' );
188 $budgets = GetBudgets( {budget_period_id => $bpid} );
189 ok( $budgets->[0]->{budget_name} lt $budgets->[1]->{budget_name}, 'default sort order for GetBudgets is by name' );
191 is( DelBudget($budget_id), 1, 'DelBudget returns true' );
192 $budgets = GetBudgets();
193 is( @$budgets, 1, 'GetBudgets returns the correct number of budget periods' );
196 # GetBudgetHierarchySpent and GetBudgetHierarchyOrdered
197 my $budget_period_total = 10_000;
198 my $budget_1_total = 1_000;
199 my $budget_11_total = 100;
200 my $budget_111_total = 50;
201 my $budget_12_total = 100;
202 my $budget_2_total = 2_000;
204 my $budget_period_id = AddBudgetPeriod(
206 budget_period_startdate => '2013-01-01',
207 budget_period_enddate => '2014-12-31',
208 budget_period_description => 'Budget Period',
209 budget_period_active => 1,
210 budget_period_total => $budget_period_total,
213 my $budget_id1 = AddBudget(
215 budget_code => 'budget_1',
216 budget_name => 'budget_1',
217 budget_period_id => $budget_period_id,
218 budget_parent_id => undef,
219 budget_amount => $budget_1_total,
222 my $budget_id2 = AddBudget(
224 budget_code => 'budget_2',
225 budget_name => 'budget_2',
226 budget_period_id => $budget_period_id,
227 budget_parent_id => undef,
228 budget_amount => $budget_2_total,
231 my $budget_id11 = AddBudget(
233 budget_code => 'budget_11',
234 budget_name => 'budget_11',
235 budget_period_id => $budget_period_id,
236 budget_parent_id => $budget_id1,
237 budget_amount => $budget_11_total,
240 my $budget_id12 = AddBudget(
242 budget_code => 'budget_12',
243 budget_name => 'budget_12',
244 budget_period_id => $budget_period_id,
245 budget_parent_id => $budget_id1,
246 budget_amount => $budget_12_total,
249 my $budget_id111 = AddBudget(
251 budget_code => 'budget_111',
252 budget_name => 'budget_111',
253 budget_period_id => $budget_period_id,
254 budget_parent_id => $budget_id11,
255 budget_owner_id => 1,
256 budget_amount => $budget_111_total,
259 my $budget_id21 = AddBudget(
261 budget_code => 'budget_21',
262 budget_name => 'budget_21',
263 budget_period_id => $budget_period_id,
264 budget_parent_id => $budget_id2,
268 my $booksellerid = C4::Bookseller::AddBookseller(
271 address1 => "bookseller's address",
278 my $basketno = C4::Acquisition::NewBasket( $booksellerid, 1 );
279 my ( $biblionumber, $biblioitemnumber ) =
280 C4::Biblio::AddBiblio( MARC::Record->new, '' );
284 budget_id => $budget_id1,
285 pending_quantity => 1,
289 budget_id => $budget_id2,
290 pending_quantity => 2,
294 budget_id => $budget_id11,
295 pending_quantity => 3,
299 budget_id => $budget_id12,
300 pending_quantity => 4,
304 budget_id => $budget_id111,
305 pending_quantity => 2,
309 # No order for budget_21
314 my $invoiceid = AddInvoice(invoicenumber => 'invoice_test_clone', booksellerid => $booksellerid, unknown => "unknown");
316 my $item_quantity = 2;
317 my $number_of_orders_to_move = 0;
318 for my $infos (@order_infos) {
319 for ( 1 .. $infos->{pending_quantity} ) {
320 my $order = Koha::Acquisition::Order->new(
322 basketno => $basketno,
323 biblionumber => $biblionumber,
324 budget_id => $infos->{budget_id},
325 order_internalnote => "internal note",
326 order_vendornote => "vendor note",
330 listprice => $item_price,
331 ecost => $item_price,
338 my $ordernumber = $order->{ordernumber};
339 push @{ $budgets{$infos->{budget_id}} }, $ordernumber;
340 $number_of_orders_to_move++;
342 for ( 1 .. $infos->{spent_quantity} ) {
343 my $order = Koha::Acquisition::Order->new(
345 basketno => $basketno,
346 biblionumber => $biblionumber,
347 budget_id => $infos->{budget_id},
348 order_internalnote => "internal note",
349 order_vendornote => "vendor note",
350 quantity => $item_quantity,
353 listprice => $item_price,
354 ecost => $item_price,
361 my $ordernumber = $order->{ordernumber};
363 biblionumber => $biblionumber,
364 ordernumber => $ordernumber,
365 budget_id => $infos->{budget_id},
366 quantityreceived => $item_quantity,
368 ecost => $item_price,
369 invoiceid => $invoiceid,
371 received_items => [],
375 is( GetBudgetHierarchySpent( $budget_id1 ), 160, "total spent for budget1 is 160" );
376 is( GetBudgetHierarchySpent( $budget_id11 ), 100, "total spent for budget11 is 100" );
377 is( GetBudgetHierarchySpent( $budget_id111 ), 20, "total spent for budget111 is 20" );
380 my $budget_period_id_cloned = C4::Budgets::CloneBudgetPeriod(
382 budget_period_id => $budget_period_id,
383 budget_period_startdate => '2014-01-01',
384 budget_period_enddate => '2014-12-31',
385 budget_period_description => 'Budget Period Cloned',
389 my $budget_period_cloned = C4::Budgets::GetBudgetPeriod($budget_period_id_cloned);
390 is($budget_period_cloned->{budget_period_description}, 'Budget Period Cloned', 'Cloned budget\'s description is updated.');
392 my $budget_hierarchy = GetBudgetHierarchy($budget_period_id);
393 my $budget_hierarchy_cloned = GetBudgetHierarchy($budget_period_id_cloned);
396 scalar(@$budget_hierarchy_cloned),
397 scalar(@$budget_hierarchy),
398 'CloneBudgetPeriod clones the same number of budgets (funds)'
401 _get_dependencies($budget_hierarchy),
402 _get_dependencies($budget_hierarchy_cloned),
403 'CloneBudgetPeriod keeps the same dependencies order'
406 # CloneBudgetPeriod with param mark_original_budget_as_inactive
407 my $budget_period = C4::Budgets::GetBudgetPeriod($budget_period_id);
408 is( $budget_period->{budget_period_active}, 1,
409 'CloneBudgetPeriod does not mark as inactive the budgetperiod if not needed'
412 $budget_hierarchy_cloned = GetBudgetHierarchy($budget_period_id_cloned);
413 my $number_of_budgets_not_reset = 0;
414 for my $budget (@$budget_hierarchy_cloned) {
415 $number_of_budgets_not_reset++ if $budget->{budget_amount} > 0;
417 is( $number_of_budgets_not_reset, 5,
418 'CloneBudgetPeriod does not reset budgets (funds) if not needed' );
420 $budget_period_id_cloned = C4::Budgets::CloneBudgetPeriod(
422 budget_period_id => $budget_period_id,
423 budget_period_startdate => '2014-01-01',
424 budget_period_enddate => '2014-12-31',
425 mark_original_budget_as_inactive => 1,
429 $budget_hierarchy = GetBudgetHierarchy($budget_period_id);
430 $budget_hierarchy_cloned = GetBudgetHierarchy($budget_period_id_cloned);
432 is( scalar(@$budget_hierarchy_cloned), scalar(@$budget_hierarchy),
433 'CloneBudgetPeriod (with inactive param) clones the same number of budgets (funds)'
436 _get_dependencies($budget_hierarchy),
437 _get_dependencies($budget_hierarchy_cloned),
438 'CloneBudgetPeriod (with inactive param) keeps the same dependencies order'
440 $budget_period = C4::Budgets::GetBudgetPeriod($budget_period_id);
441 is( $budget_period->{budget_period_active}, 0,
442 'CloneBudgetPeriod (with inactive param) marks as inactive the budgetperiod'
445 # CloneBudgetPeriod with param reset_all_budgets
446 $budget_period_id_cloned = C4::Budgets::CloneBudgetPeriod(
448 budget_period_id => $budget_period_id,
449 budget_period_startdate => '2014-01-01',
450 budget_period_enddate => '2014-12-31',
451 reset_all_budgets => 1,
455 $budget_hierarchy_cloned = GetBudgetHierarchy($budget_period_id_cloned);
456 $number_of_budgets_not_reset = 0;
457 for my $budget (@$budget_hierarchy_cloned) {
458 $number_of_budgets_not_reset++ if $budget->{budget_amount} > 0;
460 is( $number_of_budgets_not_reset, 0,
461 'CloneBudgetPeriod has reset all budgets (funds)' );
465 my $number_orders_moved = C4::Budgets::MoveOrders();
466 is( $number_orders_moved, undef, 'MoveOrders return undef if no arg passed' );
467 $number_orders_moved =
468 C4::Budgets::MoveOrders( { from_budget_period_id => $budget_period_id } );
469 is( $number_orders_moved, undef,
470 'MoveOrders return undef if only 1 arg passed' );
471 $number_orders_moved =
472 C4::Budgets::MoveOrders( { to_budget_period_id => $budget_period_id } );
473 is( $number_orders_moved, undef,
474 'MoveOrders return undef if only 1 arg passed' );
475 $number_orders_moved = C4::Budgets::MoveOrders(
477 from_budget_period_id => $budget_period_id,
478 to_budget_period_id => $budget_period_id
481 is( $number_orders_moved, undef,
482 'MoveOrders return undef if 2 budget period id are the same' );
484 $budget_period_id_cloned = C4::Budgets::CloneBudgetPeriod(
486 budget_period_id => $budget_period_id,
487 budget_period_startdate => '2014-01-01',
488 budget_period_enddate => '2014-12-31',
492 my $report = C4::Budgets::MoveOrders(
494 from_budget_period_id => $budget_period_id,
495 to_budget_period_id => $budget_period_id_cloned,
496 move_remaining_unspent => 1,
499 is( scalar( @$report ), 6 , "MoveOrders has processed 6 funds" );
501 my $number_of_orders_moved = 0;
502 $number_of_orders_moved += scalar( @{ $_->{orders_moved} } ) for @$report;
503 is( $number_of_orders_moved, $number_of_orders_to_move, "MoveOrders has moved $number_of_orders_to_move orders" );
505 my @new_budget_ids = map { $_->{budget_id} }
506 @{ C4::Budgets::GetBudgetHierarchy($budget_period_id_cloned) };
507 my @old_budget_ids = map { $_->{budget_id} }
508 @{ C4::Budgets::GetBudgetHierarchy($budget_period_id) };
509 for my $budget_id ( keys %budgets ) {
510 for my $ordernumber ( @{ $budgets{$budget_id} } ) {
511 my $budget = GetBudgetByOrderNumber($ordernumber);
512 my $is_in_new_budgets = grep /^$budget->{budget_id}$/, @new_budget_ids;
513 my $is_in_old_budgets = grep /^$budget->{budget_id}$/, @old_budget_ids;
514 is( $is_in_new_budgets, 1, "MoveOrders changed the budget_id for order $ordernumber" );
515 is( $is_in_old_budgets, 0, "MoveOrders changed the budget_id for order $ordernumber" );
520 # MoveOrders with param move_remaining_unspent
521 my @new_budgets = @{ C4::Budgets::GetBudgetHierarchy($budget_period_id_cloned) };
522 my @old_budgets = @{ C4::Budgets::GetBudgetHierarchy($budget_period_id) };
524 for my $new_budget ( @new_budgets ) {
525 my ( $old_budget ) = map { $_->{budget_code} eq $new_budget->{budget_code} ? $_ : () } @old_budgets;
526 my $new_budget_amount_should_be = $old_budget->{budget_amount} * 2 - $old_budget->{total_spent};
527 is( $new_budget->{budget_amount} + 0, $new_budget_amount_should_be, "MoveOrders updated the budget amount with the previous unspent budget (for budget $new_budget->{budget_code})" );
530 # Test SetOwnerToFundHierarchy
532 my $categorycode = 'S';
533 my $branchcode = 'CPL';
534 my $john_doe = C4::Members::AddMember(
535 cardnumber => '123456',
538 categorycode => $categorycode,
539 branchcode => $branchcode,
541 dateexpiry => '9999-12-31',
545 C4::Budgets::SetOwnerToFundHierarchy( $budget_id1, $john_doe );
546 is( C4::Budgets::GetBudget($budget_id1)->{budget_owner_id},
547 $john_doe, "SetOwnerToFundHierarchy should have set John Doe for budget 1 ($budget_id1)" );
548 is( C4::Budgets::GetBudget($budget_id11)->{budget_owner_id},
549 $john_doe, "SetOwnerToFundHierarchy should have set John Doe for budget 11 ($budget_id11)" );
550 is( C4::Budgets::GetBudget($budget_id111)->{budget_owner_id},
551 $john_doe, "SetOwnerToFundHierarchy should have set John Doe for budget 111 ($budget_id111)" );
552 is( C4::Budgets::GetBudget($budget_id12)->{budget_owner_id},
553 $john_doe, "SetOwnerToFundHierarchy should have set John Doe for budget 12 ($budget_id12 )" );
554 is( C4::Budgets::GetBudget($budget_id2)->{budget_owner_id},
555 undef, "SetOwnerToFundHierarchy should not have set an owner for budget 2 ($budget_id2)" );
556 is( C4::Budgets::GetBudget($budget_id21)->{budget_owner_id},
557 undef, "SetOwnerToFundHierarchy should not have set an owner for budget 21 ($budget_id21)" );
559 my $jane_doe = C4::Members::AddMember(
560 cardnumber => '789012',
563 categorycode => $categorycode,
564 branchcode => $branchcode,
566 dateexpiry => '9999-12-31',
570 C4::Budgets::SetOwnerToFundHierarchy( $budget_id11, $jane_doe );
571 is( C4::Budgets::GetBudget($budget_id1)->{budget_owner_id},
572 $john_doe, "SetOwnerToFundHierarchy should have set John Doe $john_doe for budget 1 ($budget_id1)" );
573 is( C4::Budgets::GetBudget($budget_id11)->{budget_owner_id},
574 $jane_doe, "SetOwnerToFundHierarchy should have set John Doe $jane_doe for budget 11 ($budget_id11)" );
575 is( C4::Budgets::GetBudget($budget_id111)->{budget_owner_id},
576 $jane_doe, "SetOwnerToFundHierarchy should have set John Doe $jane_doe for budget 111 ($budget_id111)" );
577 is( C4::Budgets::GetBudget($budget_id12)->{budget_owner_id},
578 $john_doe, "SetOwnerToFundHierarchy should have set John Doe $john_doe for budget 12 ($budget_id12 )" );
579 is( C4::Budgets::GetBudget($budget_id2)->{budget_owner_id},
580 undef, "SetOwnerToFundHierarchy should have set John Doe $john_doe for budget 2 ($budget_id2)" );
581 is( C4::Budgets::GetBudget($budget_id21)->{budget_owner_id},
582 undef, "SetOwnerToFundHierarchy should have set John Doe $john_doe for budget 21 ($budget_id21)" );
584 $schema->storage->txn_rollback();
586 sub _get_dependencies {
587 my ($budget_hierarchy) = @_;
589 for my $budget (@$budget_hierarchy) {
590 if ( $budget->{child} ) {
591 my @sorted = sort @{ $budget->{child} };
592 for my $child_id (@sorted) {
593 push @{ $graph->{ $budget->{budget_name} }{children} },
594 _get_budgetname_by_id( $budget_hierarchy, $child_id );
597 push @{ $graph->{ $budget->{budget_name} }{parents} },
598 $budget->{parent_id};
603 sub _get_budgetname_by_id {
604 my ( $budgets, $budget_id ) = @_;
606 map { ( $_->{budget_id} eq $budget_id ) ? $_->{budget_name} : () }
611 # C4::Context->userenv