View | Details | Raw Unified | Return to bug 12164
Collapse All | Expand All

(-)a/C4/Acquisition.pm (+6 lines)
Lines 1723-1728 sub SearchOrders { Link Here
1723
    my $owner = $params->{owner};
1723
    my $owner = $params->{owner};
1724
    my $pending = $params->{pending};
1724
    my $pending = $params->{pending};
1725
    my $ordered = $params->{ordered};
1725
    my $ordered = $params->{ordered};
1726
    my $budget_id = $params->{budget_id};
1726
1727
1727
    my $dbh = C4::Context->dbh;
1728
    my $dbh = C4::Context->dbh;
1728
    my @args = ();
1729
    my @args = ();
Lines 1812-1817 sub SearchOrders { Link Here
1812
        push @args, $userenv->{'number'};
1813
        push @args, $userenv->{'number'};
1813
    }
1814
    }
1814
1815
1816
    if ( $budget_id ) {
1817
        $query .= ' AND aqorders.budget_id = ?';
1818
        push @args, $budget_id;
1819
    }
1820
1815
    $query .= ' ORDER BY aqbasket.basketno';
1821
    $query .= ' ORDER BY aqbasket.basketno';
1816
1822
1817
    my $sth = $dbh->prepare($query);
1823
    my $sth = $dbh->prepare($query);
(-)a/C4/Budgets.pm (+78 lines)
Lines 1013-1018 sub CloneBudgetPeriod { Link Here
1013
1013
1014
    $budget_period->{budget_period_startdate} = $budget_period_startdate;
1014
    $budget_period->{budget_period_startdate} = $budget_period_startdate;
1015
    $budget_period->{budget_period_enddate}   = $budget_period_enddate;
1015
    $budget_period->{budget_period_enddate}   = $budget_period_enddate;
1016
    # The new budget (budget_period) should be active by default
1017
    $budget_period->{budget_period_active}    = 1;
1016
    my $original_budget_period_id = $budget_period->{budget_period_id};
1018
    my $original_budget_period_id = $budget_period->{budget_period_id};
1017
    delete $budget_period->{budget_period_id};
1019
    delete $budget_period->{budget_period_id};
1018
    my $new_budget_period_id = AddBudgetPeriod( $budget_period );
1020
    my $new_budget_period_id = AddBudgetPeriod( $budget_period );
Lines 1092-1097 sub CloneBudgetHierarchy { Link Here
1092
    }
1094
    }
1093
}
1095
}
1094
1096
1097
=head2 MoveOrders
1098
1099
  my $report = MoveOrders({
1100
    from_budget_period_id => $from_budget_period_id,
1101
    to_budget_period_id   => $to_budget_period_id,
1102
  });
