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

(-)a/Koha/Patrons.pm (+60 lines)
Lines 41-46 Koha::Patron - Koha Patron Object class Link Here
41
41
42
=cut
42
=cut
43
43
44
45
=head3 lookup
46
47
my $patrons = Koha::Patrons->lookup({
48
    search_term => $search_term,
49
    search_field => $search_field,
50
    search_type => $search_type
51
});
52
53
Parses a lookup request into a result set
54
55
=cut
56
57
sub lookup {
58
    my ( $self, $params ) = @_;
59
60
    my $search_term  = $params->{search_term};
61
    my $search_field = $params->{search_field};
62
    my $search_type  = $params->{search_type};
63
64
    my @terms         = split( /\s/, $search_term );
65
    my @search_fields = split( /,/,  $search_field );
66
    my $leading_wildcard = $search_type eq 'contains' ? '%' : '';
67
68
    my $query = {};
69
    my @term_query;
70
    foreach my $term (@terms) {
71
        my @field_query = ();
72
        foreach my $field (@search_fields) {
73
            push @field_query, { "me." . $field => { like => $leading_wildcard . $term . '%' } };
74
        }
75
        push @term_query, { -or => \@field_query };
76
    }
77
    push @{ $query->{-or} }, { -and => \@term_query };
78
79
    my $attributes_rs;
80
    if ( C4::Context->preference("ExtendedPatronAttributes") ) {
81
        my @attributes_query       = ();
82
        my $search_attribute_types = Koha::Patron::Attribute::Types->search( { staff_searchable => 1 } );
83
        foreach my $term (@terms) {
84
            my @attributes_subquery = ();
85
            while ( my $attribute = $search_attribute_types->next ) {
86
                push @attributes_subquery, {
87
                    "me.code"      => $attribute->code,
88
                    "me.attribute" => { like => $leading_wildcard . $term . '%' }
89
                };
90
            }
91
            push @attributes_query, \@attributes_subquery;
92
93
        }
94
        $attributes_rs = Koha::Patron::Attributes->search( { -and => \@attributes_query } );
95
    }
96
97
    push @{ $query->{-or} }, { 'me.borrowernumber' => { -in => [ $attributes_rs->get_column('borrowernumber') ] } };
98
99
    my $found = $self->search($query);
100
    return $found;
101
102
}
103
44
=head3 search_limited
104
=head3 search_limited
45
105
46
my $patrons = Koha::Patrons->search_limit( $params, $attributes );
106
my $patrons = Koha::Patrons->search_limit( $params, $attributes );
(-)a/Koha/REST/V1/Patrons.pm (+47 lines)
Lines 65-70 sub list { Link Here
65
    };
65
    };
66
}
66
}
67
67
68
69
=head3 lookup
70
71
Controller function that handles searching for KOha patrons
72
73
=cut
74
75
sub lookup {
76
    my $c = shift->openapi->valid_input or return;
77
78
    return try {
79
80
        my $query = {};
81
82
        my $search_term  = $c->param('search_term');
83
        my $search_field = $c->param('search_field');
84
        my $search_type  = $c->param('search_type');
85
        $c->req->params->remove('search_term');
86
        $c->req->params->remove('search_field');
87
        $c->req->params->remove('search_type');
88
        $c->req->params->remove('q');
89
90
        my $patrons = Koha::Patrons->lookup(
91
            {
92
                search_term  => $search_term,
93
                search_field => $search_field,
94
                search_type  => $search_type
95
            }
96
        );
97
98
        my $restricted = $c->param('restricted');
99
        $c->req->params->remove('restricted');
100
        $query->{debarred} = { '!=' => undef }
101
            if $restricted;
102
103
        my $patrons_rs = $patrons->search($query);
104
        $patrons = $c->objects->search($patrons_rs);
105
106
        return $c->render(
107
            status  => 200,
108
            openapi => $patrons
109
        );
110
    } catch {
111
        $c->unhandled_exception($_);
112
    };
113
}
114
68
=head3 get
115
=head3 get
69
116
70
Controller function that handles retrieving a single Koha::Patron object
117
Controller function that handles retrieving a single Koha::Patron object
(-)a/api/v1/swagger/paths/patrons.yaml (+81 lines)
Lines 449-454 Link Here
449
    x-koha-authorization:
449
    x-koha-authorization:
450
      permissions:
450
      permissions:
451
        borrowers: edit_borrowers
451
        borrowers: edit_borrowers
452
"/patrons/lookup":
453
  get:
454
    x-mojo-to: Patrons#lookup
455
    operationId: lookupPatrons
