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

(-)a/C4/Circulation.pm (-1 / +1 lines)
Lines 1125-1131 sub CanBookBeIssued { Link Here
1125
    # Only bother doing this if UseRecalls is enabled and the item is recallable
1125
    # Only bother doing this if UseRecalls is enabled and the item is recallable
1126
    # Don't look at recalls that are in transit
1126
    # Don't look at recalls that are in transit
1127
    if ( C4::Context->preference('UseRecalls') and $item_object->can_be_waiting_recall ) {
1127
    if ( C4::Context->preference('UseRecalls') and $item_object->can_be_waiting_recall ) {
1128
        my @recalls = $biblio->recalls->as_list;
1128
        my @recalls = $biblio->recalls({},{ order_by => { -asc => 'recalldate' } })->filter_by_current->as_list;
1129
1129
1130
        foreach my $r ( @recalls ) {
1130
        foreach my $r ( @recalls ) {
1131
            if ( $r->itemnumber and
1131
            if ( $r->itemnumber and
(-)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 => 'overdue' })->as_list;
263
        my @recalls = Koha::Recalls->search({ biblionumber => $item->{biblionumber}, 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/Reserves.pm (-1 / +1 lines)
Lines 423-429 sub CanItemBeReserved { Link Here
423
423
424
    # check if a recall exists on this item from this borrower
424
    # check if a recall exists on this item from this borrower
425
    return { status => 'recall' }
425
    return { status => 'recall' }
426
      if Koha::Recalls->search({ borrowernumber => $patron->borrowernumber, itemnumber => $item->itemnumber, old => undef })->count;
426
      if $patron->recalls->filter_by_current->search({ itemnumber => $item->itemnumber })->count;
427
427
428
    my $controlbranch = C4::Context->preference('ReservesControlBranch');
428
    my $controlbranch = C4::Context->preference('ReservesControlBranch');
429
429
(-)a/Koha/Biblio.pm (-13 / +5 lines)
Lines 1166-1186 sub get_marc_host { Link Here
1166
1166
1167
    my @recalls = $biblio->recalls;
1167
    my @recalls = $biblio->recalls;
1168
1168
1169
Return all active recalls attached to this biblio, sorted by oldest first
1169
Return recalls linked to this biblio
1170
1170
1171
=cut
1171
=cut
1172
1172
1173
sub recalls {
1173
sub recalls {
1174
    my ( $self, $params ) = @_;
1174
    my ( $self ) = @_;
1175
1175
    return Koha::Recalls->_new_from_dbic( scalar $self->_result->recalls );
1176
    my $args = {
1177
        biblionumber => $self->biblionumber,
1178
        old => undef,
1179
    };
1180
    $args->{ borrowernumber } = $params->{ borrowernumber } if $params->{ borrowernumber };
1181
1182
    my $recalls_rs = $self->_result->recalls->search( $args, { order_by => { -asc => 'recalldate' } });
1183
    return Koha::Recalls->_new_from_dbic( $recalls_rs );
1184
}
1176
}
1185
1177
1186
=head3 can_be_recalled
1178
=head3 can_be_recalled
Lines 1254-1263 sub can_be_recalled { Link Here
1254
1246
1255
    if ( $patron ) {
1247
    if ( $patron ) {
1256
        # check borrower has not reached open recalls allowed limit
1248
        # check borrower has not reached open recalls allowed limit
1257
        return 0 if ( $patron->recalls->count >= $recalls_allowed );
1249
        return 0 if ( $patron->recalls->filter_by_current->count >= $recalls_allowed );
1258
1250
1259
        # check borrower has not reached open recalls allowed per record limit
1251
        # check borrower has not reached open recalls allowed per record limit
1260
        return 0 if ( $patron->recalls({ biblionumber => $self->biblionumber })->count >= $recalls_per_record );
1252
        return 0 if ( $patron->recalls->filter_by_current->search({ biblionumber => $self->biblionumber })->count >= $recalls_per_record );
1261
1253
1262
        # check if any of the items under this biblio are already checked out by this borrower
1254
        # check if any of the items under this biblio are already checked out by this borrower
1263
        return 0 if ( Koha::Checkouts->search({ itemnumber => [ @all_itemnumbers ], borrowernumber => $patron->borrowernumber })->count > 0 );
1255
        return 0 if ( Koha::Checkouts->search({ itemnumber => [ @all_itemnumbers ], borrowernumber => $patron->borrowernumber })->count > 0 );
(-)a/Koha/Item.pm (-6 / +9 lines)
Lines 1517-1529 sub can_be_recalled { Link Here
1517
1517
1518
    if ( $patron ) {
1518
    if ( $patron ) {
1519
        # check borrower has not reached open recalls allowed limit
1519
        # check borrower has not reached open recalls allowed limit
1520
        return 0 if ( $patron->recalls->count >= $rule->{recalls_allowed} );
1520
        return 0 if ( $patron->recalls->filter_by_current->count >= $rule->{recalls_allowed} );
1521
1521
1522
        # check borrower has not reach open recalls allowed per record limit
1522
        # check borrower has not reach open recalls allowed per record limit
1523
        return 0 if ( $patron->recalls({ biblionumber => $self->biblionumber })->count >= $rule->{recalls_per_record} );
1523
        return 0 if ( $patron->recalls->filter_by_current->search({ biblionumber => $self->biblionumber })->count >= $rule->{recalls_per_record} );
1524
1524
1525
        # check if this patron has already recalled this item
1525
        # check if this patron has already recalled this item
1526
        return 0 if ( Koha::Recalls->search({ itemnumber => $self->itemnumber, borrowernumber => $patron->borrowernumber, old => undef })->count > 0 );
1526
        return 0 if ( Koha::Recalls->search({ itemnumber => $self->itemnumber, borrowernumber => $patron->borrowernumber })->filter_by_current->count > 0 );
1527
1527
1528
        # check if this patron has already checked out this item
1528
        # check if this patron has already checked out this item
1529
        return 0 if ( Koha::Checkouts->search({ itemnumber => $self->itemnumber, borrowernumber => $patron->borrowernumber })->count > 0 );
1529
        return 0 if ( Koha::Checkouts->search({ itemnumber => $self->itemnumber, borrowernumber => $patron->borrowernumber })->count > 0 );
Lines 1608-1616 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 =
1611
    my @recalls = Koha::Recalls->search(
1612
      Koha::Recalls->search( { biblionumber => $self->biblionumber, itemnumber => [ $self->itemnumber, undef ], status => [ 'requested', 'overdue', 'waiting', 'in_transit' ] },
1612
        {   biblionumber => $self->biblionumber,
1613
        { order_by => { -asc => 'recalldate' } } )->as_list;
1613
            itemnumber   => [ $self->itemnumber, undef ]
1614
        },
1615
        { order_by => { -asc => 'recalldate' } }
1616
    )->filter_by_current->as_list;
1614
1617
1615
    my $recall;
1618
    my $recall;
1616
    # iterate through relevant recalls to find the best one.
1619
    # iterate through relevant recalls to find the best one.
(-)a/Koha/Patron.pm (-13 / +3 lines)
Lines 2058-2081 sub safe_to_delete { Link Here
2058
2058
2059
    my $recalls = $patron->recalls;
2059
    my $recalls = $patron->recalls;
2060
2060
2061
    my $recalls = $patron->recalls({ biblionumber => $biblionumber });
2061
Return the patron's recalls.
2062
2063
Return the patron's active recalls - total, or on a specific biblio
2064
2062
2065
=cut
2063
=cut
2066
2064
2067
sub recalls {
2065
sub recalls {
2068
    my ( $self, $params ) = @_;
2066
    my ( $self ) = @_;
2069
2070
    my $biblionumber = $params->{biblionumber};
2071
2072
    my $recalls_rs = Koha::Recalls->search({ borrowernumber => $self->borrowernumber, old => undef });
2073
2074
    if ( $biblionumber ) {
2075
        $recalls_rs = Koha::Recalls->search({ borrowernumber => $self->borrowernumber, old => undef, biblionumber => $biblionumber });
2076
    }
2077
2067
2078
    return $recalls_rs;
2068
    return Koha::Recalls->search({ borrowernumber => $self->borrowernumber });
2079
}
2069
}
2080
2070
2081
=head2 Internal methods
2071
=head2 Internal methods
(-)a/Koha/Recalls.pm (+45 lines)
Lines 35-40 Koha::Recalls - Koha Recalls Object set class Link Here
35
35
36
=head2 Class methods
36
=head2 Class methods
37
37
38
=head3 filter_by_current
39
40
    my $current_recalls = $recalls->filter_by_current;
41
42
Returns a new resultset, filtering out finished recalls.
43
44
=cut
45
46
sub filter_by_current {
47
    my ($self) = @_;
48
49
    return $self->search(
50
        {
51
            status => [
52
                'in_transit',
53
                'overdue',
54
                'requested',
55
                'waiting',
56
            ]
57
        }
58
    );
59
}
60
61
=head3 filter_by_finished
62
63
    my $finished_recalls = $recalls->filter_by_finished;
64
65
Returns a new resultset, filtering out current recalls.
66
67
=cut
68
69
sub filter_by_finished {
70
    my ($self) = @_;
71
72
    return $self->search(
73
        {
74
            status => [
75
                'cancelled',
76
                'expired',
77
                'fulfilled',
78
            ]
79
        }
80
    );
81
}
82
38
=head3 add_recall
83
=head3 add_recall
39
84
40
    my ( $recall, $due_interval, $due_date ) = Koha::Recalls->add_recall({
85
    my ( $recall, $due_interval, $due_date ) = Koha::Recalls->add_recall({
(-)a/circ/circulation.pl (-1 / +1 lines)
Lines 446-452 if ($patron) { Link Here
446
    $template->param(
446
    $template->param(
447
        holds_count  => $holds->count(),
447
        holds_count  => $holds->count(),
448
        WaitingHolds => $waiting_holds,
448
        WaitingHolds => $waiting_holds,
449
        recalls => $patron->recalls,
449
        recalls => $patron->recalls->filter_by_current->search({},->search({},{ order_by => { -asc => 'recalldate' } })),
450
        specific_patron => 1,
450
        specific_patron => 1,
451
    );
451
    );
452
}
452
}
(-)a/members/moremember.pl (-1 / +1 lines)
Lines 273-279 $template->param( Link Here
273
    files => Koha::Patron::Files->new( borrowernumber => $borrowernumber ) ->GetFilesInfo(),
273
    files => Koha::Patron::Files->new( borrowernumber => $borrowernumber ) ->GetFilesInfo(),
274
    #debarments                => scalar GetDebarments({ borrowernumber => $borrowernumber }),
274
    #debarments                => scalar GetDebarments({ borrowernumber => $borrowernumber }),
275
    has_modifications         => $has_modifications,
275
    has_modifications         => $has_modifications,
276
    recalls         => $patron->recalls,
276
    recalls         => $patron->recalls({},{ order_by => { -asc => 'recalldate' } })->filter_by_current,
277
    specific_patron => 1,
277
    specific_patron => 1,
278
);
278
);
279
279
(-)a/opac/opac-recall.pl (-1 / +1 lines)
Lines 46-52 if ( C4::Context->preference('UseRecalls') ) { Link Here
46
    my $items = Koha::Items->search({ biblionumber => $biblionumber })->as_list;
46
    my $items = Koha::Items->search({ biblionumber => $biblionumber })->as_list;
47
47
48
    # check if already recalled
48
    # check if already recalled
49
    my $recalled = $biblio->recalls({ borrowernumber => $borrowernumber })->count;
49
    my $recalled = $biblio->recalls->filter_by_current->search({ borrowernumber => $borrowernumber })->count;
50
    if ( defined $recalled and $recalled > 0 ) {
50
    if ( defined $recalled and $recalled > 0 ) {
51
        my $recalls_per_record = Koha::CirculationRules->get_effective_rule({
51
        my $recalls_per_record = Koha::CirculationRules->get_effective_rule({
52
            categorycode => $patron->categorycode,
52
            categorycode => $patron->categorycode,
(-)a/t/db_dependent/Koha/Biblio.t (-5 / +5 lines)
Lines 885-891 subtest 'get_marc_authors() tests' => sub { Link Here
885
885
886
subtest 'Recalls tests' => sub {
886
subtest 'Recalls tests' => sub {
887
887
888
    plan tests => 12;
888
    plan tests => 13;
889
889
890
    $schema->storage->txn_begin;
890
    $schema->storage->txn_begin;
891
891
Lines 929-942 subtest 'Recalls tests' => sub { Link Here
929
        }
929
        }
930
    )->store;
930
    )->store;
931
931
932
    my $recalls_count = $biblio->recalls->count;
932
    my $recalls = $biblio->recalls;
933
    is( $recalls_count, 3, 'Correctly get number of active recalls for biblio' );
933
    is( $recalls->count, 3, 'Correctly get number of recalls for biblio' );
934
934
935
    $recall1->set_cancelled;
935
    $recall1->set_cancelled;
936
    $recall2->set_expired({ interface => 'COMMANDLINE' });
936
    $recall2->set_expired({ interface => 'COMMANDLINE' });
937
937
938
    $recalls_count = $biblio->recalls->count;
938
    is( $recalls->count, 3, 'Correctly get number of recalls for biblio' );
939
    is( $recalls_count, 1, 'Correctly get number of active recalls for biblio' );
939
    is( $recalls->filter_by_current->count, 1, 'Correctly get number of active recalls for biblio' );
940
940
941
    t::lib::Mocks::mock_preference('UseRecalls', 0);
941
    t::lib::Mocks::mock_preference('UseRecalls', 0);
942
    is( $biblio->can_be_recalled({ patron => $patron1 }), 0, "Can't recall with UseRecalls disabled" );
942
    is( $biblio->can_be_recalled({ patron => $patron1 }), 0, "Can't recall with UseRecalls disabled" );
(-)a/t/db_dependent/Koha/Patron.t (-3 / +7 lines)
Lines 1053-1059 subtest 'messages' => sub { Link Here
1053
1053
1054
subtest 'recalls() tests' => sub {
1054
subtest 'recalls() tests' => sub {
1055
1055
1056
    plan tests => 2;
1056
    plan tests => 3;
1057
1058
    $schema->storage->txn_begin;
1059
1057
    my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
1060
    my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
1058
    my $biblio1 = $builder->build_object({ class => 'Koha::Biblios' });
1061
    my $biblio1 = $builder->build_object({ class => 'Koha::Biblios' });
1059
    my $item1 = $builder->build_object({ class => 'Koha::Items' }, { value => { biblionumber => $biblio1->biblionumber } });
1062
    my $item1 = $builder->build_object({ class => 'Koha::Items' }, { value => { biblionumber => $biblio1->biblionumber } });
Lines 1098-1105 subtest 'recalls() tests' => sub { Link Here
1098
    )->store;
1101
    )->store;
1099
    $recall->set_cancelled;
1102
    $recall->set_cancelled;
1100
1103
1101
    is( $patron->recalls->count, 3, "Correctly gets this patron's active recalls" );
1104
    is( $patron->recalls->count,                                                                          4, "Correctly gets this patron's recalls" );
1102
    is( $patron->recalls({ biblionumber => $biblio1->biblionumber })->count, 2, "Correctly gets this patron's active recalls on a specific biblio" );
1105
    is( $patron->recalls->filter_by_current->count,                                                       3, "Correctly gets this patron's active recalls" );
1106
    is( $patron->recalls->filter_by_current->search( { biblionumber => $biblio1->biblionumber } )->count, 2, "Correctly gets this patron's active recalls on a specific biblio" );
1103
1107
1104
    $schema->storage->txn_rollback;
1108
    $schema->storage->txn_rollback;
1105
};
1109
};
(-)a/t/db_dependent/Koha/Recalls.t (-2 / +50 lines)
Lines 17-23 Link Here
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
19
20
use Test::More tests => 19;
20
use Test::More tests => 20;
21
use t::lib::TestBuilder;
21
use t::lib::TestBuilder;
22
use t::lib::Mocks;
22
use t::lib::Mocks;
23
23
Lines 173-175 $recall = Koha::Recalls->find( $recall->recall_id ); Link Here
173
ok( $recall->fulfilled, "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();
176
- 
176
177
subtest 'filter_by_current() and filter_by_finished() tests' => sub {
178
179
    plan tests => 10;
180
181
    $schema->storage->txn_begin;
182
183
    my $in_transit = $builder->build_object( { class => 'Koha::Recalls', value => { status => 'in_transit' } } );
184
    my $overdue    = $builder->build_object( { class => 'Koha::Recalls', value => { status => 'overdue' } } );
185
    my $requested  = $builder->build_object( { class => 'Koha::Recalls', value => { status => 'requested' } } );
186
    my $waiting    = $builder->build_object( { class => 'Koha::Recalls', value => { status => 'waiting' } } );
187
    my $cancelled  = $builder->build_object( { class => 'Koha::Recalls', value => { status => 'cancelled' } } );
188
    my $expired    = $builder->build_object( { class => 'Koha::Recalls', value => { status => 'expired' } } );
189
    my $fulfilled  = $builder->build_object( { class => 'Koha::Recalls', value => { status => 'fulfilled' } } );
190
191
    my $recalls = Koha::Recalls->search(
192
        {
193
            recall_id => [
194
                $in_transit->id,
195
                $overdue->id,
196
                $requested->id,
197
                $waiting->id,
198
                $cancelled->id,
199
                $expired->id,
200
                $fulfilled->id,
201
            ]
202
        },
203
        { order_by => [ 'recall_id' ] }
204
    );
205
206
    is( $recalls->count, 7, 'Resultset count is correct' );
207
208
    my $current_recalls = $recalls->filter_by_current;
209
    is( $current_recalls->count, 4, 'Current recalls count correct' );
210
211
    is( $current_recalls->next->status, 'in_transit', 'Resultset correctly includes in_transit recall');
212
    is( $current_recalls->next->status, 'overdue', 'Resultset correctly includes overdue recall');
213
    is( $current_recalls->next->status, 'requested', 'Resultset correctly includes requested recall');
214
    is( $current_recalls->next->status, 'waiting', 'Resultset correctly includes waiting recall');
215
216
    my $finished_recalls = $recalls->filter_by_finished;
217
    is( $finished_recalls->count, 3, 'Finished recalls count correct' );
218
219
    is( $finished_recalls->next->status, 'cancelled', 'Resultset correctly includes cancelled recall');
220
    is( $finished_recalls->next->status, 'expired', 'Resultset correctly includes expired recall');
221
    is( $finished_recalls->next->status, 'fulfilled', 'Resultset correctly includes fulfilled recall');
222
223
    $schema->storage->txn_rollback;
224
};

Return to bug 19532