From f5254ad023431e194278370f687aa03e1fc9af07 Mon Sep 17 00:00:00 2001 From: Kyle M Hall Date: Wed, 7 Oct 2015 12:23:24 -0400 Subject: [PATCH] Bug 14610 - Add and update modules Signed-off-by: Jennifer Schmidt --- C4/Letters.pm | 25 ++--- Koha/ArticleRequest.pm | 223 +++++++++++++++++++++++++++++++++++++++++ Koha/ArticleRequest/Status.pm | 44 ++++++++ Koha/ArticleRequests.pm | 103 +++++++++++++++++++ Koha/Biblio.pm | 175 ++++++++++++++++++++++++++++++++ Koha/Biblios.pm | 2 +- Koha/Borrower.pm | 70 +++++++++++++ Koha/Item.pm | 47 ++++++++- Koha/Template/Plugin/Biblio.pm | 11 ++ 9 files changed, 685 insertions(+), 15 deletions(-) create mode 100644 Koha/ArticleRequest.pm create mode 100644 Koha/ArticleRequest/Status.pm create mode 100644 Koha/ArticleRequests.pm diff --git a/C4/Letters.pm b/C4/Letters.pm index bc60bc3..806cfea 100644 --- a/C4/Letters.pm +++ b/C4/Letters.pm @@ -758,18 +758,19 @@ sub _parseletter_sth { # broke things for the rest of us. prepare_cached is a better # way to cache statement handles anyway. my $query = - ($table eq 'biblio' ) ? "SELECT * FROM $table WHERE biblionumber = ?" : - ($table eq 'biblioitems' ) ? "SELECT * FROM $table WHERE biblionumber = ?" : - ($table eq 'items' ) ? "SELECT * FROM $table WHERE itemnumber = ?" : - ($table eq 'issues' ) ? "SELECT * FROM $table WHERE itemnumber = ?" : - ($table eq 'old_issues' ) ? "SELECT * FROM $table WHERE itemnumber = ? ORDER BY timestamp DESC LIMIT 1" : - ($table eq 'reserves' ) ? "SELECT * FROM $table WHERE borrowernumber = ? and biblionumber = ?" : - ($table eq 'borrowers' ) ? "SELECT * FROM $table WHERE borrowernumber = ?" : - ($table eq 'branches' ) ? "SELECT * FROM $table WHERE branchcode = ?" : - ($table eq 'suggestions' ) ? "SELECT * FROM $table WHERE suggestionid = ?" : - ($table eq 'aqbooksellers') ? "SELECT * FROM $table WHERE id = ?" : - ($table eq 'aqorders' ) ? "SELECT * FROM $table WHERE ordernumber = ?" : - ($table eq 'opac_news' ) ? "SELECT * FROM $table WHERE idnew = ?" : + ($table eq 'biblio' ) ? "SELECT * FROM $table WHERE biblionumber = ?" : + ($table eq 'biblioitems' ) ? "SELECT * FROM $table WHERE biblionumber = ?" : + ($table eq 'items' ) ? "SELECT * FROM $table WHERE itemnumber = ?" : + ($table eq 'issues' ) ? "SELECT * FROM $table WHERE itemnumber = ?" : + ($table eq 'old_issues' ) ? "SELECT * FROM $table WHERE itemnumber = ? ORDER BY timestamp DESC LIMIT 1" : + ($table eq 'reserves' ) ? "SELECT * FROM $table WHERE borrowernumber = ? and biblionumber = ?" : + ($table eq 'borrowers' ) ? "SELECT * FROM $table WHERE borrowernumber = ?" : + ($table eq 'branches' ) ? "SELECT * FROM $table WHERE branchcode = ?" : + ($table eq 'suggestions' ) ? "SELECT * FROM $table WHERE suggestionid = ?" : + ($table eq 'aqbooksellers') ? "SELECT * FROM $table WHERE id = ?" : + ($table eq 'aqorders' ) ? "SELECT * FROM $table WHERE ordernumber = ?" : + ($table eq 'opac_news' ) ? "SELECT * FROM $table WHERE idnew = ?" : + ($table eq 'article_requests') ? "SELECT * FROM $table WHERE id = ?" : ($table eq 'borrower_modifications') ? "SELECT * FROM $table WHERE verification_token = ?" : ($table eq 'subscription') ? "SELECT * FROM $table WHERE subscriptionid = ?" : ($table eq 'serial') ? "SELECT * FROM $table WHERE serialid = ?" : diff --git a/Koha/ArticleRequest.pm b/Koha/ArticleRequest.pm new file mode 100644 index 0000000..cd0531d --- /dev/null +++ b/Koha/ArticleRequest.pm @@ -0,0 +1,223 @@ +package Koha::ArticleRequest; + +# Copyright ByWater Solutions 2015 +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 3 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +use Carp; + +use Koha::Database; +use Koha::Borrowers; +use Koha::Biblios; +use Koha::Items; +use Koha::Branches; +use Koha::ArticleRequest::Status; +use Koha::DateUtils qw(dt_from_string); + +use base qw(Koha::Object); + +=head1 NAME + +Koha::ArticleRequest - Koha Article Request Object class + +=head1 API + +=head2 Class Methods + +=cut + +=head3 open + +=cut + +sub open { + my ($self) = @_; + + $self->status(Koha::ArticleRequest::Status::Open); + $self->notify(); + return $self; +} + +=head3 process + +=cut + +sub process { + my ($self) = @_; + + $self->status(Koha::ArticleRequest::Status::Processing); + $self->store(); + $self->notify(); + return $self; +} + +=head3 complete + +=cut + +sub complete { + my ($self) = @_; + + $self->status(Koha::ArticleRequest::Status::Completed); + $self->store(); + $self->notify(); + return $self; +} + +=head3 cancel + +=cut + +sub cancel { + my ( $self, $notes ) = @_; + + $self->status(Koha::ArticleRequest::Status::Canceled); + $self->notes($notes) if $notes; + $self->store(); + $self->notify(); + return $self; +} + +=head3 notify + +=cut + +sub notify { + my ($self) = @_; + + my $status = $self->status; + + if ( + my $letter = C4::Letters::GetPreparedLetter( + module => 'circulation', + letter_code => "AR_$status", + message_transport_type => 'email', + tables => { + article_requests => $self->id, + borrowers => $self->borrowernumber, + biblio => $self->biblionumber, + biblioitems => $self->biblionumber, + items => $self->itemnumber, + branches => $self->branchcode, + }, + ) + ) + { + C4::Letters::EnqueueLetter( + { + letter => $letter, + borrowernumber => $self->borrowernumber, + message_transport_type => 'email', + } + ) or warn "can't enqueue letter $letter"; + } +} + +=head3 biblio + +Returns the Koha::Biblio object for this article request + +=cut + +sub biblio { + my ($self) = @_; + + $self->{_biblio} ||= Koha::Biblios->find( $self->biblionumber() ); + + return $self->{_biblio}; +} + +=head3 item + +Returns the Koha::Item object for this article request + +=cut + +sub item { + my ($self) = @_; + + $self->{_item} ||= Koha::Items->find( $self->itemnumber() ); + + return $self->{_item}; +} + +=head3 borrower + +Returns the Koha::Borrower object for this article request + +=cut + +sub borrower { + my ($self) = @_; + + $self->{_borrower} ||= Koha::Borrowers->find( $self->borrowernumber() ); + + return $self->{_borrower}; +} + +=head3 branch + +Returns the Koha::Branch object for this article request + +=cut + +sub branch { + my ($self) = @_; + + $self->{_branch} ||= Koha::Branches->find( $self->branchcode() ); + + return $self->{_branch}; +} + +=head3 store + +Override the default store behavior so that new opan requests +will have notifications sent. + +=cut + +sub store { + my ($self) = @_; + + if ( $self->in_storage() ) { + my $now = dt_from_string(); + $self->updated_on($now); + + return $self->SUPER::store(); + } + else { + $self->open(); + return $self->SUPER::store(); + } +} + +=head3 type + +=cut + +sub type { + return 'ArticleRequest'; +} + +=head1 AUTHOR + +Kyle M Hall + +=cut + +1; diff --git a/Koha/ArticleRequest/Status.pm b/Koha/ArticleRequest/Status.pm new file mode 100644 index 0000000..e3d4d3f --- /dev/null +++ b/Koha/ArticleRequest/Status.pm @@ -0,0 +1,44 @@ +package Koha::ArticleRequest::Status; + +# Copyright ByWater Solutions 2015 +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 3 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +sub Open { + return 'OPEN'; +} + +sub Processing { + return 'PROCESSING'; +} + +sub Completed { + return 'COMPLETED'; +} + +sub Canceled { + return 'CANCELED'; +} + +=head1 AUTHOR + +Kyle M Hall + +=cut + +1; diff --git a/Koha/ArticleRequests.pm b/Koha/ArticleRequests.pm new file mode 100644 index 0000000..c5c06ca --- /dev/null +++ b/Koha/ArticleRequests.pm @@ -0,0 +1,103 @@ +package Koha::ArticleRequests; + +# Copyright ByWater Solutions 2015 +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 3 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +use Carp; + +use Koha::Database; + +use Koha::ArticleRequest; +use Koha::ArticleRequest::Status; + +use base qw(Koha::Objects); + +=head1 NAME + +Koha::ArticleRequests - Koha ArticleRequests Object class + +=head1 API + +=head2 Class Methods + +=cut + +=head3 open + +=cut + +sub open { + my ( $self, $branchcode ) = @_; + my $params = { status => Koha::ArticleRequest::Status::Open }; + $params->{branchcode} = $branchcode if $branchcode; + return Koha::ArticleRequests->search( $params ); +} + +=head3 processing + +=cut + +sub processing { + my ( $self, $branchcode ) = @_; + my $params = { status => Koha::ArticleRequest::Status::Processing }; + $params->{branchcode} = $branchcode if $branchcode; + return Koha::ArticleRequests->search( $params ); +} + +=head3 completed + +=cut + +sub completed { + my ( $self, $branchcode ) = @_; + my $params = { status => Koha::ArticleRequest::Status::Completed }; + $params->{branchcode} = $branchcode if $branchcode; + return Koha::ArticleRequests->search( $params ); +} + +=head3 canceled + +=cut + +sub canceled { + my ( $self, $branchcode ) = @_; + my $params = { status => Koha::ArticleRequest::Status::Canceled }; + $params->{branchcode} = $branchcode if $branchcode; + return Koha::ArticleRequests->search( $params ); +} + +=head3 type + +=cut + +sub type { + return 'ArticleRequest'; +} + +sub object_class { + return 'Koha::ArticleRequest'; +} + +=head1 AUTHOR + +Kyle M Hall + +=cut + +1; diff --git a/Koha/Biblio.pm b/Koha/Biblio.pm index 9c467d7..fce5a55 100644 --- a/Koha/Biblio.pm +++ b/Koha/Biblio.pm @@ -25,6 +25,11 @@ use Koha::Database; use base qw(Koha::Object); +use C4::Circulation qw(GetIssuingRule); +use Koha::Items; +use Koha::ArticleRequests; +use Koha::ArticleRequest::Status; + =head1 NAME Koha::Biblio - Koha Biblio Object class @@ -35,6 +40,176 @@ Koha::Biblio - Koha Biblio Object class =cut +=head3 can_article_request + +my $bool = $biblio->can_article_request( $borrower ); + +Returns true if article requests can be made for this record + +$borrower must be a Koha::Borrower object + +=cut + +sub can_article_request { + my ( $self, $borrower ) = @_; + + my $rule = $self->article_request_type($borrower); + return q{} if $rule eq 'item_only' && !$self->items()->count(); + return 1 if $rule && $rule ne 'no'; + + return q{}; +} + +=head3 article_request_type + +my $type = $biblio->article_request_type( $borrower ); + +Returns the article request type based on items, or on the record +itself if there are no items. + +$borrower must be a Koha::Borrower object + +=cut + +sub article_request_type { + my ( $self, $borrower ) = @_; + + my $rule = $self->article_request_type_for_items( $borrower ); + return $rule if $rule; + + # If the record has no items that are requestable, go by the record itemtype + $rule = $self->article_request_type_for_bib($borrower); + return $rule if $rule; + + return q{}; +} + +=head3 article_request_type_for_bib + +my $type = $biblio->article_request_type_for_bib + +Returns the article request type 'yes', 'no', 'item_only', 'bib_only', for the given record + +=cut + +sub article_request_type_for_bib { + my ( $self, $borrower ) = @_; + + my $borrowertype = $borrower->categorycode; + my $itemtype = $self->itemtype(); + my $rules = GetIssuingRule( $borrowertype, $itemtype ); + + return $rules->{article_requests} || q{}; +} + +=head3 article_request_type_for_items + +my $type = $biblio->article_request_type_for_items + +Returns the article request type 'yes', 'no', 'item_only', 'bib_only', for the given record's items + +If there is a conflict where some items are 'bib_only' and some are 'item_only', 'bib_only' will be returned. + +=cut + +sub article_request_type_for_items { + my ( $self, $borrower ) = @_; + + my $counts; + foreach my $item ( $self->items()->as_list() ) { + my $rule = $item->article_request_type($borrower); + return $rule if $rule eq 'bib_only'; # we don't need to go any further + $counts->{$rule}++; + } + + return 'item_only' if $counts->{item_only}; + return 'yes' if $counts->{yes}; + return 'no' if $counts->{no}; + return q{}; +} + +=head3 article_requests + +my @requests = $biblio->article_requests + +Returns the article requests associated with this Biblio + +=cut + +sub article_requests { + my ( $self, $borrower ) = @_; + + $self->{_article_requests} ||= Koha::ArticleRequests->search( { biblionumber => $self->biblionumber() } ); + + return wantarray ? $self->{_article_requests}->as_list : $self->{_article_requests}; +} + +=head3 article_requests_current + +my @requests = $biblio->article_requests_current + +Returns the article requests associated with this Biblio that are incomplete + +=cut + +sub article_requests_current { + my ( $self, $borrower ) = @_; + + $self->{_article_requests_current} ||= Koha::ArticleRequests->search( + { + biblionumber => $self->biblionumber(), + -or => [ + { status => Koha::ArticleRequest::Status::Open }, + { status => Koha::ArticleRequest::Status::Processing } + ] + } + ); + + return wantarray ? $self->{_article_requests_current}->as_list : $self->{_article_requests_current}; +} + +=head3 article_requests_finished + +my @requests = $biblio->article_requests_finished + +Returns the article requests associated with this Biblio that are completed + +=cut + +sub article_requests_finished { + my ( $self, $borrower ) = @_; + + $self->{_article_requests_finished} ||= Koha::ArticleRequests->search( + { + biblionumber => $self->biblionumber(), + -or => [ + { status => Koha::ArticleRequest::Status::Completed }, + { status => Koha::ArticleRequest::Status::Canceled } + ] + } + ); + + return wantarray ? $self->{_article_requests_finished}->as_list : $self->{_article_requests_finished}; +} + +=head3 items + +my @items = $biblio->items(); +my $items = $biblio->items(); + +Returns a list of Koha::Item objects or a Koha::Items object of +items associated with this bib + +=cut + +sub items { + my ( $self ) = @_; + + $self->{_items} ||= Koha::Items->search({ biblionumber => $self->biblionumber() }); + + return $self->{_items}; +} + =head3 type =cut diff --git a/Koha/Biblios.pm b/Koha/Biblios.pm index cba48ea..020f933 100644 --- a/Koha/Biblios.pm +++ b/Koha/Biblios.pm @@ -1,6 +1,6 @@ package Koha::Biblios; -# Copyright ByWater Solutions 2014 +# Copyright ByWater Solutions 2015 # # This file is part of Koha. # diff --git a/Koha/Borrower.pm b/Koha/Borrower.pm index 93426bf..84ce27a 100644 --- a/Koha/Borrower.pm +++ b/Koha/Borrower.pm @@ -23,6 +23,9 @@ use Carp; use Koha::Database; +use Koha::ArticleRequests; +use Koha::ArticleRequest::Status; + use base qw(Koha::Object); =head1 NAME @@ -35,6 +38,73 @@ Koha::Borrower - Koha Borrower Object class =cut +=head3 article_requests + +my @requests = $borrower->article_requests(); +my $requests = $borrower->article_requests(); + +Returns either a list of ArticleRequests objects, +or an ArtitleRequests object, depending on the +calling context. + +=cut + +sub article_requests { + my ( $self ) = @_; + + $self->{_article_requests} ||= Koha::ArticleRequests->search({ borrowernumber => $self->borrowernumber() }); + + return $self->{_article_requests}; +} + +=head3 article_requests_current + +my @requests = $patron->article_requests_current + +Returns the article requests associated with this patron that are incomplete + +=cut + +sub article_requests_current { + my ( $self ) = @_; + + $self->{_article_requests_current} ||= Koha::ArticleRequests->search( + { + borrowernumber => $self->id(), + -or => [ + { status => Koha::ArticleRequest::Status::Open }, + { status => Koha::ArticleRequest::Status::Processing } + ] + } + ); + + return $self->{_article_requests_current}; +} + +=head3 article_requests_finished + +my @requests = $biblio->article_requests_finished + +Returns the article requests associated with this patron that are completed + +=cut + +sub article_requests_finished { + my ( $self, $borrower ) = @_; + + $self->{_article_requests_finished} ||= Koha::ArticleRequests->search( + { + borrowernumber => $self->id(), + -or => [ + { status => Koha::ArticleRequest::Status::Completed }, + { status => Koha::ArticleRequest::Status::Canceled } + ] + } + ); + + return $self->{_article_requests_finished}; +} + =head3 type =cut diff --git a/Koha/Item.pm b/Koha/Item.pm index 2dcccfb..b6f84c4 100644 --- a/Koha/Item.pm +++ b/Koha/Item.pm @@ -21,8 +21,8 @@ use Modern::Perl; use Carp; -use Koha::Database; - +use C4::Context; +use C4::Circulation qw(GetIssuingRule); use Koha::Branches; use base qw(Koha::Object); @@ -73,6 +73,49 @@ sub holding_branch { return $self->{_holding_branch}; } +=head3 can_article_request + +my $bool = $item->can_article_request( $borrower ) + +Returns true if item can be specifically requested + +$borrower must be a Koha::Borrower object + +=cut + +sub can_article_request { + my ( $self, $borrower ) = @_; + + my $rule = $self->article_request_type($borrower); + + return 1 if $rule && $rule ne 'no' && $rule ne 'bib_only'; + return q{}; +} + +=head3 article_request_type + +my $type = $item->article_request_type( $borrower ) + +returns 'yes', 'no', 'bib_only', or 'item_only' + +$borrower must be a Koha::Borrower object + +=cut + +sub article_request_type { + my ( $self, $borrower ) = @_; + + my $branch_control = C4::Context->preference('HomeOrHoldingBranch'); + my $branchcode = + $branch_control eq 'homebranch' ? $self->homebranch + : $branch_control eq 'holdingbranch' ? $self->holdingbranch + : undef; + my $borrowertype = $borrower->categorycode; + my $itemtype = $self->effective_itemtype(); + my $rules = GetIssuingRule( $borrowertype, $itemtype, $branchcode ); + + return $rules->{article_requests} || q{}; +} =head3 type diff --git a/Koha/Template/Plugin/Biblio.pm b/Koha/Template/Plugin/Biblio.pm index 3f9cc4f..79a6df0 100644 --- a/Koha/Template/Plugin/Biblio.pm +++ b/Koha/Template/Plugin/Biblio.pm @@ -23,6 +23,8 @@ use Template::Plugin; use base qw( Template::Plugin ); use Koha::Holds; +use Koha::Biblios; +use Koha::Borrowers; sub HoldsCount { my ( $self, $biblionumber ) = @_; @@ -32,4 +34,13 @@ sub HoldsCount { return $holds->count(); } +sub CanArticleRequest { + my ( $self, $biblionumber, $borrowernumber ) = @_; + + my $biblio = Koha::Biblios->find( $biblionumber ); + my $borrower = Koha::Borrowers->find( $borrowernumber ); + + return $biblio ? $biblio->can_article_request( $borrower ) : 0; +} + 1; -- 2.1.4