Exemplo n.º 1
0
    def from_request(cls, products, request, query=None, **kwargs):
        if query is None:
            query = QueryString(request)
            yield chaining.update(query=query)

        if products is None:
            products = indexer.get_index('product')
            products = products.search(get_product_queryset())

        # Retrieve price from index
        if products.can_use_price_field('price'):
            products = products.with_price_field('price')

        # Handle price sorting
        if query and products.can_use_price_field('price'):
            if ('sort', 'price') in query:
                products = products.order_by_price('price')
            elif ('sort', '-price') in query:
                products = products.order_by_price('-price')

        # Filter on customer group
        if products.can_use_field('customer_group'):
            customer_group = CustomerGroup.get_current()
            products = products.filter(customer_group=customer_group)

        yield products
        products = (yield chaining.forward).result

        if not products.bare_is_set():
            # Ideally we want to fetch final prices
            products = products.set_bare(False)
            yield products
Exemplo n.º 2
0
def category(request, full_slug, **kwargs):

    # Find category
    parents = None
    categories = Category.objects.all()
    for slug in full_slug.split('/'):
        categories = Category.objects.filter(slug=slug)
        if parents is None:
            categories = categories.filter(parent__isnull=True)
        else:
            categories = categories.filter(parent__in=parents)

        # Get parent id's
        parents = categories.values_list('id', flat=True)
        if not parents:
            break

    count = categories.count()
    if count == 0:
        raise Http404("Category '{0}' not found.".format(full_slug))
    elif count > 1:
        raise Http404(
            "Category '{0}' could not be resolved.".format(full_slug)
        )

    category = categories[0]

    yield chaining.update(category=category)

    result = (yield chaining.forward).result
    if result is None:
        raise ViewNotImplemented
Exemplo n.º 3
0
    def calculate(currency=None, bare=False, **kwargs):
        if currency is None:
            currency = Currency.get_current()
            yield chaining.update(currency=currency)

        with currency.activate():
            yield chaining.forward
Exemplo n.º 4
0
    def calculate(currency=None, bare=False, **kwargs):
        if currency is None:
            currency = Currency.get_current()
            yield chaining.update(currency=currency)

        with currency.activate():
            yield chaining.forward
Exemplo n.º 5
0
def _list_products_from_request(products, request, qty=None, **kwargs):
    if qty is None:
        qty = INDEXABLE_QTYS[-1]
        yield chaining.update(qty=qty)

    if products.can_use_field('qty'):
        products = products.filter(qty=qty)
        yield products
Exemplo n.º 6
0
def customer_group_from_request(request, **kwargs):

    customer = customer_from_request(request)
    yield chaining.update(customer=customer)

    group = (yield chaining.forward).result

    if group is None and customer is not None:
        yield customer.group
Exemplo n.º 7
0
def _calculate(
    price,
    product=None,
    shipping_method=None,
    cart=None,
    order=None,
    bare=False,
    **kwargs
):

    if bare or price is None or DISCOUNT in price:
        return

    discounts = Discount.objects.none()

    if product:
        discounts = Discount.objects.filter(
            applies_to=APPLIES_TO_PRODUCT_PRICE
        ).for_product(product)
    elif shipping_method:
        discounts = Discount.objects.filter(
            applies_to=APPLIES_TO_SHIPPING_COSTS
        )
    elif cart or order:
        discounts = Discount.objects.filter(applies_to=APPLIES_TO_TOTAL)

    if 'customer_group' in kwargs:
        customer_group = kwargs['customer_group']
    else:
        CustomerGroup.current_customer_group()

    now = timezone.now()
    discounts = discounts.filter(active=True)
    discounts = discounts.filter(
        Q(valid_from__isnull=True) | Q(
            valid_from__lte=now
        )
    )
    discounts = discounts.filter(
        Q(valid_to__isnull=True) | Q(
            valid_to__gte=now
        )
    )
    discounts = discounts.filter(
        Q(customer_groups=customer_group) | Q(
            customer_groups=None
        )
    )
    discounts = discounts.polymorphic()

    for discount in discounts:
        price = discount.apply(price)

    yield chaining.update(price=price)
    yield price
