use C4::Context;
use C4::Log;
+use Koha::Checkouts;
use Koha::Database;
use Koha::DateUtils;
-use Koha::Issues;
-use Koha::OldIssues;
+use Koha::Holds;
+use Koha::Old::Checkouts;
use Koha::Patron::Categories;
+use Koha::Patron::HouseboundProfile;
+use Koha::Patron::HouseboundRole;
use Koha::Patron::Images;
use Koha::Patrons;
+use Koha::Virtualshelves;
+use Koha::Club::Enrollments;
use base qw(Koha::Object);
=cut
+=head3 delete
+
+$patron->delete
+
+Delete patron's holds, lists and finally the patron.
+
+Lists owned by the borrower are deleted, but entries from the borrower to
+other lists are kept.
+
+=cut
+
+sub delete {
+ my ($self) = @_;
+
+ my $deleted;
+ $self->_result->result_source->schema->txn_do(
+ sub {
+ # Delete Patron's holds
+ $self->holds->delete;
+
+ # Delete all lists and all shares of this borrower
+ # Consistent with the approach Koha uses on deleting individual lists
+ # Note that entries in virtualshelfcontents added by this borrower to
+ # lists of others will be handled by a table constraint: the borrower
+ # is set to NULL in those entries.
+ # NOTE:
+ # We could handle the above deletes via a constraint too.
+ # But a new BZ report 11889 has been opened to discuss another approach.
+ # Instead of deleting we could also disown lists (based on a pref).
+ # In that way we could save shared and public lists.
+ # The current table constraints support that idea now.
+ # This pref should then govern the results of other routines/methods such as
+ # Koha::Virtualshelf->new->delete too.
+ # FIXME Could be $patron->get_lists
+ $_->delete for Koha::Virtualshelves->search( { owner => $self->borrowernumber } );
+
+ $deleted = $self->SUPER::delete;
+
+ logaction( "MEMBERS", "DELETE", $self->borrowernumber, "" ) if C4::Context->preference("BorrowersLog");
+ }
+ );
+ return $deleted;
+}
+
+
+=head3 category
+
+my $patron_category = $patron->category
+
+Return the patron category for this patron
+
+=cut
+
+sub category {
+ my ( $self ) = @_;
+ return Koha::Patron::Category->_new_from_dbic( $self->_result->categorycode );
+}
+
=head3 guarantor
Returns a Koha::Patron object for this patron's guarantor
sub image {
my ( $self ) = @_;
- return Koha::Patron::Images->find( $self->borrowernumber )
+ return Koha::Patron::Images->find( $self->borrowernumber );
+}
+
+sub library {
+ my ( $self ) = @_;
+ return Koha::Library->_new_from_dbic($self->_result->branchcode);
}
=head3 guarantees
return Koha::Patrons->search( { guarantorid => $self->borrowernumber } );
}
+=head3 housebound_profile
+
+Returns the HouseboundProfile associated with this patron.
+
+=cut
+
+sub housebound_profile {
+ my ( $self ) = @_;
+ my $profile = $self->_result->housebound_profile;
+ return Koha::Patron::HouseboundProfile->_new_from_dbic($profile)
+ if ( $profile );
+ return;
+}
+
+=head3 housebound_role
+
+Returns the HouseboundRole associated with this patron.
+
+=cut
+
+sub housebound_role {
+ my ( $self ) = @_;
+
+ my $role = $self->_result->housebound_role;
+ return Koha::Patron::HouseboundRole->_new_from_dbic($role) if ( $role );
+ return;
+}
+
=head3 siblings
Returns the siblings of this patron.
return 0 if ($self->checkprevcheckout eq 'no');
# More complex: patron inherits -> determine category preference
- my $checkPrevCheckoutByCat = Koha::Patron::Categories
- ->find($self->categorycode)->checkprevcheckout;
+ my $checkPrevCheckoutByCat = $self->category->checkprevcheckout;
return 1 if ($checkPrevCheckoutByCat eq 'yes');
return 0 if ($checkPrevCheckoutByCat eq 'no');
};
# Check current issues table
- my $issues = Koha::Issues->search($criteria);
+ my $issues = Koha::Checkouts->search($criteria);
return 1 if $issues->count; # 0 || N
# Check old issues table
- my $old_issues = Koha::OldIssues->search($criteria);
+ my $old_issues = Koha::Old::Checkouts->search($criteria);
return $old_issues->count; # 0 || N
}
-=head2 is_debarred
+=head3 is_debarred
my $debarment_expiration = $patron->is_debarred;
return;
}
-=head2 update_password
+=head3 is_expired
+
+my $is_expired = $patron->is_expired;
+
+Returns 1 if the patron is expired or 0;
+
+=cut
+
+sub is_expired {
+ my ($self) = @_;
+ return 0 unless $self->dateexpiry;
+ return 0 if $self->dateexpiry eq '0000-00-00';
+ return 1 if dt_from_string( $self->dateexpiry ) < dt_from_string->truncate( to => 'day' );
+ return 0;
+}
+
+=head3 is_going_to_expire
+
+my $is_going_to_expire = $patron->is_going_to_expire;
+
+Returns 1 if the patron is going to expired, depending on the NotifyBorrowerDeparture pref or 0
+
+=cut
+
+sub is_going_to_expire {
+ my ($self) = @_;
+
+ my $delay = C4::Context->preference('NotifyBorrowerDeparture') || 0;
+
+ return 0 unless $delay;
+ return 0 unless $self->dateexpiry;
+ return 0 if $self->dateexpiry eq '0000-00-00';
+ return 1 if dt_from_string( $self->dateexpiry )->subtract( days => $delay ) < dt_from_string->truncate( to => 'day' );
+ return 0;
+}
+
+=head3 update_password
my $updated = $patron->update_password( $userid, $password );
sub renew_account {
my ($self) = @_;
-
- my $date =
- C4::Context->preference('BorrowerRenewalPeriodBase') eq 'dateexpiry'
- ? dt_from_string( $self->dateexpiry )
- : dt_from_string;
- my $patron_category = Koha::Patron::Categories->find( $self->categorycode ); # FIXME Should be $self->category
- my $expiry_date = $patron_category->get_expiry_date($date);
+ my $date;
+ if ( C4::Context->preference('BorrowerRenewalPeriodBase') eq 'combination' ) {
+ $date = ( dt_from_string gt dt_from_string( $self->dateexpiry ) ) ? dt_from_string : dt_from_string( $self->dateexpiry );
+ } else {
+ $date =
+ C4::Context->preference('BorrowerRenewalPeriodBase') eq 'dateexpiry'
+ ? dt_from_string( $self->dateexpiry )
+ : dt_from_string;
+ }
+ my $expiry_date = $self->category->get_expiry_date($date);
$self->dateexpiry($expiry_date)->store;
- C4::Members::AddEnrolmentFeeIfNeeded( $self->categorycode, $self->borrowernumber );
+ $self->add_enrolment_fee_if_needed;
logaction( "MEMBERS", "RENEW", $self->borrowernumber, "Membership renewed" ) if C4::Context->preference("BorrowersLog");
return dt_from_string( $expiry_date )->truncate( to => 'day' );
}
-=head2 has_overdues
+=head3 has_overdues
my $has_overdues = $patron->has_overdues;
return $self->_result->issues->search({ date_due => { '<' => $dtf->format_datetime( dt_from_string() ) } })->count;
}
+=head3 track_login
+
+ $patron->track_login;
+ $patron->track_login({ force => 1 });
+
+ Tracks a (successful) login attempt.
+ The preference TrackLastPatronActivity must be enabled. Or you
+ should pass the force parameter.
+
+=cut
+
+sub track_login {
+ my ( $self, $params ) = @_;
+ return if
+ !$params->{force} &&
+ !C4::Context->preference('TrackLastPatronActivity');
+ $self->lastseen( dt_from_string() )->store;
+}
+
+=head3 move_to_deleted
+
+my $is_moved = $patron->move_to_deleted;
+
+Move a patron to the deletedborrowers table.
+This can be done before deleting a patron, to make sure the data are not completely deleted.
+
+=cut
+
+sub move_to_deleted {
+ my ($self) = @_;
+ my $patron_infos = $self->unblessed;
+ delete $patron_infos->{updated_on}; #This ensures the updated_on date in deletedborrowers will be set to the current timestamp
+ return Koha::Database->new->schema->resultset('Deletedborrower')->create($patron_infos);
+}
+
+=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::Pending },
+ { 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 add_enrolment_fee_if_needed
+
+my $enrolment_fee = $patron->add_enrolment_fee_if_needed;
+
+Add enrolment fee for a patron if needed.
+
+=cut
+
+sub add_enrolment_fee_if_needed {
+ my ($self) = @_;
+ my $enrolment_fee = $self->category->enrolmentfee;
+ if ( $enrolment_fee && $enrolment_fee > 0 ) {
+ # insert fee in patron debts
+ C4::Accounts::manualinvoice( $self->borrowernumber, '', '', 'A', $enrolment_fee );
+ }
+ return $enrolment_fee || 0;
+}
+
+=head3 checkouts
+
+my $issues = $patron->checkouts
+
+=cut
+
+sub checkouts {
+ my ($self) = @_;
+ my $issues = $self->_result->issues;
+ return Koha::Checkouts->_new_from_dbic( $issues );
+}
+
+=head3 get_overdues
+
+my $overdue_items = $patron->get_overdues
+
+Return the overdued items
+
+=cut
+
+sub get_overdues {
+ my ($self) = @_;
+ my $dtf = Koha::Database->new->schema->storage->datetime_parser;
+ return $self->checkouts->search(
+ {
+ 'me.date_due' => { '<' => $dtf->format_datetime(dt_from_string) },
+ },
+ {
+ prefetch => { item => { biblio => 'biblioitems' } },
+ }
+ );
+}
+
+=head3 get_age
+
+my $age = $patron->get_age
+
+Return the age of the patron
+
+=cut
+
+sub get_age {
+ my ($self) = @_;
+ my $today_str = dt_from_string->strftime("%Y-%m-%d");
+ return unless $self->dateofbirth;
+ my $dob_str = dt_from_string( $self->dateofbirth )->strftime("%Y-%m-%d");
+
+ my ( $dob_y, $dob_m, $dob_d ) = split /-/, $dob_str;
+ my ( $today_y, $today_m, $today_d ) = split /-/, $today_str;
+
+ my $age = $today_y - $dob_y;
+ if ( $dob_m . $dob_d > $today_m . $today_d ) {
+ $age--;
+ }
+
+ return $age;
+}
+
+=head3 account
+
+my $account = $patron->account
+
+=cut
+
+sub account {
+ my ($self) = @_;
+ return Koha::Account->new( { patron_id => $self->borrowernumber } );
+}
+
+=head3 holds
+
+my $holds = $patron->holds
+
+Return all the holds placed by this patron
+
+=cut
+
+sub holds {
+ my ($self) = @_;
+ my $holds_rs = $self->_result->reserves->search( {}, { order_by => 'reservedate' } );
+ return Koha::Holds->_new_from_dbic($holds_rs);
+}
+
+=head3 first_valid_email_address
+
+=cut
+
+sub first_valid_email_address {
+ my ($self) = @_;
+
+ return $self->email() || $self->emailpro() || $self->B_email() || q{};
+}
+
+=head3 get_club_enrollments
+
+=cut
+
+sub get_club_enrollments {
+ my ($self) = @_;
+
+ return Koha::Club::Enrollments->search( { borrowernumber => $self->borrowernumber(), date_canceled => undef } );
+}
+
+=head3 get_enrollable_clubs
+
+=cut
+
+sub get_enrollable_clubs {
+ my ( $self, $is_enrollable_from_opac ) = @_;
+
+ my $params;
+ $params->{is_enrollable_from_opac} = $is_enrollable_from_opac
+ if $is_enrollable_from_opac;
+ $params->{is_email_required} = 0 unless $self->first_valid_email_address();
+
+ $params->{borrower} = $self;
+
+ return Koha::Clubs->get_enrollable($params);
+}
+
=head3 type
=cut