db42742a3a
In aqplan.pl there are two different sets of params for things you can plan by: for the toolbar "Planning" menubutton the script looks up what AVs are used for "Statistic 1|2 done on" for the budget's fund(s), and passes them to the template which knows to hardcode the MONTHS, ITEMTYPES, and BRANCHES choices, but for "Select planning type" in the Filter sidebar box, the script inserts the harcoded ones itself, adds in the ones used by a fund, and for no apparent reason adds in every authorized value category that starts with the letter A and has at least one value. Those things do not actually work, because for things other than the hardcoded ones the script checks whether they are in a fund's "Statistic 1|2" and if not refuses to let you plan by them. Test plan: 1. Administration - Budgets 2. If you don't have a budget, create one and add a fund to it, but with the default data click the name Main budget 3. In the row for Main fund, click Actions->Edit 4. For Statistic 1 done on choose an authorized value which does not start with A, like BOR_NOTES, and Save 5. In the top toolbar, Planning->Plan by months 6. In the sidebar Filter box, note that there is an option to plan by AR_CANCELLATION even though you didn't select that for Statistic 1 7. Select the by BOR_NOTE choice and Submit 8. Note that you now only see Main fund, because that's the only one which uses that AV 9. Select the by months choice and Submit, see that it changes back, then select the by AR_CANCELLATION choice and see that nothing is displayed, select the by months choice again and Submit, see that the display is now completely broken 9. Apply patch, restart_all, reload the page 10. Note that the AR_CANCELLATION choice is gone, and all the choices you do have work correctly Sponsored-by: Chetco Community Public Library Signed-off-by: Caroline Cyr La Rose <caroline.cyr-la-rose@inlibro.com> Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org> Signed-off-by: Katrin Fischer <katrin.fischer@bsz-bw.de>
452 lines
14 KiB
Perl
Executable file
452 lines
14 KiB
Perl
Executable file
#!/usr/bin/perl
|
|
|
|
# Copyright 2008-2009 BibLibre SARL
|
|
# 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 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.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with Koha; if not, see <http://www.gnu.org/licenses>.
|
|
|
|
#script to administer the aqbudgets0 table
|
|
#written 20/02/2002 by paul.poulain@free.fr
|
|
# This software is placed under the gnu General Public License, v2 (http://www.gnu.org/licenses/gpl.html)
|
|
|
|
use Modern::Perl;
|
|
use CGI qw ( -utf8 );
|
|
use Date::Calc qw( Delta_YMD );
|
|
use Date::Manip qw( DateCalc UnixDate );
|
|
use Text::CSV_XS;
|
|
|
|
use C4::Budgets qw(
|
|
CanUserUseBudget
|
|
GetBudgetAuthCats
|
|
GetBudgetHierarchy
|
|
GetBudgetPeriod
|
|
GetBudgetsPlanCell
|
|
GetCols
|
|
GetPeriodsCount
|
|
HideCols
|
|
ModBudgetPlan
|
|
);
|
|
use C4::Context;
|
|
use C4::Output qw( output_html_with_http_headers );
|
|
use C4::Auth qw( get_template_and_user );
|
|
use Koha::Acquisition::Currencies;
|
|
|
|
our $input = CGI->new;
|
|
#### $input
|
|
|
|
my $dbh = C4::Context->dbh;
|
|
|
|
my ( $template, $borrowernumber, $cookie, $staff_flags ) = get_template_and_user(
|
|
{ template_name => "admin/aqplan.tt",
|
|
query => $input,
|
|
type => "intranet",
|
|
flagsrequired => { acquisition => 'planning_manage' },
|
|
}
|
|
);
|
|
|
|
my $budget_period_id = $input->param('budget_period_id');
|
|
# ' ------- get periods stuff ------------------'
|
|
# IF PERIOD_ID IS DEFINED, GET THE PERIOD - ELSE GET THE ACTIVE PERIOD BY DEFAULT
|
|
my $period = GetBudgetPeriod($budget_period_id);
|
|
my $count = GetPeriodsCount();
|
|
my $active_currency = Koha::Acquisition::Currencies->get_active;
|
|
if ( $active_currency ) {
|
|
$template->param( symbol => $active_currency->symbol,
|
|
currency => $active_currency->currency,
|
|
);
|
|
}
|
|
$template->param( period_button_only => 1 ) if $count == 0;
|
|
|
|
|
|
|
|
# authcats_loop populates the YUI planning button
|
|
my $auth_cats_loop = GetBudgetAuthCats($budget_period_id);
|
|
$budget_period_id = $period->{'budget_period_id'};
|
|
my $budget_period_startdate = $period->{'budget_period_startdate'};
|
|
my $budget_period_enddate = $period->{'budget_period_enddate'};
|
|
my $budget_period_locked = $period->{'budget_period_locked'};
|
|
my $budget_period_description = $period->{'budget_period_description'};
|
|
|
|
|
|
$template->param(
|
|
budget_period_id => $budget_period_id,
|
|
budget_period_locked => $budget_period_locked,
|
|
budget_period_description => $budget_period_description,
|
|
auth_cats_loop => $auth_cats_loop,
|
|
);
|
|
|
|
# ------- get periods stuff ------------------
|
|
|
|
|
|
my $borrower_branchcode = my $branch_code = C4::Context->userenv->{'branch'};
|
|
|
|
my $authcat = $input->param('authcat');
|
|
my $show_active = $input->param('show_active') // 0;
|
|
my $show_actual = $input->param('show_actual');
|
|
my $show_percent = $input->param('show_percent');
|
|
my $output = $input->param("output") // q{};
|
|
our $basename = $input->param("basename");
|
|
our $del = C4::Context->csv_delimiter(scalar $input->param("sep"));
|
|
|
|
my $show_mine = $input->param('show_mine') ;
|
|
|
|
my @hide_cols = $input->multi_param('hide_cols');
|
|
|
|
if ( $budget_period_locked == 1 && not defined $show_actual ) {
|
|
$show_actual = 1;
|
|
}
|
|
|
|
$authcat = 'Asort1' if not defined $authcat; # defaults to Asort if no authcat given
|
|
|
|
my $budget_id = $input->param('budget_id');
|
|
my $op = $input->param("op") // q{};
|
|
|
|
my $budgets_ref = GetBudgetHierarchy(
|
|
$budget_period_id,
|
|
$show_mine ? $borrower_branchcode : '',
|
|
$show_mine ? $borrowernumber : ''
|
|
);
|
|
|
|
# build categories list
|
|
my @category_list;
|
|
|
|
# push koha system categories
|
|
push( @category_list, 'MONTHS' );
|
|
push( @category_list, 'ITEMTYPES' );
|
|
push( @category_list, 'BRANCHES' );
|
|
push( @category_list, $_ ) foreach @$auth_cats_loop;
|
|
|
|
#reorder the list
|
|
@category_list = sort { $a cmp $b } @category_list;
|
|
|
|
$template->param( authcat_dropbox => {
|
|
values => \@category_list,
|
|
default => $authcat,
|
|
});
|
|
|
|
my @budgets = @$budgets_ref;
|
|
my @authvals;
|
|
my %labels;
|
|
|
|
my @names = $input->multi_param();
|
|
# ------------------------------------------------------------
|
|
if ( $op eq 'cud-save' ) {
|
|
#get budgets
|
|
my ( @buds, @auth_values );
|
|
foreach my $n (@names) {
|
|
next if $n =~ m/^[^0-9]/;
|
|
my @moo = split( ',', $n );
|
|
push @buds, $moo[0];
|
|
push @auth_values, $moo[1];
|
|
}
|
|
|
|
#uniq buds and auth
|
|
my %seen;
|
|
@buds = grep { !$seen{$_}++ } @buds;
|
|
@auth_values = grep { !$seen{$_}++ } @auth_values;
|
|
my @budget_lines;
|
|
|
|
foreach my $budget (@buds) {
|
|
my %budget_line;
|
|
my @cells_line;
|
|
my %cell_hash;
|
|
|
|
foreach my $authvalue (@auth_values) {
|
|
# get actual stats
|
|
my $cell_name = "$budget,$authvalue";
|
|
my $estimated_amount = $input->param("$cell_name");
|
|
my %cell_hash = (
|
|
estimated_amount => $estimated_amount,
|
|
authvalue => $authvalue,
|
|
authcat => $authcat,
|
|
budget_id => $budget,
|
|
budget_period_id => $budget_period_id,
|
|
);
|
|
push( @cells_line, \%cell_hash );
|
|
}
|
|
|
|
%budget_line = (
|
|
lines => \@cells_line,
|
|
);
|
|
push( @budget_lines, \%budget_line );
|
|
}
|
|
my $plan = \@budget_lines;
|
|
ModBudgetPlan( $plan, $budget_period_id, $authcat );
|
|
|
|
HideCols($authcat, @hide_cols);
|
|
|
|
|
|
}
|
|
# ------------------------------------------------------------
|
|
if ( $authcat =~ m/^Asort/ ) {
|
|
my $query = qq{ SELECT * FROM authorised_values WHERE category=? order by lib };
|
|
my $sth = $dbh->prepare($query);
|
|
$sth->execute($authcat );
|
|
if ( $sth->rows > 0 ) {
|
|
for ( my $i = 0 ; $i < $sth->rows ; $i++ ) {
|
|
my $results = $sth->fetchrow_hashref;
|
|
push @authvals, $results->{authorised_value};
|
|
$labels{ $results->{authorised_value} } = $results->{lib};
|
|
}
|
|
}
|
|
$sth->finish;
|
|
@authvals = sort { $a <=> $b } @authvals;
|
|
}
|
|
elsif ( $authcat eq 'MONTHS' && $budget_period_startdate && $budget_period_enddate ) {
|
|
|
|
# build months
|
|
my @start_date = UnixDate( $budget_period_startdate, ( '%Y', '%m', '%d' ) );
|
|
my @end_date = UnixDate( $budget_period_enddate, ( '%Y', '%m', '%d' ) );
|
|
|
|
my ( $Dy, $Dm, $Dd ) = Delta_YMD( @start_date, @end_date );
|
|
|
|
#calc number of months between
|
|
my $months = ( $Dy * 12 ) + $Dm;
|
|
my $start_month = $start_date[1];
|
|
my $end_month = ( $Dy * 12 ) + $Dm;
|
|
|
|
for my $mth ( 0 ... $months ) {
|
|
$mth = DateCalc( $budget_period_startdate, "+ $mth months" );
|
|
$mth = UnixDate( $mth, "%Y-%m" );
|
|
push( @authvals, $mth );
|
|
}
|
|
foreach my $vv (@authvals) {
|
|
$labels{$vv} = $vv;
|
|
}
|
|
}
|
|
|
|
elsif ( $authcat eq 'ITEMTYPES' ) {
|
|
my $query = qq| SELECT itemtype, description FROM itemtypes |;
|
|
my $sth = $dbh->prepare($query);
|
|
$sth->execute( );
|
|
|
|
if ( $sth->rows > 0 ) {
|
|
for ( my $i = 0 ; $i < $sth->rows ; $i++ ) {
|
|
my $results = $sth->fetchrow_hashref;
|
|
push @authvals, $results->{itemtype};
|
|
$labels{ $results->{itemtype} } = $results->{description};
|
|
}
|
|
}
|
|
$sth->finish;
|
|
|
|
} elsif ( $authcat eq 'BRANCHES' ) {
|
|
|
|
my $query = qq| SELECT branchcode, branchname FROM branches |;
|
|
my $sth = $dbh->prepare($query);
|
|
$sth->execute();
|
|
|
|
if ( $sth->rows > 0 ) {
|
|
for ( my $i = 0 ; $i < $sth->rows ; $i++ ) {
|
|
my $results = $sth->fetchrow_hashref;
|
|
push @authvals, $results->{branchcode};
|
|
$labels{ $results->{branchcode} } = $results->{branchname};
|
|
}
|
|
}
|
|
$sth->finish;
|
|
} elsif ($authcat) {
|
|
my $query = qq{ SELECT * FROM authorised_values WHERE category=? order by lib };
|
|
my $sth = $dbh->prepare($query);
|
|
$sth->execute($authcat);
|
|
if ( $sth->rows > 0 ) {
|
|
for ( my $i = 0 ; $i < $sth->rows ; $i++ ) {
|
|
my $results = $sth->fetchrow_hashref;
|
|
push @authvals, $results->{authorised_value};
|
|
$labels{ $results->{authorised_value} } = $results->{lib};
|
|
}
|
|
}
|
|
$sth->finish;
|
|
}
|
|
|
|
my @authvals_row;
|
|
my $i=1;
|
|
foreach my $val (@authvals) {
|
|
my %auth_hash;
|
|
$auth_hash{val} = $labels{$val};
|
|
$auth_hash{code} = $val;
|
|
$auth_hash{colnum} = $i++;
|
|
|
|
# display lookup
|
|
$auth_hash{display} = GetCols( $authcat, $auth_hash{code});
|
|
|
|
push( @authvals_row, \%auth_hash );
|
|
}
|
|
|
|
#get budgets
|
|
my ( @buds, @auth_values );
|
|
foreach my $n (@names) {
|
|
next if $n =~ m/^[^0-9]/;
|
|
$n =~ m/(\d*),(.*)/;
|
|
push @buds, $1;
|
|
push @auth_values, $2;
|
|
}
|
|
|
|
|
|
# ------------------------------------------------------------
|
|
# DEFAULT DISPLAY BEGINS
|
|
|
|
my $CGIextChoice = ( 'CSV' ); # FIXME translation
|
|
my $CGIsepChoice = ( C4::Context->csv_delimiter );
|
|
|
|
my ( @budget_lines, %cell_hash );
|
|
|
|
|
|
foreach my $budget (@budgets) {
|
|
my $budget_lock;
|
|
|
|
unless (CanUserUseBudget($borrowernumber, $budget, $staff_flags)) {
|
|
$budget_lock = 1
|
|
}
|
|
|
|
# check budget permission
|
|
if ( $period->{budget_period_locked} == 1 ) {
|
|
$budget_lock = 1;
|
|
} elsif ( $budget->{budget_permission} == 1 ) {
|
|
$budget_lock = 1 if $borrowernumber != $budget->{'budget_owner_id'};
|
|
} elsif ( $budget->{budget_permission} == 2 ) {
|
|
$budget_lock = 1 if $borrower_branchcode ne $budget->{budget_branchcode};
|
|
}
|
|
|
|
# allow hard-coded itemtype and branch planning
|
|
unless ( $authcat eq 'ITEMTYPES'
|
|
or $authcat eq 'BRANCHES'
|
|
or $authcat eq 'MONTHS' ) {
|
|
|
|
# but skip budgets that don't match the current auth-category
|
|
next if ( $budget->{'sort1_authcat'} ne $authcat
|
|
&& $budget->{'sort2_authcat'} ne $authcat );
|
|
}
|
|
|
|
my %budget_line; # each row of the table
|
|
my @cells_line;
|
|
my $actual_spent;
|
|
my $estimated_spent;
|
|
|
|
my $i = 0;
|
|
foreach my $authvalue (@authvals) {
|
|
|
|
# get actual stats
|
|
my %cell = (
|
|
budget_id => $budget->{'budget_id'},
|
|
budget_period_id => $budget->{'budget_period_id'},
|
|
cell_name => $budget->{'budget_id'} . ',' . $authvalue,
|
|
authvalue => $authvalue,
|
|
authcat => $authcat,
|
|
cell_authvalue => $authvalue,
|
|
budget_lock => $budget_lock,
|
|
);
|
|
|
|
my ( $actual, $estimated, $display ) = GetBudgetsPlanCell( \%cell, $period, $budget );
|
|
$cell{actual_amount} = sprintf( "%.2f", $actual // 0 );
|
|
$cell{estimated_amount} = sprintf( "%.2f", $estimated // 0 );
|
|
$cell{display} = $authvals_row[$i]{display};
|
|
$cell{colnum} = $i;
|
|
|
|
$actual_spent += $cell{actual_amount};
|
|
$estimated_spent += $cell{estimated_amount};
|
|
|
|
|
|
push( @cells_line, \%cell );
|
|
$i++;
|
|
}
|
|
|
|
my $budget_act_remain = $budget->{budget_amount} - $actual_spent;
|
|
my $budget_est_remain = $budget->{budget_amount} - $estimated_spent;
|
|
|
|
%budget_line = (
|
|
lines => \@cells_line,
|
|
budget_name => $budget->{budget_name},
|
|
budget_amount => $budget->{budget_amount},
|
|
budget_alloc => $budget->{budget_alloc},
|
|
budget_act_remain => sprintf( "%.2f", $budget_act_remain ),
|
|
budget_est_remain => sprintf( "%.2f", $budget_est_remain ),
|
|
budget_id => $budget->{budget_id},
|
|
budget_lock => $budget_lock,
|
|
);
|
|
|
|
|
|
|
|
$budget_line{est_negative} = '1' if $budget_est_remain < 0;
|
|
$budget_line{est_positive} = '1' if $budget_est_remain > 0;
|
|
$budget_line{act_negative} = '1' if $budget_act_remain < 0;
|
|
$budget_line{act_positive} = '1' if $budget_act_remain > 0;
|
|
|
|
# skip if active set , and spent == 0
|
|
next if ( $show_active == '1' && ( $actual_spent == 0 ) );
|
|
|
|
push( @budget_lines, \%budget_line );
|
|
}
|
|
|
|
if ( $output eq "file" ) {
|
|
_print_to_csv(\@authvals_row, \@budget_lines);
|
|
exit();
|
|
}
|
|
|
|
$template->param(
|
|
authvals_row => \@authvals_row,
|
|
budget_lines => \@budget_lines,
|
|
budget_period_description => $period->{'budget_period_description'},
|
|
budget_period_locked => $period->{'budget_period_locked'},
|
|
budget_period_id => $budget_period_id,
|
|
authcat => $authcat,
|
|
show_active => $show_active,
|
|
show_actual => $show_actual,
|
|
show_percent => $show_percent,
|
|
show_mine => $show_mine,
|
|
CGIextChoice => $CGIextChoice,
|
|
CGIsepChoice => $CGIsepChoice,
|
|
|
|
authvals => \@authvals_row,
|
|
hide_cols_loop => \@hide_cols,
|
|
);
|
|
|
|
output_html_with_http_headers $input, $cookie, $template->output;
|
|
|
|
sub _print_to_csv {
|
|
my ( $header, $results ) = @_;
|
|
|
|
binmode STDOUT, ':encoding(UTF-8)';
|
|
|
|
my $csv = Text::CSV_XS->new(
|
|
{ sep_char => $del,
|
|
always_quote => 'TRUE',
|
|
}
|
|
);
|
|
print $input->header(
|
|
-type => 'application/vnd.sun.xml.calc',
|
|
-encoding => 'utf-8',
|
|
-attachment => "$basename.csv",
|
|
-name => "$basename.csv"
|
|
);
|
|
my @col = ( 'Budget name', 'Budget total' );
|
|
foreach my $row (@$header) {
|
|
push @col, $row->{'val'};
|
|
}
|
|
push @col, 'Budget remaining';
|
|
|
|
$csv->combine(@col);
|
|
my $str = $csv->string;
|
|
print "$str\n";
|
|
|
|
foreach my $row (@$results) {
|
|
my @col = ( $row->{'budget_name'}, $row->{'budget_amount'} );
|
|
my $l = $row->{'lines'};
|
|
foreach my $line (@$l) {
|
|
push @col, $line->{'estimated_amount'};
|
|
}
|
|
push @col, $row->{'budget_est_remain'};
|
|
$csv->combine(@col);
|
|
my $str = $csv->string;
|
|
print "$str\n";
|
|
}
|
|
}
|