odoo-addon-automation-oca 17.0.1.0.0.9__py3-none-any.whl → 18.0.1.0.0.2__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 (42) hide show
  1. odoo/addons/automation_oca/README.rst +12 -8
  2. odoo/addons/automation_oca/__manifest__.py +5 -1
  3. odoo/addons/automation_oca/i18n/automation_oca.pot +42 -45
  4. odoo/addons/automation_oca/i18n/es.po +14 -1
  5. odoo/addons/automation_oca/i18n/fr.po +13 -0
  6. odoo/addons/automation_oca/i18n/it.po +16 -3
  7. odoo/addons/automation_oca/models/automation_configuration.py +294 -2
  8. odoo/addons/automation_oca/models/automation_configuration_step.py +128 -0
  9. odoo/addons/automation_oca/models/automation_record.py +6 -7
  10. odoo/addons/automation_oca/models/automation_record_step.py +11 -5
  11. odoo/addons/automation_oca/security/ir.model.access.csv +1 -0
  12. odoo/addons/automation_oca/static/description/index.html +25 -19
  13. odoo/addons/automation_oca/static/src/fields/automation_activity/automation_activity.esm.js +1 -1
  14. odoo/addons/automation_oca/static/src/fields/automation_graph/automation_graph.esm.js +0 -1
  15. odoo/addons/automation_oca/static/src/views/automation_kanban/automation_kanban_compiler.esm.js +0 -1
  16. odoo/addons/automation_oca/static/src/views/automation_kanban/automation_kanban_record.esm.js +0 -1
  17. odoo/addons/automation_oca/static/src/views/automation_kanban/automation_kanban_renderer.esm.js +0 -1
  18. odoo/addons/automation_oca/static/src/views/automation_upload/automation_upload.esm.js +69 -0
  19. odoo/addons/automation_oca/static/src/views/automation_upload/automation_upload.scss +29 -0
  20. odoo/addons/automation_oca/static/src/views/automation_upload/automation_upload.xml +44 -0
  21. odoo/addons/automation_oca/static/tests/components/graph.esm.test.js +47 -0
  22. odoo/addons/automation_oca/static/tests/components/step.esm.test.js +156 -0
  23. odoo/addons/automation_oca/tests/__init__.py +2 -0
  24. odoo/addons/automation_oca/tests/test_automation_activity.py +32 -2
  25. odoo/addons/automation_oca/tests/test_automation_base.py +2 -2
  26. odoo/addons/automation_oca/tests/test_automation_import.py +123 -0
  27. odoo/addons/automation_oca/tests/test_js.py +17 -0
  28. odoo/addons/automation_oca/views/automation_configuration.xml +22 -14
  29. odoo/addons/automation_oca/views/automation_configuration_step.xml +7 -3
  30. odoo/addons/automation_oca/views/automation_filter.xml +2 -2
  31. odoo/addons/automation_oca/views/automation_record.xml +12 -15
  32. odoo/addons/automation_oca/views/automation_record_step.xml +2 -2
  33. odoo/addons/automation_oca/views/automation_tag.xml +2 -2
  34. odoo/addons/automation_oca/wizards/__init__.py +1 -0
  35. odoo/addons/automation_oca/wizards/automation_configuration_export.py +16 -0
  36. odoo/addons/automation_oca/wizards/automation_configuration_export.xml +33 -0
  37. odoo/addons/automation_oca/wizards/mail_compose_message.py +3 -3
  38. {odoo_addon_automation_oca-17.0.1.0.0.9.dist-info → odoo_addon_automation_oca-18.0.1.0.0.2.dist-info}/METADATA +16 -11
  39. {odoo_addon_automation_oca-17.0.1.0.0.9.dist-info → odoo_addon_automation_oca-18.0.1.0.0.2.dist-info}/RECORD +41 -33
  40. odoo/addons/automation_oca/i18n/es_VE.po +0 -1591
  41. {odoo_addon_automation_oca-17.0.1.0.0.9.dist-info → odoo_addon_automation_oca-18.0.1.0.0.2.dist-info}/WHEEL +0 -0
  42. {odoo_addon_automation_oca-17.0.1.0.0.9.dist-info → odoo_addon_automation_oca-18.0.1.0.0.2.dist-info}/top_level.txt +0 -0
@@ -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
@@ -280,8 +283,8 @@ class AutomationConfiguration(models.Model):
280
283
  [Record._name, self.id],
281
284
  )
