summaryrefslogtreecommitdiff
path: root/addons/project
diff options
context:
space:
mode:
authorYannick Tivisse (yti) <yti@odoo.com>2020-04-28 09:13:36 +0000
committerYannick Tivisse <yti@odoo.com>2020-06-02 12:11:57 +0000
commitdadcec593d8328727b17f218c69fa1bc1433686f (patch)
treead4118a8d96351d5b67725112aa863c6a0096b7f /addons/project
parent09ac18776f73b00f28d222ff544bb209682a2637 (diff)
[IMP] project: Improve global UX (back2basics)
Improve the onboarding of new users and clean a few screens. Task ID: 2237996 closes odoo/odoo#50284 Related: odoo/enterprise#10536 Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com> Co-authored-by: dmonzonis <mod@odoo.com>
Diffstat (limited to 'addons/project')
-rw-r--r--addons/project/data/project_data.xml202
-rw-r--r--addons/project/models/project.py90
-rw-r--r--addons/project/report/project_report_views.xml29
-rw-r--r--addons/project/static/src/js/project_rating_reporting.js69
-rw-r--r--addons/project/views/project_assets.xml1
-rw-r--r--addons/project/views/project_views.xml98
-rw-r--r--addons/project/views/rating_views.xml158
-rw-r--r--addons/project/views/res_config_settings_views.xml4
8 files changed, 325 insertions, 326 deletions
diff --git a/addons/project/data/project_data.xml b/addons/project/data/project_data.xml
index 5e45f5c628b..63c31fe3775 100644
--- a/addons/project/data/project_data.xml
+++ b/addons/project/data/project_data.xml
@@ -83,206 +83,4 @@
<field name="parent_id" ref="mt_task_rating"/>
<field name="relation_field">project_id</field>
</record>
-
- <record forcecreate="False" id="project_project_data" model="project.project">
- <field name="name">Start here to discover Odoo</field>
- <field name="privacy_visibility">followers</field>
- <field name="user_id" ref="base.user_admin"/>
- <field name="active" eval="False"/>
- <field name="alias_name">discover</field>
- <field name="alias_model_id" ref="model_project_task"/>
- <field name="alias_contact">everyone</field>
- <field name="alias_defaults">{'project_id': 1}</field>
- <field name="alias_force_thread_id">0</field>
- <field name="alias_parent_model_id" ref="model_project_project"/>
- <field name="rating_status">stage</field>
- </record>
-
- <record forcecreate="False" id="project_stage_data_0" model="project.task.type">
- <field name="sequence">1</field>
- <field name="name">First Steps</field>
- <field name="project_ids" eval="[(4, ref('project_project_data'))]"/>
- </record>
-
- <record forcecreate="False" id="project_stage_data_1" model="project.task.type">
- <field name="sequence">2</field>
- <field name="name">Getting Better</field>
- <field name="project_ids" eval="[(4, ref('project_project_data'))]"/>
- </record>
-
- <record forcecreate="False" id="project_stage_data_2" model="project.task.type">
- <field name="sequence">3</field>
- <field name="name">Wow... You're Amazing!</field>
- <field name="project_ids" eval="[(4, ref('project_project_data'))]"/>
- </record>
-
- <record forcecreate="False" id="project_task_data_0" model="project.task">
- <field name="sequence">1</field>
- <field name="user_id" ref="base.user_admin"/>
- <field name="priority">0</field>
- <field name="project_id" ref="project.project_project_data"/>
- <field name="active" eval="False"/>
- <field name="name">Welcome to Odoo</field>
- <field name="description" type="xml">
- <p>Welcome!</p>
- <p>This project has the objective to show you all the main features from the project app.</p>
- <p>Each card will teach you tips and tricks to easily manage your projects and tasks.</p>
- </field>
- <field name="color">2</field>
- <field name="stage_id" ref="project_stage_data_0"/>
- </record>
-
- <record forcecreate="False" id="project_task_data_1" model="project.task">
- <field name="sequence">5</field>
- <field name="user_id" ref="base.user_admin"/>
- <field name="priority">0</field>
- <field name="project_id" ref="project.project_project_data"/>
- <field name="name">Try to play with the filters</field>
- <field name="description" type="xml">
- <p>Go back to the tasks view to play with the filters. Try to identify unassigned tasks or tasks that are overdue, for instance.</p>
- <p>Hint: the filters and the search bar are available in the top right corner of your screen.</p>
- </field>
- <field name="stage_id" ref="project_stage_data_1"/>
- </record>
-
- <record forcecreate="False" id="project_task_data_5" model="project.task">
- <field name="sequence">2</field>
- <field name="user_id" ref="base.user_admin"/>
- <field name="priority">0</field>
- <field name="project_id" ref="project.project_project_data"/>
- <field name="name">Try to drag &amp; drop this task wherever your want</field>
- <field name="description">... or try changing the status of your task from here.</field>
- <field name="kanban_state">done</field>
- <field name="stage_id" ref="project_stage_data_0"/>
- </record>
-
- <record forcecreate="False" id="project_task_data_2" model="project.task">
- <field name="sequence">3</field>
- <field name="user_id" ref="base.user_admin"/>
- <field name="priority">0</field>
- <field name="project_id" ref="project.project_project_data"/>
- <field name="name">Star this task to prioritize it</field>
- <field name="description" type="xml"><p>Click on the top left icon to prioritize this task and go back to the kanban view.</p> <p>Your task is now at the top of the stage.</p></field>
- <field name="stage_id" ref="project_stage_data_0"/>
- </record>
-
- <record forcecreate="False" id="project_task_data_4" model="project.task">
- <field name="sequence">3</field>
- <field name="user_id" ref="base.user_admin"/>
- <field name="priority">0</field>
- <field name="project_id" ref="project.project_project_data"/>
- <field name="name">Use the chatter to collaborate with your team</field>
- <field name="stage_id" ref="project_stage_data_1"/>
- </record>
-
- <record forcecreate="False" id="msg_task_4" model="mail.message">
- <field name="subject">Converse with your customers and colleagues</field>
- <field name="model">project.task</field>
- <field name="author_id" ref="base.partner_root"/>
- <field name="res_id" ref="project_task_data_4"/>
- <field name="body">Use this chatter to send emails. Add new people in the followers list to make them aware about the main changes about this task.</field>
- <field name="message_type">email</field>
- <field name="subtype_id" ref="mail.mt_comment"/>
- </record>
-
- <record forcecreate="False" id="msg_task_4_1" model="mail.message">
- <field name="subject">Converse with your customers and colleagues</field>
- <field name="model">project.task</field>
- <field name="author_id" ref="base.partner_root"/>
- <field name="res_id" ref="project_task_data_4"/>
- <field name="body">Use @ mentions to ping a colleague or # mentions to contact an entire team. The people following this task won't be notified of the note you are logging unless you specifically tag them.</field>
- <field name="message_type">comment</field>
- <field name="subtype_id" ref="mail.mt_note"/>
- </record>
-
- <record forcecreate="False" id="project_task_data_10" model="project.task">
- <field name="sequence">4</field>
- <field name="user_id" ref="base.user_admin"/>
- <field name="priority">0</field>
- <field name="project_id" ref="project.project_project_data"/>
- <field name="name">Organize your work by using activities.</field>
- <field name="stage_id" ref="project_stage_data_1"/>
- </record>
-
- <record forcecreate="False" id="mail_activity_task_4" model="mail.activity">
- <field name="res_id" ref="project_task_data_10"/>
- <field name="res_model_id" ref="model_project_task"/>
- <field name="activity_type_id" ref="mail.mail_activity_data_todo" />
- <field name="date_deadline" eval="datetime.now()+timedelta(days=5)"/>
- <field name="summary">Use activities to organize your work. Try marking this activity as done.</field>
- <field name="create_uid" ref="base.user_root"/>
- <field name="user_id" ref="base.user_root"/>
- </record>
-
- <record forcecreate="False" id="project_tag_data" model="project.tags">
- <field name="name">Need Assistance</field>
- <field name="color" eval="5"/>
- </record>
-
- <record forcecreate="False" id="project_task_data_6" model="project.task">
- <field name="sequence">1</field>
- <field name="user_id" ref="base.user_admin"/>
- <field name="priority">0</field>
- <field name="project_id" ref="project.project_project_data"/>
- <field name="name">Use tags to categorize your tasks</field>
- <field name="kanban_state">blocked</field>
- <field name="stage_id" ref="project_stage_data_1"/>
- <field name="description" type="xml"><p>Tags will be represented by colored dots on your task's card.</p>
- <p>Click on a tag to define its color.</p>
- <p>Tip: you can also define a color for your task from the tasks view.</p></field>
- <field name="tag_ids" eval="[(6,0,[ref('project.project_tag_data')])]"/>
- </record>
-
- <record forcecreate="False" id="project_task_data_12" model="project.task">
- <field name="sequence">1</field>
- <field name="user_id" ref="base.user_admin"/>
- <field name="priority">0</field>
- <field name="project_id" ref="project.project_project_data"/>
- <field name="color">3</field>
- <field name="name">Try to customize this card. Change its background.</field>
- <field name="description">Use the edit icon on the card from the tasks view to customize its background.</field>
- <field name="stage_id" ref="project_stage_data_2"/>
- </record>
-
- <record forcecreate="False" id="project_task_data_13" model="project.task">
- <field name="sequence">4</field>
- <field name="user_id" ref="base.user_admin"/>
- <field name="priority">0</field>
- <field name="project_id" ref="project.project_project_data"/>
- <field name="name">Set this task as being 'Ready for next stage'</field>
- <field name="description" type="xml"><p>You can change this task's state by clicking on the small circle on the card, or here, next to the task's title.</p>
- <p>Kanban states are perfect to let your colleagues know that your task is ready to be proceeded or that you need help on something.</p></field>
- <field name="stage_id" ref="project_stage_data_0"/>
- </record>
-
- <record forcecreate="False" id="project_task_data_9" model="project.task">
- <field name="sequence">2</field>
- <field name="user_id" ref="base.user_admin"/>
- <field name="priority">0</field>
- <field name="project_id" ref="project.project_project_data"/>
- <field name="name">You want to add a stage? Add a new column!</field>
- <field name="stage_id" ref="project_stage_data_2"/>
- <field name="description" type="xml"><p>Click on the last column of your tasks view to create a stage.</p><p>Feel free to adapt the steps to your business workflow by drag &amp; dropping your stages in the right places.</p> <p>Tip: You can also fold the stages you don't need to see permanently.</p></field>
- </record>
-
- <record forcecreate="false" id="project_task_data_11" model="project.task">
- <field name="sequence">2</field>
- <field name="user_id" ref="base.user_admin"/>
- <field name="priority">0</field>
- <field name="project_id" ref="project.project_project_data"/>
- <field name="name">You can set a deadline on a task</field>
- <field name="description" type="xml"><p>Deadlines are useful to get things done on time.</p><p>You will get visual clues when the due date is close or due.</p></field>
- <field name="stage_id" ref="project_stage_data_1"/>
- <field name="date_deadline" eval="datetime.now()-timedelta(days=7)"/>
- </record>
-
- <record forcecreate="false" id="project_task_data_15" model="project.task">
- <field name="sequence">5</field>
- <field name="priority">0</field>
- <field name="user_id" eval="False" />
- <field name="project_id" ref="project.project_project_data"/>
- <field name="name">Assign yourself to this task</field>
- <field name="stage_id" ref="project_stage_data_0"/>
- </record>
-
</odoo>
diff --git a/addons/project/models/project.py b/addons/project/models/project.py
index 7e8f86198aa..b2cb1b25a9a 100644
--- a/addons/project/models/project.py
+++ b/addons/project/models/project.py
@@ -133,36 +133,6 @@ class Project(models.Model):
action['context'] = "{'default_res_model': '%s','default_res_id': %d}" % (self._name, self.id)
return action
- @api.model
- def activate_sample_project(self):
- """ Unarchives the sample project 'project.project_project_data' and
- reloads the project dashboard """
- # Unarchive sample project
- project = self.env.ref('project.project_project_data', False)
- if project:
- project.write({'active': True})
-
- cover_image = self.env.ref('project.msg_task_data_14_attach', False)
- cover_task = self.env.ref('project.project_task_data_14', False)
- if cover_image and cover_task:
- cover_task.write({'displayed_image_id': cover_image.id})
-
- # Change the help message on the action (no more activate project)
- action = self.env.ref('project.open_view_project_all', False)
- action_data = None
- if action:
- action.sudo().write({
- "help": _('''<p class="o_view_nocontent_smiling_face">
- Create a new project</p>''')
- })
- action_data = action.read()[0]
-
- action_config = self.env.ref('project.open_view_project_all_config', False)
- if action_config:
- action_config.sudo().write({'help': action.help})
- # Reload the dashboard
- return action_data
-
def _compute_is_favorite(self):
for project in self:
project.is_favorite = self.env.user in project.favorite_user_ids
@@ -183,6 +153,7 @@ class Project(models.Model):
return [(6, 0, [self.env.uid])]
name = fields.Char("Name", index=True, required=True, tracking=True)
+ description = fields.Text()
active = fields.Boolean(default=True,
help="If the active field is set to False, it will allow you to hide the project without removing it.")
sequence = fields.Integer(default=10, help="Gives the sequence order when displaying a list of Projects.")
@@ -204,15 +175,14 @@ class Project(models.Model):
tasks = fields.One2many('project.task', 'project_id', string="Task Activities")
resource_calendar_id = fields.Many2one(
'resource.calendar', string='Working Time',
- default=lambda self: self.env.company.resource_calendar_id.id,
- domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]",
- help="Timetable working hours to adjust the gantt diagram report")
+ related='company_id.resource_calendar_id')
type_ids = fields.Many2many('project.task.type', 'project_task_type_rel', 'project_id', 'type_id', string='Tasks Stages')
task_count = fields.Integer(compute='_compute_task_count', string="Task Count")
task_ids = fields.One2many('project.task', 'project_id', string='Tasks',
domain=['|', ('stage_id.fold', '=', False), ('stage_id', '=', False)])
color = fields.Integer(string='Color Index')
user_id = fields.Many2one('res.users', string='Project Manager', default=lambda self: self.env.user, tracking=True)
+ alias_enabled = fields.Boolean(string='Use email alias', compute='_compute_alias_enabled', readonly=False)
alias_id = fields.Many2one('mail.alias', string='Alias', ondelete="restrict", required=True,
help="Internal email associated with this project. Incoming emails are automatically synchronized "
"with Tasks (or optionally Issues if the Issue Tracker module is installed).")
@@ -271,6 +241,10 @@ class Project(models.Model):
defaults['allow_subtasks'] = self.env.user.has_group('project.group_subtask_project')
return defaults
+ def _compute_alias_enabled(self):
+ for project in self:
+ project.alias_enabled = project.alias_domain and project.alias_id.alias_name
+
@api.depends('allowed_internal_user_ids', 'allowed_portal_user_ids')
def _compute_allowed_users(self):
for project in self:
@@ -580,8 +554,13 @@ class Task(models.Model):
domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]")
partner_is_company = fields.Boolean(related='partner_id.is_company', readonly=True)
commercial_partner_id = fields.Many2one(related='partner_id.commercial_partner_id')
- partner_email = fields.Char(related='partner_id.email', string='Customer Email')
- partner_phone = fields.Char(related='partner_id.phone')
+ partner_email = fields.Char(
+ compute='_compute_partner_email', inverse='_inverse_partner_email',
+ string='Email', readonly=False, store=True)
+ partner_phone = fields.Char(
+ compute='_compute_partner_phone', inverse='_inverse_partner_phone',
+ string="Phone", readonly=False, store=True)
+ ribbon_message = fields.Char('Ribbon message', compute='_compute_ribbon_message')
partner_city = fields.Char(related='partner_id.city', readonly=False)
manager_id = fields.Many2one('res.users', string='Project Manager', related='project_id.user_id', readonly=True)
company_id = fields.Many2one('res.company', string='Company', required=True, default=_default_company_id)
@@ -600,7 +579,7 @@ class Task(models.Model):
subtask_project_id = fields.Many2one('project.project', related="project_id.subtask_project_id", string='Sub-task Project', readonly=True)
allow_subtasks = fields.Boolean('project.project', related="project_id.allow_subtasks", readonly=True)
subtask_count = fields.Integer("Sub-task count", compute='_compute_subtask_count')
- email_from = fields.Char(string='Email', help="These people will receive email.", index=True,
+ email_from = fields.Char(string='Email From', help="These people will receive email.", index=True,
compute='_compute_email_from', store="True", readonly=False)
allowed_user_ids = fields.Many2many('res.users', string="Visible to", groups='project.group_project_manager', compute='_compute_allowed_user_ids', store=True, readonly=False)
project_privacy_visibility = fields.Selection(related='project_id.privacy_visibility', string="Project Visibility")
@@ -612,6 +591,43 @@ class Task(models.Model):
# customer portal: include comment and incoming emails in communication history
website_message_ids = fields.One2many(domain=lambda self: [('model', '=', self._name), ('message_type', 'in', ['email', 'comment'])])
+ @api.depends('partner_id.email')
+ def _compute_partner_email(self):
+ for task in self:
+ if task.partner_id and task.partner_id.email != task.partner_email:
+ task.partner_email = task.partner_id.email
+
+ def _inverse_partner_email(self):
+ for task in self:
+ if task.partner_id and task.partner_email != task.partner_id.email:
+ task.partner_id.email = task.partner_email
+
+ @api.depends('partner_id.phone')
+ def _compute_partner_phone(self):
+ for task in self:
+ if task.partner_id and task.partner_phone != task.partner_id.phone:
+ task.partner_phone = task.partner_id.phone
+
+ def _inverse_partner_phone(self):
+ for task in self:
+ if task.partner_id and task.partner_phone != task.partner_id.phone:
+ task.partner_id.phone = task.partner_phone
+
+ @api.depends('partner_email', 'partner_phone', 'partner_id')
+ def _compute_ribbon_message(self):
+ for task in self:
+ will_write_email = task.partner_id and task.partner_email != task.partner_id.email
+ will_write_phone = task.partner_id and task.partner_phone != task.partner_id.phone
+
+ if will_write_email and will_write_phone:
+ task.ribbon_message = _('By saving this change, the customer email and phone number will also be updated.')
+ elif will_write_email:
+ task.ribbon_message = _('By saving this change, the customer email will also be updated.')
+ elif will_write_phone:
+ task.ribbon_message = _('By saving this change, the customer phone number will also be updated.')
+ else:
+ task.ribbon_message = False
+
@api.constrains('parent_id')
def _check_parent_id(self):
if not self._check_recursion():
@@ -1086,7 +1102,7 @@ class ProjectTags(models.Model):
def _get_default_color(self):
return randint(1, 11)
- name = fields.Char('Tag Name', required=True)
+ name = fields.Char('Name', required=True)
color = fields.Integer(string='Color Index', default=_get_default_color)
_sql_constraints = [
diff --git a/addons/project/report/project_report_views.xml b/addons/project/report/project_report_views.xml
index 83a64e5ebfc..a12c6e05232 100644
--- a/addons/project/report/project_report_views.xml
+++ b/addons/project/report/project_report_views.xml
@@ -23,32 +23,6 @@
</field>
</record>
- <!-- Custom reports (aka filters) -->
- <record id="filter_task_report_task_pipe" model="ir.filters">
- <field name="name">Task Pipe</field>
- <field name="model_id">report.project.task.user</field>
- <field name="user_id" eval="False"/>
- <field name="context">{'group_by': ['project_id'], 'col_group_by': ['stage_id'], 'measures': ['nbr']}</field>
- </record>
- <record id="filter_task_report_workload" model="ir.filters">
- <field name="name">Workload</field>
- <field name="model_id">report.project.task.user</field>
- <field name="user_id" eval="False"/>
- <field name="context">{'group_by': ['project_id'], 'measures': ['planned_hours']}</field>
- </record>
- <record id="filter_task_report_responsible" model="ir.filters">
- <field name="name">By Responsible</field>
- <field name="model_id">report.project.task.user</field>
- <field name="user_id" eval="False"/>
- <field name="context">{'group_by': ['project_id', 'user_id']}</field>
- </record>
- <record id="filter_task_report_cumulative_flow" model="ir.filters">
- <field name="name">Cumulative Flow</field>
- <field name="model_id">report.project.task.user</field>
- <field name="user_id" eval="False"/>
- <field name="context">{'group_by': ['stage_id', 'state'], 'measures': ['nbr','planned_hours']}</field>
- </record>
-
<record id="view_task_project_user_search" model="ir.ui.view">
<field name="name">report.project.task.user.search</field>
<field name="model">report.project.task.user</field>
@@ -65,7 +39,6 @@
<field name="stage_id"/>
<filter string="Unassigned" name="unassigned" domain="[('user_id', '=', False)]"/>
<separator/>
- <filter string="New" name="new" domain="[('stage_id.sequence', '&lt;=', 1)]"/>
<group expand="0" string="Extended Filters">
<field name="priority"/>
<field name="company_id" groups="base.group_multi_company"/>
@@ -74,8 +47,6 @@
<filter string="Project" name="project" context="{'group_by': 'project_id'}"/>
<filter string="Assigned to" name="User" context="{'group_by': 'user_id'}"/>
<filter string="Stage" name="Stage" context="{'group_by': 'stage_id'}"/>
- <filter string="Assignment Date" name="assignation_month" context="{'group_by': 'date_assign:month'}"/>
- <filter string="Company" name="company" context="{'group_by': 'company_id'}" groups="base.group_multi_company"/>
</group>
</search>
</field>
diff --git a/addons/project/static/src/js/project_rating_reporting.js b/addons/project/static/src/js/project_rating_reporting.js
new file mode 100644
index 00000000000..8e393c677f0
--- /dev/null
+++ b/addons/project/static/src/js/project_rating_reporting.js
@@ -0,0 +1,69 @@
+odoo.define('project.project_rating_reporting', function (require) {
+'use strict';
+
+const core = require('web.core');
+const _t = core._t;
+
+const viewRegistry = require('web.view_registry');
+
+const PivotController = require('web.PivotController');
+const PivotView = require('web.PivotView');
+
+const GraphController = require('web.GraphController');
+const GraphView = require('web.GraphView');
+
+var ProjectPivotController = PivotController.extend({
+ /**
+ * @override
+ */
+ init: function () {
+ this._super.apply(this, arguments);
+ var measures = JSON.parse(JSON.stringify(this.measures));
+ if ('res_id' in measures) {
+ measures.res_id.string = _t('Task');
+ }
+ if ('parent_res_id' in measures) {
+ measures.parent_res_id.string = _t('Project');
+ }
+ if ('rating' in measures) {
+ measures.rating.string = _t('Rating Value (/5)');
+ }
+ this.measures = measures;
+ },
+});
+
+var ProjectPivotView = PivotView.extend({
+ config: _.extend({}, PivotView.prototype.config, {
+ Controller: ProjectPivotController,
+ }),
+});
+
+viewRegistry.add('project_rating_pivot', ProjectPivotView);
+
+var ProjectGraphController = GraphController.extend({
+ /**
+ * @override
+ */
+ init: function () {
+ this._super.apply(this, arguments);
+ _.each(this.measures, measure => {
+ if (measure.fieldName === 'res_id') {
+ measure.description = _t('Task');
+ } else if (measure.fieldName === 'parent_res_id') {
+ measure.description = _t('Project');
+ } else if (measure.fieldName === 'rating') {
+ measure.description = _t('Rating Value (/5)');
+ }
+ });
+ },
+});
+
+var ProjectGraphView = GraphView.extend({
+ config: _.extend({}, GraphView.prototype.config, {
+ Controller: ProjectGraphController,
+ }),
+});
+
+viewRegistry.add('project_rating_graph', ProjectGraphView);
+
+});
diff --git a/addons/project/views/project_assets.xml b/addons/project/views/project_assets.xml
index e6e6dddeea2..60c995c2a41 100644
--- a/addons/project/views/project_assets.xml
+++ b/addons/project/views/project_assets.xml
@@ -4,6 +4,7 @@
<xpath expr="." position="inside">
<link rel="stylesheet" href="/project/static/src/css/project.css"/>
<script type="text/javascript" src="/project/static/src/js/project_kanban.js"></script>
+ <script type="text/javascript" src="/project/static/src/js/project_rating_reporting.js"></script>
<script type="text/javascript" src="/project/static/src/js/project_task_kanban_examples.js"></script>
<script type="text/javascript" src="/project/static/src/js/tours/project.js"></script>
<link rel="stylesheet" type="text/scss" href="/project/static/src/scss/project_dashboard.scss"/>
diff --git a/addons/project/views/project_views.xml b/addons/project/views/project_views.xml
index 626f50cdc99..1f76002dd82 100644
--- a/addons/project/views/project_views.xml
+++ b/addons/project/views/project_views.xml
@@ -29,6 +29,7 @@
<separator/>
<filter string="Starred" name="starred" domain="[('priority', 'in', [1, 2])]"/>
<filter string="Late Tasks" name="late" domain="[('date_deadline', '&lt;', context_today().strftime('%Y-%m-%d'))]"/>
+ <filter string="Rated tasks" name="rating_task" domain="[('rating_last_value', '!=', 0.0)]" groups="project.group_project_rating"/>
<separator/>
<filter string="Unread Messages" name="message_needaction" domain="[('message_needaction', '=', True)]"/>
<separator/>
@@ -41,14 +42,11 @@
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', '&gt;', context_today().strftime('%Y-%m-%d'))]"/>
- <separator/>
- <filter string="Rated tasks" name="rating_task" domain="[('rating_last_value', '!=', 0.0)]" groups="project.group_project_rating"/>
<group expand="0" string="Group By">
<filter string="Stage" name="stage" context="{'group_by': 'stage_id'}"/>
<filter string="Assigned to" name="user" context="{'group_by': 'user_id'}"/>
<filter string="Project" name="project" context="{'group_by': 'project_id'}"/>
<filter string="Creation Date" name="group_create_date" context="{'group_by': 'create_date'}"/>
- <filter string="Company" name="company" context="{'group_by': 'company_id'}" groups="base.group_multi_company"/>
</group>
</search>
</field>
@@ -281,11 +279,12 @@
</h1>
<div name="options_active">
<div>
- <label for="label_tasks" class="oe_inline" string="Name of the tasks :"/>
+ <label for="label_tasks" class="oe_inline" string="Name of the tasks:"/>
<field name="label_tasks" class="oe_inline oe_input_align"/>
</div>
</div>
</div>
+ <field name="description" placeholder="Describe your project..."/>
<notebook>
<page name="settings" string="Settings">
<group>
@@ -293,6 +292,16 @@
<field name="active" invisible="1"/>
<field name="user_id" string="Project Manager" widget="many2one_avatar_user" attrs="{'readonly':[('active','=',False)]}" domain="[('share', '=', False)]"/>
<field name="partner_id" string="Customer"/>
+ <div name="alias_def" colspan="2" attrs="{'invisible': [('alias_domain', '=', False)]}">
+ <label for="alias_enabled" class="font-weight-bold" string="Create tasks by sending an email to"/>
+ <field name="alias_enabled"/>
+ <span attrs="{'invisible': [('alias_enabled', '=', False)]}">
+ <field name="alias_name" class="oe_inline" attrs="{'required': [('alias_enabled', '=', True)]}" />
+ @
+ <field name="alias_domain" class="oe_inline" readonly="1" />
+ </span>
+ </div>
+ <field name="alias_contact" class="oe_inline oe_edit_only" string="Accept Emails From" attrs="{'invisible': ['|', ('alias_domain', '=', False), ('alias_enabled', '=', False)]}"/>
</group>
<group>
<field name="analytic_account_id" domain="['|', ('company_id', '=', company_id), ('company_id', '=', False)]" context="{'default_partner_id': partner_id}" groups="analytic.group_analytic_accounting"/>
@@ -345,25 +354,6 @@
</div>
</div>
</div>
- <group name="misc">
- <group string="Time Scheduling">
- <field name="resource_calendar_id"/>
- </group>
- </group>
- </page>
- <page name="emails" string="Emails" attrs="{'invisible': [('alias_domain', '=', False)]}">
- <group name="group_alias">
- <label for="alias_name" string="Email Alias"/>
- <div name="alias_def">
- <field name="alias_id" class="oe_read_only oe_inline"
- string="Email Alias" required="0"/>
- <div class="oe_edit_only oe_inline" name="edit_alias" style="display: inline;" >
- <field name="alias_name" class="oe_inline"/>@<field name="alias_domain" class="oe_inline" readonly="1"/>
- </div>
- </div>
- <field name="alias_contact" class="oe_inline oe_edit_only"
- string="Accept Emails From"/>
- </group>
</page>
</notebook>
<div class="oe_chatter">
@@ -385,6 +375,7 @@
<filter string="My Favorites" name="my_projects" domain="[('favorite_user_ids', 'in', uid)]"/>
<separator/>
<filter string="Followed" name="followed_by_me" domain="[('message_is_follower', '=', True)]"/>
+ <filter string="My Projects" name="my_projects" domain="[('user_id', '=', uid)]"/>
<separator/>
<filter string="Archived" name="inactive" domain="[('active', '=', False)]"/>
<group expand="0" string="Group By">
@@ -399,17 +390,16 @@
<field name="name">project.project.tree</field>
<field name="model">project.project</field>
<field name="arch" type="xml">
- <tree decoration-muted="active == False" string="Projects" delete="0">
+ <tree decoration-muted="active == False" string="Projects" delete="0" multi_edit="1">
<field name="sequence" optional="show" widget="handle"/>
<field name="message_needaction" invisible="1"/>
<field name="active" invisible="1"/>
- <field name="name" string="Project Name"/>
+ <field name="name" string="Name"/>
<field name="user_id" optional="show" string="Project Manager" widget="many2one_avatar_user"/>
- <field name="partner_id" optional="show" string="Contact"/>
+ <field name="partner_id" optional="show" string="Customer"/>
<field name="analytic_account_id" optional="hide"/>
<field name="privacy_visibility" optional="hide"/>
<field name="subtask_project_id" optional="hide"/>
- <field name="resource_calendar_id" optional="hide"/>
<field name="label_tasks" optional="hide"/>
<field name="company_id" optional="show" groups="base.group_multi_company"/>
</tree>
@@ -453,16 +443,19 @@
<field name="arch" type="xml">
<form string="Project">
<group>
- <group>
- <field name="name" class="o_project_name oe_inline"
- string="Project Name" placeholder="e.g. Office Party"/>
- <field name="user_id" invisible="1"/>
- <label for="alias_name" string="Choose a Project Email" attrs="{'invisible': [('alias_domain', '=', False)]}"/>
- <div name="alias_def" attrs="{'invisible': [('alias_domain', '=', False)]}">
- <field name="alias_name" class="oe_inline"/>@<field name="alias_domain" class="oe_inline" readonly="1"/>
- </div>
- </group>
+ <field name="name" class="o_project_name oe_inline"
+ string="Project Name" placeholder="e.g. Office Party"/>
+ <field name="user_id" invisible="1"/>
</group>
+ <div name="alias_def" colspan="2" attrs="{'invisible': [('alias_domain', '=', False)]}">
+ <label for="alias_enabled" class="oe_inline" string="Create tasks by sending an email to"/>
+ <field name="alias_enabled"/>
+ <span attrs="{'invisible': [('alias_enabled', '=', False)]}">
+ <field name="alias_name" class="oe_inline" attrs="{'required': [('alias_enabled', '=', True)]}" placeholder="e.g. office-party"/>
+ @
+ <field name="alias_domain" class="oe_inline" readonly="1" />
+ </span>
+ </div>
</form>
</field>
</record>
@@ -571,13 +564,6 @@
</field>
</record>
- <record id="ir_actions_server_project_sample" model="ir.actions.server">
- <field name="name">Project: Activate Sample Project</field>
- <field name="model_id" ref="project.model_project_project"/>
- <field name="state">code</field>
- <field name="code">action = model.activate_sample_project()</field>
- </record>
-
<record id="open_view_project_all" model="ir.actions.act_window">
<field name="name">Projects</field>
<field name="res_model">project.project</field>
@@ -588,9 +574,9 @@
<field name="target">main</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
- Create a new project
+ Create a project
</p><p>
- Or <a type="action" name="%(project.ir_actions_server_project_sample)d" tabindex="-1">activate a sample project</a> to play with.
+ Projects regroup tasks on the same topic and each have their own dashboard.
</p>
</field>
</record>
@@ -606,10 +592,10 @@
<field name="search_view_id" ref="view_project_project_filter"/>
<field name="context">{}</field>
<field name="help" type="html">
- <p class="o_view_nocontent_empty_folder">
- Create a new project
+ <p class="o_view_nocontent_smiling_face">
+ Create a project
</p><p>
- Or <a type="action" name="%(project.ir_actions_server_project_sample)d" tabindex="-1">activate a sample project</a> to play with.
+ Projects regroup tasks on the same topic and each have their own dashboard.
</p>
</field>
</record>
@@ -628,6 +614,9 @@
attrs="{'invisible' : [('user_id', '!=', False)]}"/>
<field name="stage_id" widget="statusbar" options="{'clickable': '1', 'fold_field': 'fold'}" attrs="{'invisible': [('project_id', '=', False)]}"/>
</header>
+ <div class="text-center alert alert-primary" role="alert" attrs="{'invisible': ['|', ('ribbon_message', '=', False), ('ribbon_message', '=', '')]}">
+ <field name="ribbon_message"/>
+ </div>
<sheet string="Task">
<div class="oe_button_box" name="button_box">
<button name="action_subtask" type="object" class="oe_stat_button" icon="fa-tasks"
@@ -651,7 +640,7 @@
<field name="active" invisible="1"/>
<field name="partner_id" class="o_task_customer_field"/>
<field name="partner_phone" widget="phone" attrs="{'invisible': [('partner_id', '=', False)]}"/>
- <field name="partner_email" string="Email" widget="email" attrs="{'invisible': [('partner_id', '=', False)]}"/>
+ <field name="partner_email" widget="email" attrs="{'invisible': [('partner_id', '=', False)]}"/>
<field name="legend_blocked" invisible="1"/>
<field name="legend_normal" invisible="1"/>
<field name="legend_done" invisible="1"/>
@@ -660,7 +649,7 @@
<field name="project_id" required="1" domain="[('active', '=', True), ('company_id', '=', company_id)]"/>
<field name="user_id"
class="o_task_user_field"
- options='{"no_open": True}' domain="[('share', '=', False)]"/>
+ domain="[('share', '=', False)]"/>
<field
name="parent_id"
domain="[('parent_id', '=', False)]"
@@ -852,8 +841,9 @@
<!-- YTI TODO user_invisible and seq_visible seem to be useless -->
<field name="project_id" invisible="context.get('user_invisible', False)" optional="show" readonly="1"/>
<field name="partner_id" optional="hide"/>
- <field name="parent_id" groups="project.group_subtask_project" optional="show"/>
+ <field name="parent_id" groups="project.group_subtask_project" optional="hide"/>
<field name="user_id" invisible="context.get('user_invisible', False)" optional="show" widget="many2one_avatar_user"/>
+ <field name="company_id" groups="base.group_multi_company" optional="show"/>
<field name="activity_ids" widget="list_activity" optional="show"/>
<field name="date_deadline" optional="hide" widget="remaining_days" attrs="{'invisible': [('is_closed', '=', True)]}"/>
<field name="stage_id" invisible="context.get('set_visible',False)" optional="show" readonly="1"/>
@@ -955,7 +945,7 @@
<record id="action_view_all_task" model="ir.actions.act_window">
<field name="name">Tasks</field>
<field name="res_model">project.task</field>
- <field name="view_mode">kanban,tree,form,calendar,pivot,graph,activity</field>
+ <field name="view_mode">tree,kanban,form,calendar,pivot,graph,activity</field>
<field name="context">{'search_default_my_tasks': 1, 'all_task': 0}</field>
<field name="search_view_id" ref="view_task_search_form"/>
<field name="help" type="html">
@@ -979,7 +969,7 @@
<field name="act_window_id" ref="action_view_task"/>
</record>
- <menuitem name="All Tasks" id="menu_project_management" parent="menu_main_pm"
+ <menuitem name="Tasks" id="menu_project_management" parent="menu_main_pm"
action="action_view_all_task" sequence="2" groups="base.group_no_one,group_project_user"/>
<record id="project_task_action_from_partner" model="ir.actions.act_window">
@@ -1040,6 +1030,7 @@
<sheet>
<group>
<field name="name"/>
+ <field name="color" widget="color_picker"/>
</group>
</sheet>
</form>
@@ -1052,6 +1043,7 @@
<field name="arch" type="xml">
<tree string="Tags" editable="bottom">
<field name="name"/>
+ <field name="color" widget="color_picker"/>
</tree>
</field>
</record>
diff --git a/addons/project/views/rating_views.xml b/addons/project/views/rating_views.xml
index 7d7da90fa75..08b133554fc 100644
--- a/addons/project/views/rating_views.xml
+++ b/addons/project/views/rating_views.xml
@@ -1,5 +1,73 @@
<?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="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"/>
+ <field name="mode">primary</field>
+ <field name="arch" type="xml">
+ <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>
+ <div name="rating_image_container" position="replace">
+ <field name="rating_text" string="Rating"/>
+ </div>
+ </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="arch" type="xml">
+ <xpath expr="//pivot" position="attributes">
+ <attribute name="js_class">project_rating_pivot</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="arch" type="xml">
+ <xpath expr="//graph" position="attributes">
+ <attribute name="js_class">project_rating_graph</attribute>
+ </xpath>
+ </field>
+ </record>
<record id="rating_rating_view_search_project" model="ir.ui.view">
<field name="name">rating.rating.search.project</field>
@@ -32,8 +100,36 @@
</field>
</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">Customer Ratings</field>
+ <field name="name">Customer Ratings on Task</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>
@@ -42,11 +138,39 @@
<p class="o_view_nocontent_empty_folder">
No customer ratings yet
</p><p>
- Customer ratings on tasks. If you have no rating, change your project Settings to activate it.
+ Let's wait for your customers to manifest themselves.
</p>
</field>
</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>
@@ -57,10 +181,38 @@
<p class="o_view_nocontent_empty_folder">
No customer ratings yet
</p><p>
- Customer ratings on tasks. If you have no rating, change your project Settings to activate it.
+ Let's wait for your customers to manifest themselves.
</p>
</field>
<field name="context">{}</field>
</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>
diff --git a/addons/project/views/res_config_settings_views.xml b/addons/project/views/res_config_settings_views.xml
index 8346330c8c7..79b8e2a03cb 100644
--- a/addons/project/views/res_config_settings_views.xml
+++ b/addons/project/views/res_config_settings_views.xml
@@ -59,7 +59,7 @@
<div class="o_setting_right_pane">
<label for="module_project_forecast"/>
<div class="text-muted" name="project_forecast_msg">
- Schedule your teams across projects and estimate deadlines more accurately.
+ Plan resource allocation accross projets and tasks, and estimate deadlines more accurately
</div>
</div>
</div>
@@ -70,7 +70,7 @@
<div class="o_setting_right_pane">
<label for="module_hr_timesheet"/>
<div class="text-muted">
- Track time spent on tasks.
+ Track time spent on projects and tasks
</div>
</div>
</div>