1103
1104
Clone a budget hierarchy.
1105
1106
=cut
1107
1108
sub MoveOrders {
1109
    my ($params)              = @_;
1110
    my $from_budget_period_id = $params->{from_budget_period_id};
1111
    my $to_budget_period_id   = $params->{to_budget_period_id};
1112
    return
1113
      if not $from_budget_period_id
1114
          or not $to_budget_period_id
1115
          or $from_budget_period_id == $to_budget_period_id;
1116
1117
    # Can't move orders to an inactive budget (budgetperiod)
1118
    my $budget_period = GetBudgetPeriod($to_budget_period_id);
1119
    return unless $budget_period->{budget_period_active};
1120
1121
    my @report;
1122
    my $dbh     = C4::Context->dbh;
1123
    my $sth_update_aqorders = $dbh->prepare(
1124
        q|
1125
            UPDATE aqorders
1126
            SET budget_id = ?
1127
            WHERE ordernumber = ?
1128
        |
1129
    );
1130
    my $from_budgets = GetBudgetHierarchy($from_budget_period_id);
1131
    for my $from_budget (@$from_budgets) {
1132
        my $new_budget_id = $dbh->selectcol_arrayref(
1133
            q|
1134
                SELECT budget_id
1135
                FROM aqbudgets
1136
                WHERE budget_period_id = ?
1137
                    AND budget_code = ?
1138
            |, {}, $to_budget_period_id, $from_budget->{budget_code}
1139
        );
1140
        $new_budget_id = $new_budget_id->[0];
1141
        my $new_budget = GetBudget( $new_budget_id );
1142
        unless ( $new_budget ) {
1143
            push @report,
1144
              {
1145
                moved       => 0,
1146
                budget_code => $from_budget->{budget_code},
1147
                error       => 'budget_code_not_exists',
1148
              };
1149
            next;
1150
        }
1151
        my $orders_to_move = C4::Acquisition::SearchOrders(
1152
            {
1153
                budget_id => $from_budget->{budget_id},
1154
                pending   => 1,
1155
            }
1156
        );
1157
1158
        my @orders_moved;
1159
        for my $order (@$orders_to_move) {
1160
            $sth_update_aqorders->execute( $new_budget->{budget_id}, $order->{ordernumber} );
1161
            push @orders_moved, $order->{ordernumber};
1162
        }
1163
1164
        push @report,
1165
          {
1166
            budget => $new_budget,
1167
            orders_moved  => \@orders_moved,
1168
            moved         => 1,
1169
          };
1170
    }
1171
    return \@report;
1172
}
1095
1173
1096
END { }    # module clean-up code here (global destructor)
1174
END { }    # module clean-up code here (global destructor)
1097
1175
(-)a/admin/aqbudgetperiods.pl (-2 / +48 lines)
Lines 45-52 script to administer the budget periods table Link Here
45
=cut
45
=cut
46
46
47
## modules
47
## modules
48
use strict;
48
use Modern::Perl;
49
#use warnings; FIXME - Bug 2505
50
use Number::Format qw(format_price);
49
use Number::Format qw(format_price);
51
use CGI;
50
use CGI;
52
use List::Util qw/min/;
51
use List::Util qw/min/;
Lines 202-207 elsif ( $op eq 'duplicate_budget' ){ Link Here
202
    $op = 'else';
201
    $op = 'else';
203
}
202
}
204
203
204
elsif ( $op eq 'close_form' ) {
205
206
    my $budget_period = GetBudgetPeriod($budget_period_id);
207
208
    my $active_budget_periods =
209
      C4::Budgets::GetBudgetPeriods( { active => 1 } );
210
211
    # Remove the budget period from the list
212
    $active_budget_periods =
213
      [ map { ( $_->{budget_period_id} == $budget_period_id ) ? () : $_ }
214
          @$active_budget_periods ];
215
216
    my $budgets_to_move = GetBudgetHierarchy($budget_period_id);
217
218
    # C4::Context->userenv->{branchcode}, $show_mine ? $borrower_id : '')
219
220
    my $number_of_unreceived_orders = 0;
221
    for my $budget (@$budgets_to_move) {
222
223
        # We want to move funds from this budget
224
        my $unreceived_orders = C4::Acquisition::SearchOrders(
225
            { budget_id => $budget->{budget_id}, } );
226
        $budget->{unreceived_orders} = $unreceived_orders;
227
        $number_of_unreceived_orders += scalar(@$unreceived_orders);
228
    }
229
230
    $template->param(
231
        close_form       => 1,
232
        budget_period_id => $budget_period_id,
233
        budget_period_description =>
234
          $budget_period->{budget_period_description},
235
        budget_periods              => $active_budget_periods,
236
        budgets_to_move             => $budgets_to_move,
237
        number_of_unreceived_orders => $number_of_unreceived_orders,
238
    );
239
}
240
241
elsif ( $op eq 'close_confirmed' ) {
242
    my $to_budget_period_id = $input->param('to_budget_period_id');
243
    my $report              = C4::Budgets::MoveOrders(
244
        {
245
            from_budget_period_id => $budget_period_id,
246
            to_budget_period_id   => $to_budget_period_id,
247
        }
248
    );
249
}
250
205
# DEFAULT - DISPLAY AQPERIODS TABLE
251
# DEFAULT - DISPLAY AQPERIODS TABLE
206
# -------------------------------------------------------------------
252
# -------------------------------------------------------------------
207
# display the list of budget periods
253
# display the list of budget periods
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqbudgetperiods.tt (-2 / +89 lines)
Lines 4-9 Link Here
4
[% INCLUDE 'doc-head-close.inc' %]
4
[% INCLUDE 'doc-head-close.inc' %]
5
[% INCLUDE 'calendar.inc' %]
5
[% INCLUDE 'calendar.inc' %]
6
[% INCLUDE 'datatables.inc' %]
6
[% INCLUDE 'datatables.inc' %]
7
[% IF close_form %]
8
    <link href="[% interface %]/lib/jquery/plugins/treetable/stylesheets/jquery.treetable.css" rel="stylesheet" type="text/css" />
