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.
Files changed (20) hide show
  1. odoo/addons/automation_oca/README.rst +1 -1
  2. odoo/addons/automation_oca/__manifest__.py +2 -1
  3. odoo/addons/automation_oca/i18n/automation_oca.pot +42 -0
  4. odoo/addons/automation_oca/models/automation_configuration.py +292 -0
  5. odoo/addons/automation_oca/models/automation_configuration_step.py +128 -0
  6. odoo/addons/automation_oca/security/ir.model.access.csv +1 -0
  7. odoo/addons/automation_oca/static/description/index.html +1 -1
  8. odoo/addons/automation_oca/static/src/views/automation_upload/automation_upload.esm.js +67 -0
  9. odoo/addons/automation_oca/static/src/views/automation_upload/automation_upload.scss +29 -0
  10. odoo/addons/automation_oca/static/src/views/automation_upload/automation_upload.xml +51 -0
  11. odoo/addons/automation_oca/tests/__init__.py +1 -0
  12. odoo/addons/automation_oca/tests/test_automation_import.py +123 -0
  13. odoo/addons/automation_oca/views/automation_configuration.xml +12 -1
  14. odoo/addons/automation_oca/wizards/__init__.py +1 -0
  15. odoo/addons/automation_oca/wizards/automation_configuration_export.py +16 -0
  16. odoo/addons/automation_oca/wizards/automation_configuration_export.xml +35 -0
  17. {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
  18. {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
  19. {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
  20. {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:9c31f66d5f65928b8de9a05fcc341d7ab3363aef2735d3e3d5f327ea73e1c8c7
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.0",
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:9c31f66d5f65928b8de9a05fcc341d7ab3363aef2735d3e3d5f327ea73e1c8c7
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&amp;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>
@@ -3,3 +3,4 @@ from . import test_automation_activity
3
3
  from . import test_automation_base
4
4
  from . import test_automation_mail
5
5
  from . import test_automation_security
6
+ from . import test_automation_import
@@ -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 default_group_by="state" quick_create="false">
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">
@@ -1,2 +1,3 @@
1
1
  from . import mail_compose_message
2
2
  from . import automation_configuration_test
3
+ from . import automation_configuration_export
@@ -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.0.2
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:9c31f66d5f65928b8de9a05fcc341d7ab3363aef2735d3e3d5f327ea73e1c8c7
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=1FUWHlgdmEUckjDXeod3LmvQyf522d8AJfKmZjFKOAk,7127
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=rh-p-RSrlgiiXOC25eYsIlvgmyNwGDFlhItdyB_dCXw,1181
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=jNVgPC8AOqF3ZEL9HPIMMF3geVTYDBG_5YeJ9lXT_Ls,55398
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=VaWXg_6EnUnTdLDV_eZnWKXXVU27nGmZR_lnGIeKstA,12086
14
- odoo/addons/automation_oca/models/automation_configuration_step.py,sha256=fdK2ngsokOk0xT7atWRcyLdIRUU0rWazIcLwM2J8Lb0,21839
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=bqg_yjGA2q_wpEVIyYIltmPV8Am3S43bASDcCR6lRz4,1628
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=k8PKmoqtU7cddqxhLxcD4hDKQwrYMh_6EgjznqDWe6o,18438
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/tests/__init__.py,sha256=5VS2h2Hl3gUzMQqKgPUYnq-_Wkk7SfD_k0YgTsfXj3g,185
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=F6nYKsI9Un0mfzObfxfEUbZ_j2jXengWFYNLXHzxRzA,26768
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=1yOQpQirzOswywec7gg_gshvEPNJtjdExb_78V7DexI,79
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.0.2.dist-info/METADATA,sha256=Pz0YXPvpKfRFtijhHx1L0EAL5HmP9ghgkGJR-EDvy0Q,7646
60
- odoo_addon_automation_oca-16.0.1.6.0.2.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
61
- odoo_addon_automation_oca-16.0.1.6.0.2.dist-info/top_level.txt,sha256=qBj40grFkGOfDZ2WDSw3y1RnDlgG0u8rP8pvGNdbz4w,5
62
- odoo_addon_automation_oca-16.0.1.6.0.2.dist-info/RECORD,,
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,,