mirror of
https://github.com/bringout/oca-ocb-project.git
synced 2026-04-20 02:02:04 +02:00
Initial commit: Project packages
This commit is contained in:
commit
89613c97b0
753 changed files with 496325 additions and 0 deletions
|
|
@ -0,0 +1,21 @@
|
|||
<?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>
|
||||
16
odoo-bringout-oca-ocb-project/project/views/digest_views.xml
Normal file
16
odoo-bringout-oca-ocb-project/project/views/digest_views.xml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<odoo>
|
||||
<record id="digest_digest_view_form" model="ir.ui.view">
|
||||
<field name="name">digest.digest.view.form.inherit.project.task</field>
|
||||
<field name="model">digest.digest</field>
|
||||
<field name="priority">40</field>
|
||||
<field name="inherit_id" ref="digest.digest_digest_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//group[@name='kpis']/group[last()]" position="before">
|
||||
<group name="kpi_project" string="Project" groups="project.group_project_user">
|
||||
<field name="kpi_project_task_opened"/>
|
||||
</group>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<?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="domain">['|', ('res_model', '=', False), ('res_model', '=', 'project.task')]</field>
|
||||
<field name="context">{'default_res_model': 'project.task'}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No activity types found. Let's create one!
|
||||
</p><p>
|
||||
Those represent the different categories of things you have to do (e.g. "Call" or "Send email").
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
<menuitem id="project_menu_config_activity_type"
|
||||
action="mail_activity_type_action_config_project_types"
|
||||
parent="menu_project_config"/>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
<?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>
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
<?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>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="%(project.action_view_task_from_milestone)d"
|
||||
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"
|
||||
>
|
||||
<!-- 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"/>
|
||||
</span>
|
||||
<span class="o_stat_text">Tasks</span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<group>
|
||||
<group name="main_details">
|
||||
<field name="project_id" invisible="1"/>
|
||||
<field name="name" placeholder="e.g: Product Launch"/>
|
||||
<field name="deadline"/>
|
||||
<field name="is_reached"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_milestone_view_tree" model="ir.ui.view">
|
||||
<field name="name">project.milestone.view.tree</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">
|
||||
<field name="name"/>
|
||||
<field name="deadline" optional="show"/>
|
||||
<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>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,366 @@
|
|||
<?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>
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
<?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="model">project.project.stage</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree editable="bottom" sample="1">
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="name"/>
|
||||
<field name="mail_template_id" optional="hide" context="{'default_model': 'project.project'}"/>
|
||||
<field name="fold" optional="show"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_project_stage_view_form_quick_create" model="ir.ui.view">
|
||||
<field name="name">project.project.stage.view.form.quick.create</field>
|
||||
<field name="model">project.project.stage</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="mail_template_id"/>
|
||||
<field name="fold"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_project_stage_view_form" model="ir.ui.view">
|
||||
<field name="name">project.project.stage.view.form</field>
|
||||
<field name="model">project.project.stage</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<sheet>
|
||||
<widget name="web_ribbon" title="Archived" bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}"/>
|
||||
<h1><field name="name" placeholder="New"/></h1>
|
||||
<group>
|
||||
<group>
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="mail_template_id" context="{'default_model': 'project.project'}"/>
|
||||
<field name="sequence" groups="base.group_no_one"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="fold"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_project_stage_view_kanban" model="ir.ui.view">
|
||||
<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"/>
|
||||
<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>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_project_stage_view_search" model="ir.ui.view">
|
||||
<field name="name">project.project.stage.view.search</field>
|
||||
<field name="model">project.project.stage</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="name"/>
|
||||
<field name="mail_template_id"/>
|
||||
<filter string="Archived" name="archived" domain="[('active', '=', False)]"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<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="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No stages found. Let's create one!
|
||||
</p><p>
|
||||
Define the steps your projects move through from creation to completion.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<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_id" ref="project_project_stage_view_tree"/>
|
||||
<field name="act_window_id" ref="project_project_stage_configure"/>
|
||||
</record>
|
||||
|
||||
<record id="project_project_stage_configure_view_kanban" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="2"/>
|
||||
<field name="view_mode">kanban</field>
|
||||
<field name="view_id" ref="project_project_stage_view_kanban"/>
|
||||
<field name="act_window_id" ref="project_project_stage_configure"/>
|
||||
</record>
|
||||
|
||||
<record id="project_project_stage_configure_view_form" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="3"/>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="project_project_stage_view_form"/>
|
||||
<field name="act_window_id" ref="project_project_stage_configure"/>
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<?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>
|
||||
|
|
@ -0,0 +1,371 @@
|
|||
<?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,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="task_track_depending_tasks">
|
||||
<span>Task: <a href="#" data-oe-model="project.task" t-att-data-oe-id="child.id" t-esc="child.name"/></span>
|
||||
<br/>
|
||||
<t t-if="child_subtype">
|
||||
<span><t t-esc="child_subtype"/></span><br/>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
<?xml version="1.0"?>
|
||||
<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']">
|
||||
<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>
|
||||
</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>)
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="project_update_default_description" name="Project Update Description">
|
||||
<!--As this template is rendered in an html field, the spaces may be interpreted as nbsp while editing. -->
|
||||
<div name="summary">
|
||||
<br/><h1 style="font-weight: bolder;">Summary</h1>
|
||||
<br/><p>How’s this project going?</p><br/><br/>
|
||||
</div>
|
||||
|
||||
<div name="activities" t-if="show_activities">
|
||||
<h1 style="font-weight: bolder;">Activities</h1>
|
||||
</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>
|
||||
<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="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"}'/>)
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
</t>
|
||||
|
||||
<t t-if="milestones['created']">
|
||||
<t t-if="len(milestones['created']) > 1">The following milestones have been added:</t>
|
||||
<t t-else="">The following milestone has been added:</t>
|
||||
<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>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
</t>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="project_update_view_search" model="ir.ui.view">
|
||||
<field name="name">project.update.view.search</field>
|
||||
<field name="model">project.update</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Update">
|
||||
<field name="name"/>
|
||||
<field name="project_id" invisible="1"/>
|
||||
<field name="user_id"/>
|
||||
<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')]"/>
|
||||
<filter string="Off Track" name="off_track" domain="[('status', '=', 'off_track')]"/>
|
||||
<filter string="On Hold" name="on_hold" domain="[('status', '=', 'on_hold')]"/>
|
||||
<separator/>
|
||||
<filter name="date" string="Date" date="date"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_update_view_form" model="ir.ui.view">
|
||||
<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">
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
<h1>
|
||||
<field name="name" class="o_text_overflow" placeholder="e.g. Monthly review"/>
|
||||
</h1>
|
||||
</div>
|
||||
<group>
|
||||
<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="progress" widget="progressbar" options="{'editable': true}"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="user_id" widget="many2one_avatar_user" readonly="1"/>
|
||||
<field name="date"/>
|
||||
</group>
|
||||
</group>
|
||||
<separator/>
|
||||
<notebook>
|
||||
<page string="Description" name="description">
|
||||
<field name="description" nolabel="1" class="o_project_update_description" options="{'resizable': false, 'collaborative': true}"/>
|
||||
</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>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_update_view_kanban" model="ir.ui.view">
|
||||
<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">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_update_view_tree" model="ir.ui.view">
|
||||
<field name="name">project.update.view.tree</field>
|
||||
<field name="model">project.update</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree 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="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>
|
||||
</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="res_model">project.update</field>
|
||||
<field name="view_mode">kanban,tree,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">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No updates found. Let's create one!
|
||||
</p><p>
|
||||
Get a snapshot of the status of your project and share its progress with key stakeholders.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
1882
odoo-bringout-oca-ocb-project/project/views/project_views.xml
Normal file
1882
odoo-bringout-oca-ocb-project/project/views/project_views.xml
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,312 @@
|
|||
<?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="model">rating.rating</field>
|
||||
<field name="inherit_id" ref="rating.rating_rating_view_tree"/>
|
||||
<field name="mode">primary</field>
|
||||
<field name="priority">64</field>
|
||||
<field name="arch" type="xml">
|
||||
<field name="res_name" position="attributes">
|
||||
<attribute name="string">Task</attribute>
|
||||
</field>
|
||||
<field name="parent_res_name" position="attributes">
|
||||
<attribute name="string">Project</attribute>
|
||||
</field>
|
||||
<field name="rated_partner_id" position="attributes">
|
||||
<attribute name="string">Assigned to</attribute>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="rating_rating_view_form_project" model="ir.ui.view">
|
||||
<field name="name">rating.rating.form.project</field>
|
||||
<field name="model">rating.rating</field>
|
||||
<field name="inherit_id" ref="rating.rating_rating_view_form_text"/>
|
||||
<field name="mode">primary</field>
|
||||
<field name="priority">64</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//form" position="attributes">
|
||||
<attribute name="edit">0</attribute>
|
||||
</xpath>
|
||||
<field name="resource_ref" position="before">
|
||||
<field name="rated_partner_id" position="move"/>
|
||||
<field name="parent_ref" position="move"/>
|
||||
</field>
|
||||
<field name="res_name" position="attributes">
|
||||
<attribute name="string">Task</attribute>
|
||||
</field>
|
||||
<field name="resource_ref" position="attributes">
|
||||
<attribute name="string">Task</attribute>
|
||||
</field>
|
||||
<field name="parent_ref" position="attributes">
|
||||
<attribute name="string">Project</attribute>
|
||||
</field>
|
||||
<field name="parent_res_name" position="attributes">
|
||||
<attribute name="string">Project</attribute>
|
||||
</field>
|
||||
<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="partner_id" position="move"/>
|
||||
</field>
|
||||
<xpath expr="//field[@name='is_internal']" position="attributes">
|
||||
<attribute name="invisible">1</attribute>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="rating_rating_view_pivot" model="ir.ui.view">
|
||||
<field name="name">rating.rating.view.pivot.project</field>
|
||||
<field name="model">rating.rating</field>
|
||||
<field name="inherit_id" ref="rating.rating_rating_view_pivot"/>
|
||||
<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">
|
||||
<attribute name="invisible">1</attribute>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="rating_rating_view_graph" model="ir.ui.view">
|
||||
<field name="name">rating.rating.view.graph.project</field>
|
||||
<field name="model">rating.rating</field>
|
||||
<field name="inherit_id" ref="rating.rating_rating_view_graph"/>
|
||||
<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>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="rating_rating_view_search_project" model="ir.ui.view">
|
||||
<field name="name">rating.rating.search.project</field>
|
||||
<field name="model">rating.rating</field>
|
||||
<field name="inherit_id" ref="rating.rating_rating_view_search"/>
|
||||
<field name="mode">primary</field>
|
||||
<field name="priority">64</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='rated_partner_id']" position="after">
|
||||
<field name="parent_res_name" position="move"/>
|
||||
<field name="res_name" position="move"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='rated_partner_id']" position="attributes">
|
||||
<attribute name="string">Assigned to</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='parent_res_name']" position="attributes">
|
||||
<attribute name="string">Project</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='res_name']" position="attributes">
|
||||
<attribute name="string">Task</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//filter[@name='responsible']" position="after">
|
||||
<filter name="rating_text" position="move"/>
|
||||
<filter string="Project" name="groupby_project" context="{'group_by': 'parent_res_name'}"/>
|
||||
<filter name="resource" position="move"/>
|
||||
<filter name="customer" position="move"/>
|
||||
</xpath>
|
||||
<xpath expr="//filter[@name='resource']" position="attributes">
|
||||
<attribute name="string">Task</attribute>
|
||||
</xpath>
|
||||
<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>
|
||||
<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>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<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="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">
|
||||
<p class="o_view_nocontent_empty_folder">
|
||||
There are no ratings for this project at the moment
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="rating_rating_action_view_project_rating_kanban" model="ir.actions.act_window.view">
|
||||
<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"/>
|
||||
</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="act_window_id" ref="rating_rating_action_view_project_rating"/>
|
||||
<field name="view_id" ref="rating_rating_view_tree_project"/>
|
||||
</record>
|
||||
|
||||
<record id="rating_rating_action_view_project_rating_form" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="40"/>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="act_window_id" ref="rating_rating_action_view_project_rating"/>
|
||||
<field name="view_id" ref="rating_rating_view_form_project"/>
|
||||
</record>
|
||||
|
||||
<record id="rating_rating_action_view_project_rating_pivot" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="40"/>
|
||||
<field name="view_mode">pivot</field>
|
||||
<field name="act_window_id" ref="rating_rating_action_view_project_rating"/>
|
||||
<field name="view_id" ref="rating_rating_view_pivot"/>
|
||||
</record>
|
||||
|
||||
<record id="rating_rating_action_view_project_rating_graph" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="40"/>
|
||||
<field name="view_mode">graph</field>
|
||||
<field name="act_window_id" ref="rating_rating_action_view_project_rating"/>
|
||||
<field name="view_id" ref="rating_rating_view_graph"/>
|
||||
</record>
|
||||
|
||||
<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="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">
|
||||
<p class="o_view_nocontent_empty_folder">
|
||||
No customer ratings yet
|
||||
</p>
|
||||
<p>
|
||||
Let's wait for your customers to manifest themselves.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="rating_rating_action_task_kanban" model="ir.actions.act_window.view">
|
||||
<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"/>
|
||||
</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="act_window_id" ref="rating_rating_action_task"/>
|
||||
<field name="view_id" ref="rating_rating_view_tree_project"/>
|
||||
</record>
|
||||
|
||||
<record id="rating_rating_action_task_form" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="40"/>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="act_window_id" ref="rating_rating_action_task"/>
|
||||
<field name="view_id" ref="rating_rating_view_form_project"/>
|
||||
</record>
|
||||
|
||||
<record id="rating_rating_action_task_pivot" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="40"/>
|
||||
<field name="view_mode">pivot</field>
|
||||
<field name="act_window_id" ref="rating_rating_action_task"/>
|
||||
<field name="view_id" ref="rating_rating_view_pivot"/>
|
||||
</record>
|
||||
|
||||
<record id="rating_rating_action_task_graph" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="40"/>
|
||||
<field name="view_mode">graph</field>
|
||||
<field name="act_window_id" ref="rating_rating_action_task"/>
|
||||
<field name="view_id" ref="rating_rating_view_graph"/>
|
||||
</record>
|
||||
|
||||
<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="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">
|
||||
<p class="o_view_nocontent_empty_folder">
|
||||
No customer ratings yet
|
||||
</p>
|
||||
<p>
|
||||
Measure your customer satisfaction by sending rating requests when your tasks reach a certain stage.
|
||||
</p>
|
||||
</field>
|
||||
<field name="context">{
|
||||
'search_default_last_month': 1,
|
||||
'graph_groupbys': ['rated_partner_id'],
|
||||
}</field>
|
||||
</record>
|
||||
|
||||
<record id="rating_rating_action_project_report_kanban" model="ir.actions.act_window.view">
|
||||
<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"/>
|
||||
</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="act_window_id" ref="rating_rating_action_project_report"/>
|
||||
<field name="view_id" ref="rating_rating_view_tree_project"/>
|
||||
</record>
|
||||
|
||||
<record id="rating_rating_action_project_report_form" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="40"/>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="act_window_id" ref="rating_rating_action_project_report"/>
|
||||
<field name="view_id" ref="rating_rating_view_form_project"/>
|
||||
</record>
|
||||
|
||||
<record id="rating_rating_action_project_report_pivot" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="40"/>
|
||||
<field name="view_mode">pivot</field>
|
||||
<field name="act_window_id" ref="rating_rating_action_project_report"/>
|
||||
<field name="view_id" ref="rating_rating_view_pivot"/>
|
||||
</record>
|
||||
|
||||
<record id="rating_rating_action_project_report_graph" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="40"/>
|
||||
<field name="view_mode">graph</field>
|
||||
<field name="act_window_id" ref="rating_rating_action_project_report"/>
|
||||
<field name="view_id" ref="rating_rating_view_graph"/>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="res_config_settings_view_form" model="ir.ui.view">
|
||||
<field name="name">res.config.settings.view.form.inherit.project</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<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
|
||||
</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>
|
||||
</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>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?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="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">
|
||||
<field string="Tasks" name="task_count" widget="statinfo"/>
|
||||
</button>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
Loading…
Add table
Add a link
Reference in a new issue