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

(-)a/Koha/ArticleRequest.pm (+5 lines)
Lines 27-32 use Koha::Items; Link Here
27
use Koha::Libraries;
27
use Koha::Libraries;
28
use Koha::DateUtils qw( dt_from_string );
28
use Koha::DateUtils qw( dt_from_string );
29
use Koha::ArticleRequest::Status;
29
use Koha::ArticleRequest::Status;
30
use Koha::Exceptions::ArticleRequest;
30
31
31
use base qw(Koha::Object);
32
use base qw(Koha::Object);
32
33
Lines 51-56 Marks the article as requested. Send a notification if appropriate. Link Here
51
sub request {
52
sub request {
52
    my ($self) = @_;
53
    my ($self) = @_;
53
54
55
    Koha::Exceptions::ArticleRequest::LimitReached->throw(
56
        error => 'Patron cannot request more articles for today'
57
    ) unless $self->borrower->can_request_article;
58
54
    $self->status(Koha::ArticleRequest::Status::Requested);
59
    $self->status(Koha::ArticleRequest::Status::Requested);
55
    $self->SUPER::store();
60
    $self->SUPER::store();
56
    $self->notify();
61
    $self->notify();
(-)a/Koha/Exceptions/ArticleRequest.pm (+46 lines)
Line 0 Link Here
1
package Koha::Exceptions::ArticleRequest;
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it
6
# under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 3 of the License, or
8
# (at your option) any later version.
9
#
10
# Koha is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with Koha; if not, see <http://www.gnu.org/licenses>.
17
18
use Modern::Perl;
19
20
use Exception::Class (
21
    'Koha::Exceptions::ArticleRequest' => {
22
        description => 'Something went wrong!',
23
    },
24
    'Koha::Exceptions::ArticleRequest::LimitReached' => {
25
        isa         => 'Koha::Exceptions::ArticleRequest',
26
        description => 'Article request limit was reached'
27
    },
28
);
29
30
=head1 NAME
31
32
Koha::Exceptions::ArticleRequest - Base class for ArticleRequest exceptions
33
34
=head1 Exceptions
35
36
=head2 Koha::Exceptions::ArticleRequest
37
38
Generic ArticleRequest exception
39
40
=head2 Koha::Exceptions::ArticleRequest::LimitReached
41
42
Exception to be used when the article request limit has been reached.
43
44
=cut
45
46
1;
(-)a/Koha/Patron.pm (+23 lines)
Lines 958-963 sub move_to_deleted { Link Here
958
    return Koha::Database->new->schema->resultset('Deletedborrower')->create($patron_infos);
958
    return Koha::Database->new->schema->resultset('Deletedborrower')->create($patron_infos);
959
}
959
}
960
960
961
=head3 can_request_article
962
963
my $can_request = $borrower->can_request_article
964
965
Returns true if patron can request articles
966
967
=cut
968
969
sub can_request_article {
970
    my ($self) = @_;
971
    my $limit = $self->category->article_request_limit;
972
973
    return 1 unless defined $limit;
974
975
    my $dtf = Koha::Database->new->schema->storage->datetime_parser;
976
    my $compdate = dt_from_string->add( days => -1 );
977
    my $count = Koha::ArticleRequests->search([
978
        { borrowernumber => $self->borrowernumber, status => ['REQUESTED','PENDING','PROCESSING'] },
979
        { borrowernumber => $self->borrowernumber, status => 'COMPLETED', updated_on => { '>', $dtf->format_date($compdate) }},
980
    ])->count;
981
    return $count < $limit ? 1 : 0;
982
}
983
961
=head3 article_requests
984
=head3 article_requests
962
985
963
my @requests = $borrower->article_requests();
986
my @requests = $borrower->article_requests();
(-)a/circ/request-article.pl (-17 / +31 lines)
Lines 27-32 use C4::Serials qw( CountSubscriptionFromBiblionumber ); Link Here
27
use Koha::Biblios;
27
use Koha::Biblios;
28
use Koha::Patrons;
28
use Koha::Patrons;
29
use Koha::ArticleRequests;
29
use Koha::ArticleRequests;
30
use Try::Tiny;
30
31
31
my $cgi = CGI->new;
32
my $cgi = CGI->new;
32
33
Lines 68-90 if ( $action eq 'create' ) { Link Here
68
    my $patron_notes = $cgi->param('patron_notes') || undef;
69
    my $patron_notes = $cgi->param('patron_notes') || undef;
69
    my $format       = $cgi->param('format')       || undef;
70
    my $format       = $cgi->param('format')       || undef;
70
71
71
    my $ar = Koha::ArticleRequest->new(
72
    try {
72
        {
73
        my $ar = Koha::ArticleRequest->new(
73
            borrowernumber => $borrowernumber,
74
            {
74
            biblionumber   => $biblionumber,
75
                borrowernumber => $borrowernumber,
75
            branchcode     => $branchcode,
76
                biblionumber   => $biblionumber,
76
            itemnumber     => $itemnumber,
77
                branchcode     => $branchcode,
77
            title          => $title,
78
                itemnumber     => $itemnumber,
78
            author         => $author,
79
                title          => $title,
79
            volume         => $volume,
80
                author         => $author,
80
            issue          => $issue,
81
                volume         => $volume,
81
            date           => $date,
82
                issue          => $issue,
82
            pages          => $pages,
83
                date           => $date,
83
            chapters       => $chapters,
84
                pages          => $pages,
84
            patron_notes   => $patron_notes,
85
                chapters       => $chapters,
85
            format         => $format,
86
                patron_notes   => $patron_notes,
86
        }
87
                format         => $format,
87
    )->store();
88
            }
89
        )->store();
90
    } catch {
91
        $template->param(
92
            error_message => $_->{message}
93
        );
94
    };
88
95
89
}
96
}
90
97
Lines 109-114 if ( !$patron && $patron_cardnumber ) { Link Here
109
    }
116
    }
110
}
117
}
111
118
119
if( $patron && !$patron->can_request_article) {
120
    $patron = undef;
121
    $template->param(
122
        error_message => 'Patron cannot request more articles for today'
123
    );
124
}
125
112
$template->param(
126
$template->param(
113
    biblio => $biblio,
127
    biblio => $biblio,
114
    patron => $patron,
128
    patron => $patron,
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/request-article.tt (+5 lines)
Lines 46-51 Link Here
46
            <main>
46
            <main>
47
47
48
                    <h1>Request article from [% INCLUDE 'biblio-title.inc' link = 1 %]</h1>
48
                    <h1>Request article from [% INCLUDE 'biblio-title.inc' link = 1 %]</h1>
49
                    [% IF error_message %]
50
                        <div class="dialog alert">
51
                            <p>[% error_message | html %]</p>
52
                        </div>
53
                    [% END %]
49
                    [% IF no_patrons_found %]
54
                    [% IF no_patrons_found %]
50
                        <div class="dialog alert">
55
                        <div class="dialog alert">
51
                            <h3>Patron not found</h3>
56
                            <h3>Patron not found</h3>
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-request-article.tt (-1 / +6 lines)
Lines 33-39 Link Here
33
    <div class="container-fluid maincontent">
33
    <div class="container-fluid maincontent">
34
        <div class="row">
34
        <div class="row">
35
            <div class="col">
35
            <div class="col">
36
                [% IF biblio.can_article_request( patron ) %]
36
                [% IF !error_message && biblio.can_article_request( patron ) %]
37
                    <h1>Place article request for [% biblio.title | html %]</h1>
37
                    <h1>Place article request for [% biblio.title | html %]</h1>
38
                    [% IF ( disclaimer && !action) %]
38
                    [% IF ( disclaimer && !action) %]
39
                        <div class="alert alert-warning">
39
                        <div class="alert alert-warning">
Lines 216-221 Link Here
216
                            <input type="submit" class="btn btn-primary" value="Place request" />
216
                            <input type="submit" class="btn btn-primary" value="Place request" />
217
                        </form>
217
                        </form>
218
                    [% END %]
218
                    [% END %]
219
                [% ELSIF error_message %]
220
                    <h1 class="title">[% biblio.title | html %]</h1>
221
                    <div class="alert alert-info">
222
                        [% error_message | html %]
223
                    </div>
219
                [% ELSE %]
224
                [% ELSE %]
220
                    <h1 class="title">[% biblio.title | html %]</h1>
225
                    <h1 class="title">[% biblio.title | html %]</h1>
221
                    <div class="alert alert-info">
226
                    <div class="alert alert-info">
(-)a/opac/opac-request-article.pl (-20 / +34 lines)
Lines 26-31 use C4::Output qw( output_html_with_http_headers ); Link Here
26
26
27
use Koha::Biblios;
27
use Koha::Biblios;
28
use Koha::Patrons;
28
use Koha::Patrons;
29
use Try::Tiny;
29
30
30
my $cgi = CGI->new;
31
my $cgi = CGI->new;
31
32
Lines 59-84 if ( $action eq 'create' ) { Link Here
59
    my $patron_notes = $cgi->param('patron_notes') || undef;
60
    my $patron_notes = $cgi->param('patron_notes') || undef;
60
    my $format       = $cgi->param('format')       || undef;
61
    my $format       = $cgi->param('format')       || undef;
61
62
62
    my $ar = Koha::ArticleRequest->new(
63
    try {
63
        {
64
        my $ar = Koha::ArticleRequest->new(
64
            borrowernumber => $borrowernumber,
65
            {
65
            biblionumber   => $biblionumber,
66
                borrowernumber => $borrowernumber,
66
            branchcode     => $branchcode,
67
                biblionumber   => $biblionumber,
67
            itemnumber     => $itemnumber,
68
                branchcode     => $branchcode,
68
            title          => $title,
69
                itemnumber     => $itemnumber,
69
            author         => $author,
70
                title          => $title,
70
            volume         => $volume,
71
                author         => $author,
71
            issue          => $issue,
72
                volume         => $volume,
72
            date           => $date,
73
                issue          => $issue,
73
            pages          => $pages,
74
                date           => $date,
74
            chapters       => $chapters,
75
                pages          => $pages,
75
            patron_notes   => $patron_notes,
76
                chapters       => $chapters,
76
            format         => $format,
77
                patron_notes   => $patron_notes,
77
        }
78
                format         => $format,
78
    )->store();
79
            }
79
80
        )->store();
80
    print $cgi->redirect("/cgi-bin/koha/opac-user.pl#opac-user-article-requests");
81
81
    exit;
82
        print $cgi->redirect("/cgi-bin/koha/opac-user.pl#opac-user-article-requests");
83
        exit;
84
    } catch {
85
        exit unless $_->[0] && $_->[0] eq 'EXIT';
86
        $template->param(
87
            error_message => $_->{message}
88
        );
89
    };
82
# Should we redirect?
90
# Should we redirect?
83
}
91
}
84
elsif ( !$action && C4::Context->preference('ArticleRequestsOpacHostRedirection') ) {
92
elsif ( !$action && C4::Context->preference('ArticleRequestsOpacHostRedirection') ) {
Lines 96-101 elsif ( !$action && C4::Context->preference('ArticleRequestsOpacHostRedirection' Link Here
96
104
97
my $patron = Koha::Patrons->find($borrowernumber);
105
my $patron = Koha::Patrons->find($borrowernumber);
98
106
107
if(!$patron->can_request_article) {
108
    $template->param(
109
        error_message => 'You cannot request more articles for today'
110
    );
111
}
112
99
$template->param(
113
$template->param(
100
    biblio => $biblio,
114
    biblio => $biblio,
101
    patron => $patron,
115
    patron => $patron,
(-)a/t/db_dependent/ArticleRequests.t (-91 lines)
Lines 252-346 subtest 'may_article_request' => sub { Link Here
252
    $cache->clear_from_cache( Koha::CirculationRules::GUESSED_ITEMTYPES_KEY );
252
    $cache->clear_from_cache( Koha::CirculationRules::GUESSED_ITEMTYPES_KEY );
253
};
253
};
254
254
255
256
subtest 'article request limit' => sub {
257
  plan tests => 12;
258
259
  t::lib::Mocks::mock_preference('ArticleRequests', 1);
260
261
  my $item = $builder->build_sample_item;
262
263
  my $category = $builder->build_object(
264
    {
265
      class => 'Koha::Patron::Categories',
266
      value => {
267
        article_request_limit => 1
268
      }
269
    }
270
  );
271
  my $patron   = $builder->build_object(
272
    {
273
      class => 'Koha::Patrons',
274
      value => {
275
        categorycode => $category->categorycode
276
      },
277
    }
278
  );
279
  $patron->article_requests->delete();
280
281
  is($patron->can_request_article, 1, 'Patron can request more articles');
282
283
  my $article_request_1 = Koha::ArticleRequest->new(
284
    {
285
      borrowernumber => $patron->id,
286
      biblionumber   => $item->biblionumber,
287
      itemnumber     => $item->itemnumber,
288
      title          => 'an article request',
289
    }
290
  )->store();
291
292
  is($patron->can_request_article, 0, 'Patron cannot request more articles');
293
  is($patron->article_requests->count, 1, 'There is one current article request');
294
295
  try {
296
    Koha::ArticleRequest->new(
297
      {
298
        borrowernumber => $patron->id,
299
        biblionumber   => $item->biblionumber,
300
        itemnumber     => $item->itemnumber,
301
        title          => 'an second article request',
302
      }
303
    )->store();
304
  }
305
  catch {
306
    is(ref($_), 'Koha::Exceptions::ArticleRequest::LimitReached', 'Limit reached thrown');
307
  };
308
309
  is($patron->can_request_article, 0, 'Patron cannot request more articles');
310
  is($patron->article_requests->count, 1, 'There is still one article request');
311
312
  $article_request_1->created_on(dt_from_string->add(days => -1))->store();
313
314
  is($patron->can_request_article, 1, 'Patron can request more articles');
315
316
  my $article_request_3 = Koha::ArticleRequest->new(
317
    {
318
      borrowernumber => $patron->id,
319
      biblionumber   => $item->biblionumber,
320
      itemnumber     => $item->itemnumber,
321
      title          => 'an third article request',
322
    }
323
  )->store();
324
325
  is($patron->can_request_article, 0, 'Patron cannot request more articles');
326
  is($patron->article_requests->count, 2, 'There are 2 article requests');
327
328
  $article_request_3->cancel();
329
330
  is($patron->can_request_article, 1, 'Patron can request more articles');
331
332
  Koha::ArticleRequest->new(
333
    {
334
      borrowernumber => $patron->id,
335
      biblionumber   => $item->biblionumber,
336
      itemnumber     => $item->itemnumber,
337
      title          => 'an fourth article request',
338
    }
339
  )->store();
340
341
  is($patron->can_request_article, 0, 'Patron cannot request more articles');
342
  is($patron->article_requests->count, 3, 'There are 3 current article requests');
343
344
};
345
346
$schema->storage->txn_rollback();
255
$schema->storage->txn_rollback();
(-)a/t/db_dependent/Koha/Patron.t (-2 / +116 lines)
Lines 19-30 Link Here
19
19
20
use Modern::Perl;
20
use Modern::Perl;
21
21
22
use Test::More tests => 8;
22
use Test::More tests => 9;
23
use Test::Exception;
23
use Test::Exception;
24
use Test::Warn;
24
use Test::Warn;
25
25
26
use Koha::Database;
26
use Koha::Database;
27
use Koha::DateUtils qw(dt_from_string);
27
use Koha::DateUtils qw(dt_from_string);
28
use Koha::ArticleRequests;
28
use Koha::Patrons;
29
use Koha::Patrons;
29
use Koha::Patron::Relationships;
30
use Koha::Patron::Relationships;
30
31
Lines 716-718 subtest 'can_log_into() tests' => sub { Link Here
716
717
717
    $schema->storage->txn_rollback;
718
    $schema->storage->txn_rollback;
718
};
719
};
719
- 
720
721
subtest 'can_request_article() tests' => sub {
722
723
    plan tests => 13;
724
725
    $schema->storage->txn_begin;
726
727
    t::lib::Mocks::mock_preference( 'ArticleRequests', 1 );
728
729
    my $item = $builder->build_sample_item;
730
731
    my $category = $builder->build_object(
732
        {
733
            class => 'Koha::Patron::Categories',
734
            value => {
735
                article_request_limit => 1
736
            }
737
        }
738
    );
739
    my $patron = $builder->build_object(
740
        {
741
            class => 'Koha::Patrons',
742
            value => {
743
                categorycode => $category->categorycode
744
            },
745
        }
746
    );
747
748
    is( $patron->can_request_article,
749
        1, 'There are no AR, so patron can request more articles' );
750
751
    my $article_request_1 = Koha::ArticleRequest->new(
752
        {
753
            borrowernumber => $patron->id,
754
            biblionumber   => $item->biblionumber,
755
            itemnumber     => $item->itemnumber,
756
            title          => 'an article request',
757
        }
758
    )->request;
759
760
    is( $patron->can_request_article,
761
        0, 'Limit is 1, so patron cannot request more articles' );
762
    is( $patron->article_requests->count,
763
        1, 'There is one current article request' );
764
765
    throws_ok {
766
        Koha::ArticleRequest->new(
767
            {
768
                borrowernumber => $patron->id,
769
                biblionumber   => $item->biblionumber,
770
                itemnumber     => $item->itemnumber,
771
                title          => 'a second article request',
772
            }
773
        )->request;
774
    }
775
    'Koha::Exceptions::ArticleRequest::LimitReached',
776
      'When limit was reached and we ask for a new AR, Limit reached is thrown';
777
778
    is( $patron->can_request_article,
779
        0, 'There is still an AR, so patron cannot request more articles' );
780
    is( $patron->article_requests->count,
781
        1, 'There is still one article request' );
782
783
    $article_request_1->complete();
784
785
    is( $patron->can_request_article, 0,
786
'AR was completed but within one day, so patron cannot request more articles'
787
    );
788
789
    $article_request_1->updated_on( dt_from_string->add( days => -2 ) )
790
      ->store();
791
792
    is( $patron->can_request_article, 1,
793
'There are no completed AR within one day, so patron can request more articles'
794
    );
795
796
    my $article_request_3 = Koha::ArticleRequest->new(
797
        {
798
            borrowernumber => $patron->id,
799
            biblionumber   => $item->biblionumber,
800
            itemnumber     => $item->itemnumber,
801
            title          => 'a third article request',
802
        }
803
    )->request;
804
805
    is( $patron->can_request_article,
806
        0, 'A new AR was created, so patron cannot request more articles' );
807
    is( $patron->article_requests->count, 2, 'There are 2 article requests' );
808
809
    $article_request_3->cancel();
810
811
    is( $patron->can_request_article,
812
        1, 'New AR was cancelled, so patron can request more articles' );
813
814
    my $article_request_4 = Koha::ArticleRequest->new(
815
        {
816
            borrowernumber => $patron->id,
817
            biblionumber   => $item->biblionumber,
818
            itemnumber     => $item->itemnumber,
819
            title          => 'an fourth article request',
820
        }
821
    )->request;
822
823
    $article_request_4->updated_on( dt_from_string->add( days => -30 ) )
824
      ->store();
825
826
    is( $patron->can_request_article, 0,
827
'There is an old AR but not completed or cancelled, so patron cannot request more articles'
828
    );
829
    is( $patron->article_requests->count,
830
        3, 'There are 3 current article requests' );
831
832
    $schema->storage->txn_rollback;
833
};

Return to bug 27945