Exemplo n.º 8
0
def complete(request, order=None, context=None, **kwargs):

    order = completed_order_from_request(request)
    if order is None:
        raise Http404("No order has been checked out.")

    yield chaining.update(order=order)

    result = (yield chaining.forward).result
    if result is None:
        raise ViewNotImplemented
Exemplo n.º 9
0
def product(request, product_slug, **kwargs):

    try:
        product = get_product_queryset().get(slug=product_slug)
    except Product.DoesNotExist:
        raise Http404("Product '{0}' not found.".format(product_slug))

    yield chaining.update(product=product)

    result = (yield chaining.forward).result
    if result is None:
        raise ViewNotImplemented
Exemplo n.º 10
0
def product(request, product_slug, **kwargs):

    try:
        product = get_product_queryset().get(slug=product_slug)
    except Product.DoesNotExist:
        raise Http404("Product '{0}' not found.".format(product_slug))

    yield chaining.update(product=product)

    result = (yield chaining.forward).result
    if result is None:
        raise ViewNotImplemented
Exemplo n.º 11
0
def get_mollie_payment_methods(methods=None, **kwargs):
    if methods is None:
        methods = []
        client = mollie_client()
        if client is not None:
            for method in client.methods.all():
                identifier = method['id']
                if identifier in mollie_methods:
                    cls = mollie_methods[identifier]
                    methods.append(cls(identifier, method['description']))
        yield chaining.update(methods=methods)
        yield methods
Exemplo n.º 12
0
def _calculate(
    price,
    product=None,
    shipping_method=None,
    payment_method=None,
    bare=False,
    **kwargs
):

    if bare or price is None or TAX in price:
        return

    tax_policy = settings_manager['tax_policy']
    if tax_policy:
        address_type = POLICY_CUSTOMER_ADDRESS_TYPES.get(tax_policy, None)

    zone = AddressZone.get_current(address_type)
    taxes = Tax.objects.spans(zone)
    tax_rules = TaxRule.objects.none()

    if product:
        product_classes = ProductTaxClass.objects.for_product(product)
        tax_rules = TaxRule.objects.filter(product_classes__in=product_classes)
    elif shipping_method:
        tax_rules = TaxRule.objects.filter(applies_to_shipping_costs=True)
    elif payment_method:
        tax_rules = TaxRule.objects.filter(applies_to_payment_costs=True)

    if 'customer_group' in kwargs:
        customer_group = kwargs['customer_group']
    else:
        CustomerGroup.current_customer_group()

    tax_rules = tax_rules.filter(
        Q(customer_groups=customer_group) | Q(
            customer_groups=None
        )
    )
    taxes = taxes.polymorphic().filter(tax_rules__in=tax_rules).distinct()

    for tax in taxes:
        price = tax.apply(price)

    yield chaining.update(price=price)
    yield price
Exemplo n.º 13
0
def _calculate(price,
               product=None,
               shipping_method=None,
               payment_method=None,
               bare=False,
               **kwargs):

    if bare or price is None or TAX in price:
        return

    tax_policy = settings_manager['tax_policy']
    if tax_policy:
        address_type = POLICY_CUSTOMER_ADDRESS_TYPES.get(tax_policy, None)

    zone = AddressZone.get_current(address_type)
    taxes = Tax.objects.spans(zone)
    tax_rules = TaxRule.objects.none()

    if product:
        product_classes = ProductTaxClass.objects.for_product(product)
        tax_rules = TaxRule.objects.filter(product_classes__in=product_classes)
    elif shipping_method:
        tax_rules = TaxRule.objects.filter(applies_to_shipping_costs=True)
    elif payment_method:
        tax_rules = TaxRule.objects.filter(applies_to_payment_costs=True)

    if 'customer_group' in kwargs:
        customer_group = kwargs['customer_group']
    else:
        CustomerGroup.current_customer_group()

    tax_rules = tax_rules.filter(
        Q(customer_groups=customer_group) | Q(customer_groups=None))
    taxes = taxes.polymorphic().filter(tax_rules__in=tax_rules).distinct()

    for tax in taxes:
        price = tax.apply(price)

    yield chaining.update(price=price)
    yield price
