def checkout(self): '''Submit of default checkout A GET to the method will result in passing of control to begin as that is basically the entry point to the checkout A POST to the method will result in the confirmation of the order and subsequent handling of data. ''' cart_obj = Pool().get('nereid.cart') sale_obj = Pool().get('sale.sale') cart = cart_obj.open_cart() if not cart.sale: # This case is possible if the user changes his currency at # the point of checkout and the cart gets cleared. return redirect(url_for('nereid.cart.view_cart')) sale = cart.sale if not sale.lines: flash(_("Add some items to your cart before you checkout!")) return redirect(url_for('nereid.website.home')) if request.method == 'GET': return (self._begin_guest() if request.is_guest_user \ else self._begin_registered()) elif request.method == 'POST': form, do_process = self._submit_guest() if request.is_guest_user \ else self._submit_registered() if do_process: # Process Shipping self._process_shipment(sale, form) # Process Payment, if the returned value from the payment # is a response object (isinstance) then return that instead # of the success page. This will allow reidrects to a third # party gateway or service to collect payment. response = self._process_payment(sale, form) if isinstance(response, BaseResponse): return response if sale.state == 'draft': # Ensure that the order date is that of today cart_obj.check_update_date(cart) # Confirm the order sale_obj.quote([sale.id]) sale_obj.confirm([sale.id]) flash(_("Your order #%(sale)s has been processed", sale=sale.reference)) if request.is_guest_user: return redirect(url_for('nereid.website.home')) else: return redirect( url_for( 'sale.sale.render', sale=sale.id, confirmation=True ) ) return render_template('checkout.jinja', form=form, cart=cart)
def facebook_authorized_login(self): """Authorized handler to which facebook will redirect the user to after the login attempt is made. """ website_obj = Pool().get('nereid.website') facebook = website_obj.get_facebook_oauth_client() if facebook is None: return redirect( request.referrer or url_for('nereid.website.login') ) try: if 'oauth_verifier' in request.args: data = facebook.handle_oauth1_response() elif 'code' in request.args: data = facebook.handle_oauth2_response() else: data = facebook.handle_unknown_response() facebook.free_request_token() except Exception, exc: current_app.logger.error("Facebook login failed", exc) flash(_("We cannot talk to facebook at this time. Please try again")) return redirect( request.referrer or url_for('nereid.website.login') )
def add_to_cart(cls): """ Adds the given item to the cart if it exists or to a new cart The form is expected to have the following data is post quantity : decimal product : integer ID action : set (default), add Response: 'OK' if X-HTTPRequest Redirect to shopping cart if normal request """ form = AddtoCartForm(request.form) if request.method == 'POST' and form.validate(): cart = cls.open_cart(create_order=True) action = request.values.get('action', 'set') if form.quantity.data <= 0: flash( _('Be sensible! You can only add real quantities to cart') ) return redirect(url_for('nereid.cart.view_cart')) cls._add_or_update( cart.sale.id, form.product.data, form.quantity.data, action ) if action == 'add': flash(_('The product has been added to your cart'), 'info') else: flash(_('Your cart has been updated with the product'), 'info') if request.is_xhr: return jsonify(message='OK') return redirect(url_for('nereid.cart.view_cart'))
def github_authorized_login(cls): """ Authorized handler to which github will redirect the user to after the login attempt is made. """ github = request.nereid_website.get_github_oauth_client() if github is None: return redirect( request.referrer or url_for('nereid.website.login') ) try: # The response is an oauth2 response with code. But Github API # requires the if 'oauth_verifier' in request.args: data = github.handle_oauth1_response() elif 'code' in request.args: data = github.handle_oauth2_response() else: data = github.handle_unknown_response() github.free_request_token() except Exception, exc: current_app.logger.error("Github login failed %s" % exc) flash(_("We cannot talk to github at this time. Please try again")) return redirect( request.referrer or url_for('nereid.website.login') )
def linkedin_authorized_login(cls): """Authorized handler to which linkedin will redirect the user to after the login attempt is made. """ Party = Pool().get('party.party') linkedin = request.nereid_website.get_linkedin_oauth_client() if linkedin is None: return redirect( request.referrer or url_for('nereid.website.login') ) try: if 'oauth_verifier' in request.args: data = linkedin.handle_oauth1_response() elif 'code' in request.args: data = linkedin.handle_oauth2_response() else: data = linkedin.handle_unknown_response() linkedin.free_request_token() except Exception, exc: current_app.logger.error("LinkedIn login failed %s" % exc) flash(_( "We cannot talk to linkedin at this time. Please try again" )) return redirect( request.referrer or url_for('nereid.website.login') )
def render_comments(self): """ Render comments GET: Return json of all the comments of this post. POST: Create new comment for this post. """ if self.state != 'Published': abort(404) # Add re_captcha if the configuration has such an option and user # is guest if 're_captcha_public' in CONFIG.options and request.is_guest_user: comment_form = GuestCommentForm( request.form, captcha={'ip_address': request.remote_addr} ) else: comment_form = PostCommentForm(request.form) if request.method == 'GET': if self.nereid_user == request.nereid_user: return jsonify(comments=[ comment.serialize() for comment in self.comments ]) return jsonify(comments=[ comment.serialize() for comment in self.comments if not comment.is_spam ]) # If post does not allow guest comments, # then dont allow guest user to comment if not self.allow_guest_comments and request.is_guest_user: flash('Guests are not allowed to write comments') if request.is_xhr: return jsonify( success=False, errors=['Guests are not allowed to write comments'] ) return redirect(url_for( 'blog.post.render', user_id=self.nereid_user.id, uri=self.uri )) if request.method == 'POST' and comment_form.validate(): self.write([self], { 'comments': [('create', [{ 'nereid_user': current_user.id if not current_user.is_anonymous() else None, 'name': current_user.display_name if not current_user.is_anonymous() else comment_form.name.data, 'content': comment_form.content.data, }])] }) if request.is_xhr: return jsonify(success=True) if comment_form.validate() \ else jsonify(success=False, errors=comment_form.errors) return redirect(url_for( 'blog.post.render', user_id=self.nereid_user.id, uri=self.uri ))
def verify_email(self, sign, max_age=24 * 60 * 60): """ Verifies the email and redirects to home page. This is a method in addition to the activate method which activates the account in addition to verifying the email. """ try: unsigned = self._serializer.loads( self._signer.unsign(sign, max_age=max_age), salt='verification' ) except SignatureExpired: return self.build_response( 'The verification link has expired', redirect(url_for('nereid.website.home')), 400 ) except BadSignature: return self.build_response( 'The verification token is invalid!', redirect(url_for('nereid.website.home')), 400 ) else: if self.id == unsigned: self.email_verified = True self.save() return self.build_response( 'Your email has been verified!', redirect(url_for('nereid.website.home')), 200 ) else: return self.build_response( 'The verification token is invalid!', redirect(url_for('nereid.website.home')), 400 )
def add_to_cart(cls): """ Adds the given item to the cart if it exists or to a new cart The form is expected to have the following data is post quantity : decimal product : integer ID action : set (default), add Response: 'OK' if X-HTTPRequest Redirect to shopping cart if normal request """ Product = Pool().get('product.product') form = AddtoCartForm() if form.validate_on_submit(): cart = cls.open_cart(create_order=True) action = request.values.get('action', 'set') if form.quantity.data <= 0: message = _( 'Be sensible! You can only add real quantities to cart') if request.is_xhr: return jsonify(message=unicode(message)), 400 flash(message) return redirect(url_for('nereid.cart.view_cart')) if not Product(form.product.data).template.salable: message = _("This product is not for sale") if request.is_xhr: return jsonify(message=unicode(message)), 400 flash(message) return redirect(request.referrer) sale_line = cart.sale._add_or_update( form.product.data, form.quantity.data, action ) # Validate that product availability in inventory is not less than # warehouse quantity sale_line.validate_for_product_inventory() sale_line.save() if action == 'add': message = _('The product has been added to your cart') else: message = _('Your cart has been updated with the product') if request.is_xhr: return jsonify( message=unicode(message), line=sale_line.serialize(purpose='cart') ), 200 flash(message, 'info') return redirect(url_for('nereid.cart.view_cart'))
def linkedin_login(cls): """The URL to which a new request to authenticate to linedin begins Usually issues a redirect. """ linkedin = request.nereid_website.get_linkedin_oauth_client() if linkedin is None: return redirect(request.referrer or url_for("nereid.website.login")) return linkedin.authorize( callback=url_for( "nereid.user.linkedin_authorized_login", next=request.args.get("next") or request.referrer or None, _external=True, ) )
def facebook_login(cls): """The URL to which a new request to authenticate to facebook begins Usually issues a redirect. """ facebook = request.nereid_website.get_facebook_oauth_client() if facebook is None: return redirect(request.referrer or url_for("nereid.website.login")) return facebook.authorize( callback=url_for( "nereid.user.facebook_authorized_login", next=request.args.get("next") or request.referrer or None, _external=True, ) )
def github_login(cls): """The URL to which a new request to authenticate to github begins Usually issues a redirect. """ github = request.nereid_website.get_github_oauth_client() if github is None: return redirect( request.referrer or url_for('nereid.website.login') ) return github.authorize( callback = url_for('nereid.user.github_authorized_login', next = request.args.get('next') or request.referrer or None, _external = True ) )
def new_password(self): """Create a new password .. tip:: Unlike change password this does not demand the old password. And hence this method will check in the session for a parameter called allow_new_password which has to be True. This acts as a security against attempts to POST to this method and changing password. The allow_new_password flag is popped on successful saving This is intended to be used when a user requests for a password reset. """ form = NewPasswordForm(request.form) if request.method == "POST" and form.validate(): if not session.get("allow_new_password", False): current_app.logger.debug("New password not allowed in session") abort(403) self.write(request.nereid_user.id, {"password": form.password.data}) session.pop("allow_new_password") flash(_("Your password has been successfully changed! " "Please login again")) session.pop("user") return redirect(url_for("nereid.website.login")) return render_template("new-password.jinja", password_form=form)
def delete_from_cart(cls, line): """ Delete a line from the cart. The required argument in POST is: line_id : ID of the line Response: 'OK' if X-HTTPRequest else redirect to shopping cart """ SaleLine = Pool().get('sale.line') cart = cls.open_cart() if not cart.sale: abort(404) try: sale_line, = SaleLine.search([ ('id', '=', line), ('sale', '=', cart.sale.id), ]) except ValueError: message = 'Looks like the item is already deleted.' else: SaleLine.delete([sale_line]) message = 'The order item has been successfully removed.' flash(_(message)) if request.is_xhr: return jsonify(message=message) return redirect(url_for('nereid.cart.view_cart'))
def serialize(self, purpose=None): ''' Serialize timesheet line and returns a dictionary. ''' nereid_user_obj = Pool().get('nereid.user') try: nereid_user, = nereid_user_obj.search([ ('employee', '=', self.employee.id) ], limit=1) except ValueError: nereid_user = {} else: nereid_user = nereid_user.serialize('listing') # Render url for timesheet line is task on which this time is marked return { 'create_date': self.create_date.isoformat(), "url": url_for( 'project.work.render_task', project_id=self.work.parent.id, task_id=self.work.id, ), "objectType": self.__name__, "id": self.id, "displayName": "%dh %dm" % (self.hours, (self.hours * 60) % 60), "updatedBy": nereid_user, }
def new_post(cls): """Create a new post """ post_form = BlogPostForm(request.form) if request.method == 'POST' and post_form.validate(): post, = cls.create([{ 'title': post_form.title.data, 'uri': post_form.uri.data, 'content': post_form.content.data, 'nereid_user': request.nereid_user.id, 'allow_guest_comments': post_form.allow_guest_comments.data, }]) if post_form.publish.data: cls.publish([post]) flash('Your post has been published.') else: flash('Your post has been saved.') if request.is_xhr: return jsonify(success=True, item=post.serialize()) return redirect(url_for( 'blog.post.render', user_id=post.nereid_user.id, uri=post.uri )) if request.is_xhr: return jsonify( success=request.method != 'POST', # False for POST, else True errors=post_form.errors or None, ) return render_template('blog_post_form.jinja', form=post_form)
def edit_post(self): """ Edit an existing post """ if self.nereid_user != request.nereid_user: abort(404) # Search for a post with same uri post_form = BlogPostForm(request.form, obj=self) with Transaction().set_context(blog_id=self.id): if request.method == 'POST' and post_form.validate(): self.title = post_form.title.data self.content = post_form.content.data self.allow_guest_comments = post_form.allow_guest_comments.data self.save() flash('Your post has been updated.') if request.is_xhr: return jsonify(success=True, item=self.serialize()) return redirect(url_for( 'blog.post.render', user_id=self.nereid_user.id, uri=self.uri )) if request.is_xhr: return jsonify( success=request.method != 'POST', # False for POST, else True errors=post_form.errors or None, ) return render_template( 'blog_post_edit.jinja', form=post_form, post=self )
def set_language(self): """Sets the language in the session of the user. Also try to guess the currency of the user, if not use the default currency of the website Accepted Methods: GET, POST Accepts XHR: Yes The language has to be provided in the GET arguments of POST form. It is more convenient to pass the language code than the id of the language because it makes it more readable in URLs """ raise DeprecationWarning("Set language is deprecated") lang_obj = Pool().get('ir.lang') language = request.values.get('language') exists = lang_obj.search([('code', '=', language)], limit=1) if exists: flash(_('Your language preference have been saved.')) else: flash(_('Sorry! we do not speak your language yet!')) # redirect to the next url if given else take to home page redirect_to = request.values.get('next') if redirect_to: redirect_to.replace(session['language'], language) return redirect( request.values.get('next', url_for('nereid.website.home')) )
def as_json_ld(self): """ Gmail markup for order line information https://developers.google.com/gmail/markup/reference/order """ return { "@type": "Offer", "itemOffered": { "@type": "Product", "name": self.product.name, "sku": self.product.code, "url": url_for( 'product.product.render', uri=self.product.uri, _external=True ) if self.product.uri else None }, "price": str(self.amount), "priceCurrency": self.sale.currency.code, "eligibleQuantity": { "@type": "QuantitativeValue", "value": self.quantity, } }
def change_password(self): """ Changes the password .. tip:: On changing the password, the user is logged out and the login page is thrown at the user """ form = ChangePasswordForm(request.form) if request.method == "POST" and form.validate(): user = request.nereid_user # Confirm the current password password = form.old_password.data password += user.salt or "" if isinstance(password, unicode): password = password.encode("utf-8") password_sha = hashlib.sha1(password).hexdigest() if password_sha == user.password: self.write(request.nereid_user.id, {"password": form.password.data}) flash(_("Your password has been successfully changed! " "Please login again")) session.pop("user") return redirect(url_for("nereid.website.login")) else: flash(_("The current password you entered is invalid")) return render_template("change-password.jinja", change_password_form=form)
def registration(self): """ Invokes registration of an user """ registration_form = self.get_registration_form() if request.method == "POST" and registration_form.validate(): existing = self.search( [("email", "=", request.form["email"]), ("company", "=", request.nereid_website.company.id)] ) if existing: flash(_("A registration already exists with this email. " "Please contact customer care")) else: user_id = self.create( { "name": registration_form.name.data, "display_name": registration_form.name.data, "email": registration_form.email.data, "password": registration_form.password.data, "company": request.nereid_website.company.id, } ) self.create_act_code(user_id) registration.send(user_id) user = self.browse(user_id) self.send_activation_email(user) flash(_("Registration Complete. Check your email for activation")) return redirect(request.args.get("next", url_for("nereid.website.home"))) return render_template("registration.jinja", form=registration_form)
def registration(self): """ Invokes registration of an user """ registration_form = self.get_registration_form() if request.method == 'POST' and registration_form.validate(): existing = self.search([ ('email', '=', request.form['email']), ('company', '=', request.nereid_website.company.id), ]) if existing: flash(_('A registration already exists with this email. ' 'Please contact customer care') ) else: user_id = self.create({ 'name': registration_form.name.data, 'display_name': registration_form.name.data, 'email': registration_form.email.data, 'password': registration_form.password.data, 'company': request.nereid_website.company.id, }) self.create_act_code(user_id) registration.send(user_id) user = self.browse(user_id) self.send_activation_email(user) flash( _('Registration Complete. Check your email for activation') ) return redirect( request.args.get('next', url_for('nereid.website.home')) ) return render_template('registration.jinja', form=registration_form)
def change_password(cls): """ Changes the password .. tip:: On changing the password, the user is logged out and the login page is thrown at the user """ form = ChangePasswordForm(request.form) if request.method == 'POST' and form.validate(): if request.nereid_user.match_password(form.old_password.data): cls.write( [request.nereid_user], {'password': form.password.data} ) flash( _('Your password has been successfully changed! ' 'Please login again') ) logout_user() return redirect(url_for('nereid.website.login')) else: flash(_("The current password you entered is invalid")) return render_template( 'change-password.jinja', change_password_form=form )
def reset_account(self): """ Reset the password for the user. .. tip:: This does NOT reset the password, but just creates an activation code and sends the link to the email of the user. If the user uses the link, he can change his password. """ if request.method == "POST": user_ids = self.search( [("email", "=", request.form["email"]), ("company", "=", request.nereid_website.company.id)] ) if not user_ids: flash(_("Invalid email address")) return render_template("reset-password.jinja") self.create_act_code(user_ids[0], "reset") user = self.browse(user_ids[0]) self.send_reset_email(user) flash(_("An email has been sent to your account for resetting" " your credentials")) return redirect(url_for("nereid.website.login")) return render_template("reset-password.jinja")
def edit_address(self, address=None): """ Create/Edit an Address POST will create a new address or update and existing address depending on the value of address. GET will return a new address/existing address edit form :param address: ID of the address """ form = AddressForm(request.form, name=request.nereid_user.name) countries = [ (c.id, c.name) for c in request.nereid_website.countries ] form.country.choices = countries if address not in (a.id for a in request.nereid_user.party.addresses): address = None if request.method == 'POST' and form.validate(): if address is not None: self.write(address, { 'name': form.name.data, 'street': form.street.data, 'streetbis': form.streetbis.data, 'zip': form.zip.data, 'city': form.city.data, 'country': form.country.data, 'subdivision': form.subdivision.data, 'email': form.email.data, 'phone': form.phone.data, }) else: self.create({ 'name': form.name.data, 'street': form.street.data, 'streetbis': form.streetbis.data, 'zip': form.zip.data, 'city': form.city.data, 'country': form.country.data, 'subdivision': form.subdivision.data, 'party': request.nereid_user.party.id, 'email': form.email.data, 'phone': form.email.data, }) return redirect(url_for('party.address.view_address')) elif request.method == 'GET' and address: # Its an edit of existing address, prefill data record = self.browse(address) form = AddressForm( name=record.name, street=record.street, streetbis=record.streetbis, zip=record.zip, city=record.city, country=record.country.id, subdivision=record.subdivision.id, email=record.email, phone=record.phone ) form.country.choices = countries return render_template('address-edit.jinja', form=form, address=address)
def reset_account(cls): """ Reset the password for the user. .. tip:: This does NOT reset the password, but just creates an activation code and sends the link to the email of the user. If the user uses the link, he can change his password. """ form = ResetAccountForm() if form.validate_on_submit(): try: nereid_user, = cls.search([ ('email', '=', form.email.data), ('company', '=', current_website.company.id), ]) except ValueError: return cls.build_response( 'Invalid email address', render_template('reset-password.jinja'), 400 ) nereid_user.send_reset_email() return cls.build_response( 'An email has been sent to your account for resetting' ' your credentials', redirect(url_for('nereid.website.login')), 200 ) elif form.errors: if request.is_xhr or request.is_json: return jsonify(error=form.errors), 400 flash(_('Invalid email address.')) return render_template('reset-password.jinja')
def new_password(cls): """Create a new password .. tip:: Unlike change password this does not demand the old password. And hence this method will check in the session for a parameter called allow_new_password which has to be True. This acts as a security against attempts to POST to this method and changing password. The allow_new_password flag is popped on successful saving This is intended to be used when a user requests for a password reset. """ form = NewPasswordForm(request.form) if request.method == 'POST' and form.validate(): if not session.get('allow_new_password', False): current_app.logger.debug('New password not allowed in session') abort(403) cls.write( [request.nereid_user], {'password': form.password.data} ) session.pop('allow_new_password') flash(_( 'Your password has been successfully changed! ' 'Please login again')) session.pop('user') return redirect(url_for('nereid.website.login')) return render_template('new-password.jinja', password_form=form)
def activate(self, sign, max_age=24 * 60 * 60): """A web request handler for activation of the user account. This method verifies the email and if it succeeds, activates the account. If your workflow requires a manual approval of every account, override this to not activate an account, or make a no op out of this method. If all what you require is verification of email, `verify_email` method could be used. """ try: unsigned = self._serializer.loads( self._signer.unsign(sign, max_age=max_age), salt='activation' ) except SignatureExpired: flash(_("The activation link has expired")) except BadSignature: flash(_("The activation token is invalid!")) else: if self.id == unsigned: self.active = True self.email_verified = True self.save() flash(_('Your account has been activated. Please login now.')) else: flash(_('Invalid Activation Code')) return redirect(url_for('nereid.website.login'))
def new_password(self, sign, max_age=24 * 60 * 60): """Create a new password This is intended to be used when a user requests for a password reset. The link sent out to reset the password will be a timestamped sign which is validated for max_age before allowing the user to set the new password. """ form = NewPasswordForm(request.form) if request.method == 'POST' and form.validate(): try: unsigned = self._serializer.loads( self._signer.unsign(sign, max_age=max_age), salt='reset-password' ) except SignatureExpired: flash(_("The password reset link has expired")) except BadSignature: flash(_('Invalid reset password code')) else: if not self.id == unsigned: current_app.logger.debug('Invalid reset password code') abort(403) self.write([self], {'password': form.password.data}) flash(_( 'Your password has been successfully changed! ' 'Please login again')) return redirect(url_for('nereid.website.login')) return render_template( 'new-password.jinja', password_form=form, sign=sign, user=self )
def delete_task(cls, task_id): """ Delete the task from project Tasks can be deleted only if 1. The user is project admin 2. The user is an admin member in the project :param task_id: Id of the task to be deleted """ task = cls.get_task(task_id) # Check if user is among the project admins if not request.nereid_user.is_admin_of_project(task.parent): flash( "Sorry! You are not allowed to delete tasks. \ Contact your project admin for the same." ) return redirect(request.referrer) cls.write([task], {"active": False}) if request.is_xhr: return jsonify({"success": True}) flash("The task has been deleted") return redirect(url_for("project.work.render_project", project_id=task.parent.id))
def reset_account(cls): """ Reset the password for the user. .. tip:: This does NOT reset the password, but just creates an activation code and sends the link to the email of the user. If the user uses the link, he can change his password. """ if request.method == 'POST': user_ids = cls.search( [ ('email', '=', request.form['email']), ('company', '=', request.nereid_website.company.id), ] ) if not user_ids or not request.form['email']: flash(_('Invalid email address')) return render_template('reset-password.jinja') nereid_user, = user_ids nereid_user.send_reset_email() flash(_('An email has been sent to your account for resetting' ' your credentials')) return redirect(url_for('nereid.website.login')) return render_template('reset-password.jinja')
def edit_address(cls, address=None): """ Edit an Address POST will update an existing address. GET will return a existing address edit form. .. version_changed:: 3.0.3.0 For creating new address use the create_address handled instead of this one. The functionality would be deprecated in 3.2.X :param address: ID of the address """ if address is None: warnings.warn( "Address creation will be deprecated from edit_address handler." " Use party.address.create_address instead", DeprecationWarning ) return cls.create_address() address = cls(address) if address.party != current_user.party: # Check if the address belong to party abort(403) form = cls.get_address_form(address) if request.method == 'POST' and form.validate_on_submit(): cls.write([address], { 'name': form.name.data, 'street': form.street.data, 'streetbis': form.streetbis.data, 'zip': form.zip.data, 'city': form.city.data, 'country': form.country.data, 'subdivision': form.subdivision.data, }) if form.phone.data: cls.write([address], { 'phone': form.phone.data }) return redirect(url_for('party.address.view_address')) return render_template('address-edit.jinja', form=form, address=address)
def as_json_ld(self): """ Gmail markup for order information https://developers.google.com/gmail/markup/reference/order """ data = { "@context": "http://schema.org", "@type": "Order", "customer": { "@type": "Person", "name": self.party.name, }, "merchant": { "@type": "Organization", "name": self.company.rec_name }, "orderNumber": self.reference, "orderDate": str( datetime.combine(self.sale_date, datetime.min.time()) ), "orderStatus": "http://schema.org/OrderStatus/OrderProcessing", "priceCurrency": self.currency.code, "price": str(self.total_amount), "acceptedOffer": [], "url": url_for( 'sale.sale.render', active_id=self.id, access_code=self.guest_access_code, _external=True ) } for line in self.lines: if not line.type == 'line' and not line.product: continue data["acceptedOffer"].append(line.as_json_ld()) if self.invoice_address: data["billingAddress"] = { "@type": "PostalAddress", "name": self.invoice_address.name or self.party.name, "streetAddress": self.invoice_address.street, "addressLocality": self.invoice_address.city, "addressRegion": self.invoice_address.subdivision and self.invoice_address.subdivision.rec_name, # noqa "addressCountry": self.invoice_address.country and self.invoice_address.country.rec_name # noqa } return data
def render_wishlist(self): """ Render specific wishlist of current user. rename wishlist on post and delete on delete request """ Wishlist = Pool().get('wishlist.wishlist') if self.nereid_user != current_user and \ (request.method != "GET" or not self.is_public): abort(404) if request.method == "POST" and request.form.get('name'): name = request.form.get('name') wishlist = Wishlist.search([ ('nereid_user', '=', current_user.id), ('id', '!=', self.id), ('name', '=', name), ], limit=1) if wishlist: flash( _('Wishlist with name: %(name)s already exists.', name=name)) return redirect(request.referrer) else: self.name = name self.is_public = True if request.form.get('is_public') \ else False self.save() flash(_('Wishlist Updated')) if request.is_xhr: return 'success', 200 return redirect(request.referrer) elif request.method == "DELETE": Wishlist.delete([self]) if request.is_xhr: # TODO: send serialized data of current wishlist return 'success', 200 return url_for('wishlist.wishlist.render_wishlists') return render_template('wishlist.jinja', wishlist=self)
def profile(cls): """ User profile """ user_form = ProfileForm(request.form, obj=request.nereid_user) if request.method == 'POST' and user_form.validate(): cls.write( [request.nereid_user], { 'display_name': user_form.display_name.data, 'timezone': user_form.timezone.data, }) flash('Your profile has been updated.') return redirect( request.args.get('next', url_for('nereid.user.profile'))) return render_template('profile.jinja', user_form=user_form, active_type_name="general")
def create_address(cls): """ Create an address for the current nereid_user GET ~~~ Return an address creation form POST ~~~~ Creates an address and redirects to the address view. If a next_url is provided, redirects there. .. version_added: 3.0.3.0 """ form = cls.get_address_form() if request.method == 'POST' and form.validate_on_submit(): party = current_user.party address, = cls.create([{ 'name': form.name.data, 'street': form.street.data, 'streetbis': form.streetbis.data, 'zip': form.zip.data, 'city': form.city.data, 'country': form.country.data, 'subdivision': form.subdivision.data, 'party': party.id, }]) if form.phone.data: cls.write([address], {'phone': form.phone.data}) return redirect(url_for('party.address.view_address')) try: return render_template('address-add.jinja', form=form) except TemplateNotFound: # The address-add template was introduced in 3.0.3.0 # so just raise a deprecation warning till 3.2.X and then # expect the use of address-add template warnings.warn( "address-add.jinja template not found. " "Will be required in future versions", DeprecationWarning) return render_template('address-edit.jinja', form=form)
def manage_spam(self): "Mark the comment as spam" if not self.post.nereid_user == request.nereid_user: abort(403) self.is_spam = request.form.get('spam', False, type=bool) self.save() if request.is_xhr: return jsonify({ 'success': True, }) else: flash('The comment has been updated') return redirect( url_for('blog.post.render', user_id=self.post.nereid_user.id, uri=self.post.uri))
def change_guest_permission(self): "Change guest permission of the post" if self.nereid_user != request.nereid_user: abort(404) allow_guest_comment = request.form.get('allow_guest_comments') self.allow_guest_comments = True if allow_guest_comment == 'true' \ else False self.save() if request.is_xhr: return jsonify({ 'success': True, }) return redirect( url_for('blog.post.render', user_id=self.nereid_user.id, uri=self.uri))
def change_state(self): "Change the state of the post" if self.nereid_user != request.nereid_user: abort(404) state = request.form.get('state') assert (state in ('publish', 'archive', 'draft')) getattr(self, str(state))([self]) if request.is_xhr: return jsonify({ 'success': True, 'new_state': self.state, }) flash('Your post is now %s' % self.state) return redirect( url_for('blog.post.render', user_id=self.nereid_user.id, uri=self.uri))
def wishlist_product(cls): """ Add/Remove product in wishlist. If wishlist_id is passed then search for wishlist and add/remove product else create a default wishlist and add product. :params wishlist: Get the id of wishlist product: Get product id action: add or remove, add will add product to wishlist. remove will unlink product from wishlist """ Product = Pool().get('product.product') wishlist_id = request.form.get("wishlist", type=int) if wishlist_id: try: wishlist, = cls.search([ ('id', '=', wishlist_id), ('nereid_user', '=', current_user.id), ]) except ValueError: raise ValidationError("Wishlist not valid!") else: wishlist = cls._search_or_create_wishlist() product = Product.search([ ('id', '=', request.form.get("product", type=int)), ('displayed_on_eshop', '=', True), ('template.active', '=', True), ], limit=1) if not product or request.form.get('action') not in ['add', 'remove']: abort(404) cls.write([wishlist], { 'products': [(request.form.get('action'), product)], }) if request.is_xhr: # TODO: Send serailized data of wishllist return 'success', 200 return redirect( url_for('wishlist.wishlist.render_wishlist', active_id=wishlist.id))
def delete_from_cart(cls, line): """ Delete a line from the cart. The required argument in POST is: line_id : ID of the line Response: 'OK' if X-HTTPRequest else redirect to shopping cart """ SaleLine = Pool().get('sale.line') sale_line = SaleLine(line) assert sale_line.sale.id == cls.open_cart().sale.id SaleLine.delete([sale_line]) flash(_('The order item has been successfully removed')) if request.is_xhr: return jsonify(message='OK') return redirect(url_for('nereid.cart.view_cart'))
def serialize(self, purpose=None): ''' Serialize the tag and returns a dictionary. ''' return { 'create_date': self.create_date.isoformat(), "url": url_for('project.work.render_task_list', project_id=self.project.id, state="opened", tag=self.id), "objectType": self.__name__, "id": self.id, "displayName": self.name, }
def change_party(cls, party_id): """ Updates the current party of the nereid_user to the new party_id if it is one of the parties in the list of parties of the user :param party_id: ID of the party """ for party in current_user.parties: if party.id == party_id: cls.write([current_user], {'party': party.id}) break else: if request.is_xhr: return jsonify(error='The party is not valid'), 400 flash("The party is not valid") if request.is_xhr: return jsonify(success='Party has been changed successfully') return redirect( request.args.get('next', url_for('nereid.website.home')))
def login(cls): """ Simple login based on the email and password Required post data see :class:LoginForm """ login_form = LoginForm(request.form) if not request.is_guest_user and request.args.get('next'): return redirect(request.args['next']) if request.method == 'POST' and login_form.validate(): NereidUser = Pool().get('nereid.user') result = NereidUser.authenticate(login_form.email.data, login_form.password.data) # Result can be the following: # 1 - Browse record of User (successful login) # 2 - None - Login failure without message # 3 - Any other false value (no message is shown. useful if you # want to handle the message shown to user) if result: # NOTE: Translators leave %s as such flash( _("You are now logged in. Welcome %(name)s", name=result.name)) session['user'] = result.id login.send() if request.is_xhr: return 'OK' else: return redirect( request.values.get('next', url_for('nereid.website.home'))) elif result is None: flash(_("Invalid login credentials")) failed_login.send(form=login_form) if request.is_xhr: return 'NOK' return render_template('login.jinja', login_form=login_form)
def _get_email_template_context(self): """ Update context """ context = super(Sale, self)._get_email_template_context() if has_request_context() and not current_user.is_anonymous(): customer_name = current_user.display_name else: customer_name = self.party.name context.update({ 'url_for': lambda *args, **kargs: url_for(*args, **kargs), 'has_request_context': lambda *args, **kargs: has_request_context( *args, **kargs), 'current_user': current_user, 'customer_name': customer_name, 'to_json': lambda *args, **kargs: json.dumps(*args, **kargs), }) return context
def make_pkpass(self): """ Builds a pass by calling the origin model for it and then adds a serial number and signs it and builds the pkpass file. """ passfile = self.origin.get_passfile() # Add information to be provided by this API passfile.serialNumber = str(self.id) passfile.webServiceURL = url_for('nereid.passbook.pass.webservice_url', _external=True, _secure=True) passfile.authenticationToken = self.authentication_token # TODO: What to do if barcode is not there ? return passfile.create( config.get('nereid_passbook', 'certificate'), config.get('nereid_passbook', 'key'), file_open('nereid_passbook/wwdr.pem').name, '', # Password for pem file ? )
def move_task_to_project(self, project_id): """ Move task from one project to another. """ ProjectWork = Pool().get('project.work') assert self.type == 'task' try: target_project, = ProjectWork.search([('id', '=', project_id), ('type', '=', 'project')], limit=1) except ValueError: flash("No project found with given details") return redirect(request.referrer) if not (current_user.is_admin_of_project(self.parent) and current_user.is_admin_of_project(target_project)): abort(403) if self.parent.id == target_project.id: flash("Task already in this project") return redirect(request.referrer) if self.assigned_to not in [ member.user for member in target_project.members ]: self.assigned_to = None # Move task to target project self.parent = target_project.id self.save() flash("Task #%d successfully moved to project %s" % (self.id, target_project.work.name)) return redirect( url_for('project.work.render_task', project_id=target_project.id, task_id=self.id))
def registration(cls): """ Invokes registration of an user """ registration_form = cls.get_registration_form() if request.method == 'POST' and registration_form.validate(): existing = cls.search([ ('email', '=', request.form['email']), ('company', '=', request.nereid_website.company.id), ]) if existing: flash( _('A registration already exists with this email. ' 'Please contact customer care')) else: nereid_user = cls.create({ 'name': registration_form.name.data, 'display_name': registration_form.name.data, 'email': registration_form.email.data, 'password': registration_form.password.data, 'company': request.nereid_website.company.id, }) nereid_user.create_act_code() registration.send(nereid_user) nereid_user.send_activation_email() flash( _('Registration Complete. Check your email for activation') ) return redirect( request.args.get('next', url_for('nereid.website.home'))) return render_template('registration.jinja', form=registration_form)
def serialize(self, purpose=None): """ Serialize SaleLine data """ res = {} if purpose == 'cart': currency_format = partial(numbers.format_currency, currency=self.sale.currency.code, locale=current_locale.language.code) number_format = partial(numbers.format_number, locale=current_locale.language.code) res.update({ 'id': self.id, 'display_name': (self.product and self.product.name or self.description), 'url': self.product.get_absolute_url(_external=True), 'image': (self.product.default_image.transform_command().thumbnail( 150, 150, 'a').url() if self.product.default_image else None), 'product': self.product.serialize(purpose), 'quantity': number_format(self.quantity), 'unit': self.unit.symbol, 'unit_price': currency_format(self.unit_price), 'amount': currency_format(self.amount), 'remove_url': url_for('nereid.cart.delete_from_cart', line=self.id), }) elif hasattr(super(SaleLine, self), 'serialize'): return super(SaleLine, self).serialize(purpose) # pragma: no cover return res
def confirm_cart(cls, cart): ''' Confirm the sale, clear the sale from the cart ''' Sale = Pool().get('sale.sale') sale = cart.sale Sale.quote([cart.sale]) Sale.confirm([cart.sale]) cart.sale = None cart.save() # Redirect to the order confirmation page flash(_( "Your order #%(sale)s has been processed", sale=sale.reference )) return redirect(url_for( 'sale.sale.render', active_id=sale.id, confirmation=True, access_code=sale.guest_access_code, ))
def change_password(cls): """ Changes the password .. tip:: On changing the password, the user is logged out and the login page is thrown at the user """ form = ChangePasswordForm() if request.method == 'POST' and form.validate(): if current_user.match_password(form.old_password.data): cls.write( [current_user], {'password': form.password.data} ) logout_user() return cls.build_response( 'Your password has been successfully changed! ' 'Please login again', redirect(url_for('nereid.website.login')), 200 ) else: return cls.build_response( 'The current password you entered is invalid', render_template( 'change-password.jinja', change_password_form=form ), 400 ) if form.errors and (request.is_xhr or request.is_json): return jsonify(errors=form.errors), 400 return render_template( 'change-password.jinja', change_password_form=form )
def change_password(cls): """ Changes the password .. tip:: On changing the password, the user is logged out and the login page is thrown at the user """ form = ChangePasswordForm(request.form) if request.method == 'POST' and form.validate(): if request.nereid_user.match_password(form.old_password.data): cls.write([request.nereid_user], {'password': form.password.data}) flash( _('Your password has been successfully changed! ' 'Please login again')) session.pop('user') return redirect(url_for('nereid.website.login')) else: flash(_("The current password you entered is invalid")) return render_template('change-password.jinja', change_password_form=form)
def serialize(self, purpose=None): """ Return serializable dictionary suitable for use with variant selection. """ if purpose != 'variant_selection': return super(Product, self).serialize(purpose) currency_format = partial( numbers.format_currency, currency=request.nereid_website.company.currency.code, locale=request.nereid_website.default_locale.language.code ) return { 'id': self.id, 'rec_name': self.rec_name, 'name': self.name, 'code': self.code, 'price': currency_format(self.sale_price(1)), 'url': url_for('product.product.render', uri=self.uri), 'image_urls': [ { 'large': ( image.transform_command().thumbnail(500, 500, 'a') .url() ), 'thumbnail': ( image.transform_command().thumbnail(120, 120, 'a') .url() ), 'regular': image.url, } for image in self.get_images() ], }
def new_post(cls): """Create a new post """ post_form = BlogPostForm(request.form) if request.method == 'POST' and post_form.validate(): post, = cls.create([{ 'title': post_form.title.data, 'uri': post_form.uri.data, 'content': post_form.content.data, 'nereid_user': request.nereid_user.id, 'allow_guest_comments': post_form.allow_guest_comments.data, }]) if post_form.publish.data: cls.publish([post]) flash('Your post has been published.') else: flash('Your post has been saved.') if request.is_xhr: return jsonify(success=True, item=post.serialize()) return redirect( url_for('blog.post.render', user_id=post.nereid_user.id, uri=post.uri)) if request.is_xhr: return jsonify( success=request.method != 'POST', # False for POST, else True errors=post_form.errors or None, ) return render_template('blog_post_form.jinja', form=post_form)
def render_gift_card(cls, uri): """ Add gift card as a new line in cart Request: 'GET': Renders gift card page 'POST': Buy Gift Card Response: 'OK' if X-HTTPRequest Redirect to shopping cart if normal request """ SaleLine = Pool().get('sale.line') Cart = Pool().get('nereid.cart') try: product, = cls.search([('displayed_on_eshop', '=', True), ('uri', '=', uri), ('template.active', '=', True), ('is_gift_card', '=', True)], limit=1) except ValueError: abort(404) form = GiftCardForm(product) if form.validate_on_submit(): cart = Cart.open_cart(create_order=True) # Code to add gift card as a line to cart values = { 'product': product.id, 'sale': cart.sale.id, 'type': 'line', 'sequence': 10, 'quantity': 1, 'unit': None, 'description': None, 'recipient_email': form.recipient_email.data, 'recipient_name': form.recipient_name.data, 'message': form.message.data, } order_line = SaleLine(**values) order_line.on_change_product() # Here 0 means the default option to enter open amount is # selected if form.selected_amount.data != 0: order_line.gc_price = form.selected_amount.data order_line.on_change_gc_price() else: order_line.unit_price = Decimal(form.open_amount.data) order_line.save() message = 'Gift Card has been added to your cart' if request.is_xhr: # pragma: no cover return jsonify(message=message) flash(_(message), 'info') return redirect(url_for('nereid.cart.view_cart')) return render_template('catalog/gift-card.html', product=product, form=form)
class NereidUser: "******" __name__ = "nereid.user" github_id = fields.Integer('Github ID') github_url = fields.Char('Github URL') @classmethod @route("/auth/github", methods=["GET"]) def github_login(cls): """ The URL to which a new request to authenticate to github begins Usually issues a redirect. """ github = request.nereid_website.get_github_oauth_client() if github is None: return redirect(request.referrer or url_for('nereid.website.login')) return github.authorize(callback=url_for( 'nereid.user.github_authorized_login', next=request.args.get('next') or request.referrer or None, _external=True)) @classmethod @route("/auth/github-authorized-login", methods=["GET"]) def github_authorized_login(cls): """ Authorized handler to which github will redirect the user to after the login attempt is made. """ github = request.nereid_website.get_github_oauth_client() if github is None: return redirect(request.referrer or url_for('nereid.website.login')) try: # The response is an oauth2 response with code. But Github API # requires the if 'oauth_verifier' in request.args: data = github.handle_oauth1_response() elif 'code' in request.args: data = github.handle_oauth2_response() else: data = github.handle_unknown_response() github.free_request_token() except Exception, exc: current_app.logger.error("Github login failed %s" % exc) flash(_("We cannot talk to github at this time. Please try again")) return redirect(request.referrer or url_for('nereid.website.login')) if data is None: flash( _("Access was denied to github: %(reason)s", reason=request.args['error_reason'])) failed_login.send(form=data) return redirect(url_for('nereid.website.login')) # Write the oauth token to the session session['github_oauth_token'] = data['access_token'] # Find the information from facebook me = requests.get('https://api.github.com/user', params={ 'access_token': session['github_oauth_token'] }).json # Find the user users = cls.search([ ('email', '=', me['email']), ('company', '=', request.nereid_website.company.id), ]) if not users: current_app.logger.debug("No Github user with email %s" % me['email']) current_app.logger.debug("Registering new user %s" % me['name']) user, = cls.create([{ 'name': me['name'], 'display_name': me['name'], 'email': me['email'], 'github_id': me['id'], 'addresses': False, 'github_url': me['html_url'], }]) flash(_('Thanks for registering with us using github')) else: user, = users # Add the user to session and trigger signals session['user'] = user.id if not user.github_id: cls.write([user], { 'github_id': me['id'], 'github_url': me['html_url'] }) flash(_("You are now logged in. Welcome %(name)s", name=user.name)) login.send() if request.is_xhr: return 'OK' return redirect( request.values.get('next', url_for('nereid.website.home')))
def billing_address(cls): ''' Choose or Create a billing address ''' NereidCart = Pool().get('nereid.cart') Address = Pool().get('party.address') PaymentProfile = Pool().get('party.payment_profile') cart = NereidCart.open_cart() address = None if current_user.is_anonymous and cart.sale.invoice_address: address = cart.sale.invoice_address address_form = cls.get_new_address_form(address) if request.method == 'POST': if request.form.get('use_shipment_address'): if not cart.sale.shipment_address: # Without defining shipment address, the user is # trying to set invoice_address as shipment_address return redirect( url_for('nereid.checkout.shipping_address')) cart.sale.invoice_address = cart.sale.shipment_address cart.sale.save() return redirect(url_for('nereid.checkout.payment_method')) if request.form.get('payment_profile'): payment_profile = PaymentProfile( request.form.get('payment_profile', type=int)) if payment_profile and \ cart.sale.invoice_address != payment_profile.address: cart.sale.invoice_address = payment_profile.address cart.sale.save() return redirect(url_for('nereid.checkout.payment_method')) if not current_user.is_anonymous and request.form.get('address'): # Registered user has chosen an existing address address = Address(request.form.get('address', type=int)) if address.party != cart.sale.party: flash(_('The address chosen is not valid')) return redirect(url_for('nereid.checkout.billing_address')) else: # Guest user or registered user creating an address. Only # difference is that the party of address depends on guest or # not if not address_form.validate(): address = None else: if (current_user.is_anonymous and cart.sale.invoice_address and cart.sale.invoice_address != cart.sale.shipment_address): # Save to the same address if the guest user # is just trying to update the address address = cart.sale.invoice_address else: address = Address() address.party = cart.sale.party address.name = address_form.name.data address.street = address_form.street.data address.streetbis = address_form.streetbis.data address.zip = address_form.zip.data address.city = address_form.city.data address.country = address_form.country.data address.subdivision = address_form.subdivision.data if address_form.phone.data: # create contact mechanism phone = \ cart.sale.party.add_contact_mechanism_if_not_exists( 'phone', address_form.phone.data ) address.phone_number = phone.id address.save() if address is not None: # Finally save the address to the shipment cart.sale.invoice_address = address cart.sale.save() return redirect(url_for('nereid.checkout.payment_method')) addresses = [] if not current_user.is_anonymous: addresses.extend(current_user.party.addresses) return render_template( 'checkout/billing_address.jinja', addresses=addresses, address_form=address_form, )
def shipping_address(cls): ''' Choose or Create a shipping address Guest users are only allowed to create a new address while registered users are allowed to either choose an address or create a new one. GET ~~~ Renders the shipping_address selection/creation page. The template context would have an addresses variable which carries a list of addresses in the case of registered users. For guest users the variable would be empty. POST ~~~~ **Registered User**: If `address` (the id of the chosen address) is in the POST values, then the address is validated and stored as the `shipment_address` in the sale. If not, the new address form is validated to see if a new address has to be created for the party. **Guest User**: New address data has to be provided and validated to create the new address. Once the address is set succesfully, the delivery_options page is shown ''' NereidCart = Pool().get('nereid.cart') Address = Pool().get('party.address') cart = NereidCart.open_cart() address = None if current_user.is_anonymous and cart.sale.shipment_address: address = cart.sale.shipment_address address_form = cls.get_new_address_form(address) if request.method == 'POST': if not current_user.is_anonymous and request.form.get('address'): # Registered user has chosen an existing address address = Address(request.form.get('address', type=int)) if address.party != cart.sale.party: flash(_('The address chosen is not valid')) return redirect( url_for('nereid.checkout.shipping_address')) else: # Guest user or registered user creating an address. Only # difference is that the party of address depends on guest or # not if not address_form.validate(): address = None else: if current_user.is_anonymous and \ cart.sale.shipment_address: # Save to the same address if the guest user # is just trying to update the address address = cart.sale.shipment_address else: address = Address() address.party = cart.sale.party address.name = address_form.name.data address.street = address_form.street.data address.streetbis = address_form.streetbis.data address.zip = address_form.zip.data address.city = address_form.city.data address.country = address_form.country.data address.subdivision = address_form.subdivision.data if address_form.phone.data: # create contact mechanism phone = \ cart.sale.party.add_contact_mechanism_if_not_exists( 'phone', address_form.phone.data ) address.phone_number = phone.id address.save() if address is not None: # Finally save the address to the shipment cart.sale.shipment_address = address cart.sale.save() return redirect(url_for('nereid.checkout.validate_address')) addresses = [] if not current_user.is_anonymous: addresses.extend(current_user.party.addresses) return render_template( 'checkout/shipping_address.jinja', addresses=addresses, address_form=address_form, )
def sign_in(cls): ''' Step 1: Sign In or Register GET ~~~ Renders a sign-in or register page. If guest checkout is enabled, then an option to continue as guest is also permitted, in which case the email is a required field. POST ~~~~ For guest checkout, this sign in would create a new party with the name as the current session_id and move the shopping cart's sale to the new user's ownership Designer notes: The registration or login must contact the corresponding handlers. Login and Registraion handlers are designed to handle a `next` parameter where the user would be redirected to if the operation was successful. The next url is provided in the context OTOH, if the user desires to checkout as guest, the user is required to fill in the email and submit the form, which posts the email to this handler. ''' NereidCart = Pool().get('nereid.cart') NereidUser = Pool().get('nereid.user') Party = Pool().get('party.party') if not current_user.is_anonymous: form = cls.sign_in_form( email=current_user.email, checkout_mode='account', ) else: # Guest user form = cls.sign_in_form( email=session.get('email'), checkout_mode='guest', ) if form.validate_on_submit(): if form.checkout_mode.data == 'guest': if not cls.allowed_as_guest(form.email.data): return render_template( 'checkout/signin-email-in-use.jinja', email=form.email.data) cart = NereidCart.open_cart() party_name = unicode( _('Guest with email: %(email)s', email=form.email.data)) if cart.sale.party == current_website.guest_user.party: # Create a party with the email as email, and session as # name, but attach the session to it. party, = Party.create([{ 'name': party_name, 'nereid_session': session.sid, 'addresses': [], 'contact_mechanisms': [('create', [{ 'type': 'email', 'value': form.email.data, }])] }]) cart.sale.party = party # TODO: Avoid this if the user comes to sign-in twice. cart.sale.shipment_address = None cart.sale.invoice_address = None cart.sale.save() else: # Perhaps the email changed ? party = cart.sale.party party.name = party_name # contact_mechanism of email type will always be there for # Guest user contact_mechanism = filter(lambda c: c.type == 'email', party.contact_mechanisms)[0] contact_mechanism.value = form.email.data contact_mechanism.save() party.email = form.email.data party.save() return redirect(url_for('nereid.checkout.shipping_address')) else: # The user wants to use existing email to login user = NereidUser.authenticate(form.email.data, form.password.data) if user: # FIXME: Remove remember_me login_user(user, remember=form.remember.data) return redirect( url_for('nereid.checkout.shipping_address')) else: failed_login.send() if not current_user.is_anonymous: # Registered user with a fresh login can directly proceed to # step 2, which is filling the shipping address # # if this is a recent sign-in by a registred user # automatically proceed to the shipping_address step return redirect(url_for('nereid.checkout.shipping_address')) return render_template( 'checkout/signin.jinja', form=form, next=url_for('nereid.checkout.shipping_address'))
def new_opportunity(cls): """ Web handler to create a new sale opportunity """ if 're_captcha_public' in CONFIG.options: contact_form = ContactUsForm( request.form, captcha={'ip_address': request.remote_addr}) else: contact_form = ContactUsForm(request.form) if request.method == 'POST': if not contact_form.validate(): return jsonify({ "success": False, "message": "Field validation error", "errors": contact_form.errors, }) ContactMech = Pool().get('party.contact_mechanism') Party = Pool().get('party.party') Config = Pool().get('sale.configuration') config = Config(1) contact_data = contact_form.data # Create Party company = request.nereid_website.company.id if request.remote_addr and geoip: detected_country = geoip.country_name_by_addr( request.remote_addr) else: detected_country = None party, = Party.create([{ 'name': contact_data.get('company') or contact_data['name'], 'addresses': [('create', [{ 'name': contact_data['name'], }])], }]) if contact_data.get('website'): # Create website as contact mech ContactMech.create([{ 'type': 'website', 'party': party.id, 'website': contact_data['website'], }]) if contact_data.get('phone'): # Create phone as contact mech and assign as phone ContactMech.create([{ 'type': 'phone', 'party': party.id, 'other_value': contact_data['phone'], }]) # Create email as contact mech and assign as email ContactMech.create([{ 'type': 'email', 'party': party.id, 'email': contact_data['email'], }]) # Create sale opportunity if not current_user.is_anonymous() and current_user.employee: employee = current_user.employee.id description = 'Created by %s' % \ current_user.display_name else: employee = config.website_employee.id description = 'Created from website' lead, = cls.create([{ 'party': party.id, 'company': company, 'employee': employee, 'address': party.addresses[0].id, 'description': description, 'comment': contact_data['comment'], 'ip_address': request.remote_addr, 'detected_country': detected_country, }]) lead.send_notification_mail() if request.is_xhr or request.is_json: return jsonify({ "success": True, "message": "Contact saved", "lead_id": lead.id, }) return redirect( request.args.get( 'next', url_for('sale.opportunity.admin_lead', active_id=lead.id))) return render_template('crm/sale_form.jinja', form=contact_form)
def registration(cls): """ Invokes registration of an user """ Party = Pool().get('party.party') ContactMechanism = Pool().get('party.contact_mechanism') registration_form = cls.get_registration_form() if registration_form.validate_on_submit(): with Transaction().set_context(active_test=False): existing = cls.search([ ('email', '=', registration_form.email.data), ('company', '=', request.nereid_website.company.id), ]) if existing: message = _( 'A registration already exists with this email. ' 'Please contact customer care' ) if request.is_xhr or request.is_json: return jsonify(message=unicode(message)), 400 else: flash(message) else: party = Party(name=registration_form.name.data) party.addresses = [] party.contact_mechanisms = [ ContactMechanism( type="email", value=registration_form.email.data ) ] party.save() nereid_user = cls(**{ 'party': party.id, 'display_name': registration_form.name.data, 'email': registration_form.email.data, 'password': registration_form.password.data, 'company': request.nereid_website.company.id, } ) nereid_user.save() registration.send(nereid_user) nereid_user.send_activation_email() message = _( 'Registration Complete. Check your email for activation' ) if request.is_xhr or request.is_json: return jsonify(message=unicode(message)), 201 else: flash(message) return redirect( request.args.get('next', url_for('nereid.website.home')) ) if registration_form.errors and (request.is_xhr or request.is_json): return jsonify({ 'message': unicode(_('Form has errors')), 'errors': registration_form.errors, }), 400 return render_template('registration.jinja', form=registration_form)