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

(-)a/C4/Circulation.pm (-2 / +2 lines)
Lines 381-387 sub transferbook { Link Here
381
    }
381
    }
382
382
383
    # find recall
383
    # find recall
384
    my $recall = Koha::Recalls->find({ itemnumber => $itemnumber, status => 'T' });
384
    my $recall = Koha::Recalls->find({ itemnumber => $itemnumber, status => 'in_transit' });
385
    if ( defined $recall and C4::Context->preference('UseRecalls') ) {
385
    if ( defined $recall and C4::Context->preference('UseRecalls') ) {
386
        # do a transfer if the recall branch is different to the item holding branch
386
        # do a transfer if the recall branch is different to the item holding branch
387
        if ( $recall->branchcode eq $fbr ) {
387
        if ( $recall->branchcode eq $fbr ) {
Lines 2354-2360 sub AddReturn { Link Here
2354
        $request->status('RET') if $request;
2354
        $request->status('RET') if $request;
2355
    }
2355
    }
2356
2356
2357
    my $transfer_recall = Koha::Recalls->find({ itemnumber => $item->itemnumber, status => 'T' }); # all recalls that have triggered a transfer will have an allocated itemnumber
2357
    my $transfer_recall = Koha::Recalls->find({ itemnumber => $item->itemnumber, status => 'in_transit' }); # all recalls that have triggered a transfer will have an allocated itemnumber
2358
    if ( $transfer_recall and
2358
    if ( $transfer_recall and
2359
         $transfer_recall->branchcode eq $branch and
2359
         $transfer_recall->branchcode eq $branch and
2360
         C4::Context->preference('UseRecalls') ) {
2360
         C4::Context->preference('UseRecalls') ) {
(-)a/C4/Overdues.pm (-1 / +1 lines)
Lines 260-266 sub CalcFine { Link Here
260
260
261
        # check if item has been recalled. recall should have been marked Overdue by cronjob, so only look at overdue recalls
261
        # check if item has been recalled. recall should have been marked Overdue by cronjob, so only look at overdue recalls
262
        # only charge using recall_overdue_fine if there is an item-level recall for this particular item, OR a biblio-level recall
262
        # only charge using recall_overdue_fine if there is an item-level recall for this particular item, OR a biblio-level recall
263
        my @recalls = Koha::Recalls->search({ biblionumber => $item->{biblionumber}, old => undef, status => 'O' })->as_list;
263
        my @recalls = Koha::Recalls->search({ biblionumber => $item->{biblionumber}, old => undef, status => 'overdue' })->as_list;
264
        my $bib_level_recall = 0;
264
        my $bib_level_recall = 0;
265
        $bib_level_recall = 1 if scalar @recalls > 0;
265
        $bib_level_recall = 1 if scalar @recalls > 0;
266
        foreach my $recall ( @recalls ) {
266
        foreach my $recall ( @recalls ) {
(-)a/C4/XSLT.pm (-1 / +1 lines)
Lines 354-360 sub buildKohaItemsNamespace { Link Here
354
        my $status;
354
        my $status;
355
        my $substatus = '';
355
        my $substatus = '';
356
356
357
        my $recalls = Koha::Recalls->search({ itemnumber => $item->itemnumber, status => 'W' });
357
        my $recalls = Koha::Recalls->search({ itemnumber => $item->itemnumber, status => 'waiting' });
358
358
359
        if ( $recalls->count ) {
359
        if ( $recalls->count ) {
360
            # recalls take priority over holds
360
            # recalls take priority over holds
(-)a/Koha/Item.pm (-1 / +3 lines)
Lines 1608-1614 Get the most relevant recall for this item. Link Here
1608
sub check_recalls {
1608
sub check_recalls {
1609
    my ( $self ) = @_;
1609
    my ( $self ) = @_;
1610
1610
1611
    my @recalls = Koha::Recalls->search({ biblionumber => $self->biblionumber, itemnumber => [ $self->itemnumber, undef ], status => [ 'R','O','W','T' ] }, { order_by => { -asc => 'recalldate' } })->as_list;
1611
    my @recalls =
1612
      Koha::Recalls->search( { biblionumber => $self->biblionumber, itemnumber => [ $self->itemnumber, undef ], status => [ 'requested', 'overdue', 'waiting', 'in_transit' ] },
1613
        { order_by => { -asc => 'recalldate' } } )->as_list;
1612
1614
1613
    my $recall;
1615
    my $recall;
1614
    # iterate through relevant recalls to find the best one.
1616
    # iterate through relevant recalls to find the best one.
(-)a/Koha/Recall.pm (-38 / +32 lines)
Lines 142-149 Return true if recall status is requested. Link Here
142
142
143
sub requested {
143
sub requested {
144
    my ( $self ) = @_;
144
    my ( $self ) = @_;
145
    my $status = $self->status;
145
    return $self->status eq 'requested';
146
    return $status && $status eq 'R';
147
}
146
}
148
147
149
=head3 waiting
148
=head3 waiting
Lines 158-165 Return true if recall is awaiting pickup. Link Here
158
157
159
sub waiting {
158
sub waiting {
160
    my ( $self ) = @_;
159
    my ( $self ) = @_;
161
    my $status = $self->status;
160
    return $self->status eq 'waiting';
162
    return $status && $status eq 'W';
163
}
161
}
164
162
165
=head3 overdue
163
=head3 overdue
Lines 174-181 Return true if recall is overdue to be returned. Link Here
174
172
175
sub overdue {
173
sub overdue {
176
    my ( $self ) = @_;
174
    my ( $self ) = @_;
177
    my $status = $self->status;
175
    return $self->status eq 'overdue';
178
    return $status && $status eq 'O';
179
}
176
}
180
177
181
=head3 in_transit
178
=head3 in_transit
Lines 190-197 Return true if recall is in transit. Link Here
190
187
191
sub in_transit {
188
sub in_transit {
192
    my ( $self ) = @_;
189
    my ( $self ) = @_;
193
    my $status = $self->status;
190
    return $self->status eq 'in_transit';
194
    return $status && $status eq 'T';
195
}
191
}
196
192
197
=head3 expired
193
=head3 expired
Lines 206-213 Return true if recall has expired. Link Here
206
202
207
sub expired {
203
sub expired {
208
    my ( $self ) = @_;
204
    my ( $self ) = @_;
209
    my $status = $self->status;
205
    return $self->status eq 'expired';
210
    return $status && $status eq 'E';
211
}
206
}
212
207
213
=head3 cancelled
208
=head3 cancelled
Lines 222-245 Return true if recall has been cancelled. Link Here
222
217
223
sub cancelled {
218
sub cancelled {
224
    my ( $self ) = @_;
219
    my ( $self ) = @_;
225
    my $status = $self->status;
220
    return $self->status eq 'cancelled';
226
    return $status && $status eq 'C';
227
}
221
}
228
222
229
=head3 finished
223
=head3 fulfilled
230
224
231
    if ( $recall->finished )
225
    if ( $recall->fulfilled )
232
226
233
    [% IF recall.finished %]
227
    [% IF recall.fulfilled %]
234
228
235
Return true if recall is finished and has been fulfilled.
229
Return true if the recall has been fulfilled.
236
230
237
=cut
231
=cut
238
232
239
sub finished {
233
sub fulfilled {
240
    my ( $self ) = @_;
234
    my ( $self ) = @_;
241
    my $status = $self->status;
235
    return $self->status eq 'fulfilled';
242
    return $status && $status eq 'F';
243
}
236
}
244
237
245
=head3 calc_expirationdate
238
=head3 calc_expirationdate
Lines 292-301 sub start_transfer { Link Here
292
285
293
    if ( $self->item_level_recall ) {
286
    if ( $self->item_level_recall ) {
294
        # already has an itemnumber
287
        # already has an itemnumber
295
        $self->update({ status => 'T' });
288
        $self->update({ status => 'in_transit' });
296
    } else {
289
    } else {
297
        my $itemnumber = $params->{item}->itemnumber;
290
        my $itemnumber = $params->{item}->itemnumber;
298
        $self->update({ status => 'T', itemnumber => $itemnumber });
291
        $self->update({ status => 'in_transit', itemnumber => $itemnumber });
299
    }
292
    }
300
293
301
    my ( $dotransfer, $messages ) = C4::Circulation::transferbook({ to_branch => $self->branchcode, from_branch => $self->item->holdingbranch, barcode => $self->item->barcode, trigger => 'Recall' });
294
    my ( $dotransfer, $messages ) = C4::Circulation::transferbook({ to_branch => $self->branchcode, from_branch => $self->item->holdingbranch, barcode => $self->item->barcode, trigger => 'Recall' });
Lines 315-323 sub revert_transfer { Link Here
315
    my ( $self ) = @_;
308
    my ( $self ) = @_;
316
309
317
    if ( $self->item_level_recall ) {
310
    if ( $self->item_level_recall ) {
318
        $self->update({ status => 'R' });
311
        $self->update({ status => 'requested' });
319
    } else {
312
    } else {
320
        $self->update({ status => 'R', itemnumber => undef });
313
        $self->update({ status => 'requested', itemnumber => undef });
321
    }
314
    }
322
315
323
    return $self;
316
    return $self;
Lines 325-334 sub revert_transfer { Link Here
325
318
326
=head3 set_waiting
319
=head3 set_waiting
327
320
328
    $recall->set_waiting({
321
    $recall->set_waiting(
329
        expirationdate => $expirationdate,
322
        {   expirationdate => $expirationdate,
330
        item => $item_object
323
            item           => $item_object
331
    });
324
        }
325
    );
332
326
333
Set the recall as waiting and update expiration date.
327
Set the recall as waiting and update expiration date.
334
Notify the recall requester.
328
Notify the recall requester.
Lines 341-351 sub set_waiting { Link Here
341
    my $itemnumber;
335
    my $itemnumber;
342
    if ( $self->item_level_recall ) {
336
    if ( $self->item_level_recall ) {
343
        $itemnumber = $self->itemnumber;
337
        $itemnumber = $self->itemnumber;
344
        $self->update({ status => 'W', waitingdate => dt_from_string, expirationdate => $params->{expirationdate} });
338
        $self->update({ status => 'waiting', waitingdate => dt_from_string, expirationdate => $params->{expirationdate} });
345
    } else {
339
    } else {
346
        # biblio-level recall with no itemnumber. need to set itemnumber
340
        # biblio-level recall with no itemnumber. need to set itemnumber
347
        $itemnumber = $params->{item}->itemnumber;
341
        $itemnumber = $params->{item}->itemnumber;
348
        $self->update({ status => 'W', waitingdate => dt_from_string, expirationdate => $params->{expirationdate}, itemnumber => $itemnumber });
342
        $self->update({ status => 'waiting', waitingdate => dt_from_string, expirationdate => $params->{expirationdate}, itemnumber => $itemnumber });
349
    }
343
    }
350
344
351
    # send notice to recaller to pick up item
345
    # send notice to recaller to pick up item
Lines 378-386 Revert recall waiting status. Link Here
378
sub revert_waiting {
372
sub revert_waiting {
379
    my ( $self ) = @_;
373
    my ( $self ) = @_;
380
    if ( $self->item_level_recall ){
374
    if ( $self->item_level_recall ){
381
        $self->update({ status => 'R', waitingdate => undef });
375
        $self->update({ status => 'requested', waitingdate => undef });
382
    } else {
376
    } else {
383
        $self->update({ status => 'R', waitingdate => undef, itemnumber => undef });
377
        $self->update({ status => 'requested', waitingdate => undef, itemnumber => undef });
384
    }
378
    }
385
    return $self;
379
    return $self;
386
}
380
}
Lines 414-420 Set a recall as overdue when the recall has been requested and the borrower who Link Here
414
sub set_overdue {
408
sub set_overdue {
415
    my ( $self, $params ) = @_;
409
    my ( $self, $params ) = @_;
416
    my $interface = $params->{interface} || 'COMMANDLINE';
410
    my $interface = $params->{interface} || 'COMMANDLINE';
417
    $self->update({ status => 'O' });
411
    $self->update({ status => 'overdue' });
418
    C4::Log::logaction( 'RECALLS', 'OVERDUE', $self->recall_id, "Recall status set to overdue", $interface ) if ( C4::Context->preference('RecallsLog') );
412
    C4::Log::logaction( 'RECALLS', 'OVERDUE', $self->recall_id, "Recall status set to overdue", $interface ) if ( C4::Context->preference('RecallsLog') );
419
    return $self;
413
    return $self;
420
}
414
}
Lines 430-436 Set a recall as expired. This may be done manually or by a cronjob, either when Link Here
430
sub set_expired {
424
sub set_expired {
431
    my ( $self, $params ) = @_;
425
    my ( $self, $params ) = @_;
432
    my $interface = $params->{interface} || 'COMMANDLINE';
426
    my $interface = $params->{interface} || 'COMMANDLINE';
433
    $self->update({ status => 'E', old => 1, expirationdate => dt_from_string });
427
    $self->update({ status => 'expired', old => 1, expirationdate => dt_from_string });
434
    C4::Log::logaction( 'RECALLS', 'EXPIRE', $self->recall_id, "Recall expired", $interface ) if ( C4::Context->preference('RecallsLog') );
428
    C4::Log::logaction( 'RECALLS', 'EXPIRE', $self->recall_id, "Recall expired", $interface ) if ( C4::Context->preference('RecallsLog') );
435
    return $self;
429
    return $self;
436
}
430
}
Lines 445-466 Set a recall as cancelled. This may be done manually, either by the borrower tha Link Here
445
439
446
sub set_cancelled {
440
sub set_cancelled {
447
    my ( $self ) = @_;
441
    my ( $self ) = @_;
448
    $self->update({ status => 'C', old => 1, cancellationdate => dt_from_string });
442
    $self->update({ status => 'cancelled', old => 1, cancellationdate => dt_from_string });
449
    C4::Log::logaction( 'RECALLS', 'CANCEL', $self->recall_id, "Recall cancelled", 'INTRANET' ) if ( C4::Context->preference('RecallsLog') );
443
    C4::Log::logaction( 'RECALLS', 'CANCEL', $self->recall_id, "Recall cancelled", 'INTRANET' ) if ( C4::Context->preference('RecallsLog') );
450
    return $self;
444
    return $self;
451
}
445
}
452
446
453
=head3 set_finished
447
=head3 set_fulfilled
454
448
455
    $recall->set_finished;
449
    $recall->set_fulfilled;
456
450
457
Set a recall as finished. This should only be called when the item allocated to a recall is checked out to the borrower who requested the recall.
451
Set a recall as finished. This should only be called when the item allocated to a recall is checked out to the borrower who requested the recall.
458
452
459
=cut
453
=cut
460
454
461
sub set_finished {
455
sub set_fulfilled {
462
    my ( $self ) = @_;
456
    my ( $self ) = @_;
463
    $self->update({ status => 'F', old => 1 });
457
    $self->update({ status => 'fulfilled', old => 1 });
464
    C4::Log::logaction( 'RECALLS', 'FULFILL', $self->recall_id, "Recall fulfilled", 'INTRANET' ) if ( C4::Context->preference('RecallsLog') );
458
    C4::Log::logaction( 'RECALLS', 'FULFILL', $self->recall_id, "Recall fulfilled", 'INTRANET' ) if ( C4::Context->preference('RecallsLog') );
465
    return $self;
459
    return $self;
466
}
460
}
(-)a/Koha/Recalls.pm (-7 / +17 lines)
Lines 33-41 Koha::Recalls - Koha Recalls Object set class Link Here
33
33
34
=head1 API
34
=head1 API
35
35
36
=head2 Internal methods
36
=head2 Class methods
37
38
=cut
39
37
40
=head3 add_recall
38
=head3 add_recall
41
39
Lines 79-85 sub add_recall { Link Here
79
        recalldate => dt_from_string(),
77
        recalldate => dt_from_string(),
80
        biblionumber => $biblio->biblionumber,
78
        biblionumber => $biblio->biblionumber,
81
        branchcode => $branchcode,
79
        branchcode => $branchcode,
82
        status => 'R',
80
        status => 'requested',
83
        itemnumber => defined $itemnumber ? $itemnumber : undef,
81
        itemnumber => defined $itemnumber ? $itemnumber : undef,
84
        expirationdate => $expirationdate,
82
        expirationdate => $expirationdate,
85
        item_level_recall => defined $itemnumber ? 1 : 0,
83
        item_level_recall => defined $itemnumber ? 1 : 0,
Lines 149-155 sub add_recall { Link Here
149
        borrowernumber => $borrowernumber,
147
        borrowernumber => $borrowernumber,
150
    });
148
    });
151
149
152
A patron is attempting to check out an item that has been recalled by another patron. If the recall is requested/overdue, they have the option of cancelling the recall. If the recall is waiting, they also have the option of reverting the waiting status.
150
A patron is attempting to check out an item that has been recalled by another patron.
151
If the recall is requested/overdue, they have the option of cancelling the recall.
152
If the recall is waiting, they also have the option of reverting the waiting status.
153
153
154
We can also fulfill the recall here if the recall is placed by this borrower.
154
We can also fulfill the recall here if the recall is placed by this borrower.
155
155
Lines 183-191 sub move_recall { Link Here
183
183
184
    if ( $message eq 'no action provided' and $item and $item->biblionumber and $borrowernumber ) {
184
    if ( $message eq 'no action provided' and $item and $item->biblionumber and $borrowernumber ) {
185
        # move_recall was not called to revert or cancel, but was called to fulfill
185
        # move_recall was not called to revert or cancel, but was called to fulfill
186
        my $recall = Koha::Recalls->search({ borrowernumber => $borrowernumber, biblionumber => $item->biblionumber, itemnumber => [ $item->itemnumber, undef ], old => undef }, { order_by => { -asc => 'recalldate' } })->next;
186
        my $recall = Koha::Recalls->search(
187
            {
188
                borrowernumber => $borrowernumber,
189
                biblionumber   => $item->biblionumber,
190
                itemnumber     => [ $item->itemnumber, undef ],
191
                old            => undef
192
            },
193
            { order_by => { -asc => 'recalldate' } }
194
        )->next;
187
        if ( $recall ) {
195
        if ( $recall ) {
188
            $recall->set_finished;
196
            $recall->set_fulfilled;
189
            $message = 'fulfilled';
197
            $message = 'fulfilled';
190
        }
198
        }
191
    }
199
    }
Lines 193-198 sub move_recall { Link Here
193
    return $message;
201
    return $message;
194
}
202
}
195
203
204
=head2 Internal methods
205
196
=head3 _type
206
=head3 _type
197
207
198
=cut
208
=cut
(-)a/installer/data/mysql/atomicupdate/bug_19532_make_status_enum.pl (+16 lines)
Line 0 Link Here
1
use Modern::Perl;
2
3
return {
4
    bug_number => "19532",
5
    description => "Make recalls.status an enum",
6
    up => sub {
7
        my ($args) = @_;
8
        my ($dbh) = @$args{qw(dbh)};
9
10
        $dbh->do(q{
11
            ALTER TABLE recalls
12
            MODIFY COLUMN
13
                status ENUM('requested','overdue','waiting','in_transit','cancelled','expired','fulfilled') DEFAULT 'requested' COMMENT "Request status"
14
        });
15
    },
16
};
(-)a/installer/data/mysql/kohastructure.sql (-2 / +2 lines)
Lines 4291-4302 CREATE TABLE recalls ( -- information related to recalls in Koha Link Here
4291
    cancellationdate datetime DEFAULT NULL, -- the date this recall was cancelled
4291
    cancellationdate datetime DEFAULT NULL, -- the date this recall was cancelled
4292
    recallnotes mediumtext, -- notes related to this recall
4292
    recallnotes mediumtext, -- notes related to this recall
4293
    priority smallint(6) DEFAULT NULL, -- where in the queue the patron sits
4293
    priority smallint(6) DEFAULT NULL, -- where in the queue the patron sits
4294
    status varchar(1) DEFAULT NULL, -- a one letter code defining the status of the recall. R=requested, O=overdue, W=awaiting pickup, T=in transit, E=expired, C=cancelled, F=finished/completed
4294
    status ENUM('requested','overdue','waiting','in_transit','cancelled','expired','fulfilled') DEFAULT 'requested' COMMENT "Request status",
4295
    timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- the date and time this recall was last updated
4295
    timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- the date and time this recall was last updated
4296
    itemnumber int(11) DEFAULT NULL, -- foreign key from the items table defining the specific item the recall request was placed on
4296
    itemnumber int(11) DEFAULT NULL, -- foreign key from the items table defining the specific item the recall request was placed on
4297
    waitingdate datetime DEFAULT NULL, -- the date the item was marked as waiting for the patron at the library
4297
    waitingdate datetime DEFAULT NULL, -- the date the item was marked as waiting for the patron at the library
4298
    expirationdate datetime DEFAULT NULL, -- the date the recall expires
4298
    expirationdate datetime DEFAULT NULL, -- the date the recall expires
4299
    old TINYINT(1) DEFAULT NULL, -- flag if the recall is old and no longer active, i.e. expired, cancelled or completed
4299
    old TINYINT(1) DEFAULT 0, -- flag if the recall is old and no longer active, i.e. expired, cancelled or completed
4300
    item_level_recall TINYINT(1) NOT NULL DEFAULT 0, -- flag if item-level recall
4300
    item_level_recall TINYINT(1) NOT NULL DEFAULT 0, -- flag if item-level recall
4301
     PRIMARY KEY (recall_id),
4301
     PRIMARY KEY (recall_id),
4302
     KEY borrowernumber (borrowernumber),
4302
     KEY borrowernumber (borrowernumber),
(-)a/t/db_dependent/Circulation.t (-78 / +74 lines)
Lines 1455-1461 subtest "CanBookBeRenewed tests" => sub { Link Here
1455
        borrowernumber => $recall_borrower->borrowernumber,
1455
        borrowernumber => $recall_borrower->borrowernumber,
1456
        branchcode => $recall_borrower->branchcode,
1456
        branchcode => $recall_borrower->branchcode,
1457
        item_level_recall => 1,
1457
        item_level_recall => 1,
1458
        status => 'R',
1459
    })->store;
1458
    })->store;
1460
    ( $renewokay, $error ) = CanBookBeRenewed( $renewing_borrowernumber, $recall_item1->itemnumber );
1459
    ( $renewokay, $error ) = CanBookBeRenewed( $renewing_borrowernumber, $recall_item1->itemnumber );
1461
    is( $error, 'recalled', 'Cannot renew item that has been recalled' );
1460
    is( $error, 'recalled', 'Cannot renew item that has been recalled' );
Lines 1468-1474 subtest "CanBookBeRenewed tests" => sub { Link Here
1468
        borrowernumber => $recall_borrower->borrowernumber,
1467
        borrowernumber => $recall_borrower->borrowernumber,
1469
        branchcode => $recall_borrower->branchcode,
1468
        branchcode => $recall_borrower->branchcode,
1470
        item_level_recall => 0,
1469
        item_level_recall => 0,
1471
        status => 'R',
1472
    })->store;
1470
    })->store;
1473
    ( $renewokay, $error ) = CanBookBeRenewed( $renewing_borrowernumber, $recall_item1->itemnumber );
1471
    ( $renewokay, $error ) = CanBookBeRenewed( $renewing_borrowernumber, $recall_item1->itemnumber );
1474
    is( $error, 'recalled', 'Cannot renew item if biblio is recalled and has no item allocated' );
1472
    is( $error, 'recalled', 'Cannot renew item if biblio is recalled and has no item allocated' );
Lines 1481-1487 subtest "CanBookBeRenewed tests" => sub { Link Here
1481
        borrowernumber => $recall_borrower->borrowernumber,
1479
        borrowernumber => $recall_borrower->borrowernumber,
1482
        branchcode => $recall_borrower->branchcode,
1480
        branchcode => $recall_borrower->branchcode,
1483
        item_level_recall => 1,
1481
        item_level_recall => 1,
1484
        status => 'R',
1485
    })->store;
1482
    })->store;
1486
    ( $renewokay, $error ) = CanBookBeRenewed( $renewing_borrowernumber, $recall_item1->itemnumber );
1483
    ( $renewokay, $error ) = CanBookBeRenewed( $renewing_borrowernumber, $recall_item1->itemnumber );
1487
    is( $renewokay, 1, 'Can renew item if item-level recall on biblio is not on this item' );
1484
    is( $renewokay, 1, 'Can renew item if item-level recall on biblio is not on this item' );
Lines 1494-1500 subtest "CanBookBeRenewed tests" => sub { Link Here
1494
        borrowernumber => $recall_borrower->borrowernumber,
1491
        borrowernumber => $recall_borrower->borrowernumber,
1495
        branchcode => $recall_borrower->branchcode,
1492
        branchcode => $recall_borrower->branchcode,
1496
        item_level_recall => 0,
1493
        item_level_recall => 0,
1497
        status => 'R',
1498
    })->store;
1494
    })->store;
1499
    $recall->set_waiting({ item => $recall_item1 });
1495
    $recall->set_waiting({ item => $recall_item1 });
1500
    ( $renewokay, $error ) = CanBookBeRenewed( $renewing_borrowernumber, $recall_item1->itemnumber );
1496
    ( $renewokay, $error ) = CanBookBeRenewed( $renewing_borrowernumber, $recall_item1->itemnumber );
Lines 1998-2039 subtest 'AddIssue | recalls' => sub { Link Here
1998
    });
1994
    });
1999
1995
2000
    # checking out item that they have recalled
1996
    # checking out item that they have recalled
2001
    my $recall1 = Koha::Recall->new({
1997
    my $recall1 = Koha::Recall->new(
2002
        borrowernumber => $patron1->borrowernumber,
1998
        {   borrowernumber    => $patron1->borrowernumber,
2003
        biblionumber => $item->biblionumber,
1999
            biblionumber      => $item->biblionumber,
2004
        itemnumber => $item->itemnumber,
2000
            itemnumber        => $item->itemnumber,
2005
        item_level_recall => 1,
2001
            item_level_recall => 1,
2006
        branchcode => $patron1->branchcode,
2002
            branchcode        => $patron1->branchcode,
2007
        status => 'R',
2003
        }
2008
    })->store;
2004
    )->store;
2009
    AddIssue( $patron1->unblessed, $item->barcode, undef, undef, undef, undef, { recall_id => $recall1->recall_id } );
2005
    AddIssue( $patron1->unblessed, $item->barcode, undef, undef, undef, undef, { recall_id => $recall1->recall_id } );
2010
    $recall1 = Koha::Recalls->find( $recall1->recall_id );
2006
    $recall1 = Koha::Recalls->find( $recall1->recall_id );
2011
    is( $recall1->finished, 1, 'Recall was fulfilled when patron checked out item' );
2007
    is( $recall1->fulfilled, 1, 'Recall was fulfilled when patron checked out item' );
2012
    AddReturn( $item->barcode, $item->homebranch );
2008
    AddReturn( $item->barcode, $item->homebranch );
2013
2009
2014
    # this item is has a recall request. cancel recall
2010
    # this item is has a recall request. cancel recall
2015
    my $recall2 = Koha::Recall->new({
2011
    my $recall2 = Koha::Recall->new(
2016
        borrowernumber => $patron2->borrowernumber,
2012
        {   borrowernumber    => $patron2->borrowernumber,
2017
        biblionumber => $item->biblionumber,
2013
            biblionumber      => $item->biblionumber,
2018
        itemnumber => $item->itemnumber,
2014
            itemnumber        => $item->itemnumber,
2019
        item_level_recall => 1,
2015
            item_level_recall => 1,
2020
        branchcode => $patron2->branchcode,
2016
            branchcode        => $patron2->branchcode,
2021
        status => 'R',
2017
        }
2022
    })->store;
2018
    )->store;
2023
    AddIssue( $patron1->unblessed, $item->barcode, undef, undef, undef, undef, { recall_id => $recall2->recall_id, cancel_recall => 'cancel' } );
2019
    AddIssue( $patron1->unblessed, $item->barcode, undef, undef, undef, undef, { recall_id => $recall2->recall_id, cancel_recall => 'cancel' } );
2024
    $recall2 = Koha::Recalls->find( $recall2->recall_id );
2020
    $recall2 = Koha::Recalls->find( $recall2->recall_id );
2025
    is( $recall2->cancelled, 1, 'Recall was cancelled when patron checked out item' );
2021
    is( $recall2->cancelled, 1, 'Recall was cancelled when patron checked out item' );
2026
    AddReturn( $item->barcode, $item->homebranch );
2022
    AddReturn( $item->barcode, $item->homebranch );
2027
2023
2028
    # this item is waiting to fulfill a recall. revert recall
2024
    # this item is waiting to fulfill a recall. revert recall
2029
    my $recall3 = Koha::Recall->new({
2025
    my $recall3 = Koha::Recall->new(
2030
        borrowernumber => $patron2->borrowernumber,
2026
        {   borrowernumber    => $patron2->borrowernumber,
2031
        biblionumber => $item->biblionumber,
2027
            biblionumber      => $item->biblionumber,
2032
        itemnumber => $item->itemnumber,
2028
            itemnumber        => $item->itemnumber,
2033
        item_level_recall => 1,
2029
            item_level_recall => 1,
2034
        branchcode => $patron2->branchcode,
2030
            branchcode        => $patron2->branchcode,
2035
        status => 'R',
2031
        }
2036
    })->store;
2032
    )->store;
2037
    $recall3->set_waiting;
2033
    $recall3->set_waiting;
2038
    AddIssue( $patron1->unblessed, $item->barcode, undef, undef, undef, undef, { recall_id => $recall3->recall_id, cancel_recall => 'revert' } );
2034
    AddIssue( $patron1->unblessed, $item->barcode, undef, undef, undef, undef, { recall_id => $recall3->recall_id, cancel_recall => 'revert' } );
2039
    $recall3 = Koha::Recalls->find( $recall3->recall_id );
2035
    $recall3 = Koha::Recalls->find( $recall3->recall_id );
Lines 3978-3991 subtest 'CanBookBeIssued | recalls' => sub { Link Here
3978
    });
