예제 #1
0
def delivery(request):
    """
    (1) Start to checkout by confirming the delivery address.
    The customer is required to login for checkout first (see login).
    """
    basket = Basket(request)
    if basket.is_empty():
        return HttpResponseRedirect('/')

    # if the basket contains collection only products,
    # force click and collect
    if basket.is_collection_only():
        basket.set_click_and_collect(True)

    if request.method == 'POST':
        form = DeliveryAddressFrom(request.POST)
    else:
        billing = basket.billing_address if basket.billing_address else {}
        delivery = basket.delivery_address if basket.delivery_address else {}

        profile = None
        default = {}
        user = request.user
        if not user.is_anonymous():
            try:
                profile = get_customer_model().objects.get(user=user)
                default = {
                    'title': profile.title,
                    'first_name': user.first_name,
                    'last_name': user.last_name,
                    'email': user.email,
                    'telephone': profile.telephone
                }

                if basket.has_billing_address():
                    default.update({
                        'company': profile.company,
                        'address1': profile.address1,
                        'address2': profile.address2,
                        'address3': profile.address3,
                        'city': profile.city,
                        'country': profile.country,
                        'county': profile.county,
                        'postcode': profile.postcode
                    })
            except get_customer_model().DoesNotExist:
                pass
        else:
            default = {
                'email': request.session.get(settings.GUEST_USER_SESSION_VAR),
                'country': 'GB'
            }

        def _get(name, data, fallback=None):
            v = data.get(name)
            if v is None and fallback is not None:
                v = fallback.get(name)
            return v

        form = DeliveryAddressFrom(
            initial={
                'title':
                _get('title', billing, default),
                'first_name':
                _get('first_name', billing, default),
                'last_name':
                _get('last_name', billing, default),
                'email':
                _get('email', billing, default),
                'telephone':
                _get('telephone', billing, default),
                'company':
                _get('company', billing, default),
                'address1':
                _get('address1', billing, default),
                'address2':
                _get('address2', billing, default),
                'address3':
                _get('address3', billing, default),
                'city':
                _get('city', billing, default),
                'country':
                _get('country', billing, default),
                'county':
                _get('county', billing, default),
                'postcode':
                _get('postcode', billing, default),
                'deliver_to':
                DeliveryAddressFrom.DELIVERY_COLLECTION if basket.
                is_click_and_collect(
                ) else DeliveryAddressFrom.DELIVERY_BILLING_ADDRESS,
                'free_name':
                _get('free_name', delivery),
                'delivery_name':
                _get('name', delivery),
                'delivery_company':
                _get('company', delivery),
                'delivery_address1':
                _get('address1', delivery),
                'delivery_address2':
                _get('address2', delivery),
                'delivery_address3':
                _get('address3', delivery),
                'delivery_city':
                _get('city', delivery),
                'delivery_country':
                _get('country', delivery, default),
                'delivery_county':
                _get('county', delivery),
                'delivery_postcode':
                _get('postcode', delivery),
                'finance_option':
                basket.finance_option,
                'loan_deposit':
                basket.loan_deposit,
                'newsletter':
                basket.newsletter,
                'terms':
                basket.terms,
                'special_req':
                basket.special_req,
                'survey':
                basket.survey,
                'signup':
                basket.signup != None,
                'password':
                basket.signup.get('password') if basket.signup else None,
                'password_confirm':
                basket.signup.get('password') if basket.signup else None,
                'update_profile':
                basket.update_profile
            })

    form.configure(request, basket)
    current_page = CurrentPage.DELIVERY_ADDRESS()

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

        if 'email' in d:
            email = d.get('email')
        else:
            email = request.user.email

        # keep initial address information if we are not allowed to change the
        # billing address
        if not basket.can_edit_billing_address:
            for field in [
                    'company', 'address1', 'address2', 'address3', 'city',
                    'country', 'county', 'postcode'
            ]:
                d[field] = basket.billing_address.get(field)

        # save billing address
        basket.set_billing_address(title=d.get('title'),
                                   first_name=d.get('first_name'),
                                   last_name=d.get('last_name'),
                                   email=email,
                                   telephone=d.get('telephone'),
                                   company=d.get('company'),
                                   address1=d.get('address1'),
                                   address2=d.get('address2'),
                                   address3=d.get('address3'),
                                   city=d.get('city'),
                                   country=d.get('country'),
                                   county=d.get('county'),
                                   postcode=d.get('postcode'))

        # get delivery method
        deliver_to = d.get('deliver_to',
                           DeliveryAddressFrom.DELIVERY_BILLING_ADDRESS)

        basket.set_click_and_collect(
            deliver_to == DeliveryAddressFrom.DELIVERY_COLLECTION
            or basket.is_collection_only())
        basket.set_free_delivery_to(False)

        if deliver_to == DeliveryAddressFrom.FREE_DELIVERY_TO:
            location = basket.get_normalized_free_delivery_to_address()

            basket.set_delivery_address(name=d.get('delivery_free_name'),
                                        company=location.get('title'),
                                        address1=location.get('address1'),
                                        address2=location.get('address2'),
                                        address3=location.get('address3'),
                                        city=location.get('city'),
                                        country=location.get('country'),
                                        county=location.get('county'),
                                        postcode=location.get('postcode'))
            basket.set_free_delivery_to(True)
        elif deliver_to == DeliveryAddressFrom.DELIVERY_BILLING_ADDRESS:
            # deliver to my billing address
            basket.set_delivery_address(
                name='%s %s' % (d.get('first_name'), d.get('last_name')),
                company=d.get('company'),
                address1=d.get('address1'),
                address2=d.get('address2'),
                address3=d.get('address3'),
                city=d.get('city'),
                country=d.get('country'),
                county=d.get('county'),
                postcode=d.get('postcode'))
        elif deliver_to == DeliveryAddressFrom.DELIVERY_NEW_ADDRESS:
            # enter new delivery address
            basket.set_delivery_address(name=d.get('delivery_name'),
                                        company=d.get('delivery_company'),
                                        address1=d.get('delivery_address1'),
                                        address2=d.get('delivery_address2'),
                                        address3=d.get('delivery_address3'),
                                        city=d.get('delivery_city'),
                                        country=d.get('delivery_country'),
                                        county=d.get('delivery_county'),
                                        postcode=d.get('delivery_postcode'))

            # create a new record for the customer's profile
            if not request.user.is_anonymous():
                n = DeliveryAddress.objects.filter(
                    user=request.user,
                    address1=d.get('delivery_address1'),
                    address2=d.get('delivery_address2'),
                    address3=d.get('delivery_address3'),
                    city=d.get('delivery_city'),
                    country=d.get('delivery_country'),
                    county=d.get('delivery_county'),
                    postcode=d.get('delivery_postcode')).count()

                if n == 0:
                    address = DeliveryAddress()
                    address.user = request.user
                    address.name = d.get('delivery_name')
                    address.company = d.get('delivery_company')
                    address.address1 = d.get('delivery_address1')
                    address.address2 = d.get('delivery_address2')
                    address.address3 = d.get('delivery_address3')
                    address.city = d.get('delivery_city')
                    address.country = d.get('delivery_country')
                    address.county = d.get('delivery_county')
                    address.postcode = d.get('delivery_postcode')
                    address.save()
        else:
            if not basket.is_click_and_collect():
                # delivery to one of my delivery addresses taken from my profile
                delivery_address = DeliveryAddress.objects.get(
                    user=request.user, pk=deliver_to)
                basket.set_delivery_address(name=delivery_address.name,
                                            company=delivery_address.company,
                                            address1=delivery_address.address1,
                                            address2=delivery_address.address2,
                                            address3=delivery_address.address3,
                                            city=delivery_address.city,
                                            country=delivery_address.country,
                                            county=delivery_address.county,
                                            postcode=delivery_address.postcode)

        is_loan_available = settings.SHOP_LOAN_ENABLED and 'finance_option' in d and 'loan_deposit' in d

        if is_loan_available and deliver_to == DeliveryAddressFrom.DELIVERY_NEW_ADDRESS:
            # deliver to my billing address as it is required by law if finance option is chosen
            if d.get('finance_option'):
                basket.set_delivery_address(
                    name='%s %s' % (d.get('first_name'), d.get('last_name')),
                    company=d.get('company'),
                    address1=d.get('address1'),
                    address2=d.get('address2'),
                    address3=d.get('address3'),
                    city=d.get('city'),
                    country=d.get('country'),
                    county=d.get('county'),
                    postcode=d.get('postcode'))

        # loan application
        if is_loan_available:
            basket.set_finance_option(d.get('finance_option'))
            basket.set_loan_deposit(d.get('loan_deposit'))
        else:
            basket.set_finance_option(None)
            basket.set_loan_deposit(None)

        # newsletter
        if request.settings.mailchimp_enabled and 'newsletter' in d and d.get(
                'newsletter'):
            basket.newsletter = True

        # terms and conditions
        if request.settings.has_terms and 'terms' in d and d.get('terms'):
            basket.terms = True

        # special requiremenets
        basket.special_req = d.get('special_req')

        # survey
        basket.survey = d.get('survey') if 'survey' in d else None

        # signup?
        if d.get('signup', False) == True:
            basket.set_signup(email=d.get('email'),
                              first_name=d.get('first_name'),
                              last_name=d.get('last_name'),
                              password=d.get('password'))
        else:
            basket.clear_signup()

        # default delivery address?
        if 'update_profile' in d and d.get('update_profile'):
            basket.update_profile = True

        # next...
        next = next_checkout_step(request, basket, current_page)
        basket.save()
        return next

    # generate list of available delivery addresses from customer's profile
    if request.user.is_anonymous():
        delivery_addresses = []
    else:
        delivery_addresses = [{
            'id': i,
            'iso': addr.country.iso
        } for i, addr in enumerate(request.user.delivery_addresses.all(),
                                   start=3)]

    return {
        'basket': basket,
        'form': form,
        'delivery_addresses': to_json(delivery_addresses)
    }
예제 #2
0
파일: views.py 프로젝트: qianzy96/cubane
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)