odoo-addon-automation-oca 16.0.1.6.0.2__py3-none-any.whl → 16.0.1.6.1.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/i18n/es.po +42 -0
- odoo/addons/automation_oca/i18n/fr.po +42 -0
- odoo/addons/automation_oca/i18n/it.po +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.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.1.dist-info}/RECORD +23 -17
- {odoo_addon_automation_oca-16.0.1.6.0.2.dist-info → odoo_addon_automation_oca-16.0.1.6.1.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.1.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
|
|
@@ -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>
|