From 009bcc59febb2aefec6ffde3427b01cb08d1b9db Mon Sep 17 00:00:00 2001 From: "Laurent Stukkens (LTU)" Date: Fri, 20 Nov 2020 17:20:33 +0000 Subject: [PATCH] [IMP] sale_timesheet: adapt timesheet sections in portal Prior to this commit: * The portal timesheet section was only visible in invoices when invoicing policy was set to delivery. * The portal timesheet section was not visible on orders. After this commit: * The portal timesheet section will be displayed for both delivery and order invoicing policies. * The portal timesheet section will be available for orders. task-2388500 closes odoo/odoo#62516 Signed-off-by: Yannick Tivisse (yti) --- addons/sale/controllers/portal.py | 65 ++++++++++--------- addons/sale_timesheet/controllers/portal.py | 24 ++++++- addons/sale_timesheet/models/account.py | 15 ++++- .../views/sale_timesheet_portal_templates.xml | 52 +++++++++++++++ 4 files changed, 124 insertions(+), 32 deletions(-) diff --git a/addons/sale/controllers/portal.py b/addons/sale/controllers/portal.py index a06bba484d8..144acdac163 100644 --- a/addons/sale/controllers/portal.py +++ b/addons/sale/controllers/portal.py @@ -33,6 +33,39 @@ class CustomerPortal(portal.CustomerPortal): return values + def _order_get_page_view_values(self, order, access_token, **kwargs): + values = { + 'sale_order': order, + 'token': access_token, + 'return_url': '/shop/payment/validate', + 'bootstrap_formatting': True, + 'partner_id': order.partner_id.id, + 'report_type': 'html', + 'action': order._get_portal_return_action(), + } + if order.company_id: + values['res_company'] = order.company_id + + if order.has_to_be_paid(): + domain = expression.AND([ + ['&', ('state', 'in', ['enabled', 'test']), ('company_id', '=', order.company_id.id)], + ['|', ('country_ids', '=', False), ('country_ids', 'in', [order.partner_id.country_id.id])] + ]) + acquirers = request.env['payment.acquirer'].sudo().search(domain) + + values['acquirers'] = acquirers.filtered(lambda acq: (acq.payment_flow == 'form' and acq.view_template_id) or + (acq.payment_flow == 's2s' and acq.registration_view_template_id)) + values['pms'] = request.env['payment.token'].search([('partner_id', '=', order.partner_id.id)]) + values['acq_extra_fees'] = acquirers.get_acquirer_extra_fees(order.amount_total, order.currency_id, order.partner_id.country_id.id) + + if order.state in ('draft', 'sent', 'cancel'): + history = request.session.get('my_quotations_history', []) + else: + history = request.session.get('my_orders_history', []) + values.update(get_records_pager(history, order)) + + return values + # # Quotations and Sales Orders # @@ -166,36 +199,8 @@ class CustomerPortal(portal.CustomerPortal): partner_ids=order_sudo.user_id.sudo().partner_id.ids, ) - values = { - 'sale_order': order_sudo, - 'message': message, - 'token': access_token, - 'return_url': '/shop/payment/validate', - 'bootstrap_formatting': True, - 'partner_id': order_sudo.partner_id.id, - 'report_type': 'html', - 'action': order_sudo._get_portal_return_action(), - } - if order_sudo.company_id: - values['res_company'] = order_sudo.company_id - - if order_sudo.has_to_be_paid(): - domain = expression.AND([ - ['&', ('state', 'in', ['enabled', 'test']), ('company_id', '=', order_sudo.company_id.id)], - ['|', ('country_ids', '=', False), ('country_ids', 'in', [order_sudo.partner_id.country_id.id])] - ]) - acquirers = request.env['payment.acquirer'].sudo().search(domain) - - values['acquirers'] = acquirers.filtered(lambda acq: (acq.payment_flow == 'form' and acq.view_template_id) or - (acq.payment_flow == 's2s' and acq.registration_view_template_id)) - values['pms'] = request.env['payment.token'].search([('partner_id', '=', order_sudo.partner_id.id)]) - values['acq_extra_fees'] = acquirers.get_acquirer_extra_fees(order_sudo.amount_total, order_sudo.currency_id, order_sudo.partner_id.country_id.id) - - if order_sudo.state in ('draft', 'sent', 'cancel'): - history = request.session.get('my_quotations_history', []) - else: - history = request.session.get('my_orders_history', []) - values.update(get_records_pager(history, order_sudo)) + values = self._order_get_page_view_values(order_sudo, access_token, **kw) + values['message'] = message return request.render('sale.sale_order_portal_template', values) diff --git a/addons/sale_timesheet/controllers/portal.py b/addons/sale_timesheet/controllers/portal.py index 4439a8ba3fa..e4e04da4878 100644 --- a/addons/sale_timesheet/controllers/portal.py +++ b/addons/sale_timesheet/controllers/portal.py @@ -12,7 +12,29 @@ class PortalAccount(portal.PortalAccount): def _invoice_get_page_view_values(self, invoice, access_token, **kwargs): values = super(PortalAccount, self)._invoice_get_page_view_values(invoice, access_token, **kwargs) domain = request.env['account.analytic.line']._timesheet_get_portal_domain() - domain = expression.AND([domain, [('timesheet_invoice_id', '=', invoice.id)]]) + domain = expression.AND([ + domain, + request.env['account.analytic.line']._timesheet_get_sale_domain( + invoice.mapped('line_ids.sale_line_ids'), + request.env['account.move'].browse([invoice.id]) + ) + ]) + values['timesheets'] = request.env['account.analytic.line'].sudo().search(domain) + values['is_uom_day'] = request.env['account.analytic.line'].sudo()._is_timesheet_encode_uom_day() + return values + + +class CustomerPortal(portal.CustomerPortal): + def _order_get_page_view_values(self, order, access_token, **kwargs): + values = super(CustomerPortal, self)._order_get_page_view_values(order, access_token, **kwargs) + domain = request.env['account.analytic.line']._timesheet_get_portal_domain() + domain = expression.AND([ + domain, + request.env['account.analytic.line']._timesheet_get_sale_domain( + order.mapped('order_line'), + order.invoice_ids + ) + ]) values['timesheets'] = request.env['account.analytic.line'].sudo().search(domain) values['is_uom_day'] = request.env['account.analytic.line'].sudo()._is_timesheet_encode_uom_day() return values diff --git a/addons/sale_timesheet/models/account.py b/addons/sale_timesheet/models/account.py index 94744922a6c..977404fa88c 100644 --- a/addons/sale_timesheet/models/account.py +++ b/addons/sale_timesheet/models/account.py @@ -131,7 +131,20 @@ class AccountAnalyticLine(models.Model): thus there is no meaning of showing invoice with ordered quantity. """ domain = super(AccountAnalyticLine, self)._timesheet_get_portal_domain() - return expression.AND([domain, [('timesheet_invoice_type', 'in', ['billable_time', 'non_billable'])]]) + return expression.AND([domain, [('timesheet_invoice_type', 'in', ['billable_time', 'non_billable', 'billable_fixed'])]]) + + @api.model + def _timesheet_get_sale_domain(self, order_lines_ids, invoice_ids): + return [ + '|', + '&', + ('timesheet_invoice_id', 'in', invoice_ids.ids), + #TODO Question to Reviewer: non_billable was part of domain in _timesheet_get_portal_domain so I kept it here, does this make sense? + ('timesheet_invoice_type', 'in', ['billable_time', 'non_billable']), + '&', + ('timesheet_invoice_type', '=', 'billable_fixed'), + ('so_line', 'in', order_lines_ids.ids) + ] def _get_timesheets_to_merge(self): res = super(AccountAnalyticLine, self)._get_timesheets_to_merge() diff --git a/addons/sale_timesheet/views/sale_timesheet_portal_templates.xml b/addons/sale_timesheet/views/sale_timesheet_portal_templates.xml index d46a70893fc..9e198ababee 100644 --- a/addons/sale_timesheet/views/sale_timesheet_portal_templates.xml +++ b/addons/sale_timesheet/views/sale_timesheet_portal_templates.xml @@ -59,4 +59,56 @@ + +