Exemplo n.º 14
0
def checkout(request, step=None, **kwargs):

    order = order_from_request(request)
    if not order:
        raise Http404("Nothing to order.")

    data = request.POST if request.method == 'POST' else None

    process = CheckoutProcess(request, order)

    # If a step is given, attempt to go to the given step
    if step:
        try:
            process.step_to(step)
        except ProcessStepNotFound:
            # If the step can not be found, fall back to
            # the latest step.
            step = None
        except ProcessError as error:
            raise Http404(error)

    # Go to the latest step
    if not step:
        try:
            process.step_to_latest()
        except ProcessError as error:
            raise Http404(error)

        yield redirect(
            reverse(
                'checkout:checkout',
                kwargs={'step': process.current_step.key},
                current_app=resolve(request.path).namespace
            )
        )

    elif data:
        # Perform atomic transactions at this point
        with transaction.atomic():
            success = process.feed(data)
            if order.may_change:
                order.calculate()

            if success:
                # Update order
                order.save()

                # Process step was successfull, redirect to next
                # step
                if not process.is_completed():
                    # Go to the next step
                    yield redirect(
                        reverse(
                            'checkout:checkout',
                            kwargs={'step': process.current_step.key},
                            current_app=resolve(request.path).namespace
                        )
                    )

        # See if we completed the process
        if process.is_completed():
            # Redirect away from this view
            request.session['completed_order'] = order.pk
            yield redirect(
                reverse(
                    'checkout:complete',
                    current_app=resolve(request.path).namespace
                )
            )


    yield chaining.update(
        order=order,
        process=process)

    if (yield chaining.forward).result is None:
        context = {'order': order}
        try:
            result = process.render(request, context=context)
        except ProcessError as error:
            raise Http404(error)

        if result is None:
            raise ViewNotImplemented
Exemplo n.º 15
0
def edit_purchase(request, purchase_id, **kwargs):

    try:
        purchase = Purchase.objects.polymorphic().get(pk=purchase_id)
    except Purchase.DoesNotExist:
        raise Http404

    cart = cart_from_request(request)
    messages = FlashMessages()
    form = EditPurchaseForm.factory(
        purchase,
        data=request.POST
    )(request.POST)

    if 'remove' in request.POST:
        cart.remove(purchase)
        messages.success(
            request, _(
                "{0} has been removed from your "
                "cart."
            ).format(purchase)
        )
    else:
        # We require a valid form
        if form.is_valid():
            try:
                purchase = Purchase.make(**form.get_edit_purchase_args())
                cart.update(purchase)
                messages.success(request, _("Your cart has been updated."))
            except PurchaseInvalid as error:
                messages.error(
                    request, _(
                        "Your cart could not be "
                        "updated."
                    )
                )
                messages.error(request, error)
        else:
            messages.error(request, _("Your cart could not be updated."))
            messages.error(request, get_error_message(form))

    # Provide default response
    yield redirect(
        reverse(
            request.POST.get(
                'next',
                request.GET.get('next', 'cart:cart')),
            current_app=resolve(request.path).namespace
        )
    )

    yield chaining.update(
        purchase=purchase,
        cart=cart,
        messages=messages)

    if (yield chaining.forward).result is None:
        raise ViewNotImplemented

    if cart.has_changed():
        cart.calculate()
        cart.save()

    messages.transmit()
Exemplo n.º 16
0
def cart(request, **kwargs):
    cart = cart_from_request(request)
    yield chaining.update(cart=cart)

    if (yield chaining.forward).result is None:
        raise ViewNotImplemented
