Example #1
0
    def start_session(cls):
        '''
        POST: Start chat session with another user.
            :args user: User Id of nereid user.

        :return: JSON as
                {
                    thread_id: uuid,
                    members: Serialized members list.
                }
        '''
        NereidUser = Pool().get('nereid.user')
        form = NewChatForm()

        if not form.validate_on_submit():
            return jsonify(errors=form.errors), 400

        chat_with = NereidUser(form.user.data)
        if not request.nereid_user.can_chat(chat_with):
            abort(403, "You can only talk to friends")

        chat = cls.get_or_create_room(
            request.nereid_user.id, chat_with.id
        )
        return jsonify({
            'thread_id': chat.thread,
            'members': map(
                lambda m: m.user.serialize(), chat.members
            )
        })
Example #2
0
    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)
Example #3
0
    def add(cls):
        """
        Adds a contact mechanism to the party's contact mechanisms
        """
        form = cls.get_form()
        if form.validate_on_submit():
            cls.create(
                [
                    {
                        "party": request.nereid_user.party.id,
                        "type": form.type.data,
                        "value": form.value.data,
                        "comment": form.comment.data,
                    }
                ]
            )
            if request.is_xhr:
                return jsonify({"success": True})
            return redirect(request.referrer)

        if request.is_xhr:
            return jsonify({"success": False})
        else:
            for field, messages in form.errors:
                flash("<br>".join(messages), "Field %s" % field)
            return redirect(request.referrer)
Example #4
0
    def cms_static_upload(cls, upload_type):
        """
        Upload the file for cms
        """
        StaticFile = Pool().get("nereid.static.file")

        file = request.files['file']
        if file:
            static_file, = StaticFile.create([{
                'folder':
                current_website.cms_static_folder,
                'name':
                '_'.join([
                    str(int(time.time())),
                    secure_filename(file.filename),
                ]),
                'type':
                upload_type,
                'file_binary':
                file.read(),
            }])
            if request.is_xhr:
                return jsonify(success=True, item=static_file.serialize())

            flash("File uploaded")
        if request.is_xhr:
            return jsonify(success=False)
        return redirect(request.referrer)
Example #5
0
    def start_session(cls):
        '''
        POST: Start chat session with another user.
            :args user: User Id of nereid user.

        :return: JSON as
                {
                    thread_id: uuid,
                    members: Serialized members list.
                }
        '''
        NereidUser = Pool().get('nereid.user')
        form = NewChatForm()

        if not form.validate_on_submit():
            return jsonify(errors=form.errors), 400

        chat_with = NereidUser(form.user.data)
        if not request.nereid_user.can_chat(chat_with):
            abort(403, "You can only talk to friends")

        chat = cls.get_or_create_room(request.nereid_user.id, chat_with.id)
        return jsonify({
            'thread_id':
            chat.thread,
            'members':
            map(lambda m: m.user.serialize(), chat.members)
        })
Example #6
0
    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
        ))
Example #7
0
    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)
Example #8
0
    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
        )
Example #9
0
    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.lower()),
                    ('company', '=', current_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': current_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)
Example #10
0
    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'))
Example #11
0
    def registration(cls):
        """
        Invokes registration of an user
        """
        Party = Pool().get('party.party')

        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.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)
Example #12
0
    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).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()
            cart_updated.send(cart)

            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'))
Example #13
0
    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')
            user = 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 user:
                # NOTE: Translators leave %s as such
                flash(_("You are now logged in. Welcome %(name)s",
                        name=user.display_name))
                if login_user(user, remember=login_form.remember.data):
                    if request.is_xhr:
                        return jsonify({
                            'success': True,
                            'user': user.serialize(),
                        })
                    else:
                        return redirect(
                            request.values.get(
                                'next', url_for('nereid.website.home')
                            )
                        )
                else:
                    flash(_("Your account has not been activated yet!"))
            elif user is None:
                flash(_("Invalid login credentials"))

            failed_login.send(form=login_form)

            if request.is_xhr:
                rv = jsonify(message="Bad credentials")
                rv.status_code = 401
                return rv

        return render_template('login.jinja', login_form=login_form)
