示例#1
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
        ))
示例#2
0
    def default_price_list():
        """Get the pricelist of active user. In the
        event that the logged in user does not have a pricelist set against
        the user, the channel's pricelist is chosen.

        :param user: active record of the nereid user
        """
        User = Pool().get('res.user')
        user = User(Transaction().user)
        channel_price_list = user.current_channel.price_list.id if \
            user.current_channel else None

        if not has_request_context():
            # Not a nereid request
            return channel_price_list

        # If control reaches here, then this is a nereid request. Lets try
        # and personalise the pricelist of the user logged in.
        if current_user.is_anonymous():
            # Sorry anonymous users, you get the shop price
            return channel_price_list

        if current_user.party.sale_price_list:
            # There is a sale pricelist for the specific user's party.
            return current_user.party.sale_price_list.id

        return channel_price_list
示例#3
0
def get_timezone():
    """
    Returns the timezone that should be used for this request as
    `pytz.timezone` object.  This returns `None` if used outside of
    a request.
    """
    ctx = _request_ctx_stack.top
    tzinfo = getattr(ctx, 'babel_tzinfo', None)
    if tzinfo is None:
        babel = ctx.app.extensions['babel']
        if babel.timezone_selector_func is None:
            if not current_user.is_anonymous() and current_user.timezone:
                tzinfo = timezone(current_user.timezone)
            elif ctx.request.nereid_website.company.timezone:
                tzinfo = timezone(ctx.request.nereid_website.company.timezone)
            else:
                tzinfo = babel.default_timezone
        else:
            rv = babel.timezone_selector_func()
            if rv is None:
                tzinfo = babel.default_timezone
            else:
                if isinstance(rv, basestring):
                    tzinfo = timezone(rv)
                else:
                    tzinfo = rv
        ctx.babel_tzinfo = tzinfo
    return tzinfo
示例#4
0
def get_timezone():
    """
    Returns the timezone that should be used for this request as
    `pytz.timezone` object.  This returns `None` if used outside of
    a request.
    """
    ctx = _request_ctx_stack.top
    tzinfo = getattr(ctx, 'babel_tzinfo', None)
    if tzinfo is None:
        babel = ctx.app.extensions['babel']
        if babel.timezone_selector_func is None:
            if not current_user.is_anonymous() and current_user.timezone:
                tzinfo = timezone(current_user.timezone)
            else:
                tzinfo = timezone(ctx.request.nereid_website.timezone)
        else:
            rv = babel.timezone_selector_func()
            if rv is None:
                tzinfo = babel.default_timezone
            else:
                if isinstance(rv, basestring):
                    tzinfo = timezone(rv)
                else:
                    tzinfo = rv
        ctx.babel_tzinfo = tzinfo
    return tzinfo
示例#5
0
    def get_payment_form(cls):
        '''
        Return a payment form
        '''
        NereidCart = Pool().get('nereid.cart')

        cart = NereidCart.open_cart()

        payment_form = PaymentForm()

        # add possible alternate payment_methods
        payment_form.alternate_payment_method.choices = [
            (m.id, m.name) for m in cart.get_alternate_payment_methods()
        ]

        # add profiles of the registered user
        if not current_user.is_anonymous():
            payment_form.payment_profile.choices = [
                (p.id, p.rec_name) for p in
                current_user.party.get_payment_profiles()
            ]

        if (cart.sale.shipment_address == cart.sale.invoice_address) or (
                not cart.sale.invoice_address):
            payment_form.use_shipment_address.data = "y"

        return payment_form
示例#6
0
    def get_payment_form(cls):
        '''
        Return a payment form
        '''
        NereidCart = Pool().get('nereid.cart')

        cart = NereidCart.open_cart()

        payment_form = PaymentForm()

        # add possible alternate payment_methods
        payment_form.alternate_payment_method.choices = [
            (m.id, m.name) for m in cart.get_alternate_payment_methods()
        ]

        # add profiles of the registered user
        if not current_user.is_anonymous():
            payment_form.payment_profile.choices = [
                (p.id, p.rec_name)
                for p in current_user.party.get_payment_profiles()
            ]

        if (cart.sale.shipment_address == cart.sale.invoice_address) or (
                not cart.sale.invoice_address):
            payment_form.use_shipment_address.data = "y"

        return payment_form
