|
Lines 20-25
use Modern::Perl;
Link Here
|
| 20 |
use Mojo::Base 'Mojolicious::Controller'; |
20 |
use Mojo::Base 'Mojolicious::Controller'; |
| 21 |
|
21 |
|
| 22 |
use Koha::Database; |
22 |
use Koha::Database; |
|
|
23 |
use Koha::DateUtils; |
| 23 |
use Koha::Exceptions; |
24 |
use Koha::Exceptions; |
| 24 |
use Koha::Patrons; |
25 |
use Koha::Patrons; |
| 25 |
use C4::Letters qw( GetPreparedLetter EnqueueLetter SendQueuedMessages ); |
26 |
use C4::Letters qw( GetPreparedLetter EnqueueLetter SendQueuedMessages ); |
|
Lines 46-60
sub list {
Link Here
|
| 46 |
my $c = shift->openapi->valid_input or return; |
47 |
my $c = shift->openapi->valid_input or return; |
| 47 |
|
48 |
|
| 48 |
return try { |
49 |
return try { |
|
|
50 |
my $patrons_rs = Koha::Patrons->search(); |
| 49 |
|
51 |
|
| 50 |
my $query = {}; |
|
|
| 51 |
my $restricted = $c->param('restricted'); |
52 |
my $restricted = $c->param('restricted'); |
| 52 |
$c->req->params->remove('restricted'); |
53 |
$c->req->params->remove('restricted'); |
| 53 |
$query->{debarred} = { '!=' => undef } |
54 |
if ($restricted) { |
| 54 |
if $restricted; |
55 |
$patrons_rs = $patrons_rs->search( { debarred => { '!=' => undef } } ); |
|
|
56 |
} |
| 57 |
|
| 58 |
my $search = $c->param('search'); |
| 59 |
my $search_type = $c->param('search_type'); |
| 60 |
my $search_fields = $c->param('search_fields'); |
| 61 |
$c->req->params->remove('search'); |
| 62 |
$c->req->params->remove('search_type'); |
| 63 |
$c->req->params->remove('search_fields'); |
| 64 |
|
| 65 |
my $query = $c->_buildPatronSearchQuery( |
| 66 |
{ search => $search, search_type => $search_type, search_fields => $search_fields } ); |
| 67 |
$patrons_rs = $patrons_rs->search( $query, { join => 'extended_attributes' } ) if $query; |
| 55 |
|
68 |
|
| 56 |
my $patrons_rs = Koha::Patrons->search($query); |
69 |
my $patrons = $c->objects->search($patrons_rs); |
| 57 |
my $patrons = $c->objects->search($patrons_rs); |
|
|
| 58 |
|
70 |
|
| 59 |
return $c->render( |
71 |
return $c->render( |
| 60 |
status => 200, |
72 |
status => 200, |
|
Lines 65-70
sub list {
Link Here
|
| 65 |
}; |
77 |
}; |
| 66 |
} |
78 |
} |
| 67 |
|
79 |
|
|
|
80 |
sub _buildPatronSearchQuery { |
| 81 |
my ( $self, $args ) = @_; |
| 82 |
my ( $search, $search_type, $search_fields ) = @$args{qw(search search_type search_fields)}; |
| 83 |
|
| 84 |
$search //= ''; |
| 85 |
$search =~ s/^\s+|\s+$//; |
| 86 |
if ( $search eq '' ) { |
| 87 |
return; |
| 88 |
} |
| 89 |
|
| 90 |
$search_type //= C4::Context->preference('DefaultPatronSearchMethod') // 'contains'; |
| 91 |
my $leading_wildcard = $search_type eq 'contains' ? '%' : ''; |
| 92 |
|
| 93 |
my $is_standard = 0; |
| 94 |
if ( !defined $search_fields || $search_fields eq '' || $search_fields eq 'standard' ) { |
| 95 |
$is_standard = 1; |
| 96 |
$search_fields = C4::Context->preference('DefaultPatronSearchFields') |
| 97 |
// 'firstname|preferred_name|middle_name|surname|othernames|cardnumber|userid'; |
| 98 |
} elsif ( $search_fields eq 'full_address' ) { |
| 99 |
$search_fields = 'streetnumber|streettype|address|address2|city|state|zipcode|country'; |
| 100 |
} elsif ( $search_fields eq 'all_emails' ) { |
| 101 |
$search_fields = 'email|emailpro|B_email'; |
| 102 |
} elsif ( $search_fields eq 'all_phones' ) { |
| 103 |
$search_fields = 'phone|phonepro|B_phone|altcontactphone|mobile'; |
| 104 |
} |
| 105 |
my @search_fields = split /\|/, $search_fields; |
| 106 |
|
| 107 |
my @searched_attribute_fields = map { s/^_ATTR_//r } grep { /^_ATTR_/ } @search_fields; |
| 108 |
@search_fields = grep { !/^_ATTR_/ } @search_fields; |
| 109 |
|
| 110 |
my @words = split /[\s,]+/, $search; |
| 111 |
@words = grep { length > 0 } @words; |
| 112 |
|
| 113 |
my @queries; |
| 114 |
|
| 115 |
my @word_subquery_and; |
| 116 |
foreach my $word (@words) { |
| 117 |
my @word_subquery_or; |
| 118 |
foreach my $field (@search_fields) { |
| 119 |
push @word_subquery_or, { "me.$field" => { like => sprintf( '%s%s%s', $leading_wildcard, $word, '%' ) } }; |
| 120 |
|
| 121 |
if ( $field eq 'dateofbirth' ) { |
| 122 |
eval { |
| 123 |
my $dt = Koha::DateUtils::dt_from_string($word); |
| 124 |
my $date = Koha::DateUtils::output_pref( { dt => $dt, dateformat => 'rfc3339', dateonly => 1 } ); |
| 125 |
push @word_subquery_or, { "me.$field" => $date }; |
| 126 |
}; |
| 127 |
} |
| 128 |
} |
| 129 |
push @word_subquery_and, \@word_subquery_or; |
| 130 |
} |
| 131 |
push @queries, { '-and' => \@word_subquery_and }; |
| 132 |
|
| 133 |
my @search_subquery_or; |
| 134 |
foreach my $field (@search_fields) { |
| 135 |
push @search_subquery_or, { "me.$field" => { like => sprintf( '%s%s%s', $leading_wildcard, $search, '%' ) } }; |
| 136 |
} |
| 137 |
push @queries, { '-or' => \@search_subquery_or }; |
| 138 |
|
| 139 |
if ( $is_standard && !@searched_attribute_fields ) { |
| 140 |
@searched_attribute_fields = |
| 141 |
Koha::Patron::Attribute::Types->search( { staff_searchable => 1, searched_by_default => 1 } ) |
| 142 |
->get_column('code'); |
| 143 |
} |
| 144 |
|
| 145 |
if ( C4::Context->preference('ExtendedPatronAttributes') && 0 < @searched_attribute_fields ) { |
| 146 |
|
| 147 |
# Add each word for each extended patron attributes |
| 148 |
my @extended_attribute_codes_to_search = @searched_attribute_fields; |
| 149 |
my @extended_attribute_subquery_and; |
| 150 |
foreach my $word (@words) { |
| 151 |
push @extended_attribute_subquery_and, [ |
| 152 |
{ |
| 153 |
'extended_attributes.attribute' => { like => sprintf( '%s%s%s', $leading_wildcard, $word, '%' ) }, |
| 154 |
'extended_attributes.code' => \@extended_attribute_codes_to_search, |
| 155 |
}, |
| 156 |
]; |
| 157 |
} |
| 158 |
push @queries, { '-and' => \@extended_attribute_subquery_and }; |
| 159 |
} |
| 160 |
|
| 161 |
return \@queries; |
| 162 |
} |
| 163 |
|
| 68 |
=head3 get |
164 |
=head3 get |
| 69 |
|
165 |
|
| 70 |
Controller function that handles retrieving a single Koha::Patron object |
166 |
Controller function that handles retrieving a single Koha::Patron object |