Example #14
0
    def login(cls):
        """
        Simple login based on the email and password

        Required post data see :class:LoginForm
        """
        login_form = LoginForm(request.form)

        if not current_user.is_anonymous() and request.args.get('next'):
            return redirect(request.args['next'])

        if request.method == 'POST' and login_form.validate():
            NereidUser = Pool().get('nereid.user')
            user = 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 user:
                # NOTE: Translators leave %s as such
                flash(_("You are now logged in. Welcome %(name)s",
                        name=user.display_name))
                if login_user(user, remember=login_form.remember.data):
                    if request.is_xhr:
                        return jsonify({
                            'success': True,
                            'user': user.serialize(),
                        })
                    else:
                        return redirect(
                            request.values.get(
                                'next', url_for('nereid.website.home')
                            )
                        )
                else:
                    flash(_("Your account has not been activated yet!"))
            elif user is None:
                flash(_("Invalid login credentials"))

            failed_login.send(form=login_form)

            if request.is_xhr:
                rv = jsonify(message="Bad credentials")
                rv.status_code = 401
                return rv

        return render_template('login.jinja', login_form=login_form)
Example #15
0
    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.lower()), ("company", "=", current_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": current_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)
Example #16
0
    def availability(cls, uri):
        """
        Returns the following information for a product:

        +-------------------+-----------------------------------------------+
        | quantity          | Available readily to buy                      |
        +-------------------+-----------------------------------------------+
        | forecast_quantity | Forecasted quantity, if the site needs it     |
        +-------------------+-----------------------------------------------+

        .. note::
            To modify the availability, or to send any additional information,
            it is recommended to subclass the :py:meth:`~get_availability` and
            implement your custom logic. For example, you might want to check
            stock with your vendor for back orders or send a message like
            `Only 5 pieces left`

        :param uri: URI of the product for which the availability needs to
                    be found
        :return: JSON object
        """
        try:
            product, = cls.search([
                ('displayed_on_eshop', '=', True),
                ('uri', '=', uri),
            ])
        except ValueError:
            return abort(404)

        return jsonify(product.get_availability())
Example #17
0
    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()
        if form.validate_on_submit():
            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'))
            cart._add_or_update(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'))
Example #18
0
 def get_all_countries(cls):
     """
     Returns serialized list of all countries
     """
     return jsonify(countries=[
         country.serialize() for country in cls.search([])
     ])
Example #19
0
 def search_auto_complete(cls):
     """
     Handler for auto-completing search.
     """
     return jsonify(results=cls.auto_complete(
         request.args.get('q', '')
     ))
Example #20
0
    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))
Example #21
0
    def render(cls, user_id, uri):
        "Render the blog post"
        NereidUser = Pool().get('nereid.user')

        if 're_captcha_public' in CONFIG.options and request.is_guest_user:
            comment_form = GuestCommentForm(
                captcha={'ip_address': request.remote_addr})
        else:
            comment_form = PostCommentForm()

        user = NereidUser(user_id)

        posts = cls.search([
            ('nereid_user', '=', user.id),
            ('uri', '=', uri),
        ])
        if not posts:
            abort(404)

        # if only one post is found then it is rendered and
        # if more than one are found then the first one is rendered
        post = posts[0]

        if not (post.state == 'Published'
                or request.nereid_user == post.nereid_user):
            abort(403)

        if request.is_xhr:
            return jsonify(post.serialize())
        return render_template('blog_post.jinja',
                               post=post,
                               comment_form=comment_form,
                               poster=user)
