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

(-)a/C4/Reserves.pm (-45 / +75 lines)
Lines 147-169 BEGIN { Link Here
147
147
148
=head2 AddReserve
148
=head2 AddReserve
149
149
150
    AddReserve($branch,$borrowernumber,$biblionumber,$bibitems,$priority,$resdate,$expdate,$notes,$title,$checkitem,$found)
150
    AddReserve(
151
        $branch,  $borrowernumber, $biblionumber, $bibitems,   $priority, $resdate,
152
        $expdate, $notes,          $title,        $itemnumber, $found
153
      )
151
154
152
=cut
155
=cut
153
156
154
sub AddReserve {
157
sub AddReserve {
155
    my (
158
    my (
156
        $branch,    $borrowernumber, $biblionumber,
159
        $branch,  $borrowernumber, $biblionumber, $bibitems,   $priority, $resdate,
157
        $bibitems,  $priority, $resdate, $expdate, $notes,
160
        $expdate, $notes,          $title,        $itemnumber, $found
158
        $title,      $checkitem, $found
159
    ) = @_;
161
    ) = @_;
160
162
161
    if ( Koha::Holds->search( { borrowernumber => $borrowernumber, biblionumber => $biblionumber } )->count() > 0 ) {
163
    # Ensure the holds should be allowed
162
        carp("AddReserve: borrower $borrowernumber already has a hold for biblionumber $biblionumber");
164
    my $can_reserve =
165
      $itemnumber
166
      ? CanItemBeReserved( $borrowernumber, $itemnumber )
167
      : CanBookBeReserved( $borrowernumber, $biblionumber );
168
    if ( $can_reserve eq 'maxHoldsForRecord' ) {
169
        carp("AddReserve: borrower $borrowernumber has already reached the max holds for biblionumber $biblionumber");
163
        return;
170
        return;
164
    }
171
    }
165
172
166
    my $dbh     = C4::Context->dbh;
173
    my $dbh = C4::Context->dbh;
167
174
168
    $resdate = output_pref( { str => dt_from_string( $resdate ), dateonly => 1, dateformat => 'iso' })
175
    $resdate = output_pref( { str => dt_from_string( $resdate ), dateonly => 1, dateformat => 'iso' })
169
        or output_pref({ dt => dt_from_string, dateonly => 1, dateformat => 'iso' });
176
        or output_pref({ dt => dt_from_string, dateonly => 1, dateformat => 'iso' });
Lines 192-198 sub AddReserve { Link Here
192
            branchcode     => $branch,
199
            branchcode     => $branch,
193
            priority       => $priority,
200
            priority       => $priority,
194
            reservenotes   => $notes,
201
            reservenotes   => $notes,
195
            itemnumber     => $checkitem,
202
            itemnumber     => $itemnumber,
196
            found          => $found,
203
            found          => $found,
197
            waitingdate    => $waitingdate,
204
            waitingdate    => $waitingdate,
198
            expirationdate => $expdate
205
            expirationdate => $expdate
Lines 218-224 sub AddReserve { Link Here
218
                'branches'  => $branch_details,
225
                'branches'  => $branch_details,
219
                'borrowers' => $borrower,
226
                'borrowers' => $borrower,
220
                'biblio'    => $biblionumber,
227
                'biblio'    => $biblionumber,
221
                'items'     => $checkitem,
228
                'items'     => $itemnumber,
222
            },
229
            },
223
        ) ) {
230
        ) ) {
224
231
Lines 460-486 sub CanItemBeReserved { Link Here
460
467
461
    my $controlbranch = C4::Context->preference('ReservesControlBranch');
468
    my $controlbranch = C4::Context->preference('ReservesControlBranch');
462
469
463
    # we retrieve user rights on this itemtype and branchcode
470
    my $querycount = "SELECT COUNT(*) as count
464
    my $sth = $dbh->prepare(
471
                      FROM reserves
465
        "SELECT categorycode, itemtype, branchcode, reservesallowed
472
                      LEFT JOIN items USING (itemnumber)
466
                             FROM issuingrules
473
                      LEFT JOIN biblioitems ON (reserves.biblionumber=biblioitems.biblionumber)
467
                             WHERE (categorycode in (?,'*') )
474
                      LEFT JOIN borrowers USING (borrowernumber)
468
                             AND (itemtype IN (?,'*'))
475
                      WHERE borrowernumber = ?";
469
                             AND (branchcode IN (?,'*'))
470
                             ORDER BY
471
                               categorycode DESC,
472
                               itemtype     DESC,
473
                               branchcode   DESC;"
474
    );
475
476
    my $querycount = "SELECT
477
                            count(*) as count
478
                            FROM reserves
479
                                LEFT JOIN items USING (itemnumber)
480
                                LEFT JOIN biblioitems ON (reserves.biblionumber=biblioitems.biblionumber)
481
                                LEFT JOIN borrowers USING (borrowernumber)
482
                            WHERE borrowernumber = ?
483
                                ";
484
476
485
    my $branchcode  = "";
477
    my $branchcode  = "";
486
    my $branchfield = "reserves.branchcode";
478
    my $branchfield = "reserves.branchcode";
Lines 494-504 sub CanItemBeReserved { Link Here
494
        $branchcode  = $borrower->{branchcode};
486
        $branchcode  = $borrower->{branchcode};
495
    }
487
    }
496
488
489
    # we retrieve user rights on this itemtype and branchcode
490
    my $rule = _get_rule( $borrower->{categorycode}, $item->{itype}, $branchcode );
491
497
    # we retrieve rights
492
    # we retrieve rights
498
    $sth->execute( $borrower->{'categorycode'}, $item->{'itype'}, $branchcode );
493
    if ( $rule ) {
499
    if ( my $rights = $sth->fetchrow_hashref() ) {
494
        $ruleitemtype    = $rule->get_column('itemtype');
500
        $ruleitemtype    = $rights->{itemtype};
495
        $allowedreserves = $rule->get_column('reservesallowed');
501
        $allowedreserves = $rights->{reservesallowed};
502
    }
496
    }
503
    else {
497
    else {
504
        $ruleitemtype = '*';
498
        $ruleitemtype = '*';
Lines 559-564 sub CanItemBeReserved { Link Here
559
        }
553
        }
560
    }
554
    }
