@@ -184,19 +184,33 @@ def _get_node_options_eval_context(self):
184184 eval_ctx .update ({"context" : dict (eval_ctx )})
185185 return eval_ctx
186186
187+ # Odoo 18 renamed the field-level option keys and inverted their boolean sense:
188+ # old: create=False → new: no_quick_create=True
189+ # old: create_edit=False → new: no_create_edit=True
190+ _OPTION_KEY_MAP = {
191+ "create" : "no_quick_create" ,
192+ "create_edit" : "no_create_edit" ,
193+ }
194+
187195 def _read_own_options (self ):
188196 """Helper method to retrieve M2X options from ``self``
189197
190198 :return: a dictionary mapping each M2X option to its mode and value, eg:
191- {'create ': ('force', 'true' ), 'create_edit ': ('set', 'false' )}
199+ {'no_quick_create ': ('force', True ), 'no_create_edit ': ('set', True )}
192200 :rtype: dict[str, tuple[str, Any]]
193201 """
194202 self .ensure_one ()
195203 res = {}
196204 for fname , fvalue in self .read (self ._get_option_fields ())[0 ].items ():
197205 if fname != "id" and fvalue != "none" :
198206 mode , value = tuple (fvalue .split ("_" ))
199- res [fname .replace ("option_" , "" )] = (mode , value == "true" )
207+ old_key = fname .replace ("option_" , "" )
208+ new_key = self ._OPTION_KEY_MAP .get (old_key , old_key )
209+ # Value is inverted: create=False means no_quick_create=True
210+ bool_value = value == "true"
211+ if new_key != old_key :
212+ bool_value = not bool_value
213+ res [new_key ] = (mode , bool_value )
200214 return res
201215
202216 def _get_option_fields (self ):
0 commit comments