282
285
  query.add_where(f"{alias2}.id is NULL")
286
+ query.group_by = f'"{Record._table}".{self.field_id.name}'
283
287
  query_str, params = query.select(f'MIN("{Record._table}".id)')
284
- query_str += f' GROUP BY "{Record._table}".{self.field_id.name}'
285
288
  else:
286
289
  query_str, params = query.select()
287
290
  self.env.cr.execute(query_str, params)
@@ -313,7 +316,7 @@ class AutomationConfiguration(models.Model):
313
316
  ],
314
317
  }
315
318
 
316
- def _group_expand_states(self, states, domain, order):
319
+ def _group_expand_states(self, states, domain):
317
320
  """
318
321
  This is used to show all the states on the kanban view
319
322
  """
@@ -328,3 +331,292 @@ class AutomationConfiguration(models.Model):
328
331
  "model_id": self.model_id.id,
329
332
  }
330
333
  )
334
+
335
+ def export_configuration(self):
336
+ """
337
+ Export the configuration to a JSON format.
338
+ This method is used to export the configuration for external use.
339
+ """
340
+ self.ensure_one()
341
+ data = self._export_configuration()
342
+ action = self.env["ir.actions.act_window"]._for_xml_id(
343
+ "automation_oca.automation_configuration_export_act_window"
344
+ )
345
+ file_name = f"automation_configuration_{self.name or 'export'}.json"
346
+ action["res_id"] = (
347
+ self.env["automation.configuration.export"]
348
+ .create(
349
+ {
350
+ "configuration_id": self.id,
351
+ "file_name": file_name,
352
+ "file_content": base64.b64encode(
353
+ json.dumps(data).encode()
354
+ ).decode(),
355
+ }
356
+ )
357
+ .id
358
+ )
359
+ return action
360
+
361
+ def _export_configuration(self):
362
+ self.ensure_one()
363
+ data = {
364
+ "id": self._get_external_xmlid(self),
365
+ "name": self.name,
366
+ "domain": self.domain,
367
+ "model_id": self._get_external_xmlid(self.model_id),
368
+ "field_id": self._get_external_xmlid(self.field_id),
369
+ "is_periodic": self.is_periodic,
370
+ "steps": [],
371
+ }
372
+ extra_data = defaultdict(lambda: {})
373
+ for step in self.automation_direct_step_ids:
374
+ step_data = step._export_step(extra_data)
375
+ if step_data:
376
+ data["steps"].append(step_data)
377
+ data["activity_types"] = extra_data["activity_types"]
378
+ data["mail_templates"] = extra_data["mail_templates"]
379
+ data["server_actions"] = extra_data["server_actions"]
380
+ return data
381
+
382
+ def _get_external_xmlid(self, record, module="__export__", name=None):
383
+ if not record:
384
+ return False
385
+ result = record.get_external_id()[record.id]
386
+ if result:
387
+ return result
388
+ if not name:
389
+ name = f"{record._table}_{record.id}_{uuid.uuid4().hex[:8]}"
390
+ self.env["ir.model.data"].create(
391
+ {
392
+ "name": name,
393
+ "model": record._name,
394
+ "res_id": record.id,
395
+ "module": module,
396
+ }
397
+ )
398
+ return f"__export__.{name}"
399
+
400
+ def create_document_from_attachment(self, b64_data):
401
+ data = json.loads(base64.b64decode(b64_data))
402
+ return self._create_document_from_data(data).get_formview_action()
403
+
404
+ def _create_document_from_data(self, data):
405
+ record = self.create(self._create_document_from_data_vals(data))
406
+ langs = [lang[0] for lang in self.env["res.lang"].get_installed()]
407
+ for activity_type_id, activity_type in data.get("activity_types", {}).items():
408
+ if not self.env.ref(activity_type_id, raise_if_not_found=False):
409
+ self._create_document_add_activity_type(
410
+ activity_type_id, activity_type, langs
411
+ )
412
+ for mail_template_id, mail_template in data.get("mail_templates", {}).items():
413
+ if not self.env.ref(mail_template_id, raise_if_not_found=False):
414
+ self._create_document_add_mail_template(
415
+ mail_template_id, mail_template, langs
416
+ )
417
+ for server_action_id, server_action in data.get("server_actions", {}).items():
418
+ if not self.env.ref(server_action_id, raise_if_not_found=False):
419
+ self._create_document_add_server_action(
420
+ server_action_id, server_action, langs
421
+ )
422
+ for step_data in data.get("steps", []):
423
+ record._create_document_step_from_data(step_data)
424
+ return record
425
+
426
+ def _create_document_step_from_data(self, step_data, parent=False):
427
+ step = self.env["automation.configuration.step"].create(
428
+ self._create_step_vals(step_data, parent=parent)
429
+ )
430
+ for child_step in step_data.get("steps", []):
431
+ self._create_document_step_from_data(child_step, parent=step)
432
+ return step
433
+
434
+ def _create_document_add_activity_type(
435
+ self, activity_type_id, activity_data, langs
436
+ ):
437
+ activity_type = self.env["mail.activity.type"].create(
438
+ self._create_activity_vals(activity_data)
439
+ )
440
+ activity_fields = self._get_activity_type_translatable_fields()
441
+ for lang in langs:
442
+ vals = {}
443
+ for field in activity_fields:
444
+ if activity_data.get(field) and lang in activity_data[field]:
445
+ vals[field] = activity_data[field][lang]
446
+ if vals:
447
+ activity_type.with_context(lang=lang).write(vals)
448
+ self._get_external_xmlid(
449
+ activity_type,
450
+ module=activity_type_id.split(".")[0],
451
+ name=activity_type_id.split(".")[1],
452
+ )
453
+
454
+ def _get_activity_type_translatable_fields(self):
455
+ """Return the fields that are translatable for activity types."""
456
+ return ["name", "summary"]
457
+
458
+ def _create_activity_vals(self, activity_data):
459
+ return {
460
+ "name": (activity_data.get("name") or {}).get(
461
+ "en_US", "Imported activity type"
462
+ ),
463
+ "summary": (activity_data.get("summary") or {}).get(
464
+ "en_US", "Imported activity summary"
465
+ ),
466
+ "sequence": activity_data.get("sequence", 10),
467
+ "delay_count": activity_data.get("delay_count", 0),
468
+ "delay_unit": activity_data.get("delay_unit", "minutes"),
469
+ "delay_from": activity_data.get("delay_from", "now"),
470
+ "icon": activity_data.get("icon", "fa-clock"),
471
+ "decoration_type": activity_data.get("decoration_type"),
472
+ "res_model": activity_data.get("res_model"),
473
+ "triggered_next_type_id": activity_data.get("triggered_next_type_id")
474
+ and (
475
+ self.env.ref(
476
+ activity_data["triggered_next_type_id"], raise_if_not_found=False
477
+ )
478
+ or self.env["mail.activity.type"]
479
+ ).id
480
+ or False,
481
+ "chaining_type": activity_data.get("chaining_type"),
482
+ "category": activity_data.get("category"),
483
+ "default_note": activity_data.get("default_note"),
484
+ }
485
+
486
+ def _create_document_add_mail_template(
487
+ self, mail_template_id, mail_template_data, langs
488
+ ):
489
+ mail_template = self.env["mail.template"].create(
490
+ self._create_mail_template_vals(mail_template_data)
491
+ )
492
+ mail_template_fields = self._get_mail_template_translatable_fields()
493
+ for lang in langs:
494
+ vals = {}
495
+ for field in mail_template_fields:
496
+ if mail_template_data.get(field) and lang in mail_template_data[field]:
497
+ vals[field] = mail_template_data[field][lang]
498
+ if vals:
499
+ mail_template.with_context(lang=lang).write(vals)
500
+ self._get_external_xmlid(
501
+ mail_template,
502
+ module=mail_template_id.split(".")[0],
503
+ name=mail_template_id.split(".")[1],
504
+ )
505
+
506
+ def _get_mail_template_translatable_fields(self):
507
+ """Return the fields that are translatable for mail templates."""
508
+ return [
509
+ "name",
510
+ "subject",
511
+ "body_html",
512
+ ]
513
+
514
+ def _create_mail_template_vals(self, mail_template_data):
515
+ return {
516
+ "name": (mail_template_data.get("name") or {}).get(
517
+ "en_US", "Imported mail template"
518
+ ),
519
+ "subject": (mail_template_data.get("subject") or {}).get("en_US", ""),
520
+ "body_html": (mail_template_data.get("body_html") or {}).get("en_US", ""),
521
+ "model_id": self.env.ref(mail_template_data["model_id"]).id
522
+ if mail_template_data.get("model_id")
523
+ else False,
524
+ "auto_delete": mail_template_data.get("auto_delete", False),
525
+ "lang": mail_template_data.get("lang", False),
526
+ "email_from": mail_template_data.get("email_from", False),
527
+ "email_to": mail_template_data.get("email_to", False),
528
+ "partner_to": mail_template_data.get("partner_to", False),
529
+ "reply_to": mail_template_data.get("reply_to", False),
530
+ }
531
+
532
+ def _create_document_add_server_action(
533
+ self, server_action_id, server_action_data, langs
534
+ ):
535
+ server_action = self.env["ir.actions.server"].create(
536
+ self._create_server_action_vals(server_action_data)
537
+ )
538
+ server_action_fields = self._get_server_action_translatable_fields()
539
+ for lang in langs:
540
+ vals = {}
541
+ for field in server_action_fields:
542
+ if server_action_data.get(field) and lang in server_action_data[field]:
543
+ vals[field] = server_action_data[field][lang]
544
+ if vals:
545
+ server_action.with_context(lang=lang).write(vals)
546
+ self._get_external_xmlid(
547
+ server_action,
548
+ module=server_action_id.split(".")[0],
549
+ name=server_action_id.split(".")[1],
550
+ )
551
+
552
+ def _get_server_action_translatable_fields(self):
553
+ """Return the fields that are translatable for server actions."""
554
+ return [
555
+ "name",
556
+ ]
557
+
558
+ def _create_server_action_vals(self, server_action_data):
559
+ return {
560
+ "name": server_action_data.get("name", {}).get(
561
+ "en_US", "Imported server action"
562
+ ),
563
+ "state": server_action_data.get("state"),
564
+ "model_id": self.env.ref(server_action_data.get("model_id")).id,
565
+ "binding_model_id": server_action_data.get("binding_model_id")
566
+ and self.env.ref(server_action_data.get("binding_model_id")),
567
+ "binding_type": server_action_data.get("binding_type"),
568
+ "code": server_action_data.get("code"),
569
+ }
570
+
571
+ def _create_step_vals(self, step_data, parent=False):
572
+ return {
573
+ "name": step_data.get("name", ""),
574
+ "step_type": step_data.get("step_type", "mail"),
575
+ "configuration_id": self.id,
576
+ "parent_id": parent.id if parent else False,
577
+ "domain": step_data.get("domain", "[]"),
578
+ "apply_parent_domain": step_data.get("apply_parent_domain", True),
579
+ "trigger_interval": step_data.get("trigger_interval", 0),
580
+ "trigger_interval_type": step_data.get("trigger_interval_type", "seconds"),
581
+ "expiry": step_data.get("expiry", False),
582
+ "expiry_interval": step_data.get("expiry_interval", 0),
583
+ "trigger_type": step_data.get("trigger_type"),
584
+ "mail_author_id": step_data.get("mail_author_id")
585
+ and (
586
+ self.env.ref(step_data.get("mail_author_id"), raise_if_not_found=False)
587
+ or self.env.user
588
+ ).id,
589
+ "mail_template_id": step_data.get("mail_template_id")
590
+ and self.env.ref(step_data.get("mail_template_id")).id,
591
+ "server_action_id": step_data.get("server_action_id")
592
+ and self.env.ref(step_data.get("server_action_id")).id,
593
+ "server_context": step_data.get("server_context", "{}"),
594
+ "activity_type_id": step_data.get("activity_type_id")
595
+ and self.env.ref(step_data.get("activity_type_id")).id,
596
+ "activity_summary": step_data.get("activity_summary", ""),
597
+ "activity_note": step_data.get("activity_note", ""),
598
+ "activity_date_deadline_range": step_data.get(
599
+ "activity_date_deadline_range"
600
+ ),
601
+ "activity_date_deadline_range_type": step_data.get(
602
+ "activity_date_deadline_range_type"
603
+ ),
604
+ "activity_user_type": step_data.get("activity_user_type"),
605
+ "activity_user_id": step_data.get("activity_user_id")
606
+ and (
607
+ self.env.ref(
608
+ step_data.get("activity_user_id"), raise_if_not_found=False
609
+ )
610
+ or self.env.user
611
+ ).id,
612
+ "activity_user_field_id": step_data.get("activity_user_field_id")
613
+ and self.env.ref(step_data.get("activity_user_field_id")).id,
614
+ }
615
+
616
+ def _create_document_from_data_vals(self, data):
617
+ return {
618
+ "name": data.get("name", ""),
619
+ "model_id": self.env.ref(data.get("model_id")).id,
620
+ "field_id": data.get("field_id") and self.env.ref(data.get("field_id")).id,
621
+ "is_periodic": data.get("is_periodic"),
622
+ }
@@ -570,3 +570,131 @@ class AutomationConfigurationStep(models.Model):
570
570
  "scheduled_date": scheduled_date,
