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.
Files changed (23) 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/i18n/es.po +42 -0
  5. odoo/addons/automation_oca/i18n/fr.po +42 -0
  6. odoo/addons/automation_oca/i18n/it.po +42 -0
  7. odoo/addons/automation_oca/models/automation_configuration.py +292 -0
  8. odoo/addons/automation_oca/models/automation_configuration_step.py +128 -0
  9. odoo/addons/automation_oca/security/ir.model.access.csv +1 -0
  10. odoo/addons/automation_oca/static/description/index.html +1 -1
  11. odoo/addons/automation_oca/static/src/views/automation_upload/automation_upload.esm.js +67 -0
  12. odoo/addons/automation_oca/static/src/views/automation_upload/automation_upload.scss +29 -0
  13. odoo/addons/automation_oca/static/src/views/automation_upload/automation_upload.xml +51 -0
  14. odoo/addons/automation_oca/tests/__init__.py +1 -0
  15. odoo/addons/automation_oca/tests/test_automation_import.py +123 -0
  16. odoo/addons/automation_oca/views/automation_configuration.xml +12 -1
  17. odoo/addons/automation_oca/wizards/__init__.py +1 -0
  18. odoo/addons/automation_oca/wizards/automation_configuration_export.py +16 -0
  19. odoo/addons/automation_oca/wizards/automation_configuration_export.xml +35 -0
  20. {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
  21. {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
  22. {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
  23. {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: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