def details(self, redirect=None, **post): partner = request.env.user.gooderp_partner_id values = { 'error': {}, 'error_message': [] } if post: error, error_message = self.details_form_validate(post) values.update({'error': error, 'error_message': error_message}) values.update(post) if not error: values = {key: post[key] for key in self.MANDATORY_BILLING_FIELDS} partner.sudo().write(values) if redirect: return request.redirect(redirect) return request.redirect('/my/home') values.update({ 'partner': partner, 'redirect': redirect, }) return request.render("good_portal.details", values)
def extra_info(self, **post): # Check that this option is activated extra_step = request.env.ref("website_sale.extra_info_option") if not extra_step.active: return request.redirect("/shop/payment") # check that cart is valid order = request.website.sale_get_order() redirection = self.checkout_redirection(order) if redirection: return redirection # if form posted if "post_values" in post: values = {} for field_name, field_value in post.items(): if field_name in request.env["sale.order"]._fields and field_name.startswith("x_"): values[field_name] = field_value if values: order.write(values) return request.redirect("/shop/payment") values = {"website_sale_order": order, "post": post, "escape": lambda x: x.replace("'", r"\'")} values.update(request.env["sale.order"]._get_website_data(order)) return request.render("website_sale.extra_info", values)
def payment_validate(self, transaction_id=None, sale_order_id=None, **post): """ Method that should be called by the server when receiving an update for a transaction. State at this point : - UDPATE ME """ if transaction_id is None: tx = request.website.sale_get_transaction() else: tx = request.env["payment.transaction"].browse(transaction_id) if sale_order_id is None: order = request.website.sale_get_order() else: order = request.env["sale.order"].sudo().browse(sale_order_id) assert order.id == request.session.get("sale_last_order_id") if not order or (order.amount_total and not tx): return request.redirect("/shop") if (not order.amount_total and not tx) or tx.state in ["pending", "done"]: if not order.amount_total and not tx: # Orders are confirmed by payment transactions, but there is none for free orders, # (e.g. free events), so confirm immediately order.with_context(send_email=True).action_confirm() elif tx and tx.state == "cancel": # cancel the quotation order.action_cancel() # clean context and session, then redirect to the confirmation page request.website.sale_reset() if tx and tx.state == "draft": return request.redirect("/shop") return request.redirect("/shop/confirmation")
def payment_token(self, pm_id=None, **kwargs): """ Method that handles payment using saved tokens :param int pm_id: id of the payment.token that we want to use to pay. """ order = request.website.sale_get_order() # do not crash if the user has already paid and try to pay again if not order: return request.redirect('/shop/?error=no_order') assert order.partner_id.id != request.website.partner_id.id try: pm_id = int(pm_id) except ValueError: return request.redirect('/shop/?error=invalid_token_id') # We retrieve the token the user want to use to pay token = request.env['payment.token'].browse(pm_id) if not token: return request.redirect('/shop/?error=token_not_found') # we retrieve an existing transaction (if it exists obviously) tx = request.website.sale_get_transaction() or request.env['payment.transaction'].sudo() # we check if the transaction is Ok, if not then we create it tx = tx._check_or_create_sale_tx(order, token.acquirer_id, payment_token=token, tx_type='server2server') # we set the transaction id into the session (so `sale_get_transaction` can retrieve it ) request.session['sale_transaction_id'] = tx.id # we proceed the s2s payment res = tx.confirm_sale_token() # we then redirect to the page that validates the payment by giving it error if there's one if res is not True: return request.redirect('/shop/payment/validate?success=False&error=%s' % res) return request.redirect('/shop/payment/validate?success=True')
def details(self, redirect=None, **post): partner = request.env.user.partner_id values = {"error": {}, "error_message": []} if post: error, error_message = self.details_form_validate(post) values.update({"error": error, "error_message": error_message}) values.update(post) if not error: values = {key: post[key] for key in self.MANDATORY_BILLING_FIELDS} values.update({key: post[key] for key in self.OPTIONAL_BILLING_FIELDS if key in post}) values.update({"zip": values.pop("zipcode", "")}) partner.sudo().write(values) if redirect: return request.redirect(redirect) return request.redirect("/my/home") countries = request.env["res.country"].sudo().search([]) states = request.env["res.country.state"].sudo().search([]) values.update( { "partner": partner, "countries": countries, "states": states, "has_check_vat": hasattr(request.env["res.partner"], "check_vat"), "redirect": redirect, } ) return request.render("website_portal.details", values)
def payment_validate(self, transaction_id=None, sale_order_id=None, **post): """ Method that should be called by the server when receiving an update for a transaction. State at this point : - UDPATE ME """ if sale_order_id is None: order = request.website.sale_get_order() else: order = request.env['sale.order'].sudo().browse(sale_order_id) assert order.id == request.session.get('sale_last_order_id') if transaction_id: tx = request.env['payment.transaction'].sudo().browse(transaction_id) assert tx in order.transaction_ids() elif order: tx = order.get_portal_last_transaction() else: tx = None if not order or (order.amount_total and not tx): return request.redirect('/shop') # clean context and session, then redirect to the confirmation page request.website.sale_reset() if tx and tx.state == 'draft': return request.redirect('/shop') return request.redirect('/shop/confirmation')
def payment_token(self, pm_id, reference, amount, currency_id, return_url=None, **kwargs): token = request.env['payment.token'].browse(int(pm_id)) if not token: return request.redirect('/website_payment/pay?error_msg=%s' % _('Cannot setup the payment.')) partner_id = request.env.user.partner_id.id if not request.env.user._is_public() else False values = { 'acquirer_id': token.acquirer_id.id, 'reference': reference, 'amount': float(amount), 'currency_id': int(currency_id), 'partner_id': partner_id, 'payment_token_id': pm_id } tx = request.env['payment.transaction'].sudo().create(values) request.session['website_payment_tx_id'] = tx.id try: res = tx.s2s_do_transaction() except Exception as e: return request.redirect('/website_payment/pay?error_msg=%s' % _('Payment transaction failed.')) valid_state = 'authorized' if tx.acquirer_id.capture_manually else 'done' if not res or tx.state != valid_state: return request.redirect('/website_payment/pay?error_msg=%s' % _('Payment transaction failed.')) return request.redirect(return_url if return_url else '/website_payment/confirm?tx_id=%d' % tx.id)
def account(self, redirect=None, **post): partner = request.env.user.partner_id values = { 'error': {}, 'error_message': [] } if post: error, error_message = self.details_form_validate(post) values.update({'error': error, 'error_message': error_message}) values.update(post) if not error: values = {key: post[key] for key in self.MANDATORY_BILLING_FIELDS} values.update({key: post[key] for key in self.OPTIONAL_BILLING_FIELDS if key in post}) values.update({'zip': values.pop('zipcode', '')}) partner.sudo().write(values) if redirect: return request.redirect(redirect) return request.redirect('/my/home') countries = request.env['res.country'].sudo().search([]) states = request.env['res.country.state'].sudo().search([]) values.update({ 'partner': partner, 'countries': countries, 'states': states, 'has_check_vat': hasattr(request.env['res.partner'], 'check_vat'), 'redirect': redirect, 'page_name': 'my_details', }) response = request.render("portal.portal_my_details", values) response.headers['X-Frame-Options'] = 'DENY' return response
def payment_token(self, order_id, pm_id=None, **kwargs): order = request.env['sale.order'].sudo().browse(order_id) if not order or not order.order_line or pm_id is None: return request.redirect("/quote/%s" % order_id) # try to convert pm_id into an integer, if it doesn't work redirect the user to the quote try: pm_id = int(pm_id) except ValueError: return request.redirect('/quote/%s' % order_id) # retrieve the token from its id token = request.env['payment.token'].sudo().browse(pm_id) if not token: return request.redirect('/quote/%s' % order_id) # find an already existing transaction tx = request.env['payment.transaction'].sudo().search([('reference', '=', order.name)], limit=1) # set the transaction type to server2server tx_type = 'server2server' # check if the transaction exists, if not then it create one tx = tx._check_or_create_sale_tx(order, token.acquirer_id, payment_token=token, tx_type=tx_type) # set the transaction id into the session request.session['quote_%s_transaction_id' % order_id] = tx.id # proceed to the payment tx.confirm_sale_token() # redirect the user to the online quote return request.redirect('/quote/%s/%s' % (order_id, order.access_token))
def invoice_pay_token(self, invoice_id, pm_id=None, **kwargs): """ Use a token to perform a s2s transaction """ error_url = kwargs.get('error_url', '/my') success_url = kwargs.get('success_url', '/my') callback_method = kwargs.get('callback_method', '') access_token = kwargs.get('access_token') params = {} if access_token: params['access_token'] = access_token invoice_sudo = request.env['account.invoice'].sudo().browse(invoice_id).exists() if not invoice_sudo: params['error'] = 'pay_invoice_invalid_doc' return request.redirect(_build_url_w_params(error_url, params)) try: pm_id = int(pm_id) except (ValueError, TypeError): params['error'] = 'pay_invoice_invalid_token' return request.redirect(_build_url_w_params(error_url, params)) vals = { 'payment_token_id': pm_id, 'type': 'server2server', 'callback_model_id': request.env['ir.model'].sudo().search([('model', '=', invoice_sudo._name)], limit=1).id, 'callback_res_id': invoice_sudo.id, 'callback_method': callback_method, } invoice_sudo._create_payment_transaction(vals) params['success'] = 'pay_invoice' return request.redirect(_build_url_w_params(success_url, params))
def payment_token(self, pm_id, reference, amount, currency_id, return_url=None, **kwargs): token = request.env['payment.token'].browse(int(pm_id)) order_id = kwargs.get('order_id') if not token: return request.redirect('/website_payment/pay?error_msg=%s' % _('Cannot setup the payment.')) partner_id = request.env.user.partner_id.id if not request.env.user._is_public() else False values = { 'acquirer_id': token.acquirer_id.id, 'reference': reference, 'amount': float(amount), 'currency_id': int(currency_id), 'partner_id': partner_id, 'payment_token_id': pm_id, 'type': 'form_save' if token.acquirer_id.save_token != 'none' and partner_id else 'form', } if order_id: values['sale_order_ids'] = [(6, 0, [order_id])] tx = request.env['payment.transaction'].sudo().with_context(lang=None).create(values) try: res = tx.s2s_do_transaction() except Exception as e: return request.redirect('/website_payment/pay?error_msg=%s' % _('Payment transaction failed.')) valid_state = 'authorized' if tx.acquirer_id.capture_manually else 'done' if not res or tx.state != valid_state: return request.redirect('/website_payment/pay?error_msg=%s' % _('Payment transaction failed.')) return request.redirect(return_url if return_url else '/website_payment/confirm?tx_id=%d' % tx.id)
def invoice_pay_token(self, invoice_id, pm_id=None, **kwargs): """ Use a token to perform a s2s transaction """ error_url = kwargs.get('error_url', '/my') success_url = kwargs.get('success_url', '/my') access_token = kwargs.get('access_token') params = {} if access_token: params['access_token'] = access_token invoice_sudo = request.env['account.invoice'].sudo().browse(invoice_id).exists() if not invoice_sudo: params['error'] = 'pay_invoice_invalid_doc' return request.redirect(_build_url_w_params(error_url, params)) try: token = request.env['payment.token'].sudo().browse(int(pm_id)) except (ValueError, TypeError): token = False token_owner = invoice_sudo.partner_id if request.env.user._is_public() else request.env.user.partner_id if not token or token.partner_id != token_owner: params['error'] = 'pay_invoice_invalid_token' return request.redirect(_build_url_w_params(error_url, params)) vals = { 'payment_token_id': token.id, 'type': 'server2server', 'return_url': success_url, } tx = invoice_sudo._create_payment_transaction(vals) PaymentProcessing.add_payment_transaction(tx) params['success'] = 'pay_invoice' return request.redirect(_build_url_w_params(success_url, params))
def payment_token(self, pm_id=None, **kwargs): """ Method that handles payment using saved tokens :param int pm_id: id of the payment.token that we want to use to pay. """ order = request.website.sale_get_order() # do not crash if the user has already paid and try to pay again if not order: return request.redirect('/shop/?error=no_order') assert order.partner_id.id != request.website.partner_id.id try: pm_id = int(pm_id) except ValueError: return request.redirect('/shop/?error=invalid_token_id') # We retrieve the token the user want to use to pay if not request.env['payment.token'].sudo().search_count([('id', '=', pm_id)]): return request.redirect('/shop/?error=token_not_found') # Create transaction vals = {'payment_token_id': pm_id} order._create_payment_transaction(vals) return request.redirect('/shop/payment/validate')
def checkout(self, **post): order = request.website.sale_get_order() redirection = self.checkout_redirection(order) if redirection: return redirection if order.partner_id.id == request.website.user_id.sudo().partner_id.id: return request.redirect('/shop/address') for f in self._get_mandatory_billing_fields(): if not order.partner_id[f]: return request.redirect('/shop/address?partner_id=%d' % order.partner_id.id) values = self.checkout_values(**post) if post.get('express'): return request.redirect('/shop/confirm_order') values.update({'website_sale_order': order}) # Avoid useless rendering if called in ajax if post.get('xhr'): return 'ok' return request.render("website_sale.checkout", values)
def extra_info(self, **post): # Check that this option is activated extra_step = request.env.ref('website_sale.extra_info_option') if not extra_step.active: return request.redirect("/shop/payment") # check that cart is valid order = request.website.sale_get_order() redirection = self.checkout_redirection(order) if redirection: return redirection # if form posted if 'post_values' in post: values = {} for field_name, field_value in post.items(): if field_name in request.env['sale.order']._fields and field_name.startswith('x_'): values[field_name] = field_value if values: order.write(values) return request.redirect("/shop/payment") values = { 'website_sale_order': order, 'post': post, 'escape': lambda x: x.replace("'", r"\'"), 'partner': order.partner_id.id, 'order': order, } return request.render("website_sale.extra_info", values)
def pricelist(self, promo, **post): pricelist = request.env["product.pricelist"].sudo().search([("code", "=", promo)], limit=1) if pricelist and not request.website.is_pricelist_available(pricelist.id): return request.redirect("/shop/cart?code_not_available=1") request.website.sale_get_order(code=promo) return request.redirect("/shop/cart")
def cart_update(self, product_id, add_qty=1, set_qty=0, **kw): """This route is called when adding a product to cart (no options).""" sale_order = request.website.sale_get_order(force_create=True) if sale_order.state != 'draft': request.session['sale_order_id'] = None sale_order = request.website.sale_get_order(force_create=True) product_custom_attribute_values = None if kw.get('product_custom_attribute_values'): product_custom_attribute_values = json.loads(kw.get('product_custom_attribute_values')) no_variant_attribute_values = None if kw.get('no_variant_attribute_values'): no_variant_attribute_values = json.loads(kw.get('no_variant_attribute_values')) sale_order._cart_update( product_id=int(product_id), add_qty=add_qty, set_qty=set_qty, product_custom_attribute_values=product_custom_attribute_values, no_variant_attribute_values=no_variant_attribute_values ) if kw.get('express'): return request.redirect("/shop/checkout?express=1") return request.redirect("/shop/cart")
def details(self, redirect=None, **post): partner = request.env['res.users'].browse(request.uid).partner_id values = { 'error': {}, 'error_message': [] } if post: error, error_message = self.details_form_validate(post) values.update({'error': error, 'error_message': error_message}) values.update(post) if not error: values = {key: post[key] for key in self.MANDATORY_BILLING_FIELDS + self.OPTIONAL_BILLING_FIELDS} values.update({'zip': values.pop('zipcode', '')}) partner.sudo().write(values) if redirect: return request.redirect(redirect) return request.redirect('/my/home') countries = request.env['res.country'].sudo().search([]) states = request.env['res.country.state'].sudo().search([]) values.update({ 'partner': partner, 'countries': countries, 'states': states, 'has_check_vat': hasattr(request.env['res.partner'], 'check_vat'), 'redirect': redirect, }) return request.render("website_portal.details", values)
def confirm_order(self, **post): order = request.website.sale_get_order() if not order: return request.redirect("/shop") redirection = self.checkout_redirection(order) if redirection: return redirection values = self.checkout_values(post) values["error"], values["error_message"] = self.checkout_form_validate(values["checkout"]) if values["error"]: return request.website.render("website_sale.checkout", values) self.checkout_form_save(values["checkout"]) if not int(post.get('shipping_id', 0)): order.partner_shipping_id = order.partner_invoice_id request.session['sale_last_order_id'] = order.id request.website.sale_get_order(update_pricelist=True) extra_step = request.env.ref('website_sale.extra_info_option') if extra_step.active: return request.redirect("/shop/extra_info") return request.redirect("/shop/payment")
def extra_info(self, **post): # Check that this option is activated extra_step = request.env.ref('website_sale.extra_info_option') if not extra_step.active: return request.redirect("/shop/payment") # check that cart is valid order = request.website.sale_get_order() redirection = self.checkout_redirection(order) if redirection: return redirection # if form posted if 'post_values' in post: values = {} for field_name, field_value in post.items(): if field_name in request.env['sale.order']._fields and field_name.startswith('x_'): values[field_name] = field_value if values: order.write(values) return request.redirect("/shop/payment") values = { 'website_sale_order': order } values.update(request.env['sale.order']._get_website_data(order)) return request.website.render("website_sale.extra_info", values)
def pricelist(self, promo, **post): redirect = post.get('r', '/shop/cart') pricelist = request.env['product.pricelist'].sudo().search([('code', '=', promo)], limit=1) if not pricelist or (pricelist and not request.website.is_pricelist_available(pricelist.id)): return request.redirect("%s?code_not_available=1" % redirect) request.website.sale_get_order(code=promo) return request.redirect(redirect)
def checkout_redirection(self, order): # must have a draft sale order with lines at this point, otherwise reset if not order or order.state != "draft": request.session["sale_order_id"] = None request.session["sale_transaction_id"] = None return request.redirect("/shop") # if transaction pending / done: redirect to confirmation tx = request.env.context.get("website_sale_transaction") if tx and tx.state != "draft": return request.redirect("/shop/payment/confirmation/%s" % order.id)
def validate_email(self, token, id, email, forum_id=None, **kwargs): if forum_id: try: forum_id = int(forum_id) except ValueError: forum_id = None done = request.env['res.users'].sudo().browse(int(id)).process_forum_validation_token(token, email, forum_id=forum_id)[0] if done: request.session['validation_email_done'] = True if forum_id: return request.redirect("/forum/%s" % int(forum_id)) return request.redirect('/forum')
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 checkout_redirection(self, order): ''' 重定向 ''' # must have a draft sale order with lines at this point, otherwise reset if not order or order.state != 'draft': request.session['sale_order_id'] = None request.session['sale_transaction_id'] = None return request.redirect('/shop') # ??????????? # if transaction pending / done: redirect to confirmation tx = request.env.context.get('website_sale_transaction') if tx and tx.state != 'draft': return request.redirect('/shop/payment/confirmation/%s' % order.id)
def confirm_order(self, **post): order = request.website.sale_get_order() redirection = self.checkout_redirection(order) if redirection: return redirection request.session["sale_last_order_id"] = order.id request.website.sale_get_order(update_pricelist=True) extra_step = request.env.ref("website_sale.extra_info_option") if extra_step.active: return request.redirect("/shop/extra_info") return request.redirect("/shop/payment")
def add(self, order_id, option_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') option_sudo = request.env['sale.order.option'].sudo().browse(option_id) if order_sudo != option_sudo.order_id: return request.redirect(order_sudo.get_portal_url()) option_sudo.add_option_to_order() return request.redirect(option_sudo.order_id.get_portal_url(anchor='details'))
def add_product(self, name=None, category=0, **post): product = request.env['product.product'].create({ 'name': name or _("New Product"), 'public_categ_ids': category }) return request.redirect("/shop/product/%s?enable_editor=1" % slug(product.product_tmpl_id))
def actions_server(self, path_or_xml_id_or_id, **post): ServerActions = request.env['ir.actions.server'] action = action_id = None # find the action_id: either an xml_id, the path, or an ID if isinstance(path_or_xml_id_or_id, basestring) and '.' in path_or_xml_id_or_id: action = request.env.ref(path_or_xml_id_or_id, raise_if_not_found=False) if not action: action = ServerActions.search([('website_path', '=', path_or_xml_id_or_id), ('website_published', '=', True)], limit=1) if not action: try: action_id = int(path_or_xml_id_or_id) except ValueError: pass # check it effectively exists if action_id: action = ServerActions.browse(action_id).exists() # run it, return only if we got a Response object if action: if action.state == 'code' and action.website_published: action_res = action.run() if isinstance(action_res, werkzeug.wrappers.Response): return action_res return request.redirect('/')
def payment_transaction(self, acquirer_id, tx_type='form', token=None, **kwargs): """ Json method that creates a payment.transaction, used to create a transaction when the user clicks on 'pay now' button. After having created the transaction, the event continues and the user is redirected to the acquirer website. :param int acquirer_id: id of a payment.acquirer record. If not set the user is redirected to the checkout page """ # In case the route is called directly from the JS (as done in Stripe payment method) so_id = kwargs.get('so_id') access_token = kwargs.get('access_token') if so_id and access_token: order = request.env['sale.order'].sudo().search([('id', '=', so_id), ('access_token', '=', access_token)]) elif so_id: order = request.env['sale.order'].search([('id', '=', so_id)]) else: order = request.website.sale_get_order() if not order or not order.order_line or acquirer_id is None: return request.redirect("/shop/checkout") assert order.partner_id.id != request.website.partner_id.id # find or create transaction tx = request.website.sale_get_transaction() or request.env['payment.transaction'].sudo() acquirer = request.env['payment.acquirer'].browse(int(acquirer_id)) payment_token = request.env['payment.token'].sudo().browse(int(token)) if token else None tx = tx.check_or_create_sale_tx(order, acquirer, payment_token=payment_token, tx_type=tx_type) request.session['sale_transaction_id'] = tx.id if token: return request.env.ref('website_sale.payment_token_form').render(dict(tx=tx), engine='ir.qweb') return tx.render_sale_button(order, '/shop/payment/validate')
def _dispatch(cls): """ Before executing the endpoint method, add website params on request, such as - current website (record) - multilang support (set on cookies) - geoip dict data are added in the session Then follow the parent dispatching. Reminder : Do not use `request.env` before authentication phase, otherwise the env set on request will be created with uid=None (and it is a lazy property) """ request.routing_iteration = getattr(request, 'routing_iteration', 0) + 1 func = None routing_error = None # handle // in url if request.httprequest.method == 'GET' and '//' in request.httprequest.path: new_url = request.httprequest.path.replace('//', '/') + '?' + request.httprequest.query_string.decode('utf-8') return werkzeug.utils.redirect(new_url, 301) # locate the controller method try: rule, arguments = cls._match(request.httprequest.path) func = rule.endpoint request.is_frontend = func.routing.get('website', False) except werkzeug.exceptions.NotFound as e: # either we have a language prefixed route, either a real 404 # in all cases, website processes them exept if second element is static # Checking static will avoid to generate an expensive 404 web page since # most of the time the browser is loading and inexisting assets or image. A standard 404 is enough. # Earlier check would be difficult since we don't want to break data modules path_components = request.httprequest.path.split('/') request.is_frontend = len(path_components) < 3 or path_components[2] != 'static' or '.' not in path_components[-1] routing_error = e request.is_frontend_multilang = not func or (func and request.is_frontend and func.routing.get('multilang', func.routing['type'] == 'http')) # check authentication level try: if func: cls._authenticate(func) elif request.uid is None and request.is_frontend: cls._auth_method_public() except Exception as e: return cls._handle_exception(e) cls._geoip_setup_resolver() cls._geoip_resolve() # For website routes (only), add website params on `request` if request.is_frontend: request.redirect = lambda url, code=302: werkzeug.utils.redirect(url_for(url), code) cls._add_dispatch_parameters(func) path = request.httprequest.path.split('/') default_lg_id = cls._get_default_lang() if request.routing_iteration == 1: is_a_bot = cls.is_a_bot() nearest_lang = not func and cls.get_nearest_lang(request.env['res.lang']._lang_get_code(path[1])) url_lg = nearest_lang and path[1] # The default lang should never be in the URL, and a wrong lang # should never be in the URL. wrong_url_lg = url_lg and (url_lg != request.lang.url_code or url_lg == default_lg_id.url_code) # The lang is missing from the URL if multi lang is enabled for # the route and the current lang is not the default lang. # POST requests are excluded from this condition. missing_url_lg = not url_lg and request.is_frontend_multilang and request.lang != default_lg_id and request.httprequest.method != 'POST' # Bots should never be redirected when the lang is missing # because it is the only way for them to index the default lang. if wrong_url_lg or (missing_url_lg and not is_a_bot): if url_lg: path.pop(1) if request.lang != default_lg_id: path.insert(1, request.lang.url_code) path = '/'.join(path) or '/' routing_error = None redirect = request.redirect(path + '?' + request.httprequest.query_string.decode('utf-8')) redirect.set_cookie('frontend_lang', request.lang.code) return redirect elif url_lg: request.uid = None path.pop(1) routing_error = None return cls.reroute('/'.join(path) or '/') elif missing_url_lg and is_a_bot: # Ensure that if the URL without lang is not redirected, the # current lang is indeed the default lang, because it is the # lang that bots should index in that case. request.lang = default_lg_id request.context = dict(request.context, lang=default_lg_id.code) if request.lang == default_lg_id: context = dict(request.context) context['edit_translations'] = False request.context = context if routing_error: return cls._handle_exception(routing_error) # removed cache for auth public result = super(IrHttp, cls)._dispatch() cook_lang = request.httprequest.cookies.get('frontend_lang') if request.is_frontend and cook_lang != request.lang.code and hasattr(result, 'set_cookie'): result.set_cookie('frontend_lang', request.lang.code) return result
def payment_transaction(self, acquirer_id, tx_type='form', token=None, **kwargs): """ Json method that creates a payment.transaction, used to create a transaction when the user clicks on 'pay now' button. After having created the transaction, the event continues and the user is redirected to the acquirer website. :param int acquirer_id: id of a payment.acquirer record. If not set the user is redirected to the checkout page """ Transaction = request.env['payment.transaction'].sudo() # In case the route is called directly from the JS (as done in Stripe payment method) so_id = kwargs.get('so_id') so_token = kwargs.get('so_token') if so_id and so_token: order = request.env['sale.order'].sudo().search([('id', '=', so_id), ('access_token', '=', so_token)]) elif so_id: order = request.env['sale.order'].search([('id', '=', so_id)]) else: order = request.website.sale_get_order() if not order or not order.order_line or acquirer_id is None: return request.redirect("/shop/checkout") assert order.partner_id.id != request.website.partner_id.id # find an already existing transaction tx = request.website.sale_get_transaction() if tx: if tx.sale_order_id.id != order.id or tx.state in ['error', 'cancel'] or tx.acquirer_id.id != acquirer_id: tx = False elif token and tx.payment_token_id and token != tx.payment_token_id.id: # new or distinct token tx = False elif tx.state == 'draft': # button cliked but no more info -> rewrite on tx or create a new one ? tx.write(dict(Transaction.on_change_partner_id(order.partner_id.id).get('value', {}), amount=order.amount_total, type=tx_type)) if not tx: tx_values = { 'acquirer_id': acquirer_id, 'type': tx_type, 'amount': order.amount_total, 'currency_id': order.pricelist_id.currency_id.id, 'partner_id': order.partner_id.id, 'partner_country_id': order.partner_id.country_id.id, 'reference': Transaction.get_next_reference(order.name), 'sale_order_id': order.id, } if token and request.env['payment.token'].sudo().browse(int(token)).partner_id == order.partner_id: tx_values['payment_token_id'] = token tx = Transaction.create(tx_values) request.session['sale_transaction_id'] = tx.id # update quotation order.write({ 'payment_acquirer_id': acquirer_id, 'payment_tx_id': request.session['sale_transaction_id'] }) if token: return request.env.ref('website_sale.payment_token_form').render(dict(tx=tx), engine='ir.qweb') return tx.acquirer_id.with_context(submit_class='btn btn-primary', submit_txt=_('Pay Now')).sudo().render( tx.reference, order.amount_total, order.pricelist_id.currency_id.id, values={ 'return_url': '/shop/payment/validate', 'partner_id': order.partner_shipping_id.id or order.partner_invoice_id.id, 'billing_partner_id': order.partner_invoice_id.id, }, )
def _dispatch(cls): """ Before executing the endpoint method, add website params on request, such as - current website (record) - multilang support (set on cookies) - geoip dict data are added in the session Then follow the parent dispatching. Reminder : Do not use `request.env` before authentication phase, otherwise the env set on request will be created with uid=None (and it is a lazy property) """ first_pass = not hasattr(request, 'website') request.website = None func = None try: if request.httprequest.method == 'GET' and '//' in request.httprequest.path: new_url = request.httprequest.path.replace('//', '/') + '?' + request.httprequest.query_string return werkzeug.utils.redirect(new_url, 301) func, arguments = cls._find_handler() request.website_enabled = func.routing.get('website', False) except werkzeug.exceptions.NotFound: # either we have a language prefixed route, either a real 404 # in all cases, website processes them request.website_enabled = True request.website_multilang = ( request.website_enabled and func and func.routing.get('multilang', func.routing['type'] == 'http') ) cls._geoip_setup_resolver() cls._geoip_resolve() # For website routes (only), add website params on `request` cook_lang = request.httprequest.cookies.get('website_lang') if request.website_enabled: try: if func: cls._authenticate(func.routing['auth']) elif request.uid is None: cls._auth_method_public() except Exception as e: return cls._handle_exception(e) request.redirect = lambda url, code=302: werkzeug.utils.redirect(url_for(url), code) request.website = request.env['website'].get_current_website() # can use `request.env` since auth methods are called context = dict(request.context) context['website_id'] = request.website.id langs = [lg[0] for lg in request.website.get_languages()] path = request.httprequest.path.split('/') if first_pass: is_a_bot = cls.is_a_bot() nearest_lang = not func and cls.get_nearest_lang(path[1]) url_lang = nearest_lang and path[1] preferred_lang = ((cook_lang if cook_lang in langs else False) or (not is_a_bot and cls.get_nearest_lang(request.lang)) or request.website.default_lang_code) request.lang = context['lang'] = nearest_lang or preferred_lang # if lang in url but not the displayed or default language --> change or remove # or no lang in url, and lang to dispay not the default language --> add lang # and not a POST request # and not a bot or bot but default lang in url if ((url_lang and (url_lang != request.lang or url_lang == request.website.default_lang_code)) or (not url_lang and request.website_multilang and request.lang != request.website.default_lang_code) and request.httprequest.method != 'POST') \ and (not is_a_bot or (url_lang and url_lang == request.website.default_lang_code)): if url_lang: path.pop(1) if request.lang != request.website.default_lang_code: path.insert(1, request.lang) path = '/'.join(path) or '/' redirect = request.redirect(path + '?' + request.httprequest.query_string) redirect.set_cookie('website_lang', request.lang) request.context = context return redirect elif url_lang: request.uid = None path.pop(1) request.context = context return cls.reroute('/'.join(path) or '/') if path[1] == request.website.default_lang_code: context['edit_translations'] = False if not context.get('tz'): context['tz'] = request.session.get('geoip', {}).get('time_zone') # bind modified context request.context = context request.website = request.website.with_context(context) # removed cache for auth public request.cache_save = False resp = super(Http, cls)._dispatch() if request.website_enabled and cook_lang != request.lang and hasattr(resp, 'set_cookie'): resp.set_cookie('website_lang', request.lang) return resp
def checkout(self, contact_name=None, email_from=None, phone=None): post = { 'contact_name': contact_name or email_from, 'email_from': email_from, 'phone': phone, } error = set(field for field in ['email_from'] if not post.get(field)) values = dict(post, error=error) if error: return request.website.render("website_sale.checkout", values) # find or create partner partner_obj = request.registry['res.partner'] partner_id = partner_obj.search(request.cr, SUPERUSER_ID, [('email', '=', values['email_from'])]) if partner_id: partner_id = partner_id[0] partner = partner_obj.browse(request.cr, SUPERUSER_ID, partner_id) values = {} for pk, k in [('name', 'contact_name'), ('phone', 'phone')]: if post[k]: values[pk] = post[k] if values: partner.write(values) else: partner_id = partner_obj.create( request.cr, SUPERUSER_ID, { 'name': values['contact_name'], 'email': values['email_from'], 'phone': values['phone'], }) order = request.website.sale_get_order() # order_obj = request.registry.get('sale.order') order.write({'partner_id': partner_id}) # send email cr = request.cr uid = request.uid context = request.context ir_model_data = request.registry['ir.model.data'] template_id = ir_model_data.get_object_reference( 'website_sale_order', 'email_template_checkout')[1] email_ctx = dict(context) email_ctx.update({ 'default_model': 'sale.order', 'default_res_id': order.id, 'default_use_template': bool(template_id), 'default_template_id': template_id, 'default_composition_mode': 'comment', 'mark_so_as_sent': True }) composer_values = {} public_id = request.website.user_id.id if uid == public_id: composer_values[ 'email_from'] = request.website.user_id.company_id.email composer_id = request.registry['mail.compose.message'].create( composer_values) request.registry['mail.compose.message'].send_mail([composer_id]) request.website.sale_reset(context=context) return request.redirect('/shop/ready')
def mailing(self, mailing_id, email=None, res_id=None, token="", **post): mailing = request.env['mailing.mailing'].sudo().browse(mailing_id) if mailing.exists(): res_id = res_id and int(res_id) if not self._valid_unsubscribe_token(mailing_id, res_id, email, str(token)): raise exceptions.AccessDenied() if mailing.mailing_model_real == 'mailing.contact': # Unsubscribe directly + Let the user choose his subscriptions mailing.update_opt_out(email, mailing.contact_list_ids.ids, True) contacts = request.env['mailing.contact'].sudo().search([ ('email_normalized', '=', tools.email_normalize(email)) ]) subscription_list_ids = contacts.mapped( 'subscription_list_ids') # In many user are found : if user is opt_out on the list with contact_id 1 but not with contact_id 2, # assume that the user is not opt_out on both # TODO DBE Fixme : Optimise the following to get real opt_out and opt_in opt_out_list_ids = subscription_list_ids.filtered( lambda rel: rel.opt_out).mapped('list_id') opt_in_list_ids = subscription_list_ids.filtered( lambda rel: not rel.opt_out).mapped('list_id') opt_out_list_ids = set([ list.id for list in opt_out_list_ids if list not in opt_in_list_ids ]) unique_list_ids = set( [list.list_id.id for list in subscription_list_ids]) list_ids = request.env['mailing.list'].sudo().browse( unique_list_ids) unsubscribed_list = ', '.join( str(list.name) for list in mailing.contact_list_ids if list.is_public) return request.render( 'mass_mailing.page_unsubscribe', { 'contacts': contacts, 'list_ids': list_ids, 'opt_out_list_ids': opt_out_list_ids, 'unsubscribed_list': unsubscribed_list, 'email': email, 'mailing_id': mailing_id, 'res_id': res_id, 'show_blacklist_button': request.env['ir.config_parameter'].sudo().get_param( 'mass_mailing.show_blacklist_buttons'), }) else: opt_in_lists = request.env[ 'mailing.contact.subscription'].sudo().search([ ('contact_id.email_normalized', '=', email), ('opt_out', '=', False) ]).mapped('list_id') blacklist_rec = request.env['mail.blacklist'].sudo()._add( email) self._log_blacklist_action( blacklist_rec, mailing_id, _("""Requested blacklisting via unsubscribe link.""")) return request.render( 'mass_mailing.page_unsubscribed', { 'email': email, 'mailing_id': mailing_id, 'res_id': res_id, 'list_ids': opt_in_lists, 'show_blacklist_button': request.env['ir.config_parameter'].sudo().get_param( 'mass_mailing.show_blacklist_buttons'), }) return request.redirect('/web')
def _dispatch(cls): """ Before executing the endpoint method, add website params on request, such as - current website (record) - multilang support (set on cookies) - geoip dict data are added in the session Then follow the parent dispatching. Reminder : Do not use `request.env` before authentication phase, otherwise the env set on request will be created with uid=None (and it is a lazy property) """ request.routing_iteration = getattr(request, 'routing_iteration', 0) + 1 func = None routing_error = None # locate the controller method try: if request.httprequest.method == 'GET' and '//' in request.httprequest.path: new_url = request.httprequest.path.replace('//', '/') + '?' + request.httprequest.query_string.decode('utf-8') return werkzeug.utils.redirect(new_url, 301) rule, arguments = cls._find_handler(return_rule=True) func = rule.endpoint request.is_frontend = func.routing.get('website', False) except werkzeug.exceptions.NotFound as e: # either we have a language prefixed route, either a real 404 # in all cases, website processes them request.is_frontend = True routing_error = e request.is_frontend_multilang = ( request.is_frontend and (not func or (func and func.routing.get('multilang', func.routing['type'] == 'http'))) ) cls._geoip_setup_resolver() cls._geoip_resolve() # check authentication level try: if func: cls._authenticate(func.routing['auth']) elif request.uid is None and request.is_frontend: cls._auth_method_public() except Exception as e: return cls._handle_exception(e) # For website routes (only), add website params on `request` cook_lang = request.httprequest.cookies.get('frontend_lang') if request.is_frontend: request.redirect = lambda url, code=302: werkzeug.utils.redirect(url_for(url), code) cls._add_dispatch_parameters(func) path = request.httprequest.path.split('/') if request.routing_iteration == 1: is_a_bot = cls.is_a_bot() nearest_lang = not func and cls.get_nearest_lang(path[1]) url_lang = nearest_lang and path[1] # if lang in url but not the displayed or default language --> change or remove # or no lang in url, and lang to dispay not the default language --> add lang # and not a POST request # and not a bot or bot but default lang in url if ((url_lang and (url_lang != request.lang or url_lang == cls._get_default_lang().code)) or (not url_lang and request.is_frontend_multilang and request.lang != cls._get_default_lang().code) and request.httprequest.method != 'POST') \ and (not is_a_bot or (url_lang and url_lang == cls._get_default_lang().code)): if url_lang: path.pop(1) if request.lang != cls._get_default_lang().code: path.insert(1, request.lang) path = '/'.join(path) or '/' routing_error = None redirect = request.redirect(path + '?' + request.httprequest.query_string.decode('utf-8')) redirect.set_cookie('frontend_lang', request.lang) return redirect elif url_lang: request.uid = None path.pop(1) routing_error = None return cls.reroute('/'.join(path) or '/') if request.lang == cls._get_default_lang().code: context = dict(request.context) context['edit_translations'] = False request.context = context if routing_error: return cls._handle_exception(routing_error) # removed cache for auth public result = super(IrHttp, cls)._dispatch() if request.is_frontend and cook_lang != request.lang and hasattr(result, 'set_cookie'): result.set_cookie('frontend_lang', request.lang) return result
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, '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)) return request.render('sale.sale_order_portal_template', values)
def registration_confirm(self, event, **post): registrations = self._process_attendees_form(event, post) attendees_sudo = self._create_attendees_from_registration_post(event, registrations) return request.redirect(('/event/%s/registration/success?' % event.id) + werkzeug.urls.url_encode({'registration_ids': ",".join([str(id) for id in attendees_sudo.ids])}))
def delete(self, delete_pm_id=None): if delete_pm_id: pay_meth = request.env['payment.token'].browse(int(delete_pm_id)) pay_meth.unlink() return request.redirect('/my/payment_method')
def blog_post(self, blog, blog_post, tag_id=None, page=1, enable_editor=None, **post): """ Prepare all values to display the blog. :return dict values: values for the templates, containing - 'blog_post': browse of the current post - 'blog': browse of the current blog - 'blogs': list of browse records of blogs - 'tag': current tag, if tag_id in parameters - 'tags': all tags, for tag-based navigation - 'pager': a pager on the comments - 'nav_list': a dict [year][month] for archives navigation - 'next_post': next blog post, to direct the user towards the next interesting post """ BlogPost = request.env['blog.post'] date_begin, date_end = post.get('date_begin'), post.get('date_end') pager_url = "/blogpost/%s" % blog_post.id pager = request.website.pager( url=pager_url, total=len(blog_post.website_message_ids), page=page, step=self._post_comment_per_page, scope=7 ) pager_begin = (page - 1) * self._post_comment_per_page pager_end = page * self._post_comment_per_page comments = blog_post.website_message_ids[pager_begin:pager_end] tag = None if tag_id: tag = request.env['blog.tag'].browse(int(tag_id)) blog_url = QueryURL('', ['blog', 'tag'], blog=blog_post.blog_id, tag=tag, date_begin=date_begin, date_end=date_end) if not blog_post.blog_id.id == blog.id: return request.redirect("/blog/%s/post/%s" % (slug(blog_post.blog_id), slug(blog_post))) tags = request.env['blog.tag'].search([]) # Find next Post all_post = BlogPost.search([('blog_id', '=', blog.id)]) if not request.env.user.has_group('base.group_website_designer'): all_post = all_post.filtered(lambda r: r.post_date <= fields.Datetime.now()) if blog_post not in all_post: return request.redirect("/blog/%s" % (slug(blog_post.blog_id))) # should always return at least the current post all_post_ids = all_post.ids current_blog_post_index = all_post_ids.index(blog_post.id) nb_posts = len(all_post_ids) next_post_id = all_post_ids[(current_blog_post_index + 1) % nb_posts] if nb_posts > 1 else None next_post = next_post_id and BlogPost.browse(next_post_id) or False values = { 'tags': tags, 'tag': tag, 'blog': blog, 'blog_post': blog_post, 'blog_post_cover_properties': json.loads(blog_post.cover_properties), 'main_object': blog_post, 'nav_list': self.nav_list(blog), 'enable_editor': enable_editor, 'next_post': next_post, 'next_post_cover_properties': json.loads(next_post.cover_properties) if next_post else {}, 'date': date_begin, 'blog_url': blog_url, 'pager': pager, 'comments': comments, } response = request.render("website_blog.blog_post_complete", values) request.session[request.session.sid] = request.session.get(request.session.sid, []) if not (blog_post.id in request.session[request.session.sid]): request.session[request.session.sid].append(blog_post.id) # Increase counter blog_post.sudo().write({ 'visits': blog_post.visits+1, }) return response
def chatter_post(self, res_model='', res_id=None, message='', redirect=None, **kw): url = request.httprequest.referrer if message: message = _message_post_helper(res_model, int(res_id), message, **kw) url = url + "#message-%s" % (message.id,) return request.redirect(url)
def address(self, **kw): Partner = request.env['res.partner'].with_context( show_address=1).sudo() order = request.website.sale_get_order() redirection = self.checkout_redirection(order) if redirection: return redirection mode = (False, False) def_country_id = order.partner_id.country_id values, errors = {}, {} partner_id = int(kw.get('partner_id', -1)) # IF PUBLIC ORDER if order.partner_id.id == request.website.user_id.sudo().partner_id.id: mode = ('new', 'billing') country_code = request.session['geoip'].get('country_code') if country_code: def_country_id = request.env['res.country'].search( [('code', '=', country_code)], limit=1) else: def_country_id = request.website.user_id.sudo().country_id # IF ORDER LINKED TO A PARTNER else: if partner_id > 0: if partner_id == order.partner_id.id: mode = ('edit', 'billing') else: shippings = Partner.search([ ('id', 'child_of', order.partner_id.commercial_partner_id.ids) ]) if partner_id in shippings.mapped('id'): mode = ('edit', 'shipping') else: return Forbidden() if mode: values = Partner.browse(partner_id) elif partner_id == -1: mode = ('new', 'shipping') else: # no mode - refresh without post? return request.redirect('/shop/checkout') # IF POSTED if 'submitted' in kw: pre_values = self.values_preprocess(order, mode, kw) errors, error_msg = self.checkout_form_validate( mode, kw, pre_values) post, errors, error_msg = self.values_postprocess( order, mode, pre_values, errors, error_msg) if errors: errors['error_message'] = error_msg values = kw else: partner_id = self._checkout_form_save(mode, post, kw) if mode[1] == 'billing': order.partner_id = partner_id order.onchange_partner_id() elif mode[1] == 'shipping': order.partner_shipping_id = partner_id order.message_partner_ids = [(4, partner_id), (3, request.website.partner_id.id) ] if not errors: return request.redirect( kw.get('callback') or '/shop/checkout') country = 'country_id' in values and values[ 'country_id'] != '' and request.env['res.country'].browse( int(values['country_id'])) country = country and country.exists() or def_country_id render_values = { 'website_sale_order': order, 'partner_id': partner_id, 'mode': mode, 'checkout': values, 'country': country, 'countries': country.get_website_sale_countries(mode=mode[1]), "states": country.get_website_sale_states(mode=mode[1]), 'error': errors, 'callback': kw.get('callback'), } return request.render("website_sale.address", render_values)
def remove_meaning(self, meaning_id=0): meaning_id.unlink() return request.redirect(request.httprequest.referrer)
def portal_my_transactions(self, page=1, date_begin=None, date_end=None, sortby=None, **kw): url_params = dict(kw) read = False create = False write = False maids = url_params.get('maids') if maids: accesses = request.env['ir.model.access'].sudo().search([ ('id', 'in', maids.split(',')) ]) for access in accesses: read = access.perm_read or read create = access.perm_create or create write = access.perm_write or write else: return request.redirect('/my/home') if not read: return request.redirect('/my/home') values = self._prepare_portal_layout_values() business_users = request.env['res.users'].sudo() domain = [('belonging_company_id', '=', request.env.user.belonging_company_id.id), '|', ('active', '=', False), ('active', '=', True)] searchbar_sortings = { 'date': { 'label': _('Date'), 'order': 'create_date desc' }, } # default sort by order if not sortby: sortby = 'date' order = searchbar_sortings[sortby]['order'] # archive_groups = self._get_archive_groups('payment.transaction') if date_begin and date_end: domain += [('create_date', '>', date_begin), ('create_date', '<=', date_end)] # count for pager business_users_count = business_users.search_count(domain) # pager pager = portal_pager(url="/my/business/users", url_args={ 'date_begin': date_begin, 'date_end': date_end, 'sortby': sortby }, total=business_users_count, page=page, step=self._items_per_page) # content according to pager and archive selected users = business_users.search(domain, order=order, limit=self._items_per_page, offset=pager['offset']) # request.session['my_transactions_history'] = transactions.ids[:100] values.update({ 'date': date_begin, 'users': users, 'page_name': 'business_users', 'pager': pager, 'default_url': '/my/business/users', 'searchbar_sortings': searchbar_sortings, 'sortby': sortby, 'access_rights': { 'read': read, 'create': create, 'write': write }, 'maids': maids }) return request.render("manage_users_website.portal_my_business_users", values)
def payumoney_return(self, **data): _logger.info("entering handle_feedback_data with data:\n%s", pprint.pformat(data)) request.env['payment.transaction'].sudo()._handle_feedback_data( 'payumoney', data) return request.redirect('/payment/status')
def account(self, redirect=None, **post): values = self._prepare_portal_layout_values() partner = request.env.user.partner_id values.update({ 'error': {}, 'error_message': [], }) if post: reset_password_fields = ['old_pwd', 'new_password', 'confirm_pwd'] reset_password_fields_vals = {} for index in reset_password_fields: if index in post: reset_password_fields_vals.update( {index: post.get(index, 0)}) post.pop(index) error, error_message = self.details_form_validate(post) if reset_password_fields_vals: old_password = reset_password_fields_vals.get('old_pwd', None) new_password = reset_password_fields_vals.get( 'new_password', None) confirm_password = reset_password_fields_vals.get( 'confirm_pwd', None) if old_password or new_password or confirm_password: # Validation for field_name in reset_password_fields: if not reset_password_fields_vals.get(field_name): error[field_name] = 'missing' # error message for empty required fields if [err for err in list(error.values()) if err == 'missing']: if 'Some required fields are empty.' not in error_message: error_message.append('Some required fields are empty.') # error message for compare a old_password and new_password if new_password != confirm_password: error['new_password'] = '******' error['confirm_pwd'] = 'error' error_message.append( 'The new password and its confirmation must be identical.' ) elif not error: try: if request.env['res.users'].change_password( old_password, new_password.strip()): print("password change") except Exception: #error message for old_password wrong error['old_pwd'] = 'error' error_message.append( 'The old password you provided is incorrect, your password was not changed.' ) values.update({'error': error, 'error_message': error_message}) values.update(post) if not error: values = { key: post[key] for key in self.MANDATORY_BILLING_FIELDS } values.update({ key: post[key] for key in self.OPTIONAL_BILLING_FIELDS if key in post }) values.update({'zip': values.pop('zipcode', '')}) partner.sudo().write(values) if redirect: return request.redirect(redirect) return request.redirect('/my/home') countries = request.env['res.country'].sudo().search([]) states = request.env['res.country.state'].sudo().search([]) values.update({ 'partner': partner, 'countries': countries, 'states': states, 'has_check_vat': hasattr(request.env['res.partner'], 'check_vat'), 'redirect': redirect, 'page_name': 'my_details', }) response = request.render("portal.portal_my_details", values) response.headers['X-Frame-Options'] = 'DENY' return response
def web_totp(self, redirect=None, **kwargs): if request.session.uid: return request.redirect( self._login_redirect(request.session.uid, redirect=redirect)) if not request.session.pre_uid: return request.redirect('/web/login') error = None user = request.env['res.users'].browse(request.session.pre_uid) if user and request.httprequest.method == 'GET': cookies = request.httprequest.cookies key = cookies.get(TRUSTED_DEVICE_COOKIE) if key: checked_credentials = request.env[ 'auth_totp.device']._check_credentials(scope="browser", key=key) if checked_credentials == user.id: request.session.finalize() return request.redirect( self._login_redirect(request.session.uid, redirect=redirect)) elif user and request.httprequest.method == 'POST' and kwargs.get( 'totp_token'): try: with user._assert_can_auth(): user._totp_check( int(re.sub(r'\s', '', kwargs['totp_token']))) except AccessDenied as e: error = str(e) except ValueError: error = _("Invalid authentication code format.") else: request.session.finalize() response = request.redirect( self._login_redirect(request.session.uid, redirect=redirect)) if kwargs.get('remember'): name = _( "%(browser)s on %(platform)s", browser=request.httprequest.user_agent.browser. capitalize(), platform=request.httprequest.user_agent.platform. capitalize(), ) geoip = request.session.geoip if geoip: name += " (%s, %s)" % (geoip['city'], geoip['country_name']) key = request.env['auth_totp.device']._generate( "browser", name) response.set_cookie(key=TRUSTED_DEVICE_COOKIE, value=key, max_age=TRUSTED_DEVICE_AGE, httponly=True, samesite='Lax') return response return request.render('auth_totp.auth_totp_form', { 'user': user, 'error': error, 'redirect': redirect, })
def portal_chatter_post(self, res_model, res_id, message, **kw): url = request.httprequest.referrer if message: _message_post_helper(res_model, int(res_id), message, **kw) url = url + "#discussion" return request.redirect(url)
def input_document(self, **post): if "boleta" not in post: return request.render("l10n_cl_fe.boleta_layout") return request.redirect("/boleta/{}?{}".format( post["boleta"], urllib.parse.urlencode(post)))
def theme_customize_reload(self, href, enable, disable): self.theme_customize(enable and enable.split(",") or [], disable and disable.split(",") or []) return request.redirect( href + ("&theme=true" if "#" in href else "#theme=true"))
def confirm_order(self, **post): order = request.website.sale_get_order() user_id = request.env.user redirection = self.checkout_redirection(order) if redirection: return redirection transaction_id = None if transaction_id: tx = request.env['payment.transaction'].sudo().browse( transaction_id) assert tx in order.transaction_ids() elif order: tx = order.get_portal_last_transaction() else: tx = None email = post.get('email') name = post.get('name') phone = post.get('phone') pickup_type = post.get('pickup_type') city = post.get('city') street = post.get('street') zip1 = post.get('zip') state_id = post.get('state_id') country_id = post.get('country_id') if pickup_type in ['pickup_paystore', 'pickup_paynow']: if email and name and phone: partner = request.env['res.partner'].search( [('email', '=', post.get('email'))], limit=1) if request.website.is_public_user(): if not partner: partner = request.env['res.partner'].sudo().create({ 'name': post.get('name'), 'email': post.get('email'), 'phone': post.get('phone'), }) order.write({ 'partner_id': partner.id, 'partner_invoice_id': partner.id, 'partner_shipping_id': partner.id, }) if not partner: partner = request.env['res.partner'].sudo().create({ 'name': post.get('name'), 'email': post.get('email'), 'phone': post.get('phone'), 'type': 'other', 'parent_id': user_id.partner_id.id }) order.write({ 'checkout_option': post.get('pickup_type'), 'pickup_id': partner.id, }) order.onchange_partner_shipping_id() order.order_line._compute_tax_id() request.session['sale_last_order_id'] = order.id request.website.sale_get_order(update_pricelist=True) if pickup_type == 'pickup_paystore': order.with_context(send_email=True).action_confirm() request.website.sale_reset() PaymentProcessing.remove_payment_transaction(tx) return request.render("website_sale.confirmation", {'order': order}) if pickup_type == 'pickup_paynow': extra_step = request.website.viewref( 'website_sale.extra_info_option') if extra_step.active: return request.redirect("/shop/extra_info") return request.redirect("/shop/payment") elif pickup_type in ['paynow_delivery', 'payon_delivery']: if email and name and phone and city and street and country_id: partner = request.env['res.partner'].search( [('email', '=', email)], limit=1) if request.website.is_public_user(): if not partner: partner = request.env['res.partner'].sudo().create({ 'name': name, 'email': email, 'phone': phone, 'city': city, 'street': street, 'zip': zip1, 'state_id': int(state_id) or False, 'country_id': int(country_id) or False, }) order.write({ 'partner_id': partner.id, 'partner_invoice_id': partner.id, 'partner_shipping_id': partner.id, }) if not partner: partner = request.env['res.partner'].sudo().create({ 'name': name, 'email': email, 'phone': phone, 'type': 'other', 'parent_id': user_id.partner_id.id, 'city': city, 'street': street, 'zip': zip1, 'state_id': int(state_id) or False, 'country_id': int(country_id) or False, }) order.write({ 'checkout_option': post.get('pickup_type'), 'pickup_id': partner.id, }) order.onchange_partner_shipping_id() order.order_line._compute_tax_id() request.session['sale_last_order_id'] = order.id request.website.sale_get_order(update_pricelist=True) if pickup_type == 'paynow_delivery': extra_step = request.website.viewref( 'website_sale.extra_info_option') if extra_step.active: return request.redirect("/shop/extra_info") return request.redirect("/shop/payment") if pickup_type == 'payon_delivery': order.with_context(send_email=True).action_confirm() request.website.sale_reset() PaymentProcessing.remove_payment_transaction(tx) return request.render("website_sale.confirmation", {'order': order}) else: order = request.website.sale_get_order() redirection = self.checkout_redirection(order) if redirection: return redirection order.onchange_partner_shipping_id() order.order_line._compute_tax_id() request.session['sale_last_order_id'] = order.id request.website.sale_get_order(update_pricelist=True) extra_step = request.website.viewref( 'website_sale.extra_info_option') if extra_step.active: return request.redirect("/shop/extra_info") return request.redirect("/shop/payment")
def _prepare_blog_values(self, blogs, blog=False, date_begin=False, date_end=False, tags=False, state=False, page=False): """ Prepare all values to display the blogs index page or one specific blog""" BlogPost = request.env['blog.post'] # prepare domain domain = request.website.website_domain() if blog: domain += [('blog_id', '=', blog.id)] if date_begin and date_end: domain += [("post_date", ">=", date_begin), ("post_date", "<=", date_end)] active_tag_ids = tags and [unslug(tag)[1] for tag in tags.split(',')] or [] if active_tag_ids: fixed_tag_slug = ",".join( slug(t) for t in request.env['blog.tag'].browse( active_tag_ids).exists()) if fixed_tag_slug != tags: new_url = request.httprequest.full_path.replace( "/tag/%s" % tags, "/tag/%s" % fixed_tag_slug, 1) if new_url != request.httprequest.full_path: # check that really replaced and avoid loop return request.redirect(new_url, 301) domain += [('tag_ids', 'in', active_tag_ids)] if request.env.user.has_group('website.group_website_designer'): count_domain = domain + [("website_published", "=", True), ("post_date", "<=", fields.Datetime.now()) ] published_count = BlogPost.search_count(count_domain) unpublished_count = BlogPost.search_count(domain) - published_count if state == "published": domain += [("website_published", "=", True), ("post_date", "<=", fields.Datetime.now())] elif state == "unpublished": domain += [ '|', ("website_published", "=", False), ("post_date", ">", fields.Datetime.now()) ] else: domain += [("post_date", "<=", fields.Datetime.now())] use_cover = request.website.viewref( 'website_blog.opt_blog_cover_post').active fullwidth_cover = request.website.viewref( 'website_blog.opt_blog_cover_post_fullwidth_design').active # if blog, we show blog title, if use_cover and not fullwidth_cover we need pager + latest always offset = (page - 1) * self._blog_post_per_page first_post = BlogPost if not blog: first_post = BlogPost.search(domain + [('website_published', '=', True)], order="post_date desc, id asc", limit=1) if use_cover and not fullwidth_cover: offset += 1 posts = BlogPost.search( domain, offset=offset, limit=self._blog_post_per_page, order="is_published desc, post_date desc, id asc") total = BlogPost.search_count(domain) pager = request.website.pager( url=request.httprequest.path.partition('/page/')[0], total=total, page=page, step=self._blog_post_per_page, ) all_tags = blog and blogs.all_tags()[blog.id] or blogs.all_tags( join=True) tag_category = sorted(all_tags.mapped('category_id'), key=lambda category: category.name.upper()) other_tags = sorted(all_tags.filtered(lambda x: not x.category_id), key=lambda tag: tag.name.upper()) # for performance prefetch the first post with the others post_ids = (first_post | posts).ids return { 'date_begin': date_begin, 'date_end': date_end, 'first_post': first_post.with_prefetch(post_ids), 'other_tags': other_tags, 'tag_category': tag_category, 'nav_list': self.nav_list(), 'tags_list': self.tags_list, 'pager': pager, 'posts': posts.with_prefetch(post_ids), 'tag': tags, 'active_tag_ids': active_tag_ids, 'domain': domain, 'state_info': state and { "state": state, "published": published_count, "unpublished": unpublished_count }, 'blogs': blogs, 'blog': blog, }
def social(self, social, **kwargs): url = getattr(request.website, 'social_%s' % social, False) if not url: raise werkzeug.exceptions.NotFound() return request.redirect(url)
def blog_post(self, blog, blog_post, tag_id=None, page=1, enable_editor=None, **post): """ Prepare all values to display the blog. :return dict values: values for the templates, containing - 'blog_post': browse of the current post - 'blog': browse of the current blog - 'blogs': list of browse records of blogs - 'tag': current tag, if tag_id in parameters - 'tags': all tags, for tag-based navigation - 'pager': a pager on the comments - 'nav_list': a dict [year][month] for archives navigation - 'next_post': next blog post, to direct the user towards the next interesting post """ BlogPost = request.env['blog.post'] date_begin, date_end = post.get('date_begin'), post.get('date_end') domain = request.website.website_domain() blogs = blog.search(domain, order="create_date, id asc") tag = None if tag_id: tag = request.env['blog.tag'].browse(int(tag_id)) blog_url = QueryURL('', ['blog', 'tag'], blog=blog_post.blog_id, tag=tag, date_begin=date_begin, date_end=date_end) if not blog_post.blog_id.id == blog.id: return request.redirect("/blog/%s/%s" % (slug(blog_post.blog_id), slug(blog_post)), code=301) tags = request.env['blog.tag'].search([]) # Find next Post blog_post_domain = [('blog_id', '=', blog.id)] if not request.env.user.has_group('website.group_website_designer'): blog_post_domain += [('post_date', '<=', fields.Datetime.now())] all_post = BlogPost.search(blog_post_domain) if blog_post not in all_post: return request.redirect("/blog/%s" % (slug(blog_post.blog_id))) # should always return at least the current post all_post_ids = all_post.ids current_blog_post_index = all_post_ids.index(blog_post.id) nb_posts = len(all_post_ids) next_post_id = all_post_ids[(current_blog_post_index + 1) % nb_posts] if nb_posts > 1 else None next_post = next_post_id and BlogPost.browse(next_post_id) or False values = { 'tags': tags, 'tag': tag, 'blog': blog, 'blog_post': blog_post, 'blogs': blogs, 'main_object': blog_post, 'nav_list': self.nav_list(blog), 'enable_editor': enable_editor, 'next_post': next_post, 'date': date_begin, 'blog_url': blog_url, } response = request.render("website_blog.blog_post_complete", values) if blog_post.id not in request.session.get('posts_viewed', []): if sql.increment_field_skiplock(blog_post, 'visits'): if not request.session.get('posts_viewed'): request.session['posts_viewed'] = [] request.session['posts_viewed'].append(blog_post.id) request.session.modified = True return response
def payment_confirmation(self, **post): """ End of checkout process controller. Confirmation is basically seing the status of a sale.order. State at this point : - should not have any context / session info: clean them - take a sale.order id, because we request a sale.order and are not session dependant anymore """ #Jagadeesh start ''' to display buttons on shop confirmation page ''' full_bar = False cocktail_bar = False project_id = request.session.get('last_project_id') if not project_id: project_id = request.session.get('last_proj_id') project_obj = request.env['project.project'].sudo().browse(project_id) sale_obj = project_obj.sale_order_id full_bar_menu_id = request.env['beverages'].sudo().search( [('name', '=', 'Full Bar Beverage Menu')], limit=1).id cocktail_bar_menu_id = request.env['beverages'].sudo().search( [('name', '=', 'Cocktail Bar Beverage Menu')], limit=1).id fullbar_bev_select_obj = request.env['beverages.selection'].sudo( ).search([('project_id', '=', project_id), ('beverage_menu_id', '=', full_bar_menu_id)], limit=1) cocktail_bev_select_obj = request.env['beverages.selection'].sudo( ).search([('project_id', '=', project_id), ('beverage_menu_id', '=', cocktail_bar_menu_id)], limit=1) #if fullbar_bev_select_obj and not fullbar_bev_select_obj.is_completed: # full_bar = True if cocktail_bev_select_obj and not cocktail_bev_select_obj.is_completed: cocktail_bar = True elif fullbar_bev_select_obj and not fullbar_bev_select_obj.is_completed: full_bar = True #elif (cocktail_bev_select_obj and cocktail_bev_select_obj.is_completed) or (fullbar_bev_select_obj and fullbar_bev_select_obj.is_completed): # shop = True #Jagadeesh end sale_order_id = request.session.get('sale_last_order_id') if sale_order_id: order = request.env['sale.order'].sudo().browse(sale_order_id) if request.session.get('go_for_additional_beverages'): order.project_project_id = project_id for inv in order.invoice_ids: inv.inv_project_id = project_id for line in order.order_line: product_obj = line.product_id.product_tmpl_id request.env['selected.beverages'].sudo().create({ 'sale_order_id': sale_order_id, 'product_id': product_obj.id, 'product_name': product_obj.name, 'product_code': product_obj.default_code, 'qty_required': line.product_uom_qty, 'prod_type': 'Premium', 'classification': product_obj.classification, 'on_hand': product_obj.qty_available, 'forecasted': product_obj.virtual_available, 'variance': -(product_obj.qty_available), 'bev_select_id': project_obj.beverages_selection_ids[0].id, 'premium_bev_select_id': project_obj.beverages_selection_ids[0].id }) #Jagadeesh start ''' to update the quantity selected for premium products into project form selected beverages section ''' '''if order.premium_beverages: product_dic = {} for line in order.order_line: product_dic.update({line.product_id.product_tmpl_id.id : line.product_uom_qty}) beverage_selection_obj = request.env['beverages.selection'].sudo().search([('project_id','=',project_obj.id),('beverage_menu_id','=',order.beverage_menu_id.id)]) for beverage in beverage_selection_obj.selected_beverages_ids: if beverage.prod_type == 'Premium': beverage.qty_required = product_dic[beverage.product_id.id]''' #Jagadeesh end if request.session.get('for_additional_budget'): order.project_project_id = project_id for inv in order.invoice_ids: inv.inv_project_id = project_id request.env['beverage.budget'].sudo().create({ 'budget_amount': order.amount_total, 'req_partner_id': order.partner_id.id, 'date_req': str(datetime.now()), 'project_id': project_id }) request.session['go_for_additional_beverages'] = False request.session['for_additional_budget'] = False return request.render( "website_sale.confirmation", { 'order': order, 'full_bar': full_bar, 'cocktail_bar': cocktail_bar, 'project_id': project_id }) else: return request.redirect('/shop')
def old_blog_post(self, blog, blog_post, tag_id=None, page=1, enable_editor=None, **post): # Compatibility pre-v14 return request.redirect(_build_url_w_params("/blog/%s/%s" % (slug(blog), slug(blog_post)), request.params), code=301)
def beverages_products_selection(self, bar, project, selection_type, **post): request.session['view_mode'] = 'grid' return request.redirect('/beverages/%s/%s/%s/products/all' % (bar, project, selection_type))
def registration_success(self, **kwargs): """ Return registration form """ hostname = request.env["wordpress.configuration"].sudo().get_host() return request.redirect("https://" + hostname + "/app/Login")
def pricelist_change(self, pl_id, **post): if (pl_id.selectable or pl_id == request.env.user.partner_id.property_product_pricelist) \ and request.website.is_pricelist_available(pl_id.id): request.session['website_sale_current_pl'] = pl_id.id request.website.sale_get_order(force_pricelist=pl_id.id) return request.redirect(request.httprequest.referrer or '/shop')
def remove_dictionaryteam(self, dictionary_id=0, team_id=0): if dictionary_id.create_id == request.env.user: dictionary_id.update({'team_ids': [(3, team_id.id)]}) return request.redirect(request.httprequest.referrer)