Initial commit: OCA Technical packages (595 packages)

This commit is contained in:
Ernad Husremovic 2025-08-29 15:43:03 +02:00
commit 2cc02aac6e
24950 changed files with 2318079 additions and 0 deletions

View file

@ -0,0 +1,509 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2024 Dixmit
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record model="ir.ui.view" id="automation_configuration_form_view">
<field name="model">automation.configuration</field>
<field name="arch" type="xml">
<form>
<header>
<button
class="btn btn-primary"
type="object"
name="start_automation"
string="Start"
attrs="{'invisible': [('state', '!=', 'draft')]}"
/>
<button
class="btn btn-primary"
type="object"
name="run_automation"
attrs="{'invisible': [('state', '!=', 'ondemand')]}"
string="Generate new records"
/>
<button
type="object"
name="done_automation"
class="btn-secondary"
string="Mark as done"
attrs="{'invisible': [('state', 'not in', ['periodic','ondemand'])]}"
/>
<button
type="object"
name="back_to_draft"
class="btn-secondary"
string="Back to draft"
attrs="{'invisible': [('state', '!=', 'done')]}"
/>
<button
type="action"
name="%(automation_configuration_test_act_window)s"
string="Test"
class="btn-warning"
groups="automation_oca.group_automation_manager"
/>
<button
type="object"
name="run_automation"
class="btn-info"
string="Enforce generation"
attrs="{'invisible': [('state', '!=', 'periodic')]}"
/>
<field name="state" widget="statusbar" />
</header>
<div
class="alert alert-info"
role="alert"
attrs="{'invisible': [('state', '!=', 'draft')]}"
>
<div
class="px-4"
attrs="{'invisible': [('is_periodic', '=', False)]}"
>
On <b
>periodical configurations</b>, the records are created automatically by a cron job.
It is great for tasks that don't need user validation.
</div>
<div
class="px-4"
attrs="{'invisible': [('is_periodic', '=', True)]}"
>
On <b
>on demand configurations</b>, the records are created only by pressing the run button.
It is useful if you want to control the execution and created records manually.
</div>
</div>
<div
class="alert alert-info"
role="alert"
attrs="{'invisible': [('state', '!=', 'ondemand')]}"
>
<div class="px-4">
This is configuration only generates new records on demand. Press the button in order to execute them manually.
</div>
</div>
<div
class="alert alert-info"
role="alert"
attrs="{'invisible': [('state', '!=', 'periodic')]}"
>
<div class="px-4">
This a periodical configuration. New records are generated automatically.
Next execution is programed for <field
name="next_execution_date"
/>
</div>
</div>
<sheet>
<div name="button_box">
<button
name="%(automation_record_configuration_act_window)s"
type="action"
class="oe_stat_button"
icon="fa-envelope"
attrs="{'invisible': [('record_count', '=', 0)]}"
>
<field
name="record_count"
widget="statinfo"
string="Records"
/>
</button>
<button
name="%(automation_record_configuration_test_act_window)s"
type="action"
class="oe_stat_button"
icon="fa-flask"
attrs="{'invisible': [('record_test_count', '=', 0)]}"
>
<field
name="record_test_count"
widget="statinfo"
string="Tests"
/>
</button>
</div>
<widget
name="web_ribbon"
title="Archived"
bg_color="text-bg-danger"
attrs="{'invisible': [('active', '=', True)]}"
/>
<div class="oe_title">
<h1><field
name="name"
placeholder="e.g. Remember unpaid invoices"
/></h1>
</div>
<group>
<field name="active" invisible="1" />
<field
name="is_periodic"
attrs="{'readonly': [('state', '!=', 'draft')]}"
widget="boolean_toggle"
/>
<field
name="tag_ids"
widget="many2many_tags"
options="{'color_field': 'color'}"
/>
<field
name="model_id"
options="{'no_create_edit': True, 'no_open': True}"
/>
<field name="model" invisible="1" />
<field
name="field_id"
string="Unicity based on"
options="{'no_create_edit': True, 'no_open': True}"
/>
<label for="filter_id" string="Filter" />
<div class="container ps-0">
<div class="row">
<div class="col-5">
<field name="filter_id" domain="filter_domain" />
</div>
<button
name="save_filter"
type="object"
string="Save filter"
icon="fa-save"
class="text-primary filter-left col-7"
attrs="{'invisible': [('filter_id', '!=', False)]}"
/>
</div>
</div>
<field name="filter_domain" invisible="1" />
<field
name="domain"
string="Domain"
widget="domain"
attrs="{'invisible': [('filter_id', '=', False)]}"
options="{'foldable': True, 'model': 'model'}"
/>
<field
name="editable_domain"
string="Domain"
widget="domain"
attrs="{'invisible': [('filter_id', '!=', False)]}"
options="{'foldable': True, 'model': 'model'}"
/>
<field name="company_id" groups="base.group_multi_company" />
</group>
<field
name="automation_step_ids"
widget="automation_step"
mode="kanban"
class="o_automation_kanban"
>
<kanban limit="1000">
<field name="id" />
<field name="name" />
<field name="step_type" />
<field name="parent_id" />
<field name="trigger_type" />
<field name="parent_position" />
<field name="trigger_child_types" />
<field name="trigger_type_data" />
<field name="trigger_date_kind" />
<field name="step_icon" />
<field name="step_name" />
<templates>
<div
t-name="kanban-box"
class="o_automation_kanban_box p-2"
>
<div
class="o_automation_kanban_extra"
t-foreach="[...Array(record.parent_position.raw_value).keys()]"
t-as="extra"
t-key="extra"
>
<div
class="o_automation_kanban_position_line"
/>
</div>
<div class="me-5 o_automation_kanban_time">
<div
class="o_automation_kanban_position_line"
/>
<i
class="o_automation_kanban_card_position fa fa-circle text-info text-right"
title="Run on"
/>
<div
class="p-2 o_automation_kanban_time_info text-center"
>
<div
t-att-class="record.trigger_type_data.raw_value.color"
t-if="record.trigger_type_data.raw_value.message_configuration"
>
<i
t-att-class="record.trigger_type_data.raw_value.icon"
/> <t
t-esc="record.trigger_type_data.raw_value.message_configuration"
/>
</div>
<div
t-if="record.trigger_date_kind.raw_value == 'date'"
>
<i
class="fa fa-calendar pe-1"
role="img"
aria-label="At"
title="At"
/>
<field name="trigger_date_field" />
</div>
<strong>
<i
class="fa fa-clock-o pe-1"
role="img"
aria-label="Select time"
title="Select time"
/>
<t
t-if="record.trigger_interval.raw_value >= 0"
>
<span class="pe-1"><field
name="trigger_interval"
/></span>
<field
name="trigger_interval_type"
/>
</t>
<t t-else="">
<span class="pe-1">Immediatly</span>
</t>
</strong>
</div>
</div>
<div class="o_automation_kanban_card">
<div class="o_automation_kanban_header">
<button
class="o_automation_kanban_header_icon btn btn-primary"
type="edit"
>
<span
t-att-class="record.step_icon.raw_value"
t-att-title="record.step_name.raw_value"
role="img"
t-att-aria-label="record.step_name.raw_value"
/>
</button>
<div
class="o_automation_kanban_header_title"
>
<h3 class="mb0 mt0"><a
type="edit"
class="oe_kanban_action oe_kanban_action_a"
t-att-title="record.name.raw_value"
><field name="name" /></a></h3>
<div t-esc="record.step_type.value" />
</div>
<div
class="o_automation_kanban_header_actions"
>
<div
t-if="!read_only_mode"
class="float-start mt8 mr4"
>
<a
type="edit"
role="button"
class="btn btn-primary btn-sm"
href="#"
>Edit</a>
<a
type="delete"
role="button"
class="btn btn-link btn-sm"
href="#"
>Delete</a>
</div>
</div>
</div>
<div class="o_automation_kanban_graph row">
<div class="col-8">
<field
name="graph_data"
widget="automation_graph"
/>
</div>
<div class="col-4 text-center pt-2">
<h2 class="o_automation_kpi_processed">
<field name="graph_done" />
</h2>
<div
class="o_automation_kpi_processed pb-3"
> Processed</div>
<h2 class="o_automation_kpi_error">
<field name="graph_error" />
</h2>
<div
class="o_automation_kpi_error"
> Error</div>
</div>
</div>
<div
t-if="!read_only_mode"
class="o_automation_kanban_child_add text-center"
>
<div
class="o_automation_kanban_child_add_title card-footer"
>
<i
class="fa fa-plus-circle"
/> Add child activity
</div>
<div
class="o_automation_kanban_child_add_buttons"
>
<t
t-foreach="record.trigger_child_types.raw_value"
t-as="trigger_type_id"
t-key="trigger_type_id"
>
<t
t-set="trigger_type"
t-value="record.trigger_child_types.raw_value[trigger_type_id]"
/>
<div
t-att-trigger-type="trigger_type_id"
class="o_automation_kanban_child_add_button"
>
<i
t-attf-class="{{trigger_type.icon}} {{trigger_type.color}}"
t-att-title="trigger_type.name"
role="img"
t-att-aria-label="trigger_type.name"
/>
</div>
</t>
</div>
</div>
</div>
</div>
</templates>
</kanban>
</field>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" />
<field name="message_ids" />
</div>
</form>
</field>
</record>
<record model="ir.ui.view" id="automation_configuration_search_view">
<field name="model">automation.configuration</field>
<field name="arch" type="xml">
<search>
<field name="name" />
<field name="tag_ids" />
<separator />
<filter name="draft" string="Draft" domain="[('state','=', 'draft')]" />
<filter
name="run"
string="Run"
domain="[('state','in', ['periodic', 'ondemand'])]"
/>
<filter name="done" string="Done" domain="[('state','=', 'done')]" />
<separator />
<filter
name="archived"
string="Archived"
domain="[('active','=', False)]"
/>
</search>
</field>
</record>
<record model="ir.ui.view" id="automation_configuration_kanban_view">
<field name="model">automation.configuration</field>
<field name="arch" type="xml">
<kanban default_group_by="state" quick_create="false">
<field name="state" readonly="1" />
<templates>
<t t-name="kanban-box">
<div class="oe_kanban_card oe_kanban_global_click">
<div class="row">
<field name="name" class="o_text_overflow" />
<field
name="tag_ids"
widget="many2many_tags"
options="{'color_field': 'color'}"
/>
</div>
<div class="row mt8">
<div class="col-4 text-center text-black-50">
<div>Records</div>
<field name="record_count" class="h1" />
</div>
<div class="col-4 text-center text-primary">
<div>Running</div>
<field name="record_run_count" class="h1" />
</div>
<div class="col-4 text-center text-black-50">
<div>Done</div>
<field name="record_done_count" class="h1" />
</div>
</div>
<div class="row mt8">
<div class="col-4 text-center text-black-50">
<div><i
class="fa fa-envelope"
title="Mails"
/></div>
<field name="activity_mail_count" class="h2" />
</div>
<div class="col-4 text-center text-black-50">
<div><i class="fa fa-cogs" title="Actions" /></div>
<field name="activity_action_count" class="h2" />
</div>
<div class="col-4 text-center text-black-50">
<div><i
class="fa fa-hand-pointer-o"
title="Clicks"
/></div>
<field name="click_count" class="h2" />
</div>
</div>
</div>
</t>
</templates>
</kanban>
</field>
</record>
<record model="ir.ui.view" id="automation_configuration_tree_view">
<field name="model">automation.configuration</field>
<field name="arch" type="xml">
<tree>
<!-- TODO -->
<field name="name" />
</tree>
</field>
</record>
<record model="ir.actions.act_window" id="automation_configuration_act_window">
<field name="name">Automation Configuration</field> <!-- TODO -->
<field name="res_model">automation.configuration</field>
<field name="view_mode">kanban,tree,form</field>
<field name="domain">[]</field>
<field name="context">{}</field>
</record>
<record model="ir.ui.menu" id="automation_configuration_menu">
<field name="name">Automation Configuration</field>
<field name="parent_id" ref="automation_root_menu" />
<field name="action" ref="automation_configuration_act_window" />
<field name="sequence" eval="10" />
</record>
</odoo>

