package Koha::Patrons;
-# Copyright ByWater Solutions 2014
+# Copyright 2014 ByWater Solutions
+# Copyright 2016 Koha Development Team
#
# This file is part of Koha.
#
use base qw(Koha::Objects);
+our $RESULTSET_PATRON_ID_MAPPING = {
+ Accountline => 'borrowernumber',
+ ArticleRequest => 'borrowernumber',
+ BorrowerAttribute => 'borrowernumber',
+ BorrowerDebarment => 'borrowernumber',
+ BorrowerFile => 'borrowernumber',
+ BorrowerModification => 'borrowernumber',
+ ClubEnrollment => 'borrowernumber',
+ Issue => 'borrowernumber',
+ ItemsLastBorrower => 'borrowernumber',
+ Linktracker => 'borrowernumber',
+ Message => 'borrowernumber',
+ MessageQueue => 'borrowernumber',
+ OldIssue => 'borrowernumber',
+ OldReserve => 'borrowernumber',
+ Rating => 'borrowernumber',
+ Reserve => 'borrowernumber',
+ Review => 'borrowernumber',
+ Statistic => 'borrowernumber',
+ SearchHistory => 'userid',
+ Suggestion => 'suggestedby',
+ TagAll => 'borrowernumber',
+ Virtualshelfcontent => 'borrowernumber',
+ Virtualshelfshare => 'borrowernumber',
+ Virtualshelve => 'owner',
+};
+
=head1 NAME
Koha::Patron - Koha Patron Object class
=cut
+=head3 search_limited
+
+my $patrons = Koha::Patrons->search_limit( $params, $attributes );
+
+Returns all the patrons the logged in user is allowed to see
+
+=cut
+
+sub search_limited {
+ my ( $self, $params, $attributes ) = @_;
+
+ my $userenv = C4::Context->userenv;
+ my @restricted_branchcodes;
+ if ( $userenv and $userenv->{number} ) {
+ my $logged_in_user = Koha::Patrons->find( $userenv->{number} );
+ @restricted_branchcodes = $logged_in_user->libraries_where_can_see_patrons;
+ }
+ $params->{'me.branchcode'} = { -in => \@restricted_branchcodes } if @restricted_branchcodes;
+ return $self->search( $params, $attributes );
+}
+
=head3 search_housebound_choosers
Returns all Patrons which are Housebound choosers.
return Koha::Patrons->_new_from_dbic($del);
}
-=head3
+=head3 search_upcoming_membership_expires
my $patrons = Koha::Patrons->search_upcoming_membership_expires();
return Koha::Patrons->find( $self->guarantorid() );
}
-=head3 article_requests
+=head3 search_patrons_to_anonymise
-my @requests = $borrower->article_requests();
-my $requests = $borrower->article_requests();
+ my $patrons = Koha::Patrons->search_patrons_to_anonymise( { before => $older_than_date, [ library => $library ] } );
-Returns either a list of ArticleRequests objects,
-or an ArtitleRequests object, depending on the
-calling context.
+This method returns all patrons who has an issue history older than a given date.
=cut
-sub article_requests {
- my ( $self ) = @_;
+sub search_patrons_to_anonymise {
+ my ( $class, $params ) = @_;
+ my $older_than_date = $params->{before};
+ my $library = $params->{library};
+ $older_than_date = $older_than_date ? dt_from_string($older_than_date) : dt_from_string;
+ $library ||=
+ ( C4::Context->preference('IndependentBranches') && C4::Context->userenv && !C4::Context->IsSuperLibrarian() && C4::Context->userenv->{branch} )
+ ? C4::Context->userenv->{branch}
+ : undef;
- $self->{_article_requests} ||= Koha::ArticleRequests->search({ borrowernumber => $self->borrowernumber() });
-
- return $self->{_article_requests};
+ my $dtf = Koha::Database->new->schema->storage->datetime_parser;
+ my $rs = $class->_resultset->search(
+ { returndate => { '<' => $dtf->format_datetime($older_than_date), },
+ 'old_issues.borrowernumber' => { 'not' => undef },
+ privacy => { '<>' => 0 }, # Keep forever
+ ( $library ? ( 'old_issues.branchcode' => $library ) : () ),
+ },
+ { join => ["old_issues"],
+ distinct => 1,
+ }
+ );
+ return Koha::Patrons->_new_from_dbic($rs);
}
-=head3 article_requests_current
+=head3 anonymise_issue_history
-my @requests = $patron->article_requests_current
+ Koha::Patrons->search->anonymise_issue_history( { [ before => $older_than_date ] } );
-Returns the article requests associated with this patron that are incomplete
+Anonymise issue history (old_issues) for all patrons older than the given date (optional).
+To make sure all the conditions are met, the caller has the responsibility to
+call search_patrons_to_anonymise to filter the Koha::Patrons set
=cut
-sub article_requests_current {
- my ( $self ) = @_;
+sub anonymise_issue_history {
+ my ( $self, $params ) = @_;
+
+ my $older_than_date = $params->{before};
+
+ $older_than_date = dt_from_string $older_than_date if $older_than_date;
- $self->{_article_requests_current} ||= Koha::ArticleRequests->search(
+ # The default of 0 does not work due to foreign key constraints
+ # The anonymisation should not fail quietly if AnonymousPatron is not a valid entry
+ # Set it to undef (NULL)
+ my $dtf = Koha::Database->new->schema->storage->datetime_parser;
+ my $nb_rows = 0;
+ while ( my $patron = $self->next ) {
+ my $old_issues_to_anonymise = $patron->old_checkouts->search(
{
- borrowernumber => $self->id(),
- -or => [
- { status => Koha::ArticleRequest::Status::Pending },
- { status => Koha::ArticleRequest::Status::Processing }
- ]
+ (
+ $older_than_date
+ ? ( returndate =>
+ { '<' => $dtf->format_datetime($older_than_date) } )
+ : ()
+ )
}
- );
-
- return $self->{_article_requests_current};
+ );
+ my $anonymous_patron = C4::Context->preference('AnonymousPatron') || undef;
+ $nb_rows += $old_issues_to_anonymise->update( { 'old_issues.borrowernumber' => $anonymous_patron } );
+ }
+ return $nb_rows;
}
-=head3 article_requests_finished
+=head3 merge
-my @requests = $biblio->article_requests_finished
+ Koha::Patrons->search->merge( { keeper => $borrowernumber, patrons => \@borrowernumbers } );
-Returns the article requests associated with this patron that are completed
+ This subroutine merges a list of patrons into another patron record. This is accomplished by finding
+ all related patron ids for the patrons to be merged in other tables and changing the ids to be that
+ of the keeper patron.
=cut
-sub article_requests_finished {
- my ( $self, $borrower ) = @_;
+sub merge {
+ my ( $self, $params ) = @_;
+
+ my $keeper = $params->{keeper};
+ my @borrowernumbers = @{ $params->{patrons} };
- $self->{_article_requests_finished} ||= Koha::ArticleRequests->search(
- {
- borrowernumber => $self->id(),
- -or => [
- { status => Koha::ArticleRequest::Status::Completed },
- { status => Koha::ArticleRequest::Status::Canceled }
- ]
+ my $patron_to_keep = Koha::Patrons->find( $keeper );
+ return unless $patron_to_keep;
+
+ # Ensure the keeper isn't in the list of patrons to merge
+ @borrowernumbers = grep { $_ ne $keeper } @borrowernumbers;
+
+ my $schema = Koha::Database->new()->schema();
+
+ my $results;
+
+ foreach my $borrowernumber (@borrowernumbers) {
+ my $patron = Koha::Patrons->find( $borrowernumber );
+
+ next unless $patron;
+
+ # Unbless for safety, the patron will end up being deleted
+ $results->{merged}->{$borrowernumber}->{patron} = $patron->unblessed;
+
+ while (my ($r, $field) = each(%$RESULTSET_PATRON_ID_MAPPING)) {
+ my $rs = $schema->resultset($r)->search({ $field => $borrowernumber} );
+ $results->{merged}->{ $borrowernumber }->{updated}->{$r} = $rs->count();
+ $rs->update( { $field => $keeper });
}
- );
- return $self->{_article_requests_finished};
+ $patron->delete();
+ }
+
+ $results->{keeper} = $patron_to_keep;
+
+ return $results;
}
=head3 type