mirror of
https://github.com/bringout/oca-ocb-project.git
synced 2026-04-21 00:02:09 +02:00
19.0 vanilla
This commit is contained in:
parent
a2f74aefd8
commit
4a4d12c333
844 changed files with 212348 additions and 270090 deletions
|
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="account_analytic_account_view_form_inherit" model="ir.ui.view">
|
||||
<field name="name">account.analytic.account.form.inherit</field>
|
||||
<field name="model">account.analytic.account</field>
|
||||
<field name="inherit_id" ref="analytic.view_account_analytic_account_form"/>
|
||||
<field eval="40" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//button[@name='%(analytic.account_analytic_line_action)d']" position="before">
|
||||
<button class="oe_stat_button" type="object" name="action_view_projects"
|
||||
icon="fa-puzzle-piece" invisible="project_count == 0">
|
||||
<field string="Projects" name="project_count" widget="statinfo"/>
|
||||
</button>
|
||||
</xpath>
|
||||
<xpath expr="//form" position="attributes">
|
||||
<attribute name="js_class">analytic_account_form_view</attribute>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_account_analytic_account_list_inherit" model="ir.ui.view">
|
||||
<field name="name">account.analytic.account.list.inherit</field>
|
||||
<field name="model">account.analytic.account</field>
|
||||
<field name="inherit_id" ref="analytic.view_account_analytic_account_list"/>
|
||||
<field name="priority">40</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//list" position="attributes">
|
||||
<attribute name="js_class">analytic_account_list_view</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//list" position="inside">
|
||||
<field name="project_count" column_invisible="1"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<!--
|
||||
Analytic Accounts with project
|
||||
-->
|
||||
<record id="account_analytic_account_view_form_inherit" model="ir.ui.view">
|
||||
<field name="name">account.analytic.account.form.inherit</field>
|
||||
<field name="model">account.analytic.account</field>
|
||||
<field name="inherit_id" ref="analytic.view_account_analytic_account_form"/>
|
||||
<field eval="40" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//button[@name='%(analytic.account_analytic_line_action)d']" position="before">
|
||||
<button class="oe_stat_button" type="object" name="action_view_projects"
|
||||
icon="fa-puzzle-piece" attrs="{'invisible': [('project_count', '=', 0)]}">
|
||||
<field string="Projects" name="project_count" widget="statinfo"/>
|
||||
</button>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="mail_activity_plan_view_form_project_and_task" model="ir.ui.view">
|
||||
<field name="name">mail.activity.plan.view.form.project.and.task</field>
|
||||
<field name="model">mail.activity.plan</field>
|
||||
<field name="mode">primary</field>
|
||||
<field name="priority">32</field>
|
||||
<field name="inherit_id" ref="mail.mail_activity_plan_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='res_model']" position="attributes">
|
||||
<attribute name="widget">filterable_selection</attribute>
|
||||
<attribute name="options">{'whitelisted_values': ['project.project', 'project.task']}</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='template_ids']/list" position="attributes">
|
||||
<attribute name="editable">bottom</attribute>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="mail_activity_plan_action_config_project_task_plan" model="ir.actions.act_window">
|
||||
<field name="name">Activity Plans</field>
|
||||
<field name="res_model">mail.activity.plan</field>
|
||||
<field name="path">project-activity-plans</field>
|
||||
<field name="view_mode">list,kanban,form</field>
|
||||
<field name="search_view_id" ref="mail.mail_activity_plan_view_search"/>
|
||||
<field name="context">{'default_res_model': 'project.task'}</field>
|
||||
<field name="domain">[('res_model', 'in', ('project.project', 'project.task'))]</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Create a Task Activity Plan
|
||||
</p>
|
||||
<p>
|
||||
Activity plans are used to assign a list of activities in just a few clicks
|
||||
(e.g. "Progress Report", "Stand-up Meeting", ...)
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="mail_activity_plan_action_project_task_view_tree" model="ir.actions.act_window.view">
|
||||
<field name="sequence">1</field>
|
||||
<field name="view_mode">list</field>
|
||||
<field name="view_id" ref="mail.mail_activity_plan_view_tree"/>
|
||||
<field name="act_window_id" ref="project.mail_activity_plan_action_config_project_task_plan"/>
|
||||
</record>
|
||||
|
||||
<!-- Force the project view that allows to modify the target models of the plan to project or task. -->
|
||||
<record id="mail_activity_plan_action_project_task_view_form" model="ir.actions.act_window.view">
|
||||
<field name="sequence">2</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="project.mail_activity_plan_view_form_project_and_task"/>
|
||||
<field name="act_window_id" ref="project.mail_activity_plan_action_config_project_task_plan"/>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
<?xml version="1.0"?>
|
||||
<odoo>
|
||||
<!-- Activity types config -->
|
||||
<record id="mail_activity_type_action_config_project_types" model="ir.actions.act_window">
|
||||
<field name="name">Activity Types</field>
|
||||
<field name="res_model">mail.activity.type</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="path">project-activity-types</field>
|
||||
<field name="view_mode">list,kanban,form</field>
|
||||
<field name="domain">['|', ('res_model', '=', False), ('res_model', '=', 'project.task')]</field>
|
||||
<field name="context">{'default_res_model': 'project.task'}</field>
|
||||
<field name="help" type="html">
|
||||
|
|
@ -15,7 +15,4 @@
|
|||
</p>
|
||||
</field>
|
||||
</record>
|
||||
<menuitem id="project_menu_config_activity_type"
|
||||
action="mail_activity_type_action_config_project_types"
|
||||
parent="menu_project_config"/>
|
||||
</odoo>
|
||||
</odoo>
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="project_sharing_access_view_tree" model="ir.ui.view">
|
||||
<field name="name">project.collaborator.view.tree</field>
|
||||
<field name="model">project.collaborator</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Project Collaborators" create="0">
|
||||
<field name="partner_id" options="{'no_create': True}"/>
|
||||
<field name="partner_email"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_collaborator_view_search" model="ir.ui.view">
|
||||
<field name="name">project.collaborator.view.search</field>
|
||||
<field name="model">project.collaborator</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="partner_id" />
|
||||
<field name="project_id" />
|
||||
<group expand="0" string="Group By">
|
||||
<filter name="project" string="Project" context="{'group_by': 'project_id'}" />
|
||||
<filter name="collaborator" string="Collaborator" context="{'group_by': 'partner_id'}" />
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_collaborator_action" model="ir.actions.act_window">
|
||||
<field name="name">Project Collaborators</field>
|
||||
<field name="res_model">project.collaborator</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="domain">[('project_id', '=', active_id)]</field>
|
||||
<field name="search_view_id" ref="project_collaborator_view_search"/>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No collaborators found
|
||||
</p>
|
||||
<p>
|
||||
Collaborate efficiently with key stakeholders by sharing with them the Kanban view of your tasks. Collaborators will be able to edit parts of tasks and send messages.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
122
odoo-bringout-oca-ocb-project/project/views/project_menus.xml
Normal file
122
odoo-bringout-oca-ocb-project/project/views/project_menus.xml
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<menuitem
|
||||
name="Project"
|
||||
id="menu_main_pm"
|
||||
groups="group_project_manager,group_project_user"
|
||||
web_icon="project,static/description/icon.png"
|
||||
sequence="70"
|
||||
>
|
||||
<menuitem
|
||||
name="Projects"
|
||||
id="menu_projects"
|
||||
action="open_view_project_all"
|
||||
sequence="1"
|
||||
/>
|
||||
<menuitem
|
||||
name="Projects"
|
||||
id="menu_projects_group_stage"
|
||||
action="open_view_project_all_group_stage"
|
||||
groups="project.group_project_stages"
|
||||
sequence="1"
|
||||
/>
|
||||
<menuitem
|
||||
name="Tasks"
|
||||
id="menu_project_management"
|
||||
sequence="2"
|
||||
>
|
||||
<menuitem
|
||||
name="My Tasks"
|
||||
id="menu_project_management_my_tasks"
|
||||
action="action_view_my_task"
|
||||
sequence="1"
|
||||
/>
|
||||
<menuitem
|
||||
name="All Tasks"
|
||||
id="menu_project_management_all_tasks"
|
||||
action="action_view_all_task"
|
||||
sequence="2"
|
||||
/>
|
||||
</menuitem>
|
||||
<menuitem
|
||||
name="Reporting"
|
||||
id="menu_project_report"
|
||||
sequence="99"
|
||||
>
|
||||
<menuitem
|
||||
name="Tasks Analysis"
|
||||
id="menu_project_report_task_analysis"
|
||||
action="project.action_project_task_user_tree"
|
||||
sequence="10"
|
||||
/>
|
||||
<menuitem
|
||||
name="Customer Ratings"
|
||||
id="rating_rating_menu_project"
|
||||
action="rating_rating_action_project_report"
|
||||
sequence="51"
|
||||
/>
|
||||
|
||||
</menuitem>
|
||||
<menuitem
|
||||
name="Configuration"
|
||||
id="menu_project_config"
|
||||
groups="project.group_project_manager"
|
||||
sequence="100"
|
||||
>
|
||||
<menuitem
|
||||
name="Settings"
|
||||
id="project_config_settings_menu_action"
|
||||
action="project_config_settings_action"
|
||||
groups="base.group_system"
|
||||
sequence="0"
|
||||
/>
|
||||
<menuitem
|
||||
name="Projects"
|
||||
id="menu_projects_config_group_stage"
|
||||
action="open_view_project_all_config_group_stage"
|
||||
groups="project.group_project_stages"
|
||||
sequence="5"
|
||||
/>
|
||||
<menuitem
|
||||
name="Projects"
|
||||
id="menu_projects_config"
|
||||
action="open_view_project_all_config"
|
||||
sequence="5"
|
||||
/>
|
||||
<menuitem
|
||||
name="Project Stages"
|
||||
id="menu_project_config_project_stage"
|
||||
action="project_project_stage_configure"
|
||||
groups="project.group_project_stages"
|
||||
sequence="9"
|
||||
/>
|
||||
<menuitem
|
||||
name="Task Stages"
|
||||
id="menu_project_config_project"
|
||||
action="open_task_type_form"
|
||||
groups="base.group_no_one"
|
||||
sequence="10"
|
||||
/>
|
||||
<menuitem
|
||||
name="Tags"
|
||||
id="menu_project_tags_act"
|
||||
action="project_tags_action"
|
||||
/>
|
||||
<menuitem
|
||||
name="Project Roles"
|
||||
id="project_menu_config_project_roles"
|
||||
action="project_roles_action"
|
||||
/>
|
||||
<menuitem
|
||||
name="Activity Types"
|
||||
id="project_menu_config_activity_type"
|
||||
action="mail_activity_type_action_config_project_types"
|
||||
/>
|
||||
<menuitem
|
||||
name="Activity Plans"
|
||||
id="mail_activity_plan_menu_config_project"
|
||||
action="mail_activity_plan_action_config_project_task_plan"
|
||||
/>
|
||||
</menuitem>
|
||||
</menuitem>
|
||||
</odoo>
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="project_milestone_view_form" model="ir.ui.view">
|
||||
<field name="name">project.milestone.view.form</field>
|
||||
<field name="model">project.milestone</field>
|
||||
|
|
@ -12,18 +11,20 @@
|
|||
type="action"
|
||||
class="oe_stat_button"
|
||||
icon="fa-tasks"
|
||||
attrs="{'invisible': [('task_count', '=', 0)]}"
|
||||
context="{'default_project_id': project_id}"
|
||||
groups="project.group_project_milestone"
|
||||
close="1"
|
||||
invisible="not project_allow_milestones"
|
||||
>
|
||||
<!-- TODO: Remove me in master -->
|
||||
<field name="task_count" string="Tasks" widget="statinfo" invisible="1"/>
|
||||
<div class="o_form_field o_stat_info">
|
||||
<span class="o_stat_value">
|
||||
<field name="task_count" widget="statinfo" nolabel="1"/>
|
||||
<field name="task_count" nolabel="1"/>
|
||||
<span class="fw-normal"> Tasks</span>
|
||||
</span>
|
||||
<span class="o_stat_value" invisible="done_task_count == 0">
|
||||
<field name="done_task_count" nolabel="1"/>
|
||||
<span class="fw-normal"> Done</span>
|
||||
</span>
|
||||
<span class="o_stat_text">Tasks</span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
|
|
@ -41,26 +42,104 @@
|
|||
</record>
|
||||
|
||||
<record id="project_milestone_view_tree" model="ir.ui.view">
|
||||
<field name="name">project.milestone.view.tree</field>
|
||||
<field name="name">project.milestone.view.list</field>
|
||||
<field name="model">project.milestone</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree decoration-success="can_be_marked_as_done" decoration-danger="is_deadline_exceeded and not can_be_marked_as_done" decoration-muted="is_reached" editable="bottom" sample="1">
|
||||
<list decoration-success="can_be_marked_as_done" decoration-danger="is_deadline_exceeded and not can_be_marked_as_done" decoration-muted="is_reached" editable="bottom" sample="1" default_order="sequence, deadline, is_reached desc, name">
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="name"/>
|
||||
<field name="deadline" optional="show"/>
|
||||
<field name="project_id" column_invisible="1"/>
|
||||
<field name="is_reached" optional="show"/>
|
||||
<field name="is_deadline_exceeded" invisible="1"/>
|
||||
<field name="task_count" invisible="1" />
|
||||
<field name="can_be_marked_as_done" invisible="1"/>
|
||||
<button name="action_view_tasks"
|
||||
type="object"
|
||||
title="View Tasks"
|
||||
string="View Tasks"
|
||||
class="btn btn-link float-end"
|
||||
attrs="{'invisible': [('task_count', '=', 0)]}"
|
||||
groups="project.group_project_milestone"
|
||||
/>
|
||||
</tree>
|
||||
invisible="task_count == 0 or not project_allow_milestones"
|
||||
groups="project.group_project_milestone"/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_milestone_view_kanban" model="ir.ui.view">
|
||||
<field name="name">project.milestone.view.kanban</field>
|
||||
<field name="model">project.milestone</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban class="o_kanban_mobile">
|
||||
<field name="can_be_marked_as_done"/>
|
||||
<field name="is_deadline_exceeded"/>
|
||||
<templates>
|
||||
<t t-name="card">
|
||||
<div class="d-flex">
|
||||
<field name="is_reached" widget="task_done_checkmark" class="oe_inline"/>
|
||||
<strong>
|
||||
<field name="name" class="oe_inline"/>
|
||||
<t t-set="badge" t-value="'text-success'" t-if="record.can_be_marked_as_done.raw_value"/>
|
||||
<t t-set="badge" t-value="'text-danger'" t-if="record.is_deadline_exceeded.raw_value"/>
|
||||
<t t-if="record.deadline.raw_value">
|
||||
- <span t-attf-class="{{ badge }}"><field name="deadline"/></span>
|
||||
</t>
|
||||
</strong>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_milestone_action" model="ir.actions.act_window">
|
||||
<field name="name">Milestones</field>
|
||||
<field name="res_model">project.milestone</field>
|
||||
<field name="view_mode">list,kanban,form</field>
|
||||
<field name="domain">[('project_id', '=', active_id)]</field>
|
||||
<field name="context">{'default_project_id': active_id}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No milestones found. Let's create one!
|
||||
</p>
|
||||
<p>Track major progress points that must be reached to achieve success.</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_view_project_milestone_list" model="ir.actions.act_window.view">
|
||||
<field name="act_window_id" ref="project_milestone_action"/>
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view_mode">list</field>
|
||||
<field name="view_id" ref="project.project_milestone_view_tree"/>
|
||||
</record>
|
||||
|
||||
<record id="action_view_project_milestone_kanban" model="ir.actions.act_window.view">
|
||||
<field name="act_window_id" ref="project_milestone_action"/>
|
||||
<field name="sequence" eval="20"/>
|
||||
<field name="view_mode">kanban</field>
|
||||
<field name="view_id" ref="project_milestone_view_kanban"/>
|
||||
</record>
|
||||
|
||||
<record id="action_view_project_milestone_form" model="ir.actions.act_window.view">
|
||||
<field name="act_window_id" ref="project_milestone_action"/>
|
||||
<field name="sequence" eval="30"/>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="project_milestone_view_form"/>
|
||||
</record>
|
||||
|
||||
<record id="project_embedded_action_project_milestones" model="ir.embedded.actions">
|
||||
<field name="parent_res_model">project.project</field>
|
||||
<field name="sequence">10</field>
|
||||
<field name="name">Milestones</field>
|
||||
<field name="parent_action_id" ref="project.act_project_project_2_project_task_all"/>
|
||||
<field name="action_id" ref="project.project_milestone_action"/>
|
||||
<field name="domain">[('allow_milestones', '=', True)]</field>
|
||||
<field name="groups_ids" eval="[(4, ref('project.group_project_milestone'))]" />
|
||||
</record>
|
||||
|
||||
<record id="project_embedded_action_update_milestones" model="ir.embedded.actions">
|
||||
<field name="parent_res_model">project.project</field>
|
||||
<field name="sequence">25</field>
|
||||
<field name="name">Milestones</field>
|
||||
<field name="parent_action_id" ref="project.project_update_all_action"/>
|
||||
<field name="action_id" ref="project.project_milestone_action"/>
|
||||
<field name="domain">[('allow_milestones', '=', True)]</field>
|
||||
<field name="groups_ids" eval="[(4, ref('project.group_project_milestone'))]" />
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,112 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="portal_layout" name="Portal layout: project menu entry" inherit_id="portal.portal_breadcrumbs" priority="40">
|
||||
<xpath expr="//ol[hasclass('o_portal_submenu')]" position="inside">
|
||||
<li t-if="page_name == 'project' or project" class="col-lg-2" t-attf-class="breadcrumb-item #{'active ' if not project else ''}">
|
||||
<a t-if="project" t-attf-href="/my/projects">Projects</a>
|
||||
<t t-else="">Projects</t>
|
||||
</li>
|
||||
<li t-if="page_name in ['project_task', 'project_subtasks', 'project_recurrent_tasks'] and project" class="breadcrumb-item active">
|
||||
<a t-if="project" t-attf-href="/my/projects/{{ project.id }}?{{ keep_query() }}"><t t-esc="project.name"/></a>
|
||||
</li>
|
||||
<li t-elif="project" t-attf-class="breadcrumb-item #{'active ' if not project else ''} text-truncate col-8 col-lg-10">
|
||||
<t t-esc="project.name"/>
|
||||
</li>
|
||||
<li t-if="page_name == 'task' or (task and not project)" t-attf-class="breadcrumb-item #{'active ' if not task else ''}">
|
||||
<a t-if="task" t-attf-href="/my/tasks?{{ keep_query() }}">Tasks</a>
|
||||
<t t-else="">Tasks</t>
|
||||
</li>
|
||||
<li t-if="page_name == 'project_subtasks' and task and project" class="breadcrumb-item active">
|
||||
<a t-attf-href="/my/projects/{{ project.id }}/task/{{ task.id }}"><t t-esc="task.name"/></a>
|
||||
</li>
|
||||
<li t-elif="page_name == 'project_recurrent_tasks' and task and project" class="breadcrumb-item active text-truncate">
|
||||
<a t-attf-href="/my/projects/{{ project.id }}/task/{{ task.id }}?{{ keep_query() }}"><t t-esc="task.name"/></a>
|
||||
</li>
|
||||
<li t-elif="task" class="breadcrumb-item active text-break">
|
||||
<span t-field="task.name"/>
|
||||
</li>
|
||||
<li t-if="page_name == 'project_subtasks' or (task and subtask and project)" t-attf-class="breadcrumb-item text-truncate #{'active ' if not subtask else ''}">
|
||||
<a t-if="subtask" t-attf-href="/my/tasks/{{ task.id }}/subtasks?{{ keep_query() }}">Sub-tasks</a>
|
||||
<t t-else="">Sub-tasks</t>
|
||||
</li>
|
||||
<li t-elif="page_name == 'project_recurrent_tasks' and task and project" t-attf-class="breadcrumb-item text-truncate">
|
||||
Recurrent tasks
|
||||
</li>
|
||||
<li t-if="subtask" class="breadcrumb-item active text-break">
|
||||
<span t-field="subtask.name"/>
|
||||
</li>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="portal_my_home" name="Projects / Tasks" customize_show="True" inherit_id="portal.portal_my_home" priority="40">
|
||||
<xpath expr="//div[hasclass('o_portal_docs')]" position="before">
|
||||
<t t-set="portal_service_category_enable" t-value="True"/>
|
||||
</xpath>
|
||||
<div id="portal_service_category" position="inside">
|
||||
<t t-call="portal.portal_docs_entry">
|
||||
<t t-set="icon" t-value="'/web/static/img/folder.svg'"/>
|
||||
<t t-set="title">Projects</t>
|
||||
<t t-set="url" t-value="'/my/projects'"/>
|
||||
<t t-set="text">Follow the evolution of your projects</t>
|
||||
<t t-set="placeholder_count" t-value="'project_count'"/>
|
||||
</t>
|
||||
<t t-call="portal.portal_docs_entry">
|
||||
<t t-set="icon" t-value="'/project/static/src/img/tasks.svg'"/>
|
||||
<t t-set="title">Tasks</t>
|
||||
<t t-set="url" t-value="'/my/tasks'"/>
|
||||
<t t-set="text">Follow and comment on tasks in your projects</t>
|
||||
<t t-set="placeholder_count" t-value="'task_count'"/>
|
||||
</t>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="portal_my_projects" name="My Projects">
|
||||
<t t-call="portal.portal_layout">
|
||||
<t t-set="breadcrumbs_searchbar" t-value="True"/>
|
||||
|
||||
<t t-call="portal.portal_searchbar">
|
||||
<t t-set="title">Projects</t>
|
||||
</t>
|
||||
<t t-if="not projects">
|
||||
<div class="alert alert-warning" role="alert">
|
||||
There are no projects.
|
||||
</div>
|
||||
</t>
|
||||
<t t-if="projects" t-call="portal.portal_table">
|
||||
<tbody>
|
||||
<tr t-foreach="projects" t-as="project">
|
||||
<td>
|
||||
<a t-attf-href="/my/projects/#{project.id}"><span t-field="project.name"/></a>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<t t-out="project.task_count" />
|
||||
<t t-out="project.label_tasks" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="portal_my_project" name="My Project">
|
||||
<t t-call="portal.portal_layout">
|
||||
<t t-set="title" t-value="project.name"/>
|
||||
<t t-set="o_portal_fullwidth_alert" groups="project.group_project_user">
|
||||
<t t-call="portal.portal_back_in_edit_mode">
|
||||
<t t-set="backend_url" t-value="'/odoo/project.project/%s' % (project.id)"/>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
<t t-call="portal.portal_searchbar">
|
||||
<t t-set="title">Tasks</t>
|
||||
</t>
|
||||
<t t-if="not grouped_tasks">
|
||||
<div class="alert alert-warning" role="alert">
|
||||
There are no tasks.
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-call="project.portal_tasks_list"/>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,325 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="portal_my_tasks_priority_widget_template" name="Priority Widget Template">
|
||||
<t t-set="priority_label" t-value="priority_labels[task.priority]"/>
|
||||
<span t-attf-class="o_priority_star d-inline-block fa fa-star#{' text-warning' if task.priority != '0' else '-o opacity-75'} #{classes if classes else ''}" t-att-title="priority_label"/>
|
||||
<span t-attf-class="o_priority_star d-inline-block fa fa-star#{' text-warning' if task.priority in ['2', '3'] else '-o opacity-75'} #{classes if classes else ''}" t-att-title="priority_label"/>
|
||||
<span t-attf-class="o_priority_star d-inline-block fa fa-star#{' text-warning' if task.priority == '3' else '-o opacity-75'} #{classes if classes else ''}" t-att-title="priority_label"/>
|
||||
</template>
|
||||
|
||||
<template id="portal_my_tasks_state_widget_template" name="Status Widget Template">
|
||||
<span
|
||||
t-att-title="dict(task.fields_get(allfields=['state'])['state']['selection'])[task.state]"
|
||||
t-attf-class="#{'fa' if task.state in ['1_done','1_canceled','04_waiting_normal'] else 'o_status rounded-circle' } #{'fa-check-circle text-success' if task.state == '1_done' else 'fa-times-circle text-danger' if task.state == '1_canceled' else 'bg-warning' if task.state == '02_changes_requested' else 'bg-success' if task.state == '03_approved' else 'fa-hourglass-o' if task.state == '04_waiting_normal' else ''}"
|
||||
/>
|
||||
</template>
|
||||
<template id="portal_my_tasks_badge_widget_template" name="badge Widget Template">
|
||||
<span t-attf-class="badge rounded-pill o_tag o_badge_color_#{task.stage_id_color}"
|
||||
t-attf-title="#{task.stage_id.name}" t-out="task.stage_id.name"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template id="portal_tasks_list" name="Tasks List">
|
||||
<t t-if="grouped_tasks">
|
||||
<t t-call="portal.portal_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<!-- Allows overrides in modules -->
|
||||
<t t-set="group_by_in_header_list" t-value="['priority', 'milestone_id']"></t>
|
||||
<t t-if="multiple_projects" t-set="group_by_in_header_list" t-value="group_by_in_header_list + ['project_id']"/>
|
||||
<!-- Computes the right colspan once and use it everywhere -->
|
||||
<t t-set="grouped_tasks_colspan" t-value="5 if groupby in group_by_in_header_list else 6"></t>
|
||||
<t t-set="grouped_tasks_colspan" t-if="not allow_milestone" t-value="grouped_tasks_colspan - 1"></t>
|
||||
<t t-set="grouped_tasks_colspan" t-if="not multiple_projects" t-value="grouped_tasks_colspan - 1"/>
|
||||
<th t-attf-colspan="{{2 if groupby != 'priority' else 1}}"/>
|
||||
<th>Name</th>
|
||||
<th>Assignees</th>
|
||||
<th t-if="groupby != 'project_id' and multiple_projects">Project</th>
|
||||
<th t-if="groupby != 'milestone_id' and allow_milestone" name="project_portal_milestones">Milestone</th>
|
||||
<th t-if="groupby != 'state'"/>
|
||||
<th t-if="groupby != 'stage_id'" class="text-end">Stage</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<t t-foreach="grouped_tasks" t-as="tasks">
|
||||
<tbody t-if="tasks">
|
||||
<tr name="grouped_tasks_groupby_columns" t-if="groupby != 'none'" class="table-light">
|
||||
<th name="groupby_name_col" t-att-colspan="grouped_tasks_colspan">
|
||||
<t t-if="groupby == 'project_id' and multiple_projects">
|
||||
<!-- This div is necessary for documents_project_sale -->
|
||||
<div name="project_name" class="d-flex w-100 align-items-center">
|
||||
<span t-if="tasks[0].sudo().project_id" t-field="tasks[0].sudo().project_id.name"/>
|
||||
<span t-else="">No Project</span>
|
||||
</div>
|
||||
</t>
|
||||
<t t-elif="groupby == 'milestone_id'">
|
||||
<span t-if="tasks[0].sudo().milestone_id and tasks[0].sudo().allow_milestones"
|
||||
class="text-truncate"
|
||||
t-field="tasks[0].sudo().milestone_id.name"/>
|
||||
<span t-else="">No Milestone</span>
|
||||
</t>
|
||||
<t t-if="groupby == 'stage_id'">
|
||||
<!-- This div is necessary for documents_project_sale -->
|
||||
<div name="stage_name" class="d-flex w-100 align-items-center">
|
||||
<span class="text-truncate" t-field="tasks[0].sudo().stage_id.name"/>
|
||||
</div>
|
||||
</t>
|
||||
<t t-if="groupby == 'priority'">
|
||||
<span class="text-truncate" t-field="tasks[0].sudo().priority"/>
|
||||
</t>
|
||||
<t t-if="groupby == 'state'">
|
||||
<span class="text-truncate" t-field="tasks[0].sudo().state"/>
|
||||
</t>
|
||||
<t t-if="groupby == 'partner_id'">
|
||||
<span t-if="tasks[0].sudo().partner_id"
|
||||
class="text-truncate"
|
||||
t-field="tasks[0].sudo().partner_id.name"/>
|
||||
<span t-else="">No Customer</span>
|
||||
</t>
|
||||
</th>
|
||||
<th name="state_col" t-if="groupby != 'state'"/>
|
||||
<th name="stage_id_col" t-if="groupby != 'stage_id'"/>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tbody t-if="tasks">
|
||||
<t t-foreach="tasks" t-as="task">
|
||||
<tr>
|
||||
<td class="text-start">
|
||||
#<span t-esc="task.id"/>
|
||||
</td>
|
||||
<td t-if="groupby != 'priority'" class="text-end">
|
||||
<t t-call="project.portal_my_tasks_priority_widget_template"/>
|
||||
</td>
|
||||
<td>
|
||||
<a t-attf-href="/my/#{task_url}/#{task.id}?{{ keep_query() }}"><span t-att-title="task.name" t-field="task.name"/></a>
|
||||
</td>
|
||||
<td>
|
||||
<t t-set="assignees" t-value="task.sudo().user_ids"/>
|
||||
<div t-if="assignees" class="flex-nowrap ps-3">
|
||||
<img class="o_avatar rounded" t-attf-src="#{image_data_uri(assignees[:1].avatar_128)}" alt="User"/>
|
||||
<span class="align-middle" t-att-title="'\n'.join(assignees.mapped('name'))">
|
||||
<span t-field="assignees[:1].name"/><span t-if="len(assignees) > 1" class="badge ms-1 rounded-pill bg-light"> +<span t-out="len(assignees) - 1"/></span>
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
<td t-if="groupby != 'project_id' and multiple_projects">
|
||||
<span title="Current project of the task" t-out="task.project_id.name" />
|
||||
</td>
|
||||
<td t-if="groupby != 'milestone_id' and allow_milestone" name="project_portal_milestones">
|
||||
<t t-if="task.milestone_id and task.allow_milestones">
|
||||
<span t-esc="task.milestone_id.name" />
|
||||
</t>
|
||||
</td>
|
||||
<td t-if="groupby != 'state'" align="right" class="align-middle">
|
||||
<t t-call="project.portal_my_tasks_state_widget_template">
|
||||
<t t-set="path" t-value="'tasks'"/>
|
||||
</t>
|
||||
</td>
|
||||
<td t-if="groupby != 'stage_id'" class="text-end lh-1">
|
||||
<t t-call="project.portal_my_tasks_badge_widget_template"/>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="portal_my_tasks" name="My Tasks">
|
||||
<t t-call="portal.portal_layout">
|
||||
<t t-set="breadcrumbs_searchbar" t-value="True"/>
|
||||
|
||||
<t t-call="portal.portal_searchbar">
|
||||
<t t-set="title">Tasks</t>
|
||||
</t>
|
||||
<t t-if="not grouped_tasks">
|
||||
<div class="alert alert-warning" role="alert">
|
||||
There are no tasks.
|
||||
</div>
|
||||
</t>
|
||||
<t t-call="project.portal_tasks_list"/>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="task_link_preview_front_end" inherit_id="portal.frontend_layout" primary="True">
|
||||
<xpath expr="//t[@t-if='not_uses_default_logo'][1]" position="before">
|
||||
<t t-if="preview_object.displayed_image_id">
|
||||
<meta property="og:image" t-attf-content="/web/image/{{ preview_object.displayed_image_id.id }}/300x200?access_token={{ preview_object.displayed_image_id.generate_access_token()[0] }}"/>
|
||||
</t>
|
||||
</xpath>
|
||||
<xpath expr="//t[@t-if='not_uses_default_logo'][2]" position="before">
|
||||
<t t-if="preview_object.displayed_image_id">
|
||||
<meta property="twitter:image" t-attf-content="/web/image/{{ preview_object.displayed_image_id.id }}/300x200?access_token={{ preview_object.displayed_image_id.generate_access_token()[0] }}"/>
|
||||
</t>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="task_link_preview_portal_layout" inherit_id="portal.portal_layout" primary="True">
|
||||
<xpath expr="//t[@t-call='portal.frontend_layout']" position="attributes">
|
||||
<attribute name="t-call">project.task_link_preview_front_end</attribute>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="portal_my_task" name="My Task" inherit_id="portal.portal_sidebar" primary="True">
|
||||
<xpath expr="//t[@t-call='portal.portal_layout']" position="attributes">
|
||||
<attribute name="t-call">project.task_link_preview_portal_layout</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//t[@t-call='project.task_link_preview_portal_layout']" position="before">
|
||||
<t t-set="o_portal_fullwidth_alert" groups="project.group_project_user">
|
||||
<t t-call="portal.portal_back_in_edit_mode">
|
||||
<t t-set="backend_url" t-value="'/odoo/action-project.action_view_my_task/%s' % (task.id)"/>
|
||||
</t>
|
||||
</t>
|
||||
</xpath>
|
||||
<xpath expr="//div[hasclass('o_portal_sidebar')]" position="inside">
|
||||
<t t-set="title" t-value="task.name"/>
|
||||
|
||||
<div class="row o_project_portal_sidebar">
|
||||
<t t-call="portal.portal_record_sidebar">
|
||||
<t t-set="classes" t-value="'col-lg-4 col-xxl-3 d-print-none'"/>
|
||||
|
||||
<t t-set="entries">
|
||||
<div class="d-flex flex-wrap flex-column gap-4">
|
||||
<div id="task-nav" class="d-flex align-items-center flex-grow-1 p-0" t-ignore="true" role="complementary">
|
||||
<ul class="nav flex-column">
|
||||
<li class="nav-item" id="nav-header">
|
||||
<a class="nav-link p-0" href="#card_header">
|
||||
Task
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item" id="nav-chat">
|
||||
<a class="nav-link p-0" href="#task_chat">
|
||||
History
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="task-links" t-if="task_link_section" class="d-flex align-items-center flex-grow-1 ps-0" t-ignore="true" role="complementary">
|
||||
<ul class="nav flex-column">
|
||||
<t t-foreach="task_link_section" t-as="task_link">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link p-0" t-att-href="task_link['access_url']" t-att-target="task_link.get('target', '_self')">
|
||||
<t t-out="task_link['title']"/>
|
||||
</a>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div t-if="task.user_ids or task.partner_id" class="d-flex flex-column gap-4 mt-3">
|
||||
<div t-if="task.user_ids">
|
||||
<h6 class="flex-basis-100"><small class="text-muted">Assignees</small></h6>
|
||||
<t t-foreach="task.user_ids" t-as="user">
|
||||
<t t-call="portal.portal_my_contact">
|
||||
<t t-set="_spacingClass" t-value="'mb-3' if len(task.user_ids) > 1 else ''"/>
|
||||
<t t-set="_contactAvatar" t-value="image_data_uri(user.avatar_128)"/>
|
||||
<t t-set="_contactName" t-value="user.name"/>
|
||||
<div t-out="user" t-options='{"widget": "contact", "fields": ["email", "phone"]}'/>
|
||||
</t>
|
||||
</t>
|
||||
</div>
|
||||
<div class="col-12 d-flex flex-column" t-if="task.partner_id">
|
||||
<h6><small class="text-muted">Customer</small></h6>
|
||||
<t t-if="task.partner_id">
|
||||
<t t-call="portal.portal_my_contact">
|
||||
<t t-set="_contactAvatar" t-value="image_data_uri(task.partner_id.avatar_512)"/>
|
||||
<t t-set="_contactName" t-value="task.partner_id.display_name"/>
|
||||
<div t-field="task.partner_id" t-options='{"widget": "contact", "fields": ["email", "phone"]}'/>
|
||||
</t>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
<div id="task_content" class="o_portal_content col-12 col-lg-8 col-xxl-9">
|
||||
<div id="card">
|
||||
<div id="card_header" data-anchor="true">
|
||||
<div class="row justify-content-between mb-3">
|
||||
<div class="col-12 col-md-9">
|
||||
<div class="d-flex gap-2">
|
||||
<h3 class="my-0">
|
||||
<span t-field="task.name"/>
|
||||
<small class="text-muted d-none d-md-inline">(#<span t-field="task.id"/>)</small>
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<small class="text-end">Stage:</small>
|
||||
<t t-call="project.portal_my_tasks_badge_widget_template"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="card_body">
|
||||
<div class="float-end">
|
||||
<t t-call="project.portal_my_tasks_state_widget_template">
|
||||
<t t-set="path" t-value="'task'"/>
|
||||
</t>
|
||||
</div>
|
||||
<div class="row mb-4 container">
|
||||
<div class="col-12 col-md-6 flex-grow-1">
|
||||
<div t-if="project_accessible"><strong>Project:</strong> <a t-attf-href="/my/projects/#{task.project_id.id}" t-field="task.project_id"/></div>
|
||||
<div t-else=""><strong>Project:</strong> <a t-field="task.project_id"/></div>
|
||||
<div t-if="task.milestone_id and task.allow_milestones"><strong>Milestone:</strong> <span t-field="task.milestone_id"/></div>
|
||||
<div>
|
||||
<strong>Priority:</strong>
|
||||
<t t-call="project.portal_my_tasks_priority_widget_template"/>
|
||||
</div>
|
||||
<div t-if="task.date_deadline"><strong>Deadline:</strong> <span t-field="task.date_deadline" t-options='{"widget": "datetime"}'/></div>
|
||||
<div name="portal_my_task_allocated_hours">
|
||||
<strong t-if="task.allocated_hours > 0">Allocated Time:</strong>
|
||||
<t t-call="project.portal_my_task_allocated_hours_template"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-6 d-empty-none" name="portal_my_task_second_column"></div>
|
||||
</div>
|
||||
|
||||
<div class="row" t-if="task.description or task.attachment_ids">
|
||||
<div t-if="not is_html_empty(task.description)" class="mb-4 mb-md-0">
|
||||
<h5 class="mb-1">Description</h5>
|
||||
<hr class="mt-1 mb-2"/>
|
||||
<div class="py-1 px-2 bg-100 small overflow-auto table-responsive mb-4" t-field="task.description"/>
|
||||
</div>
|
||||
<div t-if="task.attachment_ids" class="o_project_portal_attachments">
|
||||
<h5 class="mb-1">Attachments</h5>
|
||||
<hr class="mt-1 mb-2"/>
|
||||
<div class="row">
|
||||
<t t-foreach="task.attachment_ids" t-as="attachment">
|
||||
<div class="col-md-6">
|
||||
<ul class="list-unstyled">
|
||||
<li class="oe_attachments">
|
||||
<a t-attf-href="/web/content/#{attachment.id}?download=true&access_token=#{attachment.access_token}"
|
||||
target="_blank" data-no-post-process="" class="d-flex align-items-center rounded bg-light p-2">
|
||||
<div class='oe_attachment_embedded o_image o_image_small me-2 me-lg-3'
|
||||
t-att-title="attachment.name" t-att-data-mimetype="attachment.mimetype"
|
||||
t-attf-data-src="/web/image/#{attachment.id}/50x40?access_token=#{attachment.access_token}">
|
||||
</div>
|
||||
<div class='oe_attachment_name text-truncate'><t t-esc='attachment.name'/></div>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
<div id="task_chat" data-anchor="true">
|
||||
<h3>Communication history</h3>
|
||||
<t t-call="portal.message_thread">
|
||||
<t t-set="token" t-value="task.access_token"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="portal_my_task_allocated_hours_template">
|
||||
<strong t-if="task.allocated_hours > 0" class="d-none">Allocated Time:</strong>
|
||||
<span t-out="task.allocated_hours" t-options='{"widget": "float_time"}'/>
|
||||
</template>
|
||||
</odoo>
|
||||
|
|
@ -1,366 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="portal_layout" name="Portal layout: project menu entry" inherit_id="portal.portal_breadcrumbs" priority="40">
|
||||
<xpath expr="//ol[hasclass('o_portal_submenu')]" position="inside">
|
||||
<li t-if="page_name == 'project' or project" class="col-lg-2" t-attf-class="breadcrumb-item #{'active ' if not project else ''}">
|
||||
<a t-if="project" t-attf-href="/my/projects?{{ keep_query() }}">Projects</a>
|
||||
<t t-else="">Projects</t>
|
||||
</li>
|
||||
<li t-if="page_name in ['project_task', 'project_subtasks'] and project" class="breadcrumb-item active">
|
||||
<a t-if="project" t-attf-href="/my/projects/{{ project.id }}?{{ keep_query() }}"><t t-esc="project.name"/></a>
|
||||
</li>
|
||||
<li t-elif="project" t-attf-class="breadcrumb-item #{'active ' if not project else ''} text-truncate col-8 col-lg-10">
|
||||
<t t-esc="project.name"/>
|
||||
</li>
|
||||
<li t-if="page_name == 'task' or (task and not project)" t-attf-class="breadcrumb-item #{'active ' if not task else ''}">
|
||||
<a t-if="task" t-attf-href="/my/tasks?{{ keep_query() }}">Tasks</a>
|
||||
<t t-else="">Tasks</t>
|
||||
</li>
|
||||
<li t-if="page_name == 'project_subtasks' and task and project" class="breadcrumb-item active">
|
||||
<a t-attf-href="/my/projects/{{ project.id }}/task/{{ task.id }}?{{ keep_query() }}"><t t-esc="task.name"/></a>
|
||||
</li>
|
||||
<li t-elif="task" class="breadcrumb-item active text-truncate">
|
||||
<span t-field="task.name"/>
|
||||
</li>
|
||||
<li t-if="page_name == 'project_subtasks' or (task and subtask and project)" t-attf-class="breadcrumb-item text-truncate #{'active ' if not subtask else ''}">
|
||||
<a t-if="subtask" t-attf-href="/my/tasks/{{ task.id }}/subtasks?{{ keep_query() }}">Sub-tasks</a>
|
||||
<t t-else="">Sub-tasks</t>
|
||||
</li>
|
||||
<li t-if="subtask" class="breadcrumb-item active text-truncate">
|
||||
<span t-field="subtask.name"/>
|
||||
</li>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="portal_my_tasks_priority_widget_template" name="Priority Widget Template">
|
||||
<span t-attf-class="o_priority_star fa fa-star#{'' if task.priority == '1' else '-o'}" t-attf-title="Priority: {{'Important' if task.priority == '1' else 'Normal'}}"/>
|
||||
</template>
|
||||
|
||||
<template id="portal_my_tasks_state_widget_template" name="Status Widget Template">
|
||||
<span t-att-title="task.kanban_state_label" t-attf-class="o_status rounded-circle #{'bg-success' if task.kanban_state == 'done' else 'bg-danger' if task.kanban_state == 'blocked' else ''}"/>
|
||||
</template>
|
||||
|
||||
<template id="portal_my_home" name="Show Projects / Tasks" customize_show="True" inherit_id="portal.portal_my_home" priority="40">
|
||||
<xpath expr="//div[hasclass('o_portal_docs')]" position="inside">
|
||||
<t t-call="portal.portal_docs_entry">
|
||||
<t t-set="title">Projects</t>
|
||||
<t t-set="url" t-value="'/my/projects'"/>
|
||||
<t t-set="placeholder_count" t-value="'project_count'"/>
|
||||
</t>
|
||||
<t t-call="portal.portal_docs_entry">
|
||||
<t t-set="title">Tasks</t>
|
||||
<t t-set="url" t-value="'/my/tasks'"/>
|
||||
<t t-set="placeholder_count" t-value="'task_count'"/>
|
||||
</t>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="portal_my_projects" name="My Projects">
|
||||
<t t-call="portal.portal_layout">
|
||||
<t t-set="breadcrumbs_searchbar" t-value="True"/>
|
||||
|
||||
<t t-call="portal.portal_searchbar">
|
||||
<t t-set="title">Projects</t>
|
||||
</t>
|
||||
<t t-if="not projects">
|
||||
<div class="alert alert-warning mt8" role="alert">
|
||||
There are no projects.
|
||||
</div>
|
||||
</t>
|
||||
<t t-if="projects" t-call="portal.portal_table">
|
||||
<tbody>
|
||||
<tr t-foreach="projects" t-as="project">
|
||||
<td>
|
||||
<a t-attf-href="/my/projects/#{project.id}?{{ keep_query() }}"><span t-field="project.name"/></a>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<t t-out="project.task_count_with_subtasks" />
|
||||
<t t-out="project.label_tasks" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="portal_my_project" name="My Project">
|
||||
<t t-call="portal.portal_layout">
|
||||
<t t-set="o_portal_fullwidth_alert" groups="project.group_project_user">
|
||||
<t t-call="portal.portal_back_in_edit_mode">
|
||||
<t t-set="backend_url" t-value="'/web#model=project.project&id=%s&view_type=kanban' % (project.id)"/>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
<t t-call="portal.portal_searchbar">
|
||||
<t t-set="title">Tasks</t>
|
||||
</t>
|
||||
<t t-if="not grouped_tasks">
|
||||
<div class="alert alert-warning mt8" role="alert">
|
||||
There are no tasks.
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-call="project.portal_tasks_list"/>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="portal_tasks_list" name="Tasks List">
|
||||
<t t-if="grouped_tasks">
|
||||
<t t-call="portal.portal_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<!-- Allows overrides in modules -->
|
||||
<t t-set="group_by_in_header_list" t-value="['priority', 'status', 'project', 'stage', 'milestone']"></t>
|
||||
<t t-set="number_of_header" t-value="8"></t>
|
||||
<!-- Computes the right colspan once and use it everywhere -->
|
||||
<t t-set="grouped_tasks_colspan" t-value="number_of_header - 1 if groupby in group_by_in_header_list else number_of_header"></t>
|
||||
<t t-set="grouped_tasks_colspan" t-value="grouped_tasks_colspan if allow_milestone else grouped_tasks_colspan - 1"></t>
|
||||
<th t-attf-colspan="{{2 if groupby != 'priority' else 1}}"/>
|
||||
<th>Name</th>
|
||||
<th>Assignees</th>
|
||||
<th t-if="groupby != 'milestone' and allow_milestone" name="project_portal_milestones">Milestone</th>
|
||||
<th t-if="groupby != 'status'"/>
|
||||
<th t-if="groupby != 'project'">Project</th>
|
||||
<th t-if="groupby != 'stage'" class="text-end">Stage</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<t t-foreach="grouped_tasks" t-as="tasks">
|
||||
<tbody t-if="tasks">
|
||||
<tr t-if="not groupby == 'none'" class="table-light">
|
||||
<th t-if="groupby == 'project'" t-attf-colspan="{{grouped_tasks_colspan}}">
|
||||
<!-- This div is necessary for documents_project_sale -->
|
||||
<div name="project_name" class="d-flex w-100 align-items-center">
|
||||
<span t-field="tasks[0].sudo().project_id.name"/>
|
||||
</div>
|
||||
</th>
|
||||
<th t-if="groupby == 'milestone'" t-attf-colspan="{{grouped_tasks_colspan}}">
|
||||
<span t-if="tasks[0].sudo().milestone_id and tasks[0].sudo().allow_milestones"
|
||||
class="text-truncate"
|
||||
t-field="tasks[0].sudo().milestone_id.name"/>
|
||||
<span t-else="">No Milestone</span>
|
||||
</th>
|
||||
<th t-if="groupby == 'stage'" t-attf-colspan="{{grouped_tasks_colspan}}">
|
||||
<span class="text-truncate" t-field="tasks[0].sudo().stage_id.name"/></th>
|
||||
<th t-if="groupby == 'priority'" t-attf-colspan="{{grouped_tasks_colspan}}">
|
||||
<span class="text-truncate" t-field="tasks[0].sudo().priority"/></th>
|
||||
<th t-if="groupby == 'status'" t-attf-colspan="{{grouped_tasks_colspan}}">
|
||||
<span class="text-truncate" t-field="tasks[0].sudo().kanban_state"/></th>
|
||||
<th t-if="groupby == 'customer'" t-attf-colspan="{{grouped_tasks_colspan}}">
|
||||
<span t-if="tasks[0].sudo().partner_id"
|
||||
class="text-truncate"
|
||||
t-field="tasks[0].sudo().partner_id.name"/>
|
||||
<span t-else="">No Customer</span>
|
||||
</th>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tbody t-if="tasks">
|
||||
<t t-foreach="tasks" t-as="task">
|
||||
<tr>
|
||||
<td class="text-start">
|
||||
#<span t-esc="task.id"/>
|
||||
</td>
|
||||
<td t-if="groupby != 'priority'" class="text-end">
|
||||
<t t-call="project.portal_my_tasks_priority_widget_template"/>
|
||||
</td>
|
||||
<td>
|
||||
<a t-attf-href="/my/#{task_url}/#{task.id}?{{ keep_query() }}"><span t-field="task.name"/></a>
|
||||
</td>
|
||||
<td>
|
||||
<t t-set="assignees" t-value="task.sudo().user_ids"/>
|
||||
<div t-if="assignees" class="row flex-nowrap ps-3">
|
||||
<img class="rounded-circle o_portal_contact_img me-2 px-0" t-attf-src="#{image_data_uri(assignees[:1].avatar_128)}" alt="User" style="width: 20px; height: 20px;"/>
|
||||
<span t-out="'%s%s' % (assignees[:1].name, ' + %s others' % len(assignees[1:]) if len(assignees.user_ids) > 1 else '')" t-att-title="'\n'.join(assignees.mapped('name'))"/>
|
||||
</div>
|
||||
</td>
|
||||
<td t-if="groupby != 'milestone' and allow_milestone" name="project_portal_milestones">
|
||||
<t t-if="task.milestone_id and task.allow_milestones">
|
||||
<span t-esc="task.milestone_id.name" />
|
||||
</t>
|
||||
</td>
|
||||
<td t-if="groupby != 'status'" align="right">
|
||||
<t t-call="project.portal_my_tasks_state_widget_template">
|
||||
<t t-set="path" t-value="'tasks'"/>
|
||||
</t>
|
||||
</td>
|
||||
<td t-if="groupby != 'project'">
|
||||
<span class="badge rounded-pill text-bg-info mw-100 text-truncate" title="Current project of the task" t-esc="task.project_id.name" />
|
||||
</td>
|
||||
<td t-if="groupby != 'stage'" class="text-end">
|
||||
<span t-attf-class="badge #{'text-bg-primary' if task.stage_id.fold else 'text-bg-light'}" title="Current stage of the task" t-esc="task.stage_id.name"/>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="portal_my_tasks" name="My Tasks">
|
||||
<t t-call="portal.portal_layout">
|
||||
<t t-set="breadcrumbs_searchbar" t-value="True"/>
|
||||
|
||||
<t t-call="portal.portal_searchbar">
|
||||
<t t-set="title">Tasks</t>
|
||||
</t>
|
||||
<t t-if="not grouped_tasks">
|
||||
<div class="alert alert-warning mt8" role="alert">
|
||||
There are no tasks.
|
||||
</div>
|
||||
</t>
|
||||
<t t-call="project.portal_tasks_list"/>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="portal_my_task" name="My Task" inherit_id="portal.portal_sidebar" primary="True">
|
||||
<xpath expr="//div[hasclass('o_portal_sidebar')]" position="inside">
|
||||
<t t-set="o_portal_fullwidth_alert" groups="project.group_project_user">
|
||||
<t t-call="portal.portal_back_in_edit_mode">
|
||||
<t t-set="backend_url" t-value="'/web#model=project.task&id=%s&action=%s&view_type=form' % (task.id, task.env.ref('project.action_view_all_task').id)"/>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
<div class="row mt16 o_project_portal_sidebar">
|
||||
<t t-call="portal.portal_record_sidebar">
|
||||
<t t-set="classes" t-value="'col-lg-3 d-print-none'"/>
|
||||
|
||||
<t t-set="entries">
|
||||
<ul class="list-group list-group-flush flex-wrap flex-row flex-lg-column">
|
||||
<li id="task-nav" class="list-group-item ps-0 flex-grow-1 d-flex align-items-center" t-ignore="true" role="complementary">
|
||||
<ul class="nav flex-column">
|
||||
<li class="nav-item" id="nav-header">
|
||||
<a class="nav-link ps-3" href="#card_header" style="max-width: 200px;">
|
||||
Task
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item" id="nav-chat">
|
||||
<a class="nav-link ps-3" href="#task_chat">
|
||||
History
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li id="task-links" t-if="task_link_section" class="list-group-item ps-0 flex-grow-1 d-flex align-items-center" t-ignore="true" role="complementary">
|
||||
<ul class="nav flex-column">
|
||||
<t t-foreach="task_link_section" t-as="task_link">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link ps-3" t-att-href="task_link['access_url']">
|
||||
<t t-out="task_link['title']"/>
|
||||
</a>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li t-if="task.user_ids or task.partner_id" class="list-group-item flex-grow-1">
|
||||
<div class="col-12 col-md-12 pb-2" t-if="task.user_ids">
|
||||
<strong>Assignees</strong>
|
||||
<t t-foreach="task.user_ids" t-as="user">
|
||||
<div class="d-flex mb-3 flex-nowrap mt-1">
|
||||
<img class="rounded-circle o_portal_contact_img" t-att-src="image_data_uri(user.avatar_128)" alt="Contact"/>
|
||||
<div class="ms-2">
|
||||
<div t-esc="user" t-options='{"widget": "contact", "fields": ["name"]}'/>
|
||||
<a t-attf-href="tel:{{user.phone}}" t-if="user.phone"><div t-esc="user" t-options='{"widget": "contact", "fields": ["phone"]}'/></a>
|
||||
<a t-if="user.email" class="text-break" t-attf-href="mailto:{{user.email}}">
|
||||
<div t-out="user" t-options='{"widget": "contact", "fields": ["email"]}'/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
<div class="col-12 col-md-12 pb-2" t-if="task.partner_id">
|
||||
<strong>Customer</strong>
|
||||
<div class="d-flex flex-nowrap mt-1">
|
||||
<img class="rounded-circle o_portal_contact_img" t-att-src="image_data_uri(task.partner_id.avatar_128)" alt="Contact"/>
|
||||
<div class="ms-2">
|
||||
<div t-field="task.partner_id" t-options='{"widget": "contact", "fields": ["name"]}'/>
|
||||
<a t-attf-href="tel:{{task.partner_id.phone}}" t-if="task.partner_id.phone"><div t-field="task.partner_id" t-options='{"widget": "contact", "fields": ["phone"]}'/></a>
|
||||
<a t-if="task.partner_id.email" class="text-break" t-attf-href="mailto:{{task.partner_id.email}}">
|
||||
<div t-field="task.partner_id" t-options='{"widget": "contact", "fields": ["email"]}'/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</t>
|
||||
</t>
|
||||
<div id="task_content" class="col-lg-9 justify-content-end">
|
||||
<div id="card" class="card">
|
||||
<div id="card_header" class="card-header bg-white" data-anchor="true">
|
||||
<div class="row g-0">
|
||||
<div class="col-12">
|
||||
<h5 class="d-flex mb-1 mb-md-0 row">
|
||||
<div class="col-9">
|
||||
<t t-call="project.portal_my_tasks_priority_widget_template"/>
|
||||
<span t-field="task.name" class="text-truncate"/>
|
||||
<small class="text-muted d-none d-md-inline"> (#<span t-field="task.id"/>)</small>
|
||||
</div>
|
||||
<div class="col-3 text-end">
|
||||
<small class="text-end">Stage:</small>
|
||||
<span t-field="task.stage_id.name" class=" badge rounded-pill text-bg-info" title="Current stage of this task"/>
|
||||
</div>
|
||||
</h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="card_body" class="card-body">
|
||||
<div class="float-end">
|
||||
<t t-call="project.portal_my_tasks_state_widget_template">
|
||||
<t t-set="path" t-value="'task'"/>
|
||||
</t>
|
||||
</div>
|
||||
<div class="row mb-4 container">
|
||||
<div class="col-12 col-md-6">
|
||||
<div t-if="project_accessible"><strong>Project:</strong> <a t-attf-href="/my/projects/#{task.project_id.id}" t-field="task.project_id"/></div>
|
||||
<div t-else=""><strong>Project:</strong> <a t-field="task.project_id"/></div>
|
||||
<div t-if="task.date_deadline"><strong>Deadline:</strong> <span t-field="task.date_deadline" t-options='{"widget": "date"}'/></div>
|
||||
<div t-if="task.milestone_id and task.allow_milestones"><strong>Milestone:</strong> <span t-field="task.milestone_id"/></div>
|
||||
<div name="portal_my_task_planned_hours">
|
||||
<t t-call="project.portal_my_task_planned_hours_template"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-6" name="portal_my_task_second_column"></div>
|
||||
</div>
|
||||
|
||||
<div class="row" t-if="task.description or task.attachment_ids">
|
||||
<div t-if="not is_html_empty(task.description)" t-attf-class="col-12 col-lg-7 mb-4 mb-md-0 {{'col-lg-7' if task.attachment_ids else 'col-lg-12'}}">
|
||||
<hr class="mb-1"/>
|
||||
<div class="d-flex my-2">
|
||||
<strong>Description</strong>
|
||||
</div>
|
||||
<div class="py-1 px-2 bg-100 small table-responsive" t-field="task.description"/>
|
||||
</div>
|
||||
<div t-if="task.attachment_ids" t-attf-class="col-12 col-lg-5 o_project_portal_attachments {{'col-lg-5' if task.description else 'col-lg-12'}}">
|
||||
<hr class="mb-1 d-none d-lg-block"/>
|
||||
<strong class="d-block mb-2">Attachments</strong>
|
||||
<div class="row">
|
||||
<div t-attf-class="col {{'col-lg-6' if not task.description else 'col-lg-12'}}">
|
||||
<ul class="list-group">
|
||||
<a class="list-group-item list-group-item-action d-flex align-items-center oe_attachments py-1 px-2" t-foreach='task.attachment_ids' t-as='attachment' t-attf-href="/web/content/#{attachment.id}?download=true&access_token=#{attachment.access_token}" target="_blank" data-no-post-process="">
|
||||
<div class='oe_attachment_embedded o_image o_image_small me-2 me-lg-3' t-att-title="attachment.name" t-att-data-mimetype="attachment.mimetype" t-attf-data-src="/web/image/#{attachment.id}/50x40?access_token=#{attachment.access_token}"/>
|
||||
<div class='oe_attachment_name text-truncate'><t t-esc='attachment.name'/></div>
|
||||
</a>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt32" id="task_chat" data-anchor="true">
|
||||
<h4><strong>Message and communication history</strong></h4>
|
||||
<t t-call="portal.message_thread">
|
||||
<t t-set="token" t-value="task.access_token"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="portal_my_task_planned_hours_template">
|
||||
<strong>Allocated Hours:</strong> <span t-esc="task.planned_hours" t-options='{"widget": "float_time"}'/>
|
||||
</template>
|
||||
</odoo>
|
||||
|
|
@ -1,15 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="project_project_stage_view_tree" model="ir.ui.view">
|
||||
<field name="name">project.project.stage.view.tree</field>
|
||||
<field name="name">project.project.stage.view.list</field>
|
||||
<field name="model">project.project.stage</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree editable="bottom" sample="1">
|
||||
<list editable="bottom" sample="1" delete="0">
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="name"/>
|
||||
<field name="name" placeholder="e.g. To Do"/>
|
||||
<field name="mail_template_id" optional="hide" context="{'default_model': 'project.project'}"/>
|
||||
<field name="company_id" optional="hide" groups="base.group_multi_company" options="{'no_create': True}"/>
|
||||
<field name="color" optional="hide" widget="color_picker"/>
|
||||
<field name="fold" optional="show"/>
|
||||
</tree>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
|
@ -19,7 +21,7 @@
|
|||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="name" placeholder="e.g. To Do"/>
|
||||
<field name="mail_template_id"/>
|
||||
<field name="fold"/>
|
||||
</group>
|
||||
|
|
@ -31,18 +33,20 @@
|
|||
<field name="name">project.project.stage.view.form</field>
|
||||
<field name="model">project.project.stage</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<form delete="0">
|
||||
<sheet>
|
||||
<widget name="web_ribbon" title="Archived" bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}"/>
|
||||
<h1><field name="name" placeholder="New"/></h1>
|
||||
<widget name="web_ribbon" title="Archived" bg_color="text-bg-danger" invisible="active"/>
|
||||
<h1><field name="name" placeholder="e.g. To Do"/></h1>
|
||||
<group>
|
||||
<group>
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="mail_template_id" context="{'default_model': 'project.project'}"/>
|
||||
<field name="color" widget="color_picker"/>
|
||||
<field name="sequence" groups="base.group_no_one"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="fold"/>
|
||||
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}" placeholder="Visible to all"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
|
|
@ -54,16 +58,15 @@
|
|||
<field name="name">project.project.stage.view.kanban</field>
|
||||
<field name="model">project.project.stage</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban class="o_kanban_mobile" sample="1" quick_create_view="project.project_project_stage_view_form_quick_create">
|
||||
<field name="name"/>
|
||||
<field name="mail_template_id"/>
|
||||
<kanban highlight_color="color" class="o_kanban_mobile" sample="1" quick_create_view="project.project_project_stage_view_form_quick_create">
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div class="o_kanban_record oe_kanban_global_click">
|
||||
<strong><field name="name"/></strong>
|
||||
<br/>
|
||||
<span class="text-muted"><field name="mail_template_id"/></span>
|
||||
</div>
|
||||
<t t-name="menu" t-if="!selection_mode" groups="base.group_user">
|
||||
<field name="color" widget="kanban_color_picker"/>
|
||||
</t>
|
||||
<t t-name="card">
|
||||
<field name="name" class="fw-bolder mb-4"/>
|
||||
<field name="mail_template_id" class="text-muted mb-2" invisible="not mail_template_id"/>
|
||||
<field name="company_id" groups="base.group_multi_company" invisible="not company_id" class="mb-2"/>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
|
|
@ -77,7 +80,11 @@
|
|||
<search>
|
||||
<field name="name"/>
|
||||
<field name="mail_template_id"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
<filter string="Archived" name="archived" domain="[('active', '=', False)]"/>
|
||||
<group>
|
||||
<filter string="Company" name="company" context="{'group_by': 'company_id'}" groups="base.group_multi_company"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
|
@ -85,7 +92,8 @@
|
|||
<record id="project_project_stage_configure" model="ir.actions.act_window">
|
||||
<field name="name">Project Stages</field>
|
||||
<field name="res_model">project.project.stage</field>
|
||||
<field name="view_mode">tree,kanban,form</field>
|
||||
<field name="path">project-stages</field>
|
||||
<field name="view_mode">list,kanban,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No stages found. Let's create one!
|
||||
|
|
@ -97,7 +105,7 @@
|
|||
|
||||
<record id="project_project_stage_configure_view_tree" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="1"/>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_mode">list</field>
|
||||
<field name="view_id" ref="project_project_stage_view_tree"/>
|
||||
<field name="act_window_id" ref="project_project_stage_configure"/>
|
||||
</record>
|
||||
|
|
@ -115,4 +123,13 @@
|
|||
<field name="view_id" ref="project_project_stage_view_form"/>
|
||||
<field name="act_window_id" ref="project_project_stage_configure"/>
|
||||
</record>
|
||||
|
||||
<record id="unlink_project_stage_action" model="ir.actions.server">
|
||||
<field name="name">Delete</field>
|
||||
<field name="model_id" ref="project.model_project_project_stage"/>
|
||||
<field name="binding_model_id" ref="project.model_project_project_stage"/>
|
||||
<field name="binding_view_types">form,list,kanban</field>
|
||||
<field name="state">code</field>
|
||||
<field name="code">action = records.unlink_wizard(stage_view=True)</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,730 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="project_project_view_activity" model="ir.ui.view">
|
||||
<field name="name">project.project.view.activity</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="arch" type="xml">
|
||||
<activity string="Project" js_class="project_project_activity">
|
||||
<templates>
|
||||
<div t-name="activity-box" class="d-flex">
|
||||
<field name="user_id" widget="many2one_avatar_user"/>
|
||||
<field name="name" string="Project Name" class="flex-grow-1 o_text_block"/>
|
||||
</div>
|
||||
</templates>
|
||||
</activity>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_send_mail_project_project" model="ir.actions.act_window">
|
||||
<field name="name">Send Email</field>
|
||||
<field name="res_model">mail.compose.message</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
<field name="group_ids" eval="[(4, ref('project.group_project_manager'))]"/>
|
||||
<field name="context">{
|
||||
'default_composition_mode': 'mass_mail',
|
||||
}</field>
|
||||
<field name="binding_model_id" ref="project.model_project_project"/>
|
||||
<field name="binding_view_types">list,kanban</field>
|
||||
</record>
|
||||
|
||||
<record id="edit_project" model="ir.ui.view">
|
||||
<field name="name">project.project.form</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Project" class="o_form_project_project" js_class="project_project_form">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<header>
|
||||
<button name="action_open_share_project_wizard" string="Share Project" type="object" class="oe_highlight" groups="project.group_project_manager"
|
||||
invisible="privacy_visibility in ['followers', 'employees'] or is_template" context="{'default_access_mode': 'read'}" data-hotkey="r"/>
|
||||
<field name="stage_id" widget="statusbar_duration" options="{'clickable': '1', 'fold_field': 'fold'}" groups="project.group_project_stages" domain="[('company_id', 'in', (company_id, False))]"/>
|
||||
</header>
|
||||
<sheet string="Project">
|
||||
<div class="oe_button_box" name="button_box" groups="base.group_user">
|
||||
<button class="oe_stat_button" type="object" name="action_view_tasks" icon="fa-check">
|
||||
<div class="o_field_widget o_stat_info">
|
||||
<field name="label_tasks" readonly="1"/>
|
||||
<span class="o_stat_value">
|
||||
<field name="closed_task_count"/> / <field name="task_count"/>
|
||||
(<field name="task_completion_percentage" widget="percentage" options="{'digits': [1, 0]}"/>)
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
<button class="oe_stat_button" name="project_update_all_action" type="object" groups="project.group_project_user" context="{'active_id': id}" invisible="is_template">
|
||||
<field name="last_update_color" invisible="1"/>
|
||||
<div class="o_stat_info">
|
||||
<field name="update_count" invisible="1"/>
|
||||
<field name="last_update_status" readonly="1" widget="status_with_color" status_label="Dashboard" hideStatusName="True"/>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<widget name="web_ribbon" title="Archived" bg_color="text-bg-danger" invisible="active"/>
|
||||
<widget name="web_ribbon" title="Template" bg_color="text-bg-info" invisible="not (is_template and active)"/>
|
||||
|
||||
<div class="oe_title">
|
||||
<h1 class="d-flex flex-row">
|
||||
<field name="is_favorite" nolabel="1" widget="project_is_favorite" class="me-2" options="{'autosave': False}"/>
|
||||
<field name="name" options="{'line_breaks': False}" widget="text" class="o_text_overflow" placeholder="e.g. Office Party"/>
|
||||
</h1>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="label_tasks" string="Name of the Tasks" placeholder="e.g. Tasks"/>
|
||||
<field name="partner_id" widget="res_partner_many2one"/>
|
||||
<field name="tag_ids" widget="many2many_tags" options="{'color_field': 'color'}"/>
|
||||
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}" placeholder="Visible to all"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="user_id" string="Project Manager" widget="many2one_avatar_user" readonly="not active" domain="[('share', '=', False)]"/>
|
||||
<field name="date_start" string="Planned Date" widget="daterange" options='{"end_date_field": "date", "always_range": "1"}' required="date_start or date" />
|
||||
<field name="date" invisible="1" required="date_start"/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page name="description" string="Description">
|
||||
<field name="description" options="{'resizable': false}" placeholder="Project description..."/>
|
||||
</page>
|
||||
<page name="settings" string="Settings">
|
||||
<group>
|
||||
<group>
|
||||
<!-- Always display the whole alias in edit mode. It depends in read only -->
|
||||
<!-- Need to add alias_id in view for getting alias_domain_id by default -->
|
||||
<field name="alias_id" invisible="1"/>
|
||||
<label for="alias_name" string="Email Alias" invisible="is_template"/>
|
||||
<field name="alias_email" widget="email" readonly="1" nolabel="1" groups="!project.group_project_manager" invisible="is_template"/>
|
||||
<div class="d-inline-flex" groups="project.group_project_manager" invisible="is_template">
|
||||
<field name="alias_name" placeholder="alias"/>@
|
||||
<field name="alias_domain_id" placeholder="e.g. mycompany.com"
|
||||
options="{'no_create': True, 'no_open': True}"/>
|
||||
</div>
|
||||
<!-- the alias contact must appear when the user start typing and it must disappear
|
||||
when the string is deleted. -->
|
||||
<field name="alias_contact" class="oe_inline" string="Accept Emails From"
|
||||
invisible="not alias_email"/>
|
||||
<field name="privacy_visibility" widget="radio"/>
|
||||
<span colspan="2" class="text-muted o_row ps-1" invisible="access_instruction_message == ''">
|
||||
<i class="fa fa-lightbulb-o pe-2" title="Info"/><field class="d-inline" name="access_instruction_message" nolabel="1"/>
|
||||
</span>
|
||||
<span colspan="2" class="text-muted o_row ps-1" invisible="privacy_visibility_warning == ''">
|
||||
<i class="fa fa-warning pe-2" title="Warning"/><field class="d-inline" name="privacy_visibility_warning" nolabel="1"/>
|
||||
</span>
|
||||
</group>
|
||||
<group name="analytic" groups="analytic.group_analytic_accounting">
|
||||
<div class="o_flexible_margin_top o_horizontal_separator text-uppercase fw-bolder small mb-3" colspan="2">analytic</div>
|
||||
<field name="account_id"/>
|
||||
</group>
|
||||
<group name="extra_settings">
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<group name="group_tasks_managment" string="Tasks Management" col="1" class="row mt16 o_settings_container">
|
||||
<div>
|
||||
<setting class="col-lg-12" id="recurring_tasks_setting" help="Auto-generate tasks for regular activities">
|
||||
<field name="allow_recurring_tasks"/>
|
||||
</setting>
|
||||
<setting class="col-lg-12" id="task_dependencies_setting" help="Determine the order in which to perform tasks">
|
||||
<field name="allow_task_dependencies"/>
|
||||
</setting>
|
||||
<setting class="col-lg-12" id="project_milestone_setting" help="Track major progress points that must be reached to achieve success">
|
||||
<field name="allow_milestones"/>
|
||||
</setting>
|
||||
</div>
|
||||
</group>
|
||||
<group name="group_time_managment" string="Time Management" invisible="1" col="1" class="row mt16 o_settings_container"/>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
<chatter reload_on_follower="True"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_project_project_filter" model="ir.ui.view">
|
||||
<field name="name">project.project.select</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Project">
|
||||
<field name="name" string="Project"/>
|
||||
<field name="tag_ids"/>
|
||||
<field name="user_id" string="Project Manager"/>
|
||||
<field name="stage_id" groups="project.group_project_stages"/>
|
||||
<field name="partner_id" string="Customer" filter_domain="[('partner_id', 'child_of', self)]" invisible="context.get('default_is_template')"/>
|
||||
<field name="activity_user_id" string="Activities of"/>
|
||||
<field name="activity_type_id" string="Activity type"/>
|
||||
<filter string="My Projects" name="own_projects" domain="[('user_id', '=', uid)]" invisible="context.get('default_is_template')"/>
|
||||
<filter string="My Favorites" name="my_projects" domain="[('favorite_user_ids', 'in', uid)]"/>
|
||||
<filter string="Unassigned" name="unassigned_projects" domain="[('user_id', '=', False)]"/>
|
||||
<separator invisible="context.get('default_is_template')"/>
|
||||
<filter string="Late Milestones" name="late_milestones" domain="[('is_milestone_exceeded', '=', True)]" groups="project.group_project_milestone" invisible="context.get('default_is_template') or not context.get('allow_milestones', True)"/>
|
||||
<separator invisible="context.get('default_is_template')"/>
|
||||
<filter string="Start Date" name="start_date" date="date_start" end_month="1" end_year="1"/>
|
||||
<filter string="End Date" name="end_date" date="date" end_month="1" end_year="1"/>
|
||||
<separator/>
|
||||
<filter string="Templates" context="{'render_project_templates': True}" name="templates" domain="[('is_template', '=', True)]"
|
||||
invisible="not context.get('display_milestone_deadline')"/>
|
||||
<separator/>
|
||||
<filter string="Archived" name="inactive" domain="[('active', '=', False)]"/>
|
||||
<separator invisible="1"/>
|
||||
<filter invisible="1" string="My Activities" name="filter_activities_my"
|
||||
domain="[('activity_user_id', '=', uid)]"/>
|
||||
<separator/>
|
||||
<filter invisible="1" string="Late Activities" name="activities_overdue"
|
||||
domain="[('my_activity_date_deadline', '<', 'today')]"
|
||||
help="Show all records whose next activity date is past"/>
|
||||
<filter invisible="1" string="Today Activities" name="activities_today"
|
||||
domain="[('my_activity_date_deadline', '=', 'today')]"/>
|
||||
<filter invisible="1" string="Future Activities" name="activities_upcoming_all"
|
||||
domain="[('my_activity_date_deadline', '>', 'today')]"/>
|
||||
<group>
|
||||
<filter string="Project Manager" name="Manager" context="{'group_by': 'user_id'}"/>
|
||||
<filter string="Stage" name="groupby_stage" context="{'group_by': 'stage_id'}" groups="project.group_project_stages"/>
|
||||
<filter string="Status" name="status" context="{'group_by': 'last_update_status'}" invisible="context.get('default_is_template')"/>
|
||||
<filter string="Tags" name="tags" context="{'group_by': 'tag_ids'}"/>
|
||||
<filter string="Company" name="company" context="{'group_by': 'company_id'}" groups="base.group_multi_company"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_project" model="ir.ui.view">
|
||||
<field name="name">project.project.list</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="arch" type="xml">
|
||||
<list decoration-muted="active == False" string="Projects" multi_edit="1" sample="1" default_order="is_favorite desc, sequence, name, id" js_class="project_project_list">
|
||||
<field name="sequence" column_invisible="True"/>
|
||||
<field name="message_needaction" column_invisible="True"/>
|
||||
<field name="active" column_invisible="True"/>
|
||||
<field name="is_milestone_exceeded" column_invisible="True"/>
|
||||
<field name="can_mark_milestone_as_done" column_invisible="True"/>
|
||||
<field name="is_milestone_deadline_exceeded" column_invisible="1"/>
|
||||
<field name="allow_milestones" column_invisible="True"/>
|
||||
<field name="is_favorite" string="Favorite" nolabel="1" widget="project_is_favorite" optional="hide"/>
|
||||
<field name="name" class="fw-bold"/>
|
||||
<field name="partner_id" optional="show" string="Customer" invisible="is_template"/>
|
||||
<field name="company_id" optional="show" groups="base.group_multi_company" options="{'no_create': True, 'no_open': True}"/>
|
||||
<field name="company_id" column_invisible="True"/>
|
||||
<field name="date_start" string="Planned Date" widget="daterange" options="{'end_date_field': 'date', 'always_range': '1'}" optional="hide"/>
|
||||
<field name="date" column_invisible="True" />
|
||||
<field name="milestone_progress" widget="progressbar"
|
||||
invisible="milestone_progress == 0 or not allow_milestones or is_template"
|
||||
optional="hide"
|
||||
/>
|
||||
<field name="next_milestone_id"
|
||||
decoration-danger="is_milestone_deadline_exceeded" decoration-success="can_mark_milestone_as_done"
|
||||
optional="hide"
|
||||
invisible="not allow_milestones or is_template"
|
||||
/>
|
||||
<field name="user_id" optional="show" string="Project Manager" widget="many2one_avatar_user" options="{'no_open':True, 'no_create': True}"/>
|
||||
<field name="last_update_color" column_invisible="True"/>
|
||||
<field name="tag_ids" widget="many2many_tags" options="{'color_field': 'color'}" optional="hide"/>
|
||||
<field name="last_update_status" string="Status" nolabel="1" width="20px" optional="show" widget="project_state_selection" invisible="is_template"/>
|
||||
<field name="stage_id_color" column_invisible="1"/>
|
||||
<field name="stage_id" domain="[('company_id', 'in', (company_id, False))]" optional="show" widget="badge" options="{'no_open': True, 'color_field': 'stage_id_color'}" />
|
||||
<button string="View Tasks" name="action_view_tasks" type="object"/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_list_view_group_stage" model="ir.ui.view">
|
||||
<field name="name">project.project.list.group.stage</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="inherit_id" ref="view_project"/>
|
||||
<field name="mode">primary</field>
|
||||
<field name="arch" type="xml">
|
||||
<list position="attributes">
|
||||
<attribute name="default_group_by">stage_id</attribute>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_project_config" model="ir.ui.view">
|
||||
<field name="name">project.project.list.config</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="inherit_id" ref="project.view_project"/>
|
||||
<field name="mode">primary</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//list" position="attributes">
|
||||
<attribute name="default_order">sequence, name, id</attribute>
|
||||
</xpath>
|
||||
<field name="sequence" position="attributes">
|
||||
<attribute name="column_invisible">0</attribute>
|
||||
<attribute name="widget">handle</attribute>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_project_config_group_stage" model="ir.ui.view">
|
||||
<field name="name">project.project.list.config.group.stage</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="inherit_id" ref="view_project_config"/>
|
||||
<field name="mode">primary</field>
|
||||
<field name="arch" type="xml">
|
||||
<list position="attributes">
|
||||
<attribute name="default_group_by">stage_id</attribute>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="quick_create_project_form" model="ir.ui.view">
|
||||
<field name="name">project.form.quick_create</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="priority">1000</field>
|
||||
<field name="arch" type="xml">
|
||||
<form class="o_form_project_project">
|
||||
<group>
|
||||
<field name="name" string="Project Title" placeholder="e.g. Office Party"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_view_kanban" model="ir.ui.view">
|
||||
<field name="name">project.project.kanban</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban class="o_kanban_mobile">
|
||||
<templates>
|
||||
<t t-name="card">
|
||||
<field name="name" class="fw-bolder" string="Project Name"/>
|
||||
<div class="d-flex">
|
||||
<field name="partner_id" string="Contact"/>
|
||||
<field name="user_id" class="ms-auto" widget="many2one_avatar_user"/>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_project_view_form_simplified" model="ir.ui.view">
|
||||
<field name="name">project.project.view.form.simplified</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Project">
|
||||
<div class="oe_title mb-lg-3 mb-md-2">
|
||||
<label for="name" string="Name"/>
|
||||
<h1>
|
||||
<field name="name" class="o_project_name" placeholder="e.g. Office Party"/>
|
||||
</h1>
|
||||
</div>
|
||||
<field name="user_id" invisible="1"/>
|
||||
<div class="row o_settings_container"/>
|
||||
<div name="alias_def" class="mt-2" colspan="2">
|
||||
<label for="alias_name" string="Create tasks by email:"/>
|
||||
<span>
|
||||
<field name="alias_id" invisible="1"/>
|
||||
<field name="alias_name" placeholder="e.g. office-party"/>@
|
||||
<field name="alias_domain_id" class="oe_inline" placeholder="e.g. mycompany.com"
|
||||
options="{'no_create': True, 'no_open': True}"/>
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_project_view_form_simplified_footer" model="ir.ui.view">
|
||||
<field name="name">project.project.view.form.simplified</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="inherit_id" ref="project.project_project_view_form_simplified"/>
|
||||
<field name="mode">primary</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='alias_def']" position="after">
|
||||
<footer>
|
||||
<button string="Create project" name="action_view_tasks" type="object" class="btn-primary o_open_tasks" data-hotkey="q"/>
|
||||
<button string="Discard" class="btn-secondary" special="cancel" data-hotkey="x"/>
|
||||
</footer>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="open_create_project" model="ir.actions.act_window">
|
||||
<field name="name">Create a Project</field>
|
||||
<field name="res_model">project.project</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="project_project_view_form_simplified_footer"/>
|
||||
<field name="target">new</field>
|
||||
<field name="context">{"default_allow_billable": 0}</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_project_kanban">
|
||||
<field name="name">project.project.kanban</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban highlight_color="color"
|
||||
class="o_project_kanban"
|
||||
js_class="project_project_kanban"
|
||||
on_create="project.open_create_project"
|
||||
action="action_view_tasks" type="object"
|
||||
quick_create_view="project.quick_create_project_form"
|
||||
sample="1"
|
||||
default_order="is_favorite desc, sequence, name, id"
|
||||
>
|
||||
<field name="allow_milestones"/>
|
||||
<field name="rating_count" />
|
||||
<field name="show_ratings"/>
|
||||
<field name="privacy_visibility"/>
|
||||
<field name="last_update_color"/>
|
||||
<field name="is_milestone_deadline_exceeded"/>
|
||||
<field name="can_mark_milestone_as_done"/>
|
||||
<field name="is_template"/>
|
||||
<progressbar field="last_update_status" colors='{"on_track": "success", "at_risk": "warning", "off_track": "danger", "on_hold": "info", "done": "purple"}'/>
|
||||
<field name="sequence" widget="handle"/>
|
||||
<templates>
|
||||
<t t-name="menu" groups="base.group_user">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div name="card_menu_view" class="col-6">
|
||||
<h5 role="menuitem" class="o_kanban_card_manage_title">
|
||||
<span>View</span>
|
||||
</h5>
|
||||
<div role="menuitem">
|
||||
<a name="action_view_tasks" type="object">Tasks</a>
|
||||
</div>
|
||||
<div role="menuitem" groups="project.group_project_milestone" t-if="record.allow_milestones.raw_value and !record.is_template.raw_value">
|
||||
<a name="action_get_list_view" type="object">Milestones</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 o_kanban_manage_reporting" t-if="!record.is_template.raw_value">
|
||||
<h5 role="menuitem" class="o_kanban_card_manage_title" groups="project.group_project_user">
|
||||
<span>Reporting</span>
|
||||
</h5>
|
||||
<div class="d-inline-block" role="menuitem" groups="project.group_project_user" name="task_analysis">
|
||||
<a name="action_view_tasks_analysis" type="object">Tasks Analysis</a>
|
||||
</div>
|
||||
<div class="d-inline-block" role="menuitem" name="project_burndown_menu" groups="project.group_project_user">
|
||||
<a name="action_project_task_burndown_chart_report" type="object">Burndown Chart</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="o_kanban_card_manage_settings row">
|
||||
<div role="menuitem" aria-haspopup="true" class="col-6" groups="project.group_project_manager">
|
||||
<field name="color" widget="kanban_color_picker"/>
|
||||
</div>
|
||||
<div role="menuitem" class="col-6" groups="project.group_project_manager">
|
||||
|
||||
<a t-if="['portal', 'invited_users'].includes(record.privacy_visibility.raw_value) and !record.is_template.raw_value" class="dropdown-item" role="menuitem" name="action_open_share_project_wizard" type="object">Share Project</a>
|
||||
|
||||
<a class="dropdown-item" role="menuitem" name="copy" type="object">Duplicate</a>
|
||||
<a class="dropdown-item" role="menuitem" type="open">Settings</a>
|
||||
</div>
|
||||
<div class="col-12 ps-0" groups="!project.group_project_manager">
|
||||
<div role="menuitem" class="w-100">
|
||||
<a class="dropdown-item mx-0" role="menuitem" type="open">View</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="card">
|
||||
<main class="o_project_kanban_main">
|
||||
<div class="d-flex align-items-baseline gap-1">
|
||||
<field name="is_favorite" widget="project_is_favorite" nolabel="1"/>
|
||||
<span class="text-truncate d-block fs-4 fw-bold" t-att-title="record.display_name.value"><field name="display_name"/></span>
|
||||
</div>
|
||||
<div class="o_project_kanban_body min-w-0 pb-4 me-2">
|
||||
<span name="partner_name" class="text-muted d-flex align-items-baseline" t-if="record.partner_id.value">
|
||||
<span class="fa fa-user me-2" aria-label="Partner" title="Partner"></span><field class="text-truncate" name="partner_id"/>
|
||||
</span>
|
||||
<div t-if="record.date.raw_value or record.date_start.raw_value" class="text-muted d-flex align-items-baseline">
|
||||
<span class="fa fa-clock-o me-2" title="Dates"/>
|
||||
<field name="date_start" widget="daterange" options="{'end_date_field': 'date'}"/>
|
||||
</div>
|
||||
<div t-if="record.alias_email.value" class="text-muted text-truncate" t-att-title="record.alias_email.value">
|
||||
<span class="fa fa-envelope-o me-2" aria-label="Domain Alias" title="Domain Alias"></span><field name="alias_email"/>
|
||||
</div>
|
||||
<div t-if="record.show_ratings.raw_value and record.rating_count.raw_value > 0" class="d-flex text-muted">
|
||||
<b class="me-1">
|
||||
<span class="fa mt4 fa-smile-o fw-bolder text-success" t-if="record.rating_avg.raw_value >= 3.66" title="Average Rating: Happy" role="img" aria-label="Happy face"/>
|
||||
<span class="fa mt4 fa-meh-o fw-bolder text-warning" t-elif="record.rating_avg.raw_value >= 2.33" title="Average Rating: Neutral" role="img" aria-label="Neutral face"/>
|
||||
<span class="fa mt4 fa-frown-o fw-bolder text-danger" t-else="" title="Average Rating: Unhappy" role="img" aria-label="Unhappy face"/>
|
||||
</b>
|
||||
<t t-if="record.rating_avg.raw_value % 1 == 0">
|
||||
<field name="rating_avg" nolabel="1" widget="float" digits="[1, 0]"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<field name="rating_avg" nolabel="1" widget="float" digits="[1, 1]"/>
|
||||
</t> / 5
|
||||
</div>
|
||||
<field name="tag_ids" widget="many2many_tags" options="{'color_field': 'color'}"/>
|
||||
</div>
|
||||
</main>
|
||||
<footer class="mt-auto pt-0">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="o_project_kanban_boxes d-flex align-items-baseline">
|
||||
<a class="o_project_kanban_box me-1" name="action_view_tasks" type="object">
|
||||
<div>
|
||||
<field name="open_task_count" class="o_value"/>
|
||||
<field name="label_tasks" class="ms-1"/>
|
||||
</div>
|
||||
</a>
|
||||
<a groups='project.group_project_milestone' t-if="record.allow_milestones and record.allow_milestones.raw_value and record.milestone_count.raw_value > 0"
|
||||
t-attf-class="d-inline-block small me-1 text-{{ record.is_milestone_deadline_exceeded.raw_value ? 'danger' : (record.can_mark_milestone_as_done.raw_value ? 'success' : 'muted') }}"
|
||||
role="button"
|
||||
name="action_get_list_view"
|
||||
type="object"
|
||||
t-attf-title="#{record.milestone_count_reached.value} Milestones reached out of #{record.milestone_count.value}"
|
||||
>
|
||||
<span class="fa fa-flag me-1"/>
|
||||
<field name="milestone_count_reached"/>/<field name="milestone_count"/>
|
||||
</a>
|
||||
</div>
|
||||
<field name="activity_ids" widget="kanban_activity" class="ms-2"/>
|
||||
</div>
|
||||
<div class="d-flex ms-auto align-items-center">
|
||||
<field name="user_id" widget="many2one_avatar_user" domain="[('share', '=', False)]" class="me-1"/>
|
||||
<field t-if="record.last_update_status.value && widget.editable && !record.is_template.raw_value" name="last_update_status" widget="project_state_selection"/>
|
||||
<span t-if="record.last_update_status.value && !widget.editable" t-att-class="'o_status_bubble mx-0 o_color_bubble_' + record.last_update_color.value" t-att-title="record.last_update_status.value"></span>
|
||||
</div>
|
||||
</footer>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_kanban_view_group_stage" model="ir.ui.view">
|
||||
<field name="name">project.project.kanban.group.stage</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="mode">primary</field>
|
||||
<field name="inherit_id" ref="view_project_kanban"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//kanban" position="attributes">
|
||||
<attribute name="default_group_by">stage_id</attribute>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_project_config_kanban" model="ir.ui.view">
|
||||
<field name="name">project.kanban.inherit.config.project</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="mode">primary</field>
|
||||
<field name="inherit_id" ref="view_project_kanban"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//kanban" position="attributes">
|
||||
<attribute name="action"></attribute>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_project_config_kanban_group_stage" model="ir.ui.view">
|
||||
<field name="name">project.kanban.inherit.config.project.group.stage</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="mode">primary</field>
|
||||
<field name="inherit_id" ref="view_project_config_kanban"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//kanban" position="attributes">
|
||||
<attribute name="default_group_by">stage_id</attribute>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_project_calendar" model="ir.ui.view">
|
||||
<field name="name">project.project.calendar</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="arch" type="xml">
|
||||
<calendar
|
||||
date_start="date_start"
|
||||
date_stop="date"
|
||||
string="Projects"
|
||||
mode="month"
|
||||
scales="month,year"
|
||||
event_open_popup="true"
|
||||
quick_create="0"
|
||||
color="stage_id_color"
|
||||
js_class="project_project_calendar">
|
||||
<field name="partner_id" invisible="not partner_id"/>
|
||||
<field name="user_id" widget="many2one_avatar_user" invisible="not user_id"/>
|
||||
<field name="is_favorite" widget="project_is_favorite" nolabel="1" string="Favorite"/>
|
||||
<field name="stage_id_color" invisible="1"/>
|
||||
<field name="stage_id" groups="project.group_project_stages" invisible="not stage_id"/>
|
||||
<field name="last_update_color" invisible="1"/>
|
||||
<field name="last_update_status" string="Status" widget="status_with_color" invisible="last_update_status == 'to_define'"/>
|
||||
<field name="tag_ids" widget="many2many_tags" options="{'color_field': 'color'}" invisible="not tag_ids"/>
|
||||
</calendar>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Please update both act_window when modifying one (open_view_project_all or open_view_project_all_group_stage) as one or the other is used in the menu menu_project -->
|
||||
<record id="open_view_project_all" model="ir.actions.act_window">
|
||||
<field name="name">Projects</field>
|
||||
<field name="path">project</field>
|
||||
<field name="res_model">project.project</field>
|
||||
<field name="domain">[("is_template", "=", False)]</field>
|
||||
<field name="context">{'display_milestone_deadline': True}</field>
|
||||
<field name="view_mode">kanban,list,form</field>
|
||||
<field name="view_id" ref="view_project_kanban"/>
|
||||
<field name="search_view_id" ref="view_project_project_filter"/>
|
||||
<field name="target">current</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No projects found. Let's create one!
|
||||
</p>
|
||||
<p>
|
||||
Create projects to organize your tasks. Define a different workflow for each project.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Please update both act_window when modifying one (open_view_project_all or open_view_project_all_group_stage) as one or the other is used in the menu menu_project -->
|
||||
<record id="open_view_project_all_group_stage" model="ir.actions.act_window">
|
||||
<field name="name">Projects</field>
|
||||
<field name="res_model">project.project</field>
|
||||
<field name="context">{'display_milestone_deadline': True}</field>
|
||||
<field name="domain">[("is_template", "=", False)]</field>
|
||||
<field name="view_mode">kanban,list,form,calendar,activity</field>
|
||||
<field name="view_id" ref="view_project_kanban"/>
|
||||
<field name="search_view_id" ref="view_project_project_filter"/>
|
||||
<field name="target">main</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No projects found. Let's create one!
|
||||
</p>
|
||||
<p>
|
||||
Projects contain tasks on the same topic, and each has its own dashboard.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="open_view_project_all_group_stage_kanban_view" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view_mode">kanban</field>
|
||||
<field name="act_window_id" ref="open_view_project_all_group_stage"/>
|
||||
<field name="view_id" ref="project_kanban_view_group_stage"/>
|
||||
</record>
|
||||
<record id="open_view_project_all_group_stage_tree_view" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="20"/>
|
||||
<field name="view_mode">list</field>
|
||||
<field name="act_window_id" ref="open_view_project_all_group_stage"/>
|
||||
<field name="view_id" ref="project_list_view_group_stage"/>
|
||||
</record>
|
||||
|
||||
<!-- Please update both act_window when modifying one (open_view_project_all_config or open_view_project_all_config_group_stage) as one or the other is used in the menu menu_project_config -->
|
||||
<record id="open_view_project_all_config" model="ir.actions.act_window">
|
||||
<field name="name">Projects</field>
|
||||
<field name="res_model">project.project</field>
|
||||
<field name="path">project-configuration</field>
|
||||
<field name="domain">[('is_template', '=', False)]</field>
|
||||
<field name="view_mode">list,kanban,form</field>
|
||||
<field name="view_ids" eval="[(5, 0, 0),
|
||||
(0, 0, {'view_mode': 'list', 'view_id': ref('view_project_config')}),
|
||||
(0, 0, {'view_mode': 'kanban', 'view_id': ref('view_project_config_kanban')})]"/>
|
||||
<field name="search_view_id" ref="view_project_project_filter"/>
|
||||
<field name="context">{'display_milestone_deadline': True}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No projects found. Let's create one!
|
||||
</p>
|
||||
<p>
|
||||
Create projects to organize your tasks and define a different workflow for each project.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Please update both act_window when modifying one (open_view_project_all_config or open_view_project_all_config_group_stage) as one or the other is used in the menu menu_project_config -->
|
||||
<record id="open_view_project_all_config_group_stage" model="ir.actions.act_window">
|
||||
<field name="name">Projects</field>
|
||||
<field name="res_model">project.project</field>
|
||||
<field name="domain">[('is_template', '=', False)]</field>
|
||||
<field name="view_mode">list,kanban,form,calendar,activity</field>
|
||||
<field name="search_view_id" ref="view_project_project_filter"/>
|
||||
<field name="context">{'display_milestone_deadline': True}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No projects found. Let's create one!
|
||||
</p>
|
||||
<p>
|
||||
Projects contain tasks on the same topic, and each has its own dashboard.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="open_view_project_all_config_group_stage_tree_action_view" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view_mode">list</field>
|
||||
<field name="act_window_id" ref="project.open_view_project_all_config_group_stage"/>
|
||||
<field name="view_id" ref="view_project_config_group_stage"/>
|
||||
</record>
|
||||
<record id="open_view_project_all_config_group_stage_kanban_action_view" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="20"/>
|
||||
<field name="view_mode">kanban</field>
|
||||
<field name="act_window_id" ref="project.open_view_project_all_config_group_stage"/>
|
||||
<field name="view_id" ref="view_project_config_kanban_group_stage"/>
|
||||
</record>
|
||||
|
||||
<record id="project_view_kanban_inherit_project" model="ir.ui.view">
|
||||
<field name="name">project.kanban.inherit.project</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="inherit_id" ref="project.view_project_kanban"/>
|
||||
<field name="priority">200</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="/kanban" position="inside">
|
||||
<field name="id"/>
|
||||
</xpath>
|
||||
<xpath expr="//div[@name='task_analysis']" position="before">
|
||||
<div role="menuitem" groups="project.group_project_user">
|
||||
<a name="project_update_all_action" type="object" t-attf-context="{'active_id': #{record.id.raw_value} }">Dashboard</a>
|
||||
</div>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_templates_view_form" model="ir.ui.view">
|
||||
<field name="name">project.project.template.form</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="inherit_id" ref="project.edit_project"/>
|
||||
<field name="mode">primary</field>
|
||||
<field name="arch" type="xml">
|
||||
<form position="attributes">
|
||||
<attribute name="js_class"></attribute>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_templates_view_list" model="ir.ui.view">
|
||||
<field name="name">project.project.template.list</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="inherit_id" ref="project.view_project"/>
|
||||
<field name="mode">primary</field>
|
||||
<field name="arch" type="xml">
|
||||
<list position="attributes">
|
||||
<attribute name="js_class"></attribute>
|
||||
<attribute name="default_order">sequence, is_favorite desc, name, id</attribute>
|
||||
</list>
|
||||
<field name="sequence" position="attributes">
|
||||
<attribute name="column_invisible">False</attribute>
|
||||
<attribute name="widget">handle</attribute>
|
||||
</field>
|
||||
<field name="partner_id" position="replace"/>
|
||||
<field name="next_milestone_id" position="replace"/>
|
||||
<field name="milestone_progress" position="replace"/>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_templates_view_kanban" model="ir.ui.view">
|
||||
<field name="name">project.project.template.kanban</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="inherit_id" ref="project.view_project_kanban"/>
|
||||
<field name="mode">primary</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban position="attributes">
|
||||
<attribute name="js_class"></attribute>
|
||||
</kanban>
|
||||
<span name="partner_name" position="replace"/>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_server_convert_project_to_template" model="ir.actions.server">
|
||||
<field name="name">Convert to Template</field>
|
||||
<field name="model_id" ref="project.model_project_project"/>
|
||||
<field name="binding_model_id" ref="project.model_project_project"/>
|
||||
<field name="binding_view_types">form</field>
|
||||
<field name="group_ids" eval="[Command.link(ref('project.group_project_manager'))]"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">
|
||||
action = record.action_toggle_project_template_mode()
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="project_role_view_list" model="ir.ui.view">
|
||||
<field name="name">project.role.list</field>
|
||||
<field name="model">project.role</field>
|
||||
<field name="arch" type="xml">
|
||||
<list editable="bottom" multi_edit="1">
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="name" placeholder="e.g. Developer"/>
|
||||
<field name="color" widget="color_picker" optional="show"/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_role_view_form" model="ir.ui.view">
|
||||
<field name="name">project.role.form</field>
|
||||
<field name="model">project.role</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<sheet>
|
||||
<widget name="web_ribbon" title="Archived" bg_color="text-bg-danger" invisible="active"/>
|
||||
<group>
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="name"/>
|
||||
<field name="color" widget="color_picker"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_role_view_kanban" model="ir.ui.view">
|
||||
<field name="name">project.role.kanban</field>
|
||||
<field name="model">project.role</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban highlight_color="color">
|
||||
<templates>
|
||||
<t t-name="menu">
|
||||
<a t-if="widget.editable" role="menuitem" type="open" class="dropdown-item">Edit</a>
|
||||
<a t-if="widget.deletable" role="menuitem" type="delete" class="dropdown-item">Delete</a>
|
||||
<field name="color" widget="kanban_color_picker"/>
|
||||
</t>
|
||||
<t t-name="card">
|
||||
<field name="name" class="fw-bold fs-4 ms-1"/>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_role_view_search" model="ir.ui.view">
|
||||
<field name="name">project.role.search</field>
|
||||
<field name="model">project.role</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="name"/>
|
||||
<filter name="archived" string="Archived" domain="[('active', '=', False)]"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_roles_action" model="ir.actions.act_window">
|
||||
<field name="name">Project Roles</field>
|
||||
<field name="res_model">project.role</field>
|
||||
<field name="view_mode">list,kanban,form</field>
|
||||
<field name="search_view_id" ref="project_role_view_search"/>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No project role found. Let's create one!
|
||||
</p>
|
||||
<p>
|
||||
Assign roles to tasks in your project templates.
|
||||
When creating a new project from the template, choose who will take on each role.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_roles_action_list" model="ir.actions.act_window.view">
|
||||
<field name="act_window_id" ref="project_roles_action"/>
|
||||
<field name="view_mode">list</field>
|
||||
<field name="view_id" ref="project.project_role_view_list"/>
|
||||
</record>
|
||||
|
||||
<record id="project_roles_action_kanban" model="ir.actions.act_window.view">
|
||||
<field name="act_window_id" ref="project_roles_action"/>
|
||||
<field name="view_mode">kanban</field>
|
||||
<field name="view_id" ref="project.project_role_view_kanban"/>
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="project_sharing_portal" name="Project Sharing View Embed">
|
||||
<t t-call="web.layout">
|
||||
<t t-set="head_project_sharing">
|
||||
<script type="text/javascript">
|
||||
odoo.__session_info__ = <t t-out="json.dumps(session_info)"/>;
|
||||
// Prevent the menu_service to load anything. In an ideal world, Project Sharing assets would only contain
|
||||
// what is genuinely necessary, and not the whole backend.
|
||||
odoo.loadMenusPromise = Promise.resolve();
|
||||
</script>
|
||||
<base target="_parent"/>
|
||||
<t t-call-assets="project.webclient"/>
|
||||
<t t-call="web.conditional_assets_tests">
|
||||
<t t-set="ignore_missing_deps" t-value="True"/>
|
||||
</t>
|
||||
</t>
|
||||
<t t-set="head" t-value="head_project_sharing + (head or '')"/>
|
||||
<t t-set="body_classname" t-value="'o_web_client o_project_sharing'"/>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,482 @@
|
|||
<?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="group_ids" 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="group_ids" eval="[(4, ref('base.group_portal')), (4, ref('base.group_user'))]"/>
|
||||
<field name="arch" type="xml">
|
||||
<kanban
|
||||
highlight_color="color"
|
||||
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"
|
||||
groups_draggable="0"
|
||||
group_edit="0"
|
||||
default_order="priority desc, sequence, state, date_deadline asc, id desc"
|
||||
>
|
||||
<field name="state"/>
|
||||
<field name="allow_milestones" />
|
||||
<field name="has_late_and_unreached_milestone"/>
|
||||
<progressbar field="state" colors='{"1_done": "success-done", "1_canceled": "danger", "03_approved": "success", "02_changes_requested": "warning", "04_waiting_normal": "info", "01_in_progress": "200"}'/>
|
||||
<templates>
|
||||
<t t-name="menu" t-if="!selection_mode">
|
||||
<div role="separator" class="dropdown-divider"></div>
|
||||
<field name="color" widget="kanban_color_picker"/>
|
||||
</t>
|
||||
<t t-name="card">
|
||||
<div t-att-class="{'opacity-50': ['1_done', '1_canceled'].includes(record.state.raw_value)}">
|
||||
<field name="name" class="fw-bolder fs-5" widget="name_with_subtask_count"/>
|
||||
<field name="project_id" invisible="context.get('default_project_id', False)" required="1" class="text-muted"/>
|
||||
<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 and !record.state.raw_value.startsWith('1_') ? 'text-danger' : ''}}">
|
||||
<field name="milestone_id" class="text-muted"/>
|
||||
</span>
|
||||
<field t-if="record.partner_id.value" name="partner_id" class="text-truncate text-muted d-block"/>
|
||||
</div>
|
||||
<field name="tag_ids" widget="many2many_tags" options="{'color_field': 'color'}" context="{'project_id': project_id}"/>
|
||||
<field t-if="record.date_deadline.raw_value" name="date_deadline" invisible="state in ['1_done', '1_canceled']" widget="remaining_days"/>
|
||||
<field t-if="record.displayed_image_id.value" groups="base.group_user" name="displayed_image_id" widget="attachment_image"/>
|
||||
<footer t-if="!selection_mode">
|
||||
<field name="priority" class="pt-1" widget="priority"/>
|
||||
<div class="d-flex ms-auto text-truncate">
|
||||
<span t-if="record.portal_user_names.raw_value.length > 0" class="pe-2 text-truncate" 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>
|
||||
<field t-else="" name="portal_user_names"/>
|
||||
</span>
|
||||
<field name="state" widget="project_task_state_selection" options="{'is_toggle_mode': false}"/>
|
||||
</div>
|
||||
</footer>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_sharing_project_task_view_tree" model="ir.ui.view">
|
||||
<field name="name">project.sharing.project.task.list</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">
|
||||
<list position="attributes">
|
||||
<attribute name="delete">0</attribute>
|
||||
<attribute name="import">0</attribute>
|
||||
<attribute name="group_create">0</attribute>
|
||||
<attribute name="default_group_by">stage_id</attribute>
|
||||
</list>
|
||||
<xpath expr="//field[@widget='res_partner_many2one']" position="attributes">
|
||||
<attribute name="widget">many2one</attribute>
|
||||
</xpath>
|
||||
<field name="user_ids" position="replace">
|
||||
<field name="portal_user_names" string="Assignees"/>
|
||||
</field>
|
||||
<xpath expr="//field[@name='milestone_id']" position="attributes">
|
||||
<attribute name="column_invisible">not context.get('allow_milestones', True)</attribute>
|
||||
</xpath>
|
||||
<field name="partner_id" position="attributes">
|
||||
<attribute name="column_invisible">0</attribute>
|
||||
</field>
|
||||
<field name="is_rotting" position="replace"/>
|
||||
<field name="rotting_days" position="replace"/>
|
||||
<field name="stage_id" position="attributes">
|
||||
<attribute name="widget">selection_badge</attribute>
|
||||
</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="group_ids" 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>
|
||||
<field name="stage_id" widget="statusbar_duration" options="{'clickable': '1', 'fold_field': 'fold'}" invisible="not project_id and not stage_id" />
|
||||
</header>
|
||||
<div groups="base.group_user" role="status" class="alert alert-info alert-dismissible rounded-0 fade show d-print-none css_editable_mode_hidden">
|
||||
<div class="text-center">This is a preview of how the project will look when it's shared with customers and they have editing access.
|
||||
<a name="action_redirect_to_project_task_form" type="object"><i class="oi oi-arrow-right me-1"/>Back to edit mode</a>
|
||||
</div>
|
||||
</div>
|
||||
<sheet string="Task">
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<field name="display_parent_task_button" invisible="1"/>
|
||||
<field name="recurrence_id" invisible="1" />
|
||||
<button name="action_project_sharing_view_parent_task" type="object" class="oe_stat_button" icon="fa-tasks" invisible="not display_parent_task_button">
|
||||
<div class="o_stat_info">
|
||||
<span class="o_stat_text">Parent Task</span>
|
||||
</div>
|
||||
</button>
|
||||
<button name="action_project_sharing_recurring_tasks" type="object" invisible="not active or not recurrence_id or not allow_recurring_tasks"
|
||||
class="oe_stat_button" icon="fa-repeat" context="{'default_user_ids': [(6, 0, [uid])]}">
|
||||
<field name="recurring_count" widget="statinfo" string="Recurring Tasks"/>
|
||||
</button>
|
||||
<button name="action_project_sharing_open_subtasks" type="object" class="oe_stat_button" icon="fa-check"
|
||||
invisible="not id or subtask_count == 0" context="{
|
||||
'default_user_ids': [(6, 0, [uid])],
|
||||
'default_project_id': project_id,
|
||||
}"
|
||||
>
|
||||
<field name="subtask_count" widget="statinfo" string="Sub-tasks"/>
|
||||
<field name="display_in_project" invisible="True"/>
|
||||
</button>
|
||||
<button name="action_project_sharing_open_blocking" type="object" invisible="not dependent_tasks_count or not allow_task_dependencies" class="oe_stat_button" icon="fa-tasks">
|
||||
<div class="o_field_widget o_stat_info">
|
||||
<span class="o_stat_text">Blocked Tasks</span>
|
||||
<span class="o_stat_value ">
|
||||
<field name="dependent_tasks_count" widget="statinfo" nolabel="1" />
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<widget name="web_ribbon" title="Archived" bg_color="text-bg-danger" invisible="active"/>
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<h1 class="d-flex w-100">
|
||||
<field name="name" options="{'line_breaks': False}" widget="text" class="o_task_name text-truncate w-md-75 w-100 pe-2" placeholder="Task Title..."/>
|
||||
</h1>
|
||||
<div class="d-flex justify-content-end align-items-center px-1" invisible="not active or is_template">
|
||||
<field name="priority" class="h3 pe-2" widget="priority"/>
|
||||
<field name="state" widget="project_task_state_selection" class="o_task_state_widget" />
|
||||
</div>
|
||||
<div class="d-flex justify-content-start align-items-center w-100 w-md-50 w-lg-25" invisible="active and not is_template">
|
||||
<field name="priority" class="h3 pe-2" widget="priority"/>
|
||||
<field name="state" widget="project_task_state_selection" class="o_task_state_widget" />
|
||||
</div>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="project_id" invisible="1"/>
|
||||
<field name="allow_milestones" invisible="1"/>
|
||||
<field name="milestone_id"
|
||||
placeholder="e.g. Product Launch"
|
||||
invisible="not allow_milestones"
|
||||
readonly="1"
|
||||
options="{'no_open': True}"/>
|
||||
<field name="user_ids" invisible="1" />
|
||||
<field name="portal_user_names"
|
||||
string="Assignees"
|
||||
class="o_task_user_field"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="parent_id" invisible="1" />
|
||||
<field name="company_id" invisible="1" />
|
||||
<field name="state" invisible="1" />
|
||||
<field name="depend_on_count" invisible="1" />
|
||||
<field name="allow_task_dependencies" invisible="1" />
|
||||
<field name="current_user_same_company_partner" invisible="1"/>
|
||||
<field name="tag_ids" context="{'project_id': project_id}" widget="many2many_tags" options="{'color_field': 'color', 'no_create': True, 'no_edit': True, 'no_edit_color': True}"/>
|
||||
<field name="partner_id" readonly="not current_user_same_company_partner" options="{'no_open': True, 'no_create': True, 'no_edit': True}" invisible="not project_id"/>
|
||||
<field name="date_deadline" decoration-danger="date_deadline < current_date and state not in ['1_done', '1_canceled']"/>
|
||||
<field name="recurring_task" invisible="not allow_recurring_tasks or not active or parent_id" groups="project.group_project_recurring_tasks"/>
|
||||
<label for="repeat_interval" invisible="not recurring_task or not allow_recurring_tasks" groups="project.group_project_recurring_tasks"/>
|
||||
<div invisible="not recurring_task or not allow_recurring_tasks" class="d-flex" groups="project.group_project_recurring_tasks" name="repeat_intervals">
|
||||
<field name="repeat_interval" required="recurring_task"
|
||||
class="me-2" style="max-width: 2rem !important;" />
|
||||
<field name="repeat_unit" required="recurring_task"
|
||||
class="me-2" style="max-width: 4rem !important;" />
|
||||
<field name="repeat_type" required="recurring_task"
|
||||
class="me-2" style="max-width: 15rem !important;" />
|
||||
<field name="repeat_until" invisible="not repeat_type == 'until'" required="repeat_type == 'until'"
|
||||
class="me-2" />
|
||||
</div>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page name="description_page" string="Description">
|
||||
<field name="description" type="html" placeholder="Add details about this task..."
|
||||
options="{'collaborative': true, 'allowAttachmentCreation': false, 'allowVideo': false}"/>
|
||||
</page>
|
||||
<page name="sub_tasks_page" string="Sub-tasks">
|
||||
<field name="child_ids" context="{
|
||||
'default_project_id': project_id, 'default_parent_id': id,
|
||||
'default_milestone_id': allow_milestones and milestone_id, 'default_partner_id': partner_id,
|
||||
'form_view_ref' : 'project.project_sharing_project_task_view_form',
|
||||
}">
|
||||
<list editable="bottom" decoration-muted="state in ['1_done','1_canceled']">
|
||||
<field name="project_id" column_invisible="True"/>
|
||||
<field name="display_in_project" column_invisible="True"/>
|
||||
<field name="state" column_invisible="True"/>
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="state" widget="project_task_state_selection" nolabel="1" width="20px"/>
|
||||
<field name="subtask_count" column_invisible="1"/>
|
||||
<field name="closed_subtask_count" column_invisible="1"/>
|
||||
<field name="name" widget="name_with_subtask_count"/>
|
||||
<field name="allow_milestones" column_invisible="True"/>
|
||||
<field name="milestone_id"
|
||||
optional="hide"
|
||||
options="{'no_open': True}"
|
||||
readonly="1"
|
||||
column_invisible="not parent.allow_milestones"
|
||||
invisible="not allow_milestones"/>
|
||||
<field name="company_id" column_invisible="True"/>
|
||||
<field name="partner_id" options="{'no_open': True, 'no_create': True, 'no_edit': True}" optional="hide"/>
|
||||
<field name="user_ids" column_invisible="True" />
|
||||
<field name="portal_user_names" string="Assignees" optional="show"/>
|
||||
<field name="date_deadline" decoration-danger="date_deadline < current_date and state not in ['1_done', '1_canceled']" optional="show"/>
|
||||
<field name="priority" widget="priority" optional="show" nolabel="1" width="20px"/>
|
||||
<field name="tag_ids" widget="many2many_tags" options="{'color_field': 'color'}" optional="hide"/>
|
||||
<field name="stage_id" domain="[('user_id', '=', False), ('project_ids', 'in', [project_id])]"/>
|
||||
<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', 'search_view_ref': 'project.project_sharing_project_task_view_search'}"
|
||||
invisible="project_id != context.get('active_id')"/>
|
||||
</list>
|
||||
</field>
|
||||
</page>
|
||||
<page name="task_dependencies" string="Blocked By" invisible="not allow_task_dependencies">
|
||||
<field name="depend_on_ids" widget="depend_on_ids_one2many" nolabel="1" options="{'link': false}" readonly="1"
|
||||
context="{
|
||||
'depend_on_count': depend_on_count,
|
||||
'list_view_ref': 'project.open_view_blocked_by_list_view',
|
||||
'search_view_ref': 'project.project_sharing_project_task_view_search',
|
||||
'search_default_project_id': project_id,
|
||||
}">
|
||||
<list editable="bottom" decoration-muted="state in ['1_done','1_canceled']">
|
||||
<field name="project_id" column_invisible="True"/>
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="state" widget="project_task_state_selection" nolabel="1" width="20px" readonly="1"/>
|
||||
<field name="subtask_count" column_invisible="1"/>
|
||||
<field name="closed_subtask_count" column_invisible="1"/>
|
||||
<field name="name" widget="name_with_subtask_count"/>
|
||||
<field name="allow_milestones" column_invisible="True"/>
|
||||
<field name="milestone_id"
|
||||
optional="hide"
|
||||
context="{'default_project_id': project_id}"
|
||||
invisible="not allow_milestones"
|
||||
column_invisible="not parent.allow_milestones"
|
||||
/>
|
||||
<field name="company_id" column_invisible="True"/>
|
||||
<field name="partner_id" options="{'no_open': True, 'no_create': True, 'no_edit': True}" optional="hide" invisible="not project_id"/>
|
||||
<field name="portal_user_names" string="Assignees" optional="show"/>
|
||||
<field name="date_deadline" decoration-danger="date_deadline < current_date and state not in ['1_done', '1_canceled']" optional="show"/>
|
||||
<field name="priority" widget="priority" optional="show" nolabel="1" width="20px" readonly="1"/>
|
||||
<field name="tag_ids" widget="many2many_tags" options="{'color_field': 'color'}" optional="hide"/>
|
||||
<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'}"
|
||||
invisible="project_id != context.get('active_id')"/>
|
||||
</list>
|
||||
</field>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
<!-- field used inside the chatter to know if the portal user is follower or not -->
|
||||
<field name="message_is_follower" invisible="1"/>
|
||||
<field name="display_follow_button" invisible="1"/>
|
||||
<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_base"/>
|
||||
<field name="mode">primary</field>
|
||||
<field name="priority">999</field>
|
||||
<field name="arch" type="xml">
|
||||
<filter name="creation_date_filter" position="after">
|
||||
<filter string="Deadline" name="date_deadline" date="date_deadline">
|
||||
<filter name="deadline_future" string="Future" domain="[('date_deadline', '>=', 'today +1d')]"/>
|
||||
<filter name="deadline_this_week" string="This Week" domain="[
|
||||
('date_deadline', '>=', '=week_start'),
|
||||
('date_deadline', '<', '=week_start +1w'),
|
||||
]"/>
|
||||
<filter name="deadline_today" string="Today" domain="[
|
||||
('date_deadline', '>=', 'today'),
|
||||
('date_deadline', '<', 'today +1d'),
|
||||
]"/>
|
||||
<filter name="deadline_past_due" string="Overdue" domain="[('date_deadline', '<', 'today')]"/>
|
||||
</filter>
|
||||
</filter>
|
||||
<filter name="create_date" position="after">
|
||||
<filter string="Deadline" name="deadline" context="{'group_by': 'date_deadline'}"/>
|
||||
</filter>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="open_view_blocked_by_list_view" model="ir.ui.view">
|
||||
<field name="name">open.view.blocked.by.list.view</field>
|
||||
<field name="model">project.task</field>
|
||||
<field name="inherit_id" ref="project.open_view_all_tasks_list_view"/>
|
||||
<field name="mode">primary</field>
|
||||
<field name="arch" type="xml">
|
||||
<list position="attributes">
|
||||
<attribute name="default_group_by"/>
|
||||
</list>
|
||||
<field name="user_ids" position="attributes">
|
||||
<attribute name="invisible">1</attribute>
|
||||
</field>
|
||||
<field name="user_ids" position="after">
|
||||
<field name="portal_user_names" string="Assignees" optional="show"/>
|
||||
</field>
|
||||
</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="path">project_sharing</field>
|
||||
<field name="view_mode">kanban,list,form</field>
|
||||
<field name="search_view_id" ref="project.project_sharing_project_task_view_search"/>
|
||||
<field name="domain">[('project_id', '=', active_id), ('has_template_ancestor', '=', False)]</field>
|
||||
<field name="context">{
|
||||
'default_project_id': active_id,
|
||||
'active_id_chatter': active_id,
|
||||
'delete': 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="sequence" eval="10"/>
|
||||
<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="sequence" eval="20"/>
|
||||
<field name="view_mode">list</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_blocking_tasks" model="ir.actions.act_window">
|
||||
<field name="name">Blocking</field>
|
||||
<field name="res_model">project.task</field>
|
||||
<field name="view_mode">list,kanban,form</field>
|
||||
<field name="search_view_id" ref="project.project_sharing_project_task_view_search"/>
|
||||
<field name="domain">[('depend_on_ids', '=', active_id), ('id', '!=', active_id)]</field>
|
||||
<field name="context">{'default_dependent_ids': 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_blocking_tree_action_view" model="ir.actions.act_window.view">
|
||||
<field name="view_mode">list</field>
|
||||
<field name="act_window_id" ref="project.project_sharing_project_task_action_blocking_tasks"/>
|
||||
<field name="view_id" ref="project.project_sharing_project_task_view_tree"/>
|
||||
</record>
|
||||
|
||||
<record id="project_sharing_blocking_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_blocking_tasks"/>
|
||||
<field name="view_id" ref="project.project_sharing_project_task_view_kanban"/>
|
||||
</record>
|
||||
|
||||
<record id="project_sharing_blocking_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_blocking_tasks"/>
|
||||
<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">list,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">list</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>
|
||||
|
||||
<record id="project_sharing_project_task_recurring_tasks_action" model="ir.actions.act_window">
|
||||
<field name="name">Project Sharing Recurrence</field>
|
||||
<field name="res_model">project.task</field>
|
||||
<field name="view_mode">list,kanban,form</field>
|
||||
<field name="search_view_id" ref="project.project_sharing_project_task_view_search"/>
|
||||
<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_recurring_tasks_tree_action_view" model="ir.actions.act_window.view">
|
||||
<field name="view_mode">list</field>
|
||||
<field name="act_window_id" ref="project.project_sharing_project_task_recurring_tasks_action"/>
|
||||
<field name="view_id" ref="project.project_sharing_project_task_view_tree"/>
|
||||
</record>
|
||||
|
||||
<record id="project_sharing_recurring_tasks_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_recurring_tasks_action"/>
|
||||
<field name="view_id" ref="project.project_sharing_project_task_view_kanban"/>
|
||||
</record>
|
||||
|
||||
<record id="project_sharing_recurring_tasks_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_recurring_tasks_action"/>
|
||||
<field name="view_id" ref="project.project_sharing_project_task_view_form"/>
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<template id="project_sharing_portal" name="Project Sharing View in Portal">
|
||||
<t t-call="portal.frontend_layout">
|
||||
<!-- To add the class on div#wrapwrap to remove the overflow -->
|
||||
<t t-set="pageName" t-value="'o_project_sharing_container'"/>
|
||||
<t t-set="no_footer" t-value="true"/>
|
||||
<t t-call="project.project_sharing"/>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="project_sharing" name="Project Sharing View">
|
||||
<!-- We need to forward the request lang to ensure that the lang set on the portal match the lang delivered -->
|
||||
<iframe class="flex-grow-1" frameborder="0" t-attf-src="/{{ request.context['lang'] }}/my/projects/{{ str(project_id) }}/project_sharing{{ '?task_id=' + task_id if task_id else '' }}"/>
|
||||
</template>
|
||||
|
||||
<template id="project_sharing_embed" name="Project Sharing View Embed">
|
||||
<t t-call="web.layout">
|
||||
<t t-set="head_project_sharing">
|
||||
<script type="text/javascript">
|
||||
odoo.__session_info__ = <t t-out="json.dumps(session_info)"/>;
|
||||
// Prevent the menu_service to load anything. In an ideal world, Project Sharing assets would only contain
|
||||
// what is genuinely necessary, and not the whole backend.
|
||||
odoo.loadMenusPromise = Promise.resolve();
|
||||
</script>
|
||||
<base target="_parent"/>
|
||||
<t t-call-assets="web.assets_common" t-js="false"/>
|
||||
<t t-call-assets="project.webclient" t-js="false"/>
|
||||
<t t-call-assets="web.assets_common" t-css="false"/>
|
||||
<t t-call-assets="project.webclient" t-css="false"/>
|
||||
<t t-call="web.conditional_assets_tests"/>
|
||||
</t>
|
||||
<t t-set="head" t-value="head_project_sharing + (head or '')"/>
|
||||
<t t-set="body_classname" t-value="'o_web_client o_project_sharing'"/>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -1,371 +0,0 @@
|
|||
<?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" force_save="0"/>
|
||||
<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" force_save="0"/>
|
||||
<field name="legend_normal" invisible="1" force_save="0"/>
|
||||
<field name="legend_done" invisible="1" force_save="0"/>
|
||||
<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-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" t-attf-title="#{record.commercial_partner_id.value}">
|
||||
<field name="commercial_partner_id" class="text-truncate d-block"/>
|
||||
</span>
|
||||
<span t-else="" t-attf-title="#{record.partner_id.value}">
|
||||
<field name="partner_id" class="text-truncate d-block"/>
|
||||
</span>
|
||||
</t>
|
||||
<t t-else="record.email_from.raw_value"><span><field name="email_from"/></span></t>
|
||||
</div>
|
||||
<div class="o_dropdown_kanban dropdown" t-if="!selection_mode">
|
||||
<a role="button" class="dropdown-toggle o-no-caret btn" data-bs-toggle="dropdown" data-bs-display="static" href="#" aria-label="Dropdown menu" title="Dropdown menu">
|
||||
<span class="fa fa-ellipsis-v"/>
|
||||
</a>
|
||||
<div class="dropdown-menu" role="menu">
|
||||
<a t-if="widget.editable" role="menuitem" type="edit" class="dropdown-item">Edit</a>
|
||||
<div invisible="1" role="separator" class="dropdown-divider"></div>
|
||||
<ul invisible="1" class="oe_kanban_colorpicker" data-field="color"/>
|
||||
</div>
|
||||
</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-out="user_count"/>
|
||||
<t t-if="user_count > 1"> assignees</t>
|
||||
<t t-else=""> assignee</t>
|
||||
</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="priority">999</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Tasks" sample="1" delete="0" import="0">
|
||||
<field name="is_closed" invisible="1" />
|
||||
<field name="sequence" invisible="1" readonly="1"/>
|
||||
<field name="allow_milestones" invisible="1"/>
|
||||
<field name="priority" widget="priority" optional="show" nolabel="1"/>
|
||||
<field name="child_text" invisible="1"/>
|
||||
<field name="allow_subtasks" invisible="1" />
|
||||
<field name="name" widget="name_with_subtask_count"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="milestone_id" attrs="{'column_invisible': [('allow_milestones', '=', False)]}"/>
|
||||
<field name="partner_id" optional="hide"/>
|
||||
<field name="portal_user_names" string="Assignees" optional="show"/>
|
||||
<field name="date_deadline" optional="hide" widget="remaining_days" attrs="{'invisible': [('is_closed', '=', True)]}"/>
|
||||
<field name="tag_ids" widget="many2many_tags" options="{'color_field': 'color'}" optional="show"/>
|
||||
<field name="kanban_state" widget="state_selection" options="{'hide_label': True}" nolabel="1" optional="show"/>
|
||||
<field name="legend_blocked" invisible="1"/>
|
||||
<field name="legend_normal" invisible="1"/>
|
||||
<field name="legend_done" invisible="1"/>
|
||||
<field name="stage_id" invisible="context.get('set_visible',False)" optional="show"/>
|
||||
</tree>
|
||||
</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' : "[('user_ids', 'in', [uid])]"}" data-hotkey="q" groups="base.group_user"/>
|
||||
<button name="action_unassign_me" string="Unassign Me" type="object" class="oe_highlight"
|
||||
attrs="{'invisible' : "[('user_ids', 'not in', [uid])]"}" 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"/>
|
||||
</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)]}"/>
|
||||
<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>
|
||||
<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)]}"
|
||||
options="{'no_open': True, 'no_create': True, 'no_edit': True}"
|
||||
/>
|
||||
<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" domain="[('user_id', '=', False), ('project_ids', 'in', [project_id])]"/>
|
||||
<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': "[('project_id', '!=', False), ('project_id', '!=', active_id)]"}"/>
|
||||
</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="priority">999</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Tasks">
|
||||
<field name="name" string="Task"/>
|
||||
<field name="tag_ids"/>
|
||||
<field name="portal_user_names" string="Assignees"/>
|
||||
<field string="Project" name="display_project_id"/>
|
||||
<field name="milestone_id" groups="project.group_project_milestone"/>
|
||||
<field name="stage_id"/>
|
||||
<field name="partner_id" operator="child_of"/>
|
||||
<filter string="Unassigned" name="unassigned" domain="[('user_ids', '=', False)]"/>
|
||||
<separator/>
|
||||
<filter string="High Priority" name="high_priority" domain="[('priority', '=', 1)]"/>
|
||||
<filter string="Low Priority" name="low_priority" domain="[('priority', '=', 0)]"/>
|
||||
<separator/>
|
||||
<filter string="Late Tasks" name="late" domain="[('date_deadline', '<', context_today().strftime('%Y-%m-%d')), ('is_closed', '=', False)]"/>
|
||||
<filter string="Tasks Due Today" name="tasks_due_today" domain="[('date_deadline', '=', context_today().strftime('%Y-%m-%d'))]"/>
|
||||
<filter string="Late Milestones" name="late_milestone" domain="[('is_closed', '=', False), ('has_late_and_unreached_milestone', '=', True)]" groups="project.group_project_milestone"/>
|
||||
<separator/>
|
||||
<filter string="Open Tasks" name="open_tasks" domain="[('is_closed', '=', False)]"/>
|
||||
<filter string="Closed Tasks" name="closed_tasks" domain="[('is_closed', '=', True)]"/>
|
||||
<filter string="Closed Last 7 Days" name="closed_last_7_days" domain="[('is_closed', '=', True), ('date_last_stage_update', '>', datetime.datetime.now() - relativedelta(days=7))]"/>
|
||||
<filter string="Closed Last 30 Days" name="closed_last_30_days" domain="[('is_closed', '=', True), ('date_last_stage_update', '>', datetime.datetime.now() - relativedelta(days=30))]"/>
|
||||
<separator/>
|
||||
<filter invisible="1" string="Today Activities" name="activities_today"
|
||||
domain="[('activity_ids.date_deadline', '=', context_today().strftime('%Y-%m-%d'))]"/>
|
||||
<filter invisible="1" string="Future Activities" name="activities_upcoming_all"
|
||||
domain="[('activity_ids.date_deadline', '>', context_today().strftime('%Y-%m-%d'))]"/>
|
||||
<group expand="0" string="Group By">
|
||||
<filter string="Stage" name="stage" context="{'group_by': 'stage_id'}"/>
|
||||
<filter string="Milestone" name="milestone" context="{'group_by': 'milestone_id'}" groups="project.group_project_milestone"/>
|
||||
<filter string="Customer" name="customer" context="{'group_by': 'partner_id'}"/>
|
||||
<filter string="Kanban State" name="kanban_state" context="{'group_by': 'kanban_state'}"/>
|
||||
<filter string="Deadline" name="date_deadline" context="{'group_by': 'date_deadline'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</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)]</field>
|
||||
<field name="context">{
|
||||
'default_project_id': active_id,
|
||||
'delete': 0,
|
||||
'active_id_chatter': active_id,
|
||||
}</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>
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record model="ir.ui.view" id="project_tags_search_view">
|
||||
<field name="name">Tags</field>
|
||||
<field name="model">project.tags</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Issue Version">
|
||||
<field name="name"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="project_tags_form_view">
|
||||
<field name="name">Tags</field>
|
||||
<field name="model">project.tags</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Tags">
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="color" widget="color_picker"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="project_tags_tree_view">
|
||||
<field name="name">Tags</field>
|
||||
<field name="model">project.tags</field>
|
||||
<field name="arch" type="xml">
|
||||
<list string="Tags" editable="top" sample="1" multi_edit="1" default_order="name">
|
||||
<field name="name"/>
|
||||
<field name="color" widget="color_picker" optional="show"/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_tags_action" model="ir.actions.act_window">
|
||||
<field name="name">Tags</field>
|
||||
<field name="res_model">project.tags</field>
|
||||
<field name="path">task-tags</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No tags found. Let's create one!
|
||||
</p>
|
||||
<p>
|
||||
Use tags to categorize your tasks.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="task_type_search" model="ir.ui.view">
|
||||
<field name="name">project.task.type.search</field>
|
||||
<field name="model">project.task.type</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Tasks Stages">
|
||||
<field name="name" string="Name"/>
|
||||
<field name="project_ids" string="Project"/>
|
||||
<field name="mail_template_id"/>
|
||||
<field name="rating_template_id"/>
|
||||
<filter string="Archived" name="inactive" domain="[('active', '=', False)]"/>
|
||||
<group>
|
||||
<filter string="Projects" name="project_ids" context="{'group_by': 'project_ids'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="task_type_edit" model="ir.ui.view">
|
||||
<field name="name">project.task.type.form</field>
|
||||
<field name="model">project.task.type</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Task Stage" delete="0">
|
||||
<field name="active" invisible="1" />
|
||||
<sheet>
|
||||
<widget name="web_ribbon" title="Archived" bg_color="text-bg-danger" invisible="active" />
|
||||
<group>
|
||||
<group>
|
||||
<field name="name" placeholder="e.g. To Do"/>
|
||||
<field name="fold"/>
|
||||
<field name="user_id" invisible="True"/>
|
||||
<field name="auto_validation_state" invisible="not rating_template_id"/>
|
||||
<field name="project_ids" widget="many2many_tags" options="{'color_field': 'color', 'edit_tags': True}" invisible="user_id" required="not user_id"/>
|
||||
<field name="rotting_threshold_days"/>
|
||||
<field name="color" widget="color_picker"/>
|
||||
<field name="sequence" groups="base.group_no_one"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="mail_template_id" context="{'default_model': 'project.task'}" invisible="user_id"/>
|
||||
</group>
|
||||
<group name="group_customer_rating" string="Customer Rating" class="row o_settings_container" invisible="user_id">
|
||||
<setting class="col-lg-12">
|
||||
<field name="rating_active"/>
|
||||
<div invisible="not rating_active">
|
||||
<field name="rating_status" widget="radio" class="o_row"/>
|
||||
<group class="mt-2">
|
||||
<field
|
||||
name="rating_status_period"
|
||||
invisible="rating_status != 'periodic'"
|
||||
required="rating_status == 'periodic'"
|
||||
/>
|
||||
<field
|
||||
name="rating_template_id"
|
||||
placeholder="Task: Rating Request"
|
||||
context="{'default_model': 'project.task'}"
|
||||
required="rating_active"
|
||||
/>
|
||||
</group>
|
||||
<span colspan="2" class="text-muted o_row ps-1">
|
||||
<i class="fa fa-lightbulb-o pe-2"/>
|
||||
<span name="rating_status_helper">
|
||||
<span invisible="rating_status == 'periodic'">A rating request will be sent as soon as a task reaches this stage.</span>
|
||||
<span invisible="rating_status == 'stage'">Rating requests will be sent as long as the task remains in this stage.</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</setting>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="task_type_tree" model="ir.ui.view">
|
||||
<field name="name">project.task.type.list</field>
|
||||
<field name="model">project.task.type</field>
|
||||
<field name="arch" type="xml">
|
||||
<list string="Task Stage" delete="0" sample="1" multi_edit="1" editable="bottom" open_form_view="True">
|
||||
<field name="sequence" widget="handle" optional="show"/>
|
||||
<field name="name" placeholder="e.g. To Do"/>
|
||||
<field name="rotting_threshold_days" optional="hide"/>
|
||||
<field name="mail_template_id" optional="hide"/>
|
||||
<field name="project_ids" required="1" optional="show" widget="many2many_tags" options="{'color_field': 'color'}"/>
|
||||
<field name="color" optional="hide" widget="color_picker"/>
|
||||
<field name="fold" optional="show"/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="task_type_tree_inherited" model="ir.ui.view">
|
||||
<field name="name">project.task.type.list.inherited</field>
|
||||
<field name="model">project.task.type</field>
|
||||
<field name="mode">primary</field>
|
||||
<field name="inherit_id" ref="task_type_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='name']" position="after">
|
||||
<field name="rating_template_id" optional="hide"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_project_task_type_kanban" model="ir.ui.view">
|
||||
<field name="name">project.task.type.kanban</field>
|
||||
<field name="model">project.task.type</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban highlight_color="color" class="o_kanban_mobile" sample="1" default_group_by="project_ids">
|
||||
<templates>
|
||||
<t t-name="menu" t-if="!selection_mode" groups="base.group_user">
|
||||
<field name="color" widget="kanban_color_picker"/>
|
||||
</t>
|
||||
<t t-name="card">
|
||||
<field name="name" class="fw-bolder text-truncate"/>
|
||||
<field name="project_ids" widget="many2many_tags" options="{'color_field': 'color'}"/>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="open_task_type_form" model="ir.actions.act_window">
|
||||
<field name="name">Task Stages</field>
|
||||
<field name="res_model">project.task.type</field>
|
||||
<field name="path">task-stages</field>
|
||||
<field name="view_mode">list,kanban,form</field>
|
||||
<field name="view_id" ref="task_type_tree_inherited"/>
|
||||
<field name="domain">[('user_id', '=', False)]</field>
|
||||
<field name="context">{'default_user_id': False}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No stages found. Let's create one!
|
||||
</p><p>
|
||||
Define the steps your tasks move through from creation to completion.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="open_task_type_form_domain" model="ir.actions.act_window">
|
||||
<field name="name">Task Stages</field>
|
||||
<field name="res_model">project.task.type</field>
|
||||
<field name="view_mode">list,kanban,form</field>
|
||||
<field name="domain">[('project_ids','=', project_id)]</field>
|
||||
<field name="view_id" ref="task_type_tree_inherited"/>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Create a new stage in the task pipeline
|
||||
</p><p>
|
||||
Define the steps that will be used in the project from the
|
||||
creation of the task, up to the closing of the task or issue.
|
||||
You will use these stages in order to track the progress in
|
||||
solving a task or an issue.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="unlink_task_type_action" model="ir.actions.server">
|
||||
<field name="name">Delete</field>
|
||||
<field name="model_id" ref="project.model_project_task_type"/>
|
||||
<field name="binding_model_id" ref="project.model_project_task_type"/>
|
||||
<field name="binding_view_types">form,list,kanban</field>
|
||||
<field name="state">code</field>
|
||||
<field name="code">action = records.unlink_wizard(stage_view=True)</field>
|
||||
</record>
|
||||
</odoo>
|
||||
1373
odoo-bringout-oca-ocb-project/project/views/project_task_views.xml
Normal file
1373
odoo-bringout-oca-ocb-project/project/views/project_task_views.xml
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -2,10 +2,10 @@
|
|||
<odoo>
|
||||
<template id="project.milestone_deadline">
|
||||
<t t-if="milestone['deadline']">
|
||||
(due <t t-esc="milestone['deadline']" t-options='{"widget": "date"}'/><t t-if="not milestone['is_reached'] or not milestone['reached_date']">
|
||||
(due <t t-out="milestone['deadline']" t-options='{"widget": "date"}'/><t t-if="not milestone['is_reached'] or not milestone['reached_date']">
|
||||
<t t-if="milestone['can_be_marked_as_done']"> - <font t-att-style="'color: rgb(0, ' + str(color_level) + ', 0)'">ready to be marked as reached</font></t>)</t><t t-else=""> - reached on<t t-if="milestone['reached_date'] > milestone['deadline']">
|
||||
<font t-att-style="'color: rgb(' + str(color_level) + ', 0, 0)'"><b><t t-esc="milestone['reached_date']" t-options='{"widget": "date"}'/></b></font>)</t><t t-else="">
|
||||
<font t-att-style="'color: rgb(0, ' + str(color_level) + ', 0)'"><b><t t-esc="milestone['reached_date']" t-options='{"widget": "date"}'/></b></font>)</t></t>
|
||||
<font style="color: rgb(255, 0, 0)"><t t-out="milestone['reached_date']" t-options='{"widget": "date"}'/></font>)</t><t t-else="">
|
||||
<font style="color: rgb(0, 128, 0)"><t t-out="milestone['reached_date']" t-options='{"widget": "date"}'/></font>)</t></t>
|
||||
</t>
|
||||
<t t-elif="milestone['can_be_marked_as_done']">
|
||||
(<font t-att-style="'color: rgb(0, ' + str(color_level) + ', 0)'">ready to be marked as reached</font>)
|
||||
|
|
@ -23,29 +23,110 @@
|
|||
<h1 style="font-weight: bolder;">Activities</h1>
|
||||
</div>
|
||||
|
||||
<div name="profitability" t-if="show_profitability">
|
||||
<t t-if="project.account_id" name="costs">
|
||||
<h3 style="font-weight: bolder"><u>Profitability</u></h3>
|
||||
|
||||
<div name="profitability_detail" class="mt-4">
|
||||
<table class="table table-striped" t-if="profitability['revenues']['data']">
|
||||
<thead class="border-2 border-start-0 border-end-0">
|
||||
<tr>
|
||||
<th class="fw-bolder" style="width: 55%">Revenues</th>
|
||||
<th class="fw-bolder text-end" style="width: 15%">Expected</th>
|
||||
<th class="fw-bolder text-end" style="width: 15%">To Invoice</th>
|
||||
<th class="fw-bolder text-end" style="width: 15%">Invoiced</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr t-foreach="profitability['revenues']['data']" t-as="revenue">
|
||||
<tr class="revenue_data">
|
||||
<td t-out="profitability['labels'][revenue['id']]"/>
|
||||
<td class="text-end" t-out="format_monetary(revenue['invoiced'] + revenue['to_invoice'])"/>
|
||||
<td class="text-end" t-out="format_monetary(revenue['to_invoice'])"/>
|
||||
<td class="text-end" t-out="format_monetary(revenue['invoiced'])"/>
|
||||
</tr>
|
||||
</tr>
|
||||
<tfoot>
|
||||
<td class="fw-bolder">Total Revenues</td>
|
||||
<td class="fw-bolder text-end" t-out="format_monetary(profitability['revenues']['total']['invoiced'] + profitability['revenues']['total']['to_invoice'])"/>
|
||||
<td class="fw-bolder text-end" t-out="format_monetary(profitability['revenues']['total']['to_invoice'])"/>
|
||||
<td class="fw-bolder text-end" t-out="format_monetary(profitability['revenues']['total']['invoiced'])"/>
|
||||
</tfoot>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table class="table table-striped mt-4 table-bordered" t-if="profitability['costs']['data']">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="fw-bolder" style="width: 55%">Costs</th>
|
||||
<th class="fw-bolder text-end" style="width: 15%">Expected</th>
|
||||
<th class="fw-bolder text-end" style="width: 15%">To Bill</th>
|
||||
<th class="fw-bolder text-end" style="width: 15%">Billed</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr t-foreach="profitability['costs']['data']" t-as="cost">
|
||||
<td t-out="profitability['labels'][cost['id']]"/>
|
||||
<td class="text-end" t-out="format_monetary(cost['billed'] + cost['to_bill'])"/>
|
||||
<td class="text-end" t-out="format_monetary(cost['to_bill'])"/>
|
||||
<td class="text-end" t-out="format_monetary(cost['billed'])"/>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tr>
|
||||
<td class="fw-bolder">Total Costs</td>
|
||||
<td class="fw-bolder text-end" t-out="format_monetary(profitability['costs']['total']['billed'] + profitability['costs']['total']['to_bill'])"/>
|
||||
<td class="fw-bolder text-end" t-out="format_monetary(profitability['costs']['total']['to_bill'])"/>
|
||||
<td class="fw-bolder text-end" t-out="format_monetary(profitability['costs']['total']['billed'])"/>
|
||||
</tr>
|
||||
<tr t-if="profitability['costs']['data'] and profitability['revenues']['data']">
|
||||
<td class="fw-bolder align-middle">Total</td>
|
||||
<td t-attf-class="#{'text-danger' if profitability['total']['margin'] < 0 else 'text-success'}" style="text-align: right">
|
||||
<t t-out="format_monetary(profitability['total']['margin'])"/><br/>
|
||||
<t t-if="profitability['expected_percentage']">
|
||||
<t t-out="profitability['expected_percentage']"/><t>%</t>
|
||||
</t>
|
||||
</td>
|
||||
<td t-attf-class="#{'text-danger' if profitability['total']['revenues'] < 0 else 'text-success'}" style="text-align: right">
|
||||
<t t-out="format_monetary(profitability['total']['revenues'])"/><br/>
|
||||
<t t-if="profitability['to_bill_to_invoice_percentage']">
|
||||
<t t-out="profitability['to_bill_to_invoice_percentage']"/><t>%</t>
|
||||
</t>
|
||||
</td>
|
||||
<td t-attf-class="#{'text-danger' if profitability['total']['costs'] < 0 else 'text-success'}" style="text-align: right">
|
||||
<t t-out="format_monetary(profitability['total']['costs'])"/><br/>
|
||||
<t t-if="profitability['billed_invoiced_percentage']">
|
||||
<t t-out="profitability['billed_invoiced_percentage']"/><t>%</t>
|
||||
</t>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
|
||||
<div name="milestone" t-if="milestones['show_section']">
|
||||
<br/>
|
||||
<h3 style="font-weight: bolder"><u>Milestones</u></h3>
|
||||
|
||||
<ul class="o_checklist" t-if="milestones['list']">
|
||||
<t t-foreach="milestones['list']" t-as="milestone">
|
||||
<li t-attf-class="{{milestone['is_reached'] and 'o_checked' or ''}}">
|
||||
<t t-esc="milestone['name']"/>
|
||||
<span t-if="milestone['is_deadline_future'] and not milestone['is_reached'] and not milestone['can_be_marked_as_done']"><font style="color: rgb(190, 190, 190);"><t t-set="color_level" t-value="64"/><t t-call="project.milestone_deadline"/></font></span>
|
||||
<span t-elif="milestone['is_deadline_exceeded']"><font style="color: rgb(255, 0, 0);"><t t-call="project.milestone_deadline"/></font></span>
|
||||
<li t-att-class="milestone['is_reached'] and 'o_checked'" t-attf-id="checkId-{{milestone_index}}">
|
||||
<t t-out="milestone['name']"/>
|
||||
<span t-if="milestone['is_deadline_exceeded']"><font style="color: rgb(255, 0, 0);"><t t-call="project.milestone_deadline"/></font></span>
|
||||
<span t-elif="not milestone['can_be_marked_as_done']"><font style="color: rgb(190, 190, 190);"><t t-set="color_level" t-value="64"/><t t-call="project.milestone_deadline"/></font></span>
|
||||
<span t-else=""><t t-set="color_level" t-value="128"/><t t-call="project.milestone_deadline"/></span>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
|
||||
<t t-if="milestones['updated']">
|
||||
<t t-if="milestones['last_update_date']">Since <t t-esc="milestones['last_update_date']" t-options='{"widget": "date"}'/> (last project update), </t>
|
||||
<t t-if="milestones['last_update_date']">Since <t t-out="milestones['last_update_date']" t-options='{"widget": "date"}'/> (last project update), </t>
|
||||
<t t-if="len(milestones['updated']) > 1">the deadline for the following milestones has been updated:</t>
|
||||
<t t-else="">the deadline for the following milestone has been updated:</t>
|
||||
<ul>
|
||||
<t t-foreach="milestones['updated']" t-as="milestone">
|
||||
<li>
|
||||
<t t-esc="milestone['name']"/> (<t t-esc="milestone['old_value']" t-options='{"widget": "date"}'/> => <t t-esc="milestone['new_value']" t-options='{"widget": "date"}'/>)
|
||||
<t t-out="milestone['name']"/> (<t t-out="milestone['old_value']" t-options='{"widget": "date"}'/> => <t t-out="milestone['new_value']" t-options='{"widget": "date"}'/>)
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
|
|
@ -57,21 +138,13 @@
|
|||
<ul>
|
||||
<t t-foreach="milestones['created']" t-as="milestone">
|
||||
<li>
|
||||
<t t-esc="milestone['name']"/><span t-if="milestone['is_deadline_future'] and not milestone['is_reached']">
|
||||
<font style="color: rgb(190, 190, 190);">
|
||||
<t t-set="color_level" t-value="64"/>
|
||||
<t t-call="project.milestone_deadline"/>
|
||||
</font>
|
||||
</span>
|
||||
<span t-else="">
|
||||
<t t-set="color_level" t-value="128"/>
|
||||
<t t-call="project.milestone_deadline"/>
|
||||
</span>
|
||||
<t t-out="milestone['name']"/>
|
||||
<span t-if="milestone['is_deadline_exceeded']"><font style="color: rgb(255, 0, 0);"><t t-call="project.milestone_deadline"/></font></span>
|
||||
<span t-else=""><font style="color: rgb(190, 190, 190);"><t t-set="color_level" t-value="128"/><t t-call="project.milestone_deadline"/></font></span>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
</t>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@
|
|||
<field name="description"/>
|
||||
<field name="status"/>
|
||||
<filter string="My Updates" name="my_updates" domain="[('user_id', '=', uid)]"/>
|
||||
<filter string="Followed Updates" name="followed_updates" domain="[('message_is_follower', '=', True)]"/>
|
||||
<separator/>
|
||||
<filter string="On Track" name="on_track" domain="[('status', '=', 'on_track')]"/>
|
||||
<filter string="At Risk" name="at_risk" domain="[('status', '=', 'at_risk')]"/>
|
||||
|
|
@ -27,7 +26,7 @@
|
|||
<field name="name">project.update.view.form</field>
|
||||
<field name="model">project.update</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Project Update" class="o_form_project_update" js_class="form_description_expander">
|
||||
<form string="Project Update" js_class="form_description_expander">
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
<h1>
|
||||
|
|
@ -38,7 +37,7 @@
|
|||
<group>
|
||||
<field name="project_id" invisible="1"/>
|
||||
<field name="color" invisible="1"/>
|
||||
<field name="status" widget="status_with_color" options="{'color_field': 'color'}"/>
|
||||
<field name="status" widget="status_with_color"/>
|
||||
<field name="progress" widget="progressbar" options="{'editable': true}"/>
|
||||
</group>
|
||||
<group>
|
||||
|
|
@ -53,11 +52,7 @@
|
|||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
<div class="oe_chatter">
|
||||
<field name="message_follower_ids" options="{'post_refresh':True}" groups="base.group_user"/>
|
||||
<field name="activity_ids"/>
|
||||
<field name="message_ids"/>
|
||||
</div>
|
||||
<chatter class="d-print-none" reload_on_follower="True"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
|
@ -66,34 +61,38 @@
|
|||
<field name="name">project.update.view.kanban</field>
|
||||
<field name="model">project.update</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban class="o_pupdate_kanban" sample="1" js_class="project_update_kanban">
|
||||
<kanban highlight_color="color" sample="0" js_class="project_update_kanban">
|
||||
<field name="color"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div t-attf-class="{{!selection_mode ? 'oe_kanban_color_' + record.color.raw_value : ''}} oe_kanban_global_click o_pupdate_kanban_card">
|
||||
<!-- Project Update Kanban View is always ungrouped - see js_class -->
|
||||
<div class="o_kanban_detail_ungrouped row">
|
||||
<div class="col-sm-4 col-6 o_pupdate_name">
|
||||
<b><field name="name_cropped"/></b>
|
||||
<div>
|
||||
<field name="user_id" widget="many2one_avatar_user"/>
|
||||
<t t-esc="record.user_id.value"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-2 text-sm-start col-6 align-end">
|
||||
<field name="color" invisible="1"/>
|
||||
<b><field name="status" widget="status_with_color" options="{'color_field': 'color'}"/></b>
|
||||
</div>
|
||||
<div class="col-sm-2 col-6 pb-0">
|
||||
<b><field name="progress_percentage" widget="percentage"/></b>
|
||||
<div>Progress</div>
|
||||
</div>
|
||||
<div class="col-sm-2 col-6 pb-0">
|
||||
<b><field name="date"/></b>
|
||||
<div>Date</div>
|
||||
</div>
|
||||
<t t-name="card" class="o_project_update_card column-gap-0 column-gap-md-3 row-gap-2 flex-row flex-wrap align-items-center px-3">
|
||||
<div class="flex-grow-1 flex-shrink-0 w-50 w-md-auto px-2 px-md-0">
|
||||
<field name="name_cropped" class="fw-bolder"/>
|
||||
<div class="d-flex gap-1">
|
||||
<field name="user_id" widget="many2one_avatar_user"/>
|
||||
<field name="user_id"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow-1 flex-shrink-0 w-50 w-md-auto px-2 px-md-0">
|
||||
<span>Status</span>
|
||||
<field name="color" invisible="1"/>
|
||||
<field name="status" class="fw-bolder" readonly="1" widget="status_with_color"/>
|
||||
</div>
|
||||
<div class="flex-grow-1 flex-shrink-0 w-50 w-md-auto px-2 px-md-0">
|
||||
<span>Progress</span>
|
||||
<field name="progress_percentage" class="fw-bolder" widget="percentage"/>
|
||||
</div>
|
||||
<div class="flex-grow-1 flex-shrink-0 w-50 w-md-auto px-2 px-md-0">
|
||||
<div id="tasks_stats" class="fw-bolder">
|
||||
<span invisible="not task_count">
|
||||
<field name="closed_task_count"/> / <field name="task_count"/> <field name="label_tasks"/> (<field name="closed_task_percentage"/>%)
|
||||
</span>
|
||||
<span invisible="task_count">0 <field name="label_tasks"/></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow-1 flex-shrink-0 w-50 w-md-auto px-2 px-md-0">
|
||||
<div>Date</div>
|
||||
<field name="date" class="fw-bolder"/>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
|
|
@ -101,25 +100,25 @@
|
|||
</record>
|
||||
|
||||
<record id="project_update_view_tree" model="ir.ui.view">
|
||||
<field name="name">project.update.view.tree</field>
|
||||
<field name="name">project.update.view.list</field>
|
||||
<field name="model">project.update</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree sample="1" js_class="project_update_list">
|
||||
<list sample="1" js_class="project_update_list">
|
||||
<field name="name"/>
|
||||
<field name="user_id" widget="many2one_avatar_user" class="fw-bold" optional="show"/>
|
||||
<field name="user_id" widget="many2one_avatar_user" class="fw-bolder" optional="show"/>
|
||||
<field name="date" optional="show"/>
|
||||
<field name="progress_percentage" string="Progress" widget="percentage" optional="show"/>
|
||||
<field name="color" invisible="1"/>
|
||||
<field name="status" widget="status_with_color" options="{'color_field': 'color'}"/>
|
||||
</tree>
|
||||
<field name="progress" string="Progress" widget="progressbar" optional="show"/>
|
||||
<field name="color" column_invisible="True"/>
|
||||
<field name="status" widget="status_with_color"/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_update_all_action" model="ir.actions.act_window">
|
||||
<field name="name">Project Updates</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="name">Dashboard</field>
|
||||
<field name="res_model">project.update</field>
|
||||
<field name="view_mode">kanban,tree,form</field>
|
||||
<field name="path">project-dashboard</field>
|
||||
<field name="view_mode">kanban,list,form</field>
|
||||
<field name="domain">[('project_id', '=', active_id)]</field>
|
||||
<field name="search_view_id" ref="project_update_view_search"/>
|
||||
<field name="help" type="html">
|
||||
|
|
@ -130,5 +129,4 @@
|
|||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="rating_rating_view_tree_project" model="ir.ui.view">
|
||||
<field name="name">rating.rating.tree.project</field>
|
||||
<field name="name">rating.rating.list.project</field>
|
||||
<field name="model">rating.rating</field>
|
||||
<field name="inherit_id" ref="rating.rating_rating_view_tree"/>
|
||||
<field name="mode">primary</field>
|
||||
|
|
@ -48,13 +48,10 @@
|
|||
<field name="rated_partner_id" position="attributes">
|
||||
<attribute name="string">Assigned to</attribute>
|
||||
</field>
|
||||
<field name="create_date" position="replace">
|
||||
<field name="write_date" readonly="1" string="Submitted On"/>
|
||||
</field>
|
||||
<field name="feedback" position="attributes">
|
||||
<attribute name="readonly">1</attribute>
|
||||
</field>
|
||||
<field name="write_date" position="after">
|
||||
<field name="rated_on" position="after">
|
||||
<field name="partner_id" position="move"/>
|
||||
</field>
|
||||
<xpath expr="//field[@name='is_internal']" position="attributes">
|
||||
|
|
@ -70,12 +67,12 @@
|
|||
<field name="mode">primary</field>
|
||||
<field name="priority">64</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//pivot" position="attributes">
|
||||
<attribute name="js_class">project_rating_pivot</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='create_date']" position="attributes">
|
||||
<xpath expr="//field[@name='rated_on']" position="attributes">
|
||||
<attribute name="invisible">1</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='rating']" position="attributes">
|
||||
<attribute name="string">Rating (1-5)</attribute>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
|
@ -86,21 +83,8 @@
|
|||
<field name="mode">primary</field>
|
||||
<field name="priority">64</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//graph" position="attributes">
|
||||
<attribute name="js_class">project_rating_graph</attribute>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="rating_rating_project_view_kanban" model="ir.ui.view">
|
||||
<field name="name">rating.rating.kanban.project</field>
|
||||
<field name="model">rating.rating</field>
|
||||
<field name="inherit_id" ref="rating.rating_rating_view_kanban"/>
|
||||
<field name="mode">primary</field>
|
||||
<field name="priority">64</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='create_date']" position="replace">
|
||||
<field name="write_date"/>
|
||||
<xpath expr="//field[@name='rating']" position="attributes">
|
||||
<attribute name="string">Rating (1-5)</attribute>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
|
@ -137,20 +121,11 @@
|
|||
<xpath expr="//filter[@name='responsible']" position="attributes">
|
||||
<attribute name="string">Assigned to</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//filter[@name='filter_create_date']" position="replace">
|
||||
<filter name="filter_write_date" string="Submitted On" date="write_date"/>
|
||||
<xpath expr="//filter[@name='filter_rated_on']" position="attributes">
|
||||
<attribute name="default_period">custom_rated_on_last_30_days</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//filter[@name='month']" position="attributes">
|
||||
<attribute name="context">{'group_by':'write_date:month'}</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//filter[@name='today']" position="attributes">
|
||||
<attribute name="domain">[('write_date', '>', (context_today() - datetime.timedelta(days=1)).strftime('%Y-%m-%d'))]</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//filter[@name='last_7days']" position="attributes">
|
||||
<attribute name="domain">[('write_date','>', (context_today() - datetime.timedelta(days=7)).strftime('%Y-%m-%d'))]</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//filter[@name='last_month']" position="attributes">
|
||||
<attribute name="domain">[('write_date','>', (context_today() - relativedelta(months=1)).strftime('%Y-%m-%d'))]</attribute>
|
||||
<attribute name="context">{'group_by':'rated_on:month'}</attribute>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
|
@ -158,7 +133,7 @@
|
|||
<record id="rating_rating_action_view_project_rating" model="ir.actions.act_window">
|
||||
<field name="name">Ratings</field>
|
||||
<field name="res_model">rating.rating</field>
|
||||
<field name="view_mode">kanban,tree,graph,pivot,form</field>
|
||||
<field name="view_mode">kanban,list,graph,pivot,form</field>
|
||||
<field name="domain">[('consumed','=',True), ('parent_res_model','=','project.project'), ('parent_res_id', '=', active_id)]</field>
|
||||
<field name="search_view_id" ref="rating_rating_view_search_project"/>
|
||||
<field name="help" type="html">
|
||||
|
|
@ -172,12 +147,12 @@
|
|||
<field name="sequence" eval="5"/>
|
||||
<field name="view_mode">kanban</field>
|
||||
<field name="act_window_id" ref="rating_rating_action_view_project_rating"/>
|
||||
<field name="view_id" ref="rating_rating_project_view_kanban"/>
|
||||
<field name="view_id" ref="rating.rating_rating_view_kanban"/>
|
||||
</record>
|
||||
|
||||
<record id="rating_rating_action_view_project_rating_tree" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_mode">list</field>
|
||||
<field name="act_window_id" ref="rating_rating_action_view_project_rating"/>
|
||||
<field name="view_id" ref="rating_rating_view_tree_project"/>
|
||||
</record>
|
||||
|
|
@ -206,7 +181,7 @@
|
|||
<record id="rating_rating_action_task" model="ir.actions.act_window">
|
||||
<field name="name">Ratings</field>
|
||||
<field name="res_model">rating.rating</field>
|
||||
<field name="view_mode">kanban,tree,pivot,graph,form</field>
|
||||
<field name="view_mode">kanban,list,pivot,graph,form</field>
|
||||
<field name="domain">[('res_model', '=', 'project.task'), ('res_id', '=', active_id), ('consumed', '=', True)]</field>
|
||||
<field name="search_view_id" ref="rating_rating_view_search_project"/>
|
||||
<field name="help" type="html">
|
||||
|
|
@ -223,12 +198,12 @@
|
|||
<field name="sequence" eval="5"/>
|
||||
<field name="view_mode">kanban</field>
|
||||
<field name="act_window_id" ref="rating_rating_action_task"/>
|
||||
<field name="view_id" ref="rating_rating_project_view_kanban"/>
|
||||
<field name="view_id" ref="rating.rating_rating_view_kanban"/>
|
||||
</record>
|
||||
|
||||
<record id="rating_rating_action_task_tree" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_mode">list</field>
|
||||
<field name="act_window_id" ref="rating_rating_action_task"/>
|
||||
<field name="view_id" ref="rating_rating_view_tree_project"/>
|
||||
</record>
|
||||
|
|
@ -257,7 +232,8 @@
|
|||
<record id="rating_rating_action_project_report" model="ir.actions.act_window">
|
||||
<field name="name">Customer Ratings</field>
|
||||
<field name="res_model">rating.rating</field>
|
||||
<field name="view_mode">kanban,tree,pivot,graph,form</field>
|
||||
<field name="path">task-ratings</field>
|
||||
<field name="view_mode">kanban,list,pivot,graph,form</field>
|
||||
<field name="domain">[('parent_res_model','=','project.project'), ('consumed', '=', True)]</field>
|
||||
<field name="search_view_id" ref="rating_rating_view_search_project"/>
|
||||
<field name="help" type="html">
|
||||
|
|
@ -269,7 +245,7 @@
|
|||
</p>
|
||||
</field>
|
||||
<field name="context">{
|
||||
'search_default_last_month': 1,
|
||||
'search_default_filter_rated_on': 1,
|
||||
'graph_groupbys': ['rated_partner_id'],
|
||||
}</field>
|
||||
</record>
|
||||
|
|
@ -278,12 +254,12 @@
|
|||
<field name="sequence" eval="5"/>
|
||||
<field name="view_mode">kanban</field>
|
||||
<field name="act_window_id" ref="rating_rating_action_project_report"/>
|
||||
<field name="view_id" ref="rating_rating_project_view_kanban"/>
|
||||
<field name="view_id" ref="rating.rating_rating_view_kanban"/>
|
||||
</record>
|
||||
|
||||
<record id="rating_rating_action_project_report_tree" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_mode">list</field>
|
||||
<field name="act_window_id" ref="rating_rating_action_project_report"/>
|
||||
<field name="view_id" ref="rating_rating_view_tree_project"/>
|
||||
</record>
|
||||
|
|
@ -308,5 +284,4 @@
|
|||
<field name="act_window_id" ref="rating_rating_action_project_report"/>
|
||||
<field name="view_id" ref="rating_rating_view_graph"/>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
|
|||
|
|
@ -6,147 +6,32 @@
|
|||
<field name="priority" eval="50"/>
|
||||
<field name="inherit_id" ref="base.res_config_settings_view_form" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[hasclass('settings')]" position="inside">
|
||||
<div class="app_settings_block" data-string="Project" string="Project" data-key="project" groups="project.group_project_manager">
|
||||
<h2>Tasks Management</h2>
|
||||
<div class="row mt16 o_settings_container" id="tasks_management">
|
||||
<div class="col-12 col-lg-6 o_setting_box">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="group_subtask_project"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="group_subtask_project"/>
|
||||
<div class="text-muted">
|
||||
Split your tasks to organize your work into sub-milestones
|
||||
<xpath expr="//form" position="inside">
|
||||
<app data-string="Project" string="Project" name="project" groups="project.group_project_manager">
|
||||
<block title="Tasks Management" id="tasks_management">
|
||||
<setting id="project_stages" help="Track the progress of your projects">
|
||||
<field name="group_project_stages"/>
|
||||
<div class="content-group" invisible="not group_project_stages">
|
||||
<div class="mt8">
|
||||
<button name="%(project.project_project_stage_configure)d" icon="oi-arrow-right" type="action" string="Configure Stages" class="btn-link"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="recurring_tasks_setting">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="group_project_recurring_tasks"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="group_project_recurring_tasks"/>
|
||||
<div class="text-muted">
|
||||
Auto-generate tasks for regular activities
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="task_dependencies_setting">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="group_project_task_dependencies"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="group_project_task_dependencies"/>
|
||||
<div class="text-muted">
|
||||
Determine the order in which to perform tasks
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="project_stages">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="group_project_stages"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="group_project_stages"/>
|
||||
<div class="text-muted">
|
||||
Track the progress of your projects
|
||||
</div>
|
||||
<div class="content-group" attrs="{'invisible': [('group_project_stages', '=', False)]}">
|
||||
<div class="mt8">
|
||||
<button name="%(project.project_project_stage_configure)d" icon="fa-arrow-right" type="action" string="Configure Stages" class="btn-link"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="project_milestone">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="group_project_milestone"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="group_project_milestone"/>
|
||||
<div class="text-muted">
|
||||
Track major progress points that must be reached to achieve success
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h2>Time Management</h2>
|
||||
<div class="row mt16 o_settings_container" name="project_time">
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="log_time_tasks_setting">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="module_hr_timesheet"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="module_hr_timesheet"/>
|
||||
<div class="text-muted">
|
||||
Track time spent on projects and tasks
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box" name="project_time_management">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="module_project_forecast" widget="upgrade_boolean"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="module_project_forecast"/>
|
||||
<div class="text-muted" name="project_forecast_msg">
|
||||
Plan resource allocation across projects and estimate deadlines more accurately
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h2 name="section_analytics">Analytics</h2>
|
||||
<div class="row mt16 o_settings_container" name="analytic">
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="track_customer_satisfaction_setting">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="group_project_rating"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="group_project_rating"/>
|
||||
<div class="text-muted">
|
||||
Track customer satisfaction on tasks
|
||||
</div>
|
||||
<div class="content-group" attrs="{'invisible': [('group_project_rating', '=', False)]}">
|
||||
<div class="mt16">
|
||||
<button name="%(project.open_task_type_form)d" context="{'project_id':id}" icon="fa-arrow-right" type="action" string="Set a Rating Email Template on Stages" class="btn-link"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box"
|
||||
id="default_plan_setting"
|
||||
groups="analytic.group_analytic_accounting"
|
||||
title="Track the profitability of your projects. Any project, its tasks and timesheets are linked to an analytic account and any analytic account belongs to a plan.">
|
||||
<div class="o_setting_left_pane"/>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="analytic_plan_id"/>
|
||||
<span class="fa fa-lg fa-building-o" title="Values set here are company-specific." groups="base.group_multi_company"/>
|
||||
<div class="text-muted">
|
||||
Assign each new project to this plan
|
||||
</div>
|
||||
<div class="content-group">
|
||||
<div class="mt16">
|
||||
<field name="analytic_plan_id"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</setting>
|
||||
</block>
|
||||
<block title="Time Management" name="project_time">
|
||||
<setting id="log_time_tasks_setting" help="Track time spent on projects and tasks">
|
||||
<field name="module_hr_timesheet"/>
|
||||
</setting>
|
||||
</block>
|
||||
</app>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_config_settings_action" model="ir.actions.act_window">
|
||||
<field name="name">Settings</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.config.settings</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">inline</field>
|
||||
<field name="context">{'module' : 'project', 'bin_size': False}</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="project_config_settings_menu_action" name="Settings" parent="menu_project_config"
|
||||
sequence="0" action="project_config_settings_action" groups="base.group_system"/>
|
||||
</odoo>
|
||||
|
|
|
|||
|
|
@ -1,22 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!-- Partners inherited form -->
|
||||
<record id="view_task_partner_info_form" model="ir.ui.view">
|
||||
<field name="name">res.partner.task.buttons</field>
|
||||
<field name="model">res.partner</field>
|
||||
<field name="inherit_id" ref="base.view_partner_form"/>
|
||||
<field name="priority" eval="7"/>
|
||||
<field name="priority" eval="8"/>
|
||||
<field name="arch" type="xml">
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button" type="action" name="%(project_task_action_from_partner)d"
|
||||
groups="project.group_project_user"
|
||||
context="{'search_default_partner_id': active_id, 'default_partner_id': active_id}" attrs="{'invisible': [('task_count', '=', 0)]}"
|
||||
icon="fa-tasks">
|
||||
<button class="oe_stat_button" type="object" name="action_view_tasks" groups="project.group_project_user" icon="fa-tasks">
|
||||
<field string="Tasks" name="task_count" widget="statinfo"/>
|
||||
</button>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue