'Create new records
@param r: the S3Request
@param attr: dictionary of parameters for the method handler'

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

    session = current.session
    request = self.request
    response = current.response
    resource = self.resource
    table = resource.table
    tablename = resource.tablename
    representation = r.representation
    output = dict()
    native = (r.method == 'create')
    _config = self._config
    insertable = _config('insertable', True)
    if (not insertable):
        if native:
            r.error(405, current.ERROR.METHOD_DISABLED)
        else:
            return dict(form=None)
    authorised = self._permitted(method='create')
    if (not authorised):
        if native:
            r.unauthorised()
        else:
            return dict(form=None)
    onvalidation = (_config('create_onvalidation') or _config('onvalidation'))
    onaccept = (_config('create_onaccept') or _config('onaccept'))
    if r.interactive:
        crud_string = self.crud_string
        if native:
            if (representation in ('popup', 'iframe')):
                response.view = self._view(r, 'popup.html')
                output['caller'] = request.vars.caller
            else:
                response.view = self._view(r, 'create.html')
            if r.component:
                title = crud_string(r.tablename, 'title_display')
                output['title'] = title
            else:
                title = crud_string(tablename, 'label_create')
                output['title'] = title
            output['title_list'] = crud_string(tablename, 'title_list')
            buttons = self.render_buttons(r, ['list'], **attr)
            if buttons:
                output['buttons'] = buttons
        link = None
        if r.component:
            defaults = r.component.get_defaults(r.record)
            if (resource.link is None):
                linked = resource.linked
                ctable = (linked.table if linked else table)
                for (k, v) in defaults.items():
                    ctable[k].default = v
                link = self._embed_component(resource, record=r.id)
                pkey = resource.pkey
                fkey = resource.fkey
                field = table[fkey]
                value = r.record[pkey]
                field.default = field.update = value
                if (r.http == 'POST'):
                    r.post_vars.update({fkey: value})
                field.comment = None
                field.readable = False
                field.writable = False
            else:
                for (k, v) in defaults.items():
                    table[k].default = v
                link = Storage(resource=resource.link, master=r.record)
        get_vars = r.get_vars
        hierarchy = None
        link_to_parent = get_vars.get('link_to_parent')
        if link_to_parent:
            try:
                parent = long(link_to_parent)
            except ValueError:
                r.error(400, ('Invalid    parent    record    ID:    %s' % link_to_parent))
            else:
                from s3hierarchy import S3Hierarchy
                h = S3Hierarchy(tablename)
                if h.config:
                    try:
                        hierarchy = h.preprocess_create_node(r, parent)
                    except KeyError:
                        import sys
                        r.error(404, sys.exc_info()[1])
        from_table = None
        from_record = get_vars.get('from_record')
        map_fields = get_vars.get('from_fields')
        if from_record:
            del get_vars['from_record']
            if (from_record.find('.') != (-1)):
                (from_table, from_record) = from_record.split('.', 1)
                from_table = current.db.get(from_table, None)
                if (not from_table):
                    r.error(404, current.ERROR.BAD_RESOURCE)
            else:
                from_table = table
            try:
                from_record = long(from_record)
            except:
                r.error(404, current.ERROR.BAD_RECORD)
            authorised = current.auth.s3_has_permission('read', from_table._tablename, from_record)
            if (not authorised):
                r.unauthorised()
            if map_fields:
                del r.get_vars['from_fields']
                if (map_fields.find('$') != (-1)):
                    mf = map_fields.split(',')
                    mf = [(((f.find('$') != (-1)) and f.split('$')) or [f, f]) for f in mf]
                    map_fields = Storage(mf)
                else:
                    map_fields = map_fields.split(',')
        message = crud_string(self.tablename, 'msg_record_created')
        if ('id' in request.post_vars):
            post_vars = request.post_vars
            original = str(post_vars.id)
            formkey = session.get(('_formkey[%s/None]' % tablename))
            formname = ('%s/%s' % (tablename, original))
            session[('_formkey[%s]' % formname)] = formkey
            if ('deleted' in table):
                table.deleted.writable = True
                post_vars['deleted'] = False
            if ('created_on' in table):
                table.created_on.writable = True
                post_vars['created_on'] = request.utcnow
            if ('created_by' in table):
                table.created_by.writable = True
                if current.auth.user:
                    post_vars['created_by'] = current.auth.user.id
                else:
                    post_vars['created_by'] = None
            post_vars['_undelete'] = True
            post_vars['_formname'] = formname
            post_vars['id'] = original
            request.vars.update(**post_vars)
        else:
            original = None
        subheadings = _config('subheadings')
        self._interim_save_button()
        if ((r.representation == 'html') and (r.method == 'create')):
            self._default_cancel_button(r)
        output['form'] = self.sqlform(request=request, resource=resource, data=self.data, record_id=original, from_table=from_table, from_record=from_record, map_fields=map_fields, onvalidation=onvalidation, onaccept=onaccept, link=link, hierarchy=hierarchy, message=message, subheadings=subheadings, format=representation)
        if self.settings.navigate_away_confirm:
            response.s3.jquery_ready.append('S3EnableNavigateAwayConfirm()')
        if (representation in ('popup', 'iframe', 'plain', 'dl')):
            self.next = None
        else:
            if ((r.http == 'POST') and ('interim_save' in r.post_vars)):
                next_vars = self._remove_filters(r.get_vars)
                create_next = r.url(target='[id]', method='update', vars=next_vars)
            elif ((r.http == 'POST') and ('save_close' in r.post_vars)):
                create_next = _config('create_next_close')
            elif (session.s3.rapid_data_entry and (not r.component)):
                if ('w' in r.get_vars):
                    w = r.get_vars.pop('w')
                else:
                    w = None
                create_next = r.url()
                if w:
                    r.get_vars['w'] = w
            else:
                create_next = _config('create_next')
            if (not create_next):
                next_vars = self._remove_filters(r.get_vars)
                if r.component:
                    self.next = r.url(method='', vars=next_vars)
                else:
                    self.next = r.url(id='[id]', method='read', vars=next_vars)
            elif callable(create_next):
                self.next = create_next(r)
            else:
                self.next = create_next
    elif (representation == 'plain'):
        response.view = self._view(r, 'plain.html')
        crud_string = self.crud_string
        message = crud_string(tablename, 'msg_record_created')
        subheadings = _config('subheadings')
        output['title'] = crud_string(tablename, 'label_create')
        output['details_btn'] = ''
        output['item'] = self.sqlform(request=request, resource=resource, data=self.data, onvalidation=onvalidation, onaccept=onaccept, message=message, subheadings=subheadings, format=representation)
    elif (representation == 'csv'):
        import cgi
        import csv
        csv.field_size_limit(1000000000)
        infile = request.vars.filename
        if (isinstance(infile, cgi.FieldStorage) and infile.filename):
            infile = infile.file
        else:
            try:
                infile = open(infile, 'rb')
            except:
                session.error = (current.T('Cannot    read    from    file:    %(filename)s') % dict(filename=infile))
                redirect(r.url(method='', representation='html'))
        try:
            self.import_csv(infile, table=table)
        except:
            session.error = current.T('Unable    to    parse    CSV    file    or    file    contains    invalid    data')
        else:
            session.confirmation = current.T('Data    uploaded')
    elif (representation == 'pdf'):
        from s3pdf import S3PDF
        exporter = S3PDF()
        return exporter(r, **attr)
    elif (representation == 'url'):
        results = self.import_url(r)
        return results
    else:
        r.error(415, current.ERROR.BAD_FORMAT)
    return output
