'Remove a delegation.
@param group_id: the auth_group ID or UID (or a list of either)
@param entity: the delegating entity
@param receiver: the receiving entity
@param role: the affiliation role
@note: if receiver is specified, only 1:1 delegations (to role_type 0)
will be removed, but not 1:N delegations => to remove for 1:N
you must specify the role instead of the receiver
@note: if both receiver and role are None, all delegations with this
group_id will be removed for the entity'

def s3_remove_delegation(self, group_id, entity, receiver=None, role=None):

    if (not self.permission.delegations):
        return False
    db = current.db
    s3db = current.s3db
    dtable = s3db.table('pr_delegation')
    rtable = s3db.table('pr_role')
    atable = s3db.table('pr_affiliation')
    if ((dtable is None) or (rtable is None) or (atable is None)):
        return False
    if ((not group_id) or (not entity) or ((not receiver) and (not role))):
        return False
    gtable = self.settings.table_group
    query = None
    if isinstance(group_id, (list, tuple)):
        if isinstance(group_id[0], str):
            query = gtable.uuid.belongs(group_id)
        else:
            group_ids = group_id
    elif (isinstance(group_id, str) and (not group_id.isdigit())):
        query = (gtable.uuid == group_id)
    else:
        group_ids = [group_id]
    if (query is not None):
        query = ((gtable.deleted != True) & query)
        groups = db(query).select(gtable.id, gtable.uuid)
        group_ids = [g.id for g in groups]
    if (not group_ids):
        return False
    query = (((((dtable.deleted != True) & dtable.group_id.belongs(group_ids)) & (dtable.role_id == rtable.id)) & (rtable.pe_id == entity)) & (atable.role_id == rtable.id))
    if receiver:
        if (not isinstance(receiver, (list, tuple))):
            receiver = [receiver]
        query &= atable.pe_id.belongs(receiver)
    elif role:
        query &= (rtable.role == role)
    rows = db(query).select(dtable.id, dtable.group_id, rtable.id, rtable.role_type)
    rmv = Storage()
    for row in rows:
        if ((not receiver) or (row[rtable.role_type] == 0)):
            deleted_fk = {'role_id': row[rtable.id], 'group_id': row[dtable.group_id]}
            rmv[row[dtable.id]] = json.dumps(deleted_fk)
    for record_id in rmv:
        query = (dtable.id == record_id)
        data = {'role_id': None, 'group_id': None, 'deleted_fk': rmv[record_id]}
        db(query).update(**data)
    if len(rmv):
        self.s3_set_roles()
    return True