571
571
  **kwargs,
572
572
  }
573
+
574
+ def _export_step(self, extra_data):
575
+ activity_type_id = self.configuration_id._get_external_xmlid(
576
+ self.activity_type_id
577
+ )
578
+ server_action_id = self.configuration_id._get_external_xmlid(
579
+ self.server_action_id
580
+ )
581
+ mail_template_id = self.configuration_id._get_external_xmlid(
582
+ self.mail_template_id
583
+ )
584
+ data = {
585
+ "name": self.name,
586
+ "domain": self.domain,
587
+ "apply_parent_domain": self.apply_parent_domain,
588
+ "step_type": self.step_type,
589
+ "trigger_interval": self.trigger_interval,
590
+ "trigger_interval_type": self.trigger_interval_type,
591
+ "expiry": self.expiry,
592
+ "expiry_interval": self.expiry_interval,
593
+ "trigger_type": self.trigger_type,
594
+ "mail_author_id": self.configuration_id._get_external_xmlid(
595
+ self.mail_author_id
596
+ ),
597
+ "mail_template_id": mail_template_id,
598
+ "server_action_id": server_action_id,
599
+ "server_context": self.server_context,
600
+ "activity_type_id": activity_type_id,
601
+ "activity_summary": self.activity_summary,
602
+ "activity_note": self.activity_note,
603
+ "activity_date_deadline_range": self.activity_date_deadline_range,
604
+ "activity_date_deadline_range_type": self.activity_date_deadline_range_type,
605
+ "activity_user_type": self.activity_user_type,
606
+ "activity_user_id": self.configuration_id._get_external_xmlid(
607
+ self.activity_user_id
608
+ ),
609
+ "activity_user_field_id": self.configuration_id._get_external_xmlid(
610
+ self.activity_user_field_id
611
+ ),
612
+ "steps": [],
613
+ }
614
+ if (
615
+ self.activity_type_id
616
+ and activity_type_id not in extra_data["activity_types"]
617
+ ):
618
+ extra_data["activity_types"][activity_type_id] = (
619
+ self._export_activity_values(self.activity_type_id)
620
+ )
621
+ if (
622
+ self.mail_template_id
623
+ and mail_template_id not in extra_data["mail_templates"]
624
+ ):
625
+ extra_data["mail_templates"][mail_template_id] = (
626
+ self._export_mail_template_values(self.mail_template_id)
627
+ )
628
+ if (
629
+ self.server_action_id
630
+ and server_action_id not in extra_data["server_actions"]
631
+ ):
632
+ extra_data["server_actions"][server_action_id] = (
633
+ self._export_server_action_values(self.server_action_id)
634
+ )
635
+ for step in self.child_ids:
636
+ step_data = step._export_step(extra_data)
637
+ if step_data:
638
+ data["steps"].append(step_data)
639
+ return data
640
+
641
+ def _export_activity_values(self, activity_type):
642
+ return {
643
+ "name": activity_type._fields["name"]._get_stored_translations(
644
+ activity_type
645
+ ),
646
+ "summary": activity_type._fields["summary"]._get_stored_translations(
647
+ activity_type
648
+ ),
649
+ "sequence": activity_type.sequence,
650
+ "delay_count": activity_type.delay_count,
651
+ "delay_unit": activity_type.delay_unit,
652
+ "delay_from": activity_type.delay_from,
653
+ "icon": activity_type.icon,
654
+ "decoration_type": activity_type.decoration_type,
655
+ "res_model": activity_type.res_model,
656
+ "triggered_next_type_id": self.configuration_id._get_external_xmlid(
657
+ activity_type.triggered_next_type_id
658
+ ),
659
+ "chaining_type": activity_type.chaining_type,
660
+ "category": activity_type.category,
661
+ "default_note": activity_type.default_note,
662
+ }
663
+
664
+ def _export_mail_template_values(self, mail_template):
665
+ return {
666
+ "name": mail_template._fields["name"]._get_stored_translations(
667
+ mail_template
668
+ ),
669
+ "subject": mail_template._fields["subject"]._get_stored_translations(
670
+ mail_template
671
+ ),
672
+ "body_html": mail_template._fields["body_html"]._get_stored_translations(
673
+ mail_template
674
+ ),
675
+ "model_id": self.configuration_id._get_external_xmlid(
676
+ mail_template.model_id
677
+ ),
678
+ "auto_delete": mail_template.auto_delete,
679
+ "lang": mail_template.lang,
680
+ "email_from": mail_template.email_from,
681
+ "email_to": mail_template.email_to,
682
+ "partner_to": mail_template.partner_to,
683
+ "reply_to": mail_template.reply_to,
684
+ }
685
+
686
+ def _export_server_action_values(self, server_action):
687
+ return {
688
+ "name": server_action._fields["name"]._get_stored_translations(
689
+ server_action
690
+ ),
691
+ "state": server_action.state,
692
+ "model_id": self.configuration_id._get_external_xmlid(
693
+ server_action.model_id
694
+ ),
695
+ "binding_model_id": self.configuration_id._get_external_xmlid(
696
+ server_action.binding_model_id
697
+ ),
698
+ "binding_type": server_action.binding_type,
699
+ "code": server_action.code,
700
+ }
@@ -127,7 +127,7 @@ class AutomationRecord(models.Model):
127
127
 