3974
    });
3979
3975
3980
    # item-level recall
3976
    # item-level recall
3981
    my $recall = Koha::Recall->new({
3977
    my $recall = Koha::Recall->new(
3982
        borrowernumber => $patron1->borrowernumber,
3978
        {   borrowernumber    => $patron1->borrowernumber,
3983
        biblionumber => $item->biblionumber,
3979
            biblionumber      => $item->biblionumber,
3984
        itemnumber => $item->itemnumber,
3980
            itemnumber        => $item->itemnumber,
3985
        item_level_recall => 1,
3981
            item_level_recall => 1,
3986
        branchcode => $patron1->branchcode,
3982
            branchcode        => $patron1->branchcode,
3987
        status => 'R',
3983
        }
3988
    })->store;
3984
    )->store;
3989
3985
3990
    my ( $issuingimpossible, $needsconfirmation ) = CanBookBeIssued( $patron2, $item->barcode, undef, undef, undef, undef );
3986
    my ( $issuingimpossible, $needsconfirmation ) = CanBookBeIssued( $patron2, $item->barcode, undef, undef, undef, undef );
3991
    is( $needsconfirmation->{RECALLED}->recall_id, $recall->recall_id, "Another patron has placed an item-level recall on this item" );
3987
    is( $needsconfirmation->{RECALLED}->recall_id, $recall->recall_id, "Another patron has placed an item-level recall on this item" );