9
    <script type="text/javascript" src="[% interface %]/lib/jquery/plugins/treetable/jquery.treetable.js"></script>
10
[% END %]
7
<script type="text/javascript" src="[% themelang %]/js/acq.js"></script>
11
<script type="text/javascript" src="[% themelang %]/js/acq.js"></script>
8
<script type="text/javascript">
12
<script type="text/javascript">
9
// #################################################################################
13
// #################################################################################
Lines 84-91 Link Here
84
                { "aTargets": [ -1 ], "bSortable": false, "bSearchable": false },
88
                { "aTargets": [ -1 ], "bSortable": false, "bSearchable": false },
85
                { "sType": "title-string", "aTargets" : [ "title-string" ] }
89
                { "sType": "title-string", "aTargets" : [ "title-string" ] }
86
            ],
90
            ],
87
            "bPaginate": false
91
            "bPaginate": false,
92
            'bAutoWidth': false
88
        } ) );
93
        } ) );
94
95
        [% IF close_form %]
96
          $("#budgeth").dataTable($.extend(true, {}, dataTablesDefaults, {
97
            sDom: "t"
98
          }));
99
          $("#move_form").submit(function(){
100
            var budget_from = "[% budget_period_description %]";
101
            var budget_to = $("#budget_period").find("option:selected").html();
102
            var alert_message = _("You have chosen to move all unreceived orders from '%s' to '%s'.").format(budget_from, budget_to);
103
            alert_message += _("\nThis action cannot be reversed. Do you wish to continue?");
104
            return confirm ( alert_message );
105
          });
106
        [% END %]
89
    });
107
    });
90
</script>
108
</script>
91
109
Lines 106-111 Link Here
106
    [% IF ( delete_confirmed ) %]&rsaquo;
124
    [% IF ( delete_confirmed ) %]&rsaquo;
107
        Data deleted
125
        Data deleted
108
    [% END %]
126
    [% END %]
127
    [% IF close_form %]&rsaquo;
128
      Close budget [% budget_period_description %]
129
    [% END %]
109
</title>
130
</title>
110
131
111
132
Lines 150-155 Link Here
150
    [% IF ( duplicate_form ) %]
171
    [% IF ( duplicate_form ) %]
151
        <a href="/cgi-bin/koha/admin/aqbudgetperiods.pl">Budgets</a> &rsaquo; Duplicate budget
172
        <a href="/cgi-bin/koha/admin/aqbudgetperiods.pl">Budgets</a> &rsaquo; Duplicate budget
152
    [% END %]
173
    [% END %]
174
175
    <!-- close a budget -->
176
    [% IF close_form %]
177
        <a href="/cgi-bin/koha/admin/aqbudgetperiods.pl">Budgets</a> &rsaquo;
178
        Close budget <a href="cgi-bin/koha/admin/aqbudgets.pl?budget_period_id=[% budget_period_id %]">[% budget_period_description %]</a>
179
    [% END %]
153
    <!-- display budget periods list -->
180
    <!-- display budget periods list -->
154
    <!-- ########################################## -->
