Bug 12844: Use Koha::Number::Price where it can be useful
[koha.git] / admin / aqbudgets.pl
index 39fffdb..fa914d5 100755 (executable)
 # with Koha; if not, write to the Free Software Foundation, Inc.,
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
-use strict;
-#use warnings; FIXME - Bug 2505
+use Modern::Perl;
+
 use CGI;
 use List::Util qw/min/;
 use Number::Format qw(format_price);
 
+use Koha::Database;
 use C4::Auth qw/get_user_subpermissions/;
 use C4::Branch; # GetBranches
 use C4::Dates qw/format_date format_date_in_iso/;
 use C4::Auth;
 use C4::Acquisition;
-use C4::Budgets;   #
+use C4::Budgets;
 use C4::Members;  # calls GetSortDetails()
 use C4::Context;
 use C4::Output;
 use C4::Koha;
 use C4::Debug;
-#use POSIX qw(locale_h);
 
 my $input = new CGI;
 my $dbh     = C4::Context->dbh;
 
 my ($template, $borrowernumber, $cookie, $staffflags ) = get_template_and_user(
-    {   template_name   => "admin/aqbudgets.tmpl",
+    {   template_name   => "admin/aqbudgets.tt",
         query           => $input,
         type            => "intranet",
         authnotrequired => 0,
@@ -56,38 +56,37 @@ $template->param( symbol => $cur->{symbol},
                   currency => $cur->{currency}
                );
 
-my $op = $input->param('op');
+my $op = $input->param('op') || 'list';
 
-# see if the user want to see all budgets or only owned ones
-my $show_mine    = 1; #SHOW BY DEFAULT
-my $show         = $input->param('show'); # SET TO 1, BY A FORM SUMBIT
-$show_mine       = $input->param('show_mine') if $show == 1;
+# see if the user want to see all budgets or only owned ones by default
+my $show_mine = $input->param('show_mine') // 1;
 
 # IF USER DOESNT HAVE PERM FOR AN 'ADD', THEN REDIRECT TO THE DEFAULT VIEW...
-if  (  not defined $template->{VARS}->{'CAN_user_acquisition_budget_add_del'}  &&  $op ==  'add_form'  )   {
-    $op = '';
+if (not defined $template->{VARS}->{'CAN_user_acquisition_budget_add_del'}
+    and $op eq 'add_form')
+{
+    $op = 'list';
 }
-my $num=FormatNumber;
 
-my $script_name               = "/cgi-bin/koha/admin/aqbudgets.pl";
-my $budget_hash               = $input->Vars;
-my $budget_id                 = $$budget_hash{budget_id};
+# get only the columns of aqbudgets in budget_hash
+my @columns = Koha::Database->new()->schema->source('Aqbudget')->columns;
+my $budget_hash = { map { join(' ',@columns) =~ /$_/ ? ( $_ => $input->param($_) )  : () } keys( %{$input->Vars()}) } ;
+
+my $budget_id                 = $input->param('budget_id');
+my $budget_period_id          = $input->param('budget_period_id');
 my $budget_permission         = $input->param('budget_permission');
-my $filter_budgetbranch       = $input->param('filter_budgetbranch');
+my $budget_users_ids          = $input->param('budget_users_ids');
+my $filter_budgetbranch       = $input->param('filter_budgetbranch') // '';
 my $filter_budgetname         = $input->param('filter_budgetname');
-#filtering non budget keys
-delete $$budget_hash{$_} foreach grep {/filter|^op$|show/} keys %$budget_hash;
 
-$template->param(
-    notree => ($filter_budgetbranch or $show_mine)
-);
+
 # ' ------- get periods stuff ------------------'
 # IF PERIODID IS DEFINED,  GET THE PERIOD - ELSE JUST GET THE ACTIVE PERIOD BY DEFAULT
-my $period = GetBudgetPeriod($$budget_hash{budget_period_id});
+my $period;
+if ( $budget_period_id ) {
+    $period = GetBudgetPeriod( $budget_period_id );
+}
 
-$template->param(
-       %$period
-);
 # ------- get periods stuff ------------------
 
 # USED FOR PERMISSION COMPARISON LATER
@@ -96,15 +95,11 @@ my $user                = GetMemberDetails($borrower_id);
 my $user_branchcode     = $user->{'branchcode'};
 
 $template->param(
-    action      => $script_name,
-    script_name => $script_name,
     show_mine   => $show_mine,
-    $op || else => 1,
+    op  => $op,
 );
 
-
-# retrieve branches
-my ( $budget, );
+my $budget;
 
 my $branches = GetBranches($show_mine);
 my @branchloop2;
@@ -117,7 +112,8 @@ foreach my $thisbranch (keys %$branches) {
     push @branchloop2, \%row;
 }
 
-$template->param(auth_cats_loop => GetBudgetAuthCats($$period{budget_period_id}) );
+$template->param(auth_cats_loop => GetBudgetAuthCats( $budget_period_id ))
+    if $budget_period_id;
 
 # Used to create form to add or  modify a record
 if ($op eq 'add_form') {
@@ -126,11 +122,16 @@ if ($op eq 'add_form') {
     #  pass the period_id to build the dropbox - because we only want to show  budgets from this period
     my $dropbox_disabled;
     if (defined $budget_id ) {    ### MOD
-        $budget           = GetBudget($budget_id);
+        $budget = GetBudget($budget_id);
+        if (!CanUserModifyBudget($borrowernumber, $budget, $staffflags)) {
+            $template->param(error_not_authorised_to_modify => 1);
+            output_html_with_http_headers $input, $cookie, $template->output;
+            exit;
+        }
         $dropbox_disabled = BudgetHasChildren($budget_id);
         my $borrower = &GetMember( borrowernumber=>$budget->{budget_owner_id} );
-        $budget->{budget_owner_name} = $borrower->{'firstname'} . ' ' . $borrower->{'surname'};
-        $$budget{$_}= sprintf("%.2f", $budget->{$_}) for grep{/amount/} keys %$budget;
+        $budget->{budget_owner_name} = ( $borrower ? $borrower->{'firstname'} . ' ' . $borrower->{'surname'} : '' );
+        $$budget{$_}= sprintf("%.2f", $budget->{$_}) for grep{ /amount|encumb|expend/ } keys %$budget;
     }
 
     # build budget hierarchy
@@ -161,7 +162,7 @@ if ($op eq 'add_form') {
             value      => $thisbranch,
             branchname => $branches->{$thisbranch}->{'branchname'},
         );
-        $row{selected} = 1 if $thisbranch eq $budget->{'budget_branchcode'};
+        $row{selected} = 1 if $budget and $thisbranch eq $budget->{'budget_branchcode'};
         push @branchloop_select, \%row;
     }
     
@@ -170,14 +171,14 @@ if ($op eq 'add_form') {
     my @auth_cats_loop1 = ();
     foreach my $category (@$categories) {
         my $entry = { category => $category,
-                        selected => $budget->{sort1_authcat} eq $category ?1:0,
+                        selected => ( $budget and $budget->{sort1_authcat} eq $category ? 1 : 0 ),
                     };
         push @auth_cats_loop1, $entry;
     }
     my @auth_cats_loop2 = ();
     foreach my $category (@$categories) {
         my $entry = { category => $category,
-                        selected => $budget->{sort2_authcat} eq $category ?1:0,
+                        selected => ( $budget and $budget->{sort2_authcat} eq $category ? 1 : 0 ),
                     };
         push @auth_cats_loop2, $entry;
     }
@@ -189,10 +190,26 @@ if ($op eq 'add_form') {
         $template->param($budget_permission => 1);
     }
 
+    if ($budget) {
+        my @budgetusers = GetBudgetUsers($budget->{budget_id});
+        my @budgetusers_loop;
+        foreach my $borrowernumber (@budgetusers) {
+            my $member = C4::Members::GetMember(
+                borrowernumber => $borrowernumber);
+            push @budgetusers_loop, {
+                firstname => $member->{firstname},
+                surname => $member->{surname},
+                borrowernumber => $borrowernumber
+            };
+        }
+        $template->param(
+            budget_users => \@budgetusers_loop,
+            budget_users_ids => join ':', @budgetusers
+        );
+    }
+
     # if no buget_id is passed then its an add
     $template->param(
-        add_validate                  => 1,
-        dateformat                => C4::Dates->new()->visual(),
         budget_parent_id                 => $budget_parent->{'budget_id'},
         budget_parent_name               => $budget_parent->{'budget_name'},
         branchloop_select         => \@branchloop_select,
@@ -210,66 +227,58 @@ if ($op eq 'add_form') {
         budget_id     => $budget->{'budget_id'},
         budget_code   => $budget->{'budget_code'},
         budget_name   => $budget->{'budget_name'},
-        budget_amount => $num->format_price(  $budget->{'budget_amount'} ),
+        budget_amount => $budget->{'budget_amount'},
     );
                                                     # END $OP eq DELETE_CONFIRM
 # called by delete_confirm, used to effectively confirm deletion of data in DB
-}  else{
-    if ( $op eq 'delete_confirmed' ) {
-        my $rc = DelBudget($budget_id);
-    }elsif( $op eq 'add_validate' ) {
-        if ( defined $$budget_hash{budget_id} ) {
+} elsif ( $op eq 'delete_confirmed' ) {
+    my $rc = DelBudget($budget_id);
+    $op = 'list';
+} elsif( $op eq 'add_validate' ) {
+    my @budgetusersid;
+    if (defined $budget_users_ids){
+        @budgetusersid = split(':', $budget_users_ids);
+    }
+
+    if (defined $budget_id) {
+        if (CanUserModifyBudget($borrowernumber, $budget_hash->{budget_id},
+            $staffflags)
+        ) {
             ModBudget( $budget_hash );
-        } else {
-            AddBudget( $budget_hash );
+            ModBudgetUsers($budget_hash->{budget_id}, @budgetusersid);
+        }
+        else {
+            $template->param(error_not_authorised_to_modify => 1);
         }
+    } else {
+        AddBudget( $budget_hash );
+        ModBudgetUsers($budget_hash->{budget_id}, @budgetusersid);
     }
+    $op = 'list';
+}
+
+if ( $op eq 'list' ) {
     my $branches = GetBranches();
     $template->param(
-        budget_id                 => $budget_id,
+        budget_id => $budget_id,
         %$period,
     );
 
-    my $moo = GetBudgetHierarchy($$period{budget_period_id}, C4::Context->userenv->{branchcode}, $show_mine?$borrower_id:'');
-    my @budgets = @$moo; #FIXME
+    my @budgets = @{
+        GetBudgetHierarchy($$period{budget_period_id},
+            C4::Context->userenv->{branchcode}, $show_mine ? $borrower_id : '')
+    };
 
-    my $toggle = 0;
-    my @loop;
     my $period_total = 0;
-    my ( $period_alloc_total, $base_spent_total );
+    my ($period_alloc_total, $spent_total, $ordered_total, $available_total) = (0,0,0,0);
 
        #This Looks WEIRD to me : should budgets be filtered in such a way ppl who donot own it would not see the amount spent on the budget by others ?
 
     foreach my $budget (@budgets) {
-        #Level and sublevels total spent
-        $budget->{'total_levels_spent'} = GetChildBudgetsSpent($budget->{"budget_id"});
-
         # PERMISSIONS
-        unless($staffflags->{'superlibrarian'} % 2   == 1 ) {
-            #IF NO PERMS, THEN DISABLE EDIT/DELETE
-            unless ( $template->{VARS}->{'CAN_user_acquisition_budget_modify'} ) {
-                $budget->{'budget_lock'} = 1;
-            }
-            # check budget permission
-            if ( $$period{budget_period_locked} == 1 ) {
-                $budget->{'budget_lock'} = 1;
-
-            } elsif ( $budget->{budget_permission} == 1 ) {
-
-                if ( $borrower_id != $budget->{'budget_owner_id'} ) {
-                    $budget->{'budget_lock'} = 1;
-                }
-                # check parent perms too
-                my $parents_perm = 0;
-                if ( $budget->{depth} > 0 ) {
-                    $parents_perm = CheckBudgetParentPerm( $budget, $borrower_id );
-                    delete $budget->{'budget_lock'} if $parents_perm == '1';
-                }
-            } elsif ( $budget->{budget_permission} == 2 ) {
-
-                $budget->{'budget_lock'} = 1 if $user_branchcode ne $budget->{budget_branchcode};
-            }
-        }    # ...SUPER_LIB END
+        unless(CanUserModifyBudget($borrowernumber, $budget, $staffflags)) {
+            $budget->{'budget_lock'} = 1;
+        }
 
         # if a budget search doesnt match, next
         if ($filter_budgetname) {
@@ -278,30 +287,28 @@ if ($op eq 'add_form') {
                   || $budget->{budget_name} =~ m/$filter_budgetname/i;
         }
         if ($filter_budgetbranch ) {
-            next unless  $budget->{budget_branchcode}  =~ m/$filter_budgetbranch/;
+            next unless  $budget->{budget_branchcode} eq $filter_budgetbranch;
         }
 
 ## TOTALS
+        $budget->{'budget_remaining'} = $budget->{'budget_amount'} - $budget->{'budget_spent'} - $budget->{budget_ordered};
+        $budget->{'total_remaining'} = $budget->{'budget_amount'} - $budget->{'total_spent'} - $budget->{total_ordered};
         # adds to total  - only if budget is a 'top-level' budget
-        $period_alloc_total += $budget->{'budget_amount_total'} if $budget->{'depth'} == 0;
-        $base_spent_total += $budget->{'budget_spent'};
-        $budget->{'budget_remaining'} = $budget->{'budget_amount'} - $budget->{'total_levels_spent'};
+        if ($budget->{depth} == 0) {
+            $period_alloc_total += $budget->{'budget_amount'};
+            $spent_total += $budget->{total_spent};
+            $ordered_total += $budget->{total_ordered};
+            $available_total += $budget->{total_remaining};
+        }
 
 # if amount == 0 dont display...
-        delete  $budget->{'budget_unalloc_sublevel'} if  $budget->{'budget_unalloc_sublevel'} == 0 ;
-
-        $budget->{'remaining_pos'} = 1 if $budget->{'budget_remaining'} > 0;
-        $budget->{'remaining_neg'} = 1 if $budget->{'budget_remaining'} < 0;
-               for (grep {/total_levels_spent|budget_spent|budget_amount|budget_remaining|budget_unalloc/} keys %$budget){
-            $budget->{$_}               = $num->format_price( $budget->{$_} ) if defined($budget->{$_})
-               }
+        delete $budget->{'budget_unalloc_sublevel'}
+            if (!defined $budget->{'budget_unalloc_sublevel'}
+            or $budget->{'budget_unalloc_sublevel'} == 0);
 
         # Value of budget_spent equals 0 instead of undefined value
-        $budget->{"budget_spent"} = $num->format_price(0) unless defined($budget->{"budget_spent"});
-
-        my $borrower = &GetMember( borrowernumber=>$budget->{budget_owner_id} );
-        $budget->{"budget_owner_name"}     = $borrower->{'firstname'} . ' ' . $borrower->{'surname'};
-        $budget->{"budget_borrowernumber"} = $borrower->{'borrowernumber'};
+        $budget->{budget_spent} = 0 unless defined($budget->{budget_spent});
+        $budget->{budget_ordered} = 0 unless defined($budget->{budget_ordered});
 
         #Make a list of parents of the bugdet
         my @budget_hierarchy;
@@ -312,39 +319,28 @@ if ($op eq 'add_form') {
             push @budget_hierarchy, { element_name => $parent->{"budget_name"}, element_id => $parent->{"budget_id"} };
             $parent_id = $parent->{"budget_parent_id"};
         }
-        push  @budget_hierarchy, { element_name => $period->{"budget_period_description"} }; 
+        push  @budget_hierarchy, { element_name => $period->{"budget_period_description"} };
         @budget_hierarchy = reverse(@budget_hierarchy);
 
-        push( @loop, {  %{$budget},
-                        branchname  => $branches->{ $budget->{branchcode} }->{branchname},
-                        budget_hierarchy => \@budget_hierarchy,
-                    }
-        );
+        $budget->{budget_hierarchy} = \@budget_hierarchy;
     }
 
-    my $budget_period_total;
-    if ( $period->{budget_period_total} ) {
-        $budget_period_total =
-          $num->format_price( $period->{budget_period_total} );
-    }
+    my $budget_period_total = $period->{budget_period_total};
 
-    if ($period_alloc_total) {
-        $period_alloc_total = $num->format_price($period_alloc_total);
-    }
-
-    if ($base_spent_total) {
-        $base_spent_total = $num->format_price($base_spent_total);
-    }
+    my $periods = GetBudgetPeriods();
 
     $template->param(
-        else                   => 1,
-        budget                 => \@loop,
+        op                     => 'list',
+        budgets                => \@budgets,
+        periods                => $periods,
         budget_period_total    => $budget_period_total,
         period_alloc_total     => $period_alloc_total,
-        base_spent_total       => $base_spent_total,
+        spent_total            => $spent_total,
+        ordered_total          => $ordered_total,
+        available_total        => $available_total,
         branchloop             => \@branchloop2,
     );
 
-} #---- END $OP eq DEFAULT
+} #---- END list
 
 output_html_with_http_headers $input, $cookie, $template->output;