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

(-)a/C4/Reserves.pm (-45 / +75 lines)
Lines 148-170 BEGIN { Link Here
148
148
149
=head2 AddReserve
149
=head2 AddReserve
150
150
151
    AddReserve($branch,$borrowernumber,$biblionumber,$bibitems,$priority,$resdate,$expdate,$notes,$title,$checkitem,$found)
151
    AddReserve(
152
        $branch,  $borrowernumber, $biblionumber, $bibitems,   $priority, $resdate,
153
        $expdate, $notes,          $title,        $itemnumber, $found
154
      )
152
155
153
=cut
156
=cut
154
157
155
sub AddReserve {
158
sub AddReserve {
156
    my (
159
    my (
157
        $branch,    $borrowernumber, $biblionumber,
160
        $branch,  $borrowernumber, $biblionumber, $bibitems,   $priority, $resdate,
158
        $bibitems,  $priority, $resdate, $expdate, $notes,
161
        $expdate, $notes,          $title,        $itemnumber, $found
159
        $title,      $checkitem, $found
160
    ) = @_;
162
    ) = @_;
161
163
162
    if ( Koha::Holds->search( { borrowernumber => $borrowernumber, biblionumber => $biblionumber } )->count() > 0 ) {
164
    # Ensure the holds should be allowed
163
        carp("AddReserve: borrower $borrowernumber already has a hold for biblionumber $biblionumber");
165
    my $can_reserve =
166
      $itemnumber
167
      ? CanItemBeReserved( $borrowernumber, $itemnumber )
168
      : CanBookBeReserved( $borrowernumber, $biblionumber );
169
    if ( $can_reserve eq 'maxHoldsForRecord' ) {
170
        carp("AddReserve: borrower $borrowernumber has already reached the max holds for biblionumber $biblionumber");
164
        return;
171
        return;
165
    }
172
    }
166
173
167
    my $dbh     = C4::Context->dbh;
174
    my $dbh = C4::Context->dbh;
168
175
169
    $resdate = format_date_in_iso( $resdate ) if ( $resdate );
176
    $resdate = format_date_in_iso( $resdate ) if ( $resdate );
170
    $resdate = C4::Dates->today( 'iso' ) unless ( $resdate );
177
    $resdate = C4::Dates->today( 'iso' ) unless ( $resdate );
Lines 197-203 sub AddReserve { Link Here
197
            branchcode     => $branch,
204
            branchcode     => $branch,
198
            priority       => $priority,
205
            priority       => $priority,
199
            reservenotes   => $notes,
206
            reservenotes   => $notes,
200
            itemnumber     => $checkitem,
207
            itemnumber     => $itemnumber,
201
            found          => $found,
208
            found          => $found,
202
            waitingdate    => $waitingdate,
209
            waitingdate    => $waitingdate,
203
            expirationdate => $expdate
210
            expirationdate => $expdate
Lines 223-229 sub AddReserve { Link Here
223
                'branches'  => $branch_details,
230
                'branches'  => $branch_details,
224
                'borrowers' => $borrower,
231
                'borrowers' => $borrower,
225
                'biblio'    => $biblionumber,
232
                'biblio'    => $biblionumber,
226
                'items'     => $checkitem,
233
                'items'     => $itemnumber,
227
            },
234
            },
228
        ) ) {
235
        ) ) {
229
236
Lines 465-491 sub CanItemBeReserved { Link Here
465
472
466
    my $controlbranch = C4::Context->preference('ReservesControlBranch');
473
    my $controlbranch = C4::Context->preference('ReservesControlBranch');
467
474
468
    # we retrieve user rights on this itemtype and branchcode
475
    my $querycount = "SELECT COUNT(*) as count
469
    my $sth = $dbh->prepare(
476
                      FROM reserves
470
        "SELECT categorycode, itemtype, branchcode, reservesallowed
477
                      LEFT JOIN items USING (itemnumber)
471
                             FROM issuingrules
478
                      LEFT JOIN biblioitems ON (reserves.biblionumber=biblioitems.biblionumber)
472
                             WHERE (categorycode in (?,'*') )
479
                      LEFT JOIN borrowers USING (borrowernumber)
473
                             AND (itemtype IN (?,'*'))
480
                      WHERE borrowernumber = ?";
474
                             AND (branchcode IN (?,'*'))
475
                             ORDER BY
476
                               categorycode DESC,
477
                               itemtype     DESC,
478
                               branchcode   DESC;"
479
    );
480
481
    my $querycount = "SELECT
482
                            count(*) as count
483
                            FROM reserves
484
                                LEFT JOIN items USING (itemnumber)
485
                                LEFT JOIN biblioitems ON (reserves.biblionumber=biblioitems.biblionumber)
486
                                LEFT JOIN borrowers USING (borrowernumber)
487
                            WHERE borrowernumber = ?
488
                                ";
489
481
490
    my $branchcode  = "";
482
    my $branchcode  = "";
491
    my $branchfield = "reserves.branchcode";
483
    my $branchfield = "reserves.branchcode";
Lines 499-509 sub CanItemBeReserved { Link Here
499
        $branchcode  = $borrower->{branchcode};
491
        $branchcode  = $borrower->{branchcode};
500
    }
492
    }
501
493
494
    # we retrieve user rights on this itemtype and branchcode
495
    my $rule = _get_rule( $borrower->{categorycode}, $item->{itype}, $branchcode );
496
502
    # we retrieve rights
497
    # we retrieve rights
503
    $sth->execute( $borrower->{'categorycode'}, $item->{'itype'}, $branchcode );
498
    if ( $rule ) {
504
    if ( my $rights = $sth->fetchrow_hashref() ) {
499
        $ruleitemtype    = $rule->get_column('itemtype');
505
        $ruleitemtype    = $rights->{itemtype};
500
        $allowedreserves = $rule->get_column('reservesallowed');
506
        $allowedreserves = $rights->{reservesallowed};
507
    }
501
    }
508
    else {
502
    else {
509
        $ruleitemtype = '*';
503
        $ruleitemtype = '*';
Lines 564-569 sub CanItemBeReserved { Link Here
564
        }
558
        }
565
    }
559
    }