181
    <!-- ########################################## -->
155
    [% IF ( else ) %]
182
    [% IF ( else ) %]
Lines 162-168 Link Here
162
<div id="yui-main">
189
<div id="yui-main">
163
<div class="yui-b">
190
<div class="yui-b">
164
191
165
[% INCLUDE 'budgets-admin-toolbar.inc' %]
192
[% UNLESS close_form %]
193
  [% INCLUDE 'budgets-admin-toolbar.inc' %]
194
[% END %]
166
195
167
[% IF ( duplicate_form ) %]
196
[% IF ( duplicate_form ) %]
168
<h3>Duplicate budget</h3>
197
<h3>Duplicate budget</h3>
Lines 309-314 Link Here
309
338
310
    </div>
339
    </div>
311
[% END %]
340
[% END %]
341
342
[% IF close_form %]
343
  [% IF budget_periods.size == 0 %]
344
    You cannot move funds of this budget, there is no active budget.
345
    Please create a new active budget and retry.
346
    <a href="/cgi-bin/koha/admin/aqbudgetperiods.pl">Back</a>
347
  [% ELSIF number_of_unreceived_orders == 0 %]
348
    There is no unreceived orders for this budget.
349
    <a href="/cgi-bin/koha/admin/aqbudgetperiods.pl">Back</a>
350
  [% ELSE %]
351
    <h3>Choose the funds you want to move unreceived orders:</h3>
352
      Fund list of budget <a href="cgi-bin/koha/admin/aqbudgets.pl?budget_period_id=[% budget_period_id %]">[% budget_period_description %]</a>:
353
    <table id="budgeth">
354
      <thead>
355
        <tr>
356
            <th>Fund id</th>
357
            <th>Fund code</th>
358
            <th>Fund name</th>
359
            <th>Unreceived orders</th>
360
        </tr>
361
      </thead>
362
      <tbody>
363
        [% FOREACH budget IN budgets_to_move %]
364
          <tr>
365
            <td>[% budget.budget_id %]</td>
366
            <td>[% budget.budget_code_indent %]</td>
367
            <td>[% budget.budget_name %]</td>
368
            <td>[% budget.unreceived_orders.size %]</td>
369
          </tr>
370
        [% END %]
371
      </tbody>
372
    </table>
373
    <form action="/cgi-bin/koha/admin/aqbudgetperiods.pl" name="f" method="post" id="move_form">
374
      <fieldset class="rows">
375
        <ol>
376
          <li>
377
            <label class="required" for="to_budget_period_id">Select a budget</label>
378
            <select name="to_budget_period_id" id="to_budget_period_id" required="required">
379
              <option value=""></option>
380
              [% FOR budget_period IN budget_periods %]
381
                <option value="[% budget_period.budget_period_id %]">[% budget_period.budget_period_description %]</option>
382
              [% END %]
383
            </select>
384
          </li>
385
        </ol>
386
      </fieldset>
387
      <fieldset class="action">
388
          <input type="hidden" name="op" value="close_confirmed" />
389
          <input type="hidden" name="budget_period_id" value="[% budget_period_id %]" />
390
          <input type="submit" value="Move unreceive orders" />
391
          <a class="cancel" href="/cgi-bin/koha/admin/aqbudgetperiods.pl">Cancel</a>
392
      </fieldset>
393
    </form>
394
  [% END %]
395
[% END %]
396
312
<!--  DEFAULT  display budget periods list -->
397
<!--  DEFAULT  display budget periods list -->
313
[% IF ( else ) %]
398
[% IF ( else ) %]
314
  <h2>Budgets administration</h2>
399
  <h2>Budgets administration</h2>
Lines 350-355 Link Here
350
                  <a href="[% script_name %]?op=add_form&amp;budget_period_id=[% period_active.budget_period_id |html %]">Edit</a>
435
                  <a href="[% script_name %]?op=add_form&amp;budget_period_id=[% period_active.budget_period_id |html %]">Edit</a>
