From f83237d3c68e71eec5ddbce0d072419cedb2d523 Mon Sep 17 00:00:00 2001 From: "Xavier BOL (xbo)" Date: Fri, 27 Nov 2020 17:25:22 +0100 Subject: [PATCH 01/23] [IMP] sale_timesheet: remove the context key added This context key has been added in the 14.0 for a fix in helpdesk to create a sale order form a ticket. But, now we remove the 'create sale order' button in the ticket to add sale order line field in the ticket, this field allows to link the timesheet in this sale order line selected in this field. Thus, this commit removes the context key used 'ticket_timesheet_ids' since this key will never be given again in this wizard. task-2424382 --- .../wizard/project_create_sale_order.py | 39 +++---------------- 1 file changed, 6 insertions(+), 33 deletions(-) diff --git a/addons/sale_timesheet/wizard/project_create_sale_order.py b/addons/sale_timesheet/wizard/project_create_sale_order.py index 8c3271128c5..7fbee90b055 100644 --- a/addons/sale_timesheet/wizard/project_create_sale_order.py +++ b/addons/sale_timesheet/wizard/project_create_sale_order.py @@ -193,7 +193,6 @@ class ProjectCreateSalesOrder(models.TransientModel): def _make_billable_at_project_rate(self, sale_order): self.ensure_one() task_left = self.project_id.tasks.filtered(lambda task: not task.sale_line_id) - ticket_timesheet_ids = self.env.context.get('ticket_timesheet_ids', []) for wizard_line in self.line_ids: task_ids = self.project_id.tasks.filtered(lambda task: not task.sale_line_id and task.timesheet_product_id == wizard_line.product_id) task_left -= task_ids @@ -213,17 +212,6 @@ class ProjectCreateSalesOrder(models.TransientModel): 'product_uom_qty': 0.0, }) - if ticket_timesheet_ids and not self.project_id.sale_line_id and not task_ids: - # With pricing = "project rate" in project. When the user wants to create a sale order from a ticket in helpdesk - # The project cannot contain any tasks. Thus, we need to give the first sale_order_line created to link - # the timesheet to this first sale order line. - # link the project to the SO line - self.project_id.write({ - 'sale_order_id': sale_order.id, - 'sale_line_id': sale_order_line.id, - 'partner_id': self.partner_id.id, - }) - # link the tasks to the SO line task_ids.write({ 'sale_line_id': sale_order_line.id, @@ -233,9 +221,6 @@ class ProjectCreateSalesOrder(models.TransientModel): # assign SOL to timesheets search_domain = [('task_id', 'in', task_ids.ids), ('so_line', '=', False)] - if ticket_timesheet_ids: - search_domain = [('id', 'in', ticket_timesheet_ids), ('so_line', '=', False)] - self.env['account.analytic.line'].search(search_domain).write({ 'so_line': sale_order_line.id }) @@ -243,18 +228,11 @@ class ProjectCreateSalesOrder(models.TransientModel): 'product_uom_qty': sale_order_line.qty_delivered }) - if ticket_timesheet_ids and self.project_id.sale_line_id and not self.project_id.tasks and len(self.line_ids) > 1: - # Then, we need to give to the project the last sale order line created - self.project_id.write({ - 'sale_line_id': sale_order_line.id - }) - else: # Otherwise, we are in the normal behaviour - # link the project to the SO line - self.project_id.write({ - 'sale_order_id': sale_order.id, - 'sale_line_id': sale_order_line.id, # we take the last sale_order_line created - 'partner_id': self.partner_id.id, - }) + self.project_id.write({ + 'sale_order_id': sale_order.id, + 'sale_line_id': sale_order_line.id, # we take the last sale_order_line created + 'partner_id': self.partner_id.id, + }) if task_left: task_left.sale_line_id = False @@ -319,12 +297,7 @@ class ProjectCreateSalesOrder(models.TransientModel): tasks = self.project_id.tasks.filtered(lambda t: not t.non_allow_billable) # assign SOL to timesheets for map_entry in map_entries: - search_domain = [('employee_id', '=', map_entry.employee_id.id), ('so_line', '=', False)] - ticket_timesheet_ids = self.env.context.get('ticket_timesheet_ids', []) - if ticket_timesheet_ids: - search_domain.append(('id', 'in', ticket_timesheet_ids)) - else: - search_domain.append(('task_id', 'in', tasks.ids)) + search_domain = [('employee_id', '=', map_entry.employee_id.id), ('so_line', '=', False), ('task_id', 'in', self.project_id.tasks.ids)] self.env['account.analytic.line'].search(search_domain).write({ 'so_line': map_entry.sale_line_id.id }) From d1953139fa986ded3424e4d178b64b8e011df1ee Mon Sep 17 00:00:00 2001 From: "Laurent Stukkens (LTU)" Date: Mon, 30 Nov 2020 15:05:38 +0100 Subject: [PATCH 02/23] [IMP] sale_timesheet: remove non_allow_billable This commit removes all reference to project.task non_allow_billable. This also implies: * account.analytic.line non_allow_billable * account.analytic.line timesheet_invoice_type selection value 'non_billable_timesheet' task-2424382 --- addons/sale_timesheet/models/account.py | 13 +++------ addons/sale_timesheet/models/project.py | 27 +++---------------- addons/sale_timesheet/models/sale_order.py | 6 ++--- .../views/hr_timesheet_views.xml | 15 ++--------- .../views/project_task_views.xml | 4 --- .../wizard/project_create_sale_order.py | 10 ++----- .../wizard/project_task_create_sale_order.py | 2 +- 7 files changed, 15 insertions(+), 62 deletions(-) diff --git a/addons/sale_timesheet/models/account.py b/addons/sale_timesheet/models/account.py index 5dbe9c56da6..fbdef4a31a7 100644 --- a/addons/sale_timesheet/models/account.py +++ b/addons/sale_timesheet/models/account.py @@ -18,21 +18,14 @@ class AccountAnalyticLine(models.Model): ('billable_time', 'Billed on Timesheets'), ('billable_fixed', 'Billed at a Fixed price'), ('non_billable', 'Non Billable Tasks'), - ('non_billable_timesheet', 'Non Billable Timesheet'), ('non_billable_project', 'No task found')], string="Billable Type", compute='_compute_timesheet_invoice_type', compute_sudo=True, store=True, readonly=True) timesheet_invoice_id = fields.Many2one('account.move', string="Invoice", readonly=True, copy=False, help="Invoice created from the timesheet") - non_allow_billable = fields.Boolean("Non-Billable", help="Your timesheet will not be billed.") so_line = fields.Many2one(compute="_compute_so_line", store=True, readonly=False) # TODO: [XBO] Since the task_id is not required in this model, then it should more efficient to depends to bill_type and pricing_type of project (See in master) - @api.depends('so_line.product_id', 'project_id', 'task_id', 'non_allow_billable', 'task_id.bill_type', 'task_id.pricing_type', 'task_id.non_allow_billable') + @api.depends('so_line.product_id', 'project_id', 'task_id', 'task_id.bill_type', 'task_id.pricing_type') def _compute_timesheet_invoice_type(self): - non_allowed_billable = self.filtered('non_allow_billable') - non_allowed_billable.timesheet_invoice_type = 'non_billable_timesheet' - non_allowed_billable_task = (self - non_allowed_billable).filtered(lambda t: t.task_id.bill_type == 'customer_project' and t.task_id.pricing_type == 'employee_rate' and t.task_id.non_allow_billable) - non_allowed_billable_task.timesheet_invoice_type = 'non_billable' - - for timesheet in self - non_allowed_billable - non_allowed_billable_task: + for timesheet in self: if timesheet.project_id: # AAL will be set to False invoice_type = 'non_billable_project' if not timesheet.task_id else 'non_billable' if timesheet.task_id and timesheet.so_line.product_id.type == 'service': @@ -113,7 +106,7 @@ class AccountAnalyticLine(models.Model): return task.sale_line_id if task.pricing_type == 'fixed_rate': return task.sale_line_id - elif task.pricing_type == 'employee_rate' and not task.non_allow_billable: + elif task.pricing_type == 'employee_rate': map_entry = project.sale_line_employee_ids.filtered(lambda map_entry: map_entry.employee_id == employee) if map_entry: return map_entry.sale_line_id diff --git a/addons/sale_timesheet/models/project.py b/addons/sale_timesheet/models/project.py index 13d2775fd03..c702df2a2d8 100644 --- a/addons/sale_timesheet/models/project.py +++ b/addons/sale_timesheet/models/project.py @@ -83,8 +83,7 @@ class Project(models.Model): @api.depends('pricing_type', 'allow_timesheets', 'allow_billable', 'sale_line_employee_ids', 'sale_line_employee_ids.employee_id', 'bill_type') def _compute_warning_employee_rate(self): projects = self.filtered(lambda p: p.allow_billable and p.allow_timesheets and p.bill_type == 'customer_project' and p.pricing_type == 'employee_rate') - tasks = projects.task_ids.filtered(lambda t: not t.non_allow_billable) - employees = self.env['account.analytic.line'].read_group([('task_id', 'in', tasks.ids), ('non_allow_billable', '=', False)], ['employee_id', 'project_id'], ['employee_id', 'project_id'], ['employee_id', 'project_id'], lazy=False) + employees = self.env['account.analytic.line'].read_group([('task_id', 'in', projects.task_ids.ids)], ['employee_id', 'project_id'], ['employee_id', 'project_id'], ['employee_id', 'project_id'], lazy=False) dict_project_employee = defaultdict(list) for line in employees: dict_project_employee[line['project_id'][0]] += [line['employee_id'][0]] @@ -235,9 +234,6 @@ class ProjectTask(models.Model): ('service_type', '=', 'timesheet'), '|', ('company_id', '=', False), ('company_id', '=', company_id)]""", help='Select a Service product with which you would like to bill your time spent on this task.') - - # TODO: [XBO] remove me in master - non_allow_billable = fields.Boolean("Non-Billable", help="Your timesheets linked to this task will not be billed.") remaining_hours_so = fields.Float('Remaining Hours on SO', compute='_compute_remaining_hours_so') remaining_hours_available = fields.Boolean(related="sale_line_id.remaining_hours_available") @@ -288,12 +284,12 @@ class ProjectTask(models.Model): for task in self: task.analytic_account_active = task.analytic_account_active or task.analytic_account_id.active - @api.depends('sale_line_id', 'project_id', 'allow_billable', 'non_allow_billable') + @api.depends('sale_line_id', 'project_id', 'allow_billable') def _compute_sale_order_id(self): for task in self: - if not task.allow_billable or task.non_allow_billable: + if not task.allow_billable: task.sale_order_id = False - elif task.allow_billable: + else: if task.sale_line_id: task.sale_order_id = task.sale_line_id.sudo().order_id elif task.project_id.sale_order_id: @@ -333,21 +329,6 @@ class ProjectTask(models.Model): project_dest = self.env['project.project'].browse(values['project_id']) if project_dest.bill_type == 'customer_project' and project_dest.pricing_type == 'employee_rate': self.write({'sale_line_id': False}) - if 'non_allow_billable' in values and self.filtered('allow_timesheets').sudo().timesheet_ids: - timesheet_ids = self.filtered('allow_timesheets').timesheet_ids.filtered( - lambda t: (not t.timesheet_invoice_id or t.timesheet_invoice_id.state == 'cancel') - ) - if values['non_allow_billable']: - timesheet_ids.write({'so_line': False}) - self.sale_line_id = False - else: - # We write project on timesheet lines to call _timesheet_preprocess. This function will set correct the SOL - for project in timesheet_ids.project_id: - current_timesheet_ids = timesheet_ids.filtered(lambda t: t.project_id == project) - current_timesheet_ids.task_id.update({'sale_line_id': project.sale_line_id.id}) - for employee in current_timesheet_ids.employee_id: - current_timesheet_ids.filtered(lambda t: t.employee_id == employee).write({'project_id': project.id}) - return res def _get_last_sol_of_customer(self): diff --git a/addons/sale_timesheet/models/sale_order.py b/addons/sale_timesheet/models/sale_order.py index 8d8492919f7..7a17b316326 100644 --- a/addons/sale_timesheet/models/sale_order.py +++ b/addons/sale_timesheet/models/sale_order.py @@ -34,7 +34,7 @@ class SaleOrder(models.Model): for sale_order in self: timesheets = sale_order.timesheet_ids if self.user_has_groups('hr_timesheet.group_hr_timesheet_approver') else sale_order.timesheet_ids.filtered(lambda t: t.user_id.id == self.env.uid) total_time = 0.0 - for timesheet in timesheets.filtered(lambda t: not t.non_allow_billable): + for timesheet in timesheets: # Timesheets may be stored in a different unit of measure, so first we convert all of them to the reference unit total_time += timesheet.unit_amount * timesheet.product_uom_id.factor_inv # Now convert to the proper unit of measure @@ -147,7 +147,7 @@ class SaleOrderLine(models.Model): if not line.is_expense and line.product_id.type == 'service' and line.product_id.service_type == 'timesheet': line.qty_delivered_method = 'timesheet' - @api.depends('analytic_line_ids.project_id', 'analytic_line_ids.non_allow_billable', 'project_id.pricing_type', 'project_id.bill_type') + @api.depends('analytic_line_ids.project_id', 'project_id.pricing_type', 'project_id.bill_type') def _compute_qty_delivered(self): super(SaleOrderLine, self)._compute_qty_delivered() @@ -159,7 +159,7 @@ class SaleOrderLine(models.Model): def _timesheet_compute_delivered_quantity_domain(self): """ Hook for validated timesheet in addionnal module """ - return [('project_id', '!=', False), ('non_allow_billable', '=', False)] + return [('project_id', '!=', False)] ########################################### # Service : Project and task generation diff --git a/addons/sale_timesheet/views/hr_timesheet_views.xml b/addons/sale_timesheet/views/hr_timesheet_views.xml index b3f34e8db5c..2a050f69666 100644 --- a/addons/sale_timesheet/views/hr_timesheet_views.xml +++ b/addons/sale_timesheet/views/hr_timesheet_views.xml @@ -10,8 +10,8 @@ - - + + @@ -36,17 +36,6 @@ - - account.analytic.line.view.tree.with.allow.billable - account.analytic.line - - - - - - - - diff --git a/addons/sale_timesheet/views/project_task_views.xml b/addons/sale_timesheet/views/project_task_views.xml index 1fcc110d8e0..2f6c610a877 100644 --- a/addons/sale_timesheet/views/project_task_views.xml +++ b/addons/sale_timesheet/views/project_task_views.xml @@ -147,15 +147,11 @@ - - - - diff --git a/addons/sale_timesheet/wizard/project_create_sale_order.py b/addons/sale_timesheet/wizard/project_create_sale_order.py index 7fbee90b055..b1824bb91de 100644 --- a/addons/sale_timesheet/wizard/project_create_sale_order.py +++ b/addons/sale_timesheet/wizard/project_create_sale_order.py @@ -66,9 +66,8 @@ class ProjectCreateSalesOrder(models.TransientModel): @api.depends('sale_order_id', 'link_selection') def _compute_info_invoice(self): for line in self: - tasks = line.project_id.tasks.filtered(lambda t: not t.non_allow_billable) domain = self.env['sale.order.line']._timesheet_compute_delivered_quantity_domain() - timesheet = self.env['account.analytic.line'].read_group(domain + [('task_id', 'in', tasks.ids), ('so_line', '=', False), ('timesheet_invoice_id', '=', False)], ['unit_amount'], ['task_id']) + timesheet = self.env['account.analytic.line'].read_group(domain + [('task_id', 'in', line.project_id.tasks.ids), ('so_line', '=', False), ('timesheet_invoice_id', '=', False)], ['unit_amount'], ['task_id']) unit_amount = round(sum(t.get('unit_amount', 0) for t in timesheet), 2) if timesheet else 0 if not unit_amount: line.info_invoice = False @@ -111,11 +110,9 @@ class ProjectCreateSalesOrder(models.TransientModel): 'sale_line_id': wizard_line.sale_line_id.id }) - self.project_id.tasks.filtered(lambda task: task.non_allow_billable).sale_line_id = False - tasks = self.project_id.tasks.filtered(lambda t: not t.non_allow_billable) # assign SOL to timesheets for map_entry in self.project_id.sale_line_employee_ids: - self.env['account.analytic.line'].search([('task_id', 'in', tasks.ids), ('employee_id', '=', map_entry.employee_id.id), ('so_line', '=', False)]).write({ + self.env['account.analytic.line'].search([('task_id', 'in', self.project_id.tasks.ids), ('employee_id', '=', map_entry.employee_id.id), ('so_line', '=', False)]).write({ 'so_line': map_entry.sale_line_id.id }) else: @@ -246,7 +243,6 @@ class ProjectCreateSalesOrder(models.TransientModel): lines_already_present = dict([(l.employee_id.id, l) for l in self.project_id.sale_line_employee_ids]) non_billable_tasks = self.project_id.tasks.filtered(lambda task: not task.sale_line_id) - non_allow_billable_tasks = self.project_id.tasks.filtered(lambda task: task.non_allow_billable) map_entries = self.env['project.sale.line.employee.map'] EmployeeMap = self.env['project.sale.line.employee.map'].sudo() @@ -292,9 +288,7 @@ class ProjectCreateSalesOrder(models.TransientModel): 'partner_id': sale_order.partner_id.id, 'email_from': sale_order.partner_id.email, }) - non_allow_billable_tasks.sale_line_id = False - tasks = self.project_id.tasks.filtered(lambda t: not t.non_allow_billable) # assign SOL to timesheets for map_entry in map_entries: search_domain = [('employee_id', '=', map_entry.employee_id.id), ('so_line', '=', False), ('task_id', 'in', self.project_id.tasks.ids)] diff --git a/addons/sale_timesheet/wizard/project_task_create_sale_order.py b/addons/sale_timesheet/wizard/project_task_create_sale_order.py index 02dbda23ab7..723ea2111c4 100644 --- a/addons/sale_timesheet/wizard/project_task_create_sale_order.py +++ b/addons/sale_timesheet/wizard/project_task_create_sale_order.py @@ -127,7 +127,7 @@ class ProjectTaskCreateSalesOrder(models.TransientModel): 'price_unit': self.price_unit, 'project_id': self.task_id.project_id.id, # prevent to re-create a project on confirmation 'task_id': self.task_id.id, - 'product_uom_qty': round(sum(self.task_id.timesheet_ids.filtered(lambda t: not t.non_allow_billable and not t.so_line).mapped('unit_amount')), 2), + 'product_uom_qty': round(sum(self.task_id.timesheet_ids.filtered(lambda t: not t.so_line).mapped('unit_amount')), 2), }) # link task to SOL From fa13d6b1b50ee69960ea3745465c353a635fa4da Mon Sep 17 00:00:00 2001 From: "Laurent Stukkens (LTU)" Date: Mon, 30 Nov 2020 15:36:28 +0100 Subject: [PATCH 03/23] [IMP] project: remove partner_email from task form view task-2424382 --- addons/project/views/project_views.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/project/views/project_views.xml b/addons/project/views/project_views.xml index 7c23bf4ae19..b8483f4fdc3 100644 --- a/addons/project/views/project_views.xml +++ b/addons/project/views/project_views.xml @@ -269,7 +269,7 @@ Customer Satisfaction - +
@@ -678,7 +678,6 @@ - From de426654a9ecc72cfa5cc5af5145dd6e994818a3 Mon Sep 17 00:00:00 2001 From: "Laurent Stukkens (LTU)" Date: Mon, 30 Nov 2020 15:40:54 +0100 Subject: [PATCH 04/23] [IMP] sale_timesheet: remove timesheet_product_id from task form view task-2424382 --- addons/sale_timesheet/views/project_task_views.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/sale_timesheet/views/project_task_views.xml b/addons/sale_timesheet/views/project_task_views.xml index 2f6c610a877..cbd4d4b53a5 100644 --- a/addons/sale_timesheet/views/project_task_views.xml +++ b/addons/sale_timesheet/views/project_task_views.xml @@ -146,7 +146,6 @@ - From 6c041c8d1fb5182ad10dff79aa53a7c558868f1b Mon Sep 17 00:00:00 2001 From: "Laurent Stukkens (LTU)" Date: Mon, 30 Nov 2020 16:01:55 +0100 Subject: [PATCH 05/23] [IMP] sale_timesheet: remove create sale order from task form view task-2424382 --- addons/sale_timesheet/models/project.py | 12 ------------ addons/sale_timesheet/views/project_task_views.xml | 2 -- 2 files changed, 14 deletions(-) diff --git a/addons/sale_timesheet/models/project.py b/addons/sale_timesheet/models/project.py index c702df2a2d8..5c6a4771f88 100644 --- a/addons/sale_timesheet/models/project.py +++ b/addons/sale_timesheet/models/project.py @@ -225,7 +225,6 @@ class ProjectTask(models.Model): is_project_map_empty = fields.Boolean("Is Project map empty", compute='_compute_is_project_map_empty') has_multi_sol = fields.Boolean(compute='_compute_has_multi_sol', compute_sudo=True) allow_billable = fields.Boolean(related="project_id.allow_billable") - display_create_order = fields.Boolean(compute='_compute_display_create_order') timesheet_product_id = fields.Many2one( 'product.product', string='Service', domain="""[ @@ -257,17 +256,6 @@ class ProjectTask(models.Model): for task in self: task.remaining_hours_so = mapped_remaining_hours[task._origin.id] - @api.depends( - 'allow_billable', 'allow_timesheets', 'sale_order_id') - def _compute_display_create_order(self): - for task in self: - show = True - if not task.allow_billable or not task.allow_timesheets or \ - (task.bill_type != 'customer_task' and not task.timesheet_product_id) or (not task.partner_id and task.bill_type != 'customer_task') or \ - task.sale_order_id or (task.bill_type != 'customer_task' and task.pricing_type != 'employee_rate'): - show = False - task.display_create_order = show - @api.onchange('sale_line_id') def _onchange_sale_line_id(self): # TODO: remove me in master diff --git a/addons/sale_timesheet/views/project_task_views.xml b/addons/sale_timesheet/views/project_task_views.xml index cbd4d4b53a5..8305711a7da 100644 --- a/addons/sale_timesheet/views/project_task_views.xml +++ b/addons/sale_timesheet/views/project_task_views.xml @@ -122,8 +122,6 @@ - -
@@ -22,14 +22,13 @@ - - - - - + + + + - + @@ -142,7 +141,6 @@ - diff --git a/addons/sale_timesheet/wizard/project_create_sale_order.py b/addons/sale_timesheet/wizard/project_create_sale_order.py index b1824bb91de..bd8d3765d4f 100644 --- a/addons/sale_timesheet/wizard/project_create_sale_order.py +++ b/addons/sale_timesheet/wizard/project_create_sale_order.py @@ -25,7 +25,7 @@ class ProjectCreateSalesOrder(models.TransientModel): result['project_id'] = active_id if not result.get('partner_id', False): result['partner_id'] = project.partner_id.id - if project.bill_type == 'customer_project' and not result.get('line_ids', False): + if project.pricing_type != 'task_rate' and not result.get('line_ids', False): if project.pricing_type == 'employee_rate': default_product = self.env.ref('sale_timesheet.time_product', False) result['line_ids'] = [ From bc50f70c447cf805abac54e18bb5950358499945 Mon Sep 17 00:00:00 2001 From: "Xavier BOL (xbo)" Date: Wed, 30 Dec 2020 16:43:01 +0100 Subject: [PATCH 13/23] [FIX] sale_timesheet: move the import to respect guidelines task-2424382 --- addons/sale_timesheet/models/sale_order.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/sale_timesheet/models/sale_order.py b/addons/sale_timesheet/models/sale_order.py index 99f24efcbc2..b0f3bede61f 100644 --- a/addons/sale_timesheet/models/sale_order.py +++ b/addons/sale_timesheet/models/sale_order.py @@ -1,9 +1,10 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +import math + from odoo import api, fields, models, _ from odoo.osv import expression -import math class SaleOrder(models.Model): From 3378ca8252d3ac0e22a8aa1632ffc436864b26b7 Mon Sep 17 00:00:00 2001 From: "Xavier BOL (xbo)" Date: Tue, 5 Jan 2021 10:19:30 +0100 Subject: [PATCH 14/23] [IMP] hr_timesheet: use access rights if user is internal Before this commit, when the user can only see his own timesheets, this user can see more than his own timesheets in timesheets portal (/my/timesheets). It is because we use the domain defined for portal and we don't use the access rights defined for this intenal user. This commit uses the access right if the user has the lowest group for Timesheet App. Otherwise, we use the domain for portal as before. Co-authored-by: Laurent Stukkens (LTU) task-2424382 --- addons/hr_timesheet/controllers/portal.py | 11 +++++++---- addons/hr_timesheet/models/hr_timesheet.py | 3 +++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/addons/hr_timesheet/controllers/portal.py b/addons/hr_timesheet/controllers/portal.py index b244ee3e656..a9dcb714ba5 100644 --- a/addons/hr_timesheet/controllers/portal.py +++ b/addons/hr_timesheet/controllers/portal.py @@ -19,8 +19,9 @@ class TimesheetCustomerPortal(CustomerPortal): def _prepare_home_portal_values(self, counters): values = super()._prepare_home_portal_values(counters) if 'timesheet_count' in counters: - domain = request.env['account.analytic.line']._timesheet_get_portal_domain() - values['timesheet_count'] = request.env['account.analytic.line'].sudo().search_count(domain) + Timesheet = request.env['account.analytic.line'] + domain = Timesheet._timesheet_get_portal_domain() + values['timesheet_count'] = Timesheet.sudo().search_count(domain) return values def _get_searchbar_inputs(self): @@ -63,9 +64,11 @@ class TimesheetCustomerPortal(CustomerPortal): @http.route(['/my/timesheets', '/my/timesheets/page/'], type='http', auth="user", website=True) def portal_my_timesheets(self, page=1, sortby=None, filterby=None, search=None, search_in='all', groupby='none', **kw): - Timesheet_sudo = request.env['account.analytic.line'].sudo() + Timesheet = request.env['account.analytic.line'] + domain = Timesheet._timesheet_get_portal_domain() + Timesheet_sudo = Timesheet.sudo() + values = self._prepare_portal_layout_values() - domain = request.env['account.analytic.line']._timesheet_get_portal_domain() _items_per_page = 100 searchbar_sortings = { diff --git a/addons/hr_timesheet/models/hr_timesheet.py b/addons/hr_timesheet/models/hr_timesheet.py index 17d4a613371..74a16b03a31 100644 --- a/addons/hr_timesheet/models/hr_timesheet.py +++ b/addons/hr_timesheet/models/hr_timesheet.py @@ -135,6 +135,9 @@ class AccountAnalyticLine(models.Model): return etree.tostring(doc, encoding='unicode') def _timesheet_get_portal_domain(self): + if self.env.user.has_group('hr_timesheet.group_hr_timesheet_user'): + # Then, he is internal user, and we take the domain for this current user + return self.env['ir.rule']._compute_domain(self._name) return ['&', '|', '|', '|', ('task_id.project_id.message_partner_ids', 'child_of', [self.env.user.partner_id.commercial_partner_id.id]), From c4a0c301ae93759c0daf95fedcfbb3606cd4403e Mon Sep 17 00:00:00 2001 From: "Xavier BOL (xbo)" Date: Tue, 5 Jan 2021 11:20:04 +0100 Subject: [PATCH 15/23] [IMP] project: move partner_id in project form view Before this commit, when the project is billable, we need to define a customer to have the list of SOL. The problem is the customer field is in "Settings" tab and not "Invoicing", it can be confused for the user to directly understand why he does not have the list of SO. This commit moves the customer field (that is partner_id) to the main sheet of the form view. Thus, the user can see directly if the customer is set or not in the project. task-2424382 --- addons/project/views/project_views.xml | 17 ++++++----------- addons/sale_timesheet/models/account.py | 2 +- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/addons/project/views/project_views.xml b/addons/project/views/project_views.xml index b8483f4fdc3..2ee22920939 100644 --- a/addons/project/views/project_views.xml +++ b/addons/project/views/project_views.xml @@ -276,13 +276,13 @@

-
-
-
-
+ + + + + + @@ -293,11 +293,6 @@ - - -