566
560
561
    my $holds_on_record = Koha::Holds->search(
562
        {
563
            borrowernumber => $borrowernumber,
564
            biblionumber   => $item->{biblionumber}
565
        }
566
    )->count();
567
    return 'maxHoldsForRecord' if ( $holds_on_record >= $rule->holds_per_record );
568
569
    if ($itemnumber) {
570
        my $hold_on_item = Koha::Holds->search(
571
            {
572
                borrowernumber => $borrowernumber,
573
                itemnumber     => $itemnumber
574
            }
575
        )->count();
576
        return 'itemAlreadyOnHold' if ($hold_on_item);
577
    }
578
567
    return 'OK';
579
    return 'OK';
568
}
580
}
569
581
Lines 1273-1279 sub ModReserveStatus { Link Here
1273
1285
1274
=head2 ModReserveAffect
1286
=head2 ModReserveAffect
1275
1287
1276
  &ModReserveAffect($itemnumber,$borrowernumber,$diffBranchSend);
1288
&ModReserveAffect( $itemnumber, $borrowernumber, $diffBranchSend, $reserve_id );
1277
1289
1278
This function affect an item and a status for a given reserve
1290
This function affect an item and a status for a given reserve
1279
The itemnumber parameter is used to find the biblionumber.
1291
The itemnumber parameter is used to find the biblionumber.
Lines 1287-1293 take care of the waiting status Link Here
1287
=cut
1299
=cut
1288
1300
1289
sub ModReserveAffect {
1301
sub ModReserveAffect {
1290
    my ( $itemnumber, $borrowernumber,$transferToDo ) = @_;
1302
    my ( $itemnumber, $borrowernumber, $transferToDo, $reserve_id ) = @_;
1291
    my $dbh = C4::Context->dbh;
1303
    my $dbh = C4::Context->dbh;
1292
1304
1293
    # we want to attach $itemnumber to $borrowernumber, find the biblionumber
1305
    # we want to attach $itemnumber to $borrowernumber, find the biblionumber
Lines 1298-1307 sub ModReserveAffect { Link Here
1298
1310
1299
    # get request - need to find out if item is already
1311
    # get request - need to find out if item is already
1300
    # waiting in order to not send duplicate hold filled notifications
1312
    # waiting in order to not send duplicate hold filled notifications
1301
    my $reserve_id = GetReserveId({
1313
    $reserve_id ||= GetReserveId(
1302
        borrowernumber => $borrowernumber,
1314
        {
1303
        biblionumber   => $biblionumber,
1315
            borrowernumber => $borrowernumber,
1304
    });
1316
            biblionumber   => $biblionumber,
1317
        }
1318
    );
1305
    return unless defined $reserve_id;
1319
    return unless defined $reserve_id;
1306
    my $request = GetReserveInfo($reserve_id);
1320
    my $request = GetReserveInfo($reserve_id);
1307
    my $already_on_shelf = ($request && $request->{found} eq 'W') ? 1 : 0;
1321
    my $already_on_shelf = ($request && $request->{found} eq 'W') ? 1 : 0;
Lines 1314-1321 sub ModReserveAffect { Link Here
1314
        SET    priority = 0,
1328
        SET    priority = 0,
1315
               itemnumber = ?,
1329
               itemnumber = ?,
1316
               found = 'T'
1330
               found = 'T'
1317
        WHERE borrowernumber = ?
1331
        WHERE reserve_id = ?
1318
          AND biblionumber = ?
1319
    ";
1332
    ";
1320
    }
1333
    }
1321
    else {
1334
    else {
Lines 1326-1337 sub ModReserveAffect { Link Here
1326
                    found = 'W',
1339
                    found = 'W',
1327
                    waitingdate = NOW(),
1340
                    waitingdate = NOW(),
1328
                    itemnumber = ?
1341
                    itemnumber = ?
1329
            WHERE borrowernumber = ?
1342
            WHERE reserve_id = ?
1330
              AND biblionumber = ?
1331
        ";
1343
        ";
1332
    }
1344
    }
1333
    $sth = $dbh->prepare($query);
1345
    $sth = $dbh->prepare($query);
1334
    $sth->execute( $itemnumber, $borrowernumber,$biblionumber);
1346
    $sth->execute( $itemnumber, $reserve_id );
1335
    _koha_notify_reserve( $itemnumber, $borrowernumber, $biblionumber ) if ( !$transferToDo && !$already_on_shelf );
1347
    _koha_notify_reserve( $itemnumber, $borrowernumber, $biblionumber ) if ( !$transferToDo && !$already_on_shelf );
1336
    _FixPriority( { biblionumber => $biblionumber } );
1348
    _FixPriority( { biblionumber => $biblionumber } );
1337
    if ( C4::Context->preference("ReturnToShelvingCart") ) {
1349
    if ( C4::Context->preference("ReturnToShelvingCart") ) {
Lines 2435-2440 sub IsItemOnHoldAndFound { Link Here
2435
    return $found;
2447
    return $found;
2436
}
2448
}
2437
2449
2450
sub _get_rule {
2451
    my ( $categorycode, $itemtype, $branchcode ) = @_;
2452
2453
    my $schema = Koha::Database->new()->schema();
2454
2455
    my $rule = $schema->resultset('Issuingrule')->search(
2456
        {
2457
            categorycode => { -in => $categorycode ? [ $categorycode, '*' ] : ['*'] },
2458
            itemtype     => { -in => $itemtype     ? [ $itemtype,     '*' ] : ['*'] },
2459
            branchcode   => { -in => $branchcode   ? [ $branchcode,   '*' ] : ['*'] },
2460
2461
        },
2462
        { order_by => { -desc => [ 'categorycode', 'itemtype', 'branchcode' ] } }
2463
    )->next();
2464
2465
    return $rule;
2466
}
2467
2438
=head1 AUTHOR
2468
=head1 AUTHOR
2439
2469
2440
Koha Development Team <http://koha-community.org/>
2470
Koha Development Team <http://koha-community.org/>
(-)a/circ/returns.pl (-18 / +16 lines)
Lines 142-164 if ($query->param('WT-itemNumber')){ Link Here
142
	updateWrongTransfer ($query->param('WT-itemNumber'),$query->param('WT-waitingAt'),$query->param('WT-From'));
142
	updateWrongTransfer ($query->param('WT-itemNumber'),$query->param('WT-waitingAt'),$query->param('WT-From'));
143
}
143
}
144
144
145
if ( $query->param('resbarcode') ) {
145
if ( $query->param('reserve_id') ) {
146
    my $item           = $query->param('itemnumber');
146
    my $reserve_id         = $query->param('reserve_id');
147
    my $borrowernumber = $query->param('borrowernumber');
147
    my $item               = $query->param('itemnumber');
148
    my $resbarcode     = $query->param('resbarcode');
148
    my $borrowernumber     = $query->param('borrowernumber');
149
    my $diffBranchReturned = $query->param('diffBranch');
149
    my $diffBranchReturned = $query->param('diffBranch');
150
    my $cancel_reserve     = $query->param('cancel_reserve');
151
150
    my $iteminfo   = GetBiblioFromItemNumber($item);
152
    my $iteminfo   = GetBiblioFromItemNumber($item);
151
    my $cancel_reserve = $query->param('cancel_reserve');
152
    # fix up item type for display
153
    # fix up item type for display
153
    $iteminfo->{'itemtype'} = C4::Context->preference('item-level_itypes') ? $iteminfo->{'itype'} : $iteminfo->{'itemtype'};
154
    $iteminfo->{'itemtype'} = C4::Context->preference('item-level_itypes') ? $iteminfo->{'itype'} : $iteminfo->{'itemtype'};
154
155
155
    if ( $cancel_reserve ) {
156
    if ( $cancel_reserve ) {
156
        CancelReserve({ borrowernumber => $borrowernumber, itemnumber => $item, charge_cancel_fee => !$forgivemanualholdsexpire });
157
        CancelReserve({ reserve_id => $reserve_id, charge_cancel_fee => !$forgivemanualholdsexpire });
157
    } else {
158
    } else {
158
        my $diffBranchSend = ($userenv_branch ne $diffBranchReturned) ? $diffBranchReturned : undef;
159
        my $diffBranchSend = ($userenv_branch ne $diffBranchReturned) ? $diffBranchReturned : undef;
159
        # diffBranchSend tells ModReserveAffect whether document is expected in this library or not,
160
        # diffBranchSend tells ModReserveAffect whether document is expected in this library or not,
160
        # i.e., whether to apply waiting status
161
        # i.e., whether to apply waiting status
161
        ModReserveAffect( $item, $borrowernumber, $diffBranchSend);
162
        ModReserveAffect( $item, $borrowernumber, $diffBranchSend, $reserve_id );
162
    }
163
    }
163
#   check if we have other reserves for this document, if we have a return send the message of transfer
164
#   check if we have other reserves for this document, if we have a return send the message of transfer
164
    my ( $messages, $nextreservinfo ) = GetOtherReserves($item);
165
    my ( $messages, $nextreservinfo ) = GetOtherReserves($item);
Lines 426-438 if ( $messages->{'ResFound'}) { Link Here
426
427
427
    if ( $reserve->{'ResFound'} eq "Waiting" or $reserve->{'ResFound'} eq "Reserved" ) {
428
    if ( $reserve->{'ResFound'} eq "Waiting" or $reserve->{'ResFound'} eq "Reserved" ) {
428
        if ( $reserve->{'ResFound'} eq "Waiting" ) {
429
        if ( $reserve->{'ResFound'} eq "Waiting" ) {
430
            $template->param( waiting => $userenv_branch eq $reserve->{'branchcode'}, );
431
        }
432
        elsif ( $reserve->{'ResFound'} eq "Reserved" ) {
429
            $template->param(
433
            $template->param(
430
                waiting      => ($userenv_branch eq $reserve->{'branchcode'} ? 1 : 0 ),
434
                intransit    => $userenv_branch eq $reserve->{'branchcode'},
431
            );
435
                transfertodo => $userenv_branch eq $reserve->{'branchcode'},
432
        } elsif ( $reserve->{'ResFound'} eq "Reserved" ) {
433
            $template->param(
434
                intransit    => ($userenv_branch eq $reserve->{'branchcode'} ? 0 : 1 ),
435
                transfertodo => ($userenv_branch eq $reserve->{'branchcode'} ? 0 : 1 ),
436
                resbarcode   => $barcode,
436
                resbarcode   => $barcode,
437
                reserved     => 1,
437
                reserved     => 1,
438
            );
438
            );
Lines 440-448 if ( $messages->{'ResFound'}) { Link Here
440
440
441
        # same params for Waiting or Reserved
441
        # same params for Waiting or Reserved
442
        $template->param(
442
        $template->param(
443
            reserve        => $reserve,
444
            patron         => $borr,
443
            found          => 1,
445
            found          => 1,
444
            currentbranch  => $branches->{$userenv_branch}->{'branchname'},
446
            barcode        => $barcode,
445
            destbranchname => $branches->{ $reserve->{'branchcode'} }->{'branchname'},
446
            name           => $borr->{'surname'} . ", " . $borr->{'title'} . " " . $borr->{'firstname'},
447
            name           => $borr->{'surname'} . ", " . $borr->{'title'} . " " . $borr->{'firstname'},
447
            borfirstname   => $borr->{'firstname'},
448
            borfirstname   => $borr->{'firstname'},
448
            borsurname     => $borr->{'surname'},
449
            borsurname     => $borr->{'surname'},
Lines 457-467 if ( $messages->{'ResFound'}) { Link Here
457
            borcnum        => $borr->{'cardnumber'},
458
            borcnum        => $borr->{'cardnumber'},
458
            debarred       => $borr->{'debarred'},
459
            debarred       => $borr->{'debarred'},
459
            gonenoaddress  => $borr->{'gonenoaddress'},
460
            gonenoaddress  => $borr->{'gonenoaddress'},
460
            barcode        => $barcode,
461
            destbranch     => $reserve->{'branchcode'},
462
            borrowernumber => $reserve->{'borrowernumber'},
461
            borrowernumber => $reserve->{'borrowernumber'},
463
            itemnumber     => $reserve->{'itemnumber'},
462
            itemnumber     => $reserve->{'itemnumber'},
464
            reservenotes   => $reserve->{'reservenotes'},
465
        );
463
        );
466
    } # else { ; }  # error?
464
    } # else { ; }  # error?
467
}
465
}
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt (-16 / +17 lines)
Lines 193-199 $(document).ready(function () { Link Here
193
    [% END %]</div>
193
    [% END %]</div>
194
[% END %]
194
[% END %]
195
195
196
[% IF ( found ) %]
196
[% IF ( reserve ) %]
197
<!-- found -->
197
<!-- found -->
198
<!-- case of a reservation found, and display info -->
198
<!-- case of a reservation found, and display info -->
199
    [% IF ( waiting ) %]
199
    [% IF ( waiting ) %]
Lines 205-211 $(document).ready(function () { Link Here
205
205
206
<div id="hold-found1" class="dialog message">
206
<div id="hold-found1" class="dialog message">
207
        <h3>Hold found (item is already waiting):  <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% itembiblionumber %]">[% title |html %]</a></h3>
207
        <h3>Hold found (item is already waiting):  <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% itembiblionumber %]">[% title |html %]</a></h3>
208
        [% IF ( reservenotes ) %]<h4>Notes: [% reservenotes %]</h4>[% END %]
208
        [% IF ( reserve.reservenotes ) %]<h4>Notes: [% reserve.reservenotes %]</h4>[% END %]
209
        <h4>Hold for:</h4>
209
        <h4>Hold for:</h4>
210
			<ul>
210
			<ul>
211
            <li><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">[% borsurname %], [% borfirstname %]</a> ([% borcnum %])</li>
211
            <li><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">[% borsurname %], [% borfirstname %]</a> ([% borcnum %])</li>
Lines 217-225 $(document).ready(function () { Link Here
217
[% IF ( debarred ) %]<li class="error">Patron is RESTRICTED</li>[% END %]
217
[% IF ( debarred ) %]<li class="error">Patron is RESTRICTED</li>[% END %]
218
[% IF ( gonenoaddress ) %]<li class="error">Patron's address is in doubt</li>[% END %]</ul>
218
[% IF ( gonenoaddress ) %]<li class="error">Patron's address is in doubt</li>[% END %]</ul>
219
		[% IF ( transfertodo ) %]
219
		[% IF ( transfertodo ) %]
220
            <h4><strong>Transfer to:</strong> [% destbranchname %]</h4>
220
            <h4><strong>Transfer to:</strong> [% Branches.GetName( reserve.branchcode ) %]</h4>
221
		[% ELSE %]
221
		[% ELSE %]
222
		<h4><strong>Hold at</strong> [% destbranchname %]</h4>
222
		<h4><strong>Hold at</strong> [% Branches.GetName( reserve.branchcode ) %]</h4>
223
        [% END %]
223
        [% END %]
224
        <form method="post" action="returns.pl" class="confirm">
224
        <form method="post" action="returns.pl" class="confirm">
225
            <input type="hidden" name="cancel_reserve" value="0" />
225
            <input type="hidden" name="cancel_reserve" value="0" />
Lines 238-244 $(document).ready(function () { Link Here
238
                <input type="hidden" name="borrowernumber" value="[% borrowernumber %]" />
238
                <input type="hidden" name="borrowernumber" value="[% borrowernumber %]" />
239
                <input type="hidden" name="biblionumber" value="[% itembiblionumber %]" />
239
                <input type="hidden" name="biblionumber" value="[% itembiblionumber %]" />
240
                <input type="hidden" name="resbarcode" value="[% barcode %]" />
240
                <input type="hidden" name="resbarcode" value="[% barcode %]" />
241
                <input type="hidden" name="diffBranch" value="[% destbranch %]" />
241
                <input type="hidden" name="diffBranch" value="[% reserves.branchcode %]" />
242
                <input type="hidden" name="exemptfine" value="[% exemptfine %]" />
242
                <input type="hidden" name="exemptfine" value="[% exemptfine %]" />
243
                <input type="hidden" name="dropboxmode" value="[% dropboxmode %]" />
243
                <input type="hidden" name="dropboxmode" value="[% dropboxmode %]" />
244
                <input type="hidden" name="forgivemanualholdsexpire" value="[% forgivemanualholdsexpire %]" />
244
                <input type="hidden" name="forgivemanualholdsexpire" value="[% forgivemanualholdsexpire %]" />
Lines 268-276 $(document).ready(function () { Link Here
268
[% IF ( gonenoaddress ) %]<li class="error">Patron's address is in doubt</li>[% END %]
268
[% IF ( gonenoaddress ) %]<li class="error">Patron's address is in doubt</li>[% END %]
269
                    </ul>
269
                    </ul>
270
		[% IF ( transfertodo ) %]
270
		[% IF ( transfertodo ) %]
271
            <h4><strong>Transfer to:</strong> [% destbranchname %]</h4>
271
            <h4><strong>Transfer to:</strong> [% Branches.GetName( reserve.branchcode ) %]</h4>
272
		[% ELSE %]
272
		[% ELSE %]
273
		<h4><strong>Hold at</strong> [% destbranchname %]</h4>
273
		<h4><strong>Hold at</strong> [% Branches.GetName( reserve.branchcode ) %]</h4>
274
        [% END %]
274
        [% END %]
275
275
276
        <form method="post" action="returns.pl" class="confirm">
276
        <form method="post" action="returns.pl" class="confirm">
Lines 284-290 $(document).ready(function () { Link Here
284
                <input type="hidden" name="dd-[% inputloo.counter %]" value="[% inputloo.duedate %]" />
284
                <input type="hidden" name="dd-[% inputloo.counter %]" value="[% inputloo.duedate %]" />
285
                <input type="hidden" name="bn-[% inputloo.counter %]" value="[% inputloo.borrowernumber %]" />
285
                <input type="hidden" name="bn-[% inputloo.counter %]" value="[% inputloo.borrowernumber %]" />
286
            [% END %]
286
            [% END %]
287
            <input type="hidden" name="diffBranch" value="[% destbranch %]" />
287
            <input type="hidden" name="diffBranch" value="[% reserves.branchcode %]" />
288
            <input type="hidden" name="exemptfine" value="[% exemptfine %]" />
288
            <input type="hidden" name="exemptfine" value="[% exemptfine %]" />
289
            <input type="hidden" name="dropboxmode" value="[% dropboxmode %]" />
289
            <input type="hidden" name="dropboxmode" value="[% dropboxmode %]" />
290
            <input type="hidden" name="forgivemanualholdsexpire" value="[% forgivemanualholdsexpire %]" />
290
            <input type="hidden" name="forgivemanualholdsexpire" value="[% forgivemanualholdsexpire %]" />
Lines 375-381 $(document).ready(function () { Link Here
375
375
376
	<div id="hold-found2" class="dialog message">
376
	<div id="hold-found2" class="dialog message">
377
      <h3>Hold found: <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% itembiblionumber %]">[% title |html %]</a></h3>
377
      <h3>Hold found: <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% itembiblionumber %]">[% title |html %]</a></h3>
378
        [% IF ( reservenotes ) %]<h4>Notes: [% reservenotes %]</h4>[% END %]
378
        [% IF ( reserve.reservenotes ) %]<h4>Notes: [% reserve.reservenotes %]</h4>[% END %]
379
        <h5>Hold for:</h5>
379
        <h5>Hold for:</h5>
380
		<ul>
380
		<ul>
381
            <li><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">
381
            <li><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">
Lines 390-398 $(document).ready(function () { Link Here
390
[% IF ( gonenoaddress ) %]<li class="error">Patron's address is in doubt</li>[% END %]
390
[% IF ( gonenoaddress ) %]<li class="error">Patron's address is in doubt</li>[% END %]
391
        </ul>
391
        </ul>
392
        [% IF ( transfertodo ) %]
392
        [% IF ( transfertodo ) %]
393
            <h4><strong>Transfer to:</strong> [% destbranchname %]</h4>
393
            <h4><strong>Transfer to:</strong> [% Branches.GetName( reserve.branchcode ) %]</h4>
394
		[% ELSE %]
394
		[% ELSE %]
395
		<h4><strong>Hold at</strong> [% destbranchname %]</h4>
395
		<h4><strong>Hold at</strong> [% Branches.GetName( reserve.branchcode ) %]</h4>
396
        [% END %]
396
        [% END %]
397
        <form method="post" action="returns.pl" class="confirm">
397
        <form method="post" action="returns.pl" class="confirm">
398
            <input type="hidden" name="print_slip" value="0" />
398
            <input type="hidden" name="print_slip" value="0" />
Lines 405-418 $(document).ready(function () { Link Here
405
            [% END %]
405
            [% END %]
406
                <input type="submit" class="deny" value="Ignore" onclick="$('.dialog:visible').hide('slow'); $('#barcode').focus(); return false;" />
406
                <input type="submit" class="deny" value="Ignore" onclick="$('.dialog:visible').hide('slow'); $('#barcode').focus(); return false;" />
407
            [% FOREACH inputloo IN inputloop %]
407
            [% FOREACH inputloo IN inputloop %]
408
	<input type="hidden" name="ri-[% inputloo.counter %]" value="[% inputloo.barcode %]" />
408
                <input type="hidden" name="ri-[% inputloo.counter %]" value="[% inputloo.barcode %]" />
409
	<input type="hidden" name="dd-[% inputloo.counter %]" value="[% inputloo.duedate %]" />
409
                <input type="hidden" name="dd-[% inputloo.counter %]" value="[% inputloo.duedate %]" />
410
	<input type="hidden" name="bn-[% inputloo.counter %]" value="[% inputloo.borrowernumber %]" />[% END %]
410
                <input type="hidden" name="bn-[% inputloo.counter %]" value="[% inputloo.borrowernumber %]" />
411
            [% END %]
411
            <input type="hidden" name="itemnumber" value="[% itemnumber %]" />
412
            <input type="hidden" name="itemnumber" value="[% itemnumber %]" />
412
            <input type="hidden" name="borrowernumber" value="[% borrowernumber %]" />
413
            <input type="hidden" name="borrowernumber" value="[% borrowernumber %]" />
413
            <input type="hidden" name="biblionumber" value="[% itembiblionumber %]" />
414
            <input type="hidden" name="biblionumber" value="[% itembiblionumber %]" />
414
            <input type="hidden" name="resbarcode" value="[% barcode %]" />
415
            <input type="hidden" name="reserve_id" value="[% reserve.reserve_id %]" />
415
            <input type="hidden" name="diffBranch" value="[% destbranch %]" />
416
            <input type="hidden" name="diffBranch" value="[% reserves.branchcode %]" />
416
            <input type="hidden" name="exemptfine" value="[% exemptfine %]" />
417
            <input type="hidden" name="exemptfine" value="[% exemptfine %]" />
417
            <input type="hidden" name="dropboxmode" value="[% dropboxmode %]" />
418
            <input type="hidden" name="dropboxmode" value="[% dropboxmode %]" />
418
            <input type="hidden" name="forgivemanualholdsexpire" value="[% forgivemanualholdsexpire %]" />
419
            <input type="hidden" name="forgivemanualholdsexpire" value="[% forgivemanualholdsexpire %]" />
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt (-1 / +1 lines)
Lines 309-315 function checkMultiHold() { Link Here
309
        [% ELSIF ( alreadypossession ) %]
309
        [% ELSIF ( alreadypossession ) %]
310
          <li> <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">[% borrowerfirstname %] [% borrowersurname %]</a> <strong>is already in possession</strong> of one item</li>
310
          <li> <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">[% borrowerfirstname %] [% borrowersurname %]</a> <strong>is already in possession</strong> of one item</li>
311
        [% ELSIF ( alreadyreserved ) %]
311
        [% ELSIF ( alreadyreserved ) %]
312
          <li><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">[% borrowerfirstname %] [% borrowersurname %]</a> <strong>already has a hold</strong> on this item </li>
312
          <li><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">[% borrowerfirstname %] [% borrowersurname %]</a> <strong>has already placed the maximum number of holds allowed</strong> on this record </li>
313
        [% ELSIF ( ageRestricted ) %]
313
        [% ELSIF ( ageRestricted ) %]
314
          <li><strong>Age restricted</strong></li>
314
          <li><strong>Age restricted</strong></li>
315
        [% ELSIF ( none_available ) %]
315
        [% ELSIF ( none_available ) %]
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-reserve.tt (-1 / +1 lines)
Lines 147-153 Link Here
147
                                                <div class="alert">Sorry, you are too young to reserve this material.</div>
147
                                                <div class="alert">Sorry, you are too young to reserve this material.</div>
148
                                            [% END %]
148
                                            [% END %]
149
                                            [% IF ( bibitemloo.already_reserved ) %]
149
                                            [% IF ( bibitemloo.already_reserved ) %]
150
                                                <div class="alert">You have already requested this title.</div>
150
                                                <div class="alert">You have already placed the maximum number of requests for this title.</div>
151
                                            [% ELSE %]
151
                                            [% ELSE %]
152
                                                [% UNLESS ( bibitemloo.bib_available ) %]
152
                                                [% UNLESS ( bibitemloo.bib_available ) %]
153
                                                    <div class="alert">No available items.</div>
153
                                                    <div class="alert">No available items.</div>
(-)a/opac/opac-reserve.pl (-9 / +4 lines)
Lines 338-344 if ( IsDebarred($borrowernumber) ) { Link Here
338
}
338
}
339
339
340
my @reserves = GetReservesFromBorrowernumber( $borrowernumber );
340
my @reserves = GetReservesFromBorrowernumber( $borrowernumber );
341
my $reserves_count = scalar(@reserves);
341
my $reserves_count = scalar @reserves;
342
$template->param( RESERVES => \@reserves );
342
$template->param( RESERVES => \@reserves );
343
if ( $maxreserves && ( $reserves_count >= $maxreserves ) ) {
343
if ( $maxreserves && ( $reserves_count >= $maxreserves ) ) {
344
    $template->param( message => 1 );
344
    $template->param( message => 1 );
Lines 353-366 unless ( $noreserves ) { Link Here
353
    }
353
    }
354
}
354
}
355
355
356
foreach my $res (@reserves) {
356
foreach my $biblionumber (@biblionumbers) {
357
    foreach my $biblionumber (@biblionumbers) {
357
    if ( CanBookBeReserved( $borrowernumber, $biblionumber ) eq 'maxHoldsForRecord' ) {
358
        if ( $res->{'biblionumber'} == $biblionumber && $res->{'borrowernumber'} == $borrowernumber) {
358
        $biblioDataHash{$biblionumber}->{already_reserved} = 1;
359
#            $template->param( message => 1 );
360
#            $noreserves = 1;
361
#            $template->param( already_reserved => 1 );
362
            $biblioDataHash{$biblionumber}->{already_reserved} = 1;
363
        }
364
    }
359
    }
365
}
360
}
366
361
(-)a/reserve/request.pl (-2 / +4 lines)
Lines 226-231 foreach my $biblionumber (@biblionumbers) { Link Here
226
    elsif ( $canReserve eq 'tooManyReserves' ) {
226
    elsif ( $canReserve eq 'tooManyReserves' ) {
227
        $exceeded_maxreserves = 1;
227
        $exceeded_maxreserves = 1;
228
    }
228
    }
229
    elsif ( $canReserve eq 'maxHoldsForRecord' ) {
230
        $template->param( alreadyreserved => 1 );
231
        $biblioloopiter{warn} = 1;
232
    }
229
    elsif ( $canReserve eq 'ageRestricted' ) {
233
    elsif ( $canReserve eq 'ageRestricted' ) {
230
        $template->param( $canReserve => 1 );
234
        $template->param( $canReserve => 1 );
231
        $biblioloopiter{$canReserve} = 1;
235
        $biblioloopiter{$canReserve} = 1;
Lines 257-269 foreach my $biblionumber (@biblionumbers) { Link Here
257
    }
261
    }
258
262
259
    if ( $holds_count ) {
263
    if ( $holds_count ) {
260
            $alreadyreserved = 1;
261
            $biblioloopiter{warn} = 1;
264
            $biblioloopiter{warn} = 1;
262
            $biblioloopiter{alreadyres} = 1;
265
            $biblioloopiter{alreadyres} = 1;
263
    }
266
    }
264
267
265
    $template->param(
268
    $template->param(
266
        alreadyreserved => $alreadyreserved,
267
        alreadypossession => $alreadypossession,
269
        alreadypossession => $alreadypossession,
268
    );
270
    );
269
271
(-)a/t/db_dependent/Holds.t (-8 / +39 lines)
Lines 8-14 use t::lib::TestBuilder; Link Here
8
use C4::Context;
8
use C4::Context;
9
use C4::Branch;
9
use C4::Branch;
10
10
11
use Test::More tests => 56;
11
use Test::More tests => 59;
12
use MARC::Record;
12
use MARC::Record;
13
use C4::Biblio;
13
use C4::Biblio;
14
use C4::Items;
14
use C4::Items;
Lines 217-232 my ($foreign_item_bibnum, $foreign_item_bibitemnum, $foreign_itemnumber) Link Here
217
  = AddItem({ homebranch => $branch_2, holdingbranch => $branch_2 } , $foreign_bibnum);
217
  = AddItem({ homebranch => $branch_2, holdingbranch => $branch_2 } , $foreign_bibnum);
218
$dbh->do('DELETE FROM issuingrules');
218
$dbh->do('DELETE FROM issuingrules');
219
$dbh->do(
219
$dbh->do(
220
    q{INSERT INTO issuingrules (categorycode, branchcode, itemtype, reservesallowed)
220
    q{INSERT INTO issuingrules (categorycode, branchcode, itemtype, reservesallowed, holds_per_record)
221
      VALUES (?, ?, ?, ?)},
221
      VALUES (?, ?, ?, ?, ?)},
222
    {},
222
    {},
223
    '*', '*', '*', 25
223
    '*', '*', '*', 25, 5
224
);
224
);
225
$dbh->do(
225
$dbh->do(
226
    q{INSERT INTO issuingrules (categorycode, branchcode, itemtype, reservesallowed)
226
    q{INSERT INTO issuingrules (categorycode, branchcode, itemtype, reservesallowed, holds_per_record)
227
      VALUES (?, ?, ?, ?)},
227
      VALUES (?, ?, ?, ?, ?)},
228
    {},
228
    {},
229
    '*', '*', 'CANNOT', 0
229
    '*', '*', 'CANNOT', 0, 5
230
);
230
);
231
231
232
# make sure some basic sysprefs are set
232
# make sure some basic sysprefs are set
Lines 317-323 is( $reserve3->{priority}, 1, "After ModReserve, the 3rd reserve becomes the fir Link Here
317
317
318
ModItem({ damaged => 1 }, $item_bibnum, $itemnumber);
318
ModItem({ damaged => 1 }, $item_bibnum, $itemnumber);
319
C4::Context->set_preference( 'AllowHoldsOnDamagedItems', 1 );
319
C4::Context->set_preference( 'AllowHoldsOnDamagedItems', 1 );
320
ok( CanItemBeReserved( $borrowernumbers[0], $itemnumber) eq 'OK', "Patron can reserve damaged item with AllowHoldsOnDamagedItems enabled" );
320
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber), 'OK', "Patron can reserve damaged item with AllowHoldsOnDamagedItems enabled" );
321
ok( defined( ( CheckReserves($itemnumber) )[1] ), "Hold can be trapped for damaged item with AllowHoldsOnDamagedItems enabled" );
321
ok( defined( ( CheckReserves($itemnumber) )[1] ), "Hold can be trapped for damaged item with AllowHoldsOnDamagedItems enabled" );
322
C4::Context->set_preference( 'AllowHoldsOnDamagedItems', 0 );
322
C4::Context->set_preference( 'AllowHoldsOnDamagedItems', 0 );
323
ok( CanItemBeReserved( $borrowernumbers[0], $itemnumber) eq 'damaged', "Patron cannot reserve damaged item with AllowHoldsOnDamagedItems disabled" );
323
ok( CanItemBeReserved( $borrowernumbers[0], $itemnumber) eq 'damaged', "Patron cannot reserve damaged item with AllowHoldsOnDamagedItems disabled" );
Lines 453-458 my $res_id = AddReserve( $branch_1, $borrowernumbers[0], $bibnum, '', 1, ); Link Here
453
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber ),
453
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber ),
454
    'tooManyReserves', 'Patron cannot reserve item with hold limit of 1, 1 bib level hold placed' );
454
    'tooManyReserves', 'Patron cannot reserve item with hold limit of 1, 1 bib level hold placed' );
455
455
456
# Test multipel holds per bib
457
$dbh->do('DELETE FROM issuingrules');
458
459
( $bibnum, $title, $bibitemnum ) = create_helper_biblio('DUMMY');
460
my ( $biblionumber_1, $biblioitemnumber_1, $itemnumber1 ) =
461
  AddItem( { homebranch => $branch_1, holdingbranch => $branch_1 }, $bibnum );
462
my ( $biblionumber_2, $biblioitemnumber_2, $itemnumber2 ) =
463
  AddItem( { homebranch => $branch_1, holdingbranch => $branch_1 }, $bibnum );
464
my ( $biblionumber_3, $biblioitemnumber_3, $itemnumber3 ) =
465
  AddItem( { homebranch => $branch_1, holdingbranch => $branch_1 }, $bibnum );
466
467
$dbh->do(
468
    q{INSERT INTO issuingrules (categorycode, branchcode, itemtype, reservesallowed, holds_per_record)
469
      VALUES (?, ?, ?, ?, ?)},
470
    {},
471
    '*', '*', '*', 99, 3
472
);
473
474
AddReserve( $branch_1, $borrowernumbers[0], $bibnum, undef, undef, undef, undef, undef, undef, $itemnumber1 );
475
476
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber1 ),
477
    'itemAlreadyOnHold', 'Patron cannot request item the patron has already requested' );
478
479
AddReserve( $branch_1, $borrowernumbers[0], $bibnum, undef, undef, undef, undef, undef, undef, $itemnumber2 );
480
481
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber3 ), 'OK', 'Patron can still request third item' );
482
483
AddReserve( $branch_1, $borrowernumbers[0], $bibnum, undef, undef, undef, undef, undef, undef, undef );
484
485
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber3 ),
486
    'maxHoldsForRecord', 'Patron cannot place any more requests for this record' );
456
487
457
# Helper method to set up a Biblio.
488
# Helper method to set up a Biblio.
458
sub create_helper_biblio {
489
sub create_helper_biblio {
(-)a/t/db_dependent/Reserves.t (-2 / +1 lines)
Lines 449-455 warning_is { Link Here
449
    $reserve_id = AddReserve('CPL',  $requesters{'CPL3'}, $bibnum,
449
    $reserve_id = AddReserve('CPL',  $requesters{'CPL3'}, $bibnum,
450
           $bibitems,  $p, output_pref($resdate), $expdate, $notes,
450
           $bibitems,  $p, output_pref($resdate), $expdate, $notes,
451
           $title,      $checkitem, $found)
451
           $title,      $checkitem, $found)
452
} "AddReserve: borrower $requesters{CPL3} already has a hold for biblionumber $bibnum";
452
} "AddReserve: borrower $requesters{CPL3} has already reached the max holds for biblionumber $bibnum";
453
is( $reserve_id, undef, 'Attempt to add a second reserve on a given record for the same patron fails.' );
453
is( $reserve_id, undef, 'Attempt to add a second reserve on a given record for the same patron fails.' );
454
454
455
# Tests for cancel reserves by users from OPAC.
455
# Tests for cancel reserves by users from OPAC.
456
- 

Return to bug 14695