odoo-addon-automation-oca 16.0.1.5.2__py3-none-any.whl → 17.0.1.0.0.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- odoo/addons/automation_oca/README.rst +7 -7
- odoo/addons/automation_oca/__init__.py +1 -0
- odoo/addons/automation_oca/__manifest__.py +1 -1
- odoo/addons/automation_oca/data/cron.xml +0 -5
- odoo/addons/automation_oca/i18n/automation_oca.pot +95 -22
- odoo/addons/automation_oca/i18n/es.po +0 -13
- odoo/addons/automation_oca/i18n/fr.po +0 -13
- odoo/addons/automation_oca/i18n/it.po +2 -15
- odoo/addons/automation_oca/models/automation_configuration.py +28 -26
- odoo/addons/automation_oca/models/automation_configuration_step.py +38 -11
- odoo/addons/automation_oca/models/automation_filter.py +5 -1
- odoo/addons/automation_oca/models/automation_record.py +64 -52
- odoo/addons/automation_oca/models/automation_record_step.py +34 -15
- odoo/addons/automation_oca/models/automation_tag.py +0 -1
- odoo/addons/automation_oca/models/mail_activity.py +3 -3
- odoo/addons/automation_oca/models/mail_mail.py +17 -15
- odoo/addons/automation_oca/models/mail_thread.py +6 -11
- odoo/addons/automation_oca/static/description/index.html +5 -5
- odoo/addons/automation_oca/static/src/fields/automation_activity/automation_activity.esm.js +5 -4
- odoo/addons/automation_oca/static/src/fields/automation_graph/automation_graph.esm.js +21 -25
- odoo/addons/automation_oca/static/src/views/automation_kanban/automation_kanban.scss +3 -0
- odoo/addons/automation_oca/static/src/views/automation_kanban/automation_kanban_compiler.esm.js +2 -3
- odoo/addons/automation_oca/static/src/views/automation_kanban/automation_kanban_record.esm.js +1 -2
- odoo/addons/automation_oca/static/src/views/automation_kanban/automation_kanban_renderer.esm.js +1 -2
- odoo/addons/automation_oca/tests/__init__.py +1 -0
- odoo/addons/automation_oca/tests/common.py +2 -1
- odoo/addons/automation_oca/tests/models.py +10 -0
- odoo/addons/automation_oca/tests/test_automation_action.py +7 -8
- odoo/addons/automation_oca/tests/test_automation_activity.py +122 -10
- odoo/addons/automation_oca/tests/test_automation_base.py +73 -82
- odoo/addons/automation_oca/tests/test_automation_date.py +59 -0
- odoo/addons/automation_oca/tests/test_automation_mail.py +31 -50
- odoo/addons/automation_oca/tests/test_automation_security.py +5 -2
- odoo/addons/automation_oca/utils/__init__.py +1 -0
- odoo/addons/automation_oca/utils/query.py +45 -0
- odoo/addons/automation_oca/views/automation_configuration.xml +60 -51
- odoo/addons/automation_oca/views/automation_configuration_step.xml +86 -49
- odoo/addons/automation_oca/views/automation_filter.xml +1 -3
- odoo/addons/automation_oca/views/automation_record.xml +32 -19
- odoo/addons/automation_oca/views/automation_record_step.xml +4 -14
- odoo/addons/automation_oca/views/automation_tag.xml +3 -4
- odoo/addons/automation_oca/views/link_tracker_clicks.xml +2 -3
- odoo/addons/automation_oca/wizards/automation_configuration_test.py +1 -2
- odoo/addons/automation_oca/wizards/automation_configuration_test.xml +4 -6
- odoo/addons/automation_oca/wizards/mail_compose_message.py +2 -3
- {odoo_addon_automation_oca-16.0.1.5.2.dist-info → odoo_addon_automation_oca-17.0.1.0.0.5.dist-info}/METADATA +12 -12
- odoo_addon_automation_oca-17.0.1.0.0.5.dist-info/RECORD +66 -0
- {odoo_addon_automation_oca-16.0.1.5.2.dist-info → odoo_addon_automation_oca-17.0.1.0.0.5.dist-info}/WHEEL +1 -1
- odoo_addon_automation_oca-17.0.1.0.0.5.dist-info/top_level.txt +1 -0
- odoo_addon_automation_oca-16.0.1.5.2.dist-info/RECORD +0 -62
- odoo_addon_automation_oca-16.0.1.5.2.dist-info/top_level.txt +0 -1
|
@@ -10,7 +10,7 @@ class TestAutomationAction(AutomationTestCase):
|
|
|
10
10
|
We will check the execution of the tasks and that we cannot execute them again
|
|
11
11
|
"""
|
|
12
12
|
activity = self.create_server_action(trigger_interval=-1)
|
|
13
|
-
self.configuration.editable_domain = "[('id', '=',
|
|
13
|
+
self.configuration.editable_domain = f"[('id', '=', {self.partner_01.id})]"
|
|
14
14
|
self.configuration.start_automation()
|
|
15
15
|
self.env["automation.configuration"].cron_automation()
|
|
16
16
|
self.assertFalse(self.partner_01.comment)
|
|
@@ -26,7 +26,7 @@ class TestAutomationAction(AutomationTestCase):
|
|
|
26
26
|
We will check the execution of the tasks and that we cannot execute them again
|
|
27
27
|
"""
|
|
28
28
|
activity = self.create_server_action()
|
|
29
|
-
self.configuration.editable_domain = "[('id', '=',
|
|
29
|
+
self.configuration.editable_domain = f"[('id', '=', {self.partner_01.id})]"
|
|
30
30
|
self.configuration.start_automation()
|
|
31
31
|
self.env["automation.configuration"].cron_automation()
|
|
32
32
|
self.assertTrue(self.partner_01.comment)
|
|
@@ -56,17 +56,16 @@ class TestAutomationAction(AutomationTestCase):
|
|
|
56
56
|
In this case, the task 1_1_1 will only be generated for partner 1 and task 1_2_1
|
|
57
57
|
for partner 2
|
|
58
58
|
"""
|
|
59
|
-
self.configuration.editable_domain =
|
|
60
|
-
self.partner_01.id,
|
|
61
|
-
self.partner_02.id,
|
|
59
|
+
self.configuration.editable_domain = (
|
|
60
|
+
f"[('id', 'in', [{self.partner_01.id}, {self.partner_02.id}])]"
|
|
62
61
|
)
|
|
63
62
|
|
|
64
63
|
activity_1 = self.create_server_action()
|
|
65
64
|
activity_1_1 = self.create_server_action(
|
|
66
|
-
parent_id=activity_1.id, domain="[('id', '=',
|
|
65
|
+
parent_id=activity_1.id, domain=f"[('id', '=', {self.partner_01.id})]"
|
|
67
66
|
)
|
|
68
67
|
activity_1_2 = self.create_server_action(
|
|
69
|
-
parent_id=activity_1.id, domain="[('id', '=',
|
|
68
|
+
parent_id=activity_1.id, domain=f"[('id', '=', {self.partner_02.id})]"
|
|
70
69
|
)
|
|
71
70
|
activity_1_1_1 = self.create_server_action(parent_id=activity_1_1.id)
|
|
72
71
|
activity_1_2_1 = self.create_server_action(parent_id=activity_1_2.id)
|
|
@@ -226,7 +225,7 @@ class TestAutomationAction(AutomationTestCase):
|
|
|
226
225
|
"""
|
|
227
226
|
self.create_server_action(server_context='{"key_value": "My Value"}')
|
|
228
227
|
self.partner_01.comment = False
|
|
229
|
-
self.configuration.editable_domain = "[('id', '=',
|
|
228
|
+
self.configuration.editable_domain = f"[('id', '=', {self.partner_01.id})]"
|
|
230
229
|
self.configuration.start_automation()
|
|
231
230
|
self.env["automation.configuration"].cron_automation()
|
|
232
231
|
|
|
@@ -1,18 +1,28 @@
|
|
|
1
1
|
# Copyright 2024 Dixmit
|
|
2
2
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
|
3
3
|
|
|
4
|
-
from odoo.
|
|
4
|
+
from odoo.exceptions import ValidationError
|
|
5
|
+
from odoo.tests import Form, new_test_user
|
|
5
6
|
|
|
6
7
|
from .common import AutomationTestCase
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
class TestAutomationActivity(AutomationTestCase):
|
|
11
|
+
@classmethod
|
|
12
|
+
def setUpClass(cls):
|
|
13
|
+
super().setUpClass()
|
|
14
|
+
cls.user = new_test_user(
|
|
15
|
+
cls.env,
|
|
16
|
+
login="test_user_automation",
|
|
17
|
+
groups="base.group_user,base.group_partner_manager",
|
|
18
|
+
)
|
|
19
|
+
|
|
10
20
|
def test_activity_execution(self):
|
|
11
21
|
"""
|
|
12
22
|
We will check the execution of activity tasks (generation of an activity)
|
|
13
23
|
"""
|
|
14
24
|
activity = self.create_activity_action()
|
|
15
|
-
self.configuration.editable_domain = "[('id', '=',
|
|
25
|
+
self.configuration.editable_domain = f"[('id', '=', {self.partner_01.id})]"
|
|
16
26
|
self.configuration.start_automation()
|
|
17
27
|
self.env["automation.configuration"].cron_automation()
|
|
18
28
|
self.assertFalse(self.partner_01.activity_ids)
|
|
@@ -44,6 +54,79 @@ class TestAutomationActivity(AutomationTestCase):
|
|
|
44
54
|
]
|
|
45
55
|
)
|
|
46
56
|
|
|
57
|
+
def test_activity_execution_check_domain(self):
|
|
58
|
+
"""
|
|
59
|
+
We will check the execution of activity tasks (generation of an activity)
|
|
60
|
+
"""
|
|
61
|
+
activity = self.create_activity_action(
|
|
62
|
+
activity_verification_domain="[('name', '=', 'My Expected Name')]"
|
|
63
|
+
)
|
|
64
|
+
self.partner_01.name = "Not My Expected Name"
|
|
65
|
+
self.configuration.editable_domain = f"[('id', '=', {self.partner_01.id})]"
|
|
66
|
+
self.configuration.start_automation()
|
|
67
|
+
self.env["automation.configuration"].cron_automation()
|
|
68
|
+
self.assertFalse(self.partner_01.activity_ids)
|
|
69
|
+
self.env["automation.record.step"]._cron_automation_steps()
|
|
70
|
+
self.assertTrue(self.partner_01.activity_ids)
|
|
71
|
+
record_activity = self.env["automation.record.step"].search(
|
|
72
|
+
[("configuration_step_id", "=", activity.id)]
|
|
73
|
+
)
|
|
74
|
+
self.assertEqual(
|
|
75
|
+
record_activity, self.partner_01.activity_ids.automation_record_step_id
|
|
76
|
+
)
|
|
77
|
+
self.assertFalse(record_activity.activity_done_on)
|
|
78
|
+
record_activity.invalidate_recordset()
|
|
79
|
+
self.assertFalse(
|
|
80
|
+
[
|
|
81
|
+
step
|
|
82
|
+
for step in record_activity.step_actions
|
|
83
|
+
if step["done"] and step["icon"] == "fa fa-clock-o"
|
|
84
|
+
]
|
|
85
|
+
)
|
|
86
|
+
with self.assertRaises(ValidationError):
|
|
87
|
+
self.partner_01.activity_ids.action_feedback()
|
|
88
|
+
self.assertFalse(record_activity.activity_done_on)
|
|
89
|
+
self.partner_01.name = "My Expected Name"
|
|
90
|
+
self.partner_01.activity_ids.action_feedback()
|
|
91
|
+
self.assertTrue(record_activity.activity_done_on)
|
|
92
|
+
|
|
93
|
+
def test_activity_execution_permission(self):
|
|
94
|
+
"""
|
|
95
|
+
We will check the execution of activity tasks (generation of an activity)
|
|
96
|
+
"""
|
|
97
|
+
activity = self.create_activity_action()
|
|
98
|
+
self.configuration.editable_domain = "[('id', '=', %s)]" % self.partner_01.id
|
|
99
|
+
self.configuration.start_automation()
|
|
100
|
+
self.env["automation.configuration"].cron_automation()
|
|
101
|
+
self.assertFalse(self.partner_01.activity_ids)
|
|
102
|
+
self.env["automation.record.step"]._cron_automation_steps()
|
|
103
|
+
self.assertTrue(self.partner_01.activity_ids)
|
|
104
|
+
record_activity = self.env["automation.record.step"].search(
|
|
105
|
+
[("configuration_step_id", "=", activity.id)]
|
|
106
|
+
)
|
|
107
|
+
self.assertEqual(
|
|
108
|
+
record_activity, self.partner_01.activity_ids.automation_record_step_id
|
|
109
|
+
)
|
|
110
|
+
self.assertFalse(record_activity.activity_done_on)
|
|
111
|
+
record_activity.invalidate_recordset()
|
|
112
|
+
self.assertFalse(
|
|
113
|
+
[
|
|
114
|
+
step
|
|
115
|
+
for step in record_activity.step_actions
|
|
116
|
+
if step["done"] and step["icon"] == "fa fa-clock-o"
|
|
117
|
+
]
|
|
118
|
+
)
|
|
119
|
+
self.partner_01.activity_ids.with_user(self.user.id).action_feedback()
|
|
120
|
+
self.assertTrue(record_activity.activity_done_on)
|
|
121
|
+
record_activity.invalidate_recordset()
|
|
122
|
+
self.assertTrue(
|
|
123
|
+
[
|
|
124
|
+
step
|
|
125
|
+
for step in record_activity.step_actions
|
|
126
|
+
if step["done"] and step["icon"] == "fa fa-clock-o"
|
|
127
|
+
]
|
|
128
|
+
)
|
|
129
|
+
|
|
47
130
|
def test_activity_execution_child(self):
|
|
48
131
|
"""
|
|
49
132
|
We will check the execution of the child task (activity_done) is only scheduled
|
|
@@ -53,7 +136,7 @@ class TestAutomationActivity(AutomationTestCase):
|
|
|
53
136
|
child_activity = self.create_server_action(
|
|
54
137
|
parent_id=activity.id, trigger_type="activity_done"
|
|
55
138
|
)
|
|
56
|
-
self.configuration.editable_domain = "[('id', '=',
|
|
139
|
+
self.configuration.editable_domain = f"[('id', '=', {self.partner_01.id})]"
|
|
57
140
|
self.configuration.start_automation()
|
|
58
141
|
self.env["automation.configuration"].cron_automation()
|
|
59
142
|
self.env["automation.record.step"]._cron_automation_steps()
|
|
@@ -81,7 +164,7 @@ class TestAutomationActivity(AutomationTestCase):
|
|
|
81
164
|
child_activity = self.create_server_action(
|
|
82
165
|
parent_id=activity.id, trigger_type="activity_done"
|
|
83
166
|
)
|
|
84
|
-
self.configuration.editable_domain = "[('id', '=',
|
|
167
|
+
self.configuration.editable_domain = f"[('id', '=', {self.partner_01.id})]"
|
|
85
168
|
self.configuration.start_automation()
|
|
86
169
|
self.env["automation.configuration"].cron_automation()
|
|
87
170
|
self.env["automation.record.step"]._cron_automation_steps()
|
|
@@ -101,16 +184,45 @@ class TestAutomationActivity(AutomationTestCase):
|
|
|
101
184
|
self.assertFalse(record_child_activity.scheduled_date)
|
|
102
185
|
self.assertEqual(record_child_activity.state, "rejected")
|
|
103
186
|
|
|
187
|
+
def test_activity_execution_on_cancel_permission(self):
|
|
188
|
+
"""
|
|
189
|
+
We will check the execution of the child task (activity_done) is only scheduled
|
|
190
|
+
after the activity is done
|
|
191
|
+
"""
|
|
192
|
+
activity = self.create_activity_action()
|
|
193
|
+
child_activity = self.create_server_action(
|
|
194
|
+
parent_id=activity.id, trigger_type="activity_done"
|
|
195
|
+
)
|
|
196
|
+
self.configuration.editable_domain = "[('id', '=', %s)]" % self.partner_01.id
|
|
197
|
+
self.configuration.start_automation()
|
|
198
|
+
self.env["automation.configuration"].cron_automation()
|
|
199
|
+
self.env["automation.record.step"]._cron_automation_steps()
|
|
200
|
+
record_activity = self.env["automation.record.step"].search(
|
|
201
|
+
[("configuration_step_id", "=", activity.id)]
|
|
202
|
+
)
|
|
203
|
+
record_child_activity = self.env["automation.record.step"].search(
|
|
204
|
+
[("configuration_step_id", "=", child_activity.id)]
|
|
205
|
+
)
|
|
206
|
+
self.assertEqual(
|
|
207
|
+
record_activity, self.partner_01.activity_ids.automation_record_step_id
|
|
208
|
+
)
|
|
209
|
+
self.assertFalse(record_activity.activity_done_on)
|
|
210
|
+
self.assertFalse(record_child_activity.scheduled_date)
|
|
211
|
+
self.partner_01.activity_ids.with_user(self.user.id).unlink()
|
|
212
|
+
self.assertFalse(record_activity.activity_done_on)
|
|
213
|
+
self.assertFalse(record_child_activity.scheduled_date)
|
|
214
|
+
self.assertEqual(record_child_activity.state, "rejected")
|
|
215
|
+
|
|
104
216
|
def test_activity_execution_cancel_child(self):
|
|
105
217
|
"""
|
|
106
|
-
We will check the execution of the child task (activity_cancel) is
|
|
107
|
-
after the activity is
|
|
218
|
+
We will check the execution of the child task (activity_cancel) is
|
|
219
|
+
only scheduled after the activity is cancelled
|
|
108
220
|
"""
|
|
109
221
|
activity = self.create_activity_action()
|
|
110
222
|
child_activity = self.create_server_action(
|
|
111
223
|
parent_id=activity.id, trigger_type="activity_cancel"
|
|
112
224
|
)
|
|
113
|
-
self.configuration.editable_domain = "[('id', '=',
|
|
225
|
+
self.configuration.editable_domain = f"[('id', '=', {self.partner_01.id})]"
|
|
114
226
|
self.configuration.start_automation()
|
|
115
227
|
self.env["automation.configuration"].cron_automation()
|
|
116
228
|
self.env["automation.record.step"]._cron_automation_steps()
|
|
@@ -138,7 +250,7 @@ class TestAutomationActivity(AutomationTestCase):
|
|
|
138
250
|
child_activity = self.create_server_action(
|
|
139
251
|
parent_id=activity.id, trigger_type="activity_cancel"
|
|
140
252
|
)
|
|
141
|
-
self.configuration.editable_domain = "[('id', '=',
|
|
253
|
+
self.configuration.editable_domain = f"[('id', '=', {self.partner_01.id})]"
|
|
142
254
|
self.configuration.start_automation()
|
|
143
255
|
self.env["automation.configuration"].cron_automation()
|
|
144
256
|
self.env["automation.record.step"]._cron_automation_steps()
|
|
@@ -167,7 +279,7 @@ class TestAutomationActivity(AutomationTestCase):
|
|
|
167
279
|
child_activity = self.create_server_action(
|
|
168
280
|
parent_id=activity.id, trigger_type="activity_not_done"
|
|
169
281
|
)
|
|
170
|
-
self.configuration.editable_domain = "[('id', '=',
|
|
282
|
+
self.configuration.editable_domain = f"[('id', '=', {self.partner_01.id})]"
|
|
171
283
|
self.configuration.start_automation()
|
|
172
284
|
self.env["automation.configuration"].cron_automation()
|
|
173
285
|
self.env["automation.record.step"]._cron_automation_steps()
|
|
@@ -198,7 +310,7 @@ class TestAutomationActivity(AutomationTestCase):
|
|
|
198
310
|
child_activity = self.create_server_action(
|
|
199
311
|
parent_id=activity.id, trigger_type="activity_not_done"
|
|
200
312
|
)
|
|
201
|
-
self.configuration.editable_domain = "[('id', '=',
|
|
313
|
+
self.configuration.editable_domain = f"[('id', '=', {self.partner_01.id})]"
|
|
202
314
|
self.configuration.start_automation()
|
|
203
315
|
self.env["automation.configuration"].cron_automation()
|
|
204
316
|
self.env["automation.record.step"]._cron_automation_steps()
|
|
@@ -7,8 +7,11 @@ from freezegun import freeze_time
|
|
|
7
7
|
|
|
8
8
|
from odoo.exceptions import ValidationError
|
|
9
9
|
from odoo.tests import Form
|
|
10
|
+
from odoo.tools import mute_logger
|
|
10
11
|
from odoo.tools.safe_eval import safe_eval
|
|
11
12
|
|
|
13
|
+
from odoo.addons.mail.tests.common import mail_new_test_user
|
|
14
|
+
|
|
12
15
|
from .common import AutomationTestCase
|
|
13
16
|
|
|
14
17
|
|
|
@@ -135,7 +138,7 @@ class TestAutomationBase(AutomationTestCase):
|
|
|
135
138
|
the records that fulfill the domain
|
|
136
139
|
"""
|
|
137
140
|
self.create_server_action()
|
|
138
|
-
self.configuration.editable_domain = "[('id', '=',
|
|
141
|
+
self.configuration.editable_domain = f"[('id', '=', {self.partner_01.id})]"
|
|
139
142
|
self.configuration.start_automation()
|
|
140
143
|
self.env["automation.configuration"].cron_automation()
|
|
141
144
|
self.assertEqual(
|
|
@@ -162,7 +165,7 @@ class TestAutomationBase(AutomationTestCase):
|
|
|
162
165
|
Check that the error is raised properly and stored the full error
|
|
163
166
|
"""
|
|
164
167
|
activity = self.create_server_action(server_action_id=self.error_action.id)
|
|
165
|
-
self.configuration.editable_domain = "[('id', '=',
|
|
168
|
+
self.configuration.editable_domain = f"[('id', '=', {self.partner_01.id})]"
|
|
166
169
|
self.configuration.start_automation()
|
|
167
170
|
self.env["automation.configuration"].cron_automation()
|
|
168
171
|
record = self.env["automation.record.step"].search(
|
|
@@ -178,7 +181,7 @@ class TestAutomationBase(AutomationTestCase):
|
|
|
178
181
|
Check the record computed fields of record
|
|
179
182
|
"""
|
|
180
183
|
self.create_server_action(server_action_id=self.error_action.id)
|
|
181
|
-
self.configuration.editable_domain = "[('id', '=',
|
|
184
|
+
self.configuration.editable_domain = f"[('id', '=', {self.partner_01.id})]"
|
|
182
185
|
self.configuration.start_automation()
|
|
183
186
|
self.env["automation.configuration"].cron_automation()
|
|
184
187
|
record = self.env["automation.record"].search(
|
|
@@ -194,7 +197,7 @@ class TestAutomationBase(AutomationTestCase):
|
|
|
194
197
|
Testing that expired actions are not executed
|
|
195
198
|
"""
|
|
196
199
|
activity = self.create_server_action(expiry=True, trigger_interval=1)
|
|
197
|
-
self.configuration.editable_domain = "[('id', '=',
|
|
200
|
+
self.configuration.editable_domain = f"[('id', '=', {self.partner_01.id})]"
|
|
198
201
|
self.configuration.start_automation()
|
|
199
202
|
self.env["automation.configuration"].cron_automation()
|
|
200
203
|
record_activity = self.env["automation.record.step"].search(
|
|
@@ -209,7 +212,7 @@ class TestAutomationBase(AutomationTestCase):
|
|
|
209
212
|
Testing that cancelled actions are not executed
|
|
210
213
|
"""
|
|
211
214
|
activity = self.create_server_action()
|
|
212
|
-
self.configuration.editable_domain = "[('id', '=',
|
|
215
|
+
self.configuration.editable_domain = f"[('id', '=', {self.partner_01.id})]"
|
|
213
216
|
self.configuration.start_automation()
|
|
214
217
|
self.env["automation.configuration"].cron_automation()
|
|
215
218
|
record_activity = self.env["automation.record.step"].search(
|
|
@@ -221,12 +224,44 @@ class TestAutomationBase(AutomationTestCase):
|
|
|
221
224
|
self.env["automation.record.step"]._cron_automation_steps()
|
|
222
225
|
self.assertEqual("cancel", record_activity.state)
|
|
223
226
|
|
|
227
|
+
def test_retry_exception(self):
|
|
228
|
+
"""
|
|
229
|
+
Testing that cancelled actions are not executed
|
|
230
|
+
"""
|
|
231
|
+
activity = self.create_server_action()
|
|
232
|
+
self.configuration.editable_domain = "[('id', '=', %s)]" % self.partner_01.id
|
|
233
|
+
self.configuration.start_automation()
|
|
234
|
+
self.env["automation.configuration"].cron_automation()
|
|
235
|
+
record_activity = self.env["automation.record.step"].search(
|
|
236
|
+
[("configuration_step_id", "=", activity.id)]
|
|
237
|
+
)
|
|
238
|
+
self.assertEqual("scheduled", record_activity.state)
|
|
239
|
+
with self.assertRaises(ValidationError):
|
|
240
|
+
record_activity.retry()
|
|
241
|
+
|
|
242
|
+
def test_retry(self):
|
|
243
|
+
"""
|
|
244
|
+
Testing that cancelled actions are not executed
|
|
245
|
+
"""
|
|
246
|
+
activity = self.create_server_action()
|
|
247
|
+
self.configuration.editable_domain = "[('id', '=', %s)]" % self.partner_01.id
|
|
248
|
+
self.configuration.start_automation()
|
|
249
|
+
self.env["automation.configuration"].cron_automation()
|
|
250
|
+
record_activity = self.env["automation.record.step"].search(
|
|
251
|
+
[("configuration_step_id", "=", activity.id)]
|
|
252
|
+
)
|
|
253
|
+
self.assertEqual("scheduled", record_activity.state)
|
|
254
|
+
record_activity.cancel()
|
|
255
|
+
self.assertEqual("cancel", record_activity.state)
|
|
256
|
+
record_activity.retry()
|
|
257
|
+
self.assertEqual("scheduled", record_activity.state)
|
|
258
|
+
|
|
224
259
|
def test_counter(self):
|
|
225
260
|
"""
|
|
226
261
|
Check the counter function
|
|
227
262
|
"""
|
|
228
263
|
self.create_server_action(server_action_id=self.error_action.id)
|
|
229
|
-
self.configuration.editable_domain = "[('id', '=',
|
|
264
|
+
self.configuration.editable_domain = f"[('id', '=', {self.partner_01.id})]"
|
|
230
265
|
self.configuration.start_automation()
|
|
231
266
|
self.assertEqual(0, self.configuration.record_count)
|
|
232
267
|
self.assertEqual(0, self.configuration.record_test_count)
|
|
@@ -274,7 +309,7 @@ class TestAutomationBase(AutomationTestCase):
|
|
|
274
309
|
activity_02 = self.create_server_action(server_action_id=self.error_action.id)
|
|
275
310
|
activity_03 = self.create_mail_activity()
|
|
276
311
|
child_activity = self.create_server_action(parent_id=activity_01.id)
|
|
277
|
-
self.configuration.editable_domain = "[('id', '=',
|
|
312
|
+
self.configuration.editable_domain = f"[('id', '=', {self.partner_01.id})]"
|
|
278
313
|
self.configuration.start_automation()
|
|
279
314
|
self.env["automation.configuration"].cron_automation()
|
|
280
315
|
self.assertEqual(0, self.configuration.activity_mail_count)
|
|
@@ -348,9 +383,7 @@ class TestAutomationBase(AutomationTestCase):
|
|
|
348
383
|
with freeze_time("2022-01-01"):
|
|
349
384
|
activity = self.create_server_action(trigger_interval=1)
|
|
350
385
|
self.assertEqual(1, activity.trigger_interval_hours)
|
|
351
|
-
self.configuration.editable_domain = (
|
|
352
|
-
"[('id', '=', %s)]" % self.partner_01.id
|
|
353
|
-
)
|
|
386
|
+
self.configuration.editable_domain = f"[('id', '=', {self.partner_01.id})]"
|
|
354
387
|
self.configuration.start_automation()
|
|
355
388
|
self.env["automation.configuration"].cron_automation()
|
|
356
389
|
record_activity = self.env["automation.record.step"].search(
|
|
@@ -367,9 +400,7 @@ class TestAutomationBase(AutomationTestCase):
|
|
|
367
400
|
trigger_interval=1, trigger_interval_type="days"
|
|
368
401
|
)
|
|
369
402
|
self.assertEqual(24, activity.trigger_interval_hours)
|
|
370
|
-
self.configuration.editable_domain = (
|
|
371
|
-
"[('id', '=', %s)]" % self.partner_01.id
|
|
372
|
-
)
|
|
403
|
+
self.configuration.editable_domain = f"[('id', '=', {self.partner_01.id})]"
|
|
373
404
|
self.configuration.start_automation()
|
|
374
405
|
self.env["automation.configuration"].cron_automation()
|
|
375
406
|
record_activity = self.env["automation.record.step"].search(
|
|
@@ -400,7 +431,7 @@ class TestAutomationBase(AutomationTestCase):
|
|
|
400
431
|
|
|
401
432
|
def test_field_not_field_unicity(self):
|
|
402
433
|
self.configuration.editable_domain = (
|
|
403
|
-
"[('id', 'in',
|
|
434
|
+
f"[('id', 'in', [{self.partner_01.id}, {self.partner_02.id}])]"
|
|
404
435
|
)
|
|
405
436
|
self.configuration.start_automation()
|
|
406
437
|
self.env["automation.configuration"].cron_automation()
|
|
@@ -415,7 +446,7 @@ class TestAutomationBase(AutomationTestCase):
|
|
|
415
446
|
|
|
416
447
|
def test_field_field_unicity(self):
|
|
417
448
|
self.configuration.editable_domain = (
|
|
418
|
-
"[('id', 'in',
|
|
449
|
+
f"[('id', 'in', [{self.partner_01.id}, {self.partner_02.id}])]"
|
|
419
450
|
)
|
|
420
451
|
self.configuration.field_id = self.env.ref("base.field_res_partner__email")
|
|
421
452
|
self.configuration.start_automation()
|
|
@@ -497,11 +528,11 @@ class TestAutomationBase(AutomationTestCase):
|
|
|
497
528
|
with Form(
|
|
498
529
|
self.env["automation.configuration.test"].with_context(
|
|
499
530
|
default_configuration_id=self.configuration.id,
|
|
500
|
-
|
|
531
|
+
default_model=self.configuration.model,
|
|
501
532
|
)
|
|
502
533
|
) as f:
|
|
503
534
|
self.assertTrue(f.resource_ref)
|
|
504
|
-
f.resource_ref = "
|
|
535
|
+
f.resource_ref = f"{self.partner_01._name},{self.partner_01.id}"
|
|
505
536
|
wizard = f.save()
|
|
506
537
|
wizard_action = wizard.test_record()
|
|
507
538
|
record = self.env[wizard_action["res_model"]].browse(wizard_action["res_id"])
|
|
@@ -559,9 +590,9 @@ class TestAutomationBase(AutomationTestCase):
|
|
|
559
590
|
)
|
|
560
591
|
self.create_server_action()
|
|
561
592
|
self.create_server_action(configuration_id=configuration_2.id)
|
|
562
|
-
self.configuration.editable_domain = "[('id', '=',
|
|
593
|
+
self.configuration.editable_domain = f"[('id', '=', {self.partner_01.id})]"
|
|
563
594
|
self.configuration.start_automation()
|
|
564
|
-
configuration_2.editable_domain = "[('id', '=',
|
|
595
|
+
configuration_2.editable_domain = f"[('id', '=', {self.partner_01.id})]"
|
|
565
596
|
configuration_2.start_automation()
|
|
566
597
|
self.env["automation.configuration"].cron_automation()
|
|
567
598
|
record_activity = self.env["automation.record"].search(
|
|
@@ -569,14 +600,35 @@ class TestAutomationBase(AutomationTestCase):
|
|
|
569
600
|
)
|
|
570
601
|
self.assertEqual(2, len(record_activity))
|
|
571
602
|
|
|
603
|
+
@mute_logger("odoo.addons.automation_oca.models.automation_record")
|
|
572
604
|
def test_generation_orphan_record(self):
|
|
605
|
+
self.user_automation = mail_new_test_user(
|
|
606
|
+
self.env,
|
|
607
|
+
login="user_automation",
|
|
608
|
+
name="User automation",
|
|
609
|
+
email="user_automation@test.example.com",
|
|
610
|
+
company_id=self.env.user.company_id.id,
|
|
611
|
+
notification_type="inbox",
|
|
612
|
+
groups="base.user_admin, automation_oca.group_automation_manager",
|
|
613
|
+
)
|
|
573
614
|
self.configuration.editable_domain = (
|
|
574
|
-
"['|', ('id', '=',
|
|
575
|
-
|
|
615
|
+
f"['|', ('id', '=', {self.partner_01.id}),"
|
|
616
|
+
f" ('id', '=', {self.partner_02.id})]"
|
|
576
617
|
)
|
|
577
618
|
self.configuration.start_automation()
|
|
578
619
|
self.env["automation.configuration"].cron_automation()
|
|
579
620
|
self.partner_01.unlink()
|
|
621
|
+
# We need two searches because in the first one, we access as a non-superuser to
|
|
622
|
+
# avoid the first return of the private method _search of automation.record and
|
|
623
|
+
# thus be able to access the part where orphaned records are filtered. The
|
|
624
|
+
# second search is to finally get the query we need, which is the one performed
|
|
625
|
+
# by accessing as a superuser.
|
|
626
|
+
automation_record_obj = self.env["automation.record"].with_user(
|
|
627
|
+
self.user_automation.id
|
|
628
|
+
)
|
|
629
|
+
records = automation_record_obj.search(
|
|
630
|
+
[("configuration_id", "=", self.configuration.id), ("is_test", "=", False)]
|
|
631
|
+
)
|
|
580
632
|
records = self.env["automation.record"].search(
|
|
581
633
|
[("configuration_id", "=", self.configuration.id), ("is_test", "=", False)]
|
|
582
634
|
)
|
|
@@ -586,64 +638,3 @@ class TestAutomationBase(AutomationTestCase):
|
|
|
586
638
|
self.assertTrue(
|
|
587
639
|
orphan_record_found, "No record named 'Orphan Record' was found"
|
|
588
640
|
)
|
|
589
|
-
|
|
590
|
-
def test_delete_step_executed(self):
|
|
591
|
-
"""
|
|
592
|
-
Testing that deleting a step will keep the results of the executed related steps
|
|
593
|
-
"""
|
|
594
|
-
activity = self.create_server_action()
|
|
595
|
-
child_activity = self.create_server_action(parent_id=activity.id)
|
|
596
|
-
self.configuration.editable_domain = "[('id', '=', %s)]" % self.partner_01.id
|
|
597
|
-
self.configuration.start_automation()
|
|
598
|
-
self.env["automation.configuration"].cron_automation()
|
|
599
|
-
record_activity = self.env["automation.record.step"].search(
|
|
600
|
-
[("configuration_step_id", "=", activity.id)]
|
|
601
|
-
)
|
|
602
|
-
self.assertEqual("scheduled", record_activity.state)
|
|
603
|
-
self.assertFalse(
|
|
604
|
-
self.env["automation.record.step"].search(
|
|
605
|
-
[("configuration_step_id", "=", child_activity.id)]
|
|
606
|
-
)
|
|
607
|
-
)
|
|
608
|
-
self.env["automation.record.step"]._cron_automation_steps()
|
|
609
|
-
self.assertEqual("done", record_activity.state)
|
|
610
|
-
record_child_activity = self.env["automation.record.step"].search(
|
|
611
|
-
[("configuration_step_id", "=", child_activity.id)]
|
|
612
|
-
)
|
|
613
|
-
self.assertEqual("scheduled", record_child_activity.state)
|
|
614
|
-
self.env["automation.record.step"]._cron_automation_steps()
|
|
615
|
-
self.assertEqual("done", record_child_activity.state)
|
|
616
|
-
child_activity.unlink()
|
|
617
|
-
child_activity.flush_recordset()
|
|
618
|
-
self.assertEqual("action", record_child_activity.step_type)
|
|
619
|
-
|
|
620
|
-
def test_delete_step_to_execute(self):
|
|
621
|
-
"""
|
|
622
|
-
Testing that deleting a step will make pending actions related
|
|
623
|
-
to be rejected
|
|
624
|
-
"""
|
|
625
|
-
activity = self.create_server_action()
|
|
626
|
-
child_activity = self.create_server_action(parent_id=activity.id)
|
|
627
|
-
self.configuration.editable_domain = "[('id', '=', %s)]" % self.partner_01.id
|
|
628
|
-
self.configuration.start_automation()
|
|
629
|
-
self.env["automation.configuration"].cron_automation()
|
|
630
|
-
record_activity = self.env["automation.record.step"].search(
|
|
631
|
-
[("configuration_step_id", "=", activity.id)]
|
|
632
|
-
)
|
|
633
|
-
self.assertEqual("scheduled", record_activity.state)
|
|
634
|
-
self.assertFalse(
|
|
635
|
-
self.env["automation.record.step"].search(
|
|
636
|
-
[("configuration_step_id", "=", child_activity.id)]
|
|
637
|
-
)
|
|
638
|
-
)
|
|
639
|
-
self.env["automation.record.step"]._cron_automation_steps()
|
|
640
|
-
self.assertEqual("done", record_activity.state)
|
|
641
|
-
record_child_activity = self.env["automation.record.step"].search(
|
|
642
|
-
[("configuration_step_id", "=", child_activity.id)]
|
|
643
|
-
)
|
|
644
|
-
self.assertEqual("scheduled", record_child_activity.state)
|
|
645
|
-
child_activity.unlink()
|
|
646
|
-
child_activity.flush_recordset()
|
|
647
|
-
self.assertEqual("action", record_child_activity.step_type)
|
|
648
|
-
self.env["automation.record.step"]._cron_automation_steps()
|
|
649
|
-
self.assertEqual("rejected", record_child_activity.state)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Copyright 2024 Dixmit
|
|
2
|
+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
|
3
|
+
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
|
|
6
|
+
from freezegun import freeze_time
|
|
7
|
+
from odoo_test_helper import FakeModelLoader
|
|
8
|
+
|
|
9
|
+
from .common import AutomationTestCase
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class TestAutomationDate(AutomationTestCase):
|
|
13
|
+
@classmethod
|
|
14
|
+
def setUpClass(cls):
|
|
15
|
+
super().setUpClass()
|
|
16
|
+
cls.loader = FakeModelLoader(cls.env, cls.__module__)
|
|
17
|
+
cls.loader.backup_registry()
|
|
18
|
+
|
|
19
|
+
# The fake class is imported here !! After the backup_registry
|
|
20
|
+
from .models import ResPartner
|
|
21
|
+
|
|
22
|
+
cls.loader.update_registry((ResPartner,))
|
|
23
|
+
|
|
24
|
+
@classmethod
|
|
25
|
+
def tearDownClass(cls):
|
|
26
|
+
cls.loader.restore_registry()
|
|
27
|
+
super().tearDownClass()
|
|
28
|
+
|
|
29
|
+
def test_schedule_date_force(self):
|
|
30
|
+
partner_01 = self.env["res.partner"].create(
|
|
31
|
+
{
|
|
32
|
+
"name": "Demo partner",
|
|
33
|
+
"comment": "Demo",
|
|
34
|
+
"email": "test@test.com",
|
|
35
|
+
"date": "2025-01-01",
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
with freeze_time("2024-01-01 00:00:00"):
|
|
39
|
+
activity = self.create_server_action(
|
|
40
|
+
trigger_date_kind="date",
|
|
41
|
+
trigger_date_field_id=self.env["ir.model.fields"]
|
|
42
|
+
.search(
|
|
43
|
+
[
|
|
44
|
+
("name", "=", "date"),
|
|
45
|
+
("model", "=", "res.partner"),
|
|
46
|
+
]
|
|
47
|
+
)
|
|
48
|
+
.id,
|
|
49
|
+
trigger_interval=1,
|
|
50
|
+
trigger_interval_type="days",
|
|
51
|
+
)
|
|
52
|
+
self.configuration.editable_domain = f"[('id', '=', {partner_01.id})]"
|
|
53
|
+
self.configuration.start_automation()
|
|
54
|
+
self.env["automation.configuration"].cron_automation()
|
|
55
|
+
record_activity = self.env["automation.record.step"].search(
|
|
56
|
+
[("configuration_step_id", "=", activity.id)]
|
|
57
|
+
)
|
|
58
|
+
self.assertEqual("scheduled", record_activity.state)
|
|
59
|
+
self.assertEqual(record_activity.scheduled_date, datetime(2025, 1, 2))
|