1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320
|
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Automation Form View -->
<record id="view_base_automation_form" model="ir.ui.view">
<field name="name">Automations</field>
<field name="model">base.automation</field>
<field name="arch" type="xml">
<form string="Automation Rule">
<sheet>
<div class="oe_button_box" name="button_box">
<button name="action_view_webhook_logs" type="object" string="Logs" class="oe_stat_button" icon="fa-list" invisible="trigger != 'on_webhook'">
</button>
</div>
<field name="active" invisible="1" />
<field name="model_name" invisible="1" force_save="True" />
<widget name="web_ribbon" title="Archived" bg_color="bg-danger" invisible="active"/>
<div class="oe_title">
<h1><field name="name" placeholder="e.g. Support flow"/></h1>
</div>
<group groups="!base.group_no_one" invisible="context.get('default_model_id')">
<group>
<field name="model_id" options="{'no_create': True}" />
</group>
</group>
<group groups="base.group_no_one">
<group>
<field name="model_id" options="{'no_create': True}" />
</group>
</group>
<group invisible="not model_id">
<group>
<label for="trigger"/>
<div>
<div class="d-flex flex-row">
<field name="trigger" widget="base_automation_trigger_selection" class="oe_inline me-3"/>
<field name="trg_selection_field_id" placeholder="Select a value..." class="oe_inline"
options="{'no_open': True, 'no_create': True}"
invisible="trigger not in ['on_state_set', 'on_priority_set']"
required="trigger in ['on_state_set', 'on_priority_set']"
/>
<field name="trg_field_ref" placeholder="Select a value..." class="oe_inline"
options="{'no_open': True, 'no_create': True}"
invisible="trigger not in ['on_stage_set', 'on_tag_set']"
required="trigger in ['on_stage_set', 'on_tag_set']"
/>
<field name="trg_field_ref_model_name" invisible="1" />
<field name="trg_date_id" class="oe_inline" string="Date Field"
options="{'no_open': True, 'no_create': True}"
invisible="trigger != 'on_time'"
required="trigger in ['on_time', 'on_time_created', 'on_time_updated']"
/>
</div>
<div class="text-muted" invisible="trigger != 'on_change'"><i class="fa fa-warning"/> Automation rules triggered by UI changes will be executed <em>every time</em> the watched fields change, <em>whether you save or not</em>.</div>
</div>
<label for="url" string="URL" invisible="trigger != 'on_webhook'"/>
<div invisible="trigger != 'on_webhook'">
<field name="url" widget="CopyClipboardURL" placeholder="URL will be created once the rule is saved."/>
<div class="alert alert-warning" role="status">
<strong><i class="fa fa-lock"/> Keep it secret, keep it safe.</strong>
<p>Your webhook URL contains a secret. Don't share it online or carelessly.</p>
<button class="btn btn-seconadry" type="object" name="action_rotate_webhook_uuid" string="Rotate Secret" icon="fa-refresh" help="Change the URL's secret if you think the URL is no longer secure. You will have to update any automated system that calls this webhook to the new URL."/>
</div>
</div>
<label for="trg_date_range" string="Delay" invisible="trigger not in ['on_time', 'on_time_created', 'on_time_updated']"/>
<div class="d-flex flex-row gap-2" invisible="trigger not in ['on_time', 'on_time_created', 'on_time_updated']">
<field name="trg_date_range" class="oe_inline" required="trigger in ['on_time', 'on_time_created', 'on_time_updated']" />
<field name="trg_date_range_type" class="oe_inline" required="trigger in ['on_time', 'on_time_created', 'on_time_updated']" />
<span invisible="trigger != 'on_time_created'">after creation</span>
<span invisible="trigger != 'on_time_updated'">after last update</span>
<span invisible="trigger != 'on_time'">after</span>
<field name="trg_date_id" class="oe_inline" string="Date Field" placeholder="Select a date field..."
options="{'no_open': True, 'no_create': True}"
context="{'hide_model': 1}"
invisible="trigger != 'on_time'"
required="trigger in ['on_time', 'on_time_created', 'on_time_updated']"/>
</div>
<field name="log_webhook_calls" widget="boolean_toggle" invisible="trigger != 'on_webhook'"/>
<field name="trg_date_calendar_id" class="oe_inline"
options="{'no_open': True, 'no_create': True}"
invisible="not trg_date_id or trg_date_range_type != 'day'"/>
<label for="least_delay_msg" invisible="trigger not in ['on_time', 'on_time_created', 'on_time_updated'] or not least_delay_msg" string="" />
<div class="alert alert-info" role="alert" invisible="trigger not in ['on_time', 'on_time_created', 'on_time_updated'] or not least_delay_msg">
<field name="least_delay_msg"/>
</div>
<field name="filter_pre_domain" widget="domain" groups="base.group_no_one"
options="{'model': 'model_name', 'in_dialog': True}"
invisible="trigger in ['on_webhook', 'on_time', 'on_time_created', 'on_time_updated']"
/>
<field name="filter_domain" widget="domain" groups="base.group_no_one"
options="{'model': 'model_name', 'in_dialog': True}"
invisible="trigger == 'on_webhook'"
/>
<label for="filter_domain" groups="!base.group_no_one"
invisible="trigger not in ['on_create_or_write', 'on_change', 'on_unlink']"
/>
<label for="filter_domain" groups="!base.group_no_one"
string="Extra Conditions"
invisible="trigger not in ['on_time', 'on_time_created', 'on_time_updated']"
/>
<field name="filter_domain" nolabel="1" widget="domain"
groups="!base.group_no_one"
options="{'model': 'model_name', 'in_dialog': False, 'foldable': True}"
invisible="trigger not in ['on_create_or_write', 'on_change', 'on_unlink', 'on_time', 'on_time_created', 'on_time_updated']"
/>
<field name="trigger_field_ids" string="When updating" placeholder="Select fields..."
options="{'no_open': True, 'no_create': True}"
domain="[('model_id', '=', model_id)]"
context="{'hide_model': 1}"
invisible="trigger != 'on_create_or_write'" widget="many2many_tags" />
<field name="on_change_field_ids" string="When updating" placeholder="Select fields..."
options="{'no_open': True, 'no_create': True}"
domain="[('model_id', '=', model_id)]"
context="{'hide_model': 1}"
invisible="trigger != 'on_change'" widget="many2many_tags" />
</group>
<group>
<label for="record_getter" string="Target Record" invisible="trigger != 'on_webhook'" />
<div invisible="trigger != 'on_webhook'">
<field name="record_getter" string="Target Record"/>
<div>
<div class="text-muted"><i class="fa fa-info-circle"/> The default target record getter will work out-of-the-box for any webhook coming from another Odoo instance.</div>
<span class="text-muted"> Available variables: </span>
<ul class="text-muted">
<li><code>env</code>: environment on which the action is triggered</li>
<li><code>model</code>: model of the record on which the action is triggered; is a void recordset</li>
<li><code>time</code>, <code>datetime</code>, <code>dateutil</code>, <code>timezone</code>: useful Python libraries</li>
<li><code>payload</code>: the payload of the call (GET parameters, JSON body), as a dict.</li>
</ul>
</div>
</div>
</group>
</group>
<notebook invisible="not model_id">
<page string="Actions To Do" name="actions">
<field
name="action_server_ids"
widget="one2many"
class="o_base_automation_actions_field"
context="{'default_model_id': model_id, 'form_view_ref': 'base_automation.ir_actions_server_view_form_automation'}"
>
<kanban>
<control>
<create string="Add an action" />
</control>
<field name="state"/>
<field name="evaluation_type"/>
<field name="value"/>
<field name="value_field_to_show"/>
<field name="update_field_type"/>
<field name="update_m2m_operation"/>
<templates>
<t t-name="card" class="flex-row align-items-center gap-1">
<field name="sequence" widget="handle" class="px-1" />
<!-- Icon section -->
<i
data-name="server_action_icon"
t-att-title="record.state.value"
class="fa fa-fw"
t-att-class="{
'code': 'fa-file-code-o',
'object_create': 'fa-edit',
'object_write': 'fa-refresh',
'multi': 'fa-list-ul',
'mail_post': 'fa-envelope',
'followers': 'fa-user-o',
'remove_followers': 'fa-user-times',
'next_activity': 'fa-clock-o',
'sms': 'fa-comments-o',
'webhook': 'fa-paper-plane',
}[record.state.raw_value]"
/>
<field name="name" class="text-truncate" />
<t invisible="state != 'object_write'">
<t invisible="not (update_field_type == 'many2many' and update_m2m_operation == 'clear') or evaluation_type != 'value'">
<span>by clearing it</span>
</t>
<t invisible="not (update_field_type == 'many2many' and update_m2m_operation == 'add') or evaluation_type != 'value'">
<span>by adding</span><field name="resource_ref"/>
</t>
<t invisible="not (update_field_type == 'many2many' and update_m2m_operation == 'remove') or evaluation_type != 'value'">
<span>by removing</span><field name="resource_ref"/>
</t>
<t invisible="not (update_field_type == 'many2many' and update_m2m_operation == 'set') or evaluation_type != 'value'">
<span>by setting it to</span><field name="resource_ref"/>
</t>
<t invisible="update_field_type == 'many2many' and evaluation_type == 'value'">
<span invisible="evaluation_type != 'value'">to</span>
<span invisible="evaluation_type != 'equation'">as</span>
<field name="resource_ref" invisible="not (value_field_to_show == 'resource_ref' and evaluation_type == 'value')" />
<field name="selection_value" invisible="not (value_field_to_show == 'selection_value' and evaluation_type == 'value')" class="d-inline"/>
<field name="update_boolean_value" invisible="not (value_field_to_show == 'update_boolean_value' and evaluation_type == 'value')" class="d-inline"/>
<em invisible="not (value_field_to_show == 'value' and evaluation_type == 'value')" class="d-inline"><field name="value"/></em>
<code invisible="not (evaluation_type == 'equation')"><field name="value" /></code>
</t>
</t>
<button type="delete" name="delete" class="btn fa fa-trash fa-xl px-3 ms-auto" title="Delete Action" />
</t>
</templates>
</kanban>
</field>
</page>
<page string="Notes" name="notes">
<field name="description" placeholder="Keep track of what this automation does and why it exists..."/>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<!-- automation List View -->
<record id="view_base_automation_tree" model="ir.ui.view">
<field name="name">base.automation.list</field>
<field name="model">base.automation</field>
<field name="arch" type="xml">
<list string="Automation Rules">
<field name="name"/>
<field name="trigger"/>
<field name="model_id"/>
</list>
</field>
</record>
<!-- automation Kanban View -->
<record id="view_base_automation_kanban" model="ir.ui.view">
<field name="name">base.automation.kanban</field>
<field name="model">base.automation</field>
<field name="arch" type="xml">
<kanban
string="Automation Rules"
class="o_base_automation_kanban_view"
records_draggable="false"
groups_draggable="false"
quick_create="false"
group_create="false"
group_edit="false"
group_delete="false"
>
<field name="active"/>
<templates>
<t t-name="card" class="flex-md-row">
<widget name="web_ribbon" title="Archived" bg_color="text-bg-danger" invisible="active" />
<div class="d-flex align-items-center w-100 w-md-25 o_automation_base_info">
<div class="d-flex flex-column">
<field name="name" class="fs-2 fw-bold"/>
<field name="model_id" invisible="context.get('default_model_id')"/>
<div class="d-flex align-items-center gap-1" invisible="trigger in ['on_time', 'on_time_created', 'on_time_updated']">
<field name="trigger" />
<field name="on_change_field_ids" invisible="trigger != 'on_change'" class="my-1" />
<field name="trg_selection_field_id" invisible="trigger not in ['on_state_set', 'on_priority_set']" class="o_tag o_tag_color_0 rounded-pill p-1 px-2" />
<field name="trg_field_ref" invisible="trigger not in ['on_stage_set', 'on_tag_set']" class="o_tag o_tag_color_0 rounded-pill p-1 px-2" />
<field name="trigger_field_ids" invisible="trigger not in ['on_create_or_write']" class="my-1" />
</div>
<div class="d-flex align-items-center gap-1" invisible="trigger != 'on_time'">
<field name="trg_date_range"/>
<field name="trg_date_range_type" class="text-lowercase text-nowrap" />
<span class="flex-shrink-0">
based on <field name="trg_date_id" invisible="trigger != 'on_time'" class="o_tag o_tag_color_0 rounded-pill p-1 px-2" />
</span>
</div>
<div class="d-flex align-items-center gap-1" invisible="trigger not in ['on_time_created', 'on_time_updated']">
<field name="trg_date_range"/>
<field name="trg_date_range_type" class="text-lowercase" />
<field name="trigger" class="text-lowercase" />
<field name="trg_date_id" invisible="trigger != 'on_time'" class="o_tag o_tag_color_0 rounded-pill p-1 px-2" />
</div>
<field name="trg_date_calendar_id" invisible="not trg_date_id or trg_date_range_type != 'day'" />
</div>
</div>
<div class="d-none d-md-flex flex-grow-1 align-items-center gap-3 o_automation_actions" data-name="more-info">
<i class="fa fa-2x fa-arrow-right text-primary" title="Actions" />
<field name="action_server_ids" widget="base_automation_actions_one2many" class="align-self-center w-100 me-md-3" />
</div>
</t>
</templates>
</kanban>
</field>
</record>
<record id="view_base_automation_search" model="ir.ui.view">
<field name="name">base.automation.search</field>
<field name="model">base.automation</field>
<field name="arch" type="xml">
<search>
<field name="name"/>
<field name="model_id"/>
<separator/>
<filter string="Archived" name="inactive" domain="[('active', '=', False)]"/>
</search>
</field>
</record>
<!-- automation Action -->
<record id="base_automation_act" model="ir.actions.act_window">
<field name="name">Automation Rules</field>
<field name="res_model">base.automation</field>
<field name="path">automations</field>
<field name="view_mode">kanban,list,form</field>
<field name="view_id" ref="view_base_automation_kanban"/>
<field name="context">{'active_test': False}</field>
<field name="help" type="html">
<img class="w-100 w-md-75"
src="/base_automation/static/img/automation.svg" />
<p>
Automate <em>everything</em> with Automation Rules
</p><p>
Send an email when an object changes state, archive records
after a month of inactivity or remind yourself to follow-up on
tasks when a specific tag is added.
</p><p>With Automation Rules, you can automate
<em>any</em> workflow.
</p>
</field>
</record>
<menuitem id="menu_base_automation_form"
parent="base.menu_automation" action="base_automation_act" sequence="1"/>
</odoo>
|