示例#7
0
    def render(self, confirmation=None):
        """Render given sale order

        :param sale: ID of the sale Order
        :param confirmation: If any value is provided for this field then this
                             page is considered the confirmation page. This
                             also passes a `True` if such an argument is proved
                             or a `False`
        """
        NereidUser = Pool().get('nereid.user')

        # This Ugly type hack is for a bug in previous versions where some
        # parts of the code passed confirmation as a text
        confirmation = False if confirmation is None else True

        # Try to find if the user can be shown the order
        access_code = request.values.get('access_code', None)

        if current_user.is_anonymous():
            if not access_code:
                # No access code provided, user is not authorized to
                # access order page
                return NereidUser.unauthorized_handler()
            if access_code != self.guest_access_code:
                # Invalid access code
                abort(403)
        else:
            if self.party.id != request.nereid_user.party.id:
                # Order does not belong to the user
                abort(403)

        return render_template(
            'sale.jinja', sale=self, confirmation=confirmation
        )
示例#8
0
    def default_price_list(user=None):
        """Get the pricelist of active user. In the
        event that the logged in user does not have a pricelist set against
        the user, the guest user's pricelist is chosen.

        :param user: active record of the nereid user
        """
        if not has_request_context():
            # Not a nereid request
            return None

        if user is not None and user.party.sale_price_list:
            # If a user was provided and the user has a pricelist, use
            # that
            return user.party.sale_price_list.id

        if not current_user.is_anonymous() and \
                current_user.party.sale_price_list:
            # If the currently logged in user has a pricelist defined, use
            # that
            return current_user.party.sale_price_list.id

        # Since there is no pricelist for the user, use the guest user's
        # pricelist if one is defined.
        guest_user = request.nereid_website.guest_user
        if guest_user.party.sale_price_list:
            return guest_user.party.sale_price_list.id

        return None
示例#9
0
    def default_price_list():
        """Get the pricelist of active user. In the
        event that the logged in user does not have a pricelist set against
        the user, the shop's pricelist is chosen.

        :param user: active record of the nereid user
        """
        User = Pool().get('res.user')
        user = User(Transaction().user)
        shop_price_list = user.shop.price_list.id if user.shop else None

        if not has_request_context():
            # Not a nereid request
            return shop_price_list

        # If control reaches here, then this is a nereid request. Lets try
        # and personalise the pricelist of the user logged in.
        if current_user.is_anonymous():
            # Sorry anonymous users, you get the shop price
            return shop_price_list

        if current_user.party.sale_price_list:
            # There is a sale pricelist for the specific user's party.
            return current_user.party.sale_price_list.id

        return shop_price_list
示例#10
0
 def _user_status(self):
     """
     Add facebook_id to the user_status if the user is logged in
     """
     rv = super(Website, self)._user_status()
     if not current_user.is_anonymous() and request.nereid_user.facebook_id:
         rv["facebook_id"] = request.nereid_user.facebook_id
     return rv
示例#11
0
    def confirm(cls, sales):
        "Send an email after sale is confirmed"
        super(Sale, cls).confirm(sales)

        if has_request_context():
            for sale in sales:

                # Change party name to invoice address name for guest user
                if current_user.is_anonymous():
                    sale.party.name = sale.invoice_address.name
                    sale.party.save()
示例#12
0
 def validate_payment_profile(self, payment_profile):
     """
     Checks if payment profile belongs to right party
     """
     if not current_user.is_anonymous() and \
             payment_profile.party != current_user.party:
         # verify that the payment profile belongs to the registered
         # user.
         flash(_('The payment profile chosen is invalid'))
         return redirect(
             url_for('nereid.checkout.payment_method')
         )
示例#13
0
    def _get_receiver_email_address(self):
        """
        Update reciever's email address(s)
        """
        to_emails = set()
        if self.party.email:
            to_emails.add(self.party.email.lower())
        if has_request_context() and not current_user.is_anonymous() and \
                current_user.email:
            to_emails.add(current_user.email.lower())

        return list(to_emails)
