odoo-addon-automation-oca 16.0.1.6.0.2__py3-none-any.whl → 16.0.1.6.1__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 +1 -1
- odoo/addons/automation_oca/__manifest__.py +2 -1
- odoo/addons/automation_oca/i18n/automation_oca.pot +42 -0
- odoo/addons/automation_oca/models/automation_configuration.py +292 -0
- odoo/addons/automation_oca/models/automation_configuration_step.py +128 -0
- odoo/addons/automation_oca/security/ir.model.access.csv +1 -0
- odoo/addons/automation_oca/static/description/index.html +1 -1
- odoo/addons/automation_oca/static/src/views/automation_upload/automation_upload.esm.js +67 -0
- odoo/addons/automation_oca/static/src/views/automation_upload/automation_upload.scss +29 -0
- odoo/addons/automation_oca/static/src/views/automation_upload/automation_upload.xml +51 -0
- odoo/addons/automation_oca/tests/__init__.py +1 -0
- odoo/addons/automation_oca/tests/test_automation_import.py +123 -0
- odoo/addons/automation_oca/views/automation_configuration.xml +12 -1
- odoo/addons/automation_oca/wizards/__init__.py +1 -0
- odoo/addons/automation_oca/wizards/automation_configuration_export.py +16 -0
- odoo/addons/automation_oca/wizards/automation_configuration_export.xml +35 -0
- {odoo_addon_automation_oca-16.0.1.6.0.2.dist-info → odoo_addon_automation_oca-16.0.1.6.1.dist-info}/METADATA +2 -2
- {odoo_addon_automation_oca-16.0.1.6.0.2.dist-info → odoo_addon_automation_oca-16.0.1.6.1.dist-info}/RECORD +20 -14
- {odoo_addon_automation_oca-16.0.1.6.0.2.dist-info → odoo_addon_automation_oca-16.0.1.6.1.dist-info}/WHEEL +0 -0
- {odoo_addon_automation_oca-16.0.1.6.0.2.dist-info → odoo_addon_automation_oca-16.0.1.6.1.dist-info}/top_level.txt +0 -0
|
@@ -11,7 +11,7 @@ Automation Oca
|
|
|
11
11
|
!! This file is generated by oca-gen-addon-readme !!
|
|
12
12
|
!! changes will be overwritten. !!
|
|
13
13
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
14
|
-
!! source digest: sha256:
|
|
14
|
+
!! source digest: sha256:69fb14c7a439c6751286889ba6e2066f2c21764271364f9acfecf97673196f7f
|
|
15
15
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
16
16
|
|
|
17
17
|
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"name": "Automation Oca",
|
|
6
6
|
"summary": """
|
|
7
7
|
Automate actions in threaded models""",
|
|
8
|
-
"version": "16.0.1.6.
|
|
8
|
+
"version": "16.0.1.6.1",
|
|
9
9
|
"license": "AGPL-3",
|
|
10
10
|
"category": "Automation",
|
|
11
11
|
"author": "Dixmit,Odoo Community Association (OCA)",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"data": [
|
|
15
15
|
"security/security.xml",
|
|
16
16
|
"security/ir.model.access.csv",
|
|
17
|
+
"wizards/automation_configuration_export.xml",
|
|
17
18
|
"views/menu.xml",
|
|
18
19
|
"wizards/automation_configuration_test.xml",
|
|
19
20
|
"views/automation_record.xml",
|
|
@@ -262,6 +262,12 @@ msgstr ""
|
|
|
262
262
|
msgid "Automation Configuration"
|
|
263
263
|
msgstr ""
|
|
264
264
|
|
|
265
|
+
#. module: automation_oca
|
|
266
|
+
#: model:ir.actions.act_window,name:automation_oca.automation_configuration_export_act_window
|
|
267
|
+
#: model_terms:ir.ui.view,arch_db:automation_oca.automation_configuration_export_form_view
|
|
268
|
+
msgid "Automation Configuration Export"
|
|
269
|
+
msgstr ""
|
|
270
|
+
|
|
265
271
|
#. module: automation_oca
|
|
266
272
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration__automation_direct_step_ids
|
|
267
273
|
msgid "Automation Direct Step"
|
|
@@ -345,6 +351,7 @@ msgid "Bounced after"
|
|
|
345
351
|
msgstr ""
|
|
346
352
|
|
|
347
353
|
#. module: automation_oca
|
|
354
|
+
#: model_terms:ir.ui.view,arch_db:automation_oca.automation_configuration_export_form_view
|
|
348
355
|
#: model_terms:ir.ui.view,arch_db:automation_oca.automation_configuration_test_form_view
|
|
349
356
|
#: model_terms:ir.ui.view,arch_db:automation_oca.automation_record_form_view
|
|
350
357
|
msgid "Cancel"
|
|
@@ -403,6 +410,7 @@ msgid "Company"
|
|
|
403
410
|
msgstr ""
|
|
404
411
|
|
|
405
412
|
#. module: automation_oca
|
|
413
|
+
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration_export__configuration_id
|
|
406
414
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration_step__configuration_id
|
|
407
415
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration_test__configuration_id
|
|
408
416
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_record__configuration_id
|
|
@@ -420,6 +428,7 @@ msgstr ""
|
|
|
420
428
|
|
|
421
429
|
#. module: automation_oca
|
|
422
430
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration__create_uid
|
|
431
|
+
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration_export__create_uid
|
|
423
432
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration_step__create_uid
|
|
424
433
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration_test__create_uid
|
|
425
434
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_filter__create_uid
|
|
@@ -431,6 +440,7 @@ msgstr ""
|
|
|
431
440
|
|
|
432
441
|
#. module: automation_oca
|
|
433
442
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration__create_date
|
|
443
|
+
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration_export__create_date
|
|
434
444
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration_step__create_date
|
|
435
445
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration_test__create_date
|
|
436
446
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_filter__create_date
|
|
@@ -460,6 +470,7 @@ msgstr ""
|
|
|
460
470
|
|
|
461
471
|
#. module: automation_oca
|
|
462
472
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration__display_name
|
|
473
|
+
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration_export__display_name
|
|
463
474
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration_step__display_name
|
|
464
475
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration_test__display_name
|
|
465
476
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_filter__display_name
|
|
@@ -584,6 +595,11 @@ msgstr ""
|
|
|
584
595
|
msgid "Expiry Interval Type"
|
|
585
596
|
msgstr ""
|
|
586
597
|
|
|
598
|
+
#. module: automation_oca
|
|
599
|
+
#: model_terms:ir.ui.view,arch_db:automation_oca.automation_configuration_form_view
|
|
600
|
+
msgid "Export"
|
|
601
|
+
msgstr ""
|
|
602
|
+
|
|
587
603
|
#. module: automation_oca
|
|
588
604
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration__field_id
|
|
589
605
|
msgid "Field"
|
|
@@ -594,6 +610,16 @@ msgstr ""
|
|
|
594
610
|
msgid "Field Label"
|
|
595
611
|
msgstr ""
|
|
596
612
|
|
|
613
|
+
#. module: automation_oca
|
|
614
|
+
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration_export__file_content
|
|
615
|
+
msgid "File Content"
|
|
616
|
+
msgstr ""
|
|
617
|
+
|
|
618
|
+
#. module: automation_oca
|
|
619
|
+
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration_export__file_name
|
|
620
|
+
msgid "File Name"
|
|
621
|
+
msgstr ""
|
|
622
|
+
|
|
597
623
|
#. module: automation_oca
|
|
598
624
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration__filter_id
|
|
599
625
|
#: model_terms:ir.ui.view,arch_db:automation_oca.automation_configuration_form_view
|
|
@@ -696,6 +722,7 @@ msgstr ""
|
|
|
696
722
|
|
|
697
723
|
#. module: automation_oca
|
|
698
724
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration__id
|
|
725
|
+
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration_export__id
|
|
699
726
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration_step__id
|
|
700
727
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration_test__id
|
|
701
728
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_filter__id
|
|
@@ -750,6 +777,7 @@ msgstr ""
|
|
|
750
777
|
|
|
751
778
|
#. module: automation_oca
|
|
752
779
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration____last_update
|
|
780
|
+
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration_export____last_update
|
|
753
781
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration_step____last_update
|
|
754
782
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration_test____last_update
|
|
755
783
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_filter____last_update
|
|
@@ -761,6 +789,7 @@ msgstr ""
|
|
|
761
789
|
|
|
762
790
|
#. module: automation_oca
|
|
763
791
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration__write_uid
|
|
792
|
+
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration_export__write_uid
|
|
764
793
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration_step__write_uid
|
|
765
794
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration_test__write_uid
|
|
766
795
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_filter__write_uid
|
|
@@ -772,6 +801,7 @@ msgstr ""
|
|
|
772
801
|
|
|
773
802
|
#. module: automation_oca
|
|
774
803
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration__write_date
|
|
804
|
+
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration_export__write_date
|
|
775
805
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration_step__write_date
|
|
776
806
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_configuration_test__write_date
|
|
777
807
|
#: model:ir.model.fields,field_description:automation_oca.field_automation_filter__write_date
|
|
@@ -1461,6 +1491,13 @@ msgstr ""
|
|
|
1461
1491
|
msgid "Unicity based on"
|
|
1462
1492
|
msgstr ""
|
|
1463
1493
|
|
|
1494
|
+
#. module: automation_oca
|
|
1495
|
+
#. odoo-javascript
|
|
1496
|
+
#: code:addons/automation_oca/static/src/views/automation_upload/automation_upload.xml:0
|
|
1497
|
+
#, python-format
|
|
1498
|
+
msgid "Upload"
|
|
1499
|
+
msgstr ""
|
|
1500
|
+
|
|
1464
1501
|
#. module: automation_oca
|
|
1465
1502
|
#: model:ir.model.fields,help:automation_oca.field_automation_configuration_step__activity_user_type
|
|
1466
1503
|
msgid ""
|
|
@@ -1499,6 +1536,11 @@ msgstr ""
|
|
|
1499
1536
|
msgid "Welcome! Thanks for being part of our database"
|
|
1500
1537
|
msgstr ""
|
|
1501
1538
|
|
|
1539
|
+
#. module: automation_oca
|
|
1540
|
+
#: model:ir.model,name:automation_oca.model_automation_configuration_export
|
|
1541
|
+
msgid "automation.configuration.export"
|
|
1542
|
+
msgstr ""
|
|
1543
|
+
|
|
1502
1544
|
#. module: automation_oca
|
|
1503
1545
|
#: model_terms:ir.ui.view,arch_db:automation_oca.automation_configuration_form_view
|
|
1504
1546
|
#: model_terms:ir.ui.view,arch_db:automation_oca.automation_configuration_step_form_view
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# Copyright 2024 Dixmit
|
|
2
2
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
|
3
3
|
|
|
4
|
+
import base64
|
|
5
|
+
import json
|
|
6
|
+
import uuid
|
|
4
7
|
from collections import defaultdict
|
|
5
8
|
|
|
6
9
|
from odoo import _, api, fields, models
|
|
@@ -326,3 +329,292 @@ class AutomationConfiguration(models.Model):
|
|
|
326
329
|
"model_id": self.model_id.id,
|
|
327
330
|
}
|
|
328
331
|
)
|
|
332
|
+
|
|
333
|
+
def export_configuration(self):
|
|
334
|
+
"""
|
|
335
|
+
Export the configuration to a JSON format.
|
|
336
|
+
This method is used to export the configuration for external use.
|
|
337
|
+
"""
|
|
338
|
+
self.ensure_one()
|
|
339
|
+
data = self._export_configuration()
|
|
340
|
+
action = self.env["ir.actions.act_window"]._for_xml_id(
|
|
341
|
+
"automation_oca.automation_configuration_export_act_window"
|
|
342
|
+
)
|
|
343
|
+
action["res_id"] = (
|
|
344
|
+
self.env["automation.configuration.export"]
|
|
345
|
+
.create(
|
|
346
|
+
{
|
|
347
|
+
"configuration_id": self.id,
|
|
348
|
+
"file_name": f"automation_configuration_{self.name or 'export'}.json",
|
|
349
|
+
"file_content": base64.b64encode(
|
|
350
|
+
json.dumps(data).encode()
|
|
351
|
+
).decode(),
|
|
352
|
+
}
|
|
353
|
+
)
|
|
354
|
+
.id
|
|
355
|
+
)
|
|
356
|
+
return action
|
|
357
|
+
|
|
358
|
+
def _export_configuration(self):
|
|
359
|
+
self.ensure_one()
|
|
360
|
+
data = {
|
|
361
|
+
"id": self._get_external_xmlid(self),
|
|
362
|
+
"name": self.name,
|
|
363
|
+
"domain": self.domain,
|
|
364
|
+
"model_id": self._get_external_xmlid(self.model_id),
|
|
365
|
+
"field_id": self._get_external_xmlid(self.field_id),
|
|
366
|
+
"is_periodic": self.is_periodic,
|
|
367
|
+
"steps": [],
|
|
368
|
+
}
|
|
369
|
+
extra_data = defaultdict(lambda: {})
|
|
370
|
+
for step in self.automation_direct_step_ids:
|
|
371
|
+
step_data = step._export_step(extra_data)
|
|
372
|
+
if step_data:
|
|
373
|
+
data["steps"].append(step_data)
|
|
374
|
+
data["activity_types"] = extra_data["activity_types"]
|
|
375
|
+
data["mail_templates"] = extra_data["mail_templates"]
|
|
376
|
+
data["server_actions"] = extra_data["server_actions"]
|
|
377
|
+
return data
|
|
378
|
+
|
|
379
|
+
def _get_external_xmlid(self, record, module="__export__", name=None):
|
|
380
|
+
if not record:
|
|
381
|
+
return False
|
|
382
|
+
result = record.get_external_id()[record.id]
|
|
383
|
+
if result:
|
|
384
|
+
return result
|
|
385
|
+
if not name:
|
|
386
|
+
name = f"{record._table}_{record.id}_{uuid.uuid4().hex[:8]}"
|
|
387
|
+
self.env["ir.model.data"].create(
|
|
388
|
+
{
|
|
389
|
+
"name": name,
|
|
390
|
+
"model": record._name,
|
|
391
|
+
"res_id": record.id,
|
|
392
|
+
"module": module,
|
|
393
|
+
}
|
|
394
|
+
)
|
|
395
|
+
return f"__export__.{name}"
|
|
396
|
+
|
|
397
|
+
def create_document_from_attachment(self, b64_data):
|
|
398
|
+
data = json.loads(base64.b64decode(b64_data))
|
|
399
|
+
return self._create_document_from_data(data).get_formview_action()
|
|
400
|
+
|
|
401
|
+
def _create_document_from_data(self, data):
|
|
402
|
+
record = self.create(self._create_document_from_data_vals(data))
|
|
403
|
+
langs = [lang[0] for lang in self.env["res.lang"].get_installed()]
|
|
404
|
+
for activity_type_id, activity_type in data.get("activity_types", {}).items():
|
|
405
|
+
if not self.env.ref(activity_type_id, raise_if_not_found=False):
|
|
406
|
+
self._create_document_add_activity_type(
|
|
407
|
+
activity_type_id, activity_type, langs
|
|
408
|
+
)
|
|
409
|
+
for mail_template_id, mail_template in data.get("mail_templates", {}).items():
|
|
410
|
+
if not self.env.ref(mail_template_id, raise_if_not_found=False):
|
|
411
|
+
self._create_document_add_mail_template(
|
|
412
|
+
mail_template_id, mail_template, langs
|
|
413
|
+
)
|
|
414
|
+
for server_action_id, server_action in data.get("server_actions", {}).items():
|
|
415
|
+
if not self.env.ref(server_action_id, raise_if_not_found=False):
|
|
416
|
+
self._create_document_add_server_action(
|
|
417
|
+
server_action_id, server_action, langs
|
|
418
|
+
)
|
|
419
|
+
for step_data in data.get("steps", []):
|
|
420
|
+
record._create_document_step_from_data(step_data)
|
|
421
|
+
return record
|
|
422
|
+
|
|
423
|
+
def _create_document_step_from_data(self, step_data, parent=False):
|
|
424
|
+
step = self.env["automation.configuration.step"].create(
|
|
425
|
+
self._create_step_vals(step_data, parent=parent)
|
|
426
|
+
)
|
|
427
|
+
for child_step in step_data.get("steps", []):
|
|
428
|
+
self._create_document_step_from_data(child_step, parent=step)
|
|
429
|
+
return step
|
|
430
|
+
|
|
431
|
+
def _create_document_add_activity_type(
|
|
432
|
+
self, activity_type_id, activity_data, langs
|
|
433
|
+
):
|
|
434
|
+
activity_type = self.env["mail.activity.type"].create(
|
|
435
|
+
self._create_activity_vals(activity_data)
|
|
436
|
+
)
|
|
437
|
+
activity_fields = self._get_activity_type_translatable_fields()
|
|
438
|
+
for lang in langs:
|
|
439
|
+
vals = {}
|
|
440
|
+
for field in activity_fields:
|
|
441
|
+
if activity_data.get(field) and lang in activity_data[field]:
|
|
442
|
+
vals[field] = activity_data[field][lang]
|
|
443
|
+
if vals:
|
|
444
|
+
activity_type.with_context(lang=lang).write(vals)
|
|
445
|
+
self._get_external_xmlid(
|
|
446
|
+
activity_type,
|
|
447
|
+
module=activity_type_id.split(".")[0],
|
|
448
|
+
name=activity_type_id.split(".")[1],
|
|
449
|
+
)
|
|
450
|
+
|
|
451
|
+
def _get_activity_type_translatable_fields(self):
|
|
452
|
+
"""Return the fields that are translatable for activity types."""
|
|
453
|
+
return ["name", "summary"]
|
|
454
|
+
|
|
455
|
+
def _create_activity_vals(self, activity_data):
|
|
456
|
+
return {
|
|
457
|
+
"name": (activity_data.get("name") or {}).get(
|
|
458
|
+
"en_US", "Imported activity type"
|
|
459
|
+
),
|
|
460
|
+
"summary": (activity_data.get("summary") or {}).get(
|
|
461
|
+
"en_US", "Imported activity summary"
|
|
462
|
+
),
|
|
463
|
+
"sequence": activity_data.get("sequence", 10),
|
|
464
|
+
"delay_count": activity_data.get("delay_count", 0),
|
|
465
|
+
"delay_unit": activity_data.get("delay_unit", "minutes"),
|
|
466
|
+
"delay_from": activity_data.get("delay_from", "now"),
|
|
467
|
+
"icon": activity_data.get("icon", "fa-clock"),
|
|
468
|
+
"decoration_type": activity_data.get("decoration_type"),
|
|
469
|
+
"res_model": activity_data.get("res_model"),
|
|
470
|
+
"triggered_next_type_id": activity_data.get("triggered_next_type_id")
|
|
471
|
+
and (
|
|
472
|
+
self.env.ref(
|
|
473
|
+
activity_data["triggered_next_type_id"], raise_if_not_found=False
|
|
474
|
+
)
|
|
475
|
+
or self.env["mail.activity.type"]
|
|
476
|
+
).id
|
|
477
|
+
or False,
|
|
478
|
+
"chaining_type": activity_data.get("chaining_type"),
|
|
479
|
+
"category": activity_data.get("category"),
|
|
480
|
+
"default_note": activity_data.get("default_note"),
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
def _create_document_add_mail_template(
|
|
484
|
+
self, mail_template_id, mail_template_data, langs
|
|
485
|
+
):
|
|
486
|
+
mail_template = self.env["mail.template"].create(
|
|
487
|
+
self._create_mail_template_vals(mail_template_data)
|
|
488
|
+
)
|
|
489
|
+
mail_template_fields = self._get_mail_template_translatable_fields()
|
|
490
|
+
for lang in langs:
|
|
491
|
+
vals = {}
|
|
492
|
+
for field in mail_template_fields:
|
|
493
|
+
if mail_template_data.get(field) and lang in mail_template_data[field]:
|
|
494
|
+
vals[field] = mail_template_data[field][lang]
|
|
495
|
+
if vals:
|
|
496
|
+
mail_template.with_context(lang=lang).write(vals)
|
|
497
|
+
self._get_external_xmlid(
|
|
498
|
+
mail_template,
|
|
499
|
+
module=mail_template_id.split(".")[0],
|
|
500
|
+
name=mail_template_id.split(".")[1],
|
|
501
|
+
)
|
|
502
|
+
|
|
503
|
+
def _get_mail_template_translatable_fields(self):
|
|
504
|
+
"""Return the fields that are translatable for mail templates."""
|
|
505
|
+
return [
|
|
506
|
+
"name",
|
|
507
|
+
"subject",
|
|
508
|
+
"body_html",
|
|
509
|
+
]
|
|
510
|
+
|
|
511
|
+
def _create_mail_template_vals(self, mail_template_data):
|
|
512
|
+
return {
|
|
513
|
+
"name": (mail_template_data.get("name") or {}).get(
|
|
514
|
+
"en_US", "Imported mail template"
|
|
515
|
+
),
|
|
516
|
+
"subject": (mail_template_data.get("subject") or {}).get("en_US", ""),
|
|
517
|
+
"body_html": (mail_template_data.get("body_html") or {}).get("en_US", ""),
|
|
518
|
+
"model_id": self.env.ref(mail_template_data["model_id"]).id
|
|
519
|
+
if mail_template_data.get("model_id")
|
|
520
|
+
else False,
|
|
521
|
+
"auto_delete": mail_template_data.get("auto_delete", False),
|
|
522
|
+
"lang": mail_template_data.get("lang", False),
|
|
523
|
+
"email_from": mail_template_data.get("email_from", False),
|
|
524
|
+
"email_to": mail_template_data.get("email_to", False),
|
|
525
|
+
"partner_to": mail_template_data.get("partner_to", False),
|
|
526
|
+
"reply_to": mail_template_data.get("reply_to", False),
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
def _create_document_add_server_action(
|
|
530
|
+
self, server_action_id, server_action_data, langs
|
|
531
|
+
):
|
|
532
|
+
server_action = self.env["ir.actions.server"].create(
|
|
533
|
+
self._create_server_action_vals(server_action_data)
|
|
534
|
+
)
|
|
535
|
+
server_action_fields = self._get_server_action_translatable_fields()
|
|
536
|
+
for lang in langs:
|
|
537
|
+
vals = {}
|
|
538
|
+
for field in server_action_fields:
|
|
539
|
+
if server_action_data.get(field) and lang in server_action_data[field]:
|
|
540
|
+
vals[field] = server_action_data[field][lang]
|
|
541
|
+
if vals:
|
|
542
|
+
server_action.with_context(lang=lang).write(vals)
|
|
543
|
+
self._get_external_xmlid(
|
|
544
|
+
server_action,
|
|
545
|
+
module=server_action_id.split(".")[0],
|
|
546
|
+
name=server_action_id.split(".")[1],
|
|
547
|
+
)
|
|
548
|
+
|
|
549
|
+
def _get_server_action_translatable_fields(self):
|
|
550
|
+
"""Return the fields that are translatable for server actions."""
|
|
551
|
+
return [
|
|
552
|
+
"name",
|
|
553
|
+
]
|
|
554
|
+
|
|
555
|
+
def _create_server_action_vals(self, server_action_data):
|
|
556
|
+
return {
|
|
557
|
+
"name": server_action_data.get("name", {}).get(
|
|
558
|
+
"en_US", "Imported server action"
|
|
559
|
+
),
|
|
560
|
+
"state": server_action_data.get("state"),
|
|
561
|
+
"model_id": self.env.ref(server_action_data.get("model_id")).id,
|
|
562
|
+
"binding_model_id": server_action_data.get("binding_model_id")
|
|
563
|
+
and self.env.ref(server_action_data.get("binding_model_id")),
|
|
564
|
+
"binding_type": server_action_data.get("binding_type"),
|
|
565
|
+
"code": server_action_data.get("code"),
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
def _create_step_vals(self, step_data, parent=False):
|
|
569
|
+
return {
|
|
570
|
+
"name": step_data.get("name", ""),
|
|
571
|
+
"step_type": step_data.get("step_type", "mail"),
|
|
572
|
+
"configuration_id": self.id,
|
|
573
|
+
"parent_id": parent.id if parent else False,
|
|
574
|
+
"domain": step_data.get("domain", "[]"),
|
|
575
|
+
"apply_parent_domain": step_data.get("apply_parent_domain", True),
|
|
576
|
+
"trigger_interval": step_data.get("trigger_interval", 0),
|
|
577
|
+
"trigger_interval_type": step_data.get("trigger_interval_type", "seconds"),
|
|
578
|
+
"expiry": step_data.get("expiry", False),
|
|
579
|
+
"expiry_interval": step_data.get("expiry_interval", 0),
|
|
580
|
+
"trigger_type": step_data.get("trigger_type"),
|
|
581
|
+
"mail_author_id": step_data.get("mail_author_id")
|
|
582
|
+
and (
|
|
583
|
+
self.env.ref(step_data.get("mail_author_id"), raise_if_not_found=False)
|
|
584
|
+
or self.env.user
|
|
585
|
+
).id,
|
|
586
|
+
"mail_template_id": step_data.get("mail_template_id")
|
|
587
|
+
and self.env.ref(step_data.get("mail_template_id")).id,
|
|
588
|
+
"server_action_id": step_data.get("server_action_id")
|
|
589
|
+
and self.env.ref(step_data.get("server_action_id")).id,
|
|
590
|
+
"server_context": step_data.get("server_context", "{}"),
|
|
591
|
+
"activity_type_id": step_data.get("activity_type_id")
|
|
592
|
+
and self.env.ref(step_data.get("activity_type_id")).id,
|
|
593
|
+
"activity_summary": step_data.get("activity_summary", ""),
|
|
594
|
+
"activity_note": step_data.get("activity_note", ""),
|
|
595
|
+
"activity_date_deadline_range": step_data.get(
|
|
596
|
+
"activity_date_deadline_range"
|
|
597
|
+
),
|
|
598
|
+
"activity_date_deadline_range_type": step_data.get(
|
|
599
|
+
"activity_date_deadline_range_type"
|
|
600
|
+
),
|
|
601
|
+
"activity_user_type": step_data.get("activity_user_type"),
|
|
602
|
+
"activity_user_id": step_data.get("activity_user_id")
|
|
603
|
+
and (
|
|
604
|
+
self.env.ref(
|
|
605
|
+
step_data.get("activity_user_id"), raise_if_not_found=False
|
|
606
|
+
)
|
|
607
|
+
or self.env.user
|
|
608
|
+
).id,
|
|
609
|
+
"activity_user_field_id": step_data.get("activity_user_field_id")
|
|
610
|
+
and self.env.ref(step_data.get("activity_user_field_id")).id,
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
def _create_document_from_data_vals(self, data):
|
|
614
|
+
return {
|
|
615
|
+
"name": data.get("name", ""),
|
|
616
|
+
"model_id": self.env.ref(data.get("model_id")).id,
|
|
617
|
+
"field_id": data.get("field_id") and self.env.ref(data.get("field_id")).id,
|
|
618
|
+
"is_periodic": data.get("is_periodic"),
|
|
619
|
+
"editable_domain": data.get("domain", "[]"),
|
|
620
|
+
}
|
|
@@ -571,3 +571,131 @@ class AutomationConfigurationStep(models.Model):
|
|
|
571
571
|
"scheduled_date": scheduled_date,
|
|
572
572
|
**kwargs,
|
|
573
573
|
}
|
|
574
|
+
|
|
575
|
+
def _export_step(self, extra_data):
|
|
576
|
+
activity_type_id = self.configuration_id._get_external_xmlid(
|
|
577
|
+
self.activity_type_id
|
|
578
|
+
)
|
|
579
|
+
server_action_id = self.configuration_id._get_external_xmlid(
|
|
580
|
+
self.server_action_id
|
|
581
|
+
)
|
|
582
|
+
mail_template_id = self.configuration_id._get_external_xmlid(
|
|
583
|
+
self.mail_template_id
|
|
584
|
+
)
|
|
585
|
+
data = {
|
|
586
|
+
"name": self.name,
|
|
587
|
+
"domain": self.domain,
|
|
588
|
+
"apply_parent_domain": self.apply_parent_domain,
|
|
589
|
+
"step_type": self.step_type,
|
|
590
|
+
"trigger_interval": self.trigger_interval,
|
|
591
|
+
"trigger_interval_type": self.trigger_interval_type,
|
|
592
|
+
"expiry": self.expiry,
|
|
593
|
+
"expiry_interval": self.expiry_interval,
|
|
594
|
+
"trigger_type": self.trigger_type,
|
|
595
|
+
"mail_author_id": self.configuration_id._get_external_xmlid(
|
|
596
|
+
self.mail_author_id
|
|
597
|
+
),
|
|
598
|
+
"mail_template_id": mail_template_id,
|
|
599
|
+
"server_action_id": server_action_id,
|
|
600
|
+
"server_context": self.server_context,
|
|
601
|
+
"activity_type_id": activity_type_id,
|
|
602
|
+
"activity_summary": self.activity_summary,
|
|
603
|
+
"activity_note": self.activity_note,
|
|
604
|
+
"activity_date_deadline_range": self.activity_date_deadline_range,
|
|
605
|
+
"activity_date_deadline_range_type": self.activity_date_deadline_range_type,
|
|
606
|
+
"activity_user_type": self.activity_user_type,
|
|
607
|
+
"activity_user_id": self.configuration_id._get_external_xmlid(
|
|
608
|
+
self.activity_user_id
|
|
609
|
+
),
|
|
610
|
+
"activity_user_field_id": self.configuration_id._get_external_xmlid(
|
|
611
|
+
self.activity_user_field_id
|
|
612
|
+
),
|
|
613
|
+
"steps": [],
|
|
614
|
+
}
|
|
615
|
+
if (
|
|
616
|
+
self.activity_type_id
|
|
617
|
+
and activity_type_id not in extra_data["activity_types"]
|
|
618
|
+
):
|
|
619
|
+
extra_data["activity_types"][
|
|
620
|
+
activity_type_id
|
|
621
|
+
] = self._export_activity_values(self.activity_type_id)
|
|
622
|
+
if (
|
|
623
|
+
self.mail_template_id
|
|
624
|
+
and mail_template_id not in extra_data["mail_templates"]
|
|
625
|
+
):
|
|
626
|
+
extra_data["mail_templates"][
|
|
627
|
+
mail_template_id
|
|
628
|
+
] = self._export_mail_template_values(self.mail_template_id)
|
|
629
|
+
if (
|
|
630
|
+
self.server_action_id
|
|
631
|
+
and server_action_id not in extra_data["server_actions"]
|
|
632
|
+
):
|
|
633
|
+
extra_data["server_actions"][
|
|
634
|
+
server_action_id
|
|
635
|
+
] = self._export_server_action_values(self.server_action_id)
|
|
636
|
+
for step in self.child_ids:
|
|
637
|
+
step_data = step._export_step(extra_data)
|
|
638
|
+
if step_data:
|
|
639
|
+
data["steps"].append(step_data)
|
|
640
|
+
return data
|
|
641
|
+
|
|
642
|
+
def _export_activity_values(self, activity_type):
|
|
643
|
+
return {
|
|
644
|
+
"name": activity_type._fields["name"]._get_stored_translations(
|
|
645
|
+
activity_type
|
|
646
|
+
),
|
|
647
|
+
"summary": activity_type._fields["summary"]._get_stored_translations(
|
|
648
|
+
activity_type
|
|
649
|
+
),
|
|
650
|
+
"sequence": activity_type.sequence,
|
|
651
|
+
"delay_count": activity_type.delay_count,
|
|
652
|
+
"delay_unit": activity_type.delay_unit,
|
|
653
|
+
"delay_from": activity_type.delay_from,
|
|
654
|
+
"icon": activity_type.icon,
|
|
655
|
+
"decoration_type": activity_type.decoration_type,
|
|
656
|
+
"res_model": activity_type.res_model,
|
|
657
|
+
"triggered_next_type_id": self.configuration_id._get_external_xmlid(
|
|
658
|
+
activity_type.triggered_next_type_id
|
|
659
|
+
),
|
|
660
|
+
"chaining_type": activity_type.chaining_type,
|
|
661
|
+
"category": activity_type.category,
|
|
662
|
+
"default_note": activity_type.default_note,
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
def _export_mail_template_values(self, mail_template):
|
|
666
|
+
return {
|
|
667
|
+
"name": mail_template._fields["name"]._get_stored_translations(
|
|
668
|
+
mail_template
|
|
669
|
+
),
|
|
670
|
+
"subject": mail_template._fields["subject"]._get_stored_translations(
|
|
671
|
+
mail_template
|
|
672
|
+
),
|
|
673
|
+
"body_html": mail_template._fields["body_html"]._get_stored_translations(
|
|
674
|
+
mail_template
|
|
675
|
+
),
|
|
676
|
+
"model_id": self.configuration_id._get_external_xmlid(
|
|
677
|
+
mail_template.model_id
|
|
678
|
+
),
|
|
679
|
+
"auto_delete": mail_template.auto_delete,
|
|
680
|
+
"lang": mail_template.lang,
|
|
681
|
+
"email_from": mail_template.email_from,
|
|
682
|
+
"email_to": mail_template.email_to,
|
|
683
|
+
"partner_to": mail_template.partner_to,
|
|
684
|
+
"reply_to": mail_template.reply_to,
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
def _export_server_action_values(self, server_action):
|
|
688
|
+
return {
|
|
689
|
+
"name": server_action._fields["name"]._get_stored_translations(
|
|
690
|
+
server_action
|
|
691
|
+
),
|
|
692
|
+
"state": server_action.state,
|
|
693
|
+
"model_id": self.configuration_id._get_external_xmlid(
|
|
694
|
+
server_action.model_id
|
|
695
|
+
),
|
|
696
|
+
"binding_model_id": self.configuration_id._get_external_xmlid(
|
|
697
|
+
server_action.binding_model_id
|
|
698
|
+
),
|
|
699
|
+
"binding_type": server_action.binding_type,
|
|
700
|
+
"code": server_action.code,
|
|
701
|
+
}
|
|
@@ -12,3 +12,4 @@ manage_automation_tag,Access Automation tag,model_automation_tag,group_automatio
|
|
|
12
12
|
access_automation_record_step,Access Automation Record Activity,model_automation_record_step,group_automation_user,1,0,0,0
|
|
13
13
|
manage_automation_record_step,Access Automation Record Activity,model_automation_record_step,group_automation_manager,1,1,1,1
|
|
14
14
|
manage_automation_configuration_test,Access Automation Configuration Test,model_automation_configuration_test,group_automation_manager,1,1,1,1
|
|
15
|
+
manage_automation_configuration_export,Access Automation Configuration Test,model_automation_configuration_export,group_automation_manager,1,1,1,1
|
|
@@ -372,7 +372,7 @@ ul.auto-toc {
|
|
|
372
372
|
!! This file is generated by oca-gen-addon-readme !!
|
|
373
373
|
!! changes will be overwritten. !!
|
|
374
374
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
375
|
-
!! source digest: sha256:
|
|
375
|
+
!! source digest: sha256:69fb14c7a439c6751286889ba6e2066f2c21764271364f9acfecf97673196f7f
|
|
376
376
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
|
377
377
|
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/automation/tree/16.0/automation_oca"><img alt="OCA/automation" src="https://img.shields.io/badge/github-OCA%2Fautomation-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/automation-16-0/automation-16-0-automation_oca"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/automation&target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
|
|
378
378
|
<p>This module allows to automate several process according to some rules.</p>
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/** @odoo-module **/
|
|
2
|
+
|
|
3
|
+
import {Component} from "@odoo/owl";
|
|
4
|
+
import {FileUploader} from "@web/views/fields/file_handler";
|
|
5
|
+
import {KanbanController} from "@web/views/kanban/kanban_controller";
|
|
6
|
+
import {kanbanView} from "@web/views/kanban/kanban_view";
|
|
7
|
+
import {registry} from "@web/core/registry";
|
|
8
|
+
import {standardWidgetProps} from "@web/views/widgets/standard_widget_props";
|
|
9
|
+
import {useService} from "@web/core/utils/hooks";
|
|
10
|
+
|
|
11
|
+
export class AutomationFileUploader extends Component {
|
|
12
|
+
setup() {
|
|
13
|
+
this.orm = useService("orm");
|
|
14
|
+
this.action = useService("action");
|
|
15
|
+
this.notification = useService("notification");
|
|
16
|
+
}
|
|
17
|
+
async onFileUploaded(file) {
|
|
18
|
+
const action = await this.orm.call(
|
|
19
|
+
"automation.configuration",
|
|
20
|
+
"create_document_from_attachment",
|
|
21
|
+
["", file.data],
|
|
22
|
+
{context: {...this.extraContext, ...this.env.searchModel.context}}
|
|
23
|
+
);
|
|
24
|
+
if (action.context && action.context.notifications) {
|
|
25
|
+
for (const [title, msg] of Object.entries(action.context.notifications)) {
|
|
26
|
+
this.notification.add(msg, {
|
|
27
|
+
title: title,
|
|
28
|
+
type: "info",
|
|
29
|
+
sticky: true,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
delete action.context.notifications;
|
|
33
|
+
}
|
|
34
|
+
this.action.doAction(action);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
AutomationFileUploader.components = {
|
|
38
|
+
FileUploader,
|
|
39
|
+
};
|
|
40
|
+
AutomationFileUploader.template = "automation_oca.AutomationFileUploader";
|
|
41
|
+
AutomationFileUploader.props = {
|
|
42
|
+
...standardWidgetProps,
|
|
43
|
+
record: {type: Object, optional: true},
|
|
44
|
+
slots: {type: Object, optional: true},
|
|
45
|
+
acceptedFileExtensions: {type: String, optional: true},
|
|
46
|
+
};
|
|
47
|
+
AutomationFileUploader.defaultProps = {
|
|
48
|
+
acceptedFileExtensions: ".json",
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
registry
|
|
52
|
+
.category("view_widgets")
|
|
53
|
+
.add("automation_oca_file_uploader", AutomationFileUploader);
|
|
54
|
+
|
|
55
|
+
export class AutomationKanbanController extends KanbanController {}
|
|
56
|
+
AutomationKanbanController.components = {
|
|
57
|
+
...KanbanController.components,
|
|
58
|
+
AutomationFileUploader,
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export const AutomationKanbanView = {
|
|
62
|
+
...kanbanView,
|
|
63
|
+
Controller: AutomationKanbanController,
|
|
64
|
+
buttonTemplate: "automation_oca.KanbanView.Buttons",
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
registry.category("views").add("automation_upload_kanban", AutomationKanbanView);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
.o_drop_area {
|
|
2
|
+
width: 100%;
|
|
3
|
+
height: 100%;
|
|
4
|
+
position: absolute;
|
|
5
|
+
background-color: #aaaa;
|
|
6
|
+
z-index: 2;
|
|
7
|
+
left: 0;
|
|
8
|
+
top: 0;
|
|
9
|
+
i {
|
|
10
|
+
justify-content: center;
|
|
11
|
+
display: flex;
|
|
12
|
+
align-items: center;
|
|
13
|
+
height: 100%;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.file_upload_kanban_action_a {
|
|
18
|
+
@include o-kanban-dashboard-dropdown-link(
|
|
19
|
+
$link-padding-gap: $o-kanban-dashboard-dropdown-complex-gap
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.o_widget_account_file_uploader {
|
|
24
|
+
.btn-primary.oe_kanban_action_button {
|
|
25
|
+
a {
|
|
26
|
+
color: $white;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" ?>
|
|
2
|
+
<templates>
|
|
3
|
+
|
|
4
|
+
<t t-name="automation_oca.AutomationFileUploader" owl="1">
|
|
5
|
+
<div
|
|
6
|
+
t-att-class="props.record and props.record.data ? 'oe_kanban_color_' + props.record.data.color : ''"
|
|
7
|
+
>
|
|
8
|
+
<FileUploader
|
|
9
|
+
acceptedFileExtensions="props.acceptedFileExtensions"
|
|
10
|
+
fileUploadClass="'account_file_uploader'"
|
|
11
|
+
multiUpload="false"
|
|
12
|
+
onUploaded.bind="onFileUploaded"
|
|
13
|
+
>
|
|
14
|
+
<t t-set-slot="toggler">
|
|
15
|
+
<t
|
|
16
|
+
t-if="props.togglerTemplate"
|
|
17
|
+
t-call="{{ props.togglerTemplate }}"
|
|
18
|
+
/>
|
|
19
|
+
<t t-else="" t-slot="default" />
|
|
20
|
+
</t>
|
|
21
|
+
<t t-slot="extra" />
|
|
22
|
+
</FileUploader>
|
|
23
|
+
</div>
|
|
24
|
+
</t>
|
|
25
|
+
|
|
26
|
+
<t
|
|
27
|
+
t-name="automation_oca.KanbanView.Buttons"
|
|
28
|
+
t-inherit="web.KanbanView.Buttons"
|
|
29
|
+
t-inherit-mode="primary"
|
|
30
|
+
owl="1"
|
|
31
|
+
>
|
|
32
|
+
<xpath
|
|
33
|
+
expr="//*[@class='btn btn-primary o-kanban-button-new']"
|
|
34
|
+
position="after"
|
|
35
|
+
>
|
|
36
|
+
|
|
37
|
+
<AutomationFileUploader>
|
|
38
|
+
<t t-set-slot="default">
|
|
39
|
+
<button
|
|
40
|
+
type="button"
|
|
41
|
+
class="btn btn-secondary o_button_upload_bill"
|
|
42
|
+
>
|
|
43
|
+
Upload
|
|
44
|
+
</button>
|
|
45
|
+
</t>
|
|
46
|
+
</AutomationFileUploader>
|
|
47
|
+
</xpath>
|
|
48
|
+
</t>
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
</templates>
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Copyright 2025 Dixmit
|
|
2
|
+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
|
3
|
+
import base64
|
|
4
|
+
import json
|
|
5
|
+
|
|
6
|
+
from .common import AutomationTestCase
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TestAutomationBase(AutomationTestCase):
|
|
10
|
+
@classmethod
|
|
11
|
+
def setUpClass(cls):
|
|
12
|
+
super().setUpClass()
|
|
13
|
+
# Adding two languages to test the import and export of automations
|
|
14
|
+
cls.env["base.language.install"].create(
|
|
15
|
+
{
|
|
16
|
+
"overwrite": True,
|
|
17
|
+
"lang_ids": [
|
|
18
|
+
(
|
|
19
|
+
6,
|
|
20
|
+
0,
|
|
21
|
+
[
|
|
22
|
+
cls.env.ref("base.lang_es").id,
|
|
23
|
+
cls.env.ref("base.lang_fr").id,
|
|
24
|
+
],
|
|
25
|
+
)
|
|
26
|
+
],
|
|
27
|
+
}
|
|
28
|
+
).lang_install()
|
|
29
|
+
cls.create_server_action()
|
|
30
|
+
cls.create_activity_action()
|
|
31
|
+
cls.create_mail_activity()
|
|
32
|
+
cls.action.with_context(lang="en_US").name = "Test Automation Configuration"
|
|
33
|
+
cls.action.with_context(
|
|
34
|
+
lang="es_ES"
|
|
35
|
+
).name = "Configuración de Automatización de Prueba"
|
|
36
|
+
cls.action.with_context(
|
|
37
|
+
lang="fr_FR"
|
|
38
|
+
).name = "Configuration d'Automatisation de Test"
|
|
39
|
+
|
|
40
|
+
def test_export_automation(self):
|
|
41
|
+
action = self.configuration.export_configuration()
|
|
42
|
+
wizard = self.env[action["res_model"]].browse(action["res_id"])
|
|
43
|
+
file = wizard.file_content
|
|
44
|
+
data = json.loads(base64.b64decode(file))
|
|
45
|
+
action_id = self.action.get_external_id()[self.action.id]
|
|
46
|
+
self.assertEqual(
|
|
47
|
+
data["server_actions"][action_id]["name"]["en_US"],
|
|
48
|
+
"Test Automation Configuration",
|
|
49
|
+
)
|
|
50
|
+
self.assertEqual(
|
|
51
|
+
data["server_actions"][action_id]["name"]["es_ES"],
|
|
52
|
+
"Configuración de Automatización de Prueba",
|
|
53
|
+
)
|
|
54
|
+
self.assertEqual(
|
|
55
|
+
data["server_actions"][action_id]["name"]["fr_FR"],
|
|
56
|
+
"Configuration d'Automatisation de Test",
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
def test_import_automation_creation_copy(self):
|
|
60
|
+
action = self.configuration.export_configuration()
|
|
61
|
+
wizard = self.env[action["res_model"]].browse(action["res_id"])
|
|
62
|
+
file = wizard.file_content
|
|
63
|
+
self.action.name = "Test Automation Configuration changed"
|
|
64
|
+
record_action = self.env[
|
|
65
|
+
"automation.configuration"
|
|
66
|
+
].create_document_from_attachment(file)
|
|
67
|
+
configuration = self.env[record_action["res_model"]].browse(
|
|
68
|
+
record_action["res_id"]
|
|
69
|
+
)
|
|
70
|
+
self.assertEqual(configuration.name, self.configuration.name)
|
|
71
|
+
self.assertEqual(3, len(configuration.automation_step_ids))
|
|
72
|
+
self.assertEqual(
|
|
73
|
+
self.action,
|
|
74
|
+
configuration.automation_step_ids.filtered(
|
|
75
|
+
lambda r: r.server_action_id
|
|
76
|
+
).server_action_id,
|
|
77
|
+
)
|
|
78
|
+
self.assertEqual(
|
|
79
|
+
self.template,
|
|
80
|
+
configuration.automation_step_ids.filtered(
|
|
81
|
+
lambda r: r.mail_template_id
|
|
82
|
+
).mail_template_id,
|
|
83
|
+
)
|
|
84
|
+
self.assertEqual(
|
|
85
|
+
self.activity_type,
|
|
86
|
+
configuration.automation_step_ids.filtered(
|
|
87
|
+
lambda r: r.activity_type_id
|
|
88
|
+
).activity_type_id,
|
|
89
|
+
)
|
|
90
|
+
self.assertEqual(self.action.name, "Test Automation Configuration changed")
|
|
91
|
+
|
|
92
|
+
def test_import_automation_creation_creation(self):
|
|
93
|
+
action = self.configuration.export_configuration()
|
|
94
|
+
wizard = self.env[action["res_model"]].browse(action["res_id"])
|
|
95
|
+
file = wizard.file_content
|
|
96
|
+
self.configuration.automation_step_ids.unlink()
|
|
97
|
+
original_action_id = self.action.id
|
|
98
|
+
self.action.unlink()
|
|
99
|
+
self.template.unlink()
|
|
100
|
+
self.activity_type.unlink()
|
|
101
|
+
record_action = self.env[
|
|
102
|
+
"automation.configuration"
|
|
103
|
+
].create_document_from_attachment(file)
|
|
104
|
+
configuration = self.env[record_action["res_model"]].browse(
|
|
105
|
+
record_action["res_id"]
|
|
106
|
+
)
|
|
107
|
+
self.assertEqual(configuration.name, self.configuration.name)
|
|
108
|
+
self.assertEqual(3, len(configuration.automation_step_ids))
|
|
109
|
+
action = configuration.automation_step_ids.filtered(
|
|
110
|
+
lambda r: r.server_action_id
|
|
111
|
+
).server_action_id
|
|
112
|
+
self.assertNotEqual(original_action_id, action.id)
|
|
113
|
+
self.assertEqual(
|
|
114
|
+
action.with_context(lang="en_US").name, "Test Automation Configuration"
|
|
115
|
+
)
|
|
116
|
+
self.assertEqual(
|
|
117
|
+
action.with_context(lang="es_ES").name,
|
|
118
|
+
"Configuración de Automatización de Prueba",
|
|
119
|
+
)
|
|
120
|
+
self.assertEqual(
|
|
121
|
+
action.with_context(lang="fr_FR").name,
|
|
122
|
+
"Configuration d'Automatisation de Test",
|
|
123
|
+
)
|
|
@@ -98,6 +98,13 @@
|
|
|
98
98
|
</div>
|
|
99
99
|
<sheet>
|
|
100
100
|
<div name="button_box">
|
|
101
|
+
<button
|
|
102
|
+
name="export_configuration"
|
|
103
|
+
type="object"
|
|
104
|
+
class="oe_stat_button"
|
|
105
|
+
icon="fa-download"
|
|
106
|
+
string="Export"
|
|
107
|
+
/>
|
|
101
108
|
<button
|
|
102
109
|
name="%(automation_record_configuration_act_window)s"
|
|
103
110
|
type="action"
|
|
@@ -426,7 +433,11 @@
|
|
|
426
433
|
<record model="ir.ui.view" id="automation_configuration_kanban_view">
|
|
427
434
|
<field name="model">automation.configuration</field>
|
|
428
435
|
<field name="arch" type="xml">
|
|
429
|
-
<kanban
|
|
436
|
+
<kanban
|
|
437
|
+
js_class="automation_upload_kanban"
|
|
438
|
+
default_group_by="state"
|
|
439
|
+
quick_create="false"
|
|
440
|
+
>
|
|
430
441
|
<field name="state" readonly="1" />
|
|
431
442
|
<templates>
|
|
432
443
|
<t t-name="kanban-box">
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Copyright 2025 Dixmit
|
|
2
|
+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
|
3
|
+
|
|
4
|
+
from odoo import fields, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class AutomationConfigurationExport(models.TransientModel):
|
|
8
|
+
|
|
9
|
+
_name = "automation.configuration.export"
|
|
10
|
+
|
|
11
|
+
configuration_id = fields.Many2one(
|
|
12
|
+
comodel_name="automation.configuration",
|
|
13
|
+
required=True,
|
|
14
|
+
)
|
|
15
|
+
file_name = fields.Char()
|
|
16
|
+
file_content = fields.Binary(readonly=True)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8" ?>
|
|
2
|
+
<!-- Copyright 2025 Dixmit
|
|
3
|
+
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
|
|
4
|
+
<odoo>
|
|
5
|
+
|
|
6
|
+
<record model="ir.ui.view" id="automation_configuration_export_form_view">
|
|
7
|
+
<field name="model">automation.configuration.export</field>
|
|
8
|
+
<field name="arch" type="xml">
|
|
9
|
+
<form string="Automation Configuration Export">
|
|
10
|
+
<!-- TODO -->
|
|
11
|
+
<group>
|
|
12
|
+
<field name="configuration_id" invisible="1" />
|
|
13
|
+
<field name="file_name" invisible="1" />
|
|
14
|
+
<field name="file_content" filename="file_name" />
|
|
15
|
+
</group>
|
|
16
|
+
<footer>
|
|
17
|
+
<button string="Cancel" class="btn-default" special="cancel" />
|
|
18
|
+
</footer>
|
|
19
|
+
</form>
|
|
20
|
+
</field>
|
|
21
|
+
</record>
|
|
22
|
+
|
|
23
|
+
<record
|
|
24
|
+
model="ir.actions.act_window"
|
|
25
|
+
id="automation_configuration_export_act_window"
|
|
26
|
+
>
|
|
27
|
+
<field name="name">Automation Configuration Export</field> <!-- TODO -->
|
|
28
|
+
<field name="res_model">automation.configuration.export</field>
|
|
29
|
+
<field name="view_mode">form</field>
|
|
30
|
+
<field name="context">{'default_configuration_id': active_id}</field>
|
|
31
|
+
<field name="target">new</field>
|
|
32
|
+
</record>
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
</odoo>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: odoo-addon-automation_oca
|
|
3
|
-
Version: 16.0.1.6.
|
|
3
|
+
Version: 16.0.1.6.1
|
|
4
4
|
Summary: Automate actions in threaded models
|
|
5
5
|
Home-page: https://github.com/OCA/automation
|
|
6
6
|
Author: Dixmit,Odoo Community Association (OCA)
|
|
@@ -26,7 +26,7 @@ Automation Oca
|
|
|
26
26
|
!! This file is generated by oca-gen-addon-readme !!
|
|
27
27
|
!! changes will be overwritten. !!
|
|
28
28
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
29
|
-
!! source digest: sha256:
|
|
29
|
+
!! source digest: sha256:69fb14c7a439c6751286889ba6e2066f2c21764271364f9acfecf97673196f7f
|
|
30
30
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
31
31
|
|
|
32
32
|
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
odoo/addons/automation_oca/README.rst,sha256=
|
|
1
|
+
odoo/addons/automation_oca/README.rst,sha256=aCKaIl6kWojRjt2fcMVM86l8w7xPbLBsxuGoKgxWVlo,7127
|
|
2
2
|
odoo/addons/automation_oca/__init__.py,sha256=dnUeA_K1torbiMNF3tt2dtECdk-FkWm01DByr9MBMIA,69
|
|
3
|
-
odoo/addons/automation_oca/__manifest__.py,sha256=
|
|
3
|
+
odoo/addons/automation_oca/__manifest__.py,sha256=4gpDuSCvSkF3qRqJIGr5aTQB_lzrh8gjeOHYsXqF8d8,1236
|
|
4
4
|
odoo/addons/automation_oca/controllers/__init__.py,sha256=4KFqEP2QHFbPN66eQJMdGsmNz2v7ywWv_FR1pW_kkLk,19
|
|
5
5
|
odoo/addons/automation_oca/controllers/main.py,sha256=DRL6AJKy18ekRPaKtmRoEh5i6fNQDWpoq2GTHztKOKI,2355
|
|
6
6
|
odoo/addons/automation_oca/data/cron.xml,sha256=viAGNb5X619yXQyfpO_HcJOAiQGzEE-m6Sp4y6F4gDs,1297
|
|
7
7
|
odoo/addons/automation_oca/demo/demo.xml,sha256=beyrfyRzVTDZ1Mm2sL5Y57W4GDsUvj9gOMUlrEMM1M8,2838
|
|
8
|
-
odoo/addons/automation_oca/i18n/automation_oca.pot,sha256=
|
|
8
|
+
odoo/addons/automation_oca/i18n/automation_oca.pot,sha256=FvAXMZTnBHqErIoIIDTSgdThCESTQOsoxraQvZqy_Xk,57414
|
|
9
9
|
odoo/addons/automation_oca/i18n/es.po,sha256=otocdP9DSYFZS0MwmNnwl_aFBu_C5StqtmpxnkW95u0,62363
|
|
10
10
|
odoo/addons/automation_oca/i18n/fr.po,sha256=YcPXsub2L0BRH0a5Wbk7jDkut3Z594mQ-wzN8krSFNQ,58989
|
|
11
11
|
odoo/addons/automation_oca/i18n/it.po,sha256=SYuAxtNuK0Vh2aAtAsjwDkXGuu53Jb2szRNXOVc6MYQ,62865
|
|
12
12
|
odoo/addons/automation_oca/models/__init__.py,sha256=gRWvgicyFDELSeVnpRow1mGuWjfm3ima2Lo-NqlymKg,318
|
|
13
|
-
odoo/addons/automation_oca/models/automation_configuration.py,sha256=
|
|
14
|
-
odoo/addons/automation_oca/models/automation_configuration_step.py,sha256=
|
|
13
|
+
odoo/addons/automation_oca/models/automation_configuration.py,sha256=QzJUurcZapvDs1y5_gZOkqtVOKFg8lv3YYKQirtwZtc,24753
|
|
14
|
+
odoo/addons/automation_oca/models/automation_configuration_step.py,sha256=71PuB9UKaIhW0MAolXCsxJeDu57Q26IXccUKjws2j_k,27109
|
|
15
15
|
odoo/addons/automation_oca/models/automation_filter.py,sha256=W8VM977yXH_hZUKCO8ZDKsvzIjYegoIGMN1QLEvikOY,706
|
|
16
16
|
odoo/addons/automation_oca/models/automation_record.py,sha256=LYZ1fkijB2R3QjBoJN_gnsPzqjkp-Gk_6LyPywMQAQA,7172
|
|
17
17
|
odoo/addons/automation_oca/models/automation_record_step.py,sha256=nJjuwO1QcsbZ12z8RvKxB92qRip2OUp8exNdXb-X24c,18202
|
|
@@ -24,12 +24,12 @@ odoo/addons/automation_oca/readme/CONTRIBUTORS.md,sha256=p8_-Mu8Mj7YOCCgizqC5Y02
|
|
|
24
24
|
odoo/addons/automation_oca/readme/CREDITS.md,sha256=bvu5tCnp4li7NCDhDhQuoWX_1DFfX7RIWUSsiwo7e0w,135
|
|
25
25
|
odoo/addons/automation_oca/readme/DESCRIPTION.md,sha256=tcf06j1PNB7EKdYZeATHF4zHYShcEQ3p9qlvu3iPPgk,347
|
|
26
26
|
odoo/addons/automation_oca/readme/USAGE.md,sha256=4orDugmPwZ35m1QqqOjIrVOeXoCzBX5JdgL0WF9rXCk,3498
|
|
27
|
-
odoo/addons/automation_oca/security/ir.model.access.csv,sha256=
|
|
27
|
+
odoo/addons/automation_oca/security/ir.model.access.csv,sha256=H4zWtq6YnmjF1XOo3w-Jyg2zUYLQvWS4S0KH2wmU_ro,1775
|
|
28
28
|
odoo/addons/automation_oca/security/security.xml,sha256=pT37-cLbQIP--Tzp0fljiyvNBPvakzyBgyf47KEC1xo,1627
|
|
29
29
|
odoo/addons/automation_oca/static/description/configuration.png,sha256=W8cAn7-cQEVhf7Zy979xMDHi1cKWbDH7uyWkjvGi9gc,55863
|
|
30
30
|
odoo/addons/automation_oca/static/description/icon.png,sha256=abhQ1HbvsatZ_WVS_G6qroJgWNa1Hppd961RD7vrAug,37729
|
|
31
31
|
odoo/addons/automation_oca/static/description/icon.svg,sha256=NkJAwQ9YAXML6VIKe90VZzKUZb58-zGNL029-GC8Pm4,4641
|
|
32
|
-
odoo/addons/automation_oca/static/description/index.html,sha256=
|
|
32
|
+
odoo/addons/automation_oca/static/description/index.html,sha256=itvIT6s2HKAtfKe0DPGpQAH27iXn7ybVo8kURWiKseE,18438
|
|
33
33
|
odoo/addons/automation_oca/static/src/fields/automation_activity/automation_activity.esm.js,sha256=pbzjSHVYdYcMOXzXtC-lyVYrydk_1YRtMVh88XpTo-E,1779
|
|
34
34
|
odoo/addons/automation_oca/static/src/fields/automation_graph/automation_graph.esm.js,sha256=vbPRaNzH1_wbB0gEBhZvm0gT0VXdgtElQIYeAOJZuNM,3214
|
|
35
35
|
odoo/addons/automation_oca/static/src/fields/automation_graph/automation_graph.xml,sha256=86VqoFswW3ZppaR0KFG4_giKPeT8vgdC1A1vpBtPjFk,297
|
|
@@ -37,14 +37,18 @@ odoo/addons/automation_oca/static/src/views/automation_kanban/automation_kanban.
|
|
|
37
37
|
odoo/addons/automation_oca/static/src/views/automation_kanban/automation_kanban_compiler.esm.js,sha256=60ABZgtcT7cguu21RuWSh3HEGEG6x8wFmrMhrBiTUS0,624
|
|
38
38
|
odoo/addons/automation_oca/static/src/views/automation_kanban/automation_kanban_record.esm.js,sha256=04sSiVoWE8RJtM5zpqcSdSl7aJWew4Iqc5jawvqO4jA,517
|
|
39
39
|
odoo/addons/automation_oca/static/src/views/automation_kanban/automation_kanban_renderer.esm.js,sha256=GjwEFRuQeP6FKie_ODYaqxvv_pYDsj8STWkFtlR3Ki8,1197
|
|
40
|
-
odoo/addons/automation_oca/
|
|
40
|
+
odoo/addons/automation_oca/static/src/views/automation_upload/automation_upload.esm.js,sha256=2mZDG8HtWTNeKu_FheN-HqxIadzMw7zXx2aLnAEvh14,2308
|
|
41
|
+
odoo/addons/automation_oca/static/src/views/automation_upload/automation_upload.scss,sha256=peysUiOjYxnG1RV-vaXikwphziRio1mmjflJxPXHyVQ,558
|
|
42
|
+
odoo/addons/automation_oca/static/src/views/automation_upload/automation_upload.xml,sha256=hoXn8pmxxdXoO4LfDlzoVtummJs1h7qsv-QscP4bdL8,1548
|
|
43
|
+
odoo/addons/automation_oca/tests/__init__.py,sha256=oE9pIZZoR1gK1wqlhTipczhOYzqmqTpgbKoIvo3jx-M,222
|
|
41
44
|
odoo/addons/automation_oca/tests/common.py,sha256=Zu5AcWGMgoDKdsQ4VMyhHTnot1f7Hunh4tDH9CSHbXw,3558
|
|
42
45
|
odoo/addons/automation_oca/tests/test_automation_action.py,sha256=GT7Kja9l1Z-9MzWhKPuDc1a5-IkdHNgABtNVX50Sr24,8994
|
|
43
46
|
odoo/addons/automation_oca/tests/test_automation_activity.py,sha256=K3wMhr-Mb0FvNu0HfNdAZT4Z1m3J4EdQGbyxPEc-7Xw,16938
|
|
44
47
|
odoo/addons/automation_oca/tests/test_automation_base.py,sha256=xb1qTY_iN0JbC7Revn-thamJn8cjXxDrSHOxpZl9VGE,29752
|
|
48
|
+
odoo/addons/automation_oca/tests/test_automation_import.py,sha256=4TBu3AJBLEScq2Kw8M2ZDfEv4ODCUmlnzZmbjc4BL2w,4740
|
|
45
49
|
odoo/addons/automation_oca/tests/test_automation_mail.py,sha256=zOzRfhH0-Zz0Jm1TX15efgXibjj7Au19597DZWvAQGc,24704
|
|
46
50
|
odoo/addons/automation_oca/tests/test_automation_security.py,sha256=iazrh9TJDCLaK1vXKXMNqBf0bizedBd3QxUwCodjesY,3883
|
|
47
|
-
odoo/addons/automation_oca/views/automation_configuration.xml,sha256=
|
|
51
|
+
odoo/addons/automation_oca/views/automation_configuration.xml,sha256=tGzQ3Z3iqMU3yegw8R7kgGDVIafYFYjKhLRUrn_qmhU,27164
|
|
48
52
|
odoo/addons/automation_oca/views/automation_configuration_step.xml,sha256=QMGqUKULEINQjLCHc7-DT1OXau0HqHy0Q8ESCasdeII,11988
|
|
49
53
|
odoo/addons/automation_oca/views/automation_filter.xml,sha256=Mx0SBoVk2U3QY-hseKymbOphlK-hOjHdFzLtPgU2jok,2271
|
|
50
54
|
odoo/addons/automation_oca/views/automation_record.xml,sha256=ebHj_9Ioks9xWykw8QtPVZ8jgfDMQXVntQoKhhtoibk,16047
|
|
@@ -52,11 +56,13 @@ odoo/addons/automation_oca/views/automation_record_step.xml,sha256=cBao3BLIo9Db_
|
|
|
52
56
|
odoo/addons/automation_oca/views/automation_tag.xml,sha256=Cm-L0rtrgxxtDt5_MRRFLgz3QQzaOjoxFq4ivLejs6M,1358
|
|
53
57
|
odoo/addons/automation_oca/views/link_tracker_clicks.xml,sha256=uSYTtxlNBBHvFEi2XAA3JW4x7fPSqoxdgPeRkkEIO1s,1668
|
|
54
58
|
odoo/addons/automation_oca/views/menu.xml,sha256=xWsODLtJ_vti86ApATNyxG8aFoiA7mhWEjGRPvn9JzI,1006
|
|
55
|
-
odoo/addons/automation_oca/wizards/__init__.py,sha256=
|
|
59
|
+
odoo/addons/automation_oca/wizards/__init__.py,sha256=GWkLxfmYslodA2MagX9xUmCOZw8OMTxanRst1Baw_ds,125
|
|
60
|
+
odoo/addons/automation_oca/wizards/automation_configuration_export.py,sha256=BMT3U9l_mhwwtUdG7rYJAZdL2AtIJTjmu2biav1yhy4,428
|
|
61
|
+
odoo/addons/automation_oca/wizards/automation_configuration_export.xml,sha256=FuzCygj4NzODv3yWHD5Y7hgy7YoPzp0L2v4S4QPVl4k,1312
|
|
56
62
|
odoo/addons/automation_oca/wizards/automation_configuration_test.py,sha256=YK0HD6Ds6B4PMaI97MUpVQaB-wsVTmw6Hpbh532tU-g,1363
|
|
57
63
|
odoo/addons/automation_oca/wizards/automation_configuration_test.xml,sha256=r9lUzD3SeFSLStlc07iXxO1b9e9RbZdUCrvMA46zfm8,1916
|
|
58
64
|
odoo/addons/automation_oca/wizards/mail_compose_message.py,sha256=XL6UGz8_fEwniXM80DhQXink4SMnWg7HHR0kHLekMyc,612
|
|
59
|
-
odoo_addon_automation_oca-16.0.1.6.
|
|
60
|
-
odoo_addon_automation_oca-16.0.1.6.
|
|
61
|
-
odoo_addon_automation_oca-16.0.1.6.
|
|
62
|
-
odoo_addon_automation_oca-16.0.1.6.
|
|
65
|
+
odoo_addon_automation_oca-16.0.1.6.1.dist-info/METADATA,sha256=31f3eNpH7LrKn-JHyyQea08kYGN_thR5CniM1xddEGQ,7644
|
|
66
|
+
odoo_addon_automation_oca-16.0.1.6.1.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
|
67
|
+
odoo_addon_automation_oca-16.0.1.6.1.dist-info/top_level.txt,sha256=qBj40grFkGOfDZ2WDSw3y1RnDlgG0u8rP8pvGNdbz4w,5
|
|
68
|
+
odoo_addon_automation_oca-16.0.1.6.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|