def accept(self, order_id, token=None, signer=None, sign=None, **post): order_obj = request.registry.get('sale.order') order = order_obj.browse(request.cr, SUPERUSER_ID, order_id) if token != order.access_token: return request.website.render('website.404') if order.require_payment: return request.website.render('website.404') if order.state != 'sent': return False attachments=sign and [('signature.png', sign.decode('base64'))] or [] ctx = dict(request.context) ctx['websiteQuote'] = True order_obj.action_confirm_quote(request.cr, SUPERUSER_ID, [order_id], context=ctx) message = _('Order signed by %s') % (signer,) _message_post_helper(message=message, res_id=order_id, res_model='sale.order', attachments=attachments, **({'token': token, 'token_field': 'access_token'} if token else {})) try: messageIQ = _('Quotation is accepted by the Customer') order.intorder_id.sudo().message_post(body = messageIQ) order.intorder_id.sudo().action_done() except: pass return True
def portal_quote_accept(self, res_id, access_token=None, partner_name=None, signature=None, order_id=None): try: order_sudo = self._document_check_access('sale.order', res_id, access_token=access_token) except (AccessError, MissingError): return {'error': _('Invalid order')} if order_sudo.state != 'sent': return {'error': _('Order is not in a state requiring customer validation.')} if not order_sudo.has_to_be_signed() and not order_sudo.has_to_be_paid(): return {'error': _('Operation not allowed')} if not signature: return {'error': _('Signature is missing.')} success_message = _('Your order has been signed but still needs to be paid to be confirmed.') if not order_sudo.has_to_be_paid(): order_sudo.action_confirm() success_message = _('Your order has been confirmed.') order_sudo.signature = signature order_sudo.signed_by = partner_name pdf = request.env.ref('sale.action_report_saleorder').sudo().render_qweb_pdf([order_sudo.id])[0] _message_post_helper( res_model='sale.order', res_id=order_sudo.id, message=_('Order signed by %s') % (partner_name,), attachments=[('%s.pdf' % order_sudo.name, pdf)], **({'token': access_token} if access_token else {})) return { 'success': success_message, 'redirect_url': order_sudo.get_portal_url(), }
def portal_quote_accept(self, res_id, access_token=None, partner_name=None, signature=None): if request.env['ir.config_parameter'].sudo().get_param( 'sale.sale_portal_confirmation_options', default='none') not in ('pay', 'sign'): return False try: order_sudo = self._order_check_access(res_id, access_token=access_token) except AccessError: return { 'error': _('Invalid order') } if order_sudo.state != 'sent': return { 'error': _('Order is not in a state requiring customer validation.') } order_sudo.action_confirm() _message_post_helper( res_model='sale.order', res_id=order_sudo.id, message=_('Order signed by %s') % (partner_name,), attachments=[('signature.png', base64.b64decode(signature))] if signature else [], **({'token': access_token, 'token_field': 'access_token'} if access_token else {})) return { 'success': _('Your Order has been confirmed.'), 'redirect_url': '/my/orders/%s?%s' % (order_sudo.id, access_token and 'access_token=%s' % order_sudo.access_token or ''), }
def portal_quote_accept(self, res_id, access_token=None, partner_name=None, signature=None): if not self._portal_quote_user_can_accept(res_id): return {'error': _('Operation not allowed')} if not signature: return {'error': _('Signature is missing.')} try: order_sudo = self._order_check_access(res_id, access_token=access_token) except AccessError: return {'error': _('Invalid order')} if order_sudo.state != 'sent': return {'error': _('Order is not in a state requiring customer validation.')} order_sudo.action_confirm() _message_post_helper( res_model='sale.order', res_id=order_sudo.id, message=_('Order signed by %s') % (partner_name,), attachments=[('signature.png', base64.b64decode(signature))] if signature else [], **({'token': access_token} if access_token else {})) return { 'success': _('Your Order has been confirmed.'), 'redirect_url': '/my/orders/%s?%s' % (order_sudo.id, access_token and 'access_token=%s' % order_sudo.access_token or ''), }
def portal_quote_accept(self, res_id, access_token=None, partner_name=None, signature=None): if not self._portal_quote_user_can_accept(res_id): return {'error': _('Operation not allowed')} if not signature: return {'error': _('Signature is missing.')} try: order_sudo = self._order_check_access(res_id, access_token=access_token) except AccessError: return {'error': _('Invalid order')} if order_sudo.state != 'quot': return {'error': _('Order is not in a state requiring customer validation.')} order_sudo.do_confirm() _message_post_helper( res_model='s2u.sale', res_id=order_sudo.id, message=_('Order signed by %s') % (partner_name,), attachments=[('signature.png', base64.b64decode(signature))] if signature else [], **({'token': access_token} if access_token else {})) return { 'success': _('Your Order has been confirmed.'), 'redirect_url': '/my/orders/%s?%s' % (order_sudo.id, access_token and 'access_token=%s' % order_sudo.access_token or ''), }
def portal_quote_accept(self, res_id, access_token=None, partner_name=None, signature=None, order_id=None): try: order_sudo = self._document_check_access('sale.order', res_id, access_token=access_token) except (AccessError, MissingError): return {'error': _('Invalid order')} if not order_sudo.has_to_be_signed(): return {'error': _('Order is not in a state requiring customer signature.')} if not signature: return {'error': _('Signature is missing.')} if not order_sudo.has_to_be_paid(): order_sudo.action_confirm() order_sudo.signature = signature order_sudo.signed_by = partner_name pdf = request.env.ref('sale.action_report_saleorder').sudo().render_qweb_pdf([order_sudo.id])[0] _message_post_helper( res_model='sale.order', res_id=order_sudo.id, message=_('Order signed by %s') % (partner_name,), attachments=[('%s.pdf' % order_sudo.name, pdf)], **({'token': access_token} if access_token else {})) return { 'force_refresh': True, 'redirect_url': order_sudo.get_portal_url(query_string='&message=sign_ok'), }
def portal_quote_decline(self, order_id, access_token=None, decline_message=None, **kwargs): try: order_sudo = self._document_check_access('sale.order', order_id, access_token=access_token) except (AccessError, MissingError): return request.redirect('/my') if order_sudo.has_to_be_signed() and decline_message: order_sudo.action_cancel() _message_post_helper( 'sale.order', order_sudo.id, decline_message, token=access_token, ) redirect_url = order_sudo.get_portal_url() else: redirect_url = order_sudo.get_portal_url( query_string="&message=cant_reject") return request.redirect(redirect_url)
def portal_quote_accept(self, res_id, access_token=None, partner_name=None, signature=None, order_id=None): try: order_sudo = self._document_check_access('sale.order', res_id, access_token=access_token) except (AccessError, MissingError): return {'error': _('Invalid order')} if not order_sudo.has_to_be_signed(): return {'error': _('The order is not in a state requiring customer signature.')} if not signature: return {'error': _('Signature is missing.')} if not order_sudo.has_to_be_paid(): order_sudo.action_confirm() order_sudo.signature = signature order_sudo.signed_by = partner_name pdf = request.env.ref('sale.action_report_saleorder').sudo().render_qweb_pdf([order_sudo.id])[0] _message_post_helper( res_model='sale.order', res_id=order_sudo.id, message=_('Order signed by %s') % (partner_name,), attachments=[('%s.pdf' % order_sudo.name, pdf)], **({'token': access_token} if access_token else {})) return { 'force_refresh': True, 'redirect_url': order_sudo.get_portal_url(query_string='&message=sign_ok'), }
def portal_order_page(self, order_id, report_type=None, access_token=None, message=False, download=False, **kw): try: order_sudo = self._document_check_access('sale.order', order_id, access_token=access_token) except (AccessError, MissingError): return request.redirect('/my') if report_type in ('html', 'pdf', 'text'): return self._show_report(model=order_sudo, report_type=report_type, report_ref='sale.action_report_saleorder', download=download) # use sudo to allow accessing/viewing orders for public user # only if he knows the private token # Log only once a day if order_sudo: # store the date as a string in the session to allow serialization now = fields.Date.today().isoformat() session_obj_date = request.session.get('view_quote_%s' % order_sudo.id) if session_obj_date != now and request.env.user.share and access_token: request.session['view_quote_%s' % order_sudo.id] = now body = _('Quotation viewed by customer %s', order_sudo.partner_id.name) _message_post_helper( "sale.order", order_sudo.id, body, token=order_sudo.access_token, message_type="notification", subtype_xmlid="mail.mt_note", partner_ids=order_sudo.user_id.sudo().partner_id.ids, ) values = self._order_get_page_view_values(order_sudo, access_token, **kw) values['message'] = message return request.render('sale.sale_order_portal_template', values)
def view(self, order_id, pdf=None, token=None, message=False, **post): # use sudo to allow accessing/viewing orders for public user # only if he knows the private token now = fields.Date.today() if token: Order = request.env['sale.order'].sudo().search([('id', '=', order_id), ('access_token', '=', token)]) else: Order = request.env['sale.order'].search([('id', '=', order_id)]) # Log only once a day if Order and request.session.get('view_quote_%s' % Order.id) != now and request.env.user.share: request.session['view_quote_%s' % Order.id] = now body = _('Quotation viewed by customer') _message_post_helper(res_model='sale.order', res_id=Order.id, message=body, token=token, message_type='notification', subtype="mail.mt_note", partner_ids=Order.user_id.sudo().partner_id.ids) if not Order: return request.render('website.404') # Token or not, sudo the order, since portal user has not access on # taxes, required to compute the total_amout of SO. order_sudo = Order.sudo() days = 0 if order_sudo.validity_date: days = (fields.Date.from_string(order_sudo.validity_date) - fields.Date.from_string(fields.Date.today())).days + 1 if pdf: pdf = request.env.ref('website_quote.report_web_quote').sudo().with_context(set_viewport_size=True).render_qweb_pdf([order_sudo.id])[0] pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(pdf))] return request.make_response(pdf, headers=pdfhttpheaders) transaction = order_sudo.get_portal_last_transaction() values = { 'quotation': order_sudo, 'message': message and int(message) or False, 'option': any(not x.line_id for x in order_sudo.options), 'order_valid': (not order_sudo.validity_date) or (now <= order_sudo.validity_date), 'days_valid': days, 'action': request.env.ref('sale.action_quotations').id, 'no_breadcrumbs': request.env.user.partner_id.commercial_partner_id not in order_sudo.message_partner_ids, 'tx_id': transaction.id if transaction else False, 'tx_state': transaction.state if transaction else False, 'payment_tx': transaction, 'tx_post_msg': transaction.acquirer_id.post_msg if transaction else False, 'need_payment': order_sudo.invoice_status == 'to invoice' and transaction.state in ['draft', 'cancel'], 'token': token, 'return_url': '/shop/payment/validate', 'bootstrap_formatting': True, 'partner_id': order_sudo.partner_id.id, } if order_sudo.require_payment or values['need_payment']: acquirers = request.env['payment.acquirer'].sudo().search([('website_published', '=', True), ('company_id', '=', order_sudo.company_id.id)]) values['form_acquirers'] = [acq for acq in acquirers if acq.payment_flow == 'form' and acq.view_template_id] values['s2s_acquirers'] = [acq for acq in acquirers if acq.payment_flow == 's2s' and acq.registration_view_template_id] values['pms'] = request.env['payment.token'].search( [('partner_id', '=', order_sudo.partner_id.id), ('acquirer_id', 'in', [acq.id for acq in values['s2s_acquirers']])]) history = request.session.get('my_quotes_history', []) values.update(get_records_pager(history, order_sudo)) return request.render('website_quote.so_quotation', values)
def portal_request_chatter_post(self, res_model, res_id, message, **kw): url = http.request.httprequest.referrer if message: # message is received in plaintext and saved in html # message = plaintext2html(message) _message_post_helper(res_model, int(res_id), message, **kw) url = url + "#discussion" return http.request.redirect(url)
def portal_quote_accept(self, order_id, access_token=None, name=None, signature=None): # get from query string if not on json param access_token = access_token or request.httprequest.args.get( 'access_token') try: order_sudo = self._document_check_access('sale.order', order_id, access_token=access_token) except (AccessError, MissingError): return {'error': _('Invalid order.')} if not order_sudo.has_to_be_signed(): return { 'error': _('The order is not in a state requiring customer signature.') } if not signature: return {'error': _('Signature is missing.')} try: order_sudo.write({ 'signed_by': name, 'signed_on': fields.Datetime.now(), 'signature': signature, }) request.env.cr.commit() except (TypeError, binascii.Error) as e: return {'error': _('Invalid signature data.')} if not order_sudo.has_to_be_paid(): order_sudo.action_confirm() order_sudo._send_order_confirmation_mail() pdf = request.env.ref( 'sale.action_report_saleorder').sudo().render_qweb_pdf( [order_sudo.id])[0] _message_post_helper('sale.order', order_sudo.id, _('Order signed by %s') % (name, ), attachments=[('%s.pdf' % order_sudo.name, pdf)], **({ 'token': access_token } if access_token else {})) query_string = '&message=sign_ok' if order_sudo.has_to_be_paid(True): query_string += '#allow_payment=yes' return { 'force_refresh': True, 'redirect_url': order_sudo.get_portal_url(query_string=query_string), }
def portal_order_page(self, order_id, pdf=None, access_token=None, message=False, **kw): try: order_sudo = self._document_check_access('sale.order', order_id, access_token=access_token) except (AccessError, MissingError): return request.redirect('/my') if pdf: pdf = request.env.ref('sale.report_web_quote').sudo().with_context(set_viewport_size=True).render_qweb_pdf([order_sudo.id])[0] pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(pdf))] return request.make_response(pdf, headers=pdfhttpheaders) # use sudo to allow accessing/viewing orders for public user # only if he knows the private token now = fields.Date.today() # Log only once a day if order_sudo and request.session.get('view_quote_%s' % order_sudo.id) != now and request.env.user.share and access_token: request.session['view_quote_%s' % order_sudo.id] = now body = _('Quotation viewed by customer') _message_post_helper(res_model='sale.order', res_id=order_sudo.id, message=body, token=order_sudo.access_token, message_type='notification', subtype="mail.mt_note", partner_ids=order_sudo.user_id.sudo().partner_id.ids) transaction = order_sudo.get_portal_last_transaction() # TODO SEB fix breadcrumbs -> should always be visible (or at least no home alone) values = { 'sale_order': order_sudo, 'message': int(message) if message else False, 'action': request.env.ref('sale.action_quotations').id, 'no_breadcrumbs': request.env.user.partner_id.commercial_partner_id not in order_sudo.message_partner_ids, 'tx_state': transaction.state if transaction else False, 'need_payment': order_sudo.invoice_status == 'to invoice' and transaction.state in ['draft', 'cancel'], 'token': access_token, 'return_url': '/shop/payment/validate', 'bootstrap_formatting': True, 'partner_id': order_sudo.partner_id.id, } if order_sudo.has_to_be_paid() or values['need_payment']: domain = expression.AND([ ['&', ('website_published', '=', True), ('company_id', '=', order_sudo.company_id.id)], ['|', ('specific_countries', '=', False), ('country_ids', 'in', [order_sudo.partner_id.country_id.id])] ]) acquirers = request.env['payment.acquirer'].sudo().search(domain) values['form_acquirers'] = [acq for acq in acquirers if acq.payment_flow == 'form' and acq.view_template_id] values['s2s_acquirers'] = [acq for acq in acquirers if acq.payment_flow == 's2s' and acq.registration_view_template_id] values['pms'] = request.env['payment.token'].search( [('partner_id', '=', order_sudo.partner_id.id), ('acquirer_id', 'in', [acq.id for acq in values['s2s_acquirers']])]) history = request.session.get('my_quotes_history', []) values.update(get_records_pager(history, order_sudo)) return request.render('sale.sale_order_portal_template', values)
def decline(self, order_id, token, **post): Order = request.env['sale.order'].sudo().browse(order_id) if token != Order.access_token: return request.render('website.404') if Order.state != 'sent': return werkzeug.utils.redirect("/quote/%s/%s?message=4" % (order_id, token)) Order.action_cancel() message = post.get('decline_message') if message: _message_post_helper(message=message, res_id=order_id, res_model='sale.order', **{'token': token} if token else {}) return werkzeug.utils.redirect("/quote/%s/%s?message=2" % (order_id, token))
def accept(self, order_id, token=None, signer=None, sign=None, **post): Order = request.env['sale.order'].sudo().browse(order_id) if token != Order.access_token or Order.require_payment: return request.render('website.404') if Order.state != 'sent': return False attachments = [('signature.png', base64.b64decode(sign))] if sign else [] Order.action_confirm() message = _('Order signed by %s') % (signer,) _message_post_helper(message=message, res_id=order_id, res_model='sale.order', attachments=attachments, **({'token': token, 'token_field': 'access_token'} if token else {})) return True
def portal_order_page(self, order_id, report_type=None, access_token=None, message=False, download=False, **kw): try: order_sudo = self._document_check_access('sale.order', order_id, access_token=access_token) except (AccessError, MissingError): return request.redirect('/my') if report_type in ('html', 'pdf', 'text'): return self._show_report(model=order_sudo, report_type=report_type, report_ref='sale.action_report_saleorder', download=download) # use sudo to allow accessing/viewing orders for public user # only if he knows the private token now = fields.Date.today() # Log only once a day if order_sudo and request.session.get( 'view_quote_%s' % order_sudo.id) != now and request.env.user.share and access_token: request.session['view_quote_%s' % order_sudo.id] = now body = _('Quotation viewed by customer') _message_post_helper(res_model='sale.order', res_id=order_sudo.id, message=body, token=order_sudo.access_token, message_type='notification', subtype="mail.mt_note", 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', } if order_sudo.company_id: values['res_company'] = order_sudo.company_id if order_sudo.has_to_be_paid(): domain = expression.AND([ ['&', ('website_published', '=', True), ('company_id', '=', order_sudo.company_id.id)], ['|', ('specific_countries', '=', 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)]) 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)) return request.render('sale.sale_order_portal_template', values)
def decline(self, order_id, token, **post): Order = request.env['sale.order'].sudo().browse(order_id) if token != Order.access_token: return request.render('website.404') if Order.state != 'sent': return werkzeug.utils.redirect("/quote/%s/%s?message=4" % (order_id, token)) Order.action_cancel() message = post.get('decline_message') if message: _message_post_helper(message=message, res_id=order_id, res_model='sale.order', **{'token': token} if token else {}) return werkzeug.utils.redirect("/quote/%s/%s?message=2" % (order_id, token))
def portal_quote_accept(self, res_id, access_token=None, partner_name=None, signature=None): try: order_sudo = self._document_check_access('sale.order', res_id, access_token=access_token) except AccessError: return {'error': _('Invalid order')} if order_sudo.state != 'sent': return { 'error': _('Order is not in a state requiring customer validation.') } if not self._portal_quote_user_can_accept(order_sudo): return {'error': _('Operation not allowed')} if not signature: return {'error': _('Signature is missing.')} success_message = _( 'Your order has been signed but still needs to be paid to be confirmed.' ) if not order_sudo.has_to_be_paid(): order_sudo.action_confirm() success_message = _('Your order has been confirmed.') order_sudo.signature = signature order_sudo.signed_by = partner_name pdf = request.env.ref( 'sale.action_report_saleorder').sudo().render_qweb_pdf( [order_sudo.id])[0] _message_post_helper(res_model='sale.order', res_id=order_sudo.id, message=_('Order signed by %s') % (partner_name, ), attachments=[('%s.pdf' % order_sudo.name, pdf)], **({ 'token': access_token } if access_token else {})) return { 'success': success_message, 'redirect_url': '/my/orders/%s?%s' % (order_sudo.id, access_token and 'access_token=%s' % order_sudo.access_token or ''), }
def portal_order_page(self, order_id, report_type=None, access_token=None, message=False, download=False, **kw): try: order_sudo = self._document_check_access('sale.order', order_id, access_token=access_token) except (AccessError, MissingError): return request.redirect('/my') if report_type in ('html', 'pdf', 'text'): return self._show_report(model=order_sudo, report_type=report_type, report_ref='sale.report_web_quote', download=download) # use sudo to allow accessing/viewing orders for public user # only if he knows the private token now = fields.Date.today() # Log only once a day if order_sudo and request.session.get('view_quote_%s' % order_sudo.id) != now and request.env.user.share and access_token: request.session['view_quote_%s' % order_sudo.id] = now body = _('Quotation viewed by customer') _message_post_helper(res_model='sale.order', res_id=order_sudo.id, message=body, token=order_sudo.access_token, message_type='notification', subtype="mail.mt_note", partner_ids=order_sudo.user_id.sudo().partner_id.ids) transaction = order_sudo.get_portal_last_transaction() values = { 'sale_order': order_sudo, 'message': int(message) if message else False, 'tx_state': transaction.state if transaction else False, 'need_payment': order_sudo.invoice_status == 'to invoice' and transaction.state in ['draft', 'cancel'], 'token': access_token, 'return_url': '/shop/payment/validate', 'bootstrap_formatting': True, 'partner_id': order_sudo.partner_id.id, 'report_type': 'html', } if order_sudo.has_to_be_paid() or values['need_payment']: domain = expression.AND([ ['&', ('website_published', '=', True), ('company_id', '=', order_sudo.company_id.id)], ['|', ('specific_countries', '=', False), ('country_ids', 'in', [order_sudo.partner_id.country_id.id])] ]) acquirers = request.env['payment.acquirer'].sudo().search(domain) values['form_acquirers'] = [acq for acq in acquirers if acq.payment_flow == 'form' and acq.view_template_id] values['s2s_acquirers'] = [acq for acq in acquirers if acq.payment_flow == 's2s' and acq.registration_view_template_id] values['pms'] = request.env['payment.token'].search( [('partner_id', '=', order_sudo.partner_id.id), ('acquirer_id', 'in', [acq.id for acq in values['s2s_acquirers']])]) 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)) return request.render('sale.sale_order_portal_template', values)
def portal_order_page(self, order_id, report_type=None, access_token=None, message=False, download=False, **kw): try: order_sudo = self._document_check_access('sale.order', order_id, access_token=access_token) except (AccessError, MissingError): return request.redirect('/my') if report_type in ('html', 'pdf', 'text'): return self._show_report(model=order_sudo, report_type=report_type, report_ref='sale.action_report_saleorder', download=download) # use sudo to allow accessing/viewing orders for public user # only if he knows the private token now = fields.Date.today() # Log only once a day if order_sudo and request.session.get('view_quote_%s' % order_sudo.id) != now and request.env.user.share and access_token: request.session['view_quote_%s' % order_sudo.id] = now body = _('Quotation viewed by customer %s') % order_sudo.partner_id.name _message_post_helper('sale.order', order_sudo.id, body, token=order_sudo.access_token, message_type='notification', subtype="mail.mt_note", 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', } if order_sudo.company_id: values['res_company'] = order_sudo.company_id if order_sudo.has_to_be_paid(): domain = expression.AND([ ['&', ('website_published', '=', True), ('company_id', '=', order_sudo.company_id.id)], ['|', ('specific_countries', '=', 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), ('acquirer_id', 'in', acquirers.filtered(lambda acq: acq.payment_flow == 's2s').ids)]) 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)) return request.render('sale.sale_order_portal_template', values)
def decline(self, order_id, access_token=None, **post): try: order_sudo = self._document_check_access('sale.order', order_id, access_token=access_token) except (AccessError, MissingError): return request.redirect('/my') if order_sudo.state != 'sent': return request.redirect(order_sudo.get_portal_url(query_string="&message=4")) order_sudo.action_cancel() message = post.get('decline_message') if message: _message_post_helper(message=message, res_id=order_id, res_model='sale.order', **{'token': access_token} if access_token else {}) return request.redirect(order_sudo.get_portal_url())
def portal_worksheet_sign(self, task_id, access_token=None, source=False, name=None, signature=None): # get from query string if not on json param access_token = access_token or request.httprequest.args.get( 'access_token') try: task_sudo = self._document_check_access('project.task', task_id, access_token=access_token) except (AccessError, MissingError): return {'error': _('Invalid Task.')} if not task_sudo.has_to_be_signed(): return { 'error': _('The worksheet is not in a state requiring customer signature.' ) } if not signature: return {'error': _('Signature is missing.')} try: task_sudo.write({ 'worksheet_signature': signature, 'worksheet_signed_by': name, }) except (TypeError, binascii.Error): return {'error': _('Invalid signature data.')} _message_post_helper( 'project.task', task_sudo.id, _('Task signed by %s') % (name, ), **({ 'token': access_token } if access_token else {})) query_string = '&message=sign_ok' return { 'force_refresh': True, 'redirect_url': task_sudo.get_portal_url(suffix='/worksheet/%s' % source, query_string=query_string), }
def generate_invoice(self, order_id=None, **data): sale_obj = request.env['sale.order'] sale = sale_obj.sudo().browse(order_id) if not sale.partner_id.vat: _message_post_helper( message=_('Please define your VAT, after try to generate the ' 'invoice again.'), res_id=order_id, res_model='sale.order') return request.redirect(sale.get_portal_url()) if sale.invoice_status != 'invoiced': invoice = sale.action_invoice_create() request.env['account.move'].browse( invoice).sudo().action_post() return request.redirect(sale.get_portal_url()) sale.invoice_ids.l10n_mx_edi_action_reinvoice() return request.redirect(sale.get_portal_url())
def decline(self, order_id, access_token=None, **post): try: order_sudo = self._document_check_access('sale.order', order_id, access_token=access_token) except (AccessError, MissingError): return request.redirect('/my') message = post.get('decline_message') query_string = False if order_sudo.has_to_be_signed() and message: order_sudo.action_cancel() _message_post_helper('sale.order', order_id, message, **{'token': access_token} if access_token else {}) else: query_string = "&message=cant_reject" return request.redirect(order_sudo.get_portal_url(query_string=query_string))
def decline(self, order_id, access_token=None, **post): try: order_sudo = self._document_check_access('sale.order', order_id, access_token=access_token) except (AccessError, MissingError): return request.redirect('/my') message = post.get('decline_message') query_string = False if order_sudo.has_to_be_signed() and message: order_sudo.action_cancel() _message_post_helper(message=message, res_id=order_id, res_model='sale.order', **{'token': access_token} if access_token else {}) else: query_string = "&message=cant_reject" return request.redirect(order_sudo.get_portal_url(query_string=query_string))
def vendor_offer_reject(self, res_id,order_id=None, partner_name=None, signature=None,access_token=None): if not signature: return {'error': _('Signature is missing.')} order = request.env['purchase.order'].browse(res_id) order_sudo = order.sudo() val = order_sudo.action_cancel_vendor_offer_api(res_id) _message_post_helper( res_model='purchase.order', res_id=order_sudo.id, message=_('Order rejected by %s') % (partner_name,), attachments=[('signature.png', base64.b64decode(signature))] if signature else [], **({'token': access_token} if access_token else {})) return { 'success': _('Your Order has been rejected.'), 'redirect_url': '/my/home', }
def portal_my_invoice_payment_detail_accept(self, invoice_id, access_token=None, name=None, signature=None): # get from query string if not on json param access_token = access_token or request.httprequest.args.get('access_token') try: invoice = self._document_check_access('account.payment', invoice_id, access_token=access_token) except (AccessError, MissingError): return {'error': _('Invalid order.')} # if not invoice.has_to_be_signed(): # return {'error': _('The order is not in a state requiring customer signature.')} if not signature: return {'error': _('Signature is missing.')} if invoice.state != 'invoice send' and invoice.state != 'pre confirm' : return {'error': _('The invoice is not in a state requiring customer signature.')} if invoice.state == 'pre confirm' : return {'error': _('The invoice has already been signed by the customer.')} try: invoice.write({ 'signed_by': name, 'signed_on': fields.Datetime.now(), 'signature': signature, 'state':'pre confirm', }) except (TypeError, binascii.Error) as e: return {'error': _('Invalid signature data.')} # if not invoice.has_to_be_paid(): # # order_sudo.action_confirm() # invoice._send_order_confirmation_mail() pdf = request.env.ref('account_payment_mail.account_payment_invoices').sudo().render_qweb_pdf([invoice.id])[0] _message_post_helper( 'account.payment', invoice.id, _('Invoice signed by %s') % (name,), attachments=[('%s.pdf' % invoice.name, pdf)], **({'token': access_token} if access_token else {})) query_string = '&message=sign_ok' # if invoice.has_to_be_paid(True): # query_string += '#allow_payment=yes' # invoice.state = 'pre-conform' return { 'force_refresh': True, 'redirect_url': invoice.get_portal_url(query_string=query_string), }
def portal_quote_validate(self, res_id, access_token=None, partner_name=None, signature=None, client_po_no=None): if not self._portal_quote_user_can_validate(res_id): return {'error': _('Operation not allowed')} if not signature: return {'error': _('Signature is missing.')} # if not client_po: # return {'error': _('Purchase Order is missing.')} try: order_sudo = self._order_check_access(res_id, access_token=access_token) except AccessError: return {'error': _('Invalid order')} if order_sudo.state != 'sent': return { 'error': _('Order is not in a state requiring customer validation.') } order_sudo.write({'x_clientpo': client_po_no, 'state': 'confirm'}) # order_sudo.action_confirm() _message_post_helper( res_model='sale.order', res_id=order_sudo.id, # message=_('Order signed by %s. \nPurchase Order Number: %s') % (partner_name,client_po_no,), # attachments=[('purchase.pdf', base64.b64decode(client_po))] if client_po else [], message=_('Order signed by %s. Purchase Order Number: %s') % (partner_name, client_po_no), attachments=[('signature.png', base64.b64decode(signature))] if signature else [], **({ 'token': access_token } if access_token else {})) return { 'success': _('Your order has been confirmed.'), 'redirect_url': '/my/orders/%s?%s' % (order_sudo.id, access_token and 'access_token=%s' % order_sudo.access_token or ''), }
def portal_stock_accept(self, res_id, access_token=None, partner_name=None, signature=None, stock_picking_id=None): try: stock_picking_sudo = self._document_check_access( 'stock.picking', res_id, access_token=access_token) except (AccessError, MissingError): return {'error': _('Invalid stock picking')} if not stock_picking_sudo.has_to_be_signed(): return { 'error': _('Stock picking is not in a' + 'state requiring customer signature.') } if not signature: return {'error': _('Signature is missing.')} stock_picking_sudo.signature = signature stock_picking_sudo.signed_by = partner_name Stock_Picking_Report = request.env.ref('stock.action_report_picking') pdf_1 = Stock_Picking_Report.sudo().render_qweb_pdf( [stock_picking_sudo.id])[0] pdf_2 = Stock_Picking_Report.sudo().render_qweb_pdf( [stock_picking_sudo.id])[0] _message_post_helper( res_model='stock.picking', res_id=stock_picking_sudo.id, message=_('Stock picking signed by %s') % (partner_name, ), attachments=[('%s.pdf' % stock_picking_sudo.name, pdf_1), ('%s.pdf' % stock_picking_sudo.name, pdf_2)], **({ 'token': access_token } if access_token else {})) return { 'force_refresh': True, 'redirect_url': stock_picking_sudo.get_portal_url(query_string='&message=sign_ok') }
def decline(self, order_id, access_token=None, **post): try: order_sudo = self._document_check_access('sale.order', order_id, access_token=access_token) except (AccessError, MissingError): return request.redirect('/my') if order_sudo.state != 'sent': return request.redirect(order_sudo.get_portal_url() + "&message=4") order_sudo.action_cancel() message = post.get('decline_message') if message: _message_post_helper( message=message, res_id=order_id, res_model='sale.order', **{'token': access_token} if access_token else {}) return request.redirect(order_sudo.get_portal_url())
def decline(self, proposal_id, access_token=None, **post): try: proposal_sudo = self._document_check_access( 'sale.proposal', proposal_id, access_token=access_token) except (AccessError, MissingError): return request.redirect('/') message = post.get('decline_message') query_string = False if message: proposal_sudo.state = 'cancel' _message_post_helper( 'sale.proposal', proposal_id, message, **{'token': access_token} if access_token else {}) else: query_string = "&message=cant_reject" return request.redirect( proposal_sudo.get_portal_url(query_string=query_string))
def accept(self, order_id, token, **post): Order = request.env['sale.order'].sudo().browse(order_id) print("order.client_order_ref") if token != Order.access_token: return request.render('website.404') if Order.state != 'sent': return werkzeug.utils.redirect("/quote/%s/%s?message=4" % (order_id, token)) Order.action_confirm() message = post.get('accept_message') client_order_ref = post.get('client_order_ref') print(client_order_ref) if client_order_ref: Order.write({"client_order_ref": client_order_ref}) if message: _message_post_helper(message=message, res_id=order_id, res_model='sale.order', **{'token': token} if token else {}) return werkzeug.utils.redirect("/quote/%s/%s?message=3" % (order_id, token))
def portal_chatter_post(self, res_model, res_id, message, **kw): url = request.httprequest.referrer notifications = [] if message: # message is received in plaintext and saved in html message = plaintext2html(message) _message_post_helper(res_model, int(res_id), message, **kw) if res_model == 'project.task': users_list = [] for user in request.env['res.users'].search([]): users_list.append(user.id) for user_id in users_list: notifications.append( ((request._cr.dbname, 'project.task', user_id), { 'chatter_notification': True, 'project_task_id': int(res_id) })) if notifications: request.env['bus.bus'].sendmany(notifications) url = url + "#discussion" return request.redirect(url)
def portal_quote_accept(self, order_id, access_token=None, name=None, signature=None): # get from query string if not on json param access_token = access_token or request.httprequest.args.get('access_token') try: order_sudo = self._document_check_access('sale.order', order_id, access_token=access_token) except (AccessError, MissingError): return {'error': _('Invalid order.')} if not order_sudo.has_to_be_signed(): return {'error': _('The order is not in a state requiring customer signature.')} if not signature: return {'error': _('Signature is missing.')} try: order_sudo.write({ 'signed_by': name, 'signed_on': fields.Datetime.now(), 'signature': signature, }) except (TypeError, binascii.Error) as e: return {'error': _('Invalid signature data.')} if not order_sudo.has_to_be_paid(): order_sudo.action_confirm() order_sudo._send_order_confirmation_mail() pdf = request.env.ref('sale.action_report_saleorder').sudo().render_qweb_pdf([order_sudo.id])[0] _message_post_helper( 'sale.order', order_sudo.id, _('Order signed by %s') % (name,), attachments=[('%s.pdf' % order_sudo.name, pdf)], **({'token': access_token} if access_token else {})) query_string = '&message=sign_ok' if order_sudo.has_to_be_paid(True): query_string += '#allow_payment=yes' return { 'force_refresh': True, 'redirect_url': order_sudo.get_portal_url(query_string=query_string), }
def decline(self, order_id, token, **post): print ("decline ****") ctx = dict(self._context) order_obj = request.registry.get('sale.order') order = order_obj.browse(request.cr, SUPERUSER_ID, order_id) if token != order.access_token: return request.website.render('website.404') if order.state != 'sent': return werkzeug.utils.redirect("/quote/%s/%s?message=4" % (order_id, token)) request.registry.get('sale.order').action_cancel(request.cr, SUPERUSER_ID, [order_id]) message = post.get('decline_message') if message: _message_post_helper(message=message, res_id=order_id, res_model='sale.order', **{'token': token, 'token_field': 'access_token'} if token else {}) try: messageIQ = _('Quotation is rejected by the Customer') order.intorder_id.sudo().message_post(body = messageIQ) ctx.update({'websiteCall' : True}) order.intorder_id.sudo().with_context().action_rejected() except: pass return werkzeug.utils.redirect("/quote/%s/%s?message=2" % (order_id, token))
def portal_my_invoice_payment_detail(self, invoice_id, access_token=None, report_type=None, download=False, **kw): try: invoice_sudo = self._document_check_access('account.payment', invoice_id, access_token=access_token) except (AccessError, MissingError): return request.redirect('/my') if report_type in ('html', 'pdf', 'text'): return self._show_report(model=invoice_sudo, report_type=report_type, report_ref='account_payment_mail.account_payment_invoices', download=download) values = self._invoice_get_page_view_values(invoice_sudo, access_token, **kw) acquirers = values.get('acquirers') if invoice_sudo: now = fields.Date.today().isoformat() session_obj_date = request.session.get('view_quote_%s' % invoice_sudo.id) if isinstance(session_obj_date, date): session_obj_date = session_obj_date.isoformat() if session_obj_date != now and request.env.user.share and access_token: request.session['view_quote_%s' % invoice_sudo.id] = now body = _('Invoice viewed by customer %s') % invoice_sudo.partner_id.name _message_post_helper( "account.payment", invoice_sudo.id, body, token=invoice_sudo.access_token, message_type="notification", subtype="mail.mt_note", partner_ids=invoice_sudo.sudo().partner_id.ids, ) # if acquirers: # country_id = values.get('partner_id') and values.get('partner_id')[0].country_id.id # values['acq_extra_fees'] = acquirers.get_acquirer_extra_fees(invoice_sudo.amount_residual, invoice_sudo.currency_id, country_id) return request.render("account_payment_mail.portal_invoice_page_account_payment", values)
def portal_request_chatter_post(self, res_model, res_id, message, redirect=None, attachment_ids='', attachment_tokens='', **kw): url = redirect if not url and http.request.httprequest.referrer: url = http.request.httprequest.referrer + "#discussion" if not url: url = '/my' res_id = int(res_id) attachment_ids = [ int(attachment_id) for attachment_id in attachment_ids.split(',') if attachment_id ] attachment_tokens = [ attachment_token for attachment_token in attachment_tokens.split(',') if attachment_token ] self._portal_post_check_attachments(attachment_ids, attachment_tokens) if message or attachment_ids: # message is received in plaintext and saved in html # if message: # message = plaintext2html(message) post_values = { 'res_model': res_model, 'res_id': res_id, 'message': message, 'send_after_commit': False, 'attachment_ids': attachment_ids, } post_values.update((fname, kw.get(fname)) for fname in self._portal_post_filter_params()) message = _message_post_helper(**post_values) return http.request.redirect(url)
def view(self, order_id, pdf=None, token=None, message=False, **post): # use sudo to allow accessing/viewing orders for public user # only if he knows the private token now = fields.Date.today() if token: Order = request.env['sale.order'].sudo().search([('id', '=', order_id), ('access_token', '=', token)]) else: Order = request.env['sale.order'].search([('id', '=', order_id)]) # Log only once a day if Order and request.session.get('view_quote') != now and request.env.user.share: request.session['view_quote'] = now body = _('Quotation viewed by customer') _message_post_helper(res_model='sale.order', res_id=Order.id, message=body, token=token, token_field="access_token", message_type='notification', subtype="mail.mt_note", partner_ids=Order.user_id.sudo().partner_id.ids) if not Order: return request.render('website.404') # Token or not, sudo the order, since portal user has not access on # taxes, required to compute the total_amout of SO. order_sudo = Order.sudo() days = 0 if order_sudo.validity_date: days = (fields.Date.from_string(order_sudo.validity_date) - fields.Date.from_string(fields.Date.today())).days + 1 if pdf: pdf = request.env.ref('website_quote.report_web_quote').sudo().with_context(set_viewport_size=True).render_qweb_pdf([order_sudo.id])[0] pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(pdf))] return request.make_response(pdf, headers=pdfhttpheaders) transaction_id = request.session.get('quote_%s_transaction_id' % order_sudo.id) if not transaction_id: Transaction = request.env['payment.transaction'].sudo().search([('reference', '=', order_sudo.name)]) else: Transaction = request.env['payment.transaction'].sudo().browse(transaction_id) values = { 'quotation': order_sudo, 'message': message and int(message) or False, 'option': any(not x.line_id for x in order_sudo.options), 'order_valid': (not order_sudo.validity_date) or (now <= order_sudo.validity_date), 'days_valid': days, 'action': request.env.ref('sale.action_quotations').id, 'no_breadcrumbs': request.env.user.partner_id.commercial_partner_id not in order_sudo.message_partner_ids, 'tx_id': Transaction.id if Transaction else False, 'tx_state': Transaction.state if Transaction else False, 'tx_post_msg': Transaction.acquirer_id.post_msg if Transaction else False, 'need_payment': order_sudo.invoice_status == 'to invoice' and Transaction.state in ['draft', 'cancel', 'error'], 'token': token, } if order_sudo.require_payment or values['need_payment']: values['acquirers'] = list(request.env['payment.acquirer'].sudo().search([('website_published', '=', True), ('company_id', '=', order_sudo.company_id.id)])) extra_context = { 'submit_class': 'btn btn-primary', 'submit_txt': _('Pay & Confirm') } values['buttons'] = {} for acquirer in values['acquirers']: values['buttons'][acquirer.id] = acquirer.with_context(**extra_context).render( '/', order_sudo.amount_total, order_sudo.pricelist_id.currency_id.id, values={ 'return_url': '/quote/%s/%s' % (order_id, token) if token else '/quote/%s' % order_id, 'type': 'form', 'alias_usage': _('If we store your payment information on our server, subscription payments will be made automatically.'), 'partner_id': order_sudo.partner_id.id, }) history = request.session.get('my_quotes_history', []) values.update(get_records_pager(history, order_sudo)) return request.render('website_quote.so_quotation', values)
def portal_order_page(self, order_id, report_type=None, access_token=None, message=False, download=False, **kw): try: order_sudo = self._document_check_access('sale.order', order_id, access_token=access_token) except (AccessError, MissingError): return request.redirect('/my') if report_type in ('html', 'pdf', 'text'): return self._show_report(model=order_sudo, report_type=report_type, report_ref='sale.action_report_saleorder', download=download) # use sudo to allow accessing/viewing orders for public user # only if he knows the private token # Log only once a day if order_sudo: # store the date as a string in the session to allow serialization now = fields.Date.today().isoformat() session_obj_date = request.session.get('view_quote_%s' % order_sudo.id) if session_obj_date != now and request.env.user.share and access_token: request.session['view_quote_%s' % order_sudo.id] = now body = _('Quotation viewed by customer %s', order_sudo.partner_id.name) _message_post_helper( "sale.order", order_sudo.id, body, token=order_sudo.access_token, message_type="notification", subtype_xmlid="mail.mt_note", partner_ids=order_sudo.user_id.sudo().partner_id.ids, ) values = { 'sale_order': order_sudo, 'message': message, 'token': access_token, 'landing_route': '/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 # Payment values if order_sudo.has_to_be_paid(): logged_in = not request.env.user._is_public() acquirers_sudo = request.env['payment.acquirer'].sudo( )._get_compatible_acquirers( order_sudo.company_id.id, order_sudo.partner_id.id, currency_id=order_sudo.currency_id.id, sale_order_id=order_sudo.id, ) # In sudo mode to read the fields of acquirers and partner (if not logged in) tokens = request.env['payment.token'].search([ ('acquirer_id', 'in', acquirers_sudo.ids), ('partner_id', '=', order_sudo.partner_id.id) ]) if logged_in else request.env['payment.token'] fees_by_acquirer = { acquirer: acquirer._compute_fees( order_sudo.amount_total, order_sudo.currency_id, order_sudo.partner_id.country_id, ) for acquirer in acquirers_sudo.filtered('fees_active') } # Prevent public partner from saving payment methods but force it for logged in partners # buying subscription products show_tokenize_input = logged_in \ and not request.env['payment.acquirer'].sudo()._is_tokenization_required( sale_order_id=order_sudo.id ) values.update({ 'acquirers': acquirers_sudo, 'tokens': tokens, 'fees_by_acquirer': fees_by_acquirer, 'show_tokenize_input': show_tokenize_input, 'amount': order_sudo.amount_total, 'currency': order_sudo.pricelist_id.currency_id, 'partner_id': order_sudo.partner_id.id, 'access_token': order_sudo.access_token, 'transaction_route': order_sudo.get_portal_url(suffix='/transaction'), 'landing_route': order_sudo.get_portal_url(), }) 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)) return request.render('sale.sale_order_portal_template', values)
def portal_my_stock(self, stock_picking_id=None, page=1, access_token=None, report_type=None, message=False, download=False, **kw): # Prepare values values = {'page_name': 'stock'} Stock = request.env['stock.picking'] Stock_move = request.env['stock.move'] domain = [('partner_id', '=', request.env.user.partner_id.id)] stock_count = Stock.sudo().search_count(domain) pager = portal_pager(url="/my/stock", total=stock_count, page=page, step=self._items_per_page) stocks = Stock.sudo().search(domain, limit=self._items_per_page, offset=pager['offset']) if stock_picking_id is None: values.update({ 'pager': pager, 'default_url': '/my/stock', 'stock_picking_ids': stocks }) return request.render("website_stock.portal_my_stock", values) else: try: stock_picking_sudo = self._document_check_access( 'stock.picking', stock_picking_id, access_token=access_token) except (AccessError, MissingError): return request.redirect('/my') if report_type in ('html', 'pdf', 'text'): return self._show_report( model=stock_picking_sudo, report_type=report_type, report_ref='stock.action_report_picking', download=download) body = _('Stock picking viewed by customer') _message_post_helper( res_model='stock.picking', res_id=stock_picking_sudo.id, message=body, token=stock_picking_sudo.access_token, message_type='notification', subtype="mail.mt_note", partner_ids=[stock_picking_sudo.partner_id.id]) stock_move_ids = Stock_move.sudo().search([('picking_id', '=', stock_picking_id)]) stock_picking_id = Stock.browse(stock_picking_id) values.update({ 'stock_picking_id': stock_picking_id, 'stock_move_ids': stock_move_ids }) return request.render("website_stock.portal_my_stock_details", values)
def portal_order_page(self, order_id, report_type=None, access_token=None, message=False, download=False, **kw): try: order_sudo = self._document_check_access('sale.order', order_id, access_token=access_token) except (AccessError, MissingError): return request.redirect('/my') if report_type in ('html', 'pdf', 'text'): return self._show_report(model=order_sudo, report_type=report_type, report_ref='sale.action_report_saleorder', download=download) if request.env.user.share and access_token: # If a public/portal user accesses the order with the access token # Log a note on the chatter. today = fields.Date.today().isoformat() session_obj_date = request.session.get('view_quote_%s' % order_sudo.id) if session_obj_date != today: # store the date as a string in the session to allow serialization request.session['view_quote_%s' % order_sudo.id] = today # The "Quotation viewed by customer" log note is an information # dedicated to the salesman and shouldn't be translated in the customer/website lgg context = { 'lang': order_sudo.user_id.partner_id.lang or order_sudo.company_id.partner_id.lang } msg = _('Quotation viewed by customer %s', order_sudo.partner_id.name) del context _message_post_helper( "sale.order", order_sudo.id, message=msg, token=order_sudo.access_token, message_type="notification", subtype_xmlid="mail.mt_note", partner_ids=order_sudo.user_id.sudo().partner_id.ids, ) backend_url = f'/web#model={order_sudo._name}'\ f'&id={order_sudo.id}'\ f'&action={order_sudo._get_portal_return_action().id}'\ f'&view_type=form' values = { 'sale_order': order_sudo, 'message': message, 'report_type': 'html', 'backend_url': backend_url, 'res_company': order_sudo.company_id, # Used to display correct company logo } # Payment values if order_sudo.has_to_be_paid(): logged_in = not request.env.user._is_public() # Make sure that the partner's company matches the sales order's company. payment_portal.PaymentPortal._ensure_matching_companies( order_sudo.partner_id, order_sudo.company_id) acquirers_sudo = request.env['payment.acquirer'].sudo( )._get_compatible_acquirers( order_sudo.company_id.id, order_sudo.partner_id.id, currency_id=order_sudo.currency_id.id, sale_order_id=order_sudo.id, ) # In sudo mode to read the fields of acquirers and partner (if not logged in) tokens = request.env['payment.token'].search([ ('acquirer_id', 'in', acquirers_sudo.ids), ('partner_id', '=', order_sudo.partner_id.id) ]) if logged_in else request.env['payment.token'] fees_by_acquirer = { acquirer: acquirer._compute_fees( order_sudo.amount_total, order_sudo.currency_id, order_sudo.partner_id.country_id, ) for acquirer in acquirers_sudo.filtered('fees_active') } values.update({ 'acquirers': acquirers_sudo, 'tokens': tokens, 'fees_by_acquirer': fees_by_acquirer, 'show_tokenize_input': PaymentPortal._compute_show_tokenize_input_mapping( acquirers_sudo, logged_in=logged_in, sale_order_id=order_sudo.id), 'amount': order_sudo.amount_total, 'currency': order_sudo.pricelist_id.currency_id, 'partner_id': order_sudo.partner_id.id, 'access_token': order_sudo.access_token, 'transaction_route': order_sudo.get_portal_url(suffix='/transaction'), 'landing_route': order_sudo.get_portal_url(), }) if order_sudo.state in ('draft', 'sent', 'cancel'): history_session_key = 'my_quotations_history' else: history_session_key = 'my_orders_history' values = self._get_page_view_values(order_sudo, access_token, values, history_session_key, False) return request.render('sale.sale_order_portal_template', values)