From bd149f17e605a96ee448261ae2e6ed7c80c4e087 Mon Sep 17 00:00:00 2001
From: Martin Renvoize <martin.renvoize@ptfs-europe.com>
Date: Thu, 21 Jun 2018 14:18:17 +0100
Subject: [PATCH] Bug 11983: Centralised Koha::Patrons method OPTION 2

---
 Koha/Patrons.pm | 258 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 258 insertions(+)

diff --git a/Koha/Patrons.pm b/Koha/Patrons.pm
index 0d2d9ec6b4..0b1dd3ca1e 100644
--- a/Koha/Patrons.pm
+++ b/Koha/Patrons.pm
@@ -62,6 +62,264 @@ sub search_limited {
     return $self->search( $params, $attributes );
 }
 
+=head3 filter_by_guarantors
+
+    Koha::Patrons->filter_by_guarantors(1);
+
+Returns patrons filtered by whether they are guarantors or not.
+
+=head4 options
+
+=over 4
+
+=item undef - do not apply filter
+
+=item 0 - limit to NOT guarantors 
+
+=item 1 - limit to ONLY guarantors
+
+=back
+
+=cut
+
+sub filter_by_guarantors {
+    my ( $self, $option ) = @_;
+
+    return $self unless defined($option);
+
+    my $guarantorList = Koha::Patrons->search(
+        { guarantorid => [ { '!=' => 0 }, { '!=' => undef } ] },
+        { select      => ['borrowernumber'] } )->_resultset->as_query;
+
+    # Patrons who are guarantors
+    return $self->search(
+        { 'me.borrowernumber' => { '-in' => $guarantorList } } )
+      if $option;
+
+    # Patrons who are not guarantors
+    return $self->search(
+        { 'me.borrowernumber' => { '-not_in' => $guarantorList } } );
+}
+
+=head3 filter_by_last_issued
+
+    Koha::Patrons->filter_by_last_issued( { after => DateTime, before => DateTime );
+
+Returns patrons filtered by whether their last issue falls betwen the passed limits.
+
+=head4 arguments hashref
+
+=over 4
+
+=item before (optional) - filter out patrons whose last_issue was since DateTime
+
+=item after (optional) - filter out patrons whose last_issue has been since DateTime
+
+=back
+
+=cut
+
+sub filter_by_last_issued {
+    my ( $self, $options ) = @_;
+
+    return $self
+      unless ( defined($options)
+        && ( $options->{before} || $options->{after} ) );
+
+    my $where = {};
+    my $attrs = {
+        join      => 'old_issues',
+        '+select' => { max => 'old_issues.timestamp', '-as' => 'last_issued' },
+        '+as'     => 'last_issued'
+    };
+    my $dtf = Koha::Database->new->schema->storage->datetime_parser;
+
+    push @{ $attrs->{'having'}->{'-and'} },
+      { 'last_issued' => { '<' => $dtf->format_datetime( $options->{before} ) }
+      }
+      if $options->{before};
+
+    push @{ $attrs->{'having'}->{'-and'} },
+      { 'last_issued' => { '>' => $dtf->format_datetime( $options->{after} ) } }
+      if $options->{after};
+
+    return $self->search( $where, $attrs );
+}
+
+=head3 filter_by_has_issues
+
+    Koha::Patrons->filter_by_has_issues(1);
+
+Returns patrons filtered by whether they have current issues or not.
+
+=head4 options
+
+=over 4
+
+=item undef - do not apply filter
+
+=item 0 - limit to patrons WITHOUT current issues 
+
+=item 1 - limit to patrons WITH current issues
+
+=back
+
+=cut
+
+sub filter_by_has_issues {
+    my ( $self, $option ) = @_;
+
+    return $self
+      unless defined($option);
+
+    my $where = {};
+    my $attrs = {
+        join      => 'issues',
+        '+select' => { max => 'issues.timestamp', '-as' => 'current_issue' },
+        '+as'     => 'current_issue'
+    };
+
+    # Patrons who have current issues
+    if ($option) {
+        $attrs->{'having'} = { 'currentissue' => { '!=' => undef } };
+    }
+
+    # Patrons who do not have current issues
+    else {
+        $attrs->{'having'} = { 'currentissue' => undef };
+
+    }
+
+    return $self->search($where,$attrs);
+}
+
+
+=head3 filter_by_expired_date
+
+    Koha::Patrons->filter_by_expired_date( { after => DateTime, before => DateTime );
+
+Returns patrons filtered by whether their accounts expired between between the passed limits.
+
+=head4 arguments hashref
+
+=over 4
+
+=item before (optional) - filter out patrons whose expired_date was since DateTime
+
+=item after (optional) - filter out patrons whose expired_date has been since DateTime
+
+=back
+
+=cut
+
+sub filter_by_expired_date {
+    my ( $self, $options ) = @_;
+
+    return $self
+      unless ( defined($options)
+        && ( $options->{before} || $options->{after} ) );
+
+    my $where = {};
+    my $attrs = {};
+    my $dtf = Koha::Database->new->schema->storage->datetime_parser;
+
+    push @{ $where->{'dateexpiry'} },
+      { '<' => $dtf->format_datetime( $options->{before} ) }
+      if $options->{before};
+
+    push @{ $where->{'dateexpiry'} },
+      { '>' => $dtf->format_datetime( $options->{after} ) }
+      if $options->{after};
+
+    return $self->search( $where, $attrs );
+}
+
+
+=head3 filter_by_amount_owed
+
+    Koha::Patrons->filter_by_amount_owed( { less_than => '2.00', more_than => '0.50' } );
+
+Returns patrons filtered by how much money they owe, between passed limits.
+
+=head4 arguments hashref
+
+=over 4
+
+=item less_than (optional) - filter out patrons who owe less than Amount
+
+=item more_than (optional) - filter out patrons who owe more than Amount
+
+=back
+
+=cut
+
+sub filter_by_amount_owed {
+    my ( $self, $options ) = @_;
+
+    return $self
+      unless ( defined($options)
+        && ( $options->{less_than} || $options->{more_than} ) );
+
+    my $where = {};
+    my $attrs = {
+        join => 'accountlines',
+        '+select' =>
+          { sum => 'accountlines.amountoutstanding', '-as' => 'outstanding' },
+        '+as' => 'outstanding'
+    };
+
+    push @{ $attrs->{'having'}->{'-and'} },
+      { 'outstanding' => { '<' => $options->{less_than} } }
+      if defined( $options->{less_than} );
+
+    push @{ $attrs->{'having'}->{'-and'} },
+      { 'outstanding' => { '>' => $options->{more_than} } }
+      if defined( $options->{more_than} );
+
+    return $self->search( $where, $attrs );
+}
+
+
+=head3 filter_by_lists
+
+    Koha::Patrons->filter_by_lists( {  on => [1], not_on => [2] } );
+
+Returns patrons filtered by which lists they appear on.
+
+=head4 arguments hashref
+
+=over 4
+
+=item on (optional) - filter out patrons who appear on List(s)
+
+=item not_on (optional) - filter out patrons who do not appear on List(s)
+
+=back
+
+=cut
+
+sub filter_by_lists {
+    my ( $self, $options ) = @_;
+
+    return $self
+      unless ( defined($options)
+        && ( $options->{on} || $options->{not_on} ) );
+
+    my $where = {};
+    my $attrs = { join => 'patron_list_patrons' };
+
+    push @{ $attrs->{'where'}->{'-and'} },
+      { 'patron_list_patrons.patron_list_id' => { '-in' => $options->{on} } }
+      if defined( $options->{on} );
+
+    push @{ $attrs->{'where'}->{'-and'} },
+      { 'patron_list_patrons.patron_list_id' =>
+          { '-not_in' => $options->{not_on} } }
+      if defined( $options->{not_on} );
+
+    return $self->search( $where, $attrs );
+}
+
 =head3 search_housebound_choosers
 
 Returns all Patrons which are Housebound choosers.
-- 
2.17.1