Files
odoo_source/addons/project/views/project_sharing_views.xml
T
Audric Onockx (auon) aa250d3245 [IMP] project: improve and create task template for recurrence
The goal of this task is to ease the deletion/archiving of recurrent
tasks by giving the user the option to either continue
or stop the recurrence. The two main use-cases are:

\- You have a recurring task for a weekly meeting.
Next week, the user will be on time off. You are thus deleting the task.
However, you would still like tasks generated for the following meetings
and to keep track of the previous meetings.

\- You have a recurring task for a weekly meeting with an employee
that has just been fired. You are thus deleting the task and
you won't need this recurrence anymore.
(You may or may not want to keep track of the previous meetings.)

The main issue we are currently facing is that we need a task that acts
as a template for the recurrence to continue. This means that a user
cannot delete all of his tasks without breaking their recurrence.

Consequently, we will be using a "task template" for each recurrence,
which will only serve technical purposes and be invisible to the users.
When the recurrence is stopped, the task template is deleted.
This simplifies the technical and functional implementation as the user
won't be able to modify the template themselves.

\- Added task templates to recurrences in the data.
\- Deleted "all tasks" option form recurence update and changed "this
and following tasks" to "this and future tasks". Most of the time, the
user is going to update the most recent task, and it doesn't make
any functional sense to update past ones.
\- Same options for delete and archive.
\- No recurrent subtasks allowed anymore.
\- `date_deadline` is copied. We compute it by adding the delta between
the create date and the `date_deadline` of the template to the next
recurrence date.
\- Added filter to several view not to display task templates.

task-2937565

closes odoo/odoo#98088

Related: odoo/upgrade#4232
Related: odoo/enterprise#30416
Signed-off-by: Xavier Bol (xbo) <xbo@odoo.com>
2023-02-14 17:08:49 +01:00