View file

@ -0,0 +1,228 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2024 Dixmit
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record model="ir.ui.view" id="automation_configuration_step_form_view">
<field name="model">automation.configuration.step</field>
<field name="arch" type="xml">
<form>
<header />
<sheet>
<div class="oe_title">
<h1><field
name="name"
placeholder="e.g. Remember unpaid invoices"
/></h1>
</div>
<div
class="alert alert-warning"
role="alert"
attrs="{'invisible': [('trigger_interval', '>=', 0)]}"
>
In this case, the task will be executed automatically when we create it in the same process.
</div>
<group>
<group>
<field name="step_type" />
<field name="configuration_id" invisible="1" />
<field name="model_id" invisible="1" />
<field name="model" invisible="1" />
</group>
<group>
<field name="trigger_date_kind" />
<label for="trigger_interval" string="Trigger" />
<div class="container ps-0">
<div class="row">
<div class="col-2"><field
name="trigger_interval"
nolabel="1"
/></div>
<div class="col-10"><field
name="trigger_interval_type"
nolabel="1"
/></div>
</div>
<div
class="row"
attrs="{'invisible': [('trigger_date_kind', '!=', 'date')]}"
>
<span class="col-2">after</span>
<div class="col-10"><field
name="trigger_date_field_id"
nolabel="1"
attrs="{'required': [('trigger_date_kind', '=', 'date')]}"
/></div>
</div>
<div class="row">
<span
class="col-2"
attrs="{'invisible': [('trigger_date_kind', '!=', 'offset')]}"
>after</span>
<span
class="col-2"
attrs="{'invisible': [('trigger_date_kind', '=', 'offset')]}"
>when</span>
<div class="col-10"><field
name="trigger_type"
nolabel="1"
/></div>
</div>
<div
class="row"
attrs="{'invisible': [('trigger_type', '=', 'start')]}"
>
<span class="col-2">of</span>
<div class="col-10">
<field
name="parent_id"
domain="[('configuration_id', '=', configuration_id)]"
/></div>
</div>
</div>
<field name="allow_expiry" invisible="1" />
<div
class="container ps-0 alert alert-warning"
colspan="2"
attrs="{'invisible': [('trigger_date_kind', '!=', 'date')]}"
>
The scheduled date will be the date of the record at the moment we generate the new record.
Later changes of the field will not affect the scheduled date.
</div>
<field
name="expiry"
attrs="{'invisible': [('allow_expiry', '=', False)]}"
/>
<label
for="expiry_interval"
string="Trigger"
attrs="{'invisible': [('expiry', '=', False)]}"
/>
<div
class="container ps-0"
attrs="{'invisible': [('expiry', '=', False)]}"
>
<div class="row">
<div class="col-2"><field
name="expiry_interval"
attrs="{'required': [('expiry', '=', True)]}"
nolabel="1"
/></div>
<div class="col-10"><field
name="expiry_interval_type"
attrs="{'required': [('expiry', '=', True)]}"
nolabel="1"
/></div>
</div>
</div>
</group>
<group attrs="{'invisible':[('step_type', '!=', 'action')]}">
<field
name="server_action_id"
context="{'default_model_id': model_id}"
attrs="{'required': [('step_type', '=', 'action')]}"
/>
</group>
<group attrs="{'invisible':[('step_type', '!=', 'mail')]}">
<field
name="mail_template_id"
attrs="{'required': [('step_type', '=', 'mail')]}"
/>
<field name="mail_author_id" />
</group>
<group attrs="{'invisible':[('step_type', '!=', 'activity')]}">
<field
name="activity_type_id"
attrs="{'required': [('step_type', '=', 'activity')]}"
/>
<label
for="activity_date_deadline_range"
string="Deadline"
/>
<div class="container ps-0">
<div class="row">
<div class="col-2"><field
name="activity_date_deadline_range"
nolabel="1"
/></div>
<div class="col-10"><field
name="activity_date_deadline_range_type"
nolabel="1"
/></div>
</div>
</div>
<field name="activity_user_type" />
<field
name="activity_user_id"
attrs="{'invisible': [('activity_user_type', '!=', 'specific')], 'required': [('activity_user_type', '=', 'specific')]}"
/>
<field
name="activity_user_field_id"
domain="[('model_id', '=', model_id)]"
attrs="{'invisible': [('activity_user_type', '!=', 'generic')], 'required': [('activity_user_type', '=', 'generic')]}"
/>
</group>
</group>
<notebook>
<page string="Specific Domain" name="specific_domain">
<group>
<field name="apply_parent_domain" />
</group>
<field
name="domain"
widget="domain"
options="{'foldable': True, 'model': 'model'}"
/>
</page>
<page string="Final Domain" name="final_domain">
<div
>This is the final domain that will be applied to the records.
Consists in the join of the specific domain of the step and the domain of the records.</div>
<field
name="applied_domain"
widget="domain"
options="{'foldable': True, 'model': 'model'}"
/>
</page>
<page
string="Activity"
name="activity"
attrs="{'invisible':[('step_type', '!=', 'activity')]}"
>
<group>
<field name="activity_summary" />
<field name="activity_note" />
</group>
</page>
<page name="action" string="Server Action">
<group>
<field name="server_context" />
</group>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<record model="ir.ui.view" id="automation_configuration_step_search_view">
<field name="model">automation.configuration.step</field>
<field name="arch" type="xml">
<search>
<!-- TODO -->
</search>
</field>
</record>
<record model="ir.ui.view" id="automation_configuration_step_tree_view">
<field name="model">automation.configuration.step</field>
<field name="arch" type="xml">
<tree>
<!-- TODO -->
<field name="name" />
</tree>
</field>
</record>
</odoo>