Exemplo n.º 17
0
def _calculate(price, total=False, order=None, **kwargs):
    if order is not None and total and order.payment is not None:
        price += order.payment.costs
        yield chaining.update(price=price)
        yield price
Exemplo n.º 18
0
def registration(request, step=None, **kwargs):

    customer = customer_from_request(request)
    if request.user.is_authenticated():
        user = request.user
    else:
        user = apps.get_model(settings.AUTH_USER_MODEL)()
    customer.user = user

    data = request.POST if request.method == 'POST' else None

    process = get_registration_process(request, customer)

    # If a step is given, attempt to go to the given step
    if step:
        try:
            process.step_to(step)
        except ProcessStepNotFound:
            # If the step can not be found, fall back to
            # the latest step.
            step = None
        except ProcessError as error:
            raise Http404(error)

    # Go to the latest step
    if not step:
        try:
            process.step_to_latest()
        except ProcessError as error:
            raise Http404(error)

        # Create the redirection
        yield redirect(
            reverse(
                'account:registration',
                kwargs={'step': process.current_step.key},
                current_app=resolve(request.path).namespace
            )
        )

    elif data:
        # Perform atomic transactions at this point
        with transaction.atomic():
            if process.feed(data):
                # Update customer
                user = customer.user
                user.save()
                customer.user = user
                customer.save()

                # Process step was successfull, redirect to next
                # step
                if not process.is_completed():
                    # Go to the next step
                    yield redirect(
                        reverse(
                            'account:registration',
                            kwargs={'step': process.current_step.key},
                            current_app=resolve(request.path).namespace
                        )
                    )

        # See if we completed the process
        if process.is_completed():
            # Assign last completed order
            order = completed_order_from_request(request)
            if order is not None:
                order.customer = customer
                order.save()

            # Redirect to login view
            yield redirect(
                reverse(
                    request.POST.get(
                        'next',
                        request.GET.get('next', LOGIN_VIEW))
                )
            )

    yield chaining.update(
        customer=customer,
        process=process)

    if (yield chaining.forward).result is None:
        context = {'customer': customer}
        try:
            result = process.render(request, context=context)
        except ProcessError as error:
            raise Http404(error)

        if result is None:
            raise ViewNotImplemented
Exemplo n.º 19
0
def add_to_cart(request, **kwargs):

    cart = cart_from_request(request)
    messages = FlashMessages()
    form = AddToCartForm.factory(data=request.POST)(request.POST)

    # Create purchase
    purchase = None
    if form.is_valid():
        try:
            purchase = Purchase.make(**form.get_purchase_args())
        except PurchaseInvalid as error:
            messages.error(request, _("Could not be added to your cart."))
            messages.error(request, error)
    else:
        messages.error(request, _("Your cart could not be updated."))
        messages.error(request, get_error_message(form))

    # Add purchase to cart
    if purchase is not None:
        try:
            cart.add(purchase)
            messages.success(
                request, _(
                    "{0} has been added to your "
                    "cart."
                ).format(purchase)
            )

        except PurchaseInvalid as error:
            messages.error(
                request, _(
                    "{0} could not be added to "
                    "your cart."
                ).format(purchase)
            )
            messages.error(request, error)

    # Provide default response
    yield redirect(
        reverse(
            request.POST.get(
                'next',
                request.GET.get('next', 'cart:cart')),
            current_app=resolve(request.path).namespace
        )
    )

    yield chaining.update(
        purchase=purchase,
        cart=cart,
        messages=messages)

    if (yield chaining.forward).result is None:
        raise ViewNotImplemented

    if cart.has_changed():
        cart.calculate()
        cart.save()
        cart.track(request)

    messages.transmit()
Exemplo n.º 20
0
def _calculate(product=None, **kwargs):
    if product is not None:
        product = product.downcast()
        if product.is_variant:
            yield chaining.update(variant=product, product=product.product)