View | Details | Raw Unified | Return to bug 14874
Collapse All | Expand All

(-)a/C4/Utils/DataTables/Members.pm (-5 / +12 lines)
Lines 59-65 sub search { Link Here
59
    }
59
    }
60
60
61
    my $searchfields = {
61
    my $searchfields = {
62
        standard => 'surname,firstname,othernames,cardnumber,userid',
62
        standard => C4::Context->preference('DefaultPatronSearchFields'),
63
        surname => 'surname',
63
        surname => 'surname',
64
        email => 'email,emailpro,B_email',
64
        email => 'email,emailpro,B_email',
65
        borrowernumber => 'borrowernumber',
65
        borrowernumber => 'borrowernumber',
Lines 87-96 sub search { Link Here
87
    foreach my $term (@terms) {
87
    foreach my $term (@terms) {
88
        next unless $term;
88
        next unless $term;
89
89
90
        $term .= '%' # end with anything
90
        my $term_dt = eval { local $SIG{__WARN__} = {}; output_pref( { str => $term, dateonly => 1, dateformat => 'sql' } ); };
91
            if $term !~ /%$/;
91
92
        $term = "%$term" # begin with anythin unless start_with
92
        if ($term_dt) {
93
            if $searchtype eq 'contain' && $term !~ /^%/;
93
            $term                 = $term_dt;
94
        } else {
95
            $term .= '%'    # end with anything
96
              if $term !~ /%$/;
97
            $term = "%$term"    # begin with anythin unless start_with
98
              if $searchtype eq 'contain' && $term !~ /^%/;
99
        }
94
100
95
        my @where_strs_or;
101
        my @where_strs_or;
96
        for my $searchfield ( split /,/, $searchfields->{$searchfieldstype} ) {
102
        for my $searchfield ( split /,/, $searchfields->{$searchfieldstype} ) {
Lines 135-140 sub search { Link Here
135
        ($limit ? $limit : "")
141
        ($limit ? $limit : "")
136
    );
142
    );
137
    my $sth = $dbh->prepare($query);
143
    my $sth = $dbh->prepare($query);
144
138
    $sth->execute(@where_args);
145
    $sth->execute(@where_args);
139
    my $patrons = $sth->fetchall_arrayref({});
146
    my $patrons = $sth->fetchall_arrayref({});
140
147
(-)a/installer/data/mysql/atomicupdate/bug14874-addDefaultPatronSearchFieldspreference (+1 lines)
Line 0 Link Here
1
INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type) VALUES ('DefaultPatronSearchFields','surname,firstname,othernames,cardnumber,userid',NULL,'Comma separated list defining the default fields to be used during a patron search','free');
(-)a/installer/data/mysql/sysprefs.sql (+1 lines)
Lines 116-121 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
116
('DefaultLongOverdueChargeValue', '', NULL, "Charge a lost item to the borrower's account when the LOST value of the item changes to n.", 'integer'),
116
('DefaultLongOverdueChargeValue', '', NULL, "Charge a lost item to the borrower's account when the LOST value of the item changes to n.", 'integer'),
117
('DefaultLongOverdueDays', '', NULL, "Set the LOST value of an item when the item has been overdue for more than n days.", 'integer'),
117
('DefaultLongOverdueDays', '', NULL, "Set the LOST value of an item when the item has been overdue for more than n days.", 'integer'),
118
('DefaultLongOverdueLostValue', '', NULL, "Set the LOST value of an item to n when the item has been overdue for more than defaultlongoverduedays days.", 'integer'),
118
('DefaultLongOverdueLostValue', '', NULL, "Set the LOST value of an item to n when the item has been overdue for more than defaultlongoverduedays days.", 'integer'),
119
('DefaultPatronSearchFields',    'surname,firstname,othernames,cardnumber,userid',NULL,'Comma separated list defining the default fields to be used during a patron search','free');
119
('defaultSortField','relevance','relevance|popularity|call_number|pubdate|acqdate|title|author','Specify the default field used for sorting','Choice'),
120
('defaultSortField','relevance','relevance|popularity|call_number|pubdate|acqdate|title|author','Specify the default field used for sorting','Choice'),
120
('defaultSortOrder','dsc','asc|dsc|az|za','Specify the default sort order','Choice'),
121
('defaultSortOrder','dsc','asc|dsc|az|za','Specify the default sort order','Choice'),
121
('DefaultToLoggedInLibraryCircRules',  '0', NULL ,  'If enabled, circ rules editor will default to the logged in library''s rules, rather than the ''all libraries'' rules.',  'YesNo'),
122
('DefaultToLoggedInLibraryCircRules',  '0', NULL ,  'If enabled, circ rules editor will default to the logged in library''s rules, rather than the ''all libraries'' rules.',  'YesNo'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/circ-patron-search-results.inc (+2 lines)
Lines 16-21 Link Here
16
        <tr>
16
        <tr>
17
            <th>Name</th>
17
            <th>Name</th>
18
            <th>Card number</th>
18
            <th>Card number</th>
19
            <th>Date of birth</th>
19
            <th>Category</th>
20
            <th>Category</th>
20
            <th>Library</th>
21
            <th>Library</th>
21
            <th>Address</th>
22
            <th>Address</th>
Lines 31-36 Link Here
31
                    <td><a href="/cgi-bin/koha/reserve/request.pl?borrowernumber=[% borrower.borrowernumber %]&amp;biblionumber=[% biblionumber %]">[% borrower.surname %], [% borrower.firstname %]</a></td>
32
                    <td><a href="/cgi-bin/koha/reserve/request.pl?borrowernumber=[% borrower.borrowernumber %]&amp;biblionumber=[% biblionumber %]">[% borrower.surname %], [% borrower.firstname %]</a></td>
32
            [% END %]
33
            [% END %]
33
                <td>[% borrower.cardnumber %]</td>
34
                <td>[% borrower.cardnumber %]</td>
35
                <td>[% borrower.dateofbirth %]</td>
34
                <td>[% Categories.GetName( borrower.categorycode ) %]</td>
36
                <td>[% Categories.GetName( borrower.categorycode ) %]</td>
35
                <td>[% Branches.GetName( borrower.branchcode ) %]</td>
37
                <td>[% Branches.GetName( borrower.branchcode ) %]</td>
36
                <td>[% borrower.address %]</td>
38
                <td>[% borrower.address %]</td>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref (+4 lines)
Lines 109-114 Patrons: Link Here
109
           class: integer
109
           class: integer
110
         - results per page in the staff client.
110
         - results per page in the staff client.
111
     -
111
     -
112
         - pref: DefaultPatronSearchFields
113
           class: multi
114
         - "Comma separated list defining the default fields to be used during a patron search"
115
     -
112
         - pref: PatronQuickAddFields
116
         - pref: PatronQuickAddFields
113
           class: multi
117
           class: multi
114
         - (separate columns with |)
118
         - (separate columns with |)
(-)a/t/db_dependent/Utils/Datatables_Members.t (-98 / +146 lines)
Lines 17-23 Link Here
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
19
20
use Test::More tests => 27;
20
use Test::More tests => 47;
21
21
22
use C4::Context;
22
use C4::Context;
23
use C4::Members;
23
use C4::Members;
Lines 29-125 use Koha::Library; Link Here
29
use Koha::Patron::Categories;
29
use Koha::Patron::Categories;
30
30
31
use t::lib::Mocks;
31
use t::lib::Mocks;
32
use t::lib::TestBuilder;
33
34
use Koha::Database;
32
35
33
use_ok( "C4::Utils::DataTables::Members" );
36
use_ok( "C4::Utils::DataTables::Members" );
34
37
35
my $dbh = C4::Context->dbh;
38
my $schema = Koha::Database->new->schema;
36
39
$schema->storage->txn_begin;
37
# Start transaction
38
$dbh->{AutoCommit} = 0;
39
$dbh->{RaiseError} = 1;
40
41
# Pick a categorycode from the DB
42
my @categories   = Koha::Patron::Categories->search_limited;
43
my $categorycode = $categories[0]->categorycode;
44
# Add a new branch so we control what borrowers it has
45
my $branchcode   = "UNC";
46
my $branch_data = {
47
    branchcode     => $branchcode,
48
    branchname     => 'Universidad Nacional de Cordoba',
49
    branchaddress1 => 'Haya de la Torre',
50
    branchaddress2 => 'S/N',
51
    branchzip      => '5000',
52
    branchcity     => 'Cordoba',
53
    branchstate    => 'Cordoba',
54
    branchcountry  => 'Argentina'
55
};
56
Koha::Library->new( $branch_data )->store;
57
58
my %john_doe = (
59
    cardnumber   => '123456',
60
    firstname    => 'John',
61
    surname      => 'Doe',
62
    categorycode => $categorycode,
63
    branchcode   => $branchcode,
64
    dateofbirth  => '',
65
    dateexpiry   => '9999-12-31',
66
    userid       => 'john.doe'
67
);
68
40
69
my %john_smith = (
41
my $builder = t::lib::TestBuilder->new;
70
    cardnumber   => '234567',
71
    firstname    =>  'John',
72
    surname      => 'Smith',
73
    categorycode => $categorycode,
74
    branchcode   => $branchcode,
75
    dateofbirth  => '',
76
    dateexpiry   => '9999-12-31',
77
    userid       => 'john.smith'
78
);
79
42
80
my %jane_doe = (
43
my $library = $builder->build({
81
    cardnumber   => '345678',
44
    source => "Branch",
82
    firstname    =>  'Jane',
45
});
83
    surname      => 'Doe',
84
    categorycode => $categorycode,
85
    branchcode   => $branchcode,
86
    dateofbirth  => '',
87
    dateexpiry   => '9999-12-31',
88
    userid       => 'jane.doe'
89
);
90
46
91
my %jeanpaul_dupont = (
47
my $branchcode=$library->{branchcode};
92
    cardnumber   => '456789',
48
93
    firstname    => 'Jean Paul',
49
my $john_doe = $builder->build({
94
    surname      => 'Dupont',
50
        source => "Borrower",
95
    categorycode => $categorycode,
51
        value => {
96
    branchcode   => $branchcode,
52
            cardnumber   => '123456',
97
    dateofbirth  => '',
53
            firstname    => 'John',
98
    dateexpiry   => '9999-12-31',
54
            surname      => 'Doe',
99
    userid       => 'jeanpaul.dupont'
55
            branchcode   => $branchcode,
100
);
56
            dateofbirth  => '1983-03-01',
57
            userid       => 'john.doe'
58
        },
59
});
101
60
102
my %dupont_brown = (
61
my $john_smith = $builder->build({
103
    cardnumber   => '567890',
62
        source => "Borrower",
104
    firstname    => 'Dupont',
63
        value => {
105
    surname      => 'Brown',
64
            cardnumber   => '234567',
106
    categorycode => $categorycode,
65
            firstname    => 'John',
107
    branchcode   => $branchcode,
66
            surname      => 'Smith',
108
    dateofbirth  => '',
67
            branchcode   => $branchcode,
109
    dateexpiry   => '9999-12-31',
68
            dateofbirth  => '1982-02-01',
110
    userid       => 'dupont.brown'
69
            userid       => 'john.smith'
111
);
70
        },
71
});
112
72
113
$john_doe{borrowernumber} = AddMember( %john_doe );
73
my $jane_doe = $builder->build({
114
warn "Error adding John Doe, check your tests" unless $john_doe{borrowernumber};
74
        source => "Borrower",
115
$john_smith{borrowernumber} = AddMember( %john_smith );
75
        value => {
116
warn "Error adding John Smith, check your tests" unless $john_smith{borrowernumber};
76
            cardnumber   => '345678',
117
$jane_doe{borrowernumber} = AddMember( %jane_doe );
77
            firstname    => 'Jane',
118
warn "Error adding Jane Doe, check your tests" unless $jane_doe{borrowernumber};
78
            surname      => 'Doe',
119
$jeanpaul_dupont{borrowernumber} = AddMember( %jeanpaul_dupont );
79
            branchcode   => $branchcode,
120
warn "Error adding Jean Paul Dupont, check your tests" unless $jeanpaul_dupont{borrowernumber};
80
            dateofbirth  => '1983-03-01',
121
$dupont_brown{borrowernumber} = AddMember( %dupont_brown );
81
            userid       => 'jane.doe'
122
warn "Error adding Dupont Brown, check your tests" unless $dupont_brown{borrowernumber};
82
        },
83
});
84
my $jeanpaul_dupont = $builder->build({
85
        source => "Borrower",
86
        value => {
87
            cardnumber   => '456789',
88
            firstname    => 'Jean Paul',
89
            surname      => 'Dupont',
90
            branchcode   => $branchcode,
91
            dateofbirth  => '1982-02-01',
92
            userid       => 'jeanpaul.dupont'
93
        },
94
});
95
my $dupont_brown = $builder->build({
96
        source => "Borrower",
97
        value => {
98
            cardnumber   => '567890',
99
            firstname    => 'Dupont',
100
            surname      => 'Brown',
101
            branchcode   => $branchcode,
102
            dateofbirth  => '1979-01-01',
103
            userid       => 'dupont.brown'
104
        },
105
});
123
106
124
# Set common datatables params
107
# Set common datatables params
125
my %dt_params = (
108
my %dt_params = (
Lines 139-145 my $search_results = C4::Utils::DataTables::Members::search({ Link Here
139
is( $search_results->{ iTotalDisplayRecords }, 1,
122
is( $search_results->{ iTotalDisplayRecords }, 1,
140
    "John Doe has only one match on $branchcode (Bug 12595)");
123
    "John Doe has only one match on $branchcode (Bug 12595)");
141
124
142
ok( $search_results->{ patrons }[0]->{ cardnumber } eq $john_doe{ cardnumber }
125
ok( $search_results->{ patrons }[0]->{ cardnumber } eq $john_doe->{ cardnumber }
143
    && ! $search_results->{ patrons }[1],
126
    && ! $search_results->{ patrons }[1],
144
    "John Doe is the only match (Bug 12595)");
127
    "John Doe is the only match (Bug 12595)");
145
128
Lines 156-162 is( $search_results->{ iTotalDisplayRecords }, 1, Link Here
156
    "Jane Doe has only one match on $branchcode (Bug 12595)");
139
    "Jane Doe has only one match on $branchcode (Bug 12595)");
157
140
158
is( $search_results->{ patrons }[0]->{ cardnumber },
141
is( $search_results->{ patrons }[0]->{ cardnumber },
159
    $jane_doe{ cardnumber },
142
    $jane_doe->{ cardnumber },
160
    "Jane Doe is the only match (Bug 12595)");
143
    "Jane Doe is the only match (Bug 12595)");
161
144
162
# Search "John"
145
# Search "John"
Lines 172-182 is( $search_results->{ iTotalDisplayRecords }, 2, Link Here
172
    "There are two John at $branchcode");
155
    "There are two John at $branchcode");
173
156
174
is( $search_results->{ patrons }[0]->{ cardnumber },
157
is( $search_results->{ patrons }[0]->{ cardnumber },
175
    $john_doe{ cardnumber },
158
    $john_doe->{ cardnumber },
176
    "John Doe is the first result");
159
    "John Doe is the first result");
177
160
178
is( $search_results->{ patrons }[1]->{ cardnumber },
161
is( $search_results->{ patrons }[1]->{ cardnumber },
179
    $john_smith{ cardnumber },
162
    $john_smith->{ cardnumber },
180
    "John Smith is the second result");
163
    "John Smith is the second result");
181
164
182
# Search "Doe"
165
# Search "Doe"
Lines 192-202 is( $search_results->{ iTotalDisplayRecords }, 2, Link Here
192
    "There are two Doe at $branchcode");
175
    "There are two Doe at $branchcode");
193
176
194
is( $search_results->{ patrons }[0]->{ cardnumber },
177
is( $search_results->{ patrons }[0]->{ cardnumber },
195
    $john_doe{ cardnumber },
178
    $john_doe->{ cardnumber },
196
    "John Doe is the first result");
179
    "John Doe is the first result");
197
180
198
is( $search_results->{ patrons }[1]->{ cardnumber },
181
is( $search_results->{ patrons }[1]->{ cardnumber },
199
    $jane_doe{ cardnumber },
182
    $jane_doe->{ cardnumber },
200
    "Jane Doe is the second result");
183
    "Jane Doe is the second result");
201
184
202
# Search "Smith" as surname - there is only one occurrence of Smith
185
# Search "Smith" as surname - there is only one occurrence of Smith
Lines 212-218 is( $search_results->{ iTotalDisplayRecords }, 1, Link Here
212
    "There is one Smith at $branchcode when searching for surname");
195
    "There is one Smith at $branchcode when searching for surname");
213
196
214
is( $search_results->{ patrons }[0]->{ cardnumber },
197
is( $search_results->{ patrons }[0]->{ cardnumber },
215
    $john_smith{ cardnumber },
198
    $john_smith->{ cardnumber },
216
    "John Smith is the first result");
199
    "John Smith is the first result");
217
200
218
# Search "Dupont" as surname - Dupont is used both as firstname and surname, we
201
# Search "Dupont" as surname - Dupont is used both as firstname and surname, we
Lines 229-235 is( $search_results->{ iTotalDisplayRecords }, 1, Link Here
229
    "There is one Dupont at $branchcode when searching for surname");
212
    "There is one Dupont at $branchcode when searching for surname");
230
213
231
is( $search_results->{ patrons }[0]->{ cardnumber },
214
is( $search_results->{ patrons }[0]->{ cardnumber },
232
    $jeanpaul_dupont{ cardnumber },
215
    $jeanpaul_dupont->{ cardnumber },
233
    "Jean Paul Dupont is the first result");
216
    "Jean Paul Dupont is the first result");
234
217
235
# Search "Doe" as surname - Doe is used twice as surname
218
# Search "Doe" as surname - Doe is used twice as surname
Lines 245-255 is( $search_results->{ iTotalDisplayRecords }, 2, Link Here
245
    "There are two Doe at $branchcode when searching for surname");
228
    "There are two Doe at $branchcode when searching for surname");
246
229
247
is( $search_results->{ patrons }[0]->{ cardnumber },
230
is( $search_results->{ patrons }[0]->{ cardnumber },
248
    $john_doe{ cardnumber },
231
    $john_doe->{ cardnumber },
249
    "John Doe is the first result");
232
    "John Doe is the first result");
250
233
251
is( $search_results->{ patrons }[1]->{ cardnumber },
234
is( $search_results->{ patrons }[1]->{ cardnumber },
252
    $jane_doe{ cardnumber },
235
    $jane_doe->{ cardnumber },
253
    "Jane Doe is the second result");
236
    "Jane Doe is the second result");
254
237
255
# Search by userid
238
# Search by userid
Lines 292-301 $attribute_type->store; Link Here
292
275
293
276
294
C4::Members::Attributes::SetBorrowerAttributes(
277
C4::Members::Attributes::SetBorrowerAttributes(
295
    $john_doe{borrowernumber}, [ { code => $attribute_type->{code}, value => 'the default value for a common user' } ]
278
    $john_doe->{borrowernumber}, [ { code => $attribute_type->{code}, value => 'the default value for a common user' } ]
296
);
279
);
297
C4::Members::Attributes::SetBorrowerAttributes(
280
C4::Members::Attributes::SetBorrowerAttributes(
298
    $jane_doe{borrowernumber}, [ { code => $attribute_type->{code}, value => 'the default value for another common user' } ]
281
    $jane_doe->{borrowernumber}, [ { code => $attribute_type->{code}, value => 'the default value for another common user' } ]
299
);
282
);
300
283
301
t::lib::Mocks::mock_preference('ExtendedPatronAttributes', 1);
284
t::lib::Mocks::mock_preference('ExtendedPatronAttributes', 1);
Lines 363-369 $search_results = C4::Utils::DataTables::Members::search({ Link Here
363
is( $search_results->{ iTotalDisplayRecords }, 1,
346
is( $search_results->{ iTotalDisplayRecords }, 1,
364
    "Jean Paul Dupont is found using contains and two terms search 'Jea Pau' (Bug 15252)");
347
    "Jean Paul Dupont is found using contains and two terms search 'Jea Pau' (Bug 15252)");
365
348
349
my @datetimeprefs = ("dmydot","iso","metric","us");
350
my %dates_in_pref = (
351
        dmydot  => ["01.02.1982","01.03.1983","01.01.1979","01.01.1988"],
352
        iso     => ["1982-02-01","1983-03-01","1979-01-01","1988-01-01"],
353
        metric  => ["01/02/1982","01/03/1983","01/01/1979","01/01/1988"],
354
        us      => ["02/01/1982","03/01/1983","01/01/1979","01/01/1988"],
355
        );
356
foreach my $dateformloo (@datetimeprefs){
357
    t::lib::Mocks::mock_preference('dateformat', $dateformloo);
358
    t::lib::Mocks::mock_preference('DefaultPatronSearchFields', 'surname,firstname,othernames,userid,dateofbirth');
359
    $search_results = C4::Utils::DataTables::Members::search({
360
        searchmember     => $dates_in_pref{$dateformloo}[0],
361
        searchfieldstype => 'standard',
362
        searchtype       => 'contain',
363
        branchcode       => $branchcode,
364
        dt_params        => \%dt_params
365
    });
366
367
    is( $search_results->{ iTotalDisplayRecords }, 2,
368
        "dateformat: $dateformloo Two borrowers have dob $dates_in_pref{$dateformloo}[0], standard search fields plus dob works");
369
370
    $search_results = C4::Utils::DataTables::Members::search({
371
        searchmember     => $dates_in_pref{$dateformloo}[2],
372
        searchfieldstype => 'standard',
373
        searchtype       => 'contain',
374
        branchcode       => $branchcode,
375
        dt_params        => \%dt_params
376
    });
377
378
    is( $search_results->{ iTotalDisplayRecords }, 1,
379
        "dateformat: $dateformloo One borrower has dob $dates_in_pref{$dateformloo}[2], standard search fields plus dob works");
380
381
    $search_results = C4::Utils::DataTables::Members::search({
382
        searchmember     => $dates_in_pref{$dateformloo}[1],
383
        searchfieldstype => 'dateofbirth',
384
        searchtype       => 'contain',
385
        branchcode       => $branchcode,
386
        dt_params        => \%dt_params
387
    });
388
389
    is( $search_results->{ iTotalDisplayRecords }, 2,
390
        "dateformat: $dateformloo Two borrowers have dob $dates_in_pref{$dateformloo}[1], dateofbirth search field works");
391
392
    $search_results = C4::Utils::DataTables::Members::search({
393
        searchmember     => $dates_in_pref{$dateformloo}[3],
394
        searchfieldstype => 'dateofbirth',
395
        searchtype       => 'contain',
396
        branchcode       => $branchcode,
397
        dt_params        => \%dt_params
398
    });
399
400
    is( $search_results->{ iTotalDisplayRecords }, 0,
401
        "dateformat: $dateformloo No borrowers have dob $dates_in_pref{$dateformloo}[3], dateofbirth search field works");
402
403
    $search_results = C4::Utils::DataTables::Members::search({
404
        searchmember     => $dates_in_pref{$dateformloo}[3],
405
        searchfieldstype => 'standard',
406
        searchtype       => 'contain',
407
        branchcode       => $branchcode,
408
        dt_params        => \%dt_params
409
    });
410
411
    is( $search_results->{ iTotalDisplayRecords }, 0,
412
        "dateformat: $dateformloo No borrowers have dob $dates_in_pref{$dateformloo}[3], standard search fields plus dob works");
413
}
414
366
# End
415
# End
367
$dbh->rollback;
416
$schema->storage->txn_rollback;
368
417
369
1;
418
1;
370
- 

Return to bug 14874