351
                  <a href="[% script_name %]?op=delete_confirm&amp;budget_period_id=[% period_active.budget_period_id %]">Delete</a>
436
                  <a href="[% script_name %]?op=delete_confirm&amp;budget_period_id=[% period_active.budget_period_id %]">Delete</a>
352
                  <a href="[% script_name %]?op=duplicate_form&amp;budget_period_id=[% period_active.budget_period_id %]">Duplicate</a>
437
                  <a href="[% script_name %]?op=duplicate_form&amp;budget_period_id=[% period_active.budget_period_id %]">Duplicate</a>
438
                  <a href="[% script_name %]?op=close_form&amp;budget_period_id=[% period_active.budget_period_id %]">Close</a>
353
                  <a href="/cgi-bin/koha/admin/aqbudgets.pl?op=add_form&amp;budget_period_id=[% period_active.budget_period_id %]">Add fund</a>
439
                  <a href="/cgi-bin/koha/admin/aqbudgets.pl?op=add_form&amp;budget_period_id=[% period_active.budget_period_id %]">Add fund</a>
354
                </td>
440
                </td>
355
                </tr>
441
                </tr>
Lines 390-395 Link Here
390
                      <a href="[% script_name %]?op=add_form&amp;budget_period_id=[% period_loo.budget_period_id |html %]">Edit</a>
476
                      <a href="[% script_name %]?op=add_form&amp;budget_period_id=[% period_loo.budget_period_id |html %]">Edit</a>
391
                      <a href="[% script_name %]?op=delete_confirm&amp;budget_period_id=[% period_loo.budget_period_id %]">Delete</a>
477
                      <a href="[% script_name %]?op=delete_confirm&amp;budget_period_id=[% period_loo.budget_period_id %]">Delete</a>
392
                      <a href="[% script_name %]?op=duplicate_form&amp;budget_period_id=[% period_loo.budget_period_id %]">Duplicate</a>
478
                      <a href="[% script_name %]?op=duplicate_form&amp;budget_period_id=[% period_loo.budget_period_id %]">Duplicate</a>
479
                      <a href="[% script_name %]?op=close_form&amp;budget_period_id=[% period_loo.budget_period_id %]">Close</a>
393
                  <a href="/cgi-bin/koha/admin/aqbudgets.pl?op=add_form&amp;budget_period_id=[% period_loo.budget_period_id %]">Add fund</a>
480
                  <a href="/cgi-bin/koha/admin/aqbudgets.pl?op=add_form&amp;budget_period_id=[% period_loo.budget_period_id %]">Add fund</a>
394
                  </td>
481
                  </td>
395
                  </tr>
482
                  </tr>
