def survey_start(self, survey_token, answer_token=None, email=False, **post): """ Start a survey by providing * a token linked to a survey; * a token linked to an answer or generate a new token if access is allowed; """ access_data = self._get_access_data(survey_token, answer_token, ensure_token=False) if access_data['validity_code'] is not True: return self._redirect_with_error(access_data, access_data['validity_code']) survey_sudo, answer_sudo = access_data['survey_sudo'], access_data['answer_sudo'] if not answer_sudo: try: answer_sudo = survey_sudo._create_answer(user=request.env.user, email=email) except UserError: answer_sudo = False if not answer_sudo: try: survey_sudo.sudo(request.env.user).check_access_rights('read') survey_sudo.sudo(request.env.user).check_access_rule('read') except: return werkzeug.utils.redirect("/") else: return request.render("survey.403", {'survey': survey_sudo}) # Select the right page if answer_sudo.state == 'new': # Intro page data = {'survey': survey_sudo, 'answer': answer_sudo, 'page': 0} return request.render('survey.survey_init', data) else: return request.redirect('/survey/fill/%s/%s' % (survey_sudo.access_token, answer_sudo.token))
def survey_display_page(self, survey_id, token, prev=None, **post): access_data = self._get_access_data(survey_id, token, ensure_token=True) if access_data['validity_code'] is not True: return self._redirect_with_error(access_data, access_data['validity_code']) survey_sudo, answer_sudo = access_data['survey_sudo'], access_data['answer_sudo'] # Select the right page if answer_sudo.state == 'new': # First page page, page_nr, last = survey_sudo.next_page(answer_sudo, 0, go_back=False) data = {'survey': survey_sudo, 'page': page, 'page_nr': page_nr, 'token': answer_sudo.token, 'test_entry': answer_sudo.test_entry} if last: data.update({'last': True}) return request.render('survey.survey', data) elif answer_sudo.state == 'done': # Display success message return request.render('survey.sfinished', {'survey': survey_sudo, 'token': token, 'user_input': answer_sudo}) elif answer_sudo.state == 'skip': flag = (True if prev and prev == 'prev' else False) page, page_nr, last = survey_sudo.next_page(answer_sudo, answer_sudo.last_displayed_page_id.id, go_back=flag) #special case if you click "previous" from the last page, then leave the survey, then reopen it from the URL, avoid crash if not page: page, page_nr, last = survey_sudo.next_page(answer_sudo, answer_sudo.last_displayed_page_id.id, go_back=True) data = {'survey': survey_sudo, 'page': page, 'page_nr': page_nr, 'token': answer_sudo.token, 'test_entry': answer_sudo.test_entry} if last: data.update({'last': True}) return request.render('survey.survey', data) else: return request.render("survey.403", {'survey': survey_sudo})
def view_user_profile(self, user_id, **post): user = self._check_user_profile_access(user_id) if not user: return request.render("website_profile.private_profile") params = self._prepare_user_profile_parameters(**post) values = self._prepare_user_profile_values(user, **params) return request.render("website_profile.user_profile_main", values)
def cart(self, **post): order = request.website.sale_get_order() if order: from_currency = order.company_id.currency_id to_currency = order.pricelist_id.currency_id compute_currency = lambda price: from_currency.compute(price, to_currency) else: compute_currency = lambda price: price values = { 'website_sale_order': order, 'compute_currency': compute_currency, 'suggested_products': [], } if order: _order = order if not request.env.context.get('pricelist'): _order = order.with_context(pricelist=order.pricelist_id.id) values['suggested_products'] = _order._cart_accessories() if post.get('type') == 'popover': return request.render("website_sale.cart_popover", values) if post.get('code_not_available'): values['code_not_available'] = post.get('code_not_available') return request.render("website_sale.cart", values)
def question(self, forum, question, **post): if not forum.active: return request.render("website_forum.header", {'forum': forum}) # Hide posts from abusers (negative karma), except for moderators if not question.can_view: raise werkzeug.exceptions.NotFound() # Hide pending posts from non-moderators and non-creator user = request.env.user if question.state == 'pending' and user.karma < forum.karma_post and question.create_uid != user: raise werkzeug.exceptions.NotFound() # increment view counter question.sudo().set_viewed() if question.parent_id: redirect_url = "/forum/%s/question/%s" % (slug(forum), slug(question.parent_id)) return werkzeug.utils.redirect(redirect_url, 301) filters = 'question' values = self._prepare_forum_values(forum=forum, searches=post) values.update({ 'main_object': question, 'question': question, 'can_bump': (question.forum_id.allow_bump and not question.child_ids and (datetime.today() - question.write_date).days > 9), 'header': {'question_data': True}, 'filters': filters, 'reversed': reversed, }) return request.render("website_forum.post_description_full", values)
def confirm_unsubscribe(self, channel, partner_id, token, **kw): subscriber = request.env['mail.channel.partner'].search([('channel_id', '=', channel.id), ('partner_id', '=', partner_id)]) if not subscriber: partner = request.env['res.partner'].browse(partner_id).sudo().exists() # FIXME: remove try/except in master try: response = request.render( 'website_mail_channel.not_subscribed', {'partner_id': partner}) # make sure the rendering (and thus error if template is # missing) happens inside the try block response.flatten() return response except ValueError: return _("The address %s is already unsubscribed or was never subscribed to any mailing list") % ( partner.email ) subscriber_token = channel._generate_action_token(partner_id, action='unsubscribe') if token != subscriber_token: return request.render('website_mail_channel.invalid_token_subscription') # remove partner channel.sudo().write({'channel_partner_ids': [(3, partner_id)]}) return request.render("website_mail_channel.confirmation_subscription", {'subscribing': False})
def survey_start(self, survey, token=None, **post): """ Start a survey by providing a token linked to an answer or generate a new token if access is allowed """ UserInput = request.env['survey.user_input'] # Controls if the survey can be displayed errpage = self._check_bad_cases(survey, token=token) if errpage: return errpage # Manual surveying if not token: vals = {'survey_id': survey.id} if not request.env.user._is_public(): vals['partner_id'] = request.env.user.partner_id.id user_input = UserInput.create(vals) else: user_input = UserInput.sudo().search([('token', '=', token)], limit=1) if not user_input: return request.render("survey.403", {'survey': survey}) # Do not open expired survey errpage = self._check_deadline(user_input) if errpage: return errpage # Select the right page if user_input.state == 'new': # Intro page data = {'survey': survey, 'page': None, 'token': user_input.token} return request.render('survey.survey_init', data) else: return request.redirect('/survey/fill/%s/%s' % (survey.id, user_input.token))
def cart(self, **post): order = request.website.sale_get_order() if order: from_currency = order.company_id.currency_id to_currency = order.pricelist_id.currency_id compute_currency = lambda price: from_currency.compute(price, to_currency) else: compute_currency = lambda price: price values = { 'website_sale_order': order, 'compute_currency': compute_currency, 'suggested_products': [], } if order: _order = order if not request.env.context.get('pricelist'): _order = order.with_context(pricelist=order.pricelist_id.id) values['suggested_products'] = _order._cart_accessories() if post.get('type') == 'popover': # force no-cache so IE11 doesn't cache this XHR return request.render("website_sale.cart_popover", values, headers={'Cache-Control': 'no-cache'}) return request.render("website_sale.cart", values)
def view(self, order_id, pdf=None, token=None, message=False, **post): # use sudo to allow accessing/viewing orders for public user # only if he knows the private token now = fields.Date.today() if token: Order = request.env['sale.order'].sudo().search([('id', '=', order_id), ('access_token', '=', token)]) else: Order = request.env['sale.order'].search([('id', '=', order_id)]) # Log only once a day if Order and request.session.get('view_quote_%s' % Order.id) != now and request.env.user.share: request.session['view_quote_%s' % Order.id] = now body = _('Quotation viewed by customer') _message_post_helper(res_model='sale.order', res_id=Order.id, message=body, token=token, message_type='notification', subtype="mail.mt_note", partner_ids=Order.user_id.sudo().partner_id.ids) if not Order: return request.render('website.404') # Token or not, sudo the order, since portal user has not access on # taxes, required to compute the total_amout of SO. order_sudo = Order.sudo() days = 0 if order_sudo.validity_date: days = (fields.Date.from_string(order_sudo.validity_date) - fields.Date.from_string(fields.Date.today())).days + 1 if pdf: pdf = request.env.ref('website_quote.report_web_quote').sudo().with_context(set_viewport_size=True).render_qweb_pdf([order_sudo.id])[0] pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(pdf))] return request.make_response(pdf, headers=pdfhttpheaders) transaction = order_sudo.get_portal_last_transaction() values = { 'quotation': order_sudo, 'message': message and int(message) or False, 'option': any(not x.line_id for x in order_sudo.options), 'order_valid': (not order_sudo.validity_date) or (now <= order_sudo.validity_date), 'days_valid': days, 'action': request.env.ref('sale.action_quotations').id, 'no_breadcrumbs': request.env.user.partner_id.commercial_partner_id not in order_sudo.message_partner_ids, 'tx_id': transaction.id if transaction else False, 'tx_state': transaction.state if transaction else False, 'payment_tx': transaction, 'tx_post_msg': transaction.acquirer_id.post_msg if transaction else False, 'need_payment': order_sudo.invoice_status == 'to invoice' and transaction.state in ['draft', 'cancel'], 'token': token, 'return_url': '/shop/payment/validate', 'bootstrap_formatting': True, 'partner_id': order_sudo.partner_id.id, } if order_sudo.require_payment or values['need_payment']: acquirers = request.env['payment.acquirer'].sudo().search([('website_published', '=', True), ('company_id', '=', order_sudo.company_id.id)]) values['form_acquirers'] = [acq for acq in acquirers if acq.payment_flow == 'form' and acq.view_template_id] values['s2s_acquirers'] = [acq for acq in acquirers if acq.payment_flow == 's2s' and acq.registration_view_template_id] values['pms'] = request.env['payment.token'].search( [('partner_id', '=', order_sudo.partner_id.id), ('acquirer_id', 'in', [acq.id for acq in values['s2s_acquirers']])]) history = request.session.get('my_quotes_history', []) values.update(get_records_pager(history, order_sudo)) return request.render('website_quote.so_quotation', values)
def equipments(self, equipment_id=False,**post): if equipment_id: vals = { "equipment": request.env["equipment.equipment"].browse(equipment_id) } return request.render("equipments.equipment_page_view", vals) vals = { "equipments" : request.env["equipment.equipment"].search([]) } return request.render("equipments.equipments_view", vals)
def orders_followup(self, order=None, **kw): order = request.env["sale.order"].browse([order]) try: order.check_access_rights("read") order.check_access_rule("read") except AccessError: return request.render("website.403") order_invoice_lines = {il.product_id.id: il.invoice_id for il in order.invoice_ids.mapped("invoice_line_ids")} return request.render( "website_portal_sale.orders_followup", {"order": order.sudo(), "order_invoice_lines": order_invoice_lines} )
def pay_orders_followup(self, order=None, **kw): pay_order = request.env['money.order'].browse([order]) try: pay_order.check_access_rights('read') pay_order.check_access_rule('read') except AccessError: return request.render("website.403") pay_order_sudo = pay_order.sudo() return request.render("good_portal_money.pay_orders_followup", { 'pay_order': pay_order_sudo, })
def mailing(self, mailing_id, email=None, res_id=None, **post): mailing = request.env['mail.mass_mailing'].sudo().browse(mailing_id) if mailing.exists(): if mailing.mailing_model == 'mail.mass_mailing.contact': contacts = request.env['mail.mass_mailing.contact'].sudo().search([('email', '=', email)]) return request.render('website_mass_mailing.page_unsubscribe', { 'contacts': contacts, 'email': email, 'mailing_id': mailing_id}) else: super(MassMailController, self).mailing(mailing_id, email=email, res_id=res_id, **post) return request.render('website_mass_mailing.page_unsubscribed')
def orders_followup(self, order=None, **kw): order = request.env['sale.order'].browse([order]) try: order.check_access_rights('read') order.check_access_rule('read') except AccessError: return request.render("website.403") order_invoice_lines = {il.product_id.id: il.invoice_id for il in order.invoice_ids.mapped('invoice_line_ids')} return request.render("website_portal_sale.orders_followup", { 'order': order.sudo(), 'order_invoice_lines': order_invoice_lines, })
def session(self, session_id=0,**post): values = { "session_ids": [] } if session_id: values.update({'session_ids': request.env["openacademy.session"].sudo().search([('id', "=", session_id)])}) return request.render("openacademy.session_page", values) #request.redirect("/") values.update({ "session_ids": request.env["openacademy.session"].sudo().search([]) }) return request.render("openacademy.sessions", values)
def tasks_followup(self, order=None, **kw): task = request.env['task'].browse([order]) try: task.check_access_rights('read') task.check_access_rule('read') except AccessError: return request.render("website.403") task_sudo = task.sudo() return request.render("good_portal_task.tasks_followup", { 'task': task_sudo, })
def orders_followup(self, order=None, **kw): order = request.env['sell.order'].browse([order]) try: order.check_access_rights('read') order.check_access_rule('read') except AccessError: return request.render("website.403") order_sudo = order.sudo() return request.render("good_portal_sell.orders_followup", { 'order': order_sudo, })
def portal_my_purchase_order(self, order_id=None, **kw): order = request.env['purchase.order'].browse(order_id) try: order.check_access_rights('read') order.check_access_rule('read') except AccessError: return request.render("website.403") history = request.session.get('my_purchases_history', []) values = { 'order': order.sudo(), } values.update(get_records_pager(history, order)) return request.render("website_portal_purchase.portal_my_purchase_order", values)
def cart(self, access_token=None, revive='', **post): """ Main cart management + abandoned cart revival access_token: Abandoned cart SO access token revive: Revival method when abandoned cart. Can be 'merge' or 'squash' """ order = request.website.sale_get_order() if order and order.state != 'draft': request.session['sale_order_id'] = None order = request.website.sale_get_order() values = {} if access_token: abandoned_order = request.env['sale.order'].sudo().search([('access_token', '=', access_token)], limit=1) if not abandoned_order: # wrong token (or SO has been deleted) return request.render('website.404') if abandoned_order.state != 'draft': # abandoned cart already finished values.update({'abandoned_proceed': True}) elif revive == 'squash' or (revive == 'merge' and not request.session['sale_order_id']): # restore old cart or merge with unexistant request.session['sale_order_id'] = abandoned_order.id return request.redirect('/shop/cart') elif revive == 'merge': abandoned_order.order_line.write({'order_id': request.session['sale_order_id']}) abandoned_order.action_cancel() elif abandoned_order.id != request.session['sale_order_id']: # abandoned cart found, user have to choose what to do values.update({'access_token': abandoned_order.access_token}) if order: from_currency = order.company_id.currency_id to_currency = order.pricelist_id.currency_id compute_currency = lambda price: from_currency._convert( price, to_currency, request.env.user.company_id, fields.Date.today()) else: compute_currency = lambda price: price values.update({ 'website_sale_order': order, 'compute_currency': compute_currency, 'date': fields.Date.today(), 'suggested_products': [], }) if order: _order = order if not request.env.context.get('pricelist'): _order = order.with_context(pricelist=order.pricelist_id.id) values['suggested_products'] = _order._cart_accessories() if post.get('type') == 'popover': # force no-cache so IE11 doesn't cache this XHR return request.render("website_sale.cart_popover", values, headers={'Cache-Control': 'no-cache'}) return request.render("website_sale.cart", values)
def mailing(self, mailing_id, email=None, res_id=None, token="", **post): mailing = request.env['mail.mass_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 == 'mail.mass_mailing.contact': # Unsubscribe directly + Let the user choose his subscriptions mailing.update_opt_out(email, mailing.contact_list_ids.ids, True) contacts = request.env['mail.mass_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['mail.mass_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['mail.mass_mailing.list_contact_rel'].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 _redirect_with_error(self, access_data, error_key): survey_sudo = access_data['survey_sudo'] answer_sudo = access_data['answer_sudo'] if error_key == 'survey_void' and access_data['can_answer']: return request.render("survey.survey_void", {'survey': survey_sudo}) elif error_key == 'survey_closed' and access_data['can_answer']: return request.render("survey.survey_expired", {'survey': survey_sudo}) elif error_key == 'survey_auth' and answer_sudo.token: return request.render("survey.auth_required", {'survey': survey_sudo, 'token': answer_sudo.token}) elif error_key == 'answer_deadline' and answer_sudo.token: return request.render("survey.survey_expired", {'survey': survey_sudo}) return werkzeug.utils.redirect("/")
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.render("website_slides.channel_not_found") elif len(channels) == 1: return request.redirect("/slides/%s" % channels.id) return request.render('website_slides.channels', { 'channels': channels, 'user': request.env.user, 'is_public_user': request.env.user == request.website.user_id })
def confirm_subscribe(self, channel, partner_id, token, **kw): subscriber = request.env['mail.channel.partner'].search([('channel_id', '=', channel.id), ('partner_id', '=', partner_id)]) if subscriber: # already registered, maybe clicked twice return request.render('website_mail_channel.invalid_token_subscription') subscriber_token = channel._generate_action_token(partner_id, action='subscribe') if token != subscriber_token: return request.render('website_mail_channel.invalid_token_subscription') # add partner channel.sudo().write({'channel_partner_ids': [(4, partner_id)]}) return request.render("website_mail_channel.confirmation_subscription", {'subscribing': True})
def confirm_unsubscribe(self, channel, partner_id, token, **kw): subscriber = request.env['mail.channel.partner'].search([('channel_id', '=', channel.id), ('partner_id', '=', partner_id)]) if not subscriber: # not registered, maybe already unsubsribed return request.render('website_mail_channel.invalid_token_subscription') subscriber_token = channel._generate_action_token(partner_id, action='unsubscribe') if token != subscriber_token: return request.render('website_mail_channel.invalid_token_subscription') # remove partner channel.sudo().write({'channel_partner_ids': [(3, partner_id)]}) return request.render("website_mail_channel.confirmation_subscription", {'subscribing': False})
def slide_view(self, slide, **kwargs): if not slide.channel_id.can_access_from_current_website(): raise werkzeug.exceptions.NotFound() self._set_viewed_slide(slide) values = self._get_slide_detail(slide) # quiz-specific: update with karma and quiz information if slide.question_ids: values.update(self._get_slide_quiz_info(slide)) # sidebar: update with user channel progress values['channel_progress'] = self._get_channel_progress(slide.channel_id, include_quiz=True) if kwargs.get('fullscreen') == '1': return request.render("website_slides.slide_fullscreen", values) return request.render("website_slides.slide_main", values)
def tags(self, forum, tag_char=None, **post): # build the list of tag first char, with their value as tag_char param Ex : [('All', 'all'), ('C', 'c'), ('G', 'g'), ('Z', z)] first_char_tag = forum.get_tags_first_char() first_char_list = [(t, t.lower()) for t in first_char_tag if t.isalnum()] first_char_list.insert(0, (_('All'), 'all')) # get active first char tag active_char_tag = first_char_list[1][1] if len(first_char_list) > 1 else 'all' if tag_char: active_char_tag = tag_char.lower() # generate domain for searched tags domain = [('forum_id', '=', forum.id), ('posts_count', '>', 0)] order_by = 'name' if active_char_tag and active_char_tag != 'all': domain.append(('name', '=ilike', tools.escape_psql(active_char_tag)+'%')) order_by = 'posts_count DESC' tags = request.env['forum.tag'].search(domain, limit=None, order=order_by) # prepare values and render template values = self._prepare_forum_values(forum=forum, searches={'tags': True}, **post) values.update({ 'tags': tags, 'pager_tag_chars': first_char_list, 'active_char_tag': active_char_tag, }) return request.render("website_forum.tag", values)
def cart(self, **post): order = request.website.sale_get_order() values = { 'website_sale_order': order, 'compute_currency': lambda price: price, 'suggested_products': [], } if post.get('type') == 'popover': return request.render("good_shop.cart_popover", values) if post.get('code_not_available'): values['code_not_available'] = post.get('code_not_available') return request.render("good_shop.cart", 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 my_orders(self, page=1, date_begin=None, date_end=None, **kw): values = self._prepare_portal_layout_values() partner = request.env.user.gooderp_partner_id SaleOrder = request.env['sell.order'] domain = [ ('partner_id', '=', partner.id) ] archive_groups = self._get_archive_groups('sell.order', domain) if date_begin and date_end: domain += [('create_date', '>', date_begin), ('create_date', '<=', date_end)] # count for pager order_count = SaleOrder.search_count(domain) # pager pager = request.website.pager( url="/my/orders", url_args={'date_begin': date_begin, 'date_end': date_end}, total=order_count, page=page, step=self._items_per_page ) # content according to pager and archive selected orders = SaleOrder.search(domain, limit=self._items_per_page, offset=pager['offset']) values.update({ 'date': date_begin, 'orders': orders, 'page_name': 'order', 'pager': pager, 'archive_groups': archive_groups, 'default_url': '/my/orders', }) return request.render("good_portal_sell.portal_my_orders", values)
def FieldTextHtml(self, model=None, res_id=None, field=None, callback=None, **kwargs): kwargs.update( model=model, res_id=res_id, field=field, datarecord=json.loads(kwargs['datarecord']), debug=request.debug) for k in kwargs: if isinstance(kwargs[k], pycompat.string_types) and kwargs[k].isdigit(): kwargs[k] = int(kwargs[k]) trans = dict( lang=kwargs.get('lang', request.env.context.get('lang')), translatable=kwargs.get('translatable'), edit_translations=kwargs.get('edit_translations'), editable=kwargs.get('enable_editor')) kwargs.update(trans) record = None if model and kwargs.get('res_id'): record = request.env[model].with_context(trans).browse(kwargs.get('res_id')) kwargs.update(content=record and getattr(record, field) or "") return request.render(kwargs.get("template") or "web_editor.FieldTextHtml", kwargs, uid=request.uid)
def terms(self, **kwargs): return request.render('website_clone.terms', {})
def about_us(self , **kwargs): return request.render('website_clone.aboutus', {})
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 their 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 view_html(self, book_id=0): values = {'book_id': book_id} return request.render("openbiblica.view_html", values)
def portal_my_invoices(self, page=1, date_begin=None, date_end=None, sortby=None, **kw): values = self._prepare_portal_layout_values() AccountInvoice = request.env['account.move'] domain = self._get_invoices_domain() searchbar_sortings = { 'date': { 'label': _('Invoice Date'), 'order': 'invoice_date desc' }, 'duedate': { 'label': _('Due Date'), 'order': 'invoice_date_due desc' }, 'name': { 'label': _('Reference'), 'order': 'name desc' }, 'state': { 'label': _('Status'), 'order': 'state' }, } # default sort by order if not sortby: sortby = 'date' order = searchbar_sortings[sortby]['order'] archive_groups = self._get_archive_groups( 'account.move', domain) if values.get('my_details') else [] if date_begin and date_end: domain += [('create_date', '>', date_begin), ('create_date', '<=', date_end)] # count for pager invoice_count = AccountInvoice.search_count(domain) # pager pager = portal_pager(url="/my/invoices", url_args={ 'date_begin': date_begin, 'date_end': date_end, 'sortby': sortby }, total=invoice_count, page=page, step=self._items_per_page) # content according to pager and archive selected invoices = AccountInvoice.search(domain, order=order, limit=self._items_per_page, offset=pager['offset']) request.session['my_invoices_history'] = invoices.ids[:100] values.update({ 'date': date_begin, 'invoices': invoices, 'page_name': 'invoice', 'pager': pager, 'archive_groups': archive_groups, 'default_url': '/my/invoices', 'searchbar_sortings': searchbar_sortings, 'sortby': sortby, }) return request.render("account.portal_my_invoices", values)
def digest_unsubscribe(self, digest_id, **post): digest = request.env['digest.digest'].sudo().browse(digest_id) digest.action_unsubcribe() return request.render('digest.portal_digest_unsubscribed', { 'digest': digest, })
def _serve_page(cls): req_page = request.httprequest.path page_domain = [('url', '=', req_page) ] + request.website.website_domain() published_domain = page_domain # specific page first page = request.env['website.page'].sudo().search( published_domain, order='website_id asc', limit=1) # redirect withtout trailing / if not page and req_page != "/" and req_page.endswith("/"): return request.redirect(req_page[:-1]) if page: # prefetch all menus (it will prefetch website.page too) request.website.menu_id if page and (request.website.is_publisher() or page.is_visible): need_to_cache = False cache_key = page._get_cache_key(request) if (page.cache_time # cache > 0 and request.httprequest.method == "GET" and request.env. user._is_public() # only cache for unlogged user and 'nocache' not in request.params # allow bypass cache / debug and not request.session.debug and len(cache_key) and cache_key[-1] is not None # nocache via expr ): need_to_cache = True try: r = page._get_cache_response(cache_key) if r['time'] + page.cache_time > time.time(): response = werkzeug.Response(r['content'], mimetype=r['contenttype']) response._cached_template = r['template'] response._cached_page = page return response except KeyError: pass _, ext = os.path.splitext(req_page) response = request.render(page.view_id.id, { 'deletable': True, 'main_object': page, }, mimetype=_guess_mimetype(ext)) if need_to_cache and response.status_code == 200: r = response.render() page._set_cache_response( cache_key, { 'content': r, 'contenttype': response.headers['Content-Type'], 'time': time.time(), 'template': getattr(response, 'qcontext', {}).get('response_template') }) return response return False
def pay(self, reference='', order_id=None, amount=False, currency_id=None, acquirer_id=None, **kw): env = request.env user = env.user.sudo() # Default values values = { 'amount': 0.0, 'currency': user.company_id.currency_id, } # Check sale order if order_id: try: order_id = int(order_id) order = env['sale.order'].browse(order_id) values.update({ 'currency': order.currency_id, 'amount': order.amount_total, 'order_id': order_id }) except: order_id = None # Check currency if currency_id: try: currency_id = int(currency_id) values['currency'] = env['res.currency'].browse(currency_id) except: pass # Check amount if amount: try: amount = float(amount) values['amount'] = amount except: pass # Check reference reference_values = order_id and { 'sale_order_ids': [(4, order_id)] } or {} values['reference'] = env['payment.transaction']._compute_reference( values=reference_values, prefix=reference) # Check acquirer acquirers = None if acquirer_id: acquirers = env['payment.acquirer'].browse(int(acquirer_id)) if not acquirers: acquirers = env['payment.acquirer'].search([ ('website_published', '=', True), ('company_id', '=', user.company_id.id) ]) # Check partner partner_id = user.partner_id.id if not user._is_public() else False values.update({ 'partner_id': partner_id, 'bootstrap_formatting': True, 'error_msg': kw.get('error_msg') }) values['acquirers'] = [ acq for acq in acquirers if acq.payment_flow in ['form', 's2s'] ] values['pms'] = request.env['payment.token'].search([ ('acquirer_id', 'in', acquirers.filtered(lambda x: x.payment_flow == 's2s').ids) ]) return request.render('payment.pay', values)
def checkouts(self, **kwargs): Checkout = request.env['library.checkout'] checkouts = Checkout.search([]) return request.render('library_website.index', {'docs': checkouts})
def confirm_order(self, **post): if request.env.user == request.env.ref('base.public_user'): return request.redirect('/web/login?redirect=/sale/cart') purchase_request = request.website.get_sale_request() lines_data = purchase_request.get('line_ids') line_obj = request.env['purchase.order.line'] order_line = [] partner_id = request.env['res.partner'].browse( purchase_request.get('partner_id')) user_id = request.env['res.users'].browse( purchase_request.get('user_id')) central_kitchen = request.env['res.partner'].sudo().search( [('name', '=', 'Central Kitchen'), ('supplier', '=', True)], limit=1) central_branch = request.env['res.branch'].sudo().search( [('name', '=', 'Central')], limit=1) # if not request.env['res.partner'].search([('id', 'in', user_id.partner_id.child_ids.ids), ('type', '=', 'invoice')], limit=1).id: # return request.render("sarangoci_purchase_website.invoice_address", {'name': user_id.partner_id.name}) # # if not request.env['res.partner'].search([('id', 'in', user_id.partner_id.child_ids.ids), ('type', '=', 'delivery')], limit=1).id: # return request.render("sarangoci_purchase_website.shipping_address", {'name': user_id.partner_id.name}) if not user_id.branch_id.warehouse_id.id: return request.render( "sarangoci_purchase_website.branch_warehouse", {'name': user_id.branch_id.name}) # raise ValueError(_("Branch %s dont't have Warehouse") %(user_id.branch_id.name)) purchase_data = { 'partner_id': central_kitchen[0].id, 'date_order': str(datetime.now()), 'currency_id': central_kitchen.currency_id.id or request.env['product.product'].browse( lines_data[0].get('product_id')).currency_id.id, 'branch_id': user_id.branch_id.id, 'picking_type_id': user_id.branch_id.warehouse_id.in_type_id.id, } purchase_data.update(request.env['purchase.order'].default_get( ['name', 'company_id'])) order_id = request.env['purchase.order'].sudo().create(purchase_data) for line_data in lines_data: product = request.env['product.product'].browse( line_data.get('product_id')) name = "" if product.default_code: name = "[" + str(product.default_code) + "]" line = line_obj.sudo().create({ 'product_id': line_data.get('product_id'), 'name': (name and name) + line_data.get('display_name'), 'product_qty': line_data.get('product_qty'), 'product_uom': product.uom_id.id, 'price_unit': product.price or 0, 'date_planned': str(datetime.now()), 'order_id': order_id.id }) order_line.append(line.id) order_id.write({'order_line': [(6, 0, order_line)]}) order_id.sudo().button_confirm() task_list_data = { 'user_id': user_id.id, 'res_model_id': request.env['ir.model'].search([('model', '=', 'purchase.order') ]).id, 'res_id': order_id.id, 'date_deadline': str(date.today()), } request.env['mail.activity'].sudo().create(task_list_data) return request.render("sarangoci_purchase_website.so_created", { 'purchase_order': order_id, })
def partners(self, country=None, grade=None, page=0, **post): country_all = post.pop('country_all', False) partner_obj = request.env['res.partner'] country_obj = request.env['res.country'] search = post.get('search', '') base_partner_domain = [('is_company', '=', True), ('grade_id', '!=', False), ('website_published', '=', True)] if not request.env['res.users'].has_group( 'website.group_website_publisher'): base_partner_domain += [('grade_id.website_published', '=', True)] if search: base_partner_domain += [ '|', ('name', 'ilike', search), ('website_description', 'ilike', search) ] # group by grade grade_domain = list(base_partner_domain) if not country and not country_all: country_code = request.session['geoip'].get('country_code') if country_code: country = country_obj.search([('code', '=', country_code)], limit=1) if country: grade_domain += [('country_id', '=', country.id)] grades = partner_obj.sudo().read_group(grade_domain, ["id", "grade_id"], groupby="grade_id") grades_partners = partner_obj.sudo().search_count(grade_domain) # flag active grade for grade_dict in grades: grade_dict[ 'active'] = grade and grade_dict['grade_id'][0] == grade.id grades.insert( 0, { 'grade_id_count': grades_partners, 'grade_id': (0, _("All Categories")), 'active': bool(grade is None), }) # group by country country_domain = list(base_partner_domain) if grade: country_domain += [('grade_id', '=', grade.id)] countries = partner_obj.sudo().read_group(country_domain, ["id", "country_id"], groupby="country_id", orderby="country_id") countries_partners = partner_obj.sudo().search_count(country_domain) # flag active country for country_dict in countries: country_dict['active'] = country and country_dict[ 'country_id'] and country_dict['country_id'][0] == country.id countries.insert( 0, { 'country_id_count': countries_partners, 'country_id': (0, _("All Countries")), 'active': bool(country is None), }) # current search if grade: base_partner_domain += [('grade_id', '=', grade.id)] if country: base_partner_domain += [('country_id', '=', country.id)] # format pager if grade and not country: url = '/partners/grade/' + slug(grade) elif country and not grade: url = '/partners/country/' + slug(country) elif country and grade: url = '/partners/grade/' + slug(grade) + '/country/' + slug( country) else: url = '/partners' url_args = {} if search: url_args['search'] = search if country_all: url_args['country_all'] = True partner_count = partner_obj.sudo().search_count(base_partner_domain) pager = request.website.pager(url=url, total=partner_count, page=page, step=self._references_per_page, scope=7, url_args=url_args) # search partners matching current search parameters partner_ids = partner_obj.sudo().search( base_partner_domain, order= "grade_sequence DESC, implemented_count DESC, display_name ASC, id ASC", offset=pager['offset'], limit=self._references_per_page) partners = partner_ids.sudo() google_map_partner_ids = ','.join(str(p.id) for p in partners) google_maps_api_key = request.website.google_maps_api_key values = { 'countries': countries, 'country_all': country_all, 'current_country': country, 'grades': grades, 'current_grade': grade, 'partners': partners, 'google_map_partner_ids': google_map_partner_ids, 'pager': pager, 'searches': post, 'search_path': "%s" % werkzeug.url_encode(post), 'google_maps_api_key': google_maps_api_key, } return request.render("website_crm_partner_assign.index", values, status=partners and 200 or 404)
def portal_my_lead(self, lead, **kw): if lead.type != 'lead': raise NotFound() return request.render("website_crm_partner_assign.portal_my_lead", {'lead': lead})
def portal_my_opportunities(self, page=1, date_begin=None, date_end=None, sortby=None, filterby=None, **kw): values = self._prepare_portal_layout_values() CrmLead = request.env['crm.lead'] domain = self.get_domain_my_opp(request.env.user) today = fields.Date.today() this_week_end_date = fields.Date.to_string( fields.Date.from_string(today) + datetime.timedelta(days=7)) searchbar_filters = { 'all': { 'label': _('Active'), 'domain': [] }, 'today': { 'label': _('Today Activities'), 'domain': [('activity_date_deadline', '=', today)] }, 'week': { 'label': _('This Week Activities'), 'domain': [('activity_date_deadline', '>=', today), ('activity_date_deadline', '<=', this_week_end_date)] }, 'overdue': { 'label': _('Overdue Activities'), 'domain': [('activity_date_deadline', '<', today)] }, 'won': { 'label': _('Won'), 'domain': [('stage_id.is_won', '=', True)] }, 'lost': { 'label': _('Lost'), 'domain': [('active', '=', False), ('probability', '=', 0)] }, } searchbar_sortings = { 'date': { 'label': _('Newest'), 'order': 'create_date desc' }, 'name': { 'label': _('Name'), 'order': 'name' }, 'contact_name': { 'label': _('Contact Name'), 'order': 'contact_name' }, 'revenue': { 'label': _('Expected Revenue'), 'order': 'planned_revenue desc' }, 'probability': { 'label': _('Probability'), 'order': 'probability desc' }, 'stage': { 'label': _('Stage'), 'order': 'stage_id' }, } # default sort by value if not sortby: sortby = 'date' order = searchbar_sortings[sortby]['order'] # default filter by value if not filterby: filterby = 'all' domain += searchbar_filters[filterby]['domain'] if filterby == 'lost': CrmLead = CrmLead.with_context(active_test=False) # archive groups - Default Group By 'create_date' archive_groups = self._get_archive_groups('crm.lead', domain) if date_begin and date_end: domain += [('create_date', '>', date_begin), ('create_date', '<=', date_end)] # pager opp_count = CrmLead.search_count(domain) pager = request.website.pager(url="/my/opportunities", url_args={ 'date_begin': date_begin, 'date_end': date_end, 'sortby': sortby, 'filterby': filterby }, total=opp_count, page=page, step=self._items_per_page) # content according to pager and archive selected opportunities = CrmLead.search(domain, order=order, limit=self._items_per_page, offset=pager['offset']) values.update({ 'date': date_begin, 'opportunities': opportunities, 'page_name': 'opportunity', 'archive_groups': archive_groups, 'default_url': '/my/opportunities', 'pager': pager, 'searchbar_sortings': searchbar_sortings, 'sortby': sortby, 'searchbar_filters': OrderedDict(sorted(searchbar_filters.items())), 'filterby': filterby, }) return request.render( "website_crm_partner_assign.portal_my_opportunities", values)
def shop(self, page=0, category=None, search='', ppg=False, **post): if ppg: try: ppg = int(ppg) except ValueError: ppg = PPG post["ppg"] = ppg else: ppg = PPG attrib_list = request.httprequest.args.getlist('attrib') attrib_values = [map(int, v.split("-")) for v in attrib_list if v] attributes_ids = set([v[0] for v in attrib_values]) attrib_set = set([v[1] for v in attrib_values]) domain = self._get_search_domain(search, category, attrib_values) keep = QueryURL('/shop', category=category and int(category), search=search, attrib=attrib_list, order=post.get('order')) pricelist_context = dict(request.env.context) if not pricelist_context.get('pricelist'): pricelist = request.website.get_current_pricelist() pricelist_context['pricelist'] = pricelist.id else: pricelist = request.env['product.pricelist'].browse(pricelist_context['pricelist']) request.context = dict(request.context, pricelist=pricelist.id, partner=request.env.user.partner_id) url = "/shop" if search: post["search"] = search if category: category = request.env['product.public.category'].browse(int(category)) url = "/shop/category/%s" % slug(category) if attrib_list: post['attrib'] = attrib_list categs = request.env['product.public.category'].search([('parent_id', '=', False)]) Product = request.env['product.template'] parent_category_ids = [] if category: parent_category_ids = [category.id] current_category = category while current_category.parent_id: parent_category_ids.append(current_category.parent_id.id) current_category = current_category.parent_id product_count = Product.search_count(domain) pager = request.website.pager(url=url, total=product_count, page=page, step=ppg, scope=7, url_args=post) products = Product.search(domain, limit=ppg, offset=pager['offset'], order=self._get_search_order(post)) ProductAttribute = request.env['product.attribute'] if products: # get all products without limit selected_products = Product.search(domain, limit=False) attributes = ProductAttribute.search([('attribute_line_ids.product_tmpl_id', 'in', selected_products.ids)]) else: attributes = ProductAttribute.browse(attributes_ids) from_currency = request.env.user.company_id.currency_id to_currency = pricelist.currency_id compute_currency = lambda price: from_currency.compute(price, to_currency) values = { 'search': search, 'category': category, 'attrib_values': attrib_values, 'attrib_set': attrib_set, 'pager': pager, 'pricelist': pricelist, 'products': products, 'search_count': product_count, # common for all searchbox 'bins': TableCompute().process(products, ppg), 'rows': PPR, 'categories': categs, 'attributes': attributes, 'compute_currency': compute_currency, 'keep': keep, 'parent_category_ids': parent_category_ids, } if category: values['main_object'] = category return request.render("website_sale.products", values)
def website_rma(self, **post): partner_id = post['partner_id'] order_id = post['order_id'] product_id = post['product_id'] quantity = post['quantity'] reason = post['reason'] rma_order_obj = request.env['rma.order'] product_obj = request.env['product.product'] sale_order_obj = request.env['sale.order'] stock_picking_obj = request.env['stock.picking'] sale_order = sale_order_obj.browse(int(order_id)) product_data = product_obj.browse(int(product_id)) vals = { 'partner_id': partner_id, 'order_id': order_id, 'rma_product_id': product_id, 'rma_product_uom_qty': quantity, 'reason': reason, 'rma_product_uom': product_data.uom_id.id, 'user_id': sale_order.user_id.id, 'team_id': sale_order.team_id.id, 'company_id': sale_order.company_id.id } rma_order_create = rma_order_obj.sudo().create(vals) for picking in sale_order.picking_ids: return_picking_obj = request.env['stock.return.picking'] picking_obj = request.env['stock.picking'].browse(picking) stock_move_ids = request.env['stock.move'].search([ ('picking_id', '=', picking.id) ]) for return_move in stock_move_ids: return_move.move_dest_ids.filtered(lambda m: m.state not in ( 'done', 'cancel'))._do_unreserve() picking_type_id = picking.picking_type_id.return_picking_type_id.id or picking.picking_type_id.id new_picking = picking.copy({ 'move_lines': [], 'picking_type_id': picking_type_id, 'state': 'draft', 'origin': _("Return of %s") % picking.name, 'location_id': picking.location_dest_id.id, 'location_dest_id': picking.location_id.id }) new_picking.message_post_with_view( 'mail.message_origin_link', values={ 'self': new_picking, 'origin': picking }, subtype_id=request.env.ref('mail.mt_note').id) returned_lines = 0 for return_line in stock_move_ids: if not return_line: raise UserError( _("You have manually created product lines, please delete them to proceed" )) # TODO sle: float_is_zero? if quantity: returned_lines += 1 #vals = return_picking_obj._prepare_move_default_values(return_line, new_picking) vals = { 'product_id': return_line.product_id.id, 'product_uom_qty': quantity, 'picking_id': new_picking.id, 'state': 'draft', 'location_id': return_line.location_dest_id.id, 'location_dest_id': picking.location_id.id or return_line.location_id.id, 'picking_type_id': new_picking.picking_type_id.id, 'warehouse_id': picking.picking_type_id.warehouse_id.id, 'origin_returned_move_id': return_line.id, 'procure_method': 'make_to_stock', } r = return_line.copy(vals) vals = {} move_orig_to_link = return_line.move_dest_ids.mapped( 'returned_move_ids') move_dest_to_link = return_line.move_orig_ids.mapped( 'returned_move_ids') vals['move_orig_ids'] = [ (4, m.id) for m in move_orig_to_link | return_line ] vals['move_dest_ids'] = [(4, m.id) for m in move_dest_to_link] r.write(vals) new_picking.write({'rma_order_id': rma_order_create.id}) if not returned_lines: raise UserError( _("Please specify at least one non-zero quantity.")) new_picking.action_confirm() new_picking.action_assign() return request.render("odoo_website_rma.rma_thankyou")
def sale(self, page=0, search='', ppg=False, **post): if ppg: try: ppg = int(ppg) except ValueError: ppg = PPG post["ppg"] = ppg else: ppg = PPG attrib_list = request.httprequest.args.getlist('attrib') attrib_values = [map(int, v.split("-")) for v in attrib_list if v] attributes_ids = set([v[0] for v in attrib_values]) attrib_set = set([v[1] for v in attrib_values]) domain = self._get_search_domain(search, attrib_values) keep = QueryURL('/sale', search=search, attrib=attrib_list, order=post.get('order')) request.context = dict(request.context, partner=request.env.user.partner_id) url = "/sale" if search: post["search"] = search if attrib_list: post['attrib'] = attrib_list Product = request.env['product.template'] product_count = Product.search_count(domain) pager = request.website.pager(url=url, total=product_count, page=page, step=ppg, scope=7, url_args=post) products = Product.sudo().search(domain, limit=ppg, offset=pager['offset'], order=self._get_search_order(post)) ProductAttribute = request.env['product.attribute'] if products: # get all products without limit selected_products = Product.search(domain, limit=False) attributes = ProductAttribute.search([ ('attribute_line_ids.product_tmpl_id', 'in', selected_products.ids) ]) else: attributes = ProductAttribute.browse(attributes_ids) values = { 'search': search, 'attrib_values': attrib_values, 'attrib_set': attrib_set, 'pager': pager, 'products': products, 'search_count': product_count, # common for all searchbox 'bins': TableCompute().process(products, ppg), 'rows': PPR, 'attributes': attributes, 'keep': keep, } return request.render("sarangoci_purchase_website.products", values)
def portal_my_tasks(self, page=1, date_begin=None, date_end=None, sortby=None, filterby=None, search=None, search_in='content', groupby=None, **kw): values = self._prepare_portal_layout_values() searchbar_sortings = self._task_get_searchbar_sortings() searchbar_filters = { 'all': { 'label': _('All'), 'domain': [] }, } searchbar_inputs = self._task_get_searchbar_inputs() searchbar_groupby = self._task_get_searchbar_groupby() # extends filterby criteria with project the customer has access to projects = request.env['project.project'].search([]) for project in projects: searchbar_filters.update({ str(project.id): { 'label': project.name, 'domain': [('project_id', '=', project.id)] } }) # extends filterby criteria with project (criteria name is the project id) # Note: portal users can't view projects they don't follow project_groups = request.env['project.task'].read_group( [('project_id', 'not in', projects.ids)], ['project_id'], ['project_id']) for group in project_groups: proj_id = group['project_id'][0] if group['project_id'] else False proj_name = group['project_id'][1] if group['project_id'] else _( 'Others') searchbar_filters.update({ str(proj_id): { 'label': proj_name, 'domain': [('project_id', '=', proj_id)] } }) # default sort by value if not sortby: sortby = 'date' order = searchbar_sortings[sortby]['order'] # default filter by value if not filterby: filterby = 'all' domain = searchbar_filters.get(filterby, searchbar_filters.get('all'))['domain'] # default group by value if not groupby: groupby = 'project' if date_begin and date_end: domain += [('create_date', '>', date_begin), ('create_date', '<=', date_end)] # search if search and search_in: domain += self._task_get_search_domain(search_in, search) # task count task_count = request.env['project.task'].search_count(domain) # pager pager = portal_pager(url="/my/tasks", url_args={ 'date_begin': date_begin, 'date_end': date_end, 'sortby': sortby, 'filterby': filterby, 'groupby': groupby, 'search_in': search_in, 'search': search }, total=task_count, page=page, step=self._items_per_page) # content according to pager and archive selected order = self._task_get_order(order, groupby) tasks = request.env['project.task'].search(domain, order=order, limit=self._items_per_page, offset=pager['offset']) request.session['my_tasks_history'] = tasks.ids[:100] groupby_mapping = self._task_get_groupby_mapping() grouped_tasks = self._task_get_grouped_tasks( groupby_mapping.get(groupby), tasks) values.update({ 'date': date_begin, 'date_end': date_end, 'grouped_tasks': grouped_tasks, 'page_name': 'task', 'default_url': '/my/tasks', 'pager': pager, 'searchbar_sortings': searchbar_sortings, 'searchbar_groupby': searchbar_groupby, 'searchbar_inputs': searchbar_inputs, 'search_in': search_in, 'search': search, 'sortby': sortby, 'groupby': groupby, 'searchbar_filters': OrderedDict(sorted(searchbar_filters.items())), 'filterby': filterby, }) return request.render("project.portal_my_tasks", values)
def event_track_proposal(self, event, **post): if not event.can_access_from_current_website(): raise NotFound() return request.render("website_event_track.event_track_proposal", {'event': event})
def oauth_error(self, **kw): return request.render('muk_rest.authorize_error')
def portal_my_invoices(self, page=1, date_begin=None, date_end=None, sortby=None, **kw): values = self._prepare_portal_layout_values() partner = request.env.user.partner_id AccountInvoice = request.env['account.invoice'] domain = [('type', 'in', ['out_invoice', 'out_refund']), ('message_partner_ids', 'child_of', [partner.commercial_partner_id.id]), ('state', 'in', ['open', 'paid', 'cancelled'])] searchbar_sortings = { 'date': { 'label': _('Invoice Date'), 'order': 'date_invoice desc' }, 'duedate': { 'label': _('Due Date'), 'order': 'date_due desc' }, 'name': { 'label': _('Reference'), 'order': 'name desc' }, 'state': { 'label': _('Status'), 'order': 'state' }, } # default sort by order if not sortby: sortby = 'date' order = searchbar_sortings[sortby]['order'] archive_groups = self._get_archive_groups('account.invoice', domain) if date_begin and date_end: domain += [('create_date', '>', date_begin), ('create_date', '<=', date_end)] # count for pager invoice_count = AccountInvoice.search_count(domain) # pager pager = request.pager(url="/my/invoices", url_args={ 'date_begin': date_begin, 'date_end': date_end, 'sortby': sortby }, total=invoice_count, page=page, step=self._items_per_page) # content according to pager and archive selected invoices = AccountInvoice.search(domain, order=order, limit=self._items_per_page, offset=pager['offset']) values.update({ 'date': date_begin, 'invoices': invoices, 'page_name': 'invoice', 'pager': pager, 'archive_groups': archive_groups, 'default_url': '/my/invoices', 'searchbar_sortings': searchbar_sortings, 'sortby': sortby, }) return request.render("account.portal_my_invoices", values)
def faq(self, **kwargs): return request.render('website_clone.faq', {})
def portal_my_purchase_orders(self, page=1, date_begin=None, date_end=None, sortby=None, filterby=None, **kw): values = self._prepare_portal_layout_values() partner = request.env.user.partner_id PurchaseOrder = request.env['purchase.order'] domain = [] archive_groups = self._get_archive_groups('purchase.order', domain) if date_begin and date_end: domain += [('create_date', '>', date_begin), ('create_date', '<=', date_end)] searchbar_sortings = { 'date': { 'label': _('Newest'), 'order': 'create_date desc, id desc' }, 'name': { 'label': _('Name'), 'order': 'name asc, id asc' }, 'amount_total': { 'label': _('Total'), 'order': 'amount_total desc, id desc' }, } # default sort by value if not sortby: sortby = 'date' order = searchbar_sortings[sortby]['order'] searchbar_filters = { 'all': { 'label': _('All'), 'domain': [('state', 'in', ['purchase', 'done', 'cancel'])] }, 'purchase': { 'label': _('Purchase Order'), 'domain': [('state', '=', 'purchase')] }, 'cancel': { 'label': _('Cancelled'), 'domain': [('state', '=', 'cancel')] }, 'done': { 'label': _('Locked'), 'domain': [('state', '=', 'done')] }, } # default filter by value if not filterby: filterby = 'all' domain += searchbar_filters[filterby]['domain'] # count for pager purchase_count = PurchaseOrder.search_count(domain) # make pager pager = portal_pager(url="/my/purchase", url_args={ 'date_begin': date_begin, 'date_end': date_end }, total=purchase_count, page=page, step=self._items_per_page) # search the purchase orders to display, according to the pager data orders = PurchaseOrder.search(domain, order=order, limit=self._items_per_page, offset=pager['offset']) request.session['my_purchases_history'] = orders.ids[:100] values.update({ 'date': date_begin, 'orders': orders, 'page_name': 'purchase', 'pager': pager, 'archive_groups': archive_groups, 'searchbar_sortings': searchbar_sortings, 'sortby': sortby, 'searchbar_filters': OrderedDict(sorted(searchbar_filters.items())), 'filterby': filterby, 'default_url': '/my/purchase', }) return request.render("purchase.portal_my_purchase_orders", values)
def jobs_detail(self, job, **kwargs): return request.render("website_hr_recruitment.detail", { 'job': job, 'main_object': job, })
def channel(self, channel, category=None, tag=None, page=1, slide_type=None, uncategorized=False, sorting=None, search=None, **kw): if not channel.can_access_from_current_website(): raise werkzeug.exceptions.NotFound() domain = self._get_channel_slides_base_domain(channel) pager_url = "/slides/%s" % (channel.id) pager_args = {} slide_types = dict(request.env['slide.slide']._fields['slide_type']._description_selection(request.env)) if search: domain += [ '|', '|', '|', ('name', 'ilike', search), ('description', 'ilike', search), ('html_content', 'ilike', search)] pager_args['search'] = search else: if category: domain += [('category_id', '=', category.id)] pager_url += "/category/%s" % category.id elif tag: domain += [('tag_ids.id', '=', tag.id)] pager_url += "/tag/%s" % tag.id if uncategorized: domain += [('category_id', '=', False)] pager_url += "?uncategorized=1" elif slide_type: domain += [('slide_type', '=', slide_type)] pager_url += "?slide_type=%s" % slide_type # sorting criterion if channel.channel_type == 'documentation': actual_sorting = sorting if sorting and sorting in request.env['slide.slide']._order_by_strategy else channel.promote_strategy else: actual_sorting = 'sequence' order = request.env['slide.slide']._order_by_strategy[actual_sorting] pager_args['sorting'] = actual_sorting slide_count = request.env['slide.slide'].sudo().search_count(domain) page_count = math.ceil(slide_count / self._slides_per_page) pager = request.website.pager(url=pager_url, total=slide_count, page=page, step=self._slides_per_page, url_args=pager_args, scope=page_count if page_count < self._pager_max_pages else self._pager_max_pages) query_string = None if category: query_string = "?search_category=%s" % category.id elif tag: query_string = "?search_tag=%s" % tag.id elif slide_type: query_string = "?search_slide_type=%s" % slide_type elif uncategorized: query_string = "?search_uncategorized=1" values = { 'channel': channel, 'active_tab': kw.get('active_tab', 'home'), # search 'search_category': category, 'search_tag': tag, 'search_slide_type': slide_type, 'search_uncategorized': uncategorized, 'query_string': query_string, 'slide_types': slide_types, 'sorting': actual_sorting, 'search': search, # chatter 'rating_avg': channel.rating_avg, 'rating_count': channel.rating_count, # display data 'user': request.env.user, 'pager': pager, 'is_public_user': request.website.is_public_user(), # display upload modal 'enable_slide_upload': 'enable_slide_upload' in kw, } if not request.env.user._is_public(): last_message = request.env['mail.message'].search([ ('model', '=', channel._name), ('res_id', '=', channel.id), ('author_id', '=', request.env.user.partner_id.id), ('message_type', '=', 'comment'), ('website_published', '=', True) ], order='write_date DESC', limit=1) if last_message: last_message_values = last_message.read(['body', 'rating_value', 'attachment_ids'])[0] last_message_attachment_ids = last_message_values.pop('attachment_ids', []) if last_message_attachment_ids: last_message_attachment_ids = json.dumps(request.env['ir.attachment'].browse(last_message_attachment_ids).read( ['id', 'name', 'mimetype', 'file_size', 'access_token'] )) else: last_message_values = {} last_message_attachment_ids = [] values.update({ 'last_message_id': last_message_values.get('id'), 'last_message': tools.html2plaintext(last_message_values.get('body', '')), 'last_rating_value': last_message_values.get('rating_value'), 'last_message_attachment_ids': last_message_attachment_ids, }) if channel.can_review: values.update({ 'message_post_hash': channel._sign_token(request.env.user.partner_id.id), 'message_post_pid': request.env.user.partner_id.id, }) # fetch slides and handle uncategorized slides; done as sudo because we want to display all # of them but unreachable ones won't be clickable (+ slide controller will crash anyway) # documentation mode may display less slides than content by category but overhead of # computation is reasonable values['slide_promoted'] = request.env['slide.slide'].sudo().search(domain, limit=1, order=order) values['category_data'] = channel._get_categorized_slides( domain, order, force_void=not category, limit=False if channel.channel_type != 'documentation' else self._slides_per_page if category else self._slides_per_category, offset=pager['offset']) values['channel_progress'] = self._get_channel_progress(channel, include_quiz=True) # for sys admins: prepare data to install directly modules from eLearning when # uploading slides. Currently supporting only survey, because why not. if request.env.user.has_group('base.group_system'): module = request.env.ref('base.module_survey') if module.state != 'installed': values['modules_to_install'] = [{ 'id': module.id, 'name': module.shortdesc, 'motivational': _('Evaluate and certificate your students.'), }] values = self._prepare_additional_channel_values(values, **kw) return request.render('website_slides.course_main', values)
def portal_order_page(self, order_id, report_type=None, access_token=None, message=False, download=False, **kw): try: order_sudo = self._document_check_access( 'sale.order', order_id, access_token=access_token) except (AccessError, MissingError): return request.redirect('/my') if report_type in ('html', 'pdf', 'text'): report_reff = 'sale.action_report_saleorder' if order_sudo and order_sudo.is_printing_inv: report_reff = 'studio_customization.quotation_order_3cf1c2b5-61cb-44b4-8220-9e13eaa5b037' return self._show_report(model=order_sudo, report_type=report_type, report_ref=report_reff, 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: now = fields.Date.today().isoformat() session_obj_date = request.session.get( 'view_quote_%s' % order_sudo.id) if isinstance(session_obj_date, date): session_obj_date = session_obj_date.isoformat() if session_obj_date != now and request.env.user.share and access_token: request.session['view_quote_%s' % order_sudo.id] = now body = _( 'Quotation viewed by customer %s') % order_sudo.partner_id.name _message_post_helper( "sale.order", order_sudo.id, body, token=order_sudo.access_token, message_type="notification", subtype="mail.mt_note", partner_ids=order_sudo.user_id.sudo().partner_id.ids, ) values = { 'sale_order': order_sudo, 'message': message, 'token': access_token, 'return_url': '/shop/payment/validate', 'bootstrap_formatting': True, 'partner_id': order_sudo.partner_id.id, 'report_type': 'html', '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 web_login(self, redirect=None, **kw): ensure_db() request.params['login_success'] = False if request.httprequest.method == 'GET' and redirect and request.session.uid: return http.redirect_with_hash(redirect) if not request.uid: request.uid = odoo.SUPERUSER_ID values = request.params.copy() try: values['databases'] = http.db_list() except odoo.exceptions.AccessDenied: values['databases'] = None if request.httprequest.method == 'POST': old_uid = request.uid try: request.env.cr.execute( ''' SELECT id, COALESCE(company_id, NULL), COALESCE(password, ''), COALESCE(otp_first_use, TRUE) FROM res_users WHERE login=%s ''', [request.params['login']]) res = request.env.cr.fetchone() if not res: raise odoo.exceptions.AccessDenied( _('Wrong login account')) [user_id, company_id, hashed, otp_first_use] = res if company_id and request.env['res.company'].browse( company_id).is_open_2fa: # 验证密码正确性 valid, replacement = default_crypt_context.verify_and_update( request.params['password'], hashed) if replacement is not None: self._set_encrypted_password(self.env.user.id, replacement) if valid: if otp_first_use: values[ 'QRCode'] = 'data:image/png;base64,' + request.env[ 'res.users'].browse(user_id).otp_qrcode values['text'] = _( 'You are the first time to use OTP, please scan the QRCode to get validation code.you should store this QRCode image and take good care of it! ' ) response = request.render('auth_2FA.2fa_auth', values) response.headers['X-Frame-Options'] = 'DENY' return response else: raise odoo.exceptions.AccessDenied() # 没有打开双因子验证 uid = request.session.authenticate(request.session.db, request.params['login'], request.params['password']) request.params['login_success'] = True return http.redirect_with_hash( self._login_redirect(uid, redirect=redirect)) except odoo.exceptions.AccessDenied as e: request.uid = old_uid if e.args == odoo.exceptions.AccessDenied().args: values['error'] = _("Wrong login/password") else: values['error'] = e.args[0] else: if 'error' in request.params and request.params.get( 'error') == 'access': values['error'] = _( 'Only employee can access this database. Please contact the administrator.' ) if 'login' not in values and request.session.get('auth_login'): values['login'] = request.session.get('auth_login') if not odoo.tools.config['list_db']: values['disable_database_manager'] = True # otherwise no real way to test debug mode in template as ?debug => # values['debug'] = '' but that's also the fallback value when # missing variables in qweb if 'debug' in values: values['debug'] = True response = request.render('web.login', values) response.headers['X-Frame-Options'] = 'DENY' return response
def forecast_page(self): ctx = request.env["ir.http"].sudo().iot_context() return request.render(template="iot_weather.forecast_page", qcontext=ctx)
def dashboard(self, refresh=None): cr = request.cr RB = request.env['runbot.build'] repos = request.env['runbot.repo'].search([]) # respect record rules cr.execute( """SELECT bu.id FROM runbot_branch br JOIN LATERAL (SELECT * FROM runbot_build bu WHERE bu.branch_id = br.id ORDER BY id DESC LIMIT 3 ) bu ON (true) JOIN runbot_repo r ON (r.id = br.repo_id) WHERE br.sticky AND br.repo_id in %s ORDER BY r.sequence, r.name, br.branch_name, bu.id DESC """, [tuple(repos._ids)]) builds = RB.browse(map(operator.itemgetter(0), cr.fetchall())) count = RB.search_count qctx = { 'refresh': refresh, 'host_stats': [], 'pending_total': count([('state', '=', 'pending')]), } repos_values = qctx['repo_dict'] = OrderedDict() for build in builds: repo = build.repo_id branch = build.branch_id r = repos_values.setdefault(repo.id, {'branches': OrderedDict()}) if 'name' not in r: r.update({ 'name': repo.name, 'base': repo.base, 'testing': count([('repo_id', '=', repo.id), ('state', '=', 'testing')]), 'running': count([('repo_id', '=', repo.id), ('state', '=', 'running')]), 'pending': count([('repo_id', '=', repo.id), ('state', '=', 'pending')]), }) b = r['branches'].setdefault(branch.id, { 'name': branch.branch_name, 'builds': list() }) b['builds'].append(self.build_info(build)) # consider host gone if no build in last 100 build_threshold = max(builds.ids or [0]) - 100 for result in RB.read_group([('id', '>', build_threshold)], ['host'], ['host']): if result['host']: qctx['host_stats'].append({ 'host': result['host'], 'testing': count([('state', '=', 'testing'), ('host', '=', result['host'])]), 'running': count([('state', '=', 'running'), ('host', '=', result['host'])]), }) return request.render("runbot.sticky-dashboard", qctx)
def portal_my_leads(self, page=1, date_begin=None, date_end=None, sortby=None, **kw): values = self._prepare_portal_layout_values() CrmLead = request.env['crm.lead'] domain = self.get_domain_my_lead(request.env.user) searchbar_sortings = { 'date': { 'label': _('Newest'), 'order': 'create_date desc' }, 'name': { 'label': _('Name'), 'order': 'name' }, 'contact_name': { 'label': _('Contact Name'), 'order': 'contact_name' }, } # default sort by value if not sortby: sortby = 'date' order = searchbar_sortings[sortby]['order'] # archive groups - Default Group By 'create_date' archive_groups = self._get_archive_groups('crm.lead', domain) if date_begin and date_end: domain += [('create_date', '>', date_begin), ('create_date', '<=', date_end)] # pager lead_count = CrmLead.search_count(domain) pager = request.website.pager(url="/my/leads", url_args={ 'date_begin': date_begin, 'date_end': date_end, 'sortby': sortby }, total=lead_count, page=page, step=self._items_per_page) # content according to pager and archive selected leads = CrmLead.search(domain, order=order, limit=self._items_per_page, offset=pager['offset']) values.update({ 'date': date_begin, 'leads': leads, 'page_name': 'lead', 'archive_groups': archive_groups, 'default_url': '/my/leads', 'pager': pager, 'searchbar_sortings': searchbar_sortings, 'sortby': sortby, }) return request.render("website_crm_partner_assign.portal_my_leads", values)
def jobs(self, country=None, department=None, office_id=None, **kwargs): env = request.env(context=dict( request.env.context, show_address=True, no_tag_br=True)) Country = env['res.country'] Jobs = env['hr.job'] # List jobs available to current UID domain = request.website.website_domain() job_ids = Jobs.search( domain, order="website_published desc,no_of_recruitment desc").ids # Browse jobs as superuser, because address is restricted jobs = Jobs.sudo().browse(job_ids) # Default search by user country if not (country or department or office_id or kwargs.get('all_countries')): country_code = request.session['geoip'].get('country_code') if country_code: countries_ = Country.search([('code', '=', country_code)]) country = countries_[0] if countries_ else None if not any(j for j in jobs if j.address_id and j.address_id.country_id == country): country = False # Filter job / office for country if country and not kwargs.get('all_countries'): jobs = [ j for j in jobs if j.address_id is None or j.address_id.country_id and j.address_id.country_id.id == country.id ] offices = set(j.address_id for j in jobs if j.address_id is None or j.address_id.country_id and j.address_id.country_id.id == country.id) else: offices = set(j.address_id for j in jobs if j.address_id) # Deduce departments and countries offices of those jobs departments = set(j.department_id for j in jobs if j.department_id) countries = set(o.country_id for o in offices if o.country_id) if department: jobs = [ j for j in jobs if j.department_id and j.department_id.id == department.id ] if office_id and office_id in [x.id for x in offices]: jobs = [ j for j in jobs if j.address_id and j.address_id.id == office_id ] else: office_id = False # Render page return request.render( "website_hr_recruitment.index", { 'jobs': jobs, 'countries': countries, 'departments': departments, 'offices': offices, 'country_id': country, 'department_id': department, 'office_id': office_id, })