Coverage for adhoc-cicd-odoo-odoo / odoo / orm / commands.py: 94%

32 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-03-09 18:22 +0000

1from __future__ import annotations 

2 

3import enum 

4import typing 

5 

6if typing.TYPE_CHECKING: 

7 from collections.abc import Collection 

8 from .types import ValuesType 

9 

10 

11class Command(enum.IntEnum): 

12 """ 

13 :class:`~odoo.fields.One2many` and :class:`~odoo.fields.Many2many` fields 

14 expect a special command to manipulate the relation they implement. 

15 

16 Internally, each command is a 3-elements tuple where the first element is a 

17 mandatory integer that identifies the command, the second element is either 

18 the related record id to apply the command on (commands update, delete, 

19 unlink and link) either 0 (commands create, clear and set), the third 

20 element is either the ``values`` to write on the record (commands create 

21 and update) either the new ``ids`` list of related records (command set), 

22 either 0 (commands delete, unlink, link, and clear). 

23 This triplet is aliased as ``CommandValue``. 

24 

25 Via Python, we encourage developers craft new commands via the various 

26 functions of this namespace. We also encourage developers to use the 

27 command identifier constant names when comparing the 1st element of 

28 existing commands. 

29 

30 Via RPC, it is impossible nor to use the functions nor the command constant 

31 names. It is required to instead write the literal 3-elements tuple where 

32 the first element is the integer identifier of the command. 

33 """ 

34 

35 CREATE = 0 

36 UPDATE = 1 

37 DELETE = 2 

38 UNLINK = 3 

39 LINK = 4 

40 CLEAR = 5 

41 SET = 6 

42 

43 @classmethod 

44 def create(cls, values: ValuesType) -> CommandValue: 

45 """ 

46 Create new records in the comodel using ``values``, link the created 

47 records to ``self``. 

48 

49 In case of a :class:`~odoo.fields.Many2many` relation, one unique 

50 new record is created in the comodel such that all records in `self` 

51 are linked to the new record. 

52 

53 In case of a :class:`~odoo.fields.One2many` relation, one new record 

54 is created in the comodel for every record in ``self`` such that every 

55 record in ``self`` is linked to exactly one of the new records. 

56 

57 Return the command triple :samp:`(CREATE, 0, {values})` 

58 """ 

59 return (cls.CREATE, 0, values) 

60 

61 @classmethod 

62 def update(cls, id: int, values: ValuesType) -> CommandValue: 

63 """ 

64 Write ``values`` on the related record. 

65 

66 Return the command triple :samp:`(UPDATE, {id}, {values})` 

67 """ 

68 return (cls.UPDATE, id, values) 

69 

70 @classmethod 

71 def delete(cls, id: int) -> CommandValue: 

72 """ 

73 Remove the related record from the database and remove its relation 

74 with ``self``. 

75 

76 In case of a :class:`~odoo.fields.Many2many` relation, removing the 

77 record from the database may be prevented if it is still linked to 

78 other records. 

79 

80 Return the command triple :samp:`(DELETE, {id}, 0)` 

81 """ 

82 return (cls.DELETE, id, 0) 

83 

84 @classmethod 

85 def unlink(cls, id: int) -> CommandValue: 

86 """ 

87 Remove the relation between ``self`` and the related record. 

88 

89 In case of a :class:`~odoo.fields.One2many` relation, the given record 

90 is deleted from the database if the inverse field is set as 

91 ``ondelete='cascade'``. Otherwise, the value of the inverse field is 

92 set to False and the record is kept. 

93 

94 Return the command triple :samp:`(UNLINK, {id}, 0)` 

95 """ 

96 return (cls.UNLINK, id, 0) 

97 

98 @classmethod 

99 def link(cls, id: int) -> CommandValue: 

100 """ 

101 Add a relation between ``self`` and the related record. 

102 

103 Return the command triple :samp:`(LINK, {id}, 0)` 

104 """ 

105 return (cls.LINK, id, 0) 

106 

107 @classmethod 

108 def clear(cls) -> CommandValue: 

109 """ 

110 Remove all records from the relation with ``self``. It behaves like 

111 executing the `unlink` command on every record. 

112 

113 Return the command triple :samp:`(CLEAR, 0, 0)` 

114 """ 

115 return (cls.CLEAR, 0, 0) 

116 

117 @classmethod 

118 def set(cls, ids: Collection[int]) -> CommandValue: 

119 """ 

120 Replace the current relations of ``self`` by the given ones. It behaves 

121 like executing the ``unlink`` command on every removed relation then 

122 executing the ``link`` command on every new relation. 

123 

124 Return the command triple :samp:`(SET, 0, {ids})` 

125 """ 

126 return (cls.SET, 0, ids) 

127 

128 

129if typing.TYPE_CHECKING: 

130 CommandValue = tuple[Command, int, typing.Literal[0] | ValuesType | Collection[int]]