View file

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2024 Dixmit
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record model="ir.ui.view" id="automation_filter_form_view">
<field name="model">automation.filter</field>
<field name="arch" type="xml">
<form>
<header />
<sheet>
<group>
<field name="name" />
<field
name="model_id"
options="{'no_create_edit': True, 'no_open': True}"
/>
<field name="model" invisible="1" />
<field
name="domain"
widget="domain"
options="{'foldable': True, 'model': 'model'}"
/>
</group>
</sheet>
</form>
</field>
</record>
<record model="ir.ui.view" id="automation_filter_search_view">
<field name="model">automation.filter</field>
<field name="arch" type="xml">
<search>
<field name="name" />
<field name="model_id" />
</search>
</field>
</record>
<record model="ir.ui.view" id="automation_filter_tree_view">
<field name="model">automation.filter</field>
<field name="arch" type="xml">
<tree>
<field name="name" />
<field name="model_id" />
</tree>
</field>
</record>
<record model="ir.actions.act_window" id="automation_filter_act_window">
<field name="name">Filters</field>
<field name="res_model">automation.filter</field>
<field name="view_mode">tree,form</field>
<field name="domain">[]</field>
<field name="context">{}</field>
</record>
<record model="ir.ui.menu" id="automation_filter_menu">
<field name="name">Filters</field>
<field name="parent_id" ref="automation_config_root_menu" />
<field name="action" ref="automation_filter_act_window" />
<field name="sequence" eval="20" />
</record>
</odoo>

