Bug 15217 Remove redundant duplicate var declaration
[koha.git] / C4 / Budgets.pm
index aed5e82..79012ba 100644 (file)
@@ -4,18 +4,18 @@ package C4::Budgets;
 #
 # This file is part of Koha.
 #
-# Koha is free software; you can redistribute it and/or modify it under the
-# terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 2 of the License, or (at your option) any later
-# version.
+# Koha is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
 #
-# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+# Koha is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
 #
-# You should have received a copy of the GNU General Public License along
-# with Koha; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+# You should have received a copy of the GNU General Public License
+# along with Koha; if not, see <http://www.gnu.org/licenses>.
 
 use strict;
 #use warnings; FIXME - Bug 2505
@@ -61,7 +61,6 @@ BEGIN {
 
         &GetCurrency
         &GetCurrencies
-        &ModCurrencies
         &ConvertCurrency
         
                &GetBudgetsPlanCell
@@ -187,6 +186,27 @@ sub BudgetHasChildren {
     return $sum->{'sum'};
 }
 
+sub GetBudgetChildren {
+    my ( $budget_id ) = @_;
+    my $dbh = C4::Context->dbh;
+    return $dbh->selectall_arrayref(q|
+       SELECT  * FROM  aqbudgets
+        WHERE budget_parent_id = ?
+    |, { Slice => {} }, $budget_id );
+}
+
+sub SetOwnerToFundHierarchy {
+    my ( $budget_id, $borrowernumber ) = @_;
+
+    my $budget = GetBudget( $budget_id );
+    $budget->{budget_owner_id} = $borrowernumber;
+    ModBudget( $budget );
+    my $children = GetBudgetChildren( $budget_id );
+    for my $child ( @$children ) {
+        SetOwnerToFundHierarchy( $child->{budget_id}, $borrowernumber );
+    }
+}
+
 # -------------------------------------------------------------------
 sub GetBudgetsPlanCell {
     my ( $cell, $period, $budget ) = @_;
@@ -499,72 +519,36 @@ sub GetBudgetHierarchy {
        $debug && warn $query,join(",",@bind_params);
        my $sth = $dbh->prepare($query);
        $sth->execute(@bind_params);
-       my $results = $sth->fetchall_arrayref({});
-       my @res     = @$results;
-       my $i = 0;
-       while (1) {
-               my $depth_cnt = 0;
-               foreach my $r (@res) {
-                       my @child;
-                       # look for children
-                       $r->{depth} = '0' if !defined $r->{budget_parent_id};
-                       foreach my $r2 (@res) {
-                               if (defined $r2->{budget_parent_id}
-                                       && $r2->{budget_parent_id} == $r->{budget_id}) {
-                                       push @child, $r2->{budget_id};
-                                       $r2->{depth} = ($r->{depth} + 1) if defined $r->{depth};
-                               }
-                       }
-                       $r->{child} = \@child if scalar @child > 0;    # add the child
-                       $depth_cnt++ if !defined $r->{'depth'};
-               }
-               last if ($depth_cnt == 0 || $i == 100);
-               $i++;
-       }
 
-       # look for top parents 1st
-       my (@sort, $depth_count);
-       ($i, $depth_count) = 0;
-       while (1) {
-               my $children = 0;
-               foreach my $r (@res) {
-                       if ($r->{depth} == $depth_count) {
-                               $children++ if (ref $r->{child} eq 'ARRAY');
-
-                               # find the parent id element_id and insert it after
-                               my $i2 = 0;
-                               my $parent;
-                               if ($depth_count > 0) {
-
-                                       # add indent
-                                       my $depth = $r->{depth} * 2;
-                                       $r->{budget_code_indent} = $r->{budget_code};
-                                       $r->{budget_name_indent} = $r->{budget_name};
-                                       foreach my $r3 (@sort) {
-                                               if ($r3->{budget_id} == $r->{budget_parent_id}) {
-                                                       $parent = $i2;
-                                                       last;
-                                               }
-                                               $i2++;
-                                       }
-                               } else {
-                                       $r->{budget_code_indent} = $r->{budget_code};
-                                       $r->{budget_name_indent} = $r->{budget_name};
-                               }
-                
-                               if (defined $parent) {
-                                       splice @sort, ($parent + 1), 0, $r;
-                               } else {
-                                       push @sort, $r;
-                               }
-                       }
-
-                       $i++;
-               }    # --------------foreach
-               $depth_count++;
-               last if $children == 0;
-       }
+    my %links;
+    # create hash with budget_id has key
+    while ( my $data = $sth->fetchrow_hashref ) {
+        $links{ $data->{'budget_id'} } = $data;
+    }
+
+    # link child to parent
+    my @first_parents;
+    foreach my $budget ( sort { $a->{budget_code} cmp $b->{budget_code} } values %links ) {
+        my $child = $links{$budget->{budget_id}};
+        if ( $child->{'budget_parent_id'} ) {
+            my $parent = $links{ $child->{'budget_parent_id'} };
+            if ($parent) {
+                unless ( $parent->{'children'} ) {
+                    # init child arrayref
+                    $parent->{'children'} = [];
+                }
+                # add as child
+                push @{ $parent->{'children'} }, $child;
+            }
+        } else {
+            push @first_parents, $child;
+        }
+    }
 
+    my @sort = ();
+    foreach my $first_parent (@first_parents) {
+        _add_budget_children(\@sort, $first_parent);
+    }
 
     foreach my $budget (@sort) {
         $budget->{budget_spent}   = GetBudgetSpent( $budget->{budget_id} );
@@ -575,6 +559,18 @@ sub GetBudgetHierarchy {
     return \@sort;
 }
 
+# Recursive method to add a budget and its chidren to an array
+sub _add_budget_children {
+    my $res = shift;
+    my $budget = shift;
+    push @$res, $budget;
+    my $children = $budget->{'children'} || [];
+    return unless @$children; # break recursivity
+    foreach my $child (@$children) {
+        _add_budget_children($res, $child);
+    }
+}
+
 # -------------------------------------------------------------------
 
 sub AddBudget {
@@ -959,25 +955,6 @@ sub GetCurrency {
     return $r;
 }
 
-=head2 ModCurrencies
-
-&ModCurrencies($currency, $newrate);
-
-Sets the exchange rate for C<$currency> to be C<$newrate>.
-
-=cut
-
-sub ModCurrencies {
-    my ( $currency, $rate ) = @_;
-    my $dbh   = C4::Context->dbh;
-    my $query = qq|
-        UPDATE currency
-        SET    rate=?
-        WHERE  currency=? |;
-    my $sth = $dbh->prepare($query);
-    $sth->execute( $rate, $currency );
-}
-
 # -------------------------------------------------------------------
 
 =head2 ConvertCurrency
@@ -1029,18 +1006,22 @@ amounts will be reset.
 =cut
 
 sub CloneBudgetPeriod {
-    my ($params)                = @_;
-    my $budget_period_id        = $params->{budget_period_id};
-    my $budget_period_startdate = $params->{budget_period_startdate};
-    my $budget_period_enddate   = $params->{budget_period_enddate};
+    my ($params)                  = @_;
+    my $budget_period_id          = $params->{budget_period_id};
+    my $budget_period_startdate   = $params->{budget_period_startdate};
+    my $budget_period_enddate     = $params->{budget_period_enddate};
+    my $budget_period_description = $params->{budget_period_description};
     my $mark_original_budget_as_inactive =
       $params->{mark_original_budget_as_inactive} || 0;
     my $reset_all_budgets = $params->{reset_all_budgets} || 0;
 
     my $budget_period = GetBudgetPeriod($budget_period_id);
 
-    $budget_period->{budget_period_startdate} = $budget_period_startdate;
-    $budget_period->{budget_period_enddate}   = $budget_period_enddate;
+    $budget_period->{budget_period_startdate}   = $budget_period_startdate;
+    $budget_period->{budget_period_enddate}     = $budget_period_enddate;
+    $budget_period->{budget_period_description} = $budget_period_description;
+    # The new budget (budget_period) should be active by default
+    $budget_period->{budget_period_active}    = 1;
     my $original_budget_period_id = $budget_period->{budget_period_id};
     delete $budget_period->{budget_period_id};
     my $new_budget_period_id = AddBudgetPeriod( $budget_period );
@@ -1107,7 +1088,7 @@ sub CloneBudgetHierarchy {
 
         my $tidy_budget =
           { map { join( ' ', @columns ) =~ /$_/ ? ( $_ => $budget->{$_} ) : () }
-              keys($budget) };
+              keys %$budget };
         my $new_budget_id = AddBudget(
             {
                 %$tidy_budget,
@@ -1127,6 +1108,105 @@ sub CloneBudgetHierarchy {
     }
 }
 
+=head2 MoveOrders
+
+  my $report = MoveOrders({
+    from_budget_period_id => $from_budget_period_id,
+    to_budget_period_id   => $to_budget_period_id,
+  });
+
+Move orders from one budget period to another.
+
+=cut
+
+sub MoveOrders {
+    my ($params)              = @_;
+    my $from_budget_period_id = $params->{from_budget_period_id};
+    my $to_budget_period_id   = $params->{to_budget_period_id};
+    my $move_remaining_unspent = $params->{move_remaining_unspent};
+    return
+      if not $from_budget_period_id
+          or not $to_budget_period_id
+          or $from_budget_period_id == $to_budget_period_id;
+
+    # Can't move orders to an inactive budget (budgetperiod)
+    my $budget_period = GetBudgetPeriod($to_budget_period_id);
+    return unless $budget_period->{budget_period_active};
+
+    my @report;
+    my $dbh     = C4::Context->dbh;
+    my $sth_update_aqorders = $dbh->prepare(
+        q|
+            UPDATE aqorders
+            SET budget_id = ?
+            WHERE ordernumber = ?
+        |
+    );
+    my $sth_update_budget_amount = $dbh->prepare(
+        q|
+            UPDATE aqbudgets
+            SET budget_amount = ?
+            WHERE budget_id = ?
+        |
+    );
+    my $from_budgets = GetBudgetHierarchy($from_budget_period_id);
+    for my $from_budget (@$from_budgets) {
+        my $new_budget_id = $dbh->selectcol_arrayref(
+            q|
+                SELECT budget_id
+                FROM aqbudgets
+                WHERE budget_period_id = ?
+                    AND budget_code = ?
+            |, {}, $to_budget_period_id, $from_budget->{budget_code}
+        );
+        $new_budget_id = $new_budget_id->[0];
+        my $new_budget = GetBudget( $new_budget_id );
+        unless ( $new_budget ) {
+            push @report,
+              {
+                moved       => 0,
+                budget      => $from_budget,
+                error       => 'budget_code_not_exists',
+              };
+            next;
+        }
+        my $orders_to_move = C4::Acquisition::SearchOrders(
+            {
+                budget_id => $from_budget->{budget_id},
+                pending   => 1,
+            }
+        );
+
+        my @orders_moved;
+        for my $order (@$orders_to_move) {
+            $sth_update_aqorders->execute( $new_budget->{budget_id}, $order->{ordernumber} );
+            push @orders_moved, $order;
+        }
+
+        my $unspent_moved = 0;
+        if ($move_remaining_unspent) {
+            my $spent   = GetBudgetHierarchySpent( $from_budget->{budget_id} );
+            my $unspent = $from_budget->{budget_amount} - $spent;
+            my $new_budget_amount = $new_budget->{budget_amount};
+            if ( $unspent > 0 ) {
+                $new_budget_amount += $unspent;
+                $unspent_moved = $unspent;
+            }
+            $new_budget->{budget_amount} = $new_budget_amount;
+            $sth_update_budget_amount->execute( $new_budget_amount,
+                $new_budget->{budget_id} );
+        }
+
+        push @report,
+          {
+            budget        => $new_budget,
+            orders_moved  => \@orders_moved,
+            moved         => 1,
+            unspent_moved => $unspent_moved,
+          };
+    }
+    return \@report;
+}
 
 END { }    # module clean-up code here (global destructor)