Example #22
0
    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 get_passes(cls, device, pass_type=None, version=None):
        """
        Getting the Serial Numbers for Passes Associated with the Device
        """
        domain = [
            ('device_library_identifier', '=', device),
            ('pass_.active', '=', True),
        ]
        updated_since = request.args.get('passesUpdatedSince',
                                         type=dateutil.parser.parse)

        passes = set()
        for registration in cls.search(domain):
            if updated_since is not None and \
                    registration.pass_.last_update < updated_since:
                # If updated_since is specified and the last_update of the
                # pass is before it, there is nothing more to send
                continue
            passes.add(registration.pass_)

        if not passes:
            return '', 204

        rv = defaultdict(list)
        for pass_ in passes:
            rv[pass_.last_update.isoformat(' ')].append(str(pass_.id))
        return jsonify(rv), 200
Example #24
0
    def get_available_gateways(cls):
        """Return the JSONified list of payment gateways available

        This is a XHR only method

        If type is specified as address then an address lookup is done
        """
        Address = Pool().get('party.address')

        value = request.args.get('value', 0, type=int)
        if request.values.get('type') == 'address':
            # Address lookup only when logged in
            if request.is_guest_user:
                abort(403)

            # If not validated as user's address this could lead to
            # exploitation by ID
            if value not in [a.id for a in
                    request.nereid_user.party.addresses]:
                abort(403)

            address = Address(value)
            value = address.country.id

        rv = [{
            'id': g.id,
            'name': g.name,
            'image': g.get_image(),
        } for g in cls._get_available_gateways(value)]

        return jsonify(result=rv)
Example #25
0
    def edit_task(self):
        """
        Edit the task
        """
        Activity = Pool().get('nereid.activity')
        Work = Pool().get('timesheet.work')

        task = self.get_task(self.id)

        Work.write([task.work], {
            'name': request.form.get('name'),
        })
        self.write([task], {
            'comment': request.form.get('comment')
        })
        Activity.create([{
            'actor': request.nereid_user.id,
            'object_': 'project.work, %d' % task.id,
            'verb': 'edited_task',
            'target': 'project.work, %d' % task.parent.id,
            'project': task.parent.id,
        }])
        if request.is_xhr:
            return jsonify({
                'success': True,
                'name': self.rec_name,
                'comment': self.comment,
            })
        return redirect(request.referrer)
Example #26
0
    def get_available_gateways(cls):
        """Return the JSONified list of payment gateways available

        This is a XHR only method

        If type is specified as address then an address lookup is done
        """
        Address = Pool().get('party.address')

        value = request.args.get('value', 0, type=int)
        if request.values.get('type') == 'address':
            # Address lookup only when logged in
            if request.is_guest_user:
                abort(403)

            # If not validated as user's address this could lead to
            # exploitation by ID
            if value not in [
                    a.id for a in request.nereid_user.party.addresses
            ]:
                abort(403)

            address = Address(value)
            value = address.country.id

        rv = [{
            'id': g.id,
            'name': g.name,
            'image': g.get_image(),
        } for g in cls._get_available_gateways(value)]

        return jsonify(result=rv)
Example #27
0
    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()
        if form.validate_on_submit():
            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'))
            cart._add_or_update(
                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'))
Example #28
0
    def assign_task(self, task_id):
        """Assign task to a user

        :param task_id: Id of Task
        """
        nereid_user_obj = Pool().get('nereid.user')

        task = self.get_task(task_id)

        new_assignee = nereid_user_obj.browse(int(request.form['user']))

        if self.can_write(task.parent, new_assignee):
            self.write(task.id, {
                'assigned_to': new_assignee.id
            })

            if request.is_xhr:
                return jsonify({
                    'success': True,
                })

            flash("Task assigned to %s" % new_assignee.name)
            return redirect(request.referrer)

        flash("Only employees can be assigned to tasks.")
        return redirect(request.referrer)
Example #29
0
    def render(cls, user_id, uri):
        "Render the blog post"
        NereidUser = Pool().get('nereid.user')

        if 're_captcha_public' in CONFIG.options and request.is_guest_user:
            comment_form = GuestCommentForm(
                captcha={'ip_address': request.remote_addr}
            )
        else:
            comment_form = PostCommentForm()

        user = NereidUser(user_id)

        posts = cls.search([
            ('nereid_user', '=', user.id),
            ('uri', '=', uri),
        ])
        if not posts:
            abort(404)

        # if only one post is found then it is rendered and
        # if more than one are found then the first one is rendered
        post = posts[0]

        if not (post.state == 'Published' or
                request.nereid_user == post.nereid_user):
            abort(403)

        if request.is_xhr:
            return jsonify(post.serialize())
        return render_template(
            'blog_post.jinja', post=post, comment_form=comment_form,
            poster=user
        )
Example #30
0
    def update_comment(self, task_id, comment_id):
        """
        Update a specific comment.
        """
        project_obj = Pool().get('project.work')
        nereid_user_obj = Pool().get('nereid.user')

        # allow modification only if the user is an admin or the author of
        # this ticket
        task = project_obj.browse(task_id)
        comment = self.browse(comment_id)
        assert task.type == "task"
        assert comment.project.id == task.id

        # Allow only admins and author of this comment to edit it
        if nereid_user_obj.is_project_admin(request.nereid_user) or \
                comment.updated_by == request.nereid_user:
            self.write(comment_id, {'comment': request.form['comment']})
        else:
            abort(403)

        if request.is_xhr:
            comment_record = self.browse(comment_id)
            html = render_template('comment.jinja', comment=comment_record)
            return jsonify({
                'success': True,
                'html': html,
                'state': project_obj.browse(task.id).state,
            })
        return redirect(request.referrer)
Example #31
0
    def render_task(cls, task_id, project_id):
        """
        Renders the task in a project
        """
        task = cls.get_task(task_id)

        comments = sorted(task.history + task.work.timesheet_lines +
                          task.attachments + task.repo_commits,
                          key=lambda x: x.create_date)

        hours = {}
        for line in task.work.timesheet_lines:
            hours[line.employee] = hours.setdefault(line.employee, 0) + \
                line.hours

        if request.is_xhr:
            response = cls.serialize(task)
            with Transaction().set_context(task=task_id):
                response['comments'] = [
                    comment.serialize('listing') for comment in comments
                ]
            return jsonify(response)

        return render_template('project/task.jinja',
                               task=task,
                               active_type_name='render_task_list',
                               project=task.parent,
                               comments=comments,
                               timesheet_summary=hours)
Example #32
0
File: user.py Project: 2cadz/nereid
    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')
Example #33
0
    def availability(cls, uri):
        """
        Returns the following information for a product:

        +-------------------+-----------------------------------------------+
        | quantity          | Available readily to buy                      |
        +-------------------+-----------------------------------------------+
        | forecast_quantity | Forecasted quantity, if the site needs it     |
        +-------------------+-----------------------------------------------+

        .. note::
            To modify the availability, or to send any additional information,
            it is recommended to subclass the :py:meth:`~get_availability` and
            implement your custom logic. For example, you might want to check
            stock with your vendor for back orders or send a message like
            `Only 5 pieces left`

        :param uri: URI of the product for which the availability needs to
                    be found
        :return: JSON object
        """
        try:
            product, = cls.search([
                ('displayed_on_eshop', '=', True),
                ('uri', '=', uri),
            ])
        except ValueError:
            return abort(404)

        return jsonify(product.get_availability())
Example #34
0
    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', '=', request.nereid_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')
