From 56ef461f44e597eb1ba0193b78e9caf228091ccd Mon Sep 17 00:00:00 2001 From: "Cedric Prieels (cpr)" Date: Thu, 9 Sep 2021 13:04:21 +0000 Subject: [PATCH] [FIX] project: follow-up the project overview removal -- This is a follow-up of odoo/enterprise#72736 -- The project overview is a significant technical debt as it is a custom qweb view. It is quite limited: It is not possible to group the data, to filter on dates, SOs or Field Service projects. Improving this is very difficult and would require weeks of development that are not worth it. In any case, all the information provided by the project overview can be found elsewhere. The stat buttons of the report are basically duplicates of the ones from the project form view. Therefore, we are removing this report and its twin, the Project Costs and Revenues. In addition, analytic items lack context for the user to understand what generated a certain cost or revenue: there is no link to the source document; the entries are not categorized (e.g. it is not easy to understand if a cost comes from a timesheet cost, a purchase order or an expense); the billable type group by works fine for timesheets but then all the other entries are flagged as Undefined, which is not very helpful; there is no option to easily isolate costs from revenues. task-2637495 See odoo/enterprise#20740 closes odoo/odoo#77547 X-original-commit: 9bbfd3c8f948a3a947cbc0eb73ffc5d89c23d4ca Related: odoo/enterprise#21324 Signed-off-by: LTU-Odoo --- addons/project/models/project.py | 2 +- addons/project/models/project_update.py | 27 +++++++--- .../src/js/right_panel/project_right_panel.js | 5 ++ .../tests/tours/project_update_tour_tests.js | 4 +- .../views/project_update_templates.xml | 21 ++++---- addons/sale_project/models/project.py | 12 ++--- addons/sale_timesheet/models/project.py | 28 +++++++--- .../sale_timesheet/models/project_update.py | 54 +++++++++---------- .../static/src/xml/sale_project_templates.xml | 8 +-- .../views/project_task_views.xml | 5 +- .../views/project_update_templates.xml | 34 ++++++------ 11 files changed, 116 insertions(+), 84 deletions(-) diff --git a/addons/project/models/project.py b/addons/project/models/project.py index 08b71669dc6..4e71218bb78 100644 --- a/addons/project/models/project.py +++ b/addons/project/models/project.py @@ -661,7 +661,7 @@ class Project(models.Model): 'user': self._get_user_values(), 'tasks_analysis': self._get_tasks_analysis(), 'milestones': self._get_milestones(), - 'buttons': sorted(self._get_stat_buttons(), key=lambda k: k['sequence']) + 'buttons': sorted(self._get_stat_buttons(), key=lambda k: k['sequence']), } def _get_user_values(self): diff --git a/addons/project/models/project_update.py b/addons/project/models/project_update.py index 0aa8672320d..7f0de705d7d 100644 --- a/addons/project/models/project_update.py +++ b/addons/project/models/project_update.py @@ -7,6 +7,7 @@ from werkzeug.urls import url_encode from odoo import api, fields, models from odoo.osv import expression +from odoo.tools import formatLang STATUS_COLOR = { 'on_track': 20, # green / success @@ -76,6 +77,13 @@ class ProjectUpdate(models.Model): update.project_id.sudo().last_update_id = update return update + def unlink(self): + projects = self.project_id + res = super().unlink() + for project in projects: + project.last_update_id = self.search([('project_id', "=", project.id)], order="date desc", limit=1) + return res + # --------------------------------- # Build default description # --------------------------------- @@ -86,10 +94,13 @@ class ProjectUpdate(models.Model): @api.model def _get_template_values(self, project): + milestones = self._get_milestone_values(project) return { 'user': self.env.user, 'project': project, - 'milestones': self._get_milestone_values(project) + 'show_activities': milestones['show_section'], + 'milestones': milestones, + 'format_lang': lambda value, digits: formatLang(self.env, value, digits=digits), } @api.model @@ -100,14 +111,14 @@ class ProjectUpdate(models.Model): '|', ('deadline', '<', fields.Date.context_today(self) + relativedelta(years=1)), ('deadline', '=', False)])._get_data_list() updated_milestones = self._get_last_updated_milestone(project) domain = [('project_id', '=', project.id)] - if project.last_update_id.date: - domain = expression.AND([domain, [('create_date', '>=', project.last_update_id.date)]]) + if project.last_update_id.create_date: + domain = expression.AND([domain, [('create_date', '>', project.last_update_id.create_date)]]) created_milestones = Milestone.search(domain)._get_data_list() return { 'show_section': (list_milestones or updated_milestones or created_milestones) and True or False, 'list': list_milestones, 'updated': updated_milestones, - 'last_update_date': project.last_update_id.date or None, + 'last_update_date': project.last_update_id.create_date or None, 'created': created_milestones, } @@ -131,8 +142,8 @@ class ProjectUpdate(models.Model): AND mm.message_type = 'notification' AND pm.project_id = %(project_id)s """ - if project.last_update_id.date: - query = query + "AND mm.date <= %(last_update_date)s" + if project.last_update_id.create_date: + query = query + "AND mm.date > %(last_update_date)s" query = query + """ WINDOW w_partition AS ( PARTITION BY pm.id @@ -142,8 +153,8 @@ class ProjectUpdate(models.Model): LIMIT 1; """ query_params = {'project_id': project.id} - if project.last_update_id.date: - query_params['last_update_date'] = project.last_update_id.date + if project.last_update_id.create_date: + query_params['last_update_date'] = project.last_update_id.create_date self.env.cr.execute(query, query_params) results = self.env.cr.dictfetchall() mapped_result = {res['milestone_id']: {'new_value': res['new_value'], 'old_value': res['old_value']} for res in results} diff --git a/addons/project/static/src/js/right_panel/project_right_panel.js b/addons/project/static/src/js/right_panel/project_right_panel.js index f47cb60a287..2c711b77665 100644 --- a/addons/project/static/src/js/right_panel/project_right_panel.js +++ b/addons/project/static/src/js/right_panel/project_right_panel.js @@ -1,6 +1,7 @@ /** @odoo-module **/ import { AddMilestone, OpenMilestone } from '@project/js/right_panel/project_utils'; +import { formatFloat } from "@web/fields/formatters"; const { useState } = owl.hooks; export default class ProjectRightPanel extends owl.Component { @@ -19,6 +20,10 @@ export default class ProjectRightPanel extends owl.Component { }); } + formatFloat(value) { + return formatFloat(value, { digits: [false, 1] }); + } + async willStart() { await super.willStart(...arguments); await this._loadQwebContext(); diff --git a/addons/project/static/tests/tours/project_update_tour_tests.js b/addons/project/static/tests/tours/project_update_tour_tests.js index 39932655efc..1d425f7c93c 100644 --- a/addons/project/static/tests/tours/project_update_tour_tests.js +++ b/addons/project/static/tests/tours/project_update_tour_tests.js @@ -130,9 +130,9 @@ tour.register('project_update_tour', { trigger: ".o_field_widget[name=description] div[name='milestone'] ul li:contains('(12/12/2099 => 12/12/2100)')", run: function () {}, }, { - trigger: ".o_field_widget[name=description] div[name='milestone'] ul li span:contains('(due on 12/12/2022)')", + trigger: ".o_field_widget[name=description] div[name='milestone'] ul li span:contains('(due 12/12/2022)')", run: function () {}, }, { - trigger: ".o_field_widget[name=description] div[name='milestone'] ul li span:contains('(due on 12/12/2100)')", + trigger: ".o_field_widget[name=description] div[name='milestone'] ul li span:contains('(due 12/12/2100)')", run: function () {}, }]); diff --git a/addons/project/views/project_update_templates.xml b/addons/project/views/project_update_templates.xml index 42a21c0565a..5e1cac3d331 100644 --- a/addons/project/views/project_update_templates.xml +++ b/addons/project/views/project_update_templates.xml @@ -2,7 +2,7 @@