From 2b3e3a44a9582ddd62ca2cf96d9331e9c310bd3e Mon Sep 17 00:00:00 2001 From: "Cedric Prieels (cpr)" Date: Thu, 2 Sep 2021 12:51:58 +0200 Subject: [PATCH] [IMP] project_{account,purchase,hr_expense}: extend form and panel This commit extends project form and panel in order to add buttons which allow user to view documents linked to the project analytic account. This commit adds bridge modules in order to handle those extensions. PR : #72736 See odoo/upgrade#2706 task-2545084 --- addons/project_account/__init__.py | 2 + addons/project_account/__manifest__.py | 19 ++++++ .../views/project_project_templates.xml | 11 ++++ addons/project_hr_expense/__init__.py | 4 ++ addons/project_hr_expense/__manifest__.py | 19 ++++++ addons/project_hr_expense/models/__init__.py | 3 + addons/project_hr_expense/models/project.py | 58 +++++++++++++++++++ .../views/project_project_views.xml | 24 ++++++++ addons/project_purchase/models/project.py | 57 ++++++++++++++++-- .../project_purchase/views/project_views.xml | 17 ++++-- 10 files changed, 203 insertions(+), 11 deletions(-) create mode 100644 addons/project_account/__init__.py create mode 100644 addons/project_account/__manifest__.py create mode 100644 addons/project_account/views/project_project_templates.xml create mode 100644 addons/project_hr_expense/__init__.py create mode 100644 addons/project_hr_expense/__manifest__.py create mode 100644 addons/project_hr_expense/models/__init__.py create mode 100644 addons/project_hr_expense/models/project.py create mode 100644 addons/project_hr_expense/views/project_project_views.xml diff --git a/addons/project_account/__init__.py b/addons/project_account/__init__.py new file mode 100644 index 00000000000..67dee8c60db --- /dev/null +++ b/addons/project_account/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. diff --git a/addons/project_account/__manifest__.py b/addons/project_account/__manifest__.py new file mode 100644 index 00000000000..742c0c2bf21 --- /dev/null +++ b/addons/project_account/__manifest__.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + + +{ + 'name': 'Project Accounting', + 'version': '1.0', + 'category': 'Project/account', + 'summary': 'Project accounting', + 'description': 'Bridge created to remove the profitability setting if the account module is installed', + 'depends': ['project', 'account'], + 'data': [ + 'views/project_project_templates.xml', + ], + 'demo': [], + 'installable': True, + 'auto_install': True, + 'license': 'OEEL-1', +} diff --git a/addons/project_account/views/project_project_templates.xml b/addons/project_account/views/project_project_templates.xml new file mode 100644 index 00000000000..ae193839258 --- /dev/null +++ b/addons/project_account/views/project_project_templates.xml @@ -0,0 +1,11 @@ + + + + res.config.settings.view.form.inherit.project + res.config.settings + + + + + + diff --git a/addons/project_hr_expense/__init__.py b/addons/project_hr_expense/__init__.py new file mode 100644 index 00000000000..dc5e6b693d1 --- /dev/null +++ b/addons/project_hr_expense/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import models diff --git a/addons/project_hr_expense/__manifest__.py b/addons/project_hr_expense/__manifest__.py new file mode 100644 index 00000000000..cf48644425e --- /dev/null +++ b/addons/project_hr_expense/__manifest__.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + + +{ + 'name': 'Project Expenses', + 'version': '1.0', + 'category': 'Project/expenses', + 'summary': 'Project expenses', + 'description': 'Bridge created to add the number of expenses linked to an AA to a project form', + 'depends': ['project', 'hr_expense'], + 'data': [ + 'views/project_project_views.xml', + ], + 'demo': [], + 'installable': True, + 'auto_install': True, + 'license': 'OEEL-1', +} diff --git a/addons/project_hr_expense/models/__init__.py b/addons/project_hr_expense/models/__init__.py new file mode 100644 index 00000000000..a0097b786ab --- /dev/null +++ b/addons/project_hr_expense/models/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import project diff --git a/addons/project_hr_expense/models/project.py b/addons/project_hr_expense/models/project.py new file mode 100644 index 00000000000..9449190dced --- /dev/null +++ b/addons/project_hr_expense/models/project.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models, _ + +class Project(models.Model): + _inherit = 'project.project' + + expenses_count = fields.Integer('# Expenses', compute='_compute_expenses_count') + + @api.depends('analytic_account_id') + def _compute_expenses_count(self): + expenses_data = self.env['hr.expense'].read_group([ + ('analytic_account_id', '!=', False), + ('analytic_account_id', 'in', self.analytic_account_id.ids) + ], + ['analytic_account_id'], ['analytic_account_id']) + mapped_data = {data['analytic_account_id'][0]: data['analytic_account_id_count'] for data in expenses_data} + for project in self: + project.expenses_count = mapped_data.get(project.analytic_account_id.id, 0) + + # ---------------------------- + # Actions + # ---------------------------- + + def action_open_project_expenses(self): + expenses = self.env['hr.expense'].search([ + ('analytic_account_id', '!=', False), + ('analytic_account_id', 'in', self.analytic_account_id.ids) + ]) + action = self.env["ir.actions.actions"]._for_xml_id("hr_expense.hr_expense_actions_all") + action.update({ + 'display_name': _('Expenses'), + 'views': [[False, 'tree'], [False, 'form'], [False, 'kanban'], [False, 'graph'], [False, 'pivot']], + 'context': {'default_analytic_account_id': self.analytic_account_id.id}, + 'domain': [('id', 'in', expenses.ids)] + }) + if(len(expenses) == 1): + action["views"] = [[False, 'form']] + action["res_id"] = expenses.id + return action + + # ---------------------------- + # Project Updates + # ---------------------------- + + def _get_stat_buttons(self): + buttons = super(Project, self)._get_stat_buttons() + buttons.append({ + 'icon': 'money', + 'text': _('Expenses'), + 'number': self.expenses_count, + 'action_type': 'object', + 'action': 'action_open_project_expenses', + 'show': self.user_has_groups('hr_expense.group_hr_expense_team_approver') and self.expenses_count > 0, + 'sequence': 10, + }) + return buttons diff --git a/addons/project_hr_expense/views/project_project_views.xml b/addons/project_hr_expense/views/project_project_views.xml new file mode 100644 index 00000000000..ccf64253c7a --- /dev/null +++ b/addons/project_hr_expense/views/project_project_views.xml @@ -0,0 +1,24 @@ + + + + + project.project.form.inherit + project.project + + + + + + + + + diff --git a/addons/project_purchase/models/project.py b/addons/project_purchase/models/project.py index 89644f20306..a29879e6f37 100644 --- a/addons/project_purchase/models/project.py +++ b/addons/project_purchase/models/project.py @@ -1,14 +1,61 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo import fields, models +from odoo import api, fields, models, _ class Project(models.Model): _inherit = "project.project" - purchase_order_count = fields.Integer(related="analytic_account_id.purchase_order_count") + purchase_orders_count = fields.Integer('# Purchase Orders', compute='_compute_purchase_orders_count') - def action_view_purchase_orders(self): - self.ensure_one() - return self.analytic_account_id.action_view_purchase_orders() + @api.depends('analytic_account_id') + def _compute_purchase_orders_count(self): + purchase_orders_data = self.env['purchase.order.line'].read_group([ + ('account_analytic_id', '!=', False), + ('account_analytic_id', 'in', self.analytic_account_id.ids) + ], ['account_analytic_id', 'order_id:count_distinct'], ['account_analytic_id']) + mapped_data = dict([(data['account_analytic_id'][0], data['order_id']) for data in purchase_orders_data]) + for project in self: + project.purchase_orders_count = mapped_data.get(project.analytic_account_id.id, 0) + + # ---------------------------- + # Actions + # ---------------------------- + + def action_open_project_purchase_orders(self): + purchase_orders = self.env['purchase.order'].search([ + ('order_line.account_analytic_id', '!=', False), + ('order_line.account_analytic_id', 'in', self.analytic_account_id.ids) + ]) + action_window = { + 'name': _('Purchase Orders'), + 'type': 'ir.actions.act_window', + 'res_model': 'purchase.order', + 'views': [[False, 'tree'], [False, 'form']], + 'domain': [('id', 'in', purchase_orders.ids)], + 'context': { + 'create': False, + } + } + if len(purchase_orders) == 1: + action_window['views'] = [[False, 'form']] + action_window['res_id'] = purchase_orders.id + return action_window + + # ---------------------------- + # Project Updates + # ---------------------------- + + def _get_stat_buttons(self): + buttons = super(Project, self)._get_stat_buttons() + buttons.append({ + 'icon': 'credit-card', + 'text': _('Purchase Orders'), + 'number': self.purchase_orders_count, + 'action_type': 'object', + 'action': 'action_open_project_purchase_orders', + 'show': self.user_has_groups('purchase.group_purchase_user') and self.purchase_orders_count > 0, + 'sequence': 13, + }) + return buttons diff --git a/addons/project_purchase/views/project_views.xml b/addons/project_purchase/views/project_views.xml index 7c686388a9f..21672b7e780 100644 --- a/addons/project_purchase/views/project_views.xml +++ b/addons/project_purchase/views/project_views.xml @@ -3,13 +3,18 @@ project.project.view.inherited project.project - - 20 + - -