示例#14
0
    def nereid_pay_using_credit_card(self, credit_card_form, amount):
        '''
        Complete using the given card.

        If the user is registered and the save card option is given, then
        first save the card and delegate to :meth:`_complete_using_profile`
        with the profile thus obtained.

        Otherwise a payment transaction is created with the given card data.
        '''
        AddPaymentProfileWizard = Pool().get(
            'party.party.payment_profile.add', type='wizard'
        )

        gateway = request.nereid_website.credit_card_gateway

        if not current_user.is_anonymous() and \
                credit_card_form.add_card_to_profiles.data and \
                request.nereid_website.save_payment_profile:
            profile_wiz = AddPaymentProfileWizard(
                AddPaymentProfileWizard.create()[0]     # Wizard session
            )

            profile_wiz.card_info.party = self.party
            profile_wiz.card_info.address = self.invoice_address
            profile_wiz.card_info.provider = gateway.provider
            profile_wiz.card_info.gateway = gateway
            profile_wiz.card_info.owner = credit_card_form.owner.data
            profile_wiz.card_info.number = credit_card_form.number.data
            profile_wiz.card_info.expiry_month = \
                credit_card_form.expiry_month.data
            profile_wiz.card_info.expiry_year = \
                unicode(credit_card_form.expiry_year.data)
            profile_wiz.card_info.csc = credit_card_form.cvv.data

            with Transaction().set_context(return_profile=True):
                profile = profile_wiz.transition_add()
                return self.nereid_pay_using_profile(
                    profile.id, amount
                )

        return self._pay_using_credit_card(
            gateway, {
                'owner': credit_card_form.owner.data,
                'number': credit_card_form.number.data,
                'expiry_month': credit_card_form.expiry_month.data,
                'expiry_year': unicode(credit_card_form.expiry_year.data),
                'cvv': credit_card_form.cvv.data,
            },
            amount
        )
示例#15
0
    def nereid_pay_using_credit_card(self, credit_card_form, amount):
        '''
        Complete using the given card.

        If the user is registered and the save card option is given, then
        first save the card and delegate to :meth:`_complete_using_profile`
        with the profile thus obtained.

        Otherwise a payment transaction is created with the given card data.
        '''
        AddPaymentProfileWizard = Pool().get(
            'party.party.payment_profile.add', type='wizard'
        )

        gateway = request.nereid_website.credit_card_gateway

        if not current_user.is_anonymous() and \
                credit_card_form.add_card_to_profiles.data and \
                request.nereid_website.save_payment_profile:
            profile_wiz = AddPaymentProfileWizard(
                AddPaymentProfileWizard.create()[0]     # Wizard session
            )

            profile_wiz.card_info.party = self.party
            profile_wiz.card_info.address = self.invoice_address
            profile_wiz.card_info.provider = gateway.provider
            profile_wiz.card_info.gateway = gateway
            profile_wiz.card_info.owner = credit_card_form.owner.data
            profile_wiz.card_info.number = credit_card_form.number.data
            profile_wiz.card_info.expiry_month = \
                credit_card_form.expiry_month.data
            profile_wiz.card_info.expiry_year = \
                unicode(credit_card_form.expiry_year.data)
            profile_wiz.card_info.csc = credit_card_form.cvv.data

            with Transaction().set_context(return_profile=True):
                profile = profile_wiz.transition_add()
                return self.nereid_pay_using_profile(
                    profile.id, amount
                )

        return self._pay_using_credit_card(
            gateway, {
                'owner': credit_card_form.owner.data,
                'number': credit_card_form.number.data,
                'expiry_month': credit_card_form.expiry_month.data,
                'expiry_year': unicode(credit_card_form.expiry_year.data),
                'cvv': credit_card_form.cvv.data,
            },
            amount
        )
示例#16
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)
示例#17
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)
示例#18
0
    def _process_payment(cls, cart):
        """
        This is separated so that other modules can easily modify the
        behavior of processing payment independent of this module.
        """
        NereidCart = Pool().get('nereid.cart')
        PaymentProfile = Pool().get('party.payment_profile')
        PaymentMethod = Pool().get('nereid.website.payment_method')

        cart = NereidCart.open_cart()
        payment_form = cls.get_payment_form()
        credit_card_form = cls.get_credit_card_form()

        if not current_user.is_anonymous() and \
                payment_form.payment_profile.data:
            # Regd. user with payment_profile
            rv = cart.sale._add_sale_payment(
                payment_profile=PaymentProfile(
                    payment_form.payment_profile.data
                )
            )
            if isinstance(rv, BaseResponse):
                # Redirects only if payment profile is invalid.
                # Then do not confirm the order, just redirect
                return rv
            return cls.confirm_cart(cart)

        elif payment_form.alternate_payment_method.data:
            # Checkout using alternate payment method
            rv = cart.sale._add_sale_payment(
                alternate_payment_method=PaymentMethod(
                    payment_form.alternate_payment_method.data
                )
            )
            if isinstance(rv, BaseResponse):
                # If the alternate payment method introduced a
                # redirect, then save the order and go to that
                cls.confirm_cart(cart)
                return rv
            return cls.confirm_cart(cart)

        elif request.nereid_website.credit_card_gateway and \
                credit_card_form.validate():
            # validate the credit card form and checkout using that
            cart.sale._add_sale_payment(
                credit_card_form=credit_card_form
            )
            return cls.confirm_cart(cart)
示例#19
0
    def _user_status():
        """Returns the commonly required status parameters of the user

        This method could be inherited and components could be added
        """
        rv = {
            'messages': map(unicode, get_flashed_messages()),
        }
        if current_user.is_anonymous():
            rv.update({'logged_id': False})
        else:
            rv.update({
                'logged_in': True,
                'name': request.nereid_user.display_name
            })
        return rv
示例#20
0
    def create(cls, vlist):
        '''
        Create a Task and add current user as participant of the project

        :param vlist: List of dictionaries of values to create
        '''
        for values in vlist:
            if has_request_context():
                if values['type'] == 'task' and not current_user.is_anonymous():
                    values.setdefault('participants', []).append(
                        ('add', [current_user.id])
                    )
            else:
                # TODO: identify the nereid user through employee
                pass
        return super(Task, cls).create(vlist)
示例#21
0
    def create(cls, vlist):
        '''
        Create a Task and add current user as participant of the project

        :param vlist: List of dictionaries of values to create
        '''
        for values in vlist:
            if has_request_context():
                if values['type'] == 'task' and not current_user.is_anonymous(
                ):
                    values.setdefault('participants', []).append(
                        ('add', [current_user.id]))
            else:
                # TODO: identify the nereid user through employee
                pass
        return super(Task, cls).create(vlist)
示例#22
0
    def sale_price(self, quantity=0):
        """Return the Sales Price.
        A wrapper designed to work as a context variable in templating

        The price is calculated from the pricelist associated with the current
        user. The user in the case of guest user is logged in user. In the
        event that the logged in user does not have a pricelist set against
        the user, the guest user's pricelist is chosen.

        Finally if neither the guest user, nor the regsitered user has a
        pricelist set against them then the list price is displayed as the
        list price of the product

        :param quantity: Quantity
        """
        Sale = Pool().get('sale.sale')

        price_list = Sale.default_price_list()

        if current_user.is_anonymous():
            customer = request.nereid_website.guest_user.party
        else:
            customer = current_user.party

        # Build a Cache key to store in cache
        cache_key = key_from_list([
            Transaction().cursor.dbname,
            Transaction().user,
            customer.id,
            price_list,
            self.id,
            quantity,
            request.nereid_currency.id,
            'product.product.sale_price',
        ])
        price = cache.get(cache_key)
        if price is None:
            # There is a valid pricelist, now get the price
            with Transaction().set_context(
                    customer=customer.id,
                    price_list=price_list,
                    currency=request.nereid_currency.id):
                price = self.get_sale_price([self], quantity)[self.id]

            # Now convert the price to the session currency
            cache.set(cache_key, price, 60 * 5)
        return price
示例#23
0
    def sale_price(self, quantity=0):
        """Return the Sales Price.
        A wrapper designed to work as a context variable in templating

        The price is calculated from the pricelist associated with the current
        user. The user in the case of guest user is logged in user. In the
        event that the logged in user does not have a pricelist set against
        the user, the guest user's pricelist is chosen.

        Finally if neither the guest user, nor the regsitered user has a
        pricelist set against them then the list price is displayed as the
        list price of the product

        :param quantity: Quantity
        """
        Sale = Pool().get('sale.sale')

        price_list = Sale.default_price_list()

        if current_user.is_anonymous():
            customer = request.nereid_website.guest_user.party
        else:
            customer = current_user.party

        # Build a Cache key to store in cache
        cache_key = key_from_list([
            Transaction().cursor.dbname,
            Transaction().user,
            customer.id,
            price_list, self.id, quantity,
            request.nereid_currency.id,
            'product.product.sale_price',
        ])
        price = cache.get(cache_key)
        if price is None:
            # There is a valid pricelist, now get the price
            with Transaction().set_context(
                customer=customer.id,
                price_list=price_list,
                currency=request.nereid_currency.id
            ):
                price = self.get_sale_price([self], quantity)[self.id]

            # Now convert the price to the session currency
            cache.set(cache_key, price, 60 * 5)
        return price