128
128
  for model, targets in model_data.items():
129
129
  try:
130
- self.env[model].check_access_rights("read")
130
+ self.env[model].check_access("read")
131
131
  except AccessError: # no read access rights
132
132
  continue
133
133
  recs = self.env[model].browse(list(targets))
@@ -179,13 +179,13 @@ class AutomationRecord(models.Model):
179
179
  def read(self, fields=None, load="_classic_read"):
180
180
  """Override to explicitely call check_access_rule, that is not called
181
181
  by the ORM. It instead directly fetches ir.rules and apply them."""
182
- self.check_access_rule("read")
182
+ self.check_access("read")
183
183
  return super().read(fields=fields, load=load)
184
184
 
185
- def check_access_rule(self, operation):
185
+ def check_access(self, operation):
186
186
  """In order to check if we can access a record, we are checking if we can access
187
187
  the related document"""
188
- super().check_access_rule(operation)
188
+ super().check_access(operation)
189
189
  if self.env.is_superuser():
190
190
  return
191
191
  default_checker = self.env["mail.thread"].get_automation_access
@@ -205,9 +205,8 @@ class AutomationRecord(models.Model):
205
205
  check_operation = checker(
206
206
  [record.id], operation, model_name=record._name
207
207
  )
208
- record.check_access_rights(check_operation)
209
- record.check_access_rule(check_operation)
208
+ record.check_access(check_operation)
210
209
 