Example #35
0
    def edit_task(self):
        """
        Edit the task
        """
        Activity = Pool().get("nereid.activity")
        Work = Pool().get("timesheet.work")

        task = self.get_task(self.id)

        Work.write([task.work], {"name": request.form.get("name")})
        self.write([task], {"comment": request.form.get("comment")})
        Activity.create(
            [
                {
                    "actor": request.nereid_user.id,
                    "object_": "project.work, %d" % task.id,
                    "verb": "edited_task",
                    "target": "project.work, %d" % task.parent.id,
                    "project": task.parent.id,
                }
            ]
        )
        if request.is_xhr:
            return jsonify({"success": True, "name": self.rec_name, "comment": self.comment})
        return redirect(request.referrer)
Example #36
0
    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)
Example #37
0
    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.'
            cart_updated.send(cart)

        flash(_(message))

        if request.is_xhr:
            return jsonify(message=message)

        return redirect(url_for('nereid.cart.view_cart'))
Example #38
0
    def render_task(cls, task_id, project_id):
        """
        Renders the task in a project
        """
        task = cls.get_task(task_id)

        comments = sorted(
            task.history + task.work.timesheet_lines + task.attachments + task.repo_commits, key=lambda x: x.create_date
        )

        hours = {}
        for line in task.work.timesheet_lines:
            hours[line.employee] = hours.setdefault(line.employee, 0) + line.hours

        if request.is_xhr:
            response = cls.serialize(task)
            with Transaction().set_context(task=task_id):
                response["comments"] = [comment.serialize("listing") for comment in comments]
            return jsonify(response)

        return render_template(
            "project/task.jinja",
            task=task,
            active_type_name="render_task_list",
            project=task.parent,
            comments=comments,
            timesheet_summary=hours,
        )
Example #39
0
    def change_constraint_dates(cls, task_id):
        """
        Change the constraint dates
        """
        Activity = Pool().get("nereid.activity")

        task = cls.get_task(task_id)

        data = {"constraint_start_time": False, "constraint_finish_time": False}

        constraint_start = request.form.get("constraint_start_time", None)
        constraint_finish = request.form.get("constraint_finish_time", None)

        if constraint_start:
            data["constraint_start_time"] = datetime.strptime(constraint_start, "%m/%d/%Y")
        if constraint_finish:
            data["constraint_finish_time"] = datetime.strptime(constraint_finish, "%m/%d/%Y")

        cls.write([task], data)
        Activity.create(
            [
                {
                    "actor": request.nereid_user.id,
                    "object_": "project.work, %d" % task.id,
                    "verb": "changed_date",
                    "project": task.parent.id,
                }
            ]
        )

        if request.is_xhr:
            return jsonify({"success": True})

        flash("The constraint dates have been changed for this task.")
        return redirect(request.referrer)
Example #40
0
    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))
Example #41
0
 def search_auto_complete(cls):
     """
     Handler for auto-completing search.
     """
     return jsonify(results=cls.auto_complete(
         request.args.get('q', '')
     ))
Example #42
0
    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"))
Example #43
0
    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'))
