From 0c3b4bb30f294828be1e4c3cb29250a0e3634164 Mon Sep 17 00:00:00 2001 From: Pedro Amorim Date: Mon, 26 Jun 2023 12:51:13 +0000 Subject: [PATCH] Bug 34092: Move search-patron.inc logic into buildPatronSearchQuery Signed-off-by: Paul Derscheid Signed-off-by: Marcel de Rooy Signed-off-by: Tomas Cohen Arazi (cherry picked from commit a9f8db17fed36434ef831316f53ded6a478e6747) Signed-off-by: Martin Renvoize --- .../prog/en/includes/js_includes.inc | 1 + .../prog/en/includes/patron-search.inc | 63 +++++-------------- .../intranet-tmpl/prog/js/staff-global.js | 62 +++++++++++++++--- 3 files changed, 72 insertions(+), 54 deletions(-) diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/js_includes.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/js_includes.inc index 1e687f8ab7..bd41d755a6 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/js_includes.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/js_includes.inc @@ -71,6 +71,7 @@ diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/patron-search.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/patron-search.inc index e0c49c5506..be8590724c 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/patron-search.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/patron-search.inc @@ -19,6 +19,8 @@ [%# You can then pass a list of filters %] [%# - branch: select library list %] [%# - category: select patron category list %] +[%# - sort1: select patron sort1 field %] +[%# - sort2: select patron sort2 field %] [%# - search_field: select patron field list %] [%# - search_type: select 'contains' or 'starts with' %] [%- SET searchtype = Koha.Preference('DefaultPatronSearchMethod') -%] @@ -316,6 +318,20 @@ }, "-and": function(){ let filters = []; + + let search_type = $("#searchtype_filter").val() || "contains"; + let search_fields = $("#searchfieldstype_filter").val(); + let pattern = $("#search_patron_filter").val(); + + filters = buildPatronSearchQuery( + pattern, + { + search_type: search_type, + search_fields: search_fields, + ...(typeof extended_attribute_types != 'undefined' && {extended_attribute_types: extended_attribute_types}) + } + ); + let f_sort1 = $("#sort1_filter").val(); if ( f_sort1 ) { filters.push({ @@ -329,53 +345,6 @@ }); } - let pattern = $("#search_patron_filter").val(); - if (!pattern) { - if ( filters.length == 0 ) { - return ""; - } - else { - return filters; - } - } - let patterns = pattern.split(/[\s,]+/).filter(function(s){ return s.length }); - - let search_type = $("#searchtype_filter").val() || "contains"; - let search_fields = $("#searchfieldstype_filter").val(); - if ( !search_fields ) { - search_fields = "[% Koha.Preference('DefaultPatronSearchFields') || 'firstname,middle_name,surname,othernames,cardnumber,userid' | html %]"; - } - - let subquery_and = []; - patterns.forEach(function(pattern,i){ - let sub_or = []; - search_fields.split(',').forEach(function(attr,ii){ - sub_or.push({["me."+attr]:{"like":(search_type == "contains" ? "%" : "" ) + pattern + "%"}}); - if ( attr == 'dateofbirth' ) { - try { - let d = $date_to_rfc3339(pattern); - sub_or.push({["me."+attr]:d}); - } catch { - // Hide the warning if the date is not correct - } - } - }); - subquery_and.push(sub_or); - }); - filters.push({"-and": subquery_and}); - - [% IF Koha.Preference('ExtendedPatronAttributes') && extended_attribute_types %] - subquery_and = []; - patterns.forEach(function(pattern,i){ - let sub_or = []; - sub_or.push({ - "extended_attributes.value": { "like": "%" + pattern + (search_type == "contains" ? "%" : "" )}, - "extended_attributes.code": extended_attribute_types - }); - subquery_and.push(sub_or); - }); - filters.push({"-and": subquery_and}); - [% END %] return filters; } }; diff --git a/koha-tmpl/intranet-tmpl/prog/js/staff-global.js b/koha-tmpl/intranet-tmpl/prog/js/staff-global.js index 80d594c458..02bc39b8f8 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/staff-global.js +++ b/koha-tmpl/intranet-tmpl/prog/js/staff-global.js @@ -510,22 +510,58 @@ function patron_autocomplete(node, options) { }; } - -function buildPatronSearchQuery(term) { +/** + * Build patron search query + * - term: The full search term input by the user + * You can then pass a list of options: + * - search_type: String 'contains' or 'starts_with', defaults to DefaultPatronSearchMethod system preference + * - search_fields: String comma-separated list of specific fields, defaults to DefaultPatronSearchFields system preference + * - extended_attribute_types: JSON object containing the patron attribute types to be searched on + */ +function buildPatronSearchQuery(term, options) { let q = []; - let leading_wildcard = defaultPatronSearchMethod === 'contains' ? '%' : ''; + let leading_wildcard; + let search_fields; + let patterns = term.split(/[\s,]+/).filter(function (s) { return s.length }); + + // Bail if no patterns + if (patterns.length == 0) { + return; + } + + // Leading wildcard: If search_type option exists, we use that + if (typeof options !== 'undefined' && options.search_type) { + leading_wildcard = options.search_type === "contains" ? '%' : ''; + // If not, we use DefaultPatronSearchMethod system preference instead + } else { + leading_wildcard = defaultPatronSearchMethod === 'contains' ? '%' : ''; + } + + // Search fields: If search_fields option exists, we use that + if (typeof options !== 'undefined' && options.search_fields) { + search_fields = options.search_fields; + // If not, we use DefaultPatronSearchFields system preference instead + } else { + search_fields = defaultPatronSearchFields; + } // Add each pattern for each search field let pattern_subquery_and = []; - term.split(/[\s,]+/) - .filter(function (s) { return s.length }) - .forEach(function (pattern, i) { + patterns.forEach(function (pattern, i) { let pattern_subquery_or = []; defaultPatronSearchFields.split(',').forEach(function (field, i) { pattern_subquery_or.push( { ["me." + field]: { 'like': leading_wildcard + pattern + '%' } } ); + if (field == 'dateofbirth') { + try { + let d = $date_to_rfc3339(pattern); + pattern_subquery_or.push({ ["me." + field]: d }); + } catch { + // Hide the warning if the date is not correct + } + } }); pattern_subquery_and.push(pattern_subquery_or); }); @@ -540,6 +576,18 @@ function buildPatronSearchQuery(term) { }); q.push({ "-or": term_subquery_or }); - + // Add each pattern for each extended patron attributes + if (typeof options !== 'undefined' && options.extended_attribute_types && extendedPatronAttributes) { + extended_attribute_subquery_and = []; + patterns.forEach(function (pattern, i) { + let extended_attribute_sub_or = []; + extended_attribute_sub_or.push({ + "extended_attributes.value": { "like": leading_wildcard + pattern + '%' }, + "extended_attributes.code": options.extended_attribute_types + }); + extended_attribute_subquery_and.push(extended_attribute_sub_or); + }); + q.push({ "-and": extended_attribute_subquery_and }); + } return q; } -- 2.39.5