'JSON search method for S3PersonAutocompleteWidget and S3AddPersonWidget2
- full name search'

@staticmethod
def pr_search_ac(r, **attr):

    response = current.response
    resource = r.resource
    resource.add_filter(response.s3.filter)
    _vars = current.request.get_vars
    value = (_vars.term or _vars.value or _vars.q or None)
    if (not value):
        output = current.xml.json_message(False, 400, 'No    value    provided!')
        raise HTTP(400, body=output)
    value = s3_unicode(value).lower()
    value = value.strip()
    settings = current.deployment_settings
    name_format = settings.get_pr_name_format()
    middle_name = ('middle_name' in name_format)
    query = (FS('first_name').lower().like((value + '%')) | FS('last_name').lower().like((value + '%')))
    if middle_name:
        query |= FS('middle_name').lower().like((value + '%'))
    if ('    ' in value):
        (value1, value2) = value.split('    ', 1)
        query |= ((FS('first_name').lower().like((value1 + '%')) & FS('last_name').lower().like((value2 + '%'))) | (FS('first_name').lower().like((value2 + '%')) & FS('last_name').lower().like((value1 + '%'))))
        if middle_name:
            query |= ((((FS('first_name').lower().like((value1 + '%')) & FS('middle_name').lower().like((value2 + '%'))) | (FS('first_name').lower().like((value2 + '%')) & FS('middle_name').lower().like((value1 + '%')))) | (FS('middle_name').lower().like((value1 + '%')) & FS('last_name').lower().like((value2 + '%')))) | (FS('middle_name').lower().like((value2 + '%')) & FS('last_name').lower().like((value1 + '%'))))
        if ('    ' in value2):
            (value21, value3) = value2.split('    ', 1)
            value12 = ('%s    %s' % (value1, value21))
            query |= ((FS('first_name').lower().like((value12 + '%')) & FS('last_name').lower().like((value3 + '%'))) | (FS('first_name').lower().like((value3 + '%')) & FS('last_name').lower().like((value12 + '%'))))
            if middle_name:
                query |= (((((FS('first_name').lower().like((value1 + '%')) & FS('middle_name').lower().like((value21 + '%'))) & FS('last_name').lower().like((value3 + '%'))) | ((FS('first_name').lower().like((value1 + '%')) & FS('last_name').lower().like((value21 + '%'))) & FS('middle_name').lower().like((value3 + '%')))) | ((FS('last_name').lower().like((value1 + '%')) & FS('middle_name').lower().like((value21 + '%'))) & FS('first_name').lower().like((value3 + '%')))) | ((FS('last_name').lower().like((value1 + '%')) & FS('first_name').lower().like((value21 + '%'))) & FS('middle_name').lower().like((value3 + '%'))))
            if ('    ' in value3):
                (value31, value4) = value3.split('    ', 1)
                value13 = ('%s    %s    %s' % (value1, value21, value31))
                value22 = ('%s    %s' % (value21, value31))
                query |= ((FS('first_name').lower().like((value13 + '%')) & FS('last_name').lower().like((value4 + '%'))) | (FS('first_name').lower().like((value4 + '%')) & FS('last_name').lower().like((value13 + '%'))))
                if middle_name:
                    query |= (((((((((FS('first_name').lower().like((value1 + '%')) & FS('middle_name').lower().like((value22 + '%'))) & FS('last_name').lower().like((value4 + '%'))) | ((FS('first_name').lower().like((value1 + '%')) & FS('last_name').lower().like((value22 + '%'))) & FS('middle_name').lower().like((value4 + '%')))) | ((FS('last_name').lower().like((value1 + '%')) & FS('middle_name').lower().like((value22 + '%'))) & FS('first_name').lower().like((value4 + '%')))) | ((FS('last_name').lower().like((value1 + '%')) & FS('first_name').lower().like((value22 + '%'))) & FS('middle_name').lower().like((value4 + '%')))) | ((FS('first_name').lower().like((value12 + '%')) & FS('middle_name').lower().like((value31 + '%'))) & FS('last_name').lower().like((value4 + '%')))) | ((FS('first_name').lower().like((value12 + '%')) & FS('last_name').lower().like((value31 + '%'))) & FS('middle_name').lower().like((value4 + '%')))) | ((FS('last_name').lower().like((value12 + '%')) & FS('middle_name').lower().like((value31 + '%'))) & FS('first_name').lower().like((value4 + '%')))) | ((FS('last_name').lower().like((value12 + '%')) & FS('first_name').lower().like((value31 + '%'))) & FS('middle_name').lower().like((value4 + '%'))))
    resource.add_filter(query)
    limit = int((_vars.limit or 0))
    MAX_SEARCH_RESULTS = settings.get_search_max_results()
    if (((not limit) or (limit > MAX_SEARCH_RESULTS)) and (resource.count() > MAX_SEARCH_RESULTS)):
        msg = current.T('There    are    more    than    %(max)s    results,    please    input    more    characters.')
        output = [{'label': s3_str((msg % {'max': MAX_SEARCH_RESULTS}))}]
    else:
        fields = ['id', 'first_name', 'middle_name', 'last_name']
        show_hr = settings.get_pr_search_shows_hr_details()
        if show_hr:
            fields.append('human_resource.job_title_id$name')
            show_orgs = settings.get_hrm_show_organisation()
            if show_orgs:
                fields.append('human_resource.organisation_id$name')
        name_format = settings.get_pr_name_format()
        match = re.match('\\s*?%\\((?P<fname>.*?)\\)s.*', name_format)
        if match:
            orderby = ('pr_person.%s' % match.group('fname'))
        else:
            orderby = 'pr_person.first_name'
        rows = resource.select(fields=fields, start=0, limit=limit, orderby=orderby)['rows']
        items = []
        iappend = items.append
        for row in rows:
            name = Storage(first_name=row['pr_person.first_name'], middle_name=row['pr_person.middle_name'], last_name=row['pr_person.last_name'])
            name = s3_fullname(name)
            item = {'id': row['pr_person.id'], 'name': name}
            if show_hr:
                job_title = row.get('hrm_job_title.name', None)
                if job_title:
                    item['job'] = job_title
                if show_orgs:
                    org = row.get('org_organisation.name', None)
                    if org:
                        item['org'] = org
            iappend(item)
        output = items
    response.headers['Content-Type'] = 'application/json'
    return json.dumps(output, separators=SEPARATORS)