323 lines
20 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="project_sharing_quick_create_task_form" model="ir.ui.view">
<field name="name">project.task.form.quick_create</field>
<field name="model">project.task</field>
<field name="priority">999</field>
<field name="groups_id" eval="[(4, ref('base.group_portal')), (4, ref('base.group_user'))]"/>
<field name="arch" type="xml">
<form>
<group>
<field name="name" string="Task Title" placeholder="e.g. Send Invitations"/>
</group>
</form>
</field>
</record>
<record id="project_sharing_project_task_view_kanban" model="ir.ui.view">
<field name="name">project.sharing.project.task.view.kanban</field>
<field name="model">project.task</field>
<field name="priority">999</field>
<field name="groups_id" eval="[(4, ref('base.group_portal')), (4, ref('base.group_user'))]"/>
<field name="arch" type="xml">
<kanban
class="o_kanban_small_column o_kanban_project_tasks"
default_group_by="stage_id"
on_create="quick_create"
quick_create_view="project.project_sharing_quick_create_task_form"
archivable="0"
import="0"
>
<field name="color"/>
<field name="priority"/>
<field name="stage_id" options='{"group_by_tooltip": {"description": "Description"}}'/>
<field name="portal_user_names"/>
<field name="partner_id"/>
<field name="sequence"/>
<field name="is_closed"/>
<field name="partner_is_company"/>
<field name="displayed_image_id"/>
<field name="active"/>
<field name="allow_subtasks"/>
<field name="child_text"/>
<field name="legend_blocked" invisible="1"/>
<field name="legend_normal" invisible="1"/>
<field name="legend_done" invisible="1"/>
<field name="allow_milestones" />
<field name="has_late_and_unreached_milestone"/>
<progressbar field="kanban_state" colors='{"done": "success", "blocked": "danger", "normal": "200"}'/>
<templates>
<t t-name="kanban-menu" t-if="!selection_mode">
<a t-if="widget.editable" role="menuitem" type="edit" class="dropdown-item">Edit</a>
<div role="separator" class="dropdown-divider"></div>
<ul class="oe_kanban_colorpicker" data-field="color"/>
</t>
<t t-name="kanban-box">
<div t-attf-class="{{!selection_mode ? 'oe_kanban_color_' + kanban_getcolor(record.color.raw_value) : ''}} oe_kanban_card oe_kanban_global_click">
<div class="oe_kanban_content">
<div class="o_kanban_record_top">
<div class="o_kanban_record_headings">
<strong class="o_kanban_record_title">
<s t-if="!record.active.raw_value"><field name="name" widget="name_with_subtask_count"/></s>
<t t-else=""><field name="name" widget="name_with_subtask_count"/></t>
</strong>
<span invisible="context.get('default_project_id', False)"><br/><field name="project_id" required="1"/></span>
<span t-if="record.allow_milestones.raw_value and record.milestone_id.raw_value" t-attf-class="{{record.has_late_and_unreached_milestone.raw_value ? 'text-danger' : ''}}">
<br/>
<field name="milestone_id" />
</span>
<br />
<t t-if="record.partner_id.value">
<span t-if="!record.partner_is_company.raw_value">
<field name="commercial_partner_id"/>
</span>
<span t-else="">
<field name="partner_id"/>
</span>
</t>
<t t-else="record.email_from.raw_value"><span><field name="email_from"/></span></t>
</div>
</div>
<div class="o_kanban_record_body">
<field name="tag_ids" widget="many2many_tags" options="{'color_field': 'color'}" context="{'project_id': project_id}"/>
<div t-if="record.date_deadline.raw_value" name="date_deadline" attrs="{'invisible': [('is_closed', '=', True)]}">
<field name="date_deadline" widget="remaining_days"/>
</div>
<div t-if="record.displayed_image_id.value" groups="base.group_user">
<field name="displayed_image_id" widget="attachment_image"/>
</div>
</div>
<div class="o_kanban_record_bottom" t-if="!selection_mode">
<div class="oe_kanban_bottom_left">
<field name="priority" widget="priority"/>
</div>
<div class="oe_kanban_bottom_right" t-if="!selection_mode">
<span t-if="record.portal_user_names.raw_value.length > 0" class="pe-2" t-att-title="record.portal_user_names.raw_value">
<t t-set="user_count" t-value="record.portal_user_names.raw_value.split(',').length"/>
<t t-if="user_count > 1"><t t-out="user_count"/> assignees</t>
<t t-else="" t-out="record.portal_user_names.raw_value"/>
</span>
<field name="kanban_state" widget="state_selection"/>
</div>
</div>
</div>
<div class="clearfix"></div>
</div>
</t>
</templates>
</kanban>
</field>
</record>
<record id="project_sharing_project_task_view_tree" model="ir.ui.view">
<field name="name">project.sharing.project.task.tree</field>
<field name="model">project.task</field>
<field name="inherit_id" ref="project_task_view_tree_main_base"/>
<field name="mode">primary</field>
<field name="priority">999</field>
<field name="arch" type="xml">
<tree position="attributes">
<attribute name="delete">0</attribute>
<attribute name="import">0</attribute>
</tree>
<field name="user_ids" position="replace">
<field name="portal_user_names" string="Assignees"/>
</field>
</field>
</record>
<record id="project_sharing_project_task_view_form" model="ir.ui.view">
<field name="name">project.sharing.project.task.view.form</field>
<field name="model">project.task</field>
<field name="priority">999</field>
<field name="groups_id" eval="[(4, ref('base.group_portal')), (4, ref('base.group_user'))]"/>
<field name="arch" type="xml">
<form string="Project Sharing: Task" class="o_form_project_tasks">
<header>
<button name="action_assign_to_me" string="Assign to Me" type="object" class="oe_highlight"
attrs="{'invisible' : &quot;[('user_ids', 'in', [uid])]&quot;}" data-hotkey="q" groups="base.group_user"/>
<button name="action_unassign_me" string="Unassign Me" type="object" class="oe_highlight"
attrs="{'invisible' : &quot;[('user_ids', 'not in', [uid])]&quot;}" data-hotkey="q"/>
<field name="stage_id" widget="statusbar" options="{'clickable': '1', 'fold_field': 'fold'}" attrs="{'invisible': [('project_id', '=', False), ('stage_id', '=', False)]}" />
</header>
<sheet string="Task">
<div class="oe_button_box" name="button_box">
<field name="display_parent_task_button" invisible="1"/>
<button name="action_project_sharing_view_parent_task" type="object" class="oe_stat_button" icon="fa-tasks" string="Parent Task" attrs="{'invisible': [('display_parent_task_button', '=', False)]}"/>
<button name="action_project_sharing_open_subtasks" type="object" class="oe_stat_button" icon="fa-tasks"
attrs="{'invisible' : ['|', '|', ('allow_subtasks', '=', False), ('id', '=', False), ('subtask_count', '=', 0)]}" context="{'default_user_ids': [(6, 0, [uid])]}">
<div class="o_field_widget o_stat_info">
<span class="o_stat_value">
<field name="subtask_count" widget="statinfo" nolabel="1"/>
</span>
<span class="o_stat_text">Sub-tasks</span>
</div>
</button>
</div>
<widget name="web_ribbon" title="Archived" bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}"/>
<div class="oe_title pe-0">
<h1 class="d-flex flex-row justify-content-between">
<field name="priority" widget="priority" class="me-3"/>
<field name="name" class="o_task_name text-truncate" placeholder="Task Title..."/>
<field name="kanban_state" widget="state_selection" class="ms-auto"/>
<field name="legend_blocked" invisible="1"/>
<field name="legend_normal" invisible="1"/>
<field name="legend_done" invisible="1"/>
</h1>
</div>
<group>
<group>
<field name="project_id" invisible="1"/>
<field name="display_project_id" string="Project" invisible="1"/>
<field name="allow_milestones" invisible="1"/>
<field name="milestone_id"
placeholder="e.g. Product Launch"
context="{'default_project_id': project_id if not parent_id or not display_project_id else display_project_id}"
attrs="{'invisible': [('allow_milestones', '=', False)]}"
options="{'no_open': True, 'no_create': True, 'no_edit': True}"
/>
<field name="user_ids" invisible="1" />
<field name="portal_user_names"
string="Assignees"
class="o_task_user_field"/>
<field name="tag_ids" context="{'project_id': project_id}" widget="many2many_tags" options="{'color_field': 'color', 'no_create_edit': True, 'no_edit_color': True}"/>
</group>
<group>
<field name="active" invisible="1"/>
<field name="parent_id" invisible="1" />
<field name="company_id" invisible="1" />
<field name="is_closed" invisible="1" />
<field name="allow_subtasks" invisible="1" />
<field name="partner_id" options="{'no_open': True, 'no_create': True, 'no_edit': True}"/>
<field name="date_deadline" attrs="{'invisible': [('is_closed', '=', True)]}"/>
</group>
</group>
<notebook>
<page name="description_page" string="Description">
<field name="description" type="html" options="{'collaborative': true}"/>
</page>
<page name="sub_tasks_page" string="Sub-tasks" attrs="{'invisible': [('allow_subtasks', '=', False)]}">
<field name="child_ids" context="{'default_project_id': project_id if not parent_id or not display_project_id else display_project_id, 'default_parent_id': id, 'default_partner_id': partner_id, 'form_view_ref' : 'project.project_sharing_project_task_view_form'}">
<tree editable="bottom">
<field name="project_id" invisible="1"/>
<field name="is_closed" invisible="1"/>
<field name="sequence" widget="handle"/>
<field name="priority" widget="priority" optional="show" nolabel="1"/>
<field name="name"/>
<field name="display_project_id" string="Project" optional="hide" invisible="1"/>
<field name="allow_milestones" invisible="1"/>
<field name="milestone_id"
optional="hide"
context="{'default_project_id': display_project_id or project_id}"
attrs="{'invisible': [('allow_milestones', '=', False)], 'column_invisible': [('parent.allow_milestones', '=', False)]}"
/>
<field name="company_id" invisible="1"/>
<field name="partner_id" options="{'no_open': True, 'no_create': True, 'no_edit': True}" optional="hide"/>
<field name="user_ids" invisible="1" />
<field name="portal_user_names" string="Assignees" optional="show"/>
<field name="date_deadline" attrs="{'invisible': [('is_closed', '=', True)]}" optional="show"/>
<field name="tag_ids" widget="many2many_tags" options="{'color_field': 'color'}" optional="hide"/>
<field name="kanban_state" widget="state_selection" options="{'hide_label': True}" nolabel="1" optional="show"/>
<field name="stage_id" optional="show"/>
<button name="action_open_task" type="object" title="View Task" string="View Task" class="btn btn-link float-end"
context="{'form_view_ref': 'project.project_sharing_project_task_view_form'}"
attrs="{'invisible': &quot;[('display_project_id', '!=', False), ('display_project_id', '!=', active_id)]&quot;}"/>
</tree>
</field>
</page>
</notebook>
</sheet>
<div class="oe_chatter"/>
</form>
</field>
</record>
<record id="project_sharing_project_task_view_search" model="ir.ui.view">
<field name="name">project.task.search.form</field>
<field name="model">project.task</field>
<field name="inherit_id" ref="project.view_task_search_form_project_base"/>
<field name="mode">primary</field>
<field name="priority">999</field>
<field name="arch" type="xml">
<search position="inside"/>
</field>
</record>
<record id="project_sharing_project_task_action" model="ir.actions.act_window">
<field name="name">Project Sharing</field>
<field name="res_model">project.task</field>
<field name="view_mode">kanban,tree,form</field>
<field name="search_view_id" ref="project.project_sharing_project_task_view_search"/>
<field name="domain">[
('display_project_id', '=', active_id),
'|',
('recurring_task', '=', False),
('recurrence_template_id', '!=', False),
]</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
No tasks found. Let's create one!
</p>
<p>
Keep track of the progress of your tasks from creation to completion.<br/>
Collaborate efficiently by chatting in real-time or via email.
</p>
</field>
</record>
<record id="project_sharing_kanban_action_view" model="ir.actions.act_window.view">
<field name="view_mode">kanban</field>
<field name="act_window_id" ref="project.project_sharing_project_task_action"/>
<field name="view_id" ref="project.project_sharing_project_task_view_kanban"/>
</record>
<record id="project_sharing_tree_action_view" model="ir.actions.act_window.view">
<field name="view_mode">tree</field>
<field name="act_window_id" ref="project.project_sharing_project_task_action"/>
<field name="view_id" ref="project.project_sharing_project_task_view_tree"/>
</record>
<record id="project_sharing_form_action_view" model="ir.actions.act_window.view">
<field name="view_mode">form</field>
<field name="act_window_id" ref="project.project_sharing_project_task_action"/>
<field name="view_id" ref="project.project_sharing_project_task_view_form"/>
</record>
<record id="project_sharing_project_task_action_sub_task" model="ir.actions.act_window">
<field name="name">Sub-tasks</field>
<field name="res_model">project.task</field>
<field name="view_mode">tree,kanban,form</field>
<field name="search_view_id" ref="project.project_sharing_project_task_view_search"/>
<field name="domain">[('id', 'child_of', active_id), ('id', '!=', active_id)]</field>
<field name="context">{'default_parent_id': active_id}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
No tasks found. Let's create one!
</p><p>
To get things done, use activities and status on tasks.<br/>
Chat in real time or by email to collaborate efficiently.
</p>
</field>
</record>
<record id="project_sharing_subtasks_tree_action_view" model="ir.actions.act_window.view">
<field name="view_mode">tree</field>
<field name="act_window_id" ref="project.project_sharing_project_task_action_sub_task"/>
<field name="view_id" ref="project.project_sharing_project_task_view_tree"/>
</record>
<record id="project_sharing_subtasks_kanban_action_view" model="ir.actions.act_window.view">
<field name="view_mode">kanban</field>
<field name="act_window_id" ref="project.project_sharing_project_task_action_sub_task"/>
<field name="view_id" ref="project.project_sharing_project_task_view_kanban"/>
</record>
<record id="project_sharing_subtasks_form_action_view" model="ir.actions.act_window.view">
<field name="view_mode">form</field>
<field name="act_window_id" ref="project.project_sharing_project_task_action_sub_task"/>
<field name="view_id" ref="project.project_sharing_project_task_view_form"/>
</record>
</odoo>