View file

@ -0,0 +1,307 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2024 Dixmit
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record model="ir.ui.view" id="automation_record_form_view">
<field name="model">automation.record</field>
<field name="arch" type="xml">
<form create="0">
<header>
<field name="state" widget="statusbar" />
</header>
<sheet>
<widget
name="web_ribbon"
title="Test"
bg_color="text-bg-danger"
attrs="{'invisible': [('is_test', '=', False)]}"
/>
<div class="oe_title">
<div attrs="{'invisible': [('is_orphan_record', '=', False)]}">
<field name="is_orphan_record" invisible="1" />
<h1><span>This record is an orphan record</span></h1>
<group>
<field name="model" />
</group>
</div>
<h1
attrs="{'invisible': [('is_orphan_record', '=', True)]}"
><field
name="resource_ref"
required="1"
options="{'hide_model': True}"
/></h1>
</div>
<group>
<field name="configuration_id" />
<field name="is_test" invisible="1" />
</group>
<field
name="automation_step_ids"
widget="automation_step"
mode="kanban"
class="o_automation_kanban"
>
<kanban limit="1000">
<field name="id" />
<field name="name" />
<field name="step_type" />
<field name="parent_id" />
<field name="trigger_type" />
<field name="parent_position" />
<field name="mail_status" />
<field name="mail_clicked_on" />
<field name="activity_done_on" />
<field name="state" />
<field name="trigger_type_data" />
<field name="step_icon" />
<field name="step_name" />
<field name="step_actions" />
<templates>
<div
t-name="kanban-box"
class="o_automation_kanban_box p-2"
>
<div
class="o_automation_kanban_extra"
t-foreach="[...Array(record.parent_position.raw_value).keys()]"
t-as="extra"
t-key="extra"
>
<div
class="o_automation_kanban_position_line"
/>
</div>
<div class="me-5 o_automation_kanban_time">
<div
class="o_automation_kanban_position_line"
/>
<i
class="o_automation_kanban_card_position fa fa-circle text-info text-right"
title="Run on"
/>
<div
class="p-2 o_automation_kanban_time_info text-center"
>
<strong>
<field
class="text-success"
name="processed_on"
t-if="record.state.raw_value === 'done'"
/>
<span
class="text-warning"
t-elif="record.state.raw_value == 'expired'"
>
Expired <field
name="processed_on"
/>
</span>
<span
class="text-info"
t-elif="record.state.raw_value == 'rejected'"
>
Rejected <field
name="processed_on"
/>
</span>
<span
class="text-danger"
t-elif="record.state.raw_value == 'error'"
>
Error on <field
name="processed_on"
/>
</span>
<span
class="text-warning"
t-elif="record.state.raw_value == 'cancel'"
>
Cancelled <field
name="processed_on"
/>
</span>
<field
name="scheduled_date"
t-elif="record.scheduled_date.value and record.state.raw_value === 'scheduled'"
/>
<span t-else="" class="text-primary">
<i
t-att-class="record.trigger_type_data.raw_value.icon"
/> <t
t-esc="record.trigger_type_data.raw_value.message"
/>
</span>
</strong>
</div>
</div>
<div class="o_automation_kanban_card">
<div class="o_automation_kanban_header">
<div
t-attf-class="o_automation_kanban_header_icon {{record.state.raw_value === 'done' ? 'btn-success': (record.state.raw_value === 'scheduled' ? 'btn-primary': (record.state.raw_value === 'error' ? 'btn-danger': (record.state.raw_value === 'rejected' ? 'btn-info': 'btn-warning')))}}"
>
<span
t-att-class="record.step_icon.raw_value"
t-att-title="record.step_name.raw_value"
role="img"
t-att-aria-label="record.step_name.raw_value"
/>
</div>
<div
class="o_automation_kanban_header_title"
>
<h3 class="mb0 mt0"><a
type="edit"
class="oe_kanban_action oe_kanban_action_a"
t-att-title="record.name.raw_value"
><field name="name" /></a></h3>
<div t-esc="record.step_type.value" />
</div>
<div
class="o_automation_kanban_header_actions"
>
<button
type="object"
name="run"
class="fa fa-play btn-primary o_automation_kanban_header_icon"
title="Run"
t-if="record.state.raw_value == 'scheduled'"
/>
<button
type="object"
name="cancel"
class="fa fa-times btn-warning o_automation_kanban_header_icon"
title="Cancel"
t-if="record.state.raw_value == 'scheduled'"
/>
</div>
</div>
<div
class="o_automation_kanban_states"
t-if="record.step_actions.raw_value.length > 0"
>
<t
t-foreach="record.step_actions.raw_value"
t-as="state"
t-key="state_index"
>
<div
t-attf-class="o_automation_kanban_state {{ state.done ? state.color: 'text-muted' }}"
>
<i
t-att-class="state.icon"
t-att-title="state.name"
role="img"
t-att-aria-label="state.name"
/> <t t-esc="state.name" />
</div>
</t>
</div>
</div>
</div>
</templates>
</kanban>
</field>
</sheet>
</form>
</field>
</record>
<record model="ir.ui.view" id="automation_record_search_view">
<field name="model">automation.record</field>
<field name="arch" type="xml">
<search>
<field name="configuration_id" />
<separator />
<filter
name="filter_create_date"
string="Created on"
date="create_date"
/>
</search>
</field>
</record>
<record model="ir.ui.view" id="automation_record_tree_view">
<field name="model">automation.record</field>
<field name="arch" type="xml">
<tree create="0">
<field name="name" />
<field name="configuration_id" />
<field name="create_date" />
<field
name="state"
widget="badge"
decoration-info="state == 'periodic'"
decoration-success="state == 'done'"
/>
</tree>
</field>
</record>
<record id="automation_record_graph_view" model="ir.ui.view">
<field name="name">automation.record.graph</field>
<field name="model">automation.record</field>
<field name="arch" type="xml">
<graph string="Records">
<field name="create_date" interval="day" />
</graph>
</field>
</record>
<record id="automation_record_pivot_view" model="ir.ui.view">
<field name="name">automation.record.pivot</field>
<field name="model">automation.record</field>
<field name="arch" type="xml">
<pivot string="Records">
<field name="configuration_id" type="row" />
<field name="state" type="col" />
</pivot>
</field>
</record>
<record model="ir.actions.act_window" id="automation_record_act_window">
<field name="name">Automation Record</field> <!-- TODO -->
<field name="res_model">automation.record</field>
<field name="view_mode">graph,pivot,tree,form</field>
<field name="domain">[]</field>
<field name="context">{}</field>
</record>
<record
model="ir.actions.act_window"
id="automation_record_configuration_act_window"
>
<field name="name">Records</field>
<field name="res_model">automation.record</field>
<field name="view_mode">tree,form</field>
<field
name="domain"
>[('configuration_id', '=', active_id), ('is_test', '=', False)]</field>
<field name="context">{}</field>
</record>
<record
model="ir.actions.act_window"
id="automation_record_configuration_test_act_window"
>
<field name="name">Test Records</field>
<field name="res_model">automation.record</field>
<field name="view_mode">tree,form</field>
<field
name="domain"
>[('configuration_id', '=', active_id), ('is_test', '=', True)]</field>
<field name="context">{}</field>
</record>
<record model="ir.ui.menu" id="automation_record_menu">
<field name="name">Records</field>
<field name="parent_id" ref="automation_reporting_root_menu" />
<field name="action" ref="automation_record_act_window" />
<field name="sequence" eval="16" />
</record>
</odoo>