Example #44
0
    def edit_task(self):
        """
        Edit the task
        """
        Activity = Pool().get('nereid.activity')
        Work = Pool().get('timesheet.work')

        task = self.get_task(self.id)

        Work.write([task.work], {
            'name': request.form.get('name'),
        })
        self.write([task], {'comment': request.form.get('comment')})
        Activity.create([{
            'actor': request.nereid_user.id,
            'object_': 'project.work, %d' % task.id,
            'verb': 'edited_task',
            'target': 'project.work, %d' % task.parent.id,
            'project': task.parent.id,
        }])
        if request.is_xhr:
            return jsonify({
                'success': True,
                'name': self.rec_name,
                'comment': self.comment,
            })
        return redirect(request.referrer)
    def get_available_methods(cls):
        """Return the JSONified list of shipment gateways available

        This is a XHR only method

        If type is specified as address then an address lookup is done

        The get could be made with the following options:

        1. address
            Checks if user is logged in
            Checks if its a valid address of the user
            extracts to_address from it

        2. Individually specify the following:
            street, streetbis, city, postal_code, subdivision, country

        The subdivision and country are not expanded into the ISO codes
        or names because doing that may not be required by many methods
        and some methods may requrie codes while others require name.

        So it is better to pass the ID of the same and the get_rate
        method of each decide if they want to expand into CODE or NAME

        """
        Address = Pool().get('party.address')

        if 'address' in request.args:
            if request.is_guest_user:
                abort(403)
            # If not validated as user's address this could lead to
            # exploitation by ID
            address_id = request.args.get('address', type=int)
            if address_id not in [
                a.id for a in request.nereid_user.party.addresses
            ]:
                abort(403)
            address = Address(address_id)
            result = cls._get_available_methods(
                street=address.street,
                streetbis=address.streetbis,
                city=address.city,
                zip=address.zip,
                subdivision=address.subdivision.id,
                country=address.country.id,
            )
        else:
            # Each specified manually
            result = cls._get_available_methods(
                street=request.args.get('street'),
                streetbis=request.args.get('streetbis'),
                city=request.args.get('city'),
                zip=request.args.get('zip'),
                subdivision=int(request.args.get('subdivision')),
                country=int(request.args.get('country')),
            )
        return jsonify(
            result=[(g['id'], g['name'], g['amount']) for g in result]
        )
Example #46
0
 def country_list(cls):
     """
     Return the list of countries in JSON
     """
     return jsonify(result=[
         {'key': c.id, 'value': c.name}
         for c in request.nereid_website.countries
     ])
Example #47
0
 def profile(cls):
     """
     User profile
     """
     if request.method == "GET" and request.is_xhr:
         user, = cls.browse([request.nereid_user.id])
         return jsonify(user.serialize())
     return super(NereidUser, cls).profile()
Example #48
0
 def profile(cls):
     """
     User profile
     """
     if request.method == "GET" and request.is_xhr:
         user, = cls.browse([request.nereid_user.id])
         return jsonify(user._json())
     return super(NereidUser, cls).profile()
Example #49
0
    def get_subdivisions(self):
        """
        Returns serialized list of all subdivisions for current country
        """
        Subdivision = Pool().get('country.subdivision')

        subdivisions = Subdivision.search([('country', '=', self.id)])
        return jsonify(result=[s.serialize() for s in subdivisions])
Example #50
0
 def country_list(cls):
     """
     Return the list of countries in JSON
     """
     return jsonify(result=[
         {'key': c.id, 'value': c.name}
         for c in request.nereid_website.countries
     ])
Example #51
0
    def view_cart(cls):
        """Returns a view of the shopping cart

        This method only handles GET. Unlike previous versions
        the checkout method has been moved to nereid.checkout.x

        For XHTTP/Ajax Requests a JSON object with order and lines information
        which should be sufficient to show order information is returned.
        """
        cart = cls.open_cart()

        if request.is_xhr:
            if not cart.sale:
                # Dont try to build further if the cart is empty
                return jsonify({'empty': True})

            # Build locale formatters
            currency_format = partial(numbers.format_currency,
                                      currency=cart.sale.currency.code,
                                      locale=current_locale.language.code)
            number_format = partial(numbers.format_number,
                                    locale=current_locale.language.code)
            return jsonify(
                cart={
                    'lines': [{
                        'product': l.product and l.product.name or None,
                        'quantity': number_format(l.quantity),
                        'unit': l.unit.symbol,
                        'unit_price': currency_format(l.unit_price),
                        'amount': currency_format(l.amount),
                    } for l in cart.sale.lines],
                    'empty':
                    len(cart.sale.lines) > 0,
                    'total_amount':
                    currency_format(cart.sale.total_amount),
                    'tax_amount':
                    currency_format(cart.sale.tax_amount),
                    'untaxed_amount':
                    currency_format(cart.sale.untaxed_amount),
                })

        response = render_template('shopping-cart.jinja', cart=cart)
        response.headers['Cache-Control'] = 'max-age=0'
        return response