Lines 3993-4006 subtest 'CanBookBeIssued | recalls' => sub { Link Here
3993
    $recall->set_cancelled;
3989
    $recall->set_cancelled;
3994
3990
3995
    # biblio-level recall
3991
    # biblio-level recall
3996
    $recall = Koha::Recall->new({
3992
    $recall = Koha::Recall->new(
3997
        borrowernumber => $patron1->borrowernumber,
3993
        {   borrowernumber    => $patron1->borrowernumber,
3998
        biblionumber => $item->biblionumber,
3994
            biblionumber      => $item->biblionumber,
3999
        itemnumber => undef,
3995
            itemnumber        => undef,
4000
        item_level_recall => 0,
3996
            item_level_recall => 0,
4001
        branchcode => $patron1->branchcode,
3997
            branchcode        => $patron1->branchcode,
4002
        status => 'R',
3998
        }
4003
    })->store;
3999
    )->store;
4004
4000
4005
    ( $issuingimpossible, $needsconfirmation ) = CanBookBeIssued( $patron2, $item->barcode, undef, undef, undef, undef );
4001
    ( $issuingimpossible, $needsconfirmation ) = CanBookBeIssued( $patron2, $item->barcode, undef, undef, undef, undef );
4006
    is( $needsconfirmation->{RECALLED}->recall_id, $recall->recall_id, "Another patron has placed a biblio-level recall and this item is eligible to fill it" );
4002
    is( $needsconfirmation->{RECALLED}->recall_id, $recall->recall_id, "Another patron has placed a biblio-level recall and this item is eligible to fill it" );
Lines 4008-4022 subtest 'CanBookBeIssued | recalls' => sub { Link Here
4008
    $recall->set_cancelled;
4004
    $recall->set_cancelled;
4009
4005
4010
    # biblio-level recall
4006
    # biblio-level recall
4011
    $recall = Koha::Recall->new({
4007
    $recall = Koha::Recall->new(
4012
        borrowernumber => $patron1->borrowernumber,
4008
        {   borrowernumber    => $patron1->borrowernumber,
4013
        biblionumber => $item->biblionumber,
4009
            biblionumber      => $item->biblionumber,
4014
        itemnumber => undef,
4010
            itemnumber        => undef,
4015
        item_level_recall => 0,
4011
            item_level_recall => 0,
4016
        branchcode => $patron1->branchcode,
4012
            branchcode        => $patron1->branchcode,
4017
        status => 'R',
4013
        }
4018
    })->store;
4014
    )->store;
4019
    $recall->set_waiting({ item => $item, expirationdate => dt_from_string() });
4015
    $recall->set_waiting( { item => $item, expirationdate => dt_from_string() } );
4020
4016
4021
    my ( undef, undef, undef, $messages ) = CanBookBeIssued( $patron1, $item->barcode, undef, undef, undef, undef );
4017
    my ( undef, undef, undef, $messages ) = CanBookBeIssued( $patron1, $item->barcode, undef, undef, undef, undef );
4022
    is( $messages->{RECALLED}, $recall->recall_id, "This book can be issued by this patron and they have placed a recall" );
4018
    is( $messages->{RECALLED}, $recall->recall_id, "This book can be issued by this patron and they have placed a recall" );
Lines 4058-4099 subtest 'AddReturn | recalls' => sub { Link Here
4058
4054
4059
    # this item can fill a recall with pickup at this branch
4055
    # this item can fill a recall with pickup at this branch
4060
    AddIssue( $patron1->unblessed, $item1->barcode );
4056
    AddIssue( $patron1->unblessed, $item1->barcode );
4061
    my $recall1 = Koha::Recall->new({
4057
    my $recall1 = Koha::Recall->new(
4062
        borrowernumber => $patron2->borrowernumber,
4058
        {   borrowernumber    => $patron2->borrowernumber,
4063
        biblionumber => $item1->biblionumber,
4059
            biblionumber      => $item1->biblionumber,
4064
        itemnumber => $item1->itemnumber,
4060
            itemnumber        => $item1->itemnumber,
4065
        item_level_recall => 1,
4061
            item_level_recall => 1,
4066
        branchcode => $item1->homebranch,
4062
            branchcode        => $item1->homebranch,
4067
        status => 'R',
4063
        }
4068
    })->store;
4064
    )->store;
4069
    my ( $doreturn, $messages, $iteminfo, $borrowerinfo ) = AddReturn( $item1->barcode, $item1->homebranch );
4065
    my ( $doreturn, $messages, $iteminfo, $borrowerinfo ) = AddReturn( $item1->barcode, $item1->homebranch );
4070
    is( $messages->{RecallFound}->recall_id, $recall1->recall_id, "Recall found" );
4066
    is( $messages->{RecallFound}->recall_id, $recall1->recall_id, "Recall found" );
4071
    $recall1->set_cancelled;
4067
    $recall1->set_cancelled;
4072
4068
4073
    # this item can fill a recall but needs transfer
4069
    # this item can fill a recall but needs transfer
4074
    AddIssue( $patron1->unblessed, $item1->barcode );
4070
    AddIssue( $patron1->unblessed, $item1->barcode );
4075
    $recall1 = Koha::Recall->new({
4071
    $recall1 = Koha::Recall->new(
4076
        borrowernumber => $patron2->borrowernumber,
4072
        {   borrowernumber    => $patron2->borrowernumber,
4077
        biblionumber => $item1->biblionumber,
4073
            biblionumber      => $item1->biblionumber,
4078
        itemnumber => $item1->itemnumber,
4074
            itemnumber        => $item1->itemnumber,
4079
        item_level_recall => 1,
4075
            item_level_recall => 1,
4080
        branchcode => $patron2->branchcode,
4076
            branchcode        => $patron2->branchcode,
4081
        status => 'R',
4077
        }
4082
    })->store;
4078
    )->store;
4083
    ( $doreturn, $messages, $iteminfo, $borrowerinfo ) = AddReturn( $item1->barcode, $item1->homebranch );
4079
    ( $doreturn, $messages, $iteminfo, $borrowerinfo ) = AddReturn( $item1->barcode, $item1->homebranch );
4084
    is( $messages->{RecallNeedsTransfer}, $item1->homebranch, "Recall requiring transfer found" );
4080
    is( $messages->{RecallNeedsTransfer}, $item1->homebranch, "Recall requiring transfer found" );
4085
    $recall1->set_cancelled;
4081
    $recall1->set_cancelled;
4086
4082
4087
    # this item is already in transit, do not ask to transfer
4083
    # this item is already in transit, do not ask to transfer
4088
    AddIssue( $patron1->unblessed, $item1->barcode );
4084
    AddIssue( $patron1->unblessed, $item1->barcode );
4089
    $recall1 = Koha::Recall->new({
4085
    $recall1 = Koha::Recall->new(
4090
        borrowernumber => $patron2->borrowernumber,
4086
        {   borrowernumber    => $patron2->borrowernumber,
4091
        biblionumber => $item1->biblionumber,
4087
            biblionumber      => $item1->biblionumber,
4092
        itemnumber => $item1->itemnumber,
4088
            itemnumber        => $item1->itemnumber,
4093
        item_level_recall => 1,
4089
            item_level_recall => 1,
4094
        branchcode => $patron2->branchcode,
4090
            branchcode        => $patron2->branchcode,
4095
        status => 'R',
4091
        }
4096
    })->store;
4092
    )->store;
4097
    $recall1->start_transfer;
4093
    $recall1->start_transfer;
4098
    ( $doreturn, $messages, $iteminfo, $borrowerinfo ) = AddReturn( $item1->barcode, $patron2->branchcode );
4094
    ( $doreturn, $messages, $iteminfo, $borrowerinfo ) = AddReturn( $item1->barcode, $patron2->branchcode );
4099
    is( $messages->{TransferredRecall}->recall_id, $recall1->recall_id, "In transit recall found" );
4095
    is( $messages->{TransferredRecall}->recall_id, $recall1->recall_id, "In transit recall found" );
(-)a/t/db_dependent/Circulation/CalcFine.t (-2 / +1 lines)
Lines 232-238 subtest 'Recall overdue fines' => sub { Link Here
232
        recalldate => dt_from_string,
232
        recalldate => dt_from_string,
233
        biblionumber => $item->biblionumber,
233
        biblionumber => $item->biblionumber,
234
        branchcode => $branch->{branchcode},
234
        branchcode => $branch->{branchcode},
235
        status => 'R',
236
        itemnumber => $item->itemnumber,
235
        itemnumber => $item->itemnumber,
237
        expirationdate => undef,
236
        expirationdate => undef,
238
        item_level_recall => 1
237
        item_level_recall => 1
Lines 242-248 subtest 'Recall overdue fines' => sub { Link Here
242
    my ($amount) = CalcFine( $item->unblessed, $patron->{categorycode}, $branch->{branchcode}, $start_dt, $end_dt );
241
    my ($amount) = CalcFine( $item->unblessed, $patron->{categorycode}, $branch->{branchcode}, $start_dt, $end_dt );
243
    is( int($amount), 25, 'Use recall fine amount specified in circulation rules' );
242
    is( int($amount), 25, 'Use recall fine amount specified in circulation rules' );
244
243
245
    $recall->set_finished;
244
    $recall->set_fulfilled;
246
    ($amount) = CalcFine( $item->unblessed, $patron->{categorycode}, $branch->{branchcode}, $start_dt, $end_dt );
245
    ($amount) = CalcFine( $item->unblessed, $patron->{categorycode}, $branch->{branchcode}, $start_dt, $end_dt );
247
    is( int($amount), 5, 'With no recall, use normal fine amount' );
246
    is( int($amount), 5, 'With no recall, use normal fine amount' );
248
247
(-)a/t/db_dependent/Circulation/transferbook.t (-16 / +16 lines)
Lines 157-183 subtest 'transfer already at destination' => sub { Link Here
157
157
158
    # recalls
158
    # recalls
159
    t::lib::Mocks::mock_preference('UseRecalls', 1);
159
    t::lib::Mocks::mock_preference('UseRecalls', 1);
160
    my $recall = Koha::Recall->new({
160
    my $recall = Koha::Recall->new(
161
        biblionumber => $item->biblionumber,
161
        {   biblionumber      => $item->biblionumber,
162
        itemnumber => $item->itemnumber,
162
            itemnumber        => $item->itemnumber,
163
        item_level_recall => 1,
163
            item_level_recall => 1,
164
        borrowernumber => $patron->borrowernumber,
164
            borrowernumber    => $patron->borrowernumber,
165
        branchcode => $library->branchcode,
165
            branchcode        => $library->branchcode,
166
        status => 'R',
166
        }
167
    })->store;
167
    )->store;
168
    ( $recall, $dotransfer, $messages ) = $recall->start_transfer;
168
    ( $recall, $dotransfer, $messages ) = $recall->start_transfer;
169
    is( $dotransfer, 0, 'Do not transfer recalled item, it has already arrived' );
169
    is( $dotransfer, 0, 'Do not transfer recalled item, it has already arrived' );
170
    is( $messages->{RecallPlacedAtHoldingBranch}, 1, "We found the recall");
170
    is( $messages->{RecallPlacedAtHoldingBranch}, 1, "We found the recall");
171
171
172
    my $item2 = $builder->build_object({ class => 'Koha::Items' }); # this item will have a different holding branch to the pickup branch
172
    my $item2 = $builder->build_object({ class => 'Koha::Items' }); # this item will have a different holding branch to the pickup branch
173
    $recall = Koha::Recall->new({
173
    $recall = Koha::Recall->new(
174
        biblionumber => $item2->biblionumber,
174
        {   biblionumber      => $item2->biblionumber,
175
        itemnumber => $item2->itemnumber,
175
            itemnumber        => $item2->itemnumber,
176
        item_level_recall => 1,
176
            item_level_recall => 1,
177
        borrowernumber => $patron->borrowernumber,
177
            borrowernumber    => $patron->borrowernumber,
178
        branchcode => $library->branchcode,
178
            branchcode        => $library->branchcode,
179
        status => 'R',
179
        }
180
    })->store;
180
    )->store;
181
    ( $recall, $dotransfer, $messages ) = $recall->start_transfer;
181
    ( $recall, $dotransfer, $messages ) = $recall->start_transfer;
182
    is( $dotransfer, 1, 'Transfer of recalled item succeeded' );
182
    is( $dotransfer, 1, 'Transfer of recalled item succeeded' );
183
    is( $messages->{RecallFound}->recall_id, $recall->recall_id, "We found the recall");
183
    is( $messages->{RecallFound}->recall_id, $recall->recall_id, "We found the recall");
(-)a/t/db_dependent/Koha/Biblio.t (-30 / +31 lines)
Lines 888-893 subtest 'Recalls tests' => sub { Link Here
888
    plan tests => 12;
888
    plan tests => 12;
889
889
890
    $schema->storage->txn_begin;
890
    $schema->storage->txn_begin;
891
891
    my $item1 = $builder->build_sample_item;
892
    my $item1 = $builder->build_sample_item;
892
    my $biblio = $item1->biblio;
893
    my $biblio = $item1->biblio;
893
    my $branchcode = $item1->holdingbranch;
894
    my $branchcode = $item1->holdingbranch;
Lines 897-932 subtest 'Recalls tests' => sub { Link Here
897
    my $item2 = $builder->build_object({ class => 'Koha::Items', value => { holdingbranch => $branchcode, homebranch => $branchcode, biblionumber => $biblio->biblionumber, itype => $item1->effective_itemtype } });
898
    my $item2 = $builder->build_object({ class => 'Koha::Items', value => { holdingbranch => $branchcode, homebranch => $branchcode, biblionumber => $biblio->biblionumber, itype => $item1->effective_itemtype } });
898
    t::lib::Mocks::mock_userenv({ patron => $patron1 });
899
    t::lib::Mocks::mock_userenv({ patron => $patron1 });
899
900
900
    my $recall1 = Koha::Recall->new({
901
    my $recall1 = Koha::Recall->new(
901
        borrowernumber => $patron1->borrowernumber,
902
        {   borrowernumber    => $patron1->borrowernumber,
902
        recalldate => Koha::DateUtils::dt_from_string,
903
            recalldate        => \'NOW()',
903
        biblionumber => $biblio->biblionumber,
904
            biblionumber      => $biblio->biblionumber,
904
        branchcode => $branchcode,
905
            branchcode        => $branchcode,
905
        status => 'R',
906
            itemnumber        => $item1->itemnumber,
906
        itemnumber => $item1->itemnumber,
907
            expirationdate    => undef,
907
        expirationdate => undef,
908
            item_level_recall => 1
908
        item_level_recall => 1
909
        }
909
    })->store;
910
    )->store;
910
    my $recall2 = Koha::Recall->new({
911
    my $recall2 = Koha::Recall->new(
911
        borrowernumber => $patron2->borrowernumber,
912
        {   borrowernumber    => $patron2->borrowernumber,
912
        recalldate => Koha::DateUtils::dt_from_string,
913
            recalldate        => \'NOW()',
913
        biblionumber => $biblio->biblionumber,
914
            biblionumber      => $biblio->biblionumber,
914
        branchcode => $branchcode,
915
            branchcode        => $branchcode,
915
        status => 'R',
916
            itemnumber        => undef,
916
        itemnumber => undef,
917
            expirationdate    => undef,
917
        expirationdate => undef,
918
            item_level_recall => 0
918
        item_level_recall => 0
919
        }
919
    })->store;
920
    )->store;
920
    my $recall3 = Koha::Recall->new({
921
    my $recall3 = Koha::Recall->new(
921
        borrowernumber => $patron3->borrowernumber,
922
        {   borrowernumber    => $patron3->borrowernumber,
922
        recalldate => Koha::DateUtils::dt_from_string,
923
            recalldate        => \'NOW()',
923
        biblionumber => $biblio->biblionumber,
924
            biblionumber      => $biblio->biblionumber,
924
        branchcode => $branchcode,
925
            branchcode        => $branchcode,
925
        status => 'R',
926
            itemnumber        => $item1->itemnumber,
926
        itemnumber => $item1->itemnumber,
927
            expirationdate    => undef,
927
        expirationdate => undef,
928
            item_level_recall => 1
928
        item_level_recall => 1
929
        }
929
    })->store;
930
    )->store;
930
931
931
    my $recalls_count = $biblio->recalls->count;
932
    my $recalls_count = $biblio->recalls->count;
932
    is( $recalls_count, 3, 'Correctly get number of active recalls for biblio' );
933
    is( $recalls_count, 3, 'Correctly get number of active recalls for biblio' );
(-)a/t/db_dependent/Koha/Item.t (-53 / +58 lines)
Lines 1179-1207 subtest 'Recalls tests' => sub { Link Here
1179
    my $patron1 = $builder->build_object({ class => 'Koha::Patrons', value => { branchcode => $branchcode } });
1179
    my $patron1 = $builder->build_object({ class => 'Koha::Patrons', value => { branchcode => $branchcode } });
1180
    my $patron2 = $builder->build_object({ class => 'Koha::Patrons', value => { branchcode => $branchcode } });
1180
    my $patron2 = $builder->build_object({ class => 'Koha::Patrons', value => { branchcode => $branchcode } });
1181
    my $patron3 = $builder->build_object({ class => 'Koha::Patrons', value => { branchcode => $branchcode } });
1181
    my $patron3 = $builder->build_object({ class => 'Koha::Patrons', value => { branchcode => $branchcode } });
1182
    my $item2 = $builder->build_object({ class => 'Koha::Items', value => { holdingbranch => $branchcode, homebranch => $branchcode, biblionumber => $biblio->biblionumber, itype => $item1->effective_itemtype } });
1182
    my $item2 = $builder->build_object(
1183
    t::lib::Mocks::mock_userenv({ patron => $patron1 });
1183
        {   class => 'Koha::Items',
1184
            value => { holdingbranch => $branchcode, homebranch => $branchcode, biblionumber => $biblio->biblionumber, itype => $item1->effective_itemtype }
1185
        }
1186
    );
1184
1187
1185
    my $recall1 = Koha::Recall->new({
1188
    t::lib::Mocks::mock_userenv( { patron => $patron1 } );
1186
        borrowernumber => $patron1->borrowernumber,
1189
1187
        recalldate => Koha::DateUtils::dt_from_string,
1190
    my $recall1 = Koha::Recall->new(
1188
        biblionumber => $biblio->biblionumber,
1191
        {   borrowernumber    => $patron1->borrowernumber,
1189
        branchcode => $branchcode,
1192
            recalldate        => \'NOW()',
1190
        status => 'R',
1193
            biblionumber      => $biblio->biblionumber,
1191
        itemnumber => $item1->itemnumber,
1194
            branchcode        => $branchcode,
1192
        expirationdate => undef,
1195
            itemnumber        => $item1->itemnumber,
1193
        item_level_recall => 1
1196
            expirationdate    => undef,
1194
    })->store;
1197
            item_level_recall => 1
1195
    my $recall2 = Koha::Recall->new({
1198
        }
1196
        borrowernumber => $patron2->borrowernumber,
1199
    )->store;
1197
        recalldate => Koha::DateUtils::dt_from_string,
1200
    my $recall2 = Koha::Recall->new(
1198
        biblionumber => $biblio->biblionumber,
1201
        {   borrowernumber    => $patron2->borrowernumber,
1199
        branchcode => $branchcode,
1202
            recalldate        => \'NOW()',
1200
        status => 'R',
1203
            biblionumber      => $biblio->biblionumber,
1201
        itemnumber => $item1->itemnumber,
1204
            branchcode        => $branchcode,
1202
        expirationdate => undef,
1205
            itemnumber        => $item1->itemnumber,
1203
        item_level_recall =>1
1206
            expirationdate    => undef,
1204
    })->store;
1207
            item_level_recall => 1
1208
        }
1209
    )->store;
1205
1210
1206
    is( $item1->recall->borrowernumber, $patron1->borrowernumber, 'Correctly returns most relevant recall' );
1211
    is( $item1->recall->borrowernumber, $patron1->borrowernumber, 'Correctly returns most relevant recall' );
1207
1212
Lines 1274-1289 subtest 'Recalls tests' => sub { Link Here
1274
    C4::Circulation::AddIssue( $patron2->unblessed, $item1->barcode );
1279
    C4::Circulation::AddIssue( $patron2->unblessed, $item1->barcode );
1275
    is( $item1->can_be_recalled({ patron => $patron1 }), 1, "Can recall item" );
1280
    is( $item1->can_be_recalled({ patron => $patron1 }), 1, "Can recall item" );
1276
1281
1277
    $recall1 = Koha::Recall->new({
1282
    $recall1 = Koha::Recall->new(
1278
        borrowernumber => $patron1->borrowernumber,
1283
        {   borrowernumber    => $patron1->borrowernumber,
1279
        recalldate => Koha::DateUtils::dt_from_string,
1284
            recalldate        => \'NOW()',
1280
        biblionumber => $biblio->biblionumber,
1285
            biblionumber      => $biblio->biblionumber,
1281
        branchcode => $branchcode,
1286
            branchcode        => $branchcode,
1282
        status => 'R',
1287
            itemnumber        => undef,
1283
        itemnumber => undef,
1288
            expirationdate    => undef,
1284
        expirationdate => undef,
1289
            item_level_recall => 0
1285
        item_level_recall => 0
1290
        }
1286
    })->store;
1291
    )->store;
1287
1292
1288
    # Patron2 has Item1 checked out. Patron1 has placed a biblio-level recall on Biblio1, so check if Item1 can fulfill Patron1's recall.
1293
    # Patron2 has Item1 checked out. Patron1 has placed a biblio-level recall on Biblio1, so check if Item1 can fulfill Patron1's recall.
1289
1294
Lines 1313-1339 subtest 'Recalls tests' => sub { Link Here
1313
1318
1314
    # check_recalls tests
1319
    # check_recalls tests
1315
1320
1316
    $recall1 = Koha::Recall->new({
1321
    $recall1 = Koha::Recall->new(
1317
        borrowernumber => $patron2->borrowernumber,
1322
        {   borrowernumber    => $patron2->borrowernumber,
1318
        recalldate => Koha::DateUtils::dt_from_string,
1323
            recalldate        => \'NOW()',
1319
        biblionumber => $biblio->biblionumber,
1324
            biblionumber      => $biblio->biblionumber,
1320
        branchcode => $branchcode,
1325
            branchcode        => $branchcode,
1321
        status => 'R',
1326
            itemnumber        => $item1->itemnumber,
1322
        itemnumber => $item1->itemnumber,
1327
            expirationdate    => undef,
1323
        expirationdate => undef,
1328
            item_level_recall => 1
1324
        item_level_recall => 1
1329
        }
1325
    })->store;
1330
    )->store;
1326
    $recall2 = Koha::Recall->new({
1331
    $recall2 = Koha::Recall->new(
1327
        borrowernumber => $patron1->borrowernumber,
1332
        {   borrowernumber    => $patron1->borrowernumber,
1328
        recalldate => Koha::DateUtils::dt_from_string,
1333
            recalldate        => \'NOW()',
1329
        biblionumber => $biblio->biblionumber,
1334
            biblionumber      => $biblio->biblionumber,
1330
        branchcode => $branchcode,
1335
            branchcode        => $branchcode,
1331
        status => 'R',
1336
            itemnumber        => undef,
1332
        itemnumber => undef,
1337
            expirationdate    => undef,
1333
        expirationdate => undef,
1338
            item_level_recall => 0
1334
        item_level_recall => 0
1339
        }
1335
    })->store;
1340
    )->store;
1336
    $recall2->set_waiting({ item => $item1 });
1341
    $recall2->set_waiting( { item => $item1 } );
1337
1342
1338
    # return a waiting recall
1343
    # return a waiting recall
1339
    my $check_recall = $item1->check_recalls;
1344
    my $check_recall = $item1->check_recalls;
(-)a/t/db_dependent/Koha/Patron.t (-36 / +36 lines)
Lines 1060-1101 subtest 'recalls() tests' => sub { Link Here
1060
    my $biblio2 = $builder->build_object({ class => 'Koha::Biblios' });
1060
    my $biblio2 = $builder->build_object({ class => 'Koha::Biblios' });
1061
    my $item2 = $builder->build_object({ class => 'Koha::Items' }, { value => { biblionumber => $biblio2->biblionumber } });
1061
    my $item2 = $builder->build_object({ class => 'Koha::Items' }, { value => { biblionumber => $biblio2->biblionumber } });
1062
1062
1063
    Koha::Recall->new({
1063
    Koha::Recall->new(
1064
        biblionumber => $biblio1->biblionumber,
1064
        {   biblionumber      => $biblio1->biblionumber,
1065
        borrowernumber => $patron->borrowernumber,
1065
            borrowernumber    => $patron->borrowernumber,
1066
        itemnumber => $item1->itemnumber,
1066
            itemnumber        => $item1->itemnumber,
1067
        branchcode => $patron->branchcode,
1067
            branchcode        => $patron->branchcode,
1068
        recalldate => dt_from_string,
1068
            recalldate        => \'NOW()',
1069
        status => 'R',
1069
            item_level_recall => 1,
1070
        item_level_recall => 1,
1070
        }
1071
    })->store;
1071
    )->store;
1072
    Koha::Recall->new({
1072
    Koha::Recall->new(
1073
        biblionumber => $biblio2->biblionumber,
1073
        {   biblionumber      => $biblio2->biblionumber,
1074
        borrowernumber => $patron->borrowernumber,
1074
            borrowernumber    => $patron->borrowernumber,
1075
        itemnumber => $item2->itemnumber,
1075
            itemnumber        => $item2->itemnumber,
1076
        branchcode => $patron->branchcode,
1076
            branchcode        => $patron->branchcode,
1077
        recalldate => dt_from_string,
1077
            recalldate        => \'NOW()',
1078
        status => 'R',
1078
            item_level_recall => 1,
1079
        item_level_recall => 1,
1079
        }
1080
    })->store;
1080
    )->store;
1081
    Koha::Recall->new({
1081
    Koha::Recall->new(
1082
        biblionumber => $biblio1->biblionumber,
1082
        {   biblionumber      => $biblio1->biblionumber,
1083
        borrowernumber => $patron->borrowernumber,
1083
            borrowernumber    => $patron->borrowernumber,
1084
        itemnumber => undef,
1084
            itemnumber        => undef,
1085
        branchcode => $patron->branchcode,
1085
            branchcode        => $patron->branchcode,
1086
        recalldate => dt_from_string,
1086
            recalldate        => \'NOW()',
1087
        status => 'R',
1087
            item_level_recall => 0,
1088
        item_level_recall => 0,
1088
        }
1089
    })->store;
1089
    )->store;
1090
    my $recall = Koha::Recall->new({
1090
    my $recall = Koha::Recall->new(
1091
        biblionumber => $biblio1->biblionumber,
1091
        {   biblionumber      => $biblio1->biblionumber,
1092
        borrowernumber => $patron->borrowernumber,
1092
            borrowernumber    => $patron->borrowernumber,
1093
        itemnumber => undef,
1093
            itemnumber        => undef,
1094
        branchcode => $patron->branchcode,
1094
            branchcode        => $patron->branchcode,
1095
        recalldate => dt_from_string,
1095
            recalldate        => \'NOW()',
1096
        status => 'R',
1096
            item_level_recall => 0,
1097
        item_level_recall => 0,
1097
        }
1098
    })->store;
1098
    )->store;
1099
    $recall->set_cancelled;
1099
    $recall->set_cancelled;
1100
1100
1101
    is( $patron->recalls->count, 3, "Correctly gets this patron's active recalls" );
1101
    is( $patron->recalls->count, 3, "Correctly gets this patron's active recalls" );
(-)a/t/db_dependent/Koha/Recall.t (-11 / +8 lines)
Lines 71-77 my $recall1 = Koha::Recall->new({ Link Here
71
    recalldate => dt_from_string,
71
    recalldate => dt_from_string,
72
    biblionumber => $biblio1->biblionumber,
72
    biblionumber => $biblio1->biblionumber,
73
    branchcode => $branch1,
73
    branchcode => $branch1,
74
    status => 'R',
74
    status => 'requested',
75
    itemnumber => $item1->itemnumber,
75
    itemnumber => $item1->itemnumber,
76
    expirationdate => undef,
76
    expirationdate => undef,
77
    item_level_recall => 1
77
    item_level_recall => 1
Lines 82-102 is( $recall1->item->homebranch, $item1->homebranch, "Recall item relationship co Link Here
82
is( $recall1->patron->categorycode, $category1, "Recall patron relationship correctly linked" );
82
is( $recall1->patron->categorycode, $category1, "Recall patron relationship correctly linked" );
83
is( $recall1->library->branchname, Koha::Libraries->find( $branch1 )->branchname, "Recall library relationship correctly linked" );
83
is( $recall1->library->branchname, Koha::Libraries->find( $branch1 )->branchname, "Recall library relationship correctly linked" );
84
is( $recall1->checkout->itemnumber, $item1->itemnumber, "Recall checkout relationship correctly linked" );
84
is( $recall1->checkout->itemnumber, $item1->itemnumber, "Recall checkout relationship correctly linked" );
85
is( $recall1->requested, 1, "Recall has been requested" );
85
ok( $recall1->requested, "Recall has been requested" );
86
86
87
is( $recall1->should_be_overdue, 1, "Correctly calculated that recall should be marked overdue" );
87
is( $recall1->should_be_overdue, 1, "Correctly calculated that recall should be marked overdue" );
88
$recall1->set_overdue({ interface => 'COMMANDLINE' });
88
$recall1->set_overdue({ interface => 'COMMANDLINE' });
89
is( $recall1->overdue, 1, "Recall is overdue" );
89
ok( $recall1->overdue, "Recall is overdue" );
90
90
91
$recall1->set_cancelled;
91
$recall1->set_cancelled;
92
is( $recall1->cancelled, 1, "Recall is cancelled" );
92
ok( $recall1->cancelled, "Recall is cancelled" );
93
93
94
my $recall2 = Koha::Recall->new({
94
my $recall2 = Koha::Recall->new({
95
    borrowernumber => $patron1->borrowernumber,
95
    borrowernumber => $patron1->borrowernumber,
96
    recalldate => dt_from_string,
96
    recalldate => dt_from_string,
97
    biblionumber => $biblio1->biblionumber,
97
    biblionumber => $biblio1->biblionumber,
98
    branchcode => $branch1,
98
    branchcode => $branch1,
99
    status => 'R',
100
    itemnumber => $item1->itemnumber,
99
    itemnumber => $item1->itemnumber,
101
    expirationdate => undef,
100
    expirationdate => undef,
102
    item_level_recall => 1
101
    item_level_recall => 1
Lines 143-149 my $recall3 = Koha::Recall->new({ Link Here
143
    recalldate => dt_from_string,
142
    recalldate => dt_from_string,
144
    biblionumber => $biblio1->biblionumber,
143
    biblionumber => $biblio1->biblionumber,
145
    branchcode => $branch1,
144
    branchcode => $branch1,
146
    status => 'R',
147
    itemnumber => $item1->itemnumber,
145
    itemnumber => $item1->itemnumber,
148
    expirationdate => undef,
146
    expirationdate => undef,
149
    item_level_recall => 1
147
    item_level_recall => 1
Lines 151-165 my $recall3 = Koha::Recall->new({ Link Here
151
149
152
# test that recall gets T status
150
# test that recall gets T status
153
$recall3->start_transfer;
151
$recall3->start_transfer;
154
is( $recall3->in_transit, 1, "Recall is in transit" );
152
ok( $recall3->in_transit, "Recall is in transit" );
155
153
156
$recall3->revert_transfer;
154
$recall3->revert_transfer;
157
is( $recall3->requested, 1, "Recall transfer has been cancelled and the status reverted" );
155
ok( $recall3->requested, "Recall transfer has been cancelled and the status reverted" );
158
is( $recall3->itemnumber, $item1->itemnumber, "Item persists for item-level recall" );
156
is( $recall3->itemnumber, $item1->itemnumber, "Item persists for item-level recall" );
159
157
160
# for testing purposes, pretend the item gets checked out
158
# for testing purposes, pretend the item gets checked out
161
$recall3->set_finished;
159
$recall3->set_fulfilled;
162
is( $recall3->finished, 1, "Recall has been fulfilled" );
160
ok( $recall3->fulfilled, "Recall has been fulfilled" );
163
161
164
C4::Circulation::AddIssue( $patron2->unblessed, $item1->barcode );
162
C4::Circulation::AddIssue( $patron2->unblessed, $item1->barcode );
165
my $recall4 = Koha::Recall->new({
163
my $recall4 = Koha::Recall->new({
Lines 167-173 my $recall4 = Koha::Recall->new({ Link Here
167
    recalldate => dt_from_string,
165
    recalldate => dt_from_string,
168
    biblionumber => $biblio1->biblionumber,
166
    biblionumber => $biblio1->biblionumber,
169
    branchcode => $branch1,
167
    branchcode => $branch1,
170
    status => 'R',
171
    itemnumber => undef,
168
    itemnumber => undef,
172
    expirationdate => undef,
169
    expirationdate => undef,
173
    item_level_recall => 0,
170
    item_level_recall => 0,
(-)a/t/db_dependent/Koha/Recalls.t (-1 / +1 lines)
Lines 170-175 ok( $recall->cancelled, "Recall cancelled with move_recall" ); Link Here
170
});
170
});
171
$message = Koha::Recalls->move_recall({ recall_id => $recall->recall_id, item => $item2, borrowernumber => $patron1->borrowernumber });
171
$message = Koha::Recalls->move_recall({ recall_id => $recall->recall_id, item => $item2, borrowernumber => $patron1->borrowernumber });
172
$recall = Koha::Recalls->find( $recall->recall_id );
172
$recall = Koha::Recalls->find( $recall->recall_id );
173
ok( $recall->finished, "Recall fulfilled with move_recall" );
173
ok( $recall->fulfilled, "Recall fulfilled with move_recall" );
174
174
175
$schema->storage->txn_rollback();
175
$schema->storage->txn_rollback();
(-)a/t/db_dependent/XSLT.t (-2 lines)
Lines 147-153 subtest 'buildKohaItemsNamespace status tests' => sub { Link Here
147
        biblionumber    => $item->biblionumber,
147
        biblionumber    => $item->biblionumber,
148
        itemnumber      => $item->itemnumber,
148
        itemnumber      => $item->itemnumber,
149
        branchcode      => $item->holdingbranch,
149
        branchcode      => $item->holdingbranch,
150
        status          => 'R',
151
    }});
150
    }});
152
    $recall->set_waiting;
151
    $recall->set_waiting;
153
    $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
152
    $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
154
- 

Return to bug 19532