'Apply method.
@param r: the S3Request
@param attr: controller options for this request'

def apply_method(self, r, **attr):

    component = self.component
    components = r.resource.components
    for c in components:
        if (c == component):
            component = components[c]
            break
    try:
        if component.link:
            component = component.link
    except:
        current.log.error('Invalid    Component!')
        raise
    tablename = component.tablename
    authorised = current.auth.s3_has_permission('create', tablename)
    if (not authorised):
        r.unauthorised()
    settings = current.deployment_settings
    types = self.types
    if (not types):
        if settings.has_module('vol'):
            types = (1, 2)
        else:
            types = (1,)
    if (types == (2,)):
        controller = 'vol'
    else:
        controller = 'hrm'
    T = current.T
    db = current.db
    s3db = current.s3db
    table = s3db[tablename]
    fkey = component.fkey
    record = r.record
    if (fkey in record):
        record_id = record[fkey]
    else:
        record_id = r.id
    get_vars = r.get_vars
    response = current.response
    if (r.http == 'POST'):
        added = 0
        post_vars = r.post_vars
        if all([(n in post_vars) for n in ('assign', 'selected', 'mode')]):
            selected = post_vars.selected
            if selected:
                selected = selected.split(',')
            else:
                selected = []
            if (post_vars.mode == 'Exclusive'):
                if ('filterURL' in post_vars):
                    filters = S3URLQuery.parse_url(post_vars.filterURL)
                else:
                    filters = None
                query = (~ FS('id').belongs(selected))
                hresource = s3db.resource('hrm_human_resource', alias=self.component, filter=query, vars=filters)
                rows = hresource.select(['id'], as_rows=True)
                selected = [str(row.id) for row in rows]
            query = ((table.human_resource_id.belongs(selected) & (table[fkey] == record_id)) & (table.deleted != True))
            rows = db(query).select(table.id)
            rows = dict(((row.id, row) for row in rows))
            onaccept = component.get_config('create_onaccept', component.get_config('onaccept', None))
            for human_resource_id in selected:
                try:
                    hr_id = int(human_resource_id.strip())
                except ValueError:
                    continue
                if (hr_id not in rows):
                    link = Storage(human_resource_id=human_resource_id)
                    link[fkey] = record_id
                    _id = table.insert(**link)
                    if onaccept:
                        link['id'] = _id
                        form = Storage(vars=link)
                        onaccept(form)
                    added += 1
        current.session.confirmation = (T('%(number)s    assigned') % dict(number=added))
        if (added > 0):
            redirect(URL(args=[r.id, self.next_tab], vars={}))
        else:
            redirect(URL(args=r.args, vars={}))
    elif (r.http == 'GET'):
        if (controller == 'vol'):
            resource_type = 'volunteer'
        elif (len(types) == 1):
            resource_type = 'staff'
        else:
            resource_type = None
        if (r.controller == 'req'):
            module = 'req'
        else:
            module = controller
        filter_widgets = hrm_human_resource_filters(resource_type=resource_type, module=module)
        list_fields = ['id', 'person_id', 'organisation_id']
        if (len(types) == 2):
            list_fields.append((T('Type'), 'type'))
        list_fields.append('job_title_id')
        if settings.get_hrm_use_certificates():
            list_fields.append((T('Certificates'), 'person_id$certification.certificate_id'))
        if settings.get_hrm_use_skills():
            list_fields.append((T('Skills'), 'person_id$competency.skill_id'))
        if settings.get_hrm_use_trainings():
            list_fields.append((T('Trainings'), 'person_id$training.course_id'))
        resource = s3db.resource('hrm_human_resource', alias=(r.component.alias if r.component else None), vars=get_vars)
        totalrows = resource.count()
        if ('pageLength' in get_vars):
            display_length = get_vars['pageLength']
            if (display_length == 'None'):
                display_length = None
            else:
                display_length = int(display_length)
        else:
            display_length = 25
        if display_length:
            limit = (4 * display_length)
        else:
            limit = None
        (filter, orderby, left) = resource.datatable_filter(list_fields, get_vars)
        resource.add_filter(filter)
        query = ((table[fkey] == record_id) & (table.deleted != True))
        rows = db(query).select(table.human_resource_id)
        already = [row.human_resource_id for row in rows]
        filter = (~ db.hrm_human_resource.id.belongs(already))
        resource.add_filter(filter)
        dt_id = 'datatable'
        dt_bulk_actions = [(T('Assign'), 'assign')]
        if (r.representation == 'html'):
            resource.configure(deletable=False)
            profile_url = URL(c=controller, f='human_resource', args=['[id]', 'profile'])
            S3CRUD.action_buttons(r, deletable=False, read_url=profile_url, update_url=profile_url)
            response.s3.no_formats = True
            if filter_widgets:
                _vars = resource.crud._remove_filters(r.get_vars)
                filter_submit_url = r.url(vars=_vars)
                resource.configure(filter_widgets=filter_widgets)
                S3FilterForm.apply_filter_defaults(r, resource)
                filter_ajax_url = URL(f='human_resource', args=['filter.options'], vars={})
                get_config = resource.get_config
                filter_clear = get_config('filter_clear', True)
                filter_formstyle = get_config('filter_formstyle', None)
                filter_submit = get_config('filter_submit', True)
                filter_form = S3FilterForm(filter_widgets, clear=filter_clear, formstyle=filter_formstyle, submit=filter_submit, ajax=True, url=filter_submit_url, ajaxurl=filter_ajax_url, _class='filter-form', _id='datatable-filter-form')
                fresource = current.s3db.resource(resource.tablename)
                alias = (r.component.alias if r.component else None)
                ff = filter_form.html(fresource, r.get_vars, target='datatable', alias=alias)
            else:
                ff = ''
            data = resource.select(list_fields, start=0, limit=limit, orderby=orderby, left=left, count=True, represent=True)
            filteredrows = data['numrows']
            dt = S3DataTable(data['rfields'], data['rows'])
            items = dt.html(totalrows, filteredrows, dt_id, dt_ajax_url=r.url(representation='aadata'), dt_bulk_actions=dt_bulk_actions, dt_pageLength=display_length, dt_pagination='true', dt_searching='false')
            STAFF = settings.get_hrm_staff_label()
            output = dict(items=items, title=(T('Assign    %(staff)s') % dict(staff=STAFF)), list_filter_form=ff)
            response.view = 'list_filter.html'
            return output
        elif (r.representation == 'aadata'):
            if ('draw' in get_vars):
                echo = int(get_vars.draw)
            else:
                echo = None
            data = resource.select(list_fields, start=0, limit=limit, orderby=orderby, left=left, count=True, represent=True)
            filteredrows = data['numrows']
            dt = S3DataTable(data['rfields'], data['rows'])
            items = dt.json(totalrows, filteredrows, dt_id, echo, dt_bulk_actions=dt_bulk_actions)
            response.headers['Content-Type'] = 'application/json'
            return items
        else:
            r.error(415, current.ERROR.BAD_FORMAT)
    else:
        r.error(405, current.ERROR.BAD_METHOD)