456
    tags:
457
      - patrons
458
    summary: Lookup patrons
459
    produces:
460
      - application/json
461
    parameters:
462
      - name: search_term
463
        in: query
464
        description: Term to use in searech
465
        required: false
466
        type: string
467
      - name: search_field
468
        in: query
469
        description: Field in the patron record to search
470
        required: false
471
        type: string
472
      - name: search_type
473
        in: query
474
        description: How to search terms, contains or starts with
475
        required: false
476
        type: string
477
        enum:
478
          - contains
479
          - starts_with
480
      - $ref: "../swagger.yaml#/parameters/match"
481
      - $ref: "../swagger.yaml#/parameters/order_by"
482
      - $ref: "../swagger.yaml#/parameters/page"
483
      - $ref: "../swagger.yaml#/parameters/per_page"
484
      - $ref: "../swagger.yaml#/parameters/q_param"
485
      - $ref: "../swagger.yaml#/parameters/q_body"
486
      - $ref: "../swagger.yaml#/parameters/request_id_header"
487
      - name: x-koha-embed
488
        in: header
489
        required: false
490
        description: Embed list sent as a request header
491
        type: array
492
        items:
493
          type: string
494
          enum:
495
            - extended_attributes
496
            - checkouts+count
497
            - overdues+count
498
            - account_balance
499
            - library
500
        collectionFormat: csv
501
    responses:
502
      "200":
503
        description: A list of patrons
504
        schema:
505
          type: array
506
          items:
507
            $ref: "../swagger.yaml#/definitions/patron"
508
      "401":
509
        description: Authentication required
510
        schema:
511
          $ref: "../swagger.yaml#/definitions/error"
512
      "403":
513
        description: Access forbidden
514
        schema:
515
          $ref: "../swagger.yaml#/definitions/error"
516
      "500":
517
        description: |
518
          Internal server error. Possible `error_code` attribute values:
519
520
          * `internal_server_error`
521
        schema:
522
          $ref: "../swagger.yaml#/definitions/error"
523
      "503":
524
        description: Under maintenance
525
        schema:
526
          $ref: "../swagger.yaml#/definitions/error"
527
    x-koha-authorization:
528
      permissions:
529
        - borrowers: "edit_borrowers"
530
        - tools: "label_creator"
531
        - serials: "routing"
532
        - acquisition: "order_manage"
452
"/patrons/{patron_id}":
533
"/patrons/{patron_id}":
453
  get:
534
  get:
454
    x-mojo-to: Patrons#get
535
    x-mojo-to: Patrons#get
(-)a/api/v1/swagger/swagger.yaml (+2 lines)
Lines 299-304 paths: Link Here
299
    $ref: ./paths/oauth.yaml#/~1oauth~1token
299
    $ref: ./paths/oauth.yaml#/~1oauth~1token
300
  /patrons:
300
  /patrons:
301
    $ref: ./paths/patrons.yaml#/~1patrons
301
    $ref: ./paths/patrons.yaml#/~1patrons
302
  "/patrons/lookup":
303
    $ref: ./paths/patrons.yaml#/~1patrons~1lookup
302
  "/patrons/{patron_id}":
304
  "/patrons/{patron_id}":
303
    $ref: "./paths/patrons.yaml#/~1patrons~1{patron_id}"
305
    $ref: "./paths/patrons.yaml#/~1patrons~1{patron_id}"
304
  "/patrons/{patron_id}/account":
306
  "/patrons/{patron_id}/account":
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/patron-search.inc (-6 / +15 lines)
Lines 278-284 Link Here
278
        [% CASE 'erm_users' %]
278
        [% CASE 'erm_users' %]
279
            let patron_search_url = '/api/v1/erm/users';
279
            let patron_search_url = '/api/v1/erm/users';
280
        [% CASE %]
280
        [% CASE %]
281
            let patron_search_url = '/api/v1/patrons';
281
            let patron_search_url = '/api/v1/patrons/lookup';
282
            let lookup = true;
282
        [% END %]
283
        [% END %]
283
        $(document).ready(function(){
284
        $(document).ready(function(){
284
285
Lines 309-314 Link Here
309
                }
310
                }
310
            });
311
            });
311
312
313
            let search_type = $("#searchtype_filter").val() || "contains";
314
            let search_fields = $("#searchfieldstype_filter").val();
315
            let pattern = $("#search_patron_filter").val();
316
            let additional_data = {};
317
            if( lookup ){
318
            additional_data = {
319
                "search_type": search_type,
320
                "search_field": search_fields,
321
                "search_term": pattern
322
            };
323
            }
