def confirm_order(self, **post): cr, uid, context, registry = request.cr, request.uid, request.context, request.registry order = request.website.sale_get_order(context=context) 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"]) request.session['sale_last_order_id'] = order.id request.website.sale_get_order(update_pricelist=True, context=context) extra_step = registry['ir.model.data'].xmlid_to_object(cr, uid, 'website_sale.extra_info_option', raise_if_not_found=True) if extra_step.active: return request.redirect("/shop/extra_info") return request.redirect("/shop/payment")
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: post.update({'zip': post.pop('zipcode', '')}) partner.sudo().write(post) 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.website.render("website_portal.details", values)
def extra_info(self, **post): cr, uid, context, registry = request.cr, request.uid, request.context, request.registry # Check that this option is activated extra_step = registry['ir.model.data'].xmlid_to_object(cr, uid, 'website_sale.extra_info_option', raise_if_not_found=True) if not extra_step.active: return request.redirect("/shop/payment") # check that cart is valid order = request.website.sale_get_order(context=context) 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.registry['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 } sale_order_obj = request.registry.get('sale.order') values.update(sale_order_obj._get_website_data(cr, uid, order, context)) return request.website.render("website_sale.extra_info", values)
def pricelist(self, promo, **post): cr, uid, pool, context = request.cr, request.uid, request.registry, request.context pl = pool['product.pricelist'].search(cr, SUPERUSER_ID, [('code', '=', promo)], context=context) if pl: if not request.website.is_pricelist_available(pl[0], context=context): return request.redirect("/shop/cart?code_not_available=1") request.website.sale_get_order(code=promo, context=context) return request.redirect("/shop/cart")
def checkout_redirection(self, order): cr, uid, context, registry = request.cr, request.uid, request.context, request.registry # 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 = context.get('website_sale_transaction') if tx and tx.state != 'draft': return request.redirect('/shop/payment/confirmation/%s' % order.id)
def actions_server(self, path_or_xml_id_or_id, **post): cr, uid, context = request.cr, request.uid, request.context res, action_id, action = None, None, None ServerActions = request.registry['ir.actions.server'] # 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_id = request.registry['ir.model.data'].xmlid_to_res_id(request.cr, request.uid, path_or_xml_id_or_id, raise_if_not_found=False) if not action_id: action_ids = ServerActions.search(cr, uid, [('website_path', '=', path_or_xml_id_or_id), ('website_published', '=', True)], context=context) action_id = action_ids and action_ids[0] or None if not action_id: try: action_id = int(path_or_xml_id_or_id) except ValueError: pass # check it effectively exists if action_id: action_ids = ServerActions.exists(cr, uid, [action_id], context=context) action_id = action_ids and action_ids[0] or None # run it, return only if we got a Response object if action_id: action = ServerActions.browse(cr, uid, action_id, context=context) if action.state == 'code' and action.website_published: action_res = ServerActions.run(cr, uid, [action_id], context=context) if isinstance(action_res, werkzeug.wrappers.Response): res = action_res if res: return res return request.redirect('/')
def event(self, event, **post): if event.menu_id and event.menu_id.child_id: target_url = event.menu_id.child_id[0].url else: target_url = '/event/%s/register' % str(event.id) if post.get('enable_editor') == '1': target_url += '?enable_editor=1' return request.redirect(target_url)
def print_saleorder(self): cr, uid, context = request.cr, SUPERUSER_ID, request.context sale_order_id = request.session.get('sale_last_order_id') if sale_order_id: pdf = request.registry['report'].get_pdf(cr, uid, [sale_order_id], 'sale.report_saleorder', data=None, context=context) pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(pdf))] return request.make_response(pdf, headers=pdfhttpheaders) else: return request.redirect('/shop')
def confirm(self, **kw): tx_id = request.session.pop('website_payment_tx_id', False) if tx_id: tx = request.env['payment.transaction'].browse(tx_id) status = (tx.state == 'done' and 'success') or 'danger' message = (tx.state == 'done' and 'Your payment was successful! It may take some time to be validated on our end.') or 'OOps! There was a problem with your payment.' return request.website.render('website_payment.confirm', {'tx': tx, 'status': status, 'message': message}) else: return request.redirect('/my/home')
def add_product(self, name=None, category=0, **post): cr, uid, context, pool = request.cr, request.uid, request.context, request.registry if not name: name = _("New Product") product_obj = request.registry.get('product.product') product_id = product_obj.create(cr, uid, { 'name': name, 'public_categ_ids': category }, context=context) product = product_obj.browse(cr, uid, product_id, context=context) return request.redirect("/shop/product/%s?enable_editor=1" % slug(product.product_tmpl_id))
def payment_transaction(self, acquirer_id): """ 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 """ cr, uid, context = request.cr, request.uid, request.context transaction_obj = request.registry.get('payment.transaction') order = request.website.sale_get_order(context=context) 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: tx_id = tx.id if tx.reference != order.name: tx = False tx_id = False elif tx.state == 'draft': # button cliked but no more info -> rewrite on tx or create a new one ? tx.write({ 'acquirer_id': acquirer_id, 'amount': order.amount_total, }) if not tx: tx_id = transaction_obj.create(cr, SUPERUSER_ID, { 'acquirer_id': acquirer_id, 'type': 'form', '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': request.env['payment.transaction'].get_next_reference(order.name), 'sale_order_id': order.id, }, context=context) request.session['sale_transaction_id'] = tx_id tx = transaction_obj.browse(cr, SUPERUSER_ID, tx_id, context=context) # update quotation request.registry['sale.order'].write( cr, SUPERUSER_ID, [order.id], { 'payment_acquirer_id': acquirer_id, 'payment_tx_id': request.session['sale_transaction_id'] }, context=context) # confirm the quotation if tx.acquirer_id.auto_confirm == 'at_pay_now': request.registry['sale.order'].action_confirm(cr, SUPERUSER_ID, [order.id], context=request.context) return tx_id
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 """ cr, uid, context = request.cr, request.uid, request.context email_act = None sale_order_obj = request.registry['sale.order'] if transaction_id is None: tx = request.website.sale_get_transaction() else: tx = request.registry['payment.transaction'].browse(cr, uid, transaction_id, context=context) if sale_order_id is None: order = request.website.sale_get_order(context=context) else: order = request.registry['sale.order'].browse(cr, SUPERUSER_ID, sale_order_id, context=context) 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(dict(context, send_email=True)).action_confirm() elif tx and tx.state == 'cancel': # cancel the quotation sale_order_obj.action_cancel(cr, SUPERUSER_ID, [order.id], context=request.context) # clean context and session, then redirect to the confirmation page request.website.sale_reset(context=context) if tx and tx.state == 'draft': return request.redirect('/shop') return request.redirect('/shop/confirmation')
def _add_event(self, event_name=None, context={}, **kwargs): if not event_name: event_name = _("New Event") Event = request.registry.get('event.event') date_begin = datetime.today() + timedelta(days=(14)) vals = { 'name': event_name, 'date_begin': date_begin.strftime('%Y-%m-%d'), 'date_end': (date_begin + timedelta(days=(1))).strftime('%Y-%m-%d'), 'seats_available': 1000, } event_id = Event.create(request.cr, request.uid, vals, context=context) event = Event.browse(request.cr, request.uid, event_id, context=context) return request.redirect("/event/%s/register?enable_editor=1" % slug(event))
def index(self, **kw): page = 'homepage' try: main_menu = request.env.ref('website.main_menu') except Exception: pass else: first_menu = main_menu.child_id and main_menu.child_id[0] if first_menu: if first_menu.url and (not (first_menu.url.startswith(('/page/', '/?', '/#')) or (first_menu.url == '/'))): return request.redirect(first_menu.url) if first_menu.url and first_menu.url.startswith('/page/'): return request.registry['ir.http'].reroute(first_menu.url) return self.page(page)
def payment(self, **post): cr, uid, context = request.cr, request.uid, request.context order = request.website.sale_get_order(context=context) carrier_id = post.get('carrier_id') if carrier_id: carrier_id = int(carrier_id) if order: request.registry['sale.order']._check_carrier_quotation( cr, uid, order, force_carrier_id=carrier_id, context=context) if carrier_id: return request.redirect("/shop/payment") res = super(website_sale, self).payment(**post) return res
def post_toc_ok(self, forum, post_id, toc_id, **kwargs): cr, uid, context = request.cr, request.uid, request.context user = request.registry['res.users'].browse(cr, uid, uid, context=context) assert user.karma >= 200, 'Not enough karma, you need 200 to promote a documentation.' toc_obj = request.registry['forum.documentation.toc'] stage_ids = toc_obj.search(cr, uid, [], limit=1, context=context) post_obj = request.registry['forum.post'] post_obj.write(cr, uid, [int(post_id)], { 'documentation_toc_id': toc_id and int(toc_id) or False, 'documentation_stage_id': stage_ids and stage_ids[0] or False }, context=context) return request.redirect('/forum/'+str(forum.id)+'/question/'+str(post_id))
def slides_index(self, *args, **post): """ Returns a list of available channels: if only one is available, redirects directly to its slides """ channels = request.env['slide.channel'].search([], order='sequence, id') if not channels: return request.website.render("website_slides.channel_not_found") elif len(channels) == 1: return request.redirect("/slides/%s" % channels.id) return request.website.render('website_slides.channels', { 'channels': channels, 'user': request.env.user, 'is_public_user': request.env.user == request.website.user_id })
def slides_index(self, *args, **post): """ Returns a list of available channels: if only one is available, redirects directly to its slides """ channels = request.env['slide.channel'].search([], order='sequence, id') if not channels: return request.website.render("website_slides.channel_not_found") elif len(channels) == 1: return request.redirect("/slides/%s" % channels.id) return request.website.render( 'website_slides.channels', { 'channels': channels, 'user': request.env.user, 'is_public_user': request.env.user == request.website.user_id })
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 """ cr, uid, context = request.cr, request.uid, request.context sale_order_id = request.session.get('sale_last_order_id') if sale_order_id: order = request.registry['sale.order'].browse(cr, SUPERUSER_ID, sale_order_id, context=context) else: return request.redirect('/shop') return request.website.render("website_sale.confirmation", {'order': order})
def reset_template(self, templates, redirect='/'): templates = request.httprequest.form.getlist('templates') modules_to_update = [] for temp_id in templates: view = request.registry['ir.ui.view'].browse(request.cr, request.uid, int(temp_id), context=request.context) if view.page: continue view.model_data_id.write({ 'noupdate': False }) if view.model_data_id.module not in modules_to_update: modules_to_update.append(view.model_data_id.module) if modules_to_update: module_obj = request.env['ir.module.module'].sudo() modules = module_obj.search([('name', 'in', modules_to_update)]) if modules: modules.button_immediate_upgrade() return request.redirect(redirect)
def page(self, page, **opt): values = { 'path': page, 'deletable': True, # used to add 'delete this page' in content menu } # /page/website.XXX --> /page/XXX if page.startswith('website.'): return request.redirect('/page/' + page[8:], code=301) elif '.' not in page: page = 'website.%s' % page try: request.website.get_template(page) except ValueError, e: # page not found if request.website.is_publisher(): values.pop('deletable') page = 'website.page_404' else: return request.registry['ir.http']._handle_exception(e, 404)
def post_toc_ok(self, forum, post_id, toc_id, **kwargs): cr, uid, context = request.cr, request.uid, request.context user = request.registry['res.users'].browse(cr, uid, uid, context=context) assert user.karma >= 200, 'Not enough karma, you need 200 to promote a documentation.' toc_obj = request.registry['forum.documentation.toc'] stage_ids = toc_obj.search(cr, uid, [], limit=1, context=context) post_obj = request.registry['forum.post'] post_obj.write( cr, uid, [int(post_id)], { 'documentation_toc_id': toc_id and int(toc_id) or False, 'documentation_stage_id': stage_ids and stage_ids[0] or False }, context=context) return request.redirect('/forum/' + str(forum.id) + '/question/' + str(post_id))
def jobs_add(self, **kwargs): job = request.env['hr.job'].create({ 'name': _('New Job Offer'), }) return request.redirect("/jobs/detail/%s?enable_editor=1" % slug(job))
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 _dispatch(self): 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 = self._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')) self._geoip_setup_resolver() self._geoip_resolve() cook_lang = request.httprequest.cookies.get('website_lang') if request.website_enabled: try: if func: self._authenticate(func.routing['auth']) elif request.uid is None: self._auth_method_public() except Exception as e: return self._handle_exception(e) request.redirect = lambda url, code=302: werkzeug.utils.redirect( url_for(url), code) request.website = request.registry['website'].get_current_website( request.cr, request.uid, context=request.context) request.context['website_id'] = request.website.id langs = [lg[0] for lg in request.website.get_languages()] path = request.httprequest.path.split('/') if first_pass: nearest_lang = not func and self.get_nearest_lang(path[1]) url_lang = nearest_lang and path[1] preferred_lang = ((cook_lang if cook_lang in langs else False) or self.get_nearest_lang(request.lang) or request.website.default_lang_code) is_a_bot = self.is_a_bot() request.lang = request.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) return redirect elif url_lang: request.uid = None path.pop(1) return self.reroute('/'.join(path) or '/') if path[1] == request.website.default_lang_code: request.context['edit_translations'] = False if not request.context.get('tz'): request.context['tz'] = request.session.get( 'geoip', {}).get('time_zone') # bind modified context request.website = request.website.with_context(request.context) # cache for auth public cache_time = getattr(func, 'routing', {}).get('cache') cache_enable = cache_time and request.httprequest.method == "GET" and request.website.user_id.id == request.uid cache_response = None if cache_enable: key = self.get_page_key() try: r = self.pool.cache[key] if r['time'] + cache_time > time.time(): cache_response = ecore.http.Response( r['content'], mimetype=r['mimetype']) else: del self.pool.cache[key] except KeyError: pass if cache_response: request.cache_save = False resp = cache_response else: request.cache_save = key if cache_enable else False resp = super(ir_http, self)._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 _dispatch(self): 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 = self._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') ) self._geoip_setup_resolver() self._geoip_resolve() cook_lang = request.httprequest.cookies.get('website_lang') if request.website_enabled: try: if func: self._authenticate(func.routing['auth']) elif request.uid is None: self._auth_method_public() except Exception as e: return self._handle_exception(e) request.redirect = lambda url, code=302: werkzeug.utils.redirect(url_for(url), code) request.website = request.registry['website'].get_current_website(request.cr, request.uid, context=request.context) request.context['website_id'] = request.website.id langs = [lg[0] for lg in request.website.get_languages()] path = request.httprequest.path.split('/') if first_pass: nearest_lang = not func and self.get_nearest_lang(path[1]) url_lang = nearest_lang and path[1] preferred_lang = ((cook_lang if cook_lang in langs else False) or self.get_nearest_lang(request.lang) or request.website.default_lang_code) is_a_bot = self.is_a_bot() request.lang = request.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) return redirect elif url_lang: path.pop(1) return self.reroute('/'.join(path) or '/') if path[1] == request.website.default_lang_code: request.context['edit_translations'] = False if not request.context.get('tz'): request.context['tz'] = request.session.get('geoip', {}).get('time_zone') # bind modified context request.website = request.website.with_context(request.context) # cache for auth public cache_time = getattr(func, 'routing', {}).get('cache') cache_enable = cache_time and request.httprequest.method == "GET" and request.website.user_id.id == request.uid cache_response = None if cache_enable: key = self.get_page_key() try: r = self.pool.cache[key] if r['time'] + cache_time > time.time(): cache_response = ecore.http.Response(r['content'], mimetype=r['mimetype']) else: del self.pool.cache[key] except KeyError: pass if cache_response: request.cache_save = False resp = cache_response else: request.cache_save = key if cache_enable else False resp = super(ir_http, self)._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 slide_set_promoted(self, slide): slide.channel_id.promoted_slide_id = slide.id return request.redirect("/slides/%s" % slide.channel_id.id)
def registration_new(self, event, **post): tickets = self._process_tickets_details(post) if not tickets: return request.redirect("/event/%s" % slug(event)) return request.website._render("website_event.registration_attendee_details", {'tickets': tickets, 'event': event})
def pricelist_change(self, pl_id, **post): if request.website.is_pricelist_available(pl_id.id, context=request.context): request.session['website_sale_current_pl'] = pl_id.id request.website.sale_get_order(force_pricelist=pl_id.id, context=request.context) return request.redirect(request.httprequest.referrer or '/shop')
def delete(self, delete_pm_id=None): if delete_pm_id: pay_meth = request.env['payment.method'].browse(int(delete_pm_id)) pay_meth.unlink() return request.redirect('/my/payment_method')
def cart_update(self, product_id, add_qty=1, set_qty=0, **kw): request.website.sale_get_order(force_create=1)._cart_update(product_id=int(product_id), add_qty=float(add_qty), set_qty=float(set_qty)) return request.redirect("/shop/cart")