'Return the description of the fields in the node.
In a normal call to this method, node is a complete view architecture
but it is actually possible to give some sub-node (this is used so
that the method can call itself recursively).
Originally, the field descriptions are drawn from the node itself.
But there is now some code calling fields_get() in order to merge some
of those information in the architecture.'

@api.model
def postprocess(self, model, node, view_id, in_tree_view, model_fields):

    result = False
    fields = {}
    children = True
    modifiers = {}
    if (model not in self.env):
        self.raise_view_error((_('Model    not    found:    %(model)s') % dict(model=model)), view_id)
    Model = self.env[model]
    if (node.tag in ('field', 'node', 'arrow')):
        if node.get('object'):
            attrs = {}
            views = {}
            xml_form = E.form(*(f for f in node if (f.tag == 'field')))
            (xarch, xfields) = self.with_context(base_model_name=model).postprocess_and_fields(node.get('object'), xml_form, view_id)
            views['form'] = {'arch': xarch, 'fields': xfields}
            attrs = {'views': views}
            fields = xfields
        if node.get('name'):
            attrs = {}
            field = Model._fields.get(node.get('name'))
            if field:
                children = False
                views = {}
                for f in node:
                    if (f.tag in ('form', 'tree', 'graph', 'kanban', 'calendar')):
                        node.remove(f)
                        (xarch, xfields) = self.with_context(base_model_name=model).postprocess_and_fields(field.comodel_name, f, view_id)
                        views[str(f.tag)] = {'arch': xarch, 'fields': xfields}
                attrs = {'views': views}
                if ((field.comodel_name in self.env) and (field.type in ('many2one', 'many2many'))):
                    Comodel = self.env[field.comodel_name]
                    node.set('can_create', ('true' if Comodel.check_access_rights('create', raise_exception=False) else 'false'))
                    node.set('can_write', ('true' if Comodel.check_access_rights('write', raise_exception=False) else 'false'))
            fields[node.get('name')] = attrs
            field = model_fields.get(node.get('name'))
            if field:
                orm.transfer_field_to_modifiers(field, modifiers)
    elif (node.tag in ('form', 'tree')):
        result = Model.view_header_get(False, node.tag)
        if result:
            node.set('string', result)
        in_tree_view = (node.tag == 'tree')
    elif (node.tag == 'calendar'):
        for additional_field in ('date_start', 'date_delay', 'date_stop', 'color', 'all_day', 'attendee'):
            if node.get(additional_field):
                fields[node.get(additional_field)] = {}
    if (not self._apply_group(model, node, modifiers, fields)):
        return fields
    orm.transfer_node_to_modifiers(node, modifiers, self._context, in_tree_view)
    for f in node:
        if (children or ((node.tag == 'field') and (f.tag in ('filter', 'separator')))):
            fields.update(self.postprocess(model, f, view_id, in_tree_view, model_fields))
    orm.transfer_modifiers_to_node(modifiers, node)
    return fields