561
555
556
    my $holds_on_record = Koha::Holds->search(
557
        {
558
            borrowernumber => $borrowernumber,
559
            biblionumber   => $item->{biblionumber}
560
        }
561
    )->count();
562
    return 'maxHoldsForRecord' if ( $holds_on_record >= $rule->holds_per_record );
563
564
    if ($itemnumber) {
565
        my $hold_on_item = Koha::Holds->search(
566
            {
567
                borrowernumber => $borrowernumber,
568
                itemnumber     => $itemnumber
569
            }
570
        )->count();
571
        return 'itemAlreadyOnHold' if ($hold_on_item);
572
    }
573
562
    return 'OK';
574
    return 'OK';
563
}
575
}
564
576
Lines 1268-1274 sub ModReserveStatus { Link Here
1268
1280
1269
=head2 ModReserveAffect
1281
=head2 ModReserveAffect
1270
1282
1271
  &ModReserveAffect($itemnumber,$borrowernumber,$diffBranchSend);
1283
&ModReserveAffect( $itemnumber, $borrowernumber, $diffBranchSend, $reserve_id );
1272
1284
1273
This function affect an item and a status for a given reserve
1285
This function affect an item and a status for a given reserve
1274
The itemnumber parameter is used to find the biblionumber.
1286
The itemnumber parameter is used to find the biblionumber.
Lines 1282-1288 take care of the waiting status Link Here
1282
=cut
1294
=cut
1283
1295
1284
sub ModReserveAffect {
1296
sub ModReserveAffect {
1285
    my ( $itemnumber, $borrowernumber,$transferToDo ) = @_;
1297
    my ( $itemnumber, $borrowernumber, $transferToDo, $reserve_id ) = @_;
1286
    my $dbh = C4::Context->dbh;
1298
    my $dbh = C4::Context->dbh;
1287
1299
1288
    # we want to attach $itemnumber to $borrowernumber, find the biblionumber
1300
    # we want to attach $itemnumber to $borrowernumber, find the biblionumber
Lines 1293-1302 sub ModReserveAffect { Link Here
1293
1305
1294
    # get request - need to find out if item is already
1306
    # get request - need to find out if item is already
1295
    # waiting in order to not send duplicate hold filled notifications
1307
    # waiting in order to not send duplicate hold filled notifications
1296
    my $reserve_id = GetReserveId({
1308
    $reserve_id ||= GetReserveId(
1297
        borrowernumber => $borrowernumber,
1309
        {
1298
        biblionumber   => $biblionumber,
1310
            borrowernumber => $borrowernumber,
1299
    });
1311
            biblionumber   => $biblionumber,
1312
        }
1313
    );
1300
    return unless defined $reserve_id;
1314
    return unless defined $reserve_id;
1301
    my $request = GetReserveInfo($reserve_id);
1315
    my $request = GetReserveInfo($reserve_id);
1302
    my $already_on_shelf = ($request && $request->{found} eq 'W') ? 1 : 0;
1316
    my $already_on_shelf = ($request && $request->{found} eq 'W') ? 1 : 0;
Lines 1309-1316 sub ModReserveAffect { Link Here
1309
        SET    priority = 0,
1323
        SET    priority = 0,
1310
               itemnumber = ?,
1324
               itemnumber = ?,
1311
               found = 'T'
1325
               found = 'T'
1312
        WHERE borrowernumber = ?
1326
        WHERE reserve_id = ?
1313
          AND biblionumber = ?
1314
    ";
1327
    ";
1315
    }
1328
    }
1316
    else {
1329
    else {
Lines 1321-1332 sub ModReserveAffect { Link Here
1321
                    found = 'W',
1334
                    found = 'W',
1322
                    waitingdate = NOW(),
1335
                    waitingdate = NOW(),
1323
                    itemnumber = ?
1336
                    itemnumber = ?
1324
            WHERE borrowernumber = ?
1337
            WHERE reserve_id = ?
1325
              AND biblionumber = ?
1326
        ";
1338
        ";
1327
    }
1339
    }
1328
    $sth = $dbh->prepare($query);
1340
    $sth = $dbh->prepare($query);
1329
    $sth->execute( $itemnumber, $borrowernumber,$biblionumber);
1341
    $sth->execute( $itemnumber, $reserve_id );
1330
    _koha_notify_reserve( $itemnumber, $borrowernumber, $biblionumber ) if ( !$transferToDo && !$already_on_shelf );
1342
    _koha_notify_reserve( $itemnumber, $borrowernumber, $biblionumber ) if ( !$transferToDo && !$already_on_shelf );
1331
    _FixPriority( { biblionumber => $biblionumber } );
1343
    _FixPriority( { biblionumber => $biblionumber } );
1332
    if ( C4::Context->preference("ReturnToShelvingCart") ) {
1344
    if ( C4::Context->preference("ReturnToShelvingCart") ) {
Lines 2431-2436 sub IsItemOnHoldAndFound { Link Here
2431
    return $found;
2443
    return $found;
2432
}
2444
}
2433
2445
2446
sub _get_rule {
2447
    my ( $categorycode, $itemtype, $branchcode ) = @_;
2448
2449
    my $schema = Koha::Database->new()->schema();
2450
2451
    my $rule = $schema->resultset('Issuingrule')->search(
2452
        {
2453
            categorycode => { -in => $categorycode ? [ $categorycode, '*' ] : ['*'] },
2454
            itemtype     => { -in => $itemtype     ? [ $itemtype,     '*' ] : ['*'] },
2455
            branchcode   => { -in => $branchcode   ? [ $branchcode,   '*' ] : ['*'] },
2456
2457
        },
2458
        { order_by => { -desc => [ 'categorycode', 'itemtype', 'branchcode' ] } }
2459
    )->next();
2460
2461
    return $rule;
2462
}
2463
2434
=head1 AUTHOR
2464
=head1 AUTHOR
2435
2465
2436
Koha Development Team <http://koha-community.org/>
2466
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 418-430 if ( $messages->{'ResFound'}) { Link Here
418
419
419
    if ( $reserve->{'ResFound'} eq "Waiting" or $reserve->{'ResFound'} eq "Reserved" ) {
420
    if ( $reserve->{'ResFound'} eq "Waiting" or $reserve->{'ResFound'} eq "Reserved" ) {
420
        if ( $reserve->{'ResFound'} eq "Waiting" ) {
421
        if ( $reserve->{'ResFound'} eq "Waiting" ) {
422
            $template->param( waiting => $userenv_branch eq $reserve->{'branchcode'}, );
423
        }
424
        elsif ( $reserve->{'ResFound'} eq "Reserved" ) {
421
            $template->param(
425
            $template->param(
422
                waiting      => ($userenv_branch eq $reserve->{'branchcode'} ? 1 : 0 ),
426
                intransit    => $userenv_branch eq $reserve->{'branchcode'},
423
            );
427
                transfertodo => $userenv_branch eq $reserve->{'branchcode'},
424
        } elsif ( $reserve->{'ResFound'} eq "Reserved" ) {
425
            $template->param(
426
                intransit    => ($userenv_branch eq $reserve->{'branchcode'} ? 0 : 1 ),
427
                transfertodo => ($userenv_branch eq $reserve->{'branchcode'} ? 0 : 1 ),
428
                resbarcode   => $barcode,
428
                resbarcode   => $barcode,
429
                reserved     => 1,
429
                reserved     => 1,
430
            );
430
            );
Lines 432-440 if ( $messages->{'ResFound'}) { Link Here
432
432
433
        # same params for Waiting or Reserved
433
        # same params for Waiting or Reserved
434
        $template->param(
434
        $template->param(
435
            reserve        => $reserve,
436
            patron         => $borr,
435
            found          => 1,
437
            found          => 1,
436
            currentbranch  => $branches->{$userenv_branch}->{'branchname'},
438
            barcode        => $barcode,
437
            destbranchname => $branches->{ $reserve->{'branchcode'} }->{'branchname'},
438
            name           => $borr->{'surname'} . ", " . $borr->{'title'} . " " . $borr->{'firstname'},
439
            name           => $borr->{'surname'} . ", " . $borr->{'title'} . " " . $borr->{'firstname'},
439
            borfirstname   => $borr->{'firstname'},
440
            borfirstname   => $borr->{'firstname'},
440
            borsurname     => $borr->{'surname'},
441
            borsurname     => $borr->{'surname'},
Lines 449-459 if ( $messages->{'ResFound'}) { Link Here
449
            borcnum        => $borr->{'cardnumber'},
450
            borcnum        => $borr->{'cardnumber'},
450
            debarred       => $borr->{'debarred'},
451
            debarred       => $borr->{'debarred'},
451
            gonenoaddress  => $borr->{'gonenoaddress'},
452
            gonenoaddress  => $borr->{'gonenoaddress'},
452
            barcode        => $barcode,
453
            destbranch     => $reserve->{'branchcode'},
454
            borrowernumber => $reserve->{'borrowernumber'},
453
            borrowernumber => $reserve->{'borrowernumber'},
455
            itemnumber     => $reserve->{'itemnumber'},
454
            itemnumber     => $reserve->{'itemnumber'},
456
            reservenotes   => $reserve->{'reservenotes'},
457
        );
455
        );
458
    } # else { ; }  # error?
456
    } # else { ; }  # error?
459
}
457
}
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt (-16 / +17 lines)
Lines 194-200 $(document).ready(function () { Link Here
194
    [% END %]</div>
194
    [% END %]</div>
195
[% END %]
195
[% END %]
196
196
197
[% IF ( found ) %]
197
[% IF ( reserve ) %]
198
<!-- found -->
198
<!-- found -->
199
<!-- case of a reservation found, and display info -->
199
<!-- case of a reservation found, and display info -->
200
    [% IF ( waiting ) %]
200
    [% IF ( waiting ) %]
Lines 202-208 $(document).ready(function () { Link Here
202
202
203
    <div id="hold-found1" class="dialog message audio-alert-action">
203
    <div id="hold-found1" class="dialog message audio-alert-action">
204
        <h3>Hold found (item is already waiting):  <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% itembiblionumber %]">[% title |html %]</a></h3>
204
        <h3>Hold found (item is already waiting):  <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% itembiblionumber %]">[% title |html %]</a></h3>
205
        [% IF ( reservenotes ) %]<h4>Notes: [% reservenotes %]</h4>[% END %]
205
        [% IF ( reserve.reservenotes ) %]<h4>Notes: [% reserve.reservenotes %]</h4>[% END %]
206
        <h4>Hold for:</h4>
206
        <h4>Hold for:</h4>
207
			<ul>
207
			<ul>
208
            <li><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">[% borsurname %], [% borfirstname %]</a> ([% borcnum %])</li>
208
            <li><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">[% borsurname %], [% borfirstname %]</a> ([% borcnum %])</li>
Lines 214-222 $(document).ready(function () { Link Here
214
[% IF ( debarred ) %]<li class="error">Patron is RESTRICTED</li>[% END %]
214
[% IF ( debarred ) %]<li class="error">Patron is RESTRICTED</li>[% END %]
215
[% IF ( gonenoaddress ) %]<li class="error">Patron's address is in doubt</li>[% END %]</ul>
215
[% IF ( gonenoaddress ) %]<li class="error">Patron's address is in doubt</li>[% END %]</ul>
216
		[% IF ( transfertodo ) %]
216
		[% IF ( transfertodo ) %]
217
            <h4><strong>Transfer to:</strong> [% destbranchname %]</h4>
217
            <h4><strong>Transfer to:</strong> [% Branches.GetName( reserve.branchcode ) %]</h4>
218
		[% ELSE %]
218
		[% ELSE %]
219
		<h4><strong>Hold at</strong> [% destbranchname %]</h4>
219
		<h4><strong>Hold at</strong> [% Branches.GetName( reserve.branchcode ) %]</h4>
220
        [% END %]
220
        [% END %]
221
        <form method="post" action="returns.pl" class="confirm">
221
        <form method="post" action="returns.pl" class="confirm">
222
            <input type="hidden" name="cancel_reserve" value="0" />
222
            <input type="hidden" name="cancel_reserve" value="0" />
Lines 235-241 $(document).ready(function () { Link Here
235
                <input type="hidden" name="borrowernumber" value="[% borrowernumber %]" />
235
                <input type="hidden" name="borrowernumber" value="[% borrowernumber %]" />
236
                <input type="hidden" name="biblionumber" value="[% itembiblionumber %]" />
236
                <input type="hidden" name="biblionumber" value="[% itembiblionumber %]" />
237
                <input type="hidden" name="resbarcode" value="[% barcode %]" />
237
                <input type="hidden" name="resbarcode" value="[% barcode %]" />
238
                <input type="hidden" name="diffBranch" value="[% destbranch %]" />
238
                <input type="hidden" name="diffBranch" value="[% reserves.branchcode %]" />
239
                <input type="hidden" name="exemptfine" value="[% exemptfine %]" />
239
                <input type="hidden" name="exemptfine" value="[% exemptfine %]" />
240
                <input type="hidden" name="dropboxmode" value="[% dropboxmode %]" />
240
                <input type="hidden" name="dropboxmode" value="[% dropboxmode %]" />
241
                <input type="hidden" name="forgivemanualholdsexpire" value="[% forgivemanualholdsexpire %]" />
241
                <input type="hidden" name="forgivemanualholdsexpire" value="[% forgivemanualholdsexpire %]" />
Lines 262-270 $(document).ready(function () { Link Here
262
[% IF ( gonenoaddress ) %]<li class="error">Patron's address is in doubt</li>[% END %]
262
[% IF ( gonenoaddress ) %]<li class="error">Patron's address is in doubt</li>[% END %]
263
                    </ul>
263
                    </ul>
264
		[% IF ( transfertodo ) %]
264
		[% IF ( transfertodo ) %]
265
            <h4><strong>Transfer to:</strong> [% destbranchname %]</h4>
265
            <h4><strong>Transfer to:</strong> [% Branches.GetName( reserve.branchcode ) %]</h4>
266
		[% ELSE %]
266
		[% ELSE %]
267
		<h4><strong>Hold at</strong> [% destbranchname %]</h4>
267
		<h4><strong>Hold at</strong> [% Branches.GetName( reserve.branchcode ) %]</h4>
268
        [% END %]
268
        [% END %]
269
269
270
        <form method="post" action="returns.pl" class="confirm">
270
        <form method="post" action="returns.pl" class="confirm">
Lines 278-284 $(document).ready(function () { Link Here
278
                <input type="hidden" name="dd-[% inputloo.counter %]" value="[% inputloo.duedate %]" />
278
                <input type="hidden" name="dd-[% inputloo.counter %]" value="[% inputloo.duedate %]" />
279
                <input type="hidden" name="bn-[% inputloo.counter %]" value="[% inputloo.borrowernumber %]" />
279
                <input type="hidden" name="bn-[% inputloo.counter %]" value="[% inputloo.borrowernumber %]" />
280
            [% END %]
280
            [% END %]
281
            <input type="hidden" name="diffBranch" value="[% destbranch %]" />
281
            <input type="hidden" name="diffBranch" value="[% reserves.branchcode %]" />
282
            <input type="hidden" name="exemptfine" value="[% exemptfine %]" />
282
            <input type="hidden" name="exemptfine" value="[% exemptfine %]" />
283
            <input type="hidden" name="dropboxmode" value="[% dropboxmode %]" />
283
            <input type="hidden" name="dropboxmode" value="[% dropboxmode %]" />
284
            <input type="hidden" name="forgivemanualholdsexpire" value="[% forgivemanualholdsexpire %]" />
284
            <input type="hidden" name="forgivemanualholdsexpire" value="[% forgivemanualholdsexpire %]" />
Lines 356-362 $(document).ready(function () { Link Here
356
356
357
    <div id="hold-found2" class="dialog message audio-alert-action">
357
    <div id="hold-found2" class="dialog message audio-alert-action">
358
      <h3>Hold found: <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% itembiblionumber %]">[% title |html %]</a></h3>
358
      <h3>Hold found: <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% itembiblionumber %]">[% title |html %]</a></h3>
359
        [% IF ( reservenotes ) %]<h4>Notes: [% reservenotes %]</h4>[% END %]
359
        [% IF ( reserve.reservenotes ) %]<h4>Notes: [% reserve.reservenotes %]</h4>[% END %]
360
        <h5>Hold for:</h5>
360
        <h5>Hold for:</h5>
361
		<ul>
361
		<ul>
362
            <li><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">
362
            <li><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">
Lines 371-379 $(document).ready(function () { Link Here
371
[% IF ( gonenoaddress ) %]<li class="error">Patron's address is in doubt</li>[% END %]
371
[% IF ( gonenoaddress ) %]<li class="error">Patron's address is in doubt</li>[% END %]
372
        </ul>
372
        </ul>
373
        [% IF ( transfertodo ) %]
373
        [% IF ( transfertodo ) %]
374
            <h4><strong>Transfer to:</strong> [% destbranchname %]</h4>
374
            <h4><strong>Transfer to:</strong> [% Branches.GetName( reserve.branchcode ) %]</h4>
375
		[% ELSE %]
375
		[% ELSE %]
376
		<h4><strong>Hold at</strong> [% destbranchname %]</h4>
376
		<h4><strong>Hold at</strong> [% Branches.GetName( reserve.branchcode ) %]</h4>
377
        [% END %]
377
        [% END %]
378
        <form method="post" action="returns.pl" class="confirm">
378
        <form method="post" action="returns.pl" class="confirm">
379
            <input type="hidden" name="print_slip" value="0" />
379
            <input type="hidden" name="print_slip" value="0" />
Lines 386-399 $(document).ready(function () { Link Here
386
            [% END %]
386
            [% END %]
387
                <input type="submit" class="deny" value="Ignore" onclick="$('.dialog:visible').hide('slow'); $('#barcode').focus(); return false;" />
387
                <input type="submit" class="deny" value="Ignore" onclick="$('.dialog:visible').hide('slow'); $('#barcode').focus(); return false;" />
388
            [% FOREACH inputloo IN inputloop %]
388
            [% FOREACH inputloo IN inputloop %]
389
	<input type="hidden" name="ri-[% inputloo.counter %]" value="[% inputloo.barcode %]" />
389
                <input type="hidden" name="ri-[% inputloo.counter %]" value="[% inputloo.barcode %]" />
390
	<input type="hidden" name="dd-[% inputloo.counter %]" value="[% inputloo.duedate %]" />
390
                <input type="hidden" name="dd-[% inputloo.counter %]" value="[% inputloo.duedate %]" />
391
	<input type="hidden" name="bn-[% inputloo.counter %]" value="[% inputloo.borrowernumber %]" />[% END %]
391
                <input type="hidden" name="bn-[% inputloo.counter %]" value="[% inputloo.borrowernumber %]" />
392
            [% END %]
392
            <input type="hidden" name="itemnumber" value="[% itemnumber %]" />
393
            <input type="hidden" name="itemnumber" value="[% itemnumber %]" />
393
            <input type="hidden" name="borrowernumber" value="[% borrowernumber %]" />
394
            <input type="hidden" name="borrowernumber" value="[% borrowernumber %]" />
394
            <input type="hidden" name="biblionumber" value="[% itembiblionumber %]" />
395
            <input type="hidden" name="biblionumber" value="[% itembiblionumber %]" />
395
            <input type="hidden" name="resbarcode" value="[% barcode %]" />
396
            <input type="hidden" name="reserve_id" value="[% reserve.reserve_id %]" />
396
            <input type="hidden" name="diffBranch" value="[% destbranch %]" />
397
            <input type="hidden" name="diffBranch" value="[% reserves.branchcode %]" />
397
            <input type="hidden" name="exemptfine" value="[% exemptfine %]" />
398
            <input type="hidden" name="exemptfine" value="[% exemptfine %]" />
398
            <input type="hidden" name="dropboxmode" value="[% dropboxmode %]" />
399
            <input type="hidden" name="dropboxmode" value="[% dropboxmode %]" />
399
            <input type="hidden" name="forgivemanualholdsexpire" value="[% forgivemanualholdsexpire %]" />
400
            <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 337-343 if ( IsDebarred($borrowernumber) ) { Link Here
337
}
337
}
338
338
339
my @reserves = GetReservesFromBorrowernumber( $borrowernumber );
339
my @reserves = GetReservesFromBorrowernumber( $borrowernumber );
340
my $reserves_count = scalar(@reserves);
340
my $reserves_count = scalar @reserves;
341
$template->param( RESERVES => \@reserves );
341
$template->param( RESERVES => \@reserves );
342
if ( $maxreserves && ( $reserves_count >= $maxreserves ) ) {
342
if ( $maxreserves && ( $reserves_count >= $maxreserves ) ) {
343
    $template->param( message => 1 );
343
    $template->param( message => 1 );
Lines 352-365 unless ( $noreserves ) { Link Here
352
    }
352
    }
353
}
353
}
354
354
355
foreach my $res (@reserves) {
355
foreach my $biblionumber (@biblionumbers) {
356
    foreach my $biblionumber (@biblionumbers) {
356
    if ( CanBookBeReserved( $borrowernumber, $biblionumber ) eq 'maxHoldsForRecord' ) {
357
        if ( $res->{'biblionumber'} == $biblionumber && $res->{'borrowernumber'} == $borrowernumber) {
357
        $biblioDataHash{$biblionumber}->{already_reserved} = 1;
358
#            $template->param( message => 1 );
359
#            $noreserves = 1;
360
#            $template->param( already_reserved => 1 );
361
            $biblioDataHash{$biblionumber}->{already_reserved} = 1;
362
        }
363
    }
358
    }
364
}
359
}
365
360
(-)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 216-231 my ($foreign_item_bibnum, $foreign_item_bibitemnum, $foreign_itemnumber) Link Here
216
  = AddItem({ homebranch => $branch_2, holdingbranch => $branch_2 } , $foreign_bibnum);
216
  = AddItem({ homebranch => $branch_2, holdingbranch => $branch_2 } , $foreign_bibnum);
217
$dbh->do('DELETE FROM issuingrules');
217
$dbh->do('DELETE FROM issuingrules');
218
$dbh->do(
218
$dbh->do(
219
    q{INSERT INTO issuingrules (categorycode, branchcode, itemtype, reservesallowed)
219
    q{INSERT INTO issuingrules (categorycode, branchcode, itemtype, reservesallowed, holds_per_record)
220
      VALUES (?, ?, ?, ?)},
220
      VALUES (?, ?, ?, ?, ?)},
221
    {},
221
    {},
222
    '*', '*', '*', 25
222
    '*', '*', '*', 25, 5
223
);
223
);
224
$dbh->do(
224
$dbh->do(
225
    q{INSERT INTO issuingrules (categorycode, branchcode, itemtype, reservesallowed)
225
    q{INSERT INTO issuingrules (categorycode, branchcode, itemtype, reservesallowed, holds_per_record)
226
      VALUES (?, ?, ?, ?)},
226
      VALUES (?, ?, ?, ?, ?)},
227
    {},
227
    {},
228
    '*', '*', 'CANNOT', 0
228
    '*', '*', 'CANNOT', 0, 5
229
);
229
);
230
230
231
# make sure some basic sysprefs are set
231
# make sure some basic sysprefs are set
Lines 316-322 is( $reserve3->{priority}, 1, "After ModReserve, the 3rd reserve becomes the fir Link Here
316
316
317
ModItem({ damaged => 1 }, $item_bibnum, $itemnumber);
317
ModItem({ damaged => 1 }, $item_bibnum, $itemnumber);
318
C4::Context->set_preference( 'AllowHoldsOnDamagedItems', 1 );
318
C4::Context->set_preference( 'AllowHoldsOnDamagedItems', 1 );
319
ok( CanItemBeReserved( $borrowernumbers[0], $itemnumber) eq 'OK', "Patron can reserve damaged item with AllowHoldsOnDamagedItems enabled" );
319
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber), 'OK', "Patron can reserve damaged item with AllowHoldsOnDamagedItems enabled" );
320
ok( defined( ( CheckReserves($itemnumber) )[1] ), "Hold can be trapped for damaged item with AllowHoldsOnDamagedItems enabled" );
320
ok( defined( ( CheckReserves($itemnumber) )[1] ), "Hold can be trapped for damaged item with AllowHoldsOnDamagedItems enabled" );
321
C4::Context->set_preference( 'AllowHoldsOnDamagedItems', 0 );
321
C4::Context->set_preference( 'AllowHoldsOnDamagedItems', 0 );
322
ok( CanItemBeReserved( $borrowernumbers[0], $itemnumber) eq 'damaged', "Patron cannot reserve damaged item with AllowHoldsOnDamagedItems disabled" );
322
ok( CanItemBeReserved( $borrowernumbers[0], $itemnumber) eq 'damaged', "Patron cannot reserve damaged item with AllowHoldsOnDamagedItems disabled" );
Lines 452-457 my $res_id = AddReserve( $branch_1, $borrowernumbers[0], $bibnum, '', 1, ); Link Here
452
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber ),
452
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber ),
453
    'tooManyReserves', 'Patron cannot reserve item with hold limit of 1, 1 bib level hold placed' );
453
    'tooManyReserves', 'Patron cannot reserve item with hold limit of 1, 1 bib level hold placed' );
454
454
455
# Test multipel holds per bib
456
$dbh->do('DELETE FROM issuingrules');
457
458
( $bibnum, $title, $bibitemnum ) = create_helper_biblio('DUMMY');
459
my ( $biblionumber_1, $biblioitemnumber_1, $itemnumber1 ) =
460
  AddItem( { homebranch => $branch_1, holdingbranch => $branch_1 }, $bibnum );
461
my ( $biblionumber_2, $biblioitemnumber_2, $itemnumber2 ) =
462
  AddItem( { homebranch => $branch_1, holdingbranch => $branch_1 }, $bibnum );
463
my ( $biblionumber_3, $biblioitemnumber_3, $itemnumber3 ) =
464
  AddItem( { homebranch => $branch_1, holdingbranch => $branch_1 }, $bibnum );
465
466
$dbh->do(
467
    q{INSERT INTO issuingrules (categorycode, branchcode, itemtype, reservesallowed, holds_per_record)
468
      VALUES (?, ?, ?, ?, ?)},
469
    {},
470
    '*', '*', '*', 99, 3
471
);
472
473
AddReserve( $branch_1, $borrowernumbers[0], $bibnum, undef, undef, undef, undef, undef, undef, $itemnumber1 );
474
475
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber1 ),
476
    'itemAlreadyOnHold', 'Patron cannot request item the patron has already requested' );
477
478
AddReserve( $branch_1, $borrowernumbers[0], $bibnum, undef, undef, undef, undef, undef, undef, $itemnumber2 );
479
480
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber3 ), 'OK', 'Patron can still request third item' );
481
482
AddReserve( $branch_1, $borrowernumbers[0], $bibnum, undef, undef, undef, undef, undef, undef, undef );
483
484
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber3 ),
485
    'maxHoldsForRecord', 'Patron cannot place any more requests for this record' );
455
486
456
# Helper method to set up a Biblio.
487
# Helper method to set up a Biblio.
457
sub create_helper_biblio {
488
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