View file

@ -0,0 +1,142 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2024 Dixmit
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record model="ir.ui.view" id="automation_record_step_form_view">
<field name="model">automation.record.step</field>
<field name="arch" type="xml">
<form create="0">
<header>
<field name="state" widget="statusbar" />
</header>
<sheet>
<group>
<field name="id" />
<field name="name" />
<field name="scheduled_date" />
<field name="processed_on" />
<field name="step_type" />
<field
name="message_id"
attrs="{'invisible': [('message_id', '=', False)]}"
/>
</group>
<group
name="error"
string="Error"
attrs="{'invisible': [('state', '!=', 'error')]}"
>
<field name="error_trace" nolabel="1" />
</group>
</sheet>
</form>
</field>
</record>
<record model="ir.ui.view" id="automation_record_step_tree_view">
<field name="model">automation.record.step</field>
<field name="arch" type="xml">
<tree create="0">
<field name="name" />
<field name="state" />
<button
name="run"
type="object"
string="Run"
attrs="{'invisible': [('state', '!=', 'scheduled')]}"
/>
</tree>
</field>
</record>
<record id="automation_record_step_search_view" model="ir.ui.view">
<field name="name">automation.record.step.search</field>
<field name="model">automation.record.step</field>
<field name="arch" type="xml">
<search>
<field name="configuration_step_id" />
<field name="configuration_id" />
<field name="record_id" />
<separator />
<filter
string="Scheduled"
name="scheduled"
domain="[('state', '=', 'scheduled')]"
/>
<filter string="Done" name="done" domain="[('state', '=', 'done')]" />
<filter
string="Expired"
name="expired"
domain="[('state', '=', 'expired')]"
/>
<filter
string="Rejected"
name="rejected"
domain="[('state', '=', 'rejected')]"
/>
<filter
string="Error"
name="error"
domain="[('state', '=', 'error')]"
/>
<filter
string="Canceled"
name="cancel"
domain="[('state', '=', 'cancel')]"
/>
<separator />
<filter
name="filter_schedule_date"
string="Scheduled date"
date="scheduled_date"
/>
<separator />
<filter
name="filter_processed_on"
string="Processed on"
date="processed_on"
/>
</search>
</field>
</record>
<record id="automation_record_step_graph_view" model="ir.ui.view">
<field name="name">automation.record.step.graph</field>
<field name="model">automation.record.step</field>
<field name="arch" type="xml">
<graph string="Records">
<field name="scheduled_date" interval="day" />
<field name="state" />
</graph>
</field>
</record>
<record id="automation_record_step_pivot_view" model="ir.ui.view">
<field name="name">automation.record.step.pivot</field>
<field name="model">automation.record.step</field>
<field name="arch" type="xml">
<pivot string="Records">
<field name="configuration_id" type="row" />
<field name="state" type="col" />
</pivot>
</field>
</record>
<record model="ir.actions.act_window" id="automation_record_step_act_window">
<field name="name">Activities</field>
<field name="res_model">automation.record.step</field>
<field name="view_mode">graph,pivot,tree,form</field>
<field name="domain">[]</field>
<field name="context">{}</field>
</record>
<record model="ir.ui.menu" id="automation_record_step_menu">
<field name="name">Activities</field>
<field name="parent_id" ref="automation_reporting_root_menu" />
<field name="action" ref="automation_record_step_act_window" />
<field name="sequence" eval="20" />
</record>
</odoo>