(-)a/t/db_dependent/Budgets.t (-2 / +55 lines)
Lines 1-5 Link Here
1
use Modern::Perl;
1
use Modern::Perl;
2
use Test::More tests => 31;
2
use Test::More tests => 37;
3
3
4
BEGIN {use_ok('C4::Budgets') }
4
BEGIN {use_ok('C4::Budgets') }
5
use C4::Biblio;
5
use C4::Biblio;
Lines 16-21 $dbh->{RaiseError} = 1; Link Here
16
16
17
$dbh->do('DELETE FROM aqbudgetperiods');
17
$dbh->do('DELETE FROM aqbudgetperiods');
18
18
19
# Mock userenv
20
local $SIG{__WARN__} = sub { warn $_[0] unless $_[0] =~ /redefined/ };
21
my $userenv;
22
*C4::Context::userenv = \&Mock_userenv;
23
$userenv = { flags => 1, id => 'my_userid', branch => 'CPL' };
24
19
#
25
#
20
# Budget Periods :
26
# Budget Periods :
21
#
27
#
Lines 258-263 my %budgets; Link Here
258
my $invoiceid = AddInvoice(invoicenumber => 'invoice_test_clone', booksellerid => $booksellerid, unknown => "unknown");
264
my $invoiceid = AddInvoice(invoicenumber => 'invoice_test_clone', booksellerid => $booksellerid, unknown => "unknown");
259
my $item_price = 10;
265
my $item_price = 10;
260
my $item_quantity = 2;
266
my $item_quantity = 2;
267
my $number_of_orders_to_move = 0;
261
for my $infos (@order_infos) {
268
for my $infos (@order_infos) {
262
    for ( 1 .. $infos->{pending_quantity} ) {
269
    for ( 1 .. $infos->{pending_quantity} ) {
263
        my ( undef, $ordernumber ) = C4::Acquisition::NewOrder(
270
        my ( undef, $ordernumber ) = C4::Acquisition::NewOrder(
Lines 279-284 for my $infos (@order_infos) { Link Here
279
            }
286
            }
280
        );
287
        );
281
        push @{ $budgets{$infos->{budget_id}} }, $ordernumber;
288
        push @{ $budgets{$infos->{budget_id}} }, $ordernumber;
289
        $number_of_orders_to_move++;
282
    }
290
    }
283
    for ( 1 .. $infos->{spent_quantity} ) {
291
    for ( 1 .. $infos->{spent_quantity} ) {
284
        my ( undef, $ordernumber ) = C4::Acquisition::NewOrder(
292
        my ( undef, $ordernumber ) = C4::Acquisition::NewOrder(
Lines 397-402 is( $number_of_budgets_not_reset, 0, Link Here
397
    'CloneBudgetPeriod has reset all budgets (funds)' );
405
    'CloneBudgetPeriod has reset all budgets (funds)' );
398
406
399
407
408
# MoveOrders
409
my $number_orders_moved = C4::Budgets::MoveOrders();
410
is( $number_orders_moved, undef, 'MoveOrders return undef if no arg passed' );
411
$number_orders_moved =
412
  C4::Budgets::MoveOrders( { from_budget_period_id => $budget_period_id } );
413
is( $number_orders_moved, undef,
414
    'MoveOrders return undef if only 1 arg passed' );
415
$number_orders_moved =
416
  C4::Budgets::MoveOrders( { to_budget_period_id => $budget_period_id } );
417
is( $number_orders_moved, undef,
418
    'MoveOrders return undef if only 1 arg passed' );
419
$number_orders_moved = C4::Budgets::MoveOrders(
420
    {
421
        from_budget_period_id => $budget_period_id,
422
        to_budget_period_id   => $budget_period_id
423
    }
424
);
425
is( $number_orders_moved, undef,
426
    'MoveOrders return undef if 2 budget period id are the same' );
427
428
$budget_period_id_cloned = C4::Budgets::CloneBudgetPeriod(
429
    {
430
        budget_period_id        => $budget_period_id,
431
        budget_period_startdate => '2014-01-01',
432
        budget_period_enddate   => '2014-12-31',
433
        reset_all_funds         => 1,
434
    }
435
);
436
437
my $report = C4::Budgets::MoveOrders(
438
    {
439
        from_budget_period_id => $budget_period_id,
440
        to_budget_period_id   => $budget_period_id_cloned,
441
    }
442
);
443
is( scalar( @$report ), 6 , "MoveOrders has processed 6 funds" );
444
445
my $number_of_orders_moved = 0;
446
$number_of_orders_moved += scalar( @{ $_->{orders_moved} } ) for @$report;
447
is( $number_of_orders_moved, $number_of_orders_to_move, "MoveOrders has moved $number_of_orders_to_move orders" );
448
400
sub _get_dependencies {
449
sub _get_dependencies {
401
    my ($budget_hierarchy) = @_;
450
    my ($budget_hierarchy) = @_;
402
    my $graph;
451
    my $graph;
Lines 421-423 sub _get_budgetname_by_id { Link Here
421
      @$budgets;
470
      @$budgets;
422
    return $budget_name;
471
    return $budget_name;
423
}
472
}
424
- 
473
474
# C4::Context->userenv
475
sub Mock_userenv {
476
    return $userenv;
477
}

Return to bug 12164