Example #52
0
    def update_task(self, task_id, project_id=None):
        """
        Accepts a POST request against a task_id and updates the ticket

        :param task_id: The ID of the task which needs to be updated
        """
        history_obj = Pool().get('project.work.history')

        task = self.get_task(task_id)

        history_data = {
            'project': task.id,
            'updated_by': request.nereid_user.id,
            'comment': request.form['comment']
        }

        updatable_attrs = ['state']
        post_attrs = [request.form.get(attr, None) for attr in updatable_attrs]

        if any(post_attrs):
            # Combined update of task and history since there is some value
            # posted in addition to the comment
            task_changes = {}
            for attr in updatable_attrs:
                if getattr(task, attr) != request.form[attr]:
                    task_changes[attr] = request.form[attr]

            if task_changes:
                # Only write change if anything has really changed
                self.write(task.id, task_changes)
                comment_id = self.browse(task.id).history[-1].id
                history_obj.write(comment_id, history_data)
            else:
                # just create comment since nothing really changed since this
                # update. This is to cover to cover cases where two users who
                # havent refreshed the web page close the ticket
                comment_id = history_obj.create(history_data)
        else:
            # Just comment, no update to task
            comment_id = history_obj.create(history_data)

        if request.nereid_user.id not in (p.id for p in task.participants):
            # Add the user to the participants if not already in the list
            self.write(
                task.id, {'participants': [('add', [request.nereid_user.id])]}
            )

        if request.is_xhr:
            comment_record = history_obj.browse(comment_id)
            html = render_template('comment.jinja', comment=comment_record)
            return jsonify({
                'success': True,
                'html': html,
                'state': self.browse(task.id).state,
            })
        return redirect(request.referrer)
Example #53
0
    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')))
Example #54
0
    def cms_static_list(cls, page=1):
        """
            Return JSON with list of all files inside cms static folder
        """
        StaticFile = Pool().get("nereid.static.file")

        files = Pagination(
            StaticFile,
            [('folder', '=', current_website.cms_static_folder.id)], page, 10)
        return jsonify(items=[item.serialize() for item in files])
Example #55
0
 def mark_cancelled(self):
     """
     Convert the lead as cancelled
     """
     self.cancel([self])
     if request.is_xhr or request.is_json:
         return jsonify({
             'success': True,
             'message': 'The lead is cancelled.'
         })
     return redirect(request.referrer)
Example #56
0
 def mark_converted(self):
     """
     Convert the opportunity
     """
     self.convert([self])
     if request.is_xhr or request.is_json:
         return jsonify({
             'success': True,
             'message': 'Awesome! The Opportunity is converted.'
         })
     return redirect(request.referrer)
Example #57
0
 def mark_lead(self):
     """
     Convert the opportunity to lead
     """
     self.lead([self])
     if request.is_xhr or request.is_json:
         return jsonify({
             'success': True,
             'message': 'The lead is marked back to open.'
         })
     return redirect(request.referrer)
Example #58
0
 def mark_lost(self):
     """
     Convert the lead to lost
     """
     self.lost([self])
     if request.is_xhr or request.is_json:
         return jsonify({
             'success': True,
             'message': 'The lead is marked as lost.'
         })
     return redirect(request.referrer)
Example #59
0
    def subdivision_list(cls):
        """
        Return the list of states for given country
        """
        Subdivision = Pool().get('country.subdivision')

        country = int(request.args.get('country', 0))
        if country not in [c.id for c in request.nereid_website.countries]:
            abort(404)
        subdivisions = Subdivision.search([('country', '=', country)])
        return jsonify(result=[s.serialize() for s in subdivisions])
Example #60
0
 def get_auth_token(cls):
     """
     A method that returns a login token and user information in a json
     response. This should probably be called with basic authentication in
     the header. The token generated could then be used for subsequent
     requests.
     """
     return jsonify({
         'user': current_user.serialize(),
         'token': current_user.get_auth_token(),
     })