Esempio n. 1
0
def delivery_options(request):
    """
    (2) Provide details on delivery options.
    """
    basket = Basket(request)
    if basket.is_empty():
        return HttpResponseRedirect('/')

    # construct delivery options form for entire basket
    items = basket.items
    choices = basket.get_delivery_choices()

    # construct form
    if request.method == 'POST':
        form = DeliveryOptionsFrom(request.POST)
        try:
            option = basket.get_delivery_options()[0]
        except IndexError:
            option = None
    else:
        option = basket.get_delivery_option_or_default()
        form = DeliveryOptionsFrom()

    # configure form with specific delivery options
    form.configure(request, choices, option)
    current_page = CurrentPage.DELIVERY_OPTIONS()

    # if the current open is not within the given set of choices,
    # then change the delivery option to the first one.
    if option:
        if option.id not in [_id for _id, _ in choices]:
            option = basket.get_default_delivery_option()
            basket.set_delivery_option(option)
            basket.save()
            basket = Basket(request)

    # form validation
    if request.method == 'POST' and form.is_valid():
        d = form.cleaned_data

        # get delivery option
        option = DeliveryOption.objects.get(pk=d.get('delivery_option'))

        # configure delivery option
        basket.set_delivery_option(option)

        # next...
        next = next_checkout_step(request, basket, current_page)
        basket.save()
        return next
    else:
        if basket.is_click_and_collect() and request.method == 'POST':
            next = next_checkout_step(request, basket, current_page)
            basket.save()
            return next

    delivery_option = basket.get_delivery_details(
        option) if option != None else None

    return {
        'basket': basket,
        'items': items,
        'form': form,
        'is_click_and_collect': basket.is_click_and_collect(),
        'delivery_option': delivery_option,
        'choices': choices
    }
Esempio n. 2
0
def update(request):
    """
    Update basket. This may also trigger "continue shopping" and "checkout".
    """
    # get prefix
    prefix = get_basket_prefix(request, request.POST)

    # get basket
    basket = Basket(request, prefix=prefix)
    return_url = get_return_url(request)

    # keep track of removed items
    removed_items = []

    def add_removed_item(item):
        removed_items.append(item)

    if not basket.is_frozen:
        # update quantity
        for item in list(basket.items):
            k = 'qty_%s' % item.hash
            if k in request.POST:
                try:
                    qty = int(request.POST.get(k, 0))
                except ValueError:
                    qty = 0

                removed = basket.update_quantity_by_hash(item.hash, qty)
                if removed:
                    add_removed_item(item)

        # remove item
        item_hash = request.POST.get('remove_basket_item', '')
        if item_hash != '':
            item = basket.remove_item_by_hash(item_hash)
            if item:
                add_removed_item(item)

        # voucher
        if 'voucher-code' in request.POST:
            voucher_code = request.POST.get('voucher-code')
            if voucher_code:
                voucher_code = voucher_code.upper()
            if voucher_code:
                if voucher_code != basket.get_voucher_code():
                    # add voucher code to basket
                    if not basket.set_voucher(voucher_code):
                        if not request.is_ajax():
                            messages.error(
                                request,
                                'Expired or unrecognised voucher code.')
            else:
                basket.remove_voucher()

        # delivery country
        if 'country_iso' in request.POST:
            try:
                country = Country.objects.get(
                    iso=request.POST.get('country_iso'))
                basket.set_delivery_country(country)
            except Country.DoesNotExist:
                pass

        # custom total (staff only)
        if request.user.is_staff or request.user.is_superuser:
            if 'custom-total' in request.POST:
                custom_total = request.POST.get('custom-total')
                if custom_total == '':
                    basket.clear_custom_total()
                else:
                    custom_total = Decimal(custom_total)
                    basket.set_custom_total(custom_total)

    # click and collect
    if 'click_and_collect' in request.POST:
        basket.set_click_and_collect(
            request.POST.get('click_and_collect') in ['true', 'on'])

    # delivery option
    option_id = request.POST.get('delivery_option_id', None)
    delivery_option_details = None
    if option_id:
        try:
            option = DeliveryOption.objects.get(pk=option_id, enabled=True)
            delivery_option_details = basket.get_delivery_details(option)
            basket.set_delivery_option(option)
        except DeliveryOption.DoesNotExist:
            pass

    # processing state (backend only)
    if request.user.is_staff or request.user.is_superuser:
        for item in list(basket.items):
            k = 'processed_%s' % item.hash
            if k in request.POST:
                processed = request.POST.get(k, 'off') == 'on'
                basket.update_processed_by_hash(item.hash, processed)

    # save changes to basket
    basket.save()

    # ajax?
    if request.is_ajax():
        basket = Basket(request, prefix=prefix)
        return to_json_response({
            'success':
            True,
            'prefix':
            basket.prefix,
            'html':
            get_basket_html(request, basket),
            'delivery':
            get_delivery_option_details_html(request, delivery_option_details),
            'is_collection_only':
            basket.is_collection_only(),
            'finance_options':
            [option.to_dict() for option in basket.get_finance_options()],
            'removed': [item.to_ga_dict() for item in removed_items]
        })

    # next
    action = request.POST.get('action', 'update')
    if action == 'continue':
        return HttpResponseRedirect(return_url)
    elif action == 'checkout':
        return HttpResponseRedirect(reverse('shop.order.delivery'))
    else:
        return HttpResponseRedirect(return_url)