示例#24
0
    def _user_status():
        """Returns the commonly required status parameters of the user

        This method could be inherited and components could be added
        """
        rv = {
            'messages': map(unicode, get_flashed_messages()),
        }
        if current_user.is_anonymous():
            rv.update({
                'logged_id': False
            })
        else:
            rv.update({
                'logged_in': True,
                'name': request.nereid_user.display_name
            })
        return rv
示例#25
0
    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
示例#26
0
    def _process_payment(cls, cart):
        """
        This is separated so that other modules can easily modify the
        behavior of processing payment independent of this module.
        """
        NereidCart = Pool().get('nereid.cart')

        cart = NereidCart.open_cart()
        payment_form = cls.get_payment_form()
        credit_card_form = cls.get_credit_card_form()

        amount_to_checkout = cart.sale._get_amount_to_checkout()

        if not current_user.is_anonymous() and \
                payment_form.payment_profile.data:
            # Regd. user with payment_profile
            rv = cart.sale.nereid_pay_using_profile(
                payment_form.payment_profile.data, amount_to_checkout)
            if isinstance(rv, BaseResponse):
                # Redirects only if payment profile is invalid.
                # Then do not confirm the order, just redirect
                return rv
            return cls.confirm_cart(cart)

        elif payment_form.alternate_payment_method.data:
            # Checkout using alternate payment method
            rv = cart.sale.nereid_pay_using_alternate_payment_method(
                payment_form, amount_to_checkout)
            if isinstance(rv, BaseResponse):
                # If the alternate payment method introduced a
                # redirect, then save the order and go to that
                cls.confirm_cart(cart)
                return rv
            return cls.confirm_cart(cart)

        elif request.nereid_website.credit_card_gateway and \
                credit_card_form.validate():
            # validate the credit card form and checkout using that
            cart.sale.nereid_pay_using_credit_card(credit_card_form,
                                                   amount_to_checkout)
            return cls.confirm_cart(cart)
示例#27
0
    def add_comment_to_sale(self):
        """
        Add comment to sale.

        User can add comment or note to sale order.
        """
        comment_is_allowed = False

        if self.state not in ['confirmed', 'processing']:
            abort(403)

        if current_user.is_anonymous():
            access_code = request.values.get('access_code', None)
            if access_code and access_code == self.guest_access_code:
                # No access code provided
                comment_is_allowed = True

        elif current_user.is_authenticated() and \
                current_user.party == self.party:
            comment_is_allowed = True

        if not comment_is_allowed:
            abort(403)

        if request.form.get('comment') and not self.comment \
                and self.state == 'confirmed':
            self.comment = request.form.get('comment')
            self.save()
            if request.is_xhr:
                return jsonify({
                    'message': 'Comment Added',
                    'comment': self.comment,
                })

            flash(_('Comment Added'))
        return redirect(request.referrer)
示例#28
0
    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_form = cls.get_new_address_form()

        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:    # noqa
                        # 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,
        )
示例#29
0
    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 == request.nereid_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')
        )
示例#30
0
    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,
        )
示例#31
0
    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,
        )
示例#32
0
    def new_opportunity(cls):
        """
        Web handler to create a new sale opportunity
        """
        if config.has_option('nereid', 're_captcha_public_key'):
            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')
            sale_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 = sale_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)
示例#33
0
    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 == request.nereid_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'))
示例#34
0
    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_form = cls.get_new_address_form()

        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,
        )
示例#35
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))
示例#36
0
 def default_user():
     if not current_user.is_anonymous():
         return current_user.id
示例#37
0
    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)
示例#38
0
 def default_user():
     if not current_user.is_anonymous():
         return current_user.id