211
210
  def write(self, vals):
212
- self.check_access_rule("write")
211
+ self.check_access("write")
213
212
  return super().write(vals)
@@ -227,16 +227,15 @@ class AutomationRecordStep(models.Model):
227
227
  }
228
228
  if self.configuration_step_id.mail_author_id:
229
229
  composer_values["author_id"] = self.configuration_step_id.mail_author_id.id
230
- composer_values[
231
- "email_from"
232
- ] = self.configuration_step_id.mail_author_id.email_formatted
230
+ composer_values["email_from"] = (
231
+ self.configuration_step_id.mail_author_id.email_formatted
232
+ )
233
233
  res_ids = [self.record_id.res_id]
234
234
  composer = (
235
235
  self.env["mail.compose.message"]
236
236
  .with_context(active_ids=res_ids)
237
237
  .create(composer_values)
238
238
  )
239
- # composer.body =
240
239
  extra_context = self._run_mail_context()
241
240
  composer = composer.with_context(active_ids=res_ids, **extra_context)
242
241
  # auto-commit except in testing mode
@@ -315,11 +314,18 @@ class AutomationRecordStep(models.Model):
315
314
 
316
315
  def _activate(self):
317
316
  todo = self.filtered(lambda r: not r.scheduled_date)
317
+ current_date = fields.Datetime.now()
318
318
  for record in todo:
319
319
  config = record.configuration_step_id
320
- record.scheduled_date = config._get_record_activity_scheduled_date(
320
+ scheduled_date = config._get_record_activity_scheduled_date(
321
321
  record.record_id.resource_ref, force=True
322
322
  )
323
+ record.write(
324
+ {
325
+ "scheduled_date": scheduled_date,
326
+ "do_not_wait": scheduled_date < current_date,
327
+ }
328
+ )
323
329
  todo._trigger_activities()
324
330
 
325
331
  def _set_activity_done(self):
@@ -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