324
312
            let additional_filters = {
325
            let additional_filters = {
313
                surname: function(){
326
                surname: function(){
314
                    let start_with = $("#firstletter_filter").val()
327
                    let start_with = $("#firstletter_filter").val()
Lines 318-327 Link Here
318
                "-and": function(){
331
                "-and": function(){
319
                    let filters = [];
332
                    let filters = [];
320
333
321
                    let search_type = $("#searchtype_filter").val() || "contains";
322
                    let search_fields = $("#searchfieldstype_filter").val();
323
                    let pattern = $("#search_patron_filter").val();
324
325
                    filters = buildPatronSearchQuery(
334
                    filters = buildPatronSearchQuery(
326
                        pattern,
335
                        pattern,
327
                        {
336
                        {
Lines 659-665 Link Here
659
                    });
668
                    });
660
                },
669
                },
661
                [% END %]
670
                [% END %]
662
            }, typeof table_settings !== 'undefined' ? table_settings : null, 1, additional_filters);
671
            }, typeof table_settings !== 'undefined' ? table_settings : null, 1, additional_filters, additional_data);
663
672
664
            $("#patron_search_form").on('submit', filter);
673
            $("#patron_search_form").on('submit', filter);
665
            $("#patron_search_form").on('submit', update_search_type);
674
            $("#patron_search_form").on('submit', update_search_type);
(-)a/koha-tmpl/intranet-tmpl/prog/js/datatables.js (-3 / +5 lines)
Lines 507-512 jQuery.fn.dataTable.ext.errMode = function(settings, note, message) { Link Here
507
function _dt_default_ajax (params){
507
function _dt_default_ajax (params){
508
    let default_filters = params.default_filters;
508
    let default_filters = params.default_filters;
509
    let options = params.options;
509
    let options = params.options;
510
    let additional_data = params.additional_data;
510
511
511
    if(!options.criteria || ['contains', 'starts_with', 'ends_with', 'exact'].indexOf(options.criteria.toLowerCase()) === -1) options.criteria = 'contains';
512
    if(!options.criteria || ['contains', 'starts_with', 'ends_with', 'exact'].indexOf(options.criteria.toLowerCase()) === -1) options.criteria = 'contains';
512
    options.criteria = options.criteria.toLowerCase();
513
    options.criteria = options.criteria.toLowerCase();
Lines 692-697 function _dt_default_ajax (params){ Link Here
692
                });
693
                });
693
                dataSet._order_by = orderArray.filter((v, i, a) => a.indexOf(v) === i).join(',');
694
                dataSet._order_by = orderArray.filter((v, i, a) => a.indexOf(v) === i).join(',');
694
            }
695
            }
696
            dataSet = { ...dataSet, ...additional_data };
695
697
696
            return dataSet;
698
            return dataSet;
697
        }
699
        }
Lines 938-946 function _dt_add_filters(table_node, table_dt, filters_options = {}) { Link Here
938
    *                                                available from the columns_settings template toolkit include
940
    *                                                available from the columns_settings template toolkit include
939
    * @param  {Boolean} add_filters                  Add a filters row as the top row of the table
941
    * @param  {Boolean} add_filters                  Add a filters row as the top row of the table
940
    * @param  {Object}  default_filters              Add a set of default search filters to apply at table initialisation
942
    * @param  {Object}  default_filters              Add a set of default search filters to apply at table initialisation
943
    * @param  {Object}  additional_data              Add additional parameters to the ajax data
941
    * @return {Object}                               The dataTables instance
944
    * @return {Object}                               The dataTables instance
942
    */
945
    */
943
    $.fn.kohaTable = function(options, table_settings, add_filters, default_filters) {
946
    $.fn.kohaTable = function(options, table_settings, add_filters, default_filters, additional_data) {
944
        var settings = null;
947
        var settings = null;
945
948
946
        if(options) {
949
        if(options) {
Lines 963-969 function _dt_add_filters(table_node, table_dt, filters_options = {}) { Link Here
963
                        'language': {
966
                        'language': {
964
                            'emptyTable': (options.emptyTable) ? options.emptyTable : __("No data available in table")
967
                            'emptyTable': (options.emptyTable) ? options.emptyTable : __("No data available in table")
965
                        },
968
                        },
966
                        'ajax': _dt_default_ajax({default_filters, options}),
969
                        'ajax': _dt_default_ajax({default_filters, options,additional_data}),
967
                    }, options);
970
                    }, options);
968
        }
971
        }
969
972
970
- 

Return to bug 33554