View file

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2024 Dixmit
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record model="ir.ui.view" id="automation_tag_search_view">
<field name="model">automation.tag</field>
<field name="arch" type="xml">
<search>
<field name="name" />
</search>
</field>
</record>
<record model="ir.ui.view" id="automation_tag_tree_view">
<field name="model">automation.tag</field>
<field name="arch" type="xml">
<tree editable="bottom">
<field name="name" />
<field name="color" />
</tree>
</field>
</record>
<record model="ir.actions.act_window" id="automation_tag_act_window">
<field name="name">Tags</field> <!-- TODO -->
<field name="res_model">automation.tag</field>
<field name="view_mode">tree,form</field>
<field name="domain">[]</field>
<field name="context">{}</field>
</record>
<record model="ir.ui.menu" id="automation_tag_menu">
<field name="name">Tags</field>
<field name="parent_id" ref="automation_config_root_menu" />
<field name="action" ref="automation_tag_act_window" />
<field name="sequence" eval="40" />
</record>
</odoo>

View file

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="link_tracker_click_search_view" model="ir.ui.view">
<field name="name">link.tracker.click.view.search.inherit.mass_mailing</field>
<field name="model">link.tracker.click</field>
<field name="inherit_id" ref="link_tracker.link_tracker_click_view_search" />
<field name="arch" type="xml">
<xpath expr="//field[@name='country_id']" position="after">
<field name="automation_configuration_id" />
</xpath>
<xpath expr="//filter[@name='groupby_country_id']" position="after">
<filter
string="Automation configuration"
name="groupby_automation_configuration_id"
context="{'group_by': 'automation_configuration_id'}"
/>
</xpath>
</field>
</record>
<record model="ir.actions.act_window" id="link_tracker_click_act_window">
<field name="name">Clicks</field>
<field name="res_model">link.tracker.click</field>
<field name="view_mode">graph,pivot,tree</field>
<field name="domain">[('automation_record_step_id', '!=', False)]</field>
<field
name="context"
>{'search_default_groupby_automation_configuration_id': 1}</field>
</record>
<record model="ir.ui.menu" id="link_tracker_click_menu">
<field name="name">Clicks</field>
<field name="parent_id" ref="automation_reporting_root_menu" />
<field name="action" ref="link_tracker_click_act_window" />
<field name="sequence" eval="30" />
</record>
</odoo>

View file

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record model="ir.ui.menu" id="automation_root_menu">
<field name="name">Automation</field>
<field name="web_icon">automation_oca,static/description/icon.png</field>
<field name="groups_id" eval="[(4, ref('group_automation_user'))]" />
<field name="sequence" eval="55" />
</record>
<record model="ir.ui.menu" id="automation_reporting_root_menu">
<field name="name">Reporting</field>
<field name="parent_id" ref="automation_root_menu" />
<field name="groups_id" eval="[(4, ref('group_automation_manager'))]" />
<field name="sequence" eval="40" />
</record>
<record model="ir.ui.menu" id="automation_config_root_menu">
<field name="name">Configuration</field>
<field name="parent_id" ref="automation_root_menu" />
<field name="groups_id" eval="[(4, ref('group_automation_manager'))]" />
<field name="sequence" eval="90" />
</record>
</odoo>