diff --git a/MetaAnalytic.py b/MetaAnalytic.py
index 994d317a97b039e1a2bf7f6dcbbd143004521af3_TWV0YUFuYWx5dGljLnB5..191d5560a4bac9cefa92c873e37b09a9abdce476_TWV0YUFuYWx5dGljLnB5 100644
--- a/MetaAnalytic.py
+++ b/MetaAnalytic.py
@@ -155,6 +155,18 @@
 
         @AddMethod(superclass)
         @api.model
+        def get_analytic_field_names(self):
+
+            field_names = []
+            analytic_osv = self.env["analytic.structure"]
+            for model_name, prefix, suffix in all_analytic:
+                for ordering in analytic_osv.get_dimensions_names(model_name):
+                    field_names.append("%s%s_%s" % (prefix, ordering, suffix))
+
+            return field_names
+
+        @AddMethod(superclass)
+        @api.model
         def fields_get(self, allfields=None, attributes=None):
             """Override this method to rename analytic fields."""
 
diff --git a/NEWS.rst b/NEWS.rst
index 994d317a97b039e1a2bf7f6dcbbd143004521af3_TkVXUy5yc3Q=..191d5560a4bac9cefa92c873e37b09a9abdce476_TkVXUy5yc3Q= 100644
--- a/NEWS.rst
+++ b/NEWS.rst
@@ -26,6 +26,8 @@
 - code_description
 - parent_column
 New partners without name, does not trigger an analytic_code creation.
+Added a method able to return the technical names of all the analytic fields of
+a class.
 
 .. _2.2:
 
diff --git a/README.rst b/README.rst
index 994d317a97b039e1a2bf7f6dcbbd143004521af3_UkVBRE1FLnJzdA==..191d5560a4bac9cefa92c873e37b09a9abdce476_UkVBRE1FLnJzdA== 100644
--- a/README.rst
+++ b/README.rst
@@ -101,6 +101,10 @@
 
 .. _AnalyticFields:
 
+This metaclass adds a method able to return the technical names of all the
+analytic fields of the inheriting class:
+.. get_analytic_field_names
+
 Add analytic fields to a model
 ------------------------------
 
diff --git a/models/analytic_structure.py b/models/analytic_structure.py
index 994d317a97b039e1a2bf7f6dcbbd143004521af3_bW9kZWxzL2FuYWx5dGljX3N0cnVjdHVyZS5weQ==..191d5560a4bac9cefa92c873e37b09a9abdce476_bW9kZWxzL2FuYWx5dGljX3N0cnVjdHVyZS5weQ== 100644
--- a/models/analytic_structure.py
+++ b/models/analytic_structure.py
@@ -300,7 +300,7 @@
             else:
                 # No analytic structure defined for this field, hide it.
                 modifiers = json.loads(match.get("modifiers", "{}"))
-                modifiers["invisible"] = modifiers["tree_invisible"] = True
+                modifiers["invisible"] = modifiers["column_invisible"] = True
                 modifiers["required"] = False
                 match.set("invisible", "true")
                 match.set("required", "false")
@@ -346,4 +346,11 @@
                 )
                 view["fields"].update(elem_fields_def)
 
+                # Prepare the "modifiers" attribute normally dynamically added.
+                # Specifics here:
+                # * We compare against explicit attributes in the view. This
+                #   way we avoid all-read-only fields as the main
+                #   "analytic_dimensions" pseudo-field is read-only.
+                # * When comparing, handle column_invisible -> invisible (see
+                #   odoo/osv/orm.py > transfer_node_to_modifiers).
                 modifiers = json.loads(elem.attrib.get("modifiers", "{}"))
@@ -349,4 +356,13 @@
                 modifiers = json.loads(elem.attrib.get("modifiers", "{}"))
+                modifiers = json.dumps(
+                    {
+                        attr: value
+                        for attr, value in modifiers.items()
+                        if elem.attrib.get(_MODIFIER_TO_ATTR.get(attr, attr))
+                        in ("True", "true", "1")
+                    }
+                )
+
                 # Now we can insert the fields in the view's architecture.
 
                 model_map = {
@@ -382,3 +398,8 @@
         view["arch"] = etree.tostring(doc)
 
         return view
+
+
+# Used above in analytic_fields_view_get to compare "modifiers" vs explicit
+# attributes. See odoo/osv/orm.py > transfer_node_to_modifiers.
+_MODIFIER_TO_ATTR = {"column_invisible": "invisible"}