Example #1
0
    def test_discount_met(self):
        '''
        View Basket with item in it.
        Discount is met and deducted from grand total
        banner and total shows discount is applied
        and discount is correctly applied
        '''
        # Remove all bought items
        OrderLineItem.objects.all().delete()

        # Check lesson is over discount threshold
        lesson = Lesson.objects.get(lesson_name='B Lesson')
        self.assertGreaterEqual(lesson.price, settings.DISCOUNT_THRESHOLD)

        # Add item to basket
        response = self.client.post('/basket/add_to_basket/',
                                    {'lesson_id': lesson.lesson_id},
                                    follow=True)
        self.assertContains(response, '"item_added": "True"')

        # View Basket page
        response = self.client.get('/basket/', follow=True)
        self.assertTrue(response.status_code, 200)
        self.assertTemplateUsed(response, 'basket/basket.html')

        # Send request through context processor to get current grand total
        request = response.wsgi_request
        grand_total = round(basket_contents(request)['grand_total'], 2)
        # Calculate grand total
        test_grand_total = round(lesson.price - ((lesson.price / 100) *
                                 settings.DISCOUNT_PERCENTAGE), 2)
        # Do totals match
        self.assertEqual(grand_total, test_grand_total)

        # Lesson details and price appear on webpage
        self.assertContains(response, lesson.lesson_name)
        self.assertContains(response, html.escape(f'Total: €{lesson.price}'))
        self.assertContains(
            response,
            html.escape(f'Grand Total: €{grand_total}'))
        self.assertContains(
            response,
            f'{settings.DISCOUNT_PERCENTAGE}% discount applied!')

        # Discount banner threshold met
        self.assertContains(response,
                            (f'A {settings.DISCOUNT_PERCENTAGE}% discount has '
                             'been applied to your basket!'))
Example #2
0
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    if request.method == 'POST':
        basket = request.session.get('basket', {})

        form_data = {
            'full_name': request.POST['full_name'],
            'email': request.POST['email'],
            'phone_number': request.POST['phone_number'],
            'country': request.POST['country'],
            'postcode': request.POST['postcode'],
            'town_or_city': request.POST['town_or_city'],
            'street_address1': request.POST['street_address1'],
            'street_address2': request.POST['street_address2'],
            'county': request.POST['county'],
            'preferred_service_date': request.POST['preferred_service_date'],
        }
        order_form = OrderForm(form_data)
        if order_form.is_valid():
            print("form valid")
            order = order_form.save(commit=False)
            pid = request.POST.get('client_secret').split('_secret')[0]
            order.stripe_pid = pid
            order.original_basket = json.dumps(basket)
            order.save()

            for item_id, quantity in basket.items():
                service = Services.objects.get(id=item_id)
                order_line_item = OrderLineItem(
                    order=order,
                    service=service,
                    quantity=quantity,
                )
                order_line_item.save()

            request.session['save_info'] = 'save-info' in request.POST
            return redirect(reverse('checkout_success', args=[order.order_number]))
        else:
            print("Fail")
            print(order_form.errors)
            messages.error(request, 'There was an error with your form. \
                Please double check your information.')
    else:
        print("Get")
        basket = request.session.get('basket', {})
        if not basket:
            messages.error(request, "There's nothing in your basket")
            return redirect(reverse('service_list'))

        current_basket = basket_contents(request)
        total = current_basket['grand_total']
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        if request.user.is_authenticated:
            try:
                profile = UserProfile.objects.get(user=request.user)
                order_form = OrderForm(initial={
                    'full_name': profile.user.get_full_name(),
                    'email': profile.user.email,
                    'phone_number': profile.default_phone_number,
                    'country': profile.default_country,
                    'postcode': profile.default_postcode,
                    'town_or_city': profile.default_town_or_city,
                    'street_address1': profile.default_street_address1,
                    'street_address2': profile.default_street_address2,
                    'county': profile.default_county,
                })
            except UserProfile.DoesNotExist:
                order_form = OrderForm()
        else:
            order_form = OrderForm()

    if not stripe_public_key:
        messages.warning(request, 'Stripe public key is missing. \
            Did you forget to set it in your environment?')

    template = 'checkout/checkout.html'
    context = {
        'order_form': order_form,
        'stripe_public_key': stripe_public_key,
        'client_secret': intent.client_secret,
    }

    return render(request, template, context)
Example #3
0
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    if request.method == 'POST':
        basket = request.session.get('basket', {})

        form_data = {
            'full_name': request.POST['full_name'],
            'email': request.POST['email'],
            'phone_number': request.POST['phone_number'],
            'postcode': request.POST['postcode'],
            'town_or_city': request.POST['town_or_city'],
            'street_address1': request.POST['street_address1'],
            'street_address2': request.POST['street_address2'],
            'county': request.POST['county'],
            'country': request.POST['country'],
        }

        order_form = OrderForm(form_data)
        if order_form.is_valid():
            order = order_form.save(commit=False)
            pid = request.POST.get('client_secret').split('_secret')[0]
            order.stripe_pid = pid
            order.original_basket = json.dumps(basket)
            order.save()
            for item_id, item_data in basket.items():
                try:
                    product = get_object_or_404(Product, pk=item_id)
                    product_subscription = Product_Subscription.objects.filter(product=item_id)

                    if 'item_subscription' in basket[item_id]:
                        for subs_size, quantity in item_data['item_subscription'].items():
                            prod_sub = product_subscription.filter(subscription_type=subs_size)
                            selected_product_subs = get_object_or_404(Product_Subscription, pk=prod_sub[0].id)
                            # Future enhancement - need to check if the quantity_available >= quantity
                            # before the order_line_item is saved. 
                            # If there is not enough stock then the user should be asked if they would
                            # like to purchase the quantity that is available, or to remove the item from their order
                            order_line_item = OrderLineItem(
                                order=order,
                                product=product,
                                quantity=quantity,
                                product_subscription=selected_product_subs,
                            )

                            order_line_item.save()
                    elif 'items_by_size' in basket[item_id]:
                        for subs_size, quantity in item_data['items_by_size'].items():
                            prod_sub = product_subscription.filter(size=subs_size)
                            for p in prod_sub:
                                prod_size = p.size
                            sel_prod_size = get_object_or_404(Sizes, code=prod_size)
                            selected_product_subs = get_object_or_404(Product_Subscription, pk=prod_sub[0].id)
                            # Future enhancement - need to check if the quantity_available >= quantity
                            # before the order_line_item is saved. 
                            # If there is not enough stock then the user should be asked if they would
                            # like to purchase the quantity that is available, or to remove the item from their order
                            order_line_item = OrderLineItem(
                                order=order,
                                product=product,
                                quantity=quantity,
                                product_subscription=selected_product_subs,
                                product_size=sel_prod_size,
                            )
                            order_line_item.save()
                    # Update quantity_available - reduce stock after purchase
                    if selected_product_subs.quantity_available >= quantity:
                        selected_product_subs.quantity_available -= quantity
                        selected_product_subs.save()
                    else:
                        messages.error(request, (
                            "There was an error updating the stock for this product %s"
                            % selected_product_subs.name)
                        )
                except Product.DoesNotExist:
                    messages.error(request, (
                        "A product in your basket was not found in our database."
                        "Please contact us for assistance")
                    )
                    order.delete()
                    return redirect(reverse('view_basket'))

            request.session['save_info'] = 'save-info' in request.POST
            return redirect(reverse('checkout_success', args=[order.order_number]))
        else:
            messages.error(request, 'There is an error on the form. \
                Please review the details entered')
    else:
        basket = request.session.get('basket', {})
        if not basket:
            messages.error(request, "There are no items in your basket right now")
            return redirect(reverse('products'))

        current_basket = basket_contents(request)
        total = current_basket['grand_total']
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        # Attempt to prefill the form with any info
        # the user maintains in their profile
        if request.user.is_authenticated:
            try:
                profile = UserProfile.objects.get(user=request.user)
                order_form = OrderForm(initial={
                    'full_name': profile.user.get_full_name(),
                    'email': profile.user.email,
                    'phone_number': profile.default_phone_number,
                    'country': profile.default_country,
                    'postcode': profile.default_postcode,
                    'town_or_city': profile.default_town_or_city,
                    'street_address1': profile.default_street_address1,
                    'street_address2': profile.default_street_address2,
                    'county': profile.default_county,
                })
            except UserProfile.DoesNotExist:
                order_form = OrderForm()
        else:
            order_form = OrderForm()

    if not stripe_public_key:
        messages.warning(request, 'Stripe public key has not been set.')

    template = 'checkout/checkout.html'
    context = {
        'order_form': order_form,
        'stripe_public_key': stripe_public_key,
        'client_secret': intent.client_secret,
    }

    return render(request, template, context)
Example #4
0
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    if request.method == 'POST':
        basket = request.session.get('basket', {})

        form_data = {
            'full_name': request.POST['full_name'],
            'email': request.POST['email'],
            'phone_number': request.POST['phone_number'],
            'street_address1': request.POST['street_address1'],
            'street_address2': request.POST['street_address2'],
            'town_or_city': request.POST['town_or_city'],
            'county': request.POST['county'],
            'postcode': request.POST['postcode'],
            'country': request.POST['country'],
        }
        order_form = OrderForm(form_data)
        if order_form.is_valid():
            order = order_form.save(commit=False)
            pid = request.POST.get('client_secret').split('_secret')[0]
            order.stripe_pid = pid
            order.original_basket = json.dumps(basket)
            order.save()
            for item_id, item_data in basket.items():
                try:
                    product = Product.objects.get(id=item_id)
                    if isinstance(item_data, int):
                        order_line_item = OrderLineItem(
                            order=order,
                            product=product,
                            quantity=item_data,
                        )
                        order_line_item.save()

                except Product.DoesNotExist:
                    messages.error(
                        request,
                        ("Oh no! We don't recognise some of your flowers!"
                         "Please email us for assistance!"))
                    order.delete()
                    return redirect(reverse('view_basket'))

            request.session['save_info'] = 'save-info' in request.POST
            return redirect(
                reverse('checkout_complete', args=[order.order_number]))
        else:
            messages.error(
                request, 'There was an error with your form. \
                Please double check your information.')

    else:
        basket = request.session.get('basket', {})
        if not basket:
            messages.error(
                request, "You don't have any lovely flowers in your basket!")
            return redirect(reverse('products'))

        current_basket = basket_contents(request)
        total = current_basket['grand_total']
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        if request.user.is_authenticated:
            try:
                profile = UserProfile.objects.get(user=request.user)
                order_form = OrderForm(
                    initial={
                        'full_name': profile.user.get_full_name(),
                        'email': profile.user.email,
                        'phone_number': profile.default_phone_number,
                        'street_address1': profile.default_street_address1,
                        'street_address2': profile.default_street_address2,
                        'town_or_city': profile.default_town_or_city,
                        'county': profile.default_county,
                        'postcode': profile.default_postcode,
                        'country': profile.default_country,
                    })
            except UserProfile.DoesNotExist:
                order_form = OrderForm()
        else:
            order_form = OrderForm()

    if not stripe_public_key:
        messages.warning(
            request, "Did you forget to set the Stripe Public Key? \
                 It seems to be missing!")

    template = 'checkout/checkout.html'
    context = {
        'order_form': order_form,
        'stripe_public_key': stripe_public_key,
        'client_secret': intent.client_secret,
    }

    return render(request, template, context)
Example #5
0
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    if request.method == "POST":
        basket = request.session.get("basket", {})
        print(basket)
        print("basket")
        form_data = {
            "full_name": request.POST["full_name"],
            "email": request.POST["email"],
            "phone_number": request.POST["phone_number"],
            "street_address1": request.POST["street_address1"],
            "street_address2": request.POST["street_address2"],
            "town_or_city": request.POST["town_or_city"],
            "country": request.POST["country"],
        }
        order_form = OrderForm(form_data)
        if order_form.is_valid():
            order = order_form.save(commit=False)
            print(order)
            pid = request.POST.get('client_secret').split('_secret')[0]
            order.stripe_pid = pid
            order.original_basket = json.dumps(basket)
            order.save()
            for item_id, item_data in basket.items():
                try:
                    product = Product.objects.get(id=item_id)
                    if isinstance(item_data, int):
                        order_line_item = OrderLineItem(
                            order=order,
                            product=product,
                            quantity=item_data,
                        )
                        order_line_item.save()
                except Product.DoesNotExist:
                    messages.error(request, (
                        "One of the products in your basket wasn't found in our database."
                        "Please try again!"))
                    order.delete()
                    return redirect(reverse('basket'))

            request.session['save_info'] = 'save-info' in request.POST
            return redirect(
                reverse('checkout_success', args=[order.order_number]))
        else:
            print(order_form)
            messages.error(
                request, 'There was an error with your form. \
                Please double check your information.')
    else:
        basket = request.session.get('basket', {})
        if not basket:
            messages.error(request,
                           "There's nothing in your basket at the moment")
            return redirect(reverse('products'))

        current_basket = basket_contents(request)
        total = current_basket['total']
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )
        # If the user is authenticated prefill the form with their details.

        if request.user.is_authenticated:
            try:
                profile = UserProfile.objects.get(user=request.user)
                order_form = OrderForm(
                    initial={
                        'full_name': profile.user.get_full_name(),
                        'email': profile.user.email,
                        'phone_number': profile.default_phone_number,
                        'street_address1': profile.default_street_address1,
                        'street_address2': profile.default_street_address2,
                        'town_or_city': profile.default_town_or_city,
                        'country': profile.default_country,
                    })
            except UserProfile.DoesNotExist:
                order_form = OrderForm()
        else:
            order_form = OrderForm()

    if not stripe_public_key:
        messages.warning(
            request, 'Stripe public key is missing. \
            Did you forget to set it in your environment?')
    print(intent.currency)
    print(intent.amount)
    template = 'checkout/checkout.html'
    context = {
        'order_form': order_form,
        'stripe_public_key': stripe_public_key,
        'client_secret': intent.client_secret,
    }

    return render(request, template, context)
Example #6
0
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    if request.method == 'POST':
        basket = request.session.get('basket', {})

        form_data = {
            'full_name': request.POST['full_name'],
            'email': request.POST['email'],
            'phone_number': request.POST['phone_number'],
            'country': request.POST['country'],
            'postcode': request.POST['postcode'],
            'town_or_city': request.POST['town_or_city'],
            'street_address1': request.POST['street_address1'],
            'street_address2': request.POST['street_address2'],
            'county': request.POST['county'],
        }

        order_form = OrderForm(form_data)
        if order_form.is_valid():
            order = order_form.save(commit=False)
            pid = request.POST.get('client_secret').split('_secret')[0]
            order.stripe_pid = pid
            order.original_basket = json.dumps(basket)
            order.save()
            for item_id, item_data in basket.items():
                try:
                    product = Product.objects.get(id=item_id)
                    if isinstance(item_data, int):
                        order_line_item = OrderLineItem(
                            order=order,
                            product=product,
                            quantity=item_data,
                        )
                        order_line_item.save()
                    else:
                        for size, quantity in item_data['items_by_size'].items():
                            order_line_item = OrderLineItem(
                                order=order,
                                product=product,
                                quantity=quantity,
                                product_size=size,
                            )
                            order_line_item.save()
                except Product.DoesNotExist:

                    order.delete()
                    return redirect(reverse('view_basket'))

            # Save the info to the user's profile if all is well
            request.session['save_info'] = 'save-info' in request.POST
            return redirect(reverse('checkout_success',
                            args=[order.order_number]))

    else:
        basket = request.session.get('basket', {})
        if not basket:
            return redirect(reverse('products'))

        current_basket = basket_contents(request)
        total = current_basket['grand_total']
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        if request.user.is_authenticated:
            try:
                profile = UserProfile.objects.get(user=request.user)
                order_form = OrderForm(initial={
                    'full_name': profile.user.get_full_name(),
                    'email': profile.user.email,
                    'phone_number': profile.default_phone_number,
                    'country': profile.default_country,
                    'postcode': profile.default_postcode,
                    'town_or_city': profile.default_town_or_city,
                    'street_address1': profile.default_street_address1,
                    'street_address2': profile.default_street_address2,
                    'county': profile.default_county,
                })
            except UserProfile.DoesNotExist:
                order_form = OrderForm()
        else:
            order_form = OrderForm()
            template = 'checkout/checkout.html'
            context = {
                'order_form': order_form,
                'stripe_public_key': stripe_public_key,
                'client_secret': intent.client_secret,
                }
            return render(request, template, context)
    if not stripe_public_key:

        return render(request, template, context)
def checkout(request):
    """

    Retrieve order form data
    Retrieve basket contents and create order line item(s)
    Create Stripe payment intent

    Returns:
    Checkout page, stripe public key and individual payment intent

    """
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    if request.method == 'POST':
        basket = request.session.get('basket', {})
        pid = request.POST.get('client_secret').split('_secret')[0]

        form_data = {
            'full_name': request.POST['full_name'],
            'email': request.POST['email'],
            'phone_number': request.POST['phone_number'],
            'street_address1': request.POST['street_address1'],
            'street_address2': request.POST['street_address2'],
            'town_or_city': request.POST['town_or_city'],
            'county': request.POST['county'],
            'country': request.POST['country'],
            'postcode': request.POST['postcode'],
        }

        order_form = OrderForm(form_data)

        if order_form.is_valid():
            order = order_form.save(commit=False)
            pid = request.POST.get('client_secret').split('_secret')[0]
            order.stripe_pid = pid
            order.original_basket = json.dumps(basket)
            order.save()

            for item_id, item_data in basket.items():
                try:
                    product = get_object_or_404(Product, id=item_id)
                    inventory = product.inventory

                    order_line_item = OrderLineItem(
                        order=order,
                        product=product,
                        quantity=item_data,
                    )
                    order_line_item.save()

                    # Remove items from inventory
                    if not product.inventory_updated:
                        product.remove_items_from_inventory(count=item_data,
                                                            save=True)
                        product.inventory_updated = True

                    if not product.has_inventory():
                        if not inventory >= item_data:
                            order.order_fulfilled = False
                            order.save()

                except Product.DoesNotExist:
                    messages.error(request,
                                   ("One of the products in your basket \
                            wasn't found in our database."
                                    "Please contact us for assistance"))
                    order.delete()
                    return redirect(reverse('view_basket'))

            request.session['save_info'] = 'save-info' in request.POST
            return redirect(
                reverse('checkout_success', args=[order.order_number]))

        else:
            messages.error(
                request, 'There was an error in your form. \
                Please double check your information.')

    else:
        basket = request.session.get('basket', {})
        if not basket:
            messages.error(request, "There's nothing in your basket right now")
            return redirect(reverse('products'))

        for item_id, item_data in basket.items():
            product = get_object_or_404(Product, id=item_id)
            inventory = product.inventory
            if not product.has_inventory():
                messages.error(
                    request, f"Oh no, looks like {product.name} \
                    has very recently sold out. \
                        Please remove from your basket to proceed.")
                return redirect(reverse('view_basket'))
            if inventory < item_data:
                messages.error(
                    request, f"Oh no, looks like there are only {inventory} \
                    {product.name}. \
                        Left in stock, please alter your basket to proceed.")
                return redirect(reverse('view_basket'))

        current_basket = basket_contents(request)
        total = current_basket['grand_total']
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        # Try to prefill the form with saved info
        if request.user.is_authenticated:
            try:
                profile = UserProfile.objects.get(user=request.user)
                order_form = OrderForm(
                    initial={
                        'full_name': profile.default_full_name,
                        'email': profile.user.email,
                        'phone_number': profile.default_phone_number,
                        'street_address1': profile.default_street_address1,
                        'street_address2': profile.default_street_address2,
                        'town_or_city': profile.default_town_or_city,
                        'county': profile.default_county,
                        'country': profile.default_country,
                        'postcode': profile.default_postcode,
                    })

            except UserProfile.DoesNotExist:
                order_form = OrderForm()
        else:
            order_form = OrderForm()

    if not stripe_public_key:
        messages.warning(
            request, 'Stripe public key is missing. \
            Did you forget to set it in your environment?')

    template = 'checkout/checkout.html'
    context = {
        'order_form': order_form,
        'stripe_public_key': stripe_public_key,
        'client_secret': intent.client_secret,
    }

    return render(request, template, context)
Example #8
0
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY
    profile = get_object_or_404(UserProfile, user=request.user)

    if request.method == 'POST':
        basket = request.session.get('basket', {})
        order_form = OrderForm(request.POST)

        # Confirm with stripe this order has been paid for
        try:
            payment_intent_id = (
                request.POST.get('client_secret').split('_secret')[0])
            stripe.api_key = settings.STRIPE_SECRET_KEY
            fetched_intent = stripe.PaymentIntent.retrieve(payment_intent_id, )
            paid = fetched_intent['charges']['data'][0]['paid']
        except Exception:
            messages.error(request, ("Error:  Could not confirm order with "
                                     "stripe no charges have been made."))
            return redirect(reverse('view_basket'))

        # Create order if form is valid and has been paid for
        if order_form.is_valid() and paid:
            order = order_form.save(commit=False)
            payment_intent_id = (
                request.POST.get('client_secret').split('_secret')[0])
            order.stripe_id = payment_intent_id
            order.original_basket = json.dumps(basket)
            order.profile = profile
            order.save()
            for item in basket.items():
                lesson = get_object_or_404(Lesson, lesson_id=item[0])
                order_line_item = OrderLineItem(
                    order=order,
                    lesson=lesson,
                    profile=profile,
                )
                order_line_item.save()
            return redirect(
                reverse('checkout_success', args=[order.order_number]))
        else:
            messages.error(request, ("There was an error with your form, no "
                                     "charges have been made."))
            return redirect(reverse('checkout'))

    else:
        basket = request.session.get('basket', {})
        if not basket:
            messages.error(request, "Your basket is empty")
            return redirect(reverse('home'))

        # Prepare grand total for stripe and create payment intent
        current_basket = basket_contents(request)
        total = current_basket['grand_total']
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(amount=stripe_total,
                                             currency=settings.STRIPE_CURRENCY)

        # Get full name
        full_name = ''
        if profile.first_name and profile.last_name:
            full_name = f'{profile.first_name} {profile.last_name}'

        order_form = OrderForm(initial={
            'full_name': full_name,
            'email': profile.user.email
        })

    if not stripe_public_key:
        messages.warning(request, 'Missing public key for stripe')

    template = 'checkout/checkout.html'
    context = {
        'order_form': order_form,
        'stripe_public_key': stripe_public_key,
        'client_secret': intent.client_secret,
    }

    return render(request, template, context)
Example #9
0
def checkout(request):
    """A View to return the checkout form"""

    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    if request.method == 'POST':
        basket = request.session.get('basket', {})
        form_data = {
            'first_name': request.POST['first_name'],
            'last_name': request.POST['last_name'],
            'email': request.POST['email'],
            'telephone_number': request.POST['telephone_number'],
            'street_address1': request.POST['street_address1'],
            'street_address2': request.POST['street_address2'],
            'city_town': request.POST['city_town'],
            'county_state': request.POST['county_state'],
            'postcode_zip': request.POST['postcode_zip'],
            'country': request.POST['country'],
        }
        order_form = OrderForm(form_data)
        if order_form.is_valid():
            order = order_form.save()
            for item_id, quantity in basket.items():
                try:
                    product = Product.objects.get(id=item_id)
                    order_line_item = OrderLineItem(
                        order=order,
                        product=product,
                        quantity=quantity,
                    )
                    order_line_item.save()
                except Product.DoesNotExist:
                    sweetify.error(request, title='Ooops', text='One of the products in your basket wasn\'t found!',
                 icon='error')
                    order.delete()
                    return redirect(reverse('view_basket'))
            request.session['save_info'] = 'save-info' in request.POST
            return redirect(reverse('checkout_success', args=[order.order_number]))
        else:
            sweetify.error(request, title='Ooops', text='There has been a problem with your submission',
                 icon='error')
            return redirect(reverse('store'))
    else:
        basket = request.session.get('basket', {})
        if not basket:
            sweetify.error(request, title='Ooops', text='Errrrr there is nothing in here!',
                 icon='error')
            return redirect(reverse('store'))

        current_basket = basket_contents(request)
        total = current_basket['grand_total']
        
        #Stripe
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY
        )
        order_form = OrderForm()
        template = 'checkout/checkout.html'
        context = {
            'order_form': order_form,
            'stripe_public_key': stripe_public_key, 
            'client_secret': intent.client_secret,
        }
        return render(request, template, context)
Example #10
0
def checkout(request):
    """ A view to show the checkout """

    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    if request.method == 'POST':
        bag = request.session.get('basket', {})

        form_data = {
            'full_name': request.POST['full_name'],
            'email': request.POST['email'],
            'phone_number': request.POST['phone_number'],
            'street_address1': request.POST['street_address1'],
            'street_address2': request.POST['street_address2'],
            'town_or_city': request.POST['town_or_city'],
            'county': request.POST['county'],
            'post_code': request.POST['post_code'],
            'country': request.POST['country'],
        }
        order_form = OrderForm(form_data)

        if order_form.is_valid():
            order = order_form.save(commit=False)
            pid = request.POST.get('client_secret').split('_secret')[0]
            order.stripe_pid = pid
            order.original_bag = json.dumps(bag)
            order.save()

            for item_id, item_data in bag.items():
                try:
                    product = get_object_or_404(Product, pk=item_id)
                    if isinstance(item_data, int):
                        order_line_item = OrderLineItem(
                            order=order,
                            product=product,
                            quantity=item_data
                        )
                        order_line_item.save()
                    else:
                        for size, quantity in item_data['items_by_size'].items():
                            order_line_item = OrderLineItem(
                                order=order,
                                product=product,
                                quantity=quantity,
                                product_size=size
                            )
                            order_line_item.save()
                except product.DoesNotExist:
                    messages.error(request, (
                        "One of the products in your basket does not exist.",
                        "Please call us for assistance"))
                    order.delete()
                    return redirect(reverse('view_basket'))
            request.session['save_info'] = 'save_info' in request.POST
            return redirect(reverse('checkout_success', args=[order.order_number]))

        else:
            messages.error(request, 'There was error in your form. \
                Please double check the details you have entered')
    else:
        bag = request.session.get('basket', {})
        if not bag:
            messages.error(request, "You haven't added anything to your basket!")
            return redirect(reverse('products'))

        current_basket = basket_contents(request)
        total = current_basket['grand_total']
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

    if request.user.is_authenticated:
        try:
            profile = UserProfile.objects.get(user=request.user)
            order_form = OrderForm(initial={
                'full_name': profile.user.get_full_name(),
                'email': profile.user.email,
                'phone_number': profile.default_phone_number,
                'street_address1': profile.default_street_address1,
                'street_address2': profile.default_street_address2,
                'town_or_city': profile.default_town_or_city,
                'county': profile.default_county,
                'post_code': profile.default_post_code,
                'country': profile.default_country,
            })
        except UserProfile.DoesNotExist:
            order_form = OrderForm()
    else:
        order_form = OrderForm()

    if not stripe_public_key:
        messages.warning(request,
                         'Did you forget to set your stripe public \
                          key in your environment variables?')

    order_form = OrderForm()
    template = 'checkout/checkout.html'

    context = {
        'order_form': order_form,
        'stripe_public_key': stripe_public_key,
        'client_secret': intent.client_secret,
    }

    return render(request, template, context)
Example #11
0
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    if request.method == 'POST':
        basket = request.session.get('basket', {})
        form_data = {
            'full_name': request.POST['full_name'],
            'email': request.POST['email'],
            'phone_number': request.POST['phone_number'],
            'country': request.POST['country'],
            'postcode': request.POST['postcode'],
            'town_or_city': request.POST['town_or_city'],
            'street_address': request.POST['street_address'],
        }
        receipt_form = ReceiptForm(form_data)
        if receipt_form.is_valid():
            receipt = receipt_form.save(commit=False)
            pid = request.POST.get('client_secret').split('_secret')[0]
            receipt.stripe_pid = pid
            receipt.original_basket = json.dumps(basket)
            receipt.save()
            for item_id, quantity in basket.items():
                try:
                    product = Product.objects.get(id=item_id)
                    receipt_line_item = ReceiptLineItem(
                        receipt=receipt,
                        product=product,
                        quantity=quantity,
                    )
                    receipt_line_item.save()
                except Product.DoesNotExist:
                    messages.error(request, ("One of the products in your \
                        basket wasn't found in our database. "
                                             "Please call us for assistance!"))
                    receipt.delete()
                    return redirect(reverse('basket_view'))

            request.session['save_info'] = 'save-info' in request.POST
            return redirect(
                reverse('checkout_success', args=[receipt.receipt_number]))
        else:
            messages.error(
                request, 'There was an error with your form. \
                Please check your detail information.')
    else:
        basket = request.session.get('basket', {})
        if not basket:
            messages.error(request, 'There is no item in your basket!')
            return redirect(reverse('products'))

        current_basket = basket_contents(request)
        total_plus_tax = current_basket['total_plus_tax']
        stripe_total_plus_tax = round(total_plus_tax * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total_plus_tax,
            currency=settings.STRIPE_CURRENCY,
        )

        if request.user.is_authenticated:
            try:
                profile = UserProfile.objects.get(user=request.user)
                receipt_form = ReceiptForm(
                    initial={
                        'full_name': profile.user.get_full_name(),
                        'email': profile.user.email,
                        'phone_number': profile.default_phone_number,
                        'country': profile.default_country,
                        'postcode': profile.default_postcode,
                        'town_or_city': profile.default_town_or_city,
                        'street_address': profile.default_street_address,
                    })
            except UserProfile.DoesNotExist:
                receipt_form = ReceiptForm()
        else:
            receipt_form = ReceiptForm()

    if not stripe_public_key:
        messages.warning(
            request, 'Stripe public key is missing. \
            Check your setting environment?')

    template = 'checkout/checkout.html'
    context = {
        'receipt_form': receipt_form,
        'stripe_public_key': stripe_public_key,
        'client_secret': intent.client_secret,
    }

    return render(request, template, context)
Example #12
0
def checkout(request):
    """
    Creates order from basket items, takes payment through Stripe and
    emails user receipt
    """
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY
    if request.method == 'POST':
        basket = request.session.get('basket', {})
        form_data = {
            'fullname': request.POST['fullname'],
            'phone_number': request.POST['phone_number'],
            'address_line1': request.POST['address_line1'],
            'address_line2': request.POST['address_line2'],
            'town_city': request.POST['town_city'],
            'postcode': request.POST['postcode'],
            'country': request.POST['country'],
        }
        order_form = OrderForm(form_data)

        if order_form.is_valid():
            order = order_form.save(commit=False)
            order.order_user = request.user
            order.save()
            for id, quantity in basket.items():
                try:
                    product = Products.objects.get(pk=id)
                    order_item = OrderItem(order=order,
                                           product=product,
                                           quantity=quantity)
                    order_item.save()
                    del request.session['basket']
                    del request.session['product_count']
                    request.session.modified = True

                    context = {
                        'order': order,
                    }
                    from_email = os.environ.get('EMAIL_USER')
                    user = request.user
                    header = "Tartan Thom Receipt"
                    html_message = render_to_string('checkout/receipt.html',
                                                    context)
                    plain_message = strip_tags(html_message)
                    send_mail(header,
                              plain_message,
                              from_email, [user.email],
                              html_message=html_message,
                              fail_silently=False)

                except Products.DoesNotExist:
                    order.delete()
            return redirect(
                reverse('checkout:checkout_success',
                        args=[order.order_number]))
        else:
            messages.error(request,
                           "Please review the details in the order form")
    else:
        basket = request.session.get('basket', {})
        current_contents = basket_contents(request)
        grand_total = current_contents['grand_total']
        stripe_total = round(grand_total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(amount=stripe_total,
                                             currency=settings.STRIPE_CURRENCY)
        order_form = OrderForm()
        context = {
            'order_form': order_form,
            'stripe_public_key': stripe_public_key,
            'client_secret': intent.client_secret,
        }

    return render(request, 'checkout/checkout.html', context)
Example #13
0
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    if request.method == 'POST':
        basket = request.session.get('basket', {})

        form_data = {
            'full_name': request.POST['full_name'],
            'email': request.POST['email'],
            'phone_number': request.POST['phone_number'],
            'country': request.POST['country'],
            'postcode': request.POST['postcode'],
            'town_or_city': request.POST['town_or_city'],
            'street_address1': request.POST['street_address1'],
            'street_address2': request.POST['street_address2'],
            'county': request.POST['county'],
        }
        order_form = OrderForm(form_data)
        if order_form.is_valid():
            order = order_form.save(commit=False)
            pid = request.POST.get('client_secret').split('_secret')[0]
            order.stripe_pid = pid
            order.original_basket = json.dumps(basket)
            order.save()
            for item_id, item_data in basket.items():
                try:
                    artwork = Artworks.objects.get(id=item_id)
                    if isinstance(item_data, int):
                        order_item = OrderItems(
                            order=order,
                            artworks=artwork,
                            quantity=item_data,
                        )
                        order_item.save()
                except Artworks.DoesNotExist:
                    messages.error(request, (
                        "One of the artworks in your basket wasn't found."
                        "Please call us for assistance!")
                    )
                    order.delete()
                    return redirect(reverse('view_basket'))

            request.session['save_info'] = 'save-info' in request.POST
            return redirect(reverse('checkout_success',
                            args=[order.order_number]))
        else:
            messages.error(request, 'There was an error with your form. \
                Please double check your information.')
    else:
        basket = request.session.get('basket', {})
        if not basket:
            messages.error(request, "There's nothing in your basket")
            return redirect(reverse('artworks'))

        current_basket = basket_contents(request)
        total = current_basket['grand_total']
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        # Attempt to prefill the form with any info
        #  the user maintains in their profile
        if request.user.is_authenticated:
            try:
                profile = Patron.objects.get(user=request.user)
                order_form = OrderForm(initial={
                    'full_name': profile.user.get_full_name(),
                    'email': profile.default_email,
                    'phone_number': profile.default_phone_number,
                    'country': profile.default_country,
                    'postcode': profile.default_postcode,
                    'town_or_city': profile.default_town_or_city,
                    'street_address1': profile.default_street_address1,
                    'street_address2': profile.default_street_address2,
                    'county': profile.default_county,
                })
            except Patron.DoesNotExist:
                order_form = OrderForm()
        else:
            order_form = OrderForm()

    if not stripe_public_key:
        messages.warning(request, 'Stripe public key is missing. \
            Did you forget to set it in your environment?')

    template = 'checkout/checkout.html'
    context = {
        'order_form': order_form,
        'stripe_public_key': stripe_public_key,
        'client_secret': intent.client_secret,
    }

    return render(request, template, context)
Example #14
0
def checkout(request):
    """A view to display checkout page """
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    if request.method == 'POST':
        basket = request.session.get('basket', {})

        form_data = {
            'full_name': request.POST['full_name'],
            'email': request.POST['email'],
            'phone_number': request.POST['phone_number'],
            'street_address1': request.POST['street_address1'],
            'street_address2': request.POST['street_address2'],
            'postcode': request.POST['postcode'],
            'town_or_city': request.POST['town_or_city'],
        }

        form = OrderForm(form_data)

        if form.is_valid():
            order = form.save(commit=False)
            pid = request.POST.get('client_secret').split('_secret')[0]
            order.stripe_pid = pid
            order.original_basket = json.dumps(basket)
            order.save()
            for item_id, item_data in basket.items():
                try:
                    product = Deal.objects.get(id=item_id)
                    if isinstance(item_data, int):
                        order_line_item = OrderLineItem(order=order,
                                                        product=product,
                                                        quantity=item_data)
                        order_line_item.save()
                except Deal.DoesNotExist:
                    messages.error(
                        request,
                        "One of the items in your basket wasn't found in our database. Please contact us for help"
                    )
                    order.delete()
                    return redirect(reverse('view_basket'))

            request.session['save_info'] = 'save-info' in request.POST
            return redirect(
                reverse('checkout_success', args=[order.order_number]))
        else:
            messages.error(
                request, 'There was an error with your form. Please try again')
    else:
        basket = request.session.get('basket', {})
        if not basket:
            messages.error(
                request, "There is nothing in your basket, please add an item")
            return redirect(reverse('deals'))

        form = forms.OrderForm
        current_basket = basket_contents(request)
        total = current_basket['total']
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        if not stripe_public_key:
            messages.warning(
                request, 'Stripepublic key is missing. \
                Please add this information')

    context = {
        'form': form,
        'stripe_public_key': stripe_public_key,
        'client_secret': intent.client_secret,
    }
    return render(request, 'checkout/checkout.html', context)
Example #15
0
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    if request.method == 'POST':
        basket = request.session.get('basket', {})

        form_data = {
            'first_name': request.POST['first_name'],
            'last_name': request.POST['last_name'],
            'email': request.POST['email'],
            'phone_number': request.POST['phone_number'],
            'street_address_1': request.POST['street_address_1'],
            'street_address_2': request.POST['street_address_2'],
            'postcode': request.POST['postcode'],
            'town': request.POST['town'],
            'county': request.POST['county'],
        }
        order_form = OrderForm(form_data)
        if order_form.is_valid():
            order = order_form.save()
            for item_id, item_data in basket.items():
                try:
                    product = Product.objects.get(id=item_id)
                    if isinstance(item_data, int):
                        order_line_item = OrderLineItem(
                            order=order,
                            product=product,
                            quantity=item_data,
                        )
                        order_line_item.save()
                    else:
                        for size, quantity in item_data['items_by_size'].items(
                        ):
                            order_line_item = OrderLineItem(
                                order=order,
                                product=product,
                                quantity=quantity,
                                product_size=size,
                            )
                            order_line_item.save()
                except Product.DoesNotExist:
                    messages.error(request,
                                   ("Item not found."
                                    "Please contact us for assistance!"))
                    order.delete()
                    return redirect(reverse('basket'))

            request.session['save_info'] = 'save-info' in request.POST
            return redirect(
                reverse('checkout_success', args=[order.order_number]))
        else:
            messages.error(
                request, 'There was an error with your form. \
                Please double check your information.')
    else:
        basket = request.session.get('basket', {})
        if not basket:
            messages.error(request, "There are no items in your basket")
            return redirect(reverse('catalogue'))

        current_basket = basket_contents(request)
        total = current_basket['grand_total']
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        if request.user.is_authenticated:
            try:
                profile = UserProfile.objects.get(user=request.user)
                order_form = OrderForm(
                    initial={
                        'full_name': profile.user.get_full_name(),
                        'email': profile.user.email,
                        'phone_number': profile.default_phone_number,
                        'postcode': profile.default_postcode,
                        'town': profile.default_town,
                        'street_address_1': profile.default_street_address_1,
                        'street_address_2': profile.default_street_address_2,
                        'county': profile.default_county,
                    })
            except UserProfile.DoesNotExist:
                order_form = OrderForm()
        else:
            order_form = OrderForm()

    if not stripe_public_key:
        messages.warning(request, 'Missing stripe public key')

    template = 'checkout/checkout.html'
    context = {
        'order_form': order_form,
        'stripe_public_key': stripe_public_key,
        'client_secret': intent.client_secret,
    }

    return render(request, template, context)
Example #16
0
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    # Checking if the method is 'POST and getting the 'basket'
    if request.method == 'POST':
        basket = request.session.get('basket', {})
        # Putting 'form_data' into dictionary so we can create its instance
        form_data = {
            'full_name': request.POST['full_name'],
            'email': request.POST['email'],
            'phone_number': request.POST['phone_number'],
            'country': request.POST['country'],
            'postcode': request.POST['postcode'],
            'town_or_city': request.POST['town_or_city'],
            'street_address1': request.POST['street_address1'],
            'street_address2': request.POST['street_address2'],
            'county': request.POST['county'],
        }
        order_form = OrderForm(form_data)

        #   1.We get the 'product_id' out of the basket.
        #   2.If its value is an integer we know we're
        #   working with an item that doesn't have sizes
        #   so the quantity will be the 'item_data'.
        #   3.If the item has sizes, iterate through each
        #   size and create a 'line_item' accordingly.
        #   4.If a product isn't found, add an error message.
        #   5.Delete the empty order and return the user to
        #   the shopping basket page.

        if order_form.is_valid():
            # Needed for the order number to be passed as an argument
            # Prevent multiple save events from being executed
            order = order_form.save(commit=False)
            # Split at the word 'secret', the first part of it is
            # the 'PaymentIntent' id
            pid = request.POST.get('client_secret').split('_secret')[0]
            order.stripe_pid = pid
            order.original_basket = json.dumps(basket)
            order.save()
            for item_id, item_data in basket.items():
                try:
                    product = Product.objects.get(id=item_id)
                    if isinstance(item_data, int):
                        order_line_item = OrderLineItem(
                            order=order,
                            product=product,
                            quantity=item_data,
                        )
                        order_line_item.save()
                    else:
                        for size, quantity in item_data['items_by_size'].items(
                        ):
                            order_line_item = OrderLineItem(
                                order=order,
                                product=product,
                                quantity=quantity,
                                product_size=size,
                            )
                            order_line_item.save()
                except Product.DoesNotExist:
                    messages.error(request, (
                        "One of the products in your basket wasn't found in our database."
                        "Please call us for assistance!"))
                    order.delete()
                    return redirect(reverse('view_basket'))

            #   Check if the user wants to save their profile
            #   information to the
            #   session. Then, redirect them to a 'checkout_success' page.

            request.session['save_info'] = 'save-info' in request.POST
            return redirect(
                reverse('checkout_success', args=[order.order_number]))
        else:
            messages.error(
                request, 'There was an error with your form. \
                Please double check your information.')
    else:

        #   Getting basket from the session, if nothins in the basket,
        #   print error message. Afterwards, redirect ot products page

        basket = request.session.get('basket', {})
        if not basket:
            messages.error(request,
                           "There's nothing in your basket at the moment")
            return redirect(reverse('products'))

        current_basket = basket_contents(request)
        total = current_basket['grand_total']
        # Stripe requires the amount to charge as an int
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        # Payemnt intent
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )
        #   Check if the user is authenticated
        #   If yes, get their profile and use
        #   the initial parameter on the order form
        #   to fill all its fields with the relevant information
        if request.user.is_authenticated:
            try:
                profile = UserProfile.objects.get(user=request.user)
                order_form = OrderForm(
                    initial={
                        'full_name': profile.user.get_full_name(),
                        'email': profile.user.email,
                        'phone_number': profile.default_phone_number,
                        'country': profile.default_country,
                        'postcode': profile.default_postcode,
                        'town_or_city': profile.default_town_or_city,
                        'street_address1': profile.default_street_address1,
                        'street_address2': profile.default_street_address2,
                        'county': profile.default_county,
                    })
            #   If the user is not authenticated, render an empty form
            except UserProfile.DoesNotExist:
                order_form = OrderForm()
        else:
            # Create instance of the order form and render it out
            order_form = OrderForm()

    # Alert message if you forgot to set STRIPE_PUBLIC_KEY
    if not stripe_public_key:
        messages.warning(request, 'Stripe public key is not found')

    template = 'checkout/checkout.html'
    context = {
        'order_form': order_form,
        'stripe_public_key': stripe_public_key,
        'client_secret': intent.client_secret,
    }

    return render(request, template, context)
Example #17
0
def checkout(request):
    """ Gets info from user profile, processes payment """
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    if request.method == 'POST':
        basket = request.session.get('basket', {})
        form_data = {
            'full_name': request.POST['full_name'],
            'email': request.POST['email'],
            'phone_number': request.POST['phone_number'],
            'country': request.POST['country'],
            'postcode': request.POST['postcode'],
            'town_or_city': request.POST['town_or_city'],
            'street_address1': request.POST['street_address1'],
            'street_address2': request.POST['street_address2'],
            'county': request.POST['county'],
        }
        order_form = OrderForm(form_data)
        if order_form.is_valid():
            order = order_form.save(commit=False)
            pid = request.POST.get('client_secret').split('_secret')[0]
            order.stripe_pid = pid
            order.original_basket = json.dumps(basket)
            order.save()
            for item_id, quantity in basket.items():
                """ iterates through basket items """
                try:
                    """ saves each basket item as order line item """
                    product = Product.objects.get(id=item_id)
                    order_line_item = OrderLineItem(
                        order=order,
                        product=product,
                        quantity=quantity,
                    )
                    order_line_item.save()
                except Product.DoesNotExist:
                    """ if produce doesn't exist in database, shows error message and redirects to basket """
                    messages.error(request, (
                        "One of the products in your basket wasn't found in our database. Please get in touch so we can help."
                    ))
                    order.delete()
                    return redirect(reverse('view_basket'))
            """ Checks whether user ticks box to save details """
            request.session['save_info'] = 'save-info' in request.POST
            return redirect(
                reverse('checkout_success', args=[order.order_number]))
        else:
            """ ie, if order_form is not valid """
            messages.error(
                request,
                'Error. Please check the details on your payment form.')
    else:
        """ ie, if request.method == 'GET' """
        basket = request.session.get('basket', {})
        if not basket:
            messages.error(request, "There's nothing in your basket.")
            return redirect(reverse('products'))

        current_basket = basket_contents(request)
        total = current_basket['grand_total']
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        if request.user.is_authenticated:
            try:
                profile = UserProfile.objects.get(user=request.user)
                order_form = OrderForm(
                    initial={
                        'full_name': profile.default_full_name,
                        'email': profile.user.email,
                        'phone_number': profile.default_phone_number,
                        'country': profile.default_country,
                        'postcode': profile.default_postcode,
                        'town_or_city': profile.default_town_or_city,
                        'street_address1': profile.default_street_address1,
                        'street_address2': profile.default_street_address2,
                        'county': profile.default_county,
                    })
            except UserProfile.DoesNotExist:
                order_form = OrderForm()
        else:
            order_form = OrderForm()

    if not stripe_public_key:
        messages.warning(request, 'Did you forget to set your public key?')

    template = 'checkout/checkout.html'
    context = {
        'order_form': order_form,
        'stripe_public_key': stripe_public_key,
        'client_secret': intent.client_secret,
    }

    return render(request, template, context)
Example #18
0
def checkout(request):
    """
    A view to return the checkout by card page
    """
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    basket = request.session.get('basket', {})

    if not basket:
        messages.error(request, 'There are no products in your basket')
        return redirect(reverse, 'show_basket')

    # stripe
    current_basket = basket_contents(request)
    total = current_basket['basket_total']
    stripe_total = round(total*100)
    stripe.api_key = stripe_secret_key
    intent = stripe.PaymentIntent.create(
        amount=stripe_total,
        currency=settings.STRIPE_CURRENCY,
    )

    user = request.user
    delivery_form = UserDeliveryAddressForm()
    delivery_addresses = None
    delivery_address_forms = [delivery_form]

    DeliveryFormSet = modelformset_factory(
        DeliveryAddress, UserDeliveryAddressForm)

    if user.is_authenticated:
        user_profile = get_object_or_404(UserProfile, user=user)
        order_form = UserProfileForm(instance=user_profile)

        if request.method == 'POST':
            # save any changes or new addresses authenticated user has made

            my_formset = DeliveryFormSet(
                request.POST, request.FILES)
            if my_formset.is_valid():
                for form in my_formset.forms:
                    form = form.save(commit=False)
                    if form.address_ref == '':
                        continue
                    else:
                        form.address_ref = form.address_ref.replace(
                            ' ', '-')
                        form.user = user_profile
                        form.save()
            else:
                messages.error(
                    request, 'One of your forms is invalid, please check and try again')

            # get the address reference of the delivery address selected on the checkout page
            if 'delivery_address_ref' in request.session:
                address_ref = request.session.get(
                    'delivery_address_ref', 'None')

            # default to the billing address
            if not address_ref:
                customer_name = user_profile.full_name
                phone_number = user_profile.default_phone_number
                order_address_line1 = user_profile.billing_address_line1
                order_address_line2 = user_profile.billing_address_line2
                order_town_or_city = user_profile.billing_town_or_city
                order_county = user_profile.billing_county
                order_country = user_profile.billing_country
                order_post_code = user_profile.billing_post_code
            else:
                # use the shipping address selected by user
                order_delivery_address = get_object_or_404(
                    DeliveryAddress, user=user_profile, address_ref=address_ref)
                customer_name = order_delivery_address.contact_name
                phone_number = order_delivery_address.contact_phone_number
                order_address_line1 = order_delivery_address.address_line1
                order_address_line2 = order_delivery_address.address_line2
                order_town_or_city = order_delivery_address.town_or_city
                order_county = order_delivery_address.county
                order_country = order_delivery_address.country
                order_post_code = order_delivery_address.post_code

            form_data = {
                'customer_name': customer_name,
                'email': user_profile.email,
                'phone_number': phone_number,
                'order_address_line1': order_address_line1,
                'order_address_line2': order_address_line2,
                'order_town_or_city': order_town_or_city,
                'order_county': order_county,
                'order_country': order_country,
                'order_post_code': order_post_code,
            }
            order_form = OrderForm(form_data)

            if order_form.is_valid():
                order = order_form.save(commit=False)
                order.user_profile = user_profile
                order.payment_processor = 'Stripe'
                client_secret = request.POST.get(
                    'client_secret').split('_secret')[0]
                order.payment_id = client_secret
                order.original_basket = json.dumps(basket)
                order.save()

                favourites = []
                for item_id, item_qty in basket.items():
                    try:
                        product = get_object_or_404(Product, pk=item_id)
                        order_line = OrderItem(
                            order=order,
                            product=product,
                            quantity=item_qty,
                        )
                        order_line.save()
                        # add purchased products to user favourites
                        if not user_profile.favourites:
                            favourites.append(int(product.id))
                            user_profile.favourites = json.dumps(favourites)
                            user_profile.save()
                        else:
                            favourites = json.loads(user_profile.favourites)
                            favourites.append(int(product.id))
                            favourites = list(dict.fromkeys(favourites))
                            user_profile.favourites = json.dumps(favourites)
                            user_profile.save()
                    except Product.DoesNotExist:
                        messages.error(
                            request, 'One of the products in your basket no longer exists in our catalogue. \
                                please empty your basket and try again')
                        order.delete()
                        return redirect(reverse('show_basket'))

                return redirect(reverse('checkout_success', args=[order.order_number]))
            else:
                messages.error(
                    request, 'There was an error in your form. Please check and try again')

        delivery_addresses = DeliveryAddress.objects.filter(user=user_profile)
        delivery_address_forms = DeliveryFormSet(
            queryset=delivery_addresses)
    else:
        if request.method == 'POST':
            form_data = {
                'customer_name': request.POST['customer_name'],
                'email': request.POST['email'],
                'phone_number': request.POST['phone_number'],
                'order_address_line1': request.POST['order_address_line1'],
                'order_address_line2': request.POST['order_address_line2'],
                'order_town_or_city': request.POST['order_town_or_city'],
                'order_county': request.POST['order_county'],
                'order_country': request.POST['order_country'],
                'order_post_code': request.POST['order_post_code'],
            }
            order_form = OrderForm(form_data)
            if order_form.is_valid():
                order = order_form.save(commit=False)
                order.payment_processor = 'Stripe'
                client_secret = request.POST.get(
                    'client_secret').split('_secret')[0]
                order.payment_id = client_secret
                order.original_basket = json.dumps(basket)
                order.save()

                for item_id, item_qty in basket.items():
                    try:
                        product = get_object_or_404(Product, pk=item_id)
                        order_line = OrderItem(
                            order=order,
                            product=product,
                            quantity=item_qty,
                        )
                        order_line.save()
                    except Product.DoesNotExist:
                        messages.error(
                            request, 'One of the products in your basket no longer exists in our catalogue. \
                                please empty your basket and try again')
                        order.delete()
                        return redirect(reverse('show_basket'))
                return redirect(reverse('checkout_success', args=[order.order_number]))
            else:
                messages.error(
                    request, 'There was an error in your form. Please check and try again')

        order_form = OrderForm()

    context = {
        'form': order_form,
        'delivery_addresses': delivery_addresses,
        'delivery_forms': delivery_address_forms,
        'stripe_public_key': stripe_public_key,
        'client_secret': intent.client_secret,
    }

    return render(request, 'checkout/checkout.html', context)
Example #19
0
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    if request.method == 'POST':
        basket = request.session.get('basket', {})

        form_data = {
            'full_name': request.POST['full_name'],
            'email': request.POST['email'],
            'phone_number': request.POST['phone_number'],
            'country': request.POST['country'],
            'postcode': request.POST['postcode'],
            'town_or_city': request.POST['town_or_city'],
            'street_address1': request.POST['street_address1'],
            'street_address2': request.POST['street_address2'],
            'county': request.POST['county'],
        }
        order_form = OrderForm(form_data)
        if order_form.is_valid():
            order = order_form.save(commit=False)
            pid = request.POST.get('client_secret').split('_secret')[0]
            order.stripe_pid = pid
            order.original_basket = json.dumps(basket)
            order.save()
            updatedFields = {
                'order_number': order.order_number,
                'order_date': order.date
            }
            for item_id, item_data in basket.items():
                try:
                    product = Product.objects.get(id=item_id)
                    if product.category.friendly_name == "Appointments":
                        item_data = 1  # limit number of appointments to 1
                        appointment_details = request.session.get(
                            'appointment_details', {})
                        appointment = AppointmentsCalendar.objects.filter(
                            pk=appointment_details['id'])
                        appointment.update(**updatedFields)

                        cust_email = appointment_details['cust_email']
                        host_email = settings.DEFAULT_FROM_EMAIL

                        filePath = 'appointments/confirmation_emails/'
                        subject = render_to_string(
                            f'{filePath}confirmation_email_subject.txt',
                            {'email': appointment_details})
                        cust_body = render_to_string(
                            f'{filePath}confirmation_cust_email_body.txt',
                            {'email': appointment_details})
                        host_body = render_to_string(
                            f'{filePath}confirmation_host_email_body.txt',
                            {'email': appointment_details})

                        try:
                            # send confirmation message to customer email address
                            send_mail(subject, cust_body, host_email,
                                      [cust_email])
                            # send confirmation message to host email address
                            send_mail(subject, host_body, cust_email,
                                      [host_email])
                        except Exception as e:
                            messages.error(
                                request,
                                'Sorry, there was a problem sending your appointment request. Please try again.'
                            )
                            return HttpResponse(content=e, status=400)

                    if isinstance(item_data, int):
                        order_line_item = OrderLineItem(
                            order=order,
                            product=product,
                            quantity=item_data,
                        )
                        order_line_item.save()
                    else:
                        for potency, quantity in item_data[
                                'items_by_potency'].items():
                            order_line_item = OrderLineItem(
                                order=order,
                                product=product,
                                quantity=quantity,
                                potency=potency,
                            )
                            order_line_item.save()
                except Product.DoesNotExist:
                    messages.error(request, (
                        "One of the products in your basket wasn't found in our database. "
                        "Please call us for assistance!"))
                    order.delete()
                    return redirect(reverse('view_basket'))

            request.session['save_info'] = 'save-info' in request.POST
            return redirect(
                reverse('checkout_success', args=[order.order_number]))
        else:
            messages.error(
                request, 'There was an error with your form. \
                Please double check your information.')
    else:
        basket = request.session.get('basket', {})
        if not basket:
            messages.error(request,
                           "There's nothing in your basket at the moment")
            return redirect(reverse('products'))

        current_basket = basket_contents(request)
        total = current_basket['grand_total']
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        if request.user.is_authenticated:
            try:
                profile = UserProfile.objects.get(user=request.user)
                order_form = OrderForm(
                    initial={
                        'full_name': profile.user.username,
                        'email': profile.user.email,
                        'phone_number': profile.default_phone_number,
                        'country': profile.default_country,
                        'postcode': profile.default_postcode,
                        'town_or_city': profile.default_town_or_city,
                        'street_address1': profile.default_street_address1,
                        'street_address2': profile.default_street_address2,
                        'county': profile.default_county,
                    })
            except UserProfile.DoesNotExist:
                order_form = OrderForm()
        else:
            order_form = OrderForm()

    if not stripe_public_key:
        messages.warning(
            request, 'Stripe public key is missing. \
            Did you forget to set it in your environment?')

    context = {
        'order_form': order_form,
        'stripe_public_key': stripe_public_key,
        'client_secret': intent.client_secret,
    }

    return render(request, 'checkout/checkout.html', context)
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    if request.method == 'POST':
        basket = request.session.get('basket', {})

        form_data = {
            'full_name': request.POST['full_name'],
            'email': request.POST['email'],
            'phone_number': request.POST['phone_number'],
            'country': request.POST['country'],
            'postcode': request.POST['postcode'],
            'town_or_city': request.POST['town_or_city'],
            'street_address1': request.POST['street_address1'],
            'street_address2': request.POST['street_address2'],
            'county': request.POST['county'],
        }

        order_form = OrderForm(form_data)
        if order_form.is_valid():
            order = order_form.save(commit=False)
            pid = request.POST.get('client_secret').split('_secret')[0]
            order.stripe_pid = pid
            order.original_basket = json.dumps(basket)
            order.save()
            for item_id, item_data in basket.items():
                try:
                    product = Product.objects.get(id=item_id)
                    if isinstance(item_data, int):
                        order_line_item = OrderLineItem(
                            order=order,
                            product=product,
                            quantity=item_data,
                        )
                        order_line_item.save()
                except Product.DoesNotExist:
                    sweetify.sweetalert(
                        request,
                        'Product not found',
                        text='Please contact us for further assistance',
                        persistent='Ok')
                    order.delete()
                    return redirect(reverse('view_basket'))
            request.session['save_info'] = 'save-info' in request.POST
            return redirect(
                reverse('checkout_success', args=[order.order_number]))
        else:
            sweetify.sweetalert(request,
                                'There was an error with the form',
                                text='Please check your inputted information',
                                persistent='Ok')

    else:
        basket = request.session.get('basket', {})
        if not basket:
            sweetify.sweetalert(request,
                                'Please try again later',
                                text='There is nothing in the basket',
                                persistent='Ok')
            return redirect(reverse('products'))

        current_basket = basket_contents(request)
        total = current_basket['grand_total']
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        # Attempt to prefill the form with any info
        # the user maintains in their profile
        if request.user.is_authenticated:
            try:
                profile = UserProfile.objects.get(user=request.user)
                order_form = OrderForm(
                    initial={
                        'full_name': profile.user.get_full_name(),
                        'email': profile.user.email,
                        'phone_number': profile.default_phone_number,
                        'country': profile.default_country,
                        'postcode': profile.default_postcode,
                        'town_or_city': profile.default_town_or_city,
                        'street_address1': profile.default_street_address1,
                        'street_address2': profile.default_street_address2,
                        'county': profile.default_county,
                    })
            except UserProfile.DoesNotExist:
                order_form = OrderForm()
        else:
            order_form = OrderForm()

    if not stripe_public_key:
        sweetify.sweetalert(
            request,
            'Stripe Public Key Missing',
            text='Did you forget to set it in your environment?',
            persistent='Ok')

    template = 'checkout/checkout.html'
    context = {
        'order_form': order_form,
        'stripe_public_key': stripe_public_key,
        'client_secret': intent.client_secret,
    }

    return render(request, template, context)
def checkout(request):
    """
    This view displays the order form & basket
    so that a user can check their order, add
    their delivery details and checkout.
    User details are prepopulated
    where known.
    When a user posts the form, this view
    will also create a stripe payment intent,
    create the order & order line items.
    The "checkout" boolean is used to identify
    the order progress.
    """

    stripe_public_key = settings.STRIPE_PUBLISHABLE_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    if request.method == 'POST':
        basket = request.session.get('basket', {})
        form_data = {
            'full_name': request.POST['full_name'],
            'email': request.POST['email'],
            'phone_number': request.POST['phone_number'],
            'address_1': request.POST['address_1'],
            'address_2': request.POST['address_2'],
            'city': request.POST['city'],
            'county': request.POST['county'],
            'country': request.POST['country'],
            'postcode': request.POST['postcode'],
        }
        order_form = OrderForm(form_data)
        if order_form.is_valid():
            order = order_form.save(commit=False)
            payment_intent_id = request.POST.get('client_secret').split(
                '_secret')[0]
            order.stripe_payment_intent_id = payment_intent_id
            order = order_form.save()
            for colour_id, item_data in basket.items():
                try:
                    colour = get_object_or_404(Colour, pk=colour_id)
                    product = get_object_or_404(Product, pk=colour.product.id)
                    order_line_item = OrderLineItem(
                        order=order,
                        product=product,
                        colour=colour,
                        quantity=item_data,
                    )
                    order_line_item.save()
                except Product.DoesNotExist or Colour.DoesNotExist:
                    messages.error(
                        request,
                        ('There was an error processing your basket. '
                         'Please call for further assistance.'),
                    )
                    order.delete()
                    return redirect(reverse('view_basket'))

            request.session['save_info'] = 'save-info' in request.POST
            return redirect(
                reverse('checkout_success', args=[order.order_number]))

        else:
            messages.error(
                request,
                'Your form contains some invalid details. '
                'Please double check your information',
            )
    else:
        basket = request.session.get('basket', {})
        if not basket:
            messages.error(request,
                           "There's nothing in your basket at the moment")
            return redirect(reverse('products'))

        current_basket = basket_contents(request)
        grand_total = current_basket['grand_total']
        stripe_total = round(grand_total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
            payment_method_types=['card'],
        )

        if request.user.is_authenticated:
            try:
                profile = UserProfile.objects.get(user=request.user)
                saved_info = {
                    'full_name': profile.user.get_full_name(),
                    'email': profile.user.email,
                    'phone_number': profile.default_phone_number,
                    'country': profile.default_country,
                    'postcode': profile.default_postcode,
                    'city': profile.default_city,
                    'address_1': profile.default_address_1,
                    'address_2': profile.default_address_2,
                    'county': profile.default_county,
                }
                order_form = OrderForm(initial=saved_info)
            except UserProfile.DoesNotExist:
                order_form = OrderForm()
        else:
            order_form = OrderForm()

    context = {
        'checkout': True,
        'order_form': order_form,
        'stripe_public_key': stripe_public_key,
        'client_secret': intent.client_secret,
    }

    return render(request, 'checkout/checkout.html', context)
Example #22
0
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    if request.method == 'POST':
        basket = request.session.get('basket', {})

        form_data = {
            'full_name': request.POST['full_name'],
            'email': request.POST['email'],
            'phone_number': request.POST['phone_number'],
            'country': request.POST['country'],
            'postcode': request.POST['postcode'],
            'town_or_city': request.POST['town_or_city'],
            'street_address1': request.POST['street_address1'],
            'street_address2': request.POST['street_address2'],
            'county': request.POST['county'],
        }
        order_form = OrderForm(form_data)
        if order_form.is_valid():
            order = order_form.save(commit=False)  # prevent multiple save events from being executed on the database by commit=False
            pid = request.POST.get('client_secret').split('_secret')[0]
            order.stripe_pid = pid 
            order.original_basket = json.dumps(basket)
            order.save() 
            for item_id, item_data in basket.items():
                try:
                    product = Product.objects.get(id=item_id)
                    if isinstance(item_data, int):
                        order_line_item = OrderLineItem(
                            order=order,
                            product=product,
                            quantity=item_data,
                        )
                        order_line_item.save()

                except Product.DoesNotExist:
                    messages.error(request, (
                        "One of the products in your basket wasn't found in our database. "
                        "Please call us for assistance!")
                    )
                    order.delete()
                    return redirect(reverse('view_basket'))

            request.session['save_info'] = 'save-info' in request.POST
            return redirect(reverse('checkout_success', args=[order.order_number]))
        else:
            messages.error(request, 'There was an error with your form. \
                Please double check your information.')

    else:
        basket = request.session.get('basket', {})
        if not basket:
            messages.error(request, "There's nothing in your basket at the moment")
            return redirect(reverse('products'))
        
        current_basket = basket_contents(request)
        total = current_basket['grand_total']
        stripe_total = round(total *100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        order_form = OrderForm()

    if not stripe_public_key:
        messages.warning(request, 'Stripe public key is missing. \
            Did you forget to set it in your environment?')

    template = 'checkout/checkout.html'
    context = {
        'order_form': order_form,
        'stripe_public_key': stripe_public_key,
        'client_secret': intent.client_secret,
    }

    return render(request, template, context)
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    if request.method == "POST":
        basket = request.session.get('basket', {})
        form_data = {
            'full_name': request.POST['full_name'],
            'email': request.POST['email'],
            'phone_number': request.POST['phone_number'],
            'postcode': request.POST['postcode'],
            'town_or_city': request.POST['town_or_city'],
            'street_address1': request.POST['street_address1'],
            'street_address2': request.POST['street_address2'],
            'county': request.POST['county'],
            'delivery_option': request.POST['delivery_option'],
            'click_and_collect_option':
            request.POST['click_and_collect_option'],
        }
        order_form = OrderForm(form_data)

        if order_form.is_valid():
            order = order_form.save()
            for item_id, item_data in basket.items():
                basket_obj = do_db_query(request, item_id=item_id)
                if '@' in str(basket_obj):
                    order_line_ticket_item = OrderLineTicketItem(
                        order=order,
                        ticket=basket_obj,
                        quantity=item_data,
                    )
                    order_line_ticket_item.save()
                else:
                    order_line_product_item = OrderLineProductItem(
                        order=order,
                        product=basket_obj,
                        quantity=item_data,
                    )
                    order_line_product_item.save()

            return redirect(
                reverse('checkout-success', args=[order.order_number]))
        else:
            messages.error(
                request, 'There was an error with your form \
                Please double check your information.')

    else:
        basket = request.session.get('basket', {})
        if not basket:
            messages.error(request, "Basket is currently empty.")
            return redirect(reverse('products-home'))

        current_basket = basket_contents(request)
        total = current_basket['grand_total']
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        if request.user.is_authenticated:
            try:
                user = User.objects.get(email=request.user.email)
                order_form = OrderForm(
                    initial={
                        'full_name': f'{user.first_name} {user.last_name}',
                        'email': user.email
                    })
            except User.DoesNotExist:
                order_form = OrderForm()
        else:
            order_form = OrderForm()

    if not stripe_public_key:
        messages.warning(
            request, 'Stripe public key is missing. \
            Did you forget to set it in your environment?')

    context = {
        'order_form': order_form,
        'stripe_public_key': stripe_public_key,
        'client_secret': intent.client_secret,
    }

    return render(request, 'checkout/checkout.html', context)
Example #24
0
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY
    # If valid
    if request.method == 'POST':
        basket = request.session.get('basket', {})

        form_data = {
            'full_name': request.POST['full_name'],
            'email': request.POST['email'],
            'phone_number': request.POST['phone_number'],
            'country': request.POST['country'],
            'postcode': request.POST['postcode'],
            'town_or_city': request.POST['town_or_city'],
            'street_address1': request.POST['street_address1'],
            'street_address2': request.POST['street_address2'],
            'county': request.POST['county'],
        }
        order_form = OrderForm(form_data)
        if order_form.is_valid():
            order = order_form.save(commit=False)
            pid = request.POST.get('client_secret').split('_secret')[0]
            order.stripe_pid = pid
            order.original_basket = json.dumps(basket)
            order.save()
            for item_id, item_data in basket.items():
                try:
                    product = Product.objects.get(id=item_id)
                    if isinstance(item_data, int):
                        order_line_item = OrderLineItem(
                            order=order,
                            product=product,
                            quantity=item_data,
                        )
                        order_line_item.save()
                    else:
                        for size, \
                                quantity in item_data['items_by_size'].items():
                            order_line_item = OrderLineItem(
                                order=order,
                                product=product,
                                quantity=quantity,
                                product_size=size,
                            )
                            order_line_item.save()
                except Product.DoesNotExist:
                    messages.error(request,
                                   (" One of the products in your basket "
                                    " wasn't found in our database. "
                                    " Please contact us for assistance! "))
                    order.delete()
                    return redirect(reverse('view_basket'))

            request.session['save_info'] = 'save-info' in request.POST
            return redirect(
                reverse('checkout_success', args=[order.order_number]))
        else:
            messages.error(
                request, 'There was an error with your form. \
                Please double check your information.')
            return redirect(reverse('products'))

    # If not valid
    else:
        basket = request.session.get('basket', {})
        # To prevent people from manually accessing the URL by typing /checkout
        if not basket:
            messages.error(request, "there's nothing in your "
                           "basket at the moment")
            return redirect(reverse('products'))

        # To calculate basket total for stripe
        current_basket = basket_contents(request)
        total = current_basket['grand_total']
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        # Prefill order information
        if request.user.is_authenticated:
            try:
                profile = UserProfile.objects.get(user=request.user)
                order_form = OrderForm(
                    initial={
                        'full_name': profile.default_full_name,
                        'email': profile.user.email,
                        'phone_number': profile.default_phone_number,
                        'country': profile.default_country,
                        'postcode': profile.default_postcode,
                        'town_or_city': profile.default_town_or_city,
                        'street_address1': profile.default_street_address1,
                        'street_address2': profile.default_street_address2,
                        'county': profile.default_county,
                    })
            except UserProfile.DoesNotExist:
                order_form = OrderForm()
        else:
            order_form = OrderForm()

    if not stripe_public_key:
        messages.warning(
            request, 'Stripe public key is missing. Did you '
            'forget to set it in your environment?')

    template = 'checkout/checkout.html'
    context = {
        'order_form': order_form,
        'stripe_public_key': stripe_public_key,
        'client_secret': intent.client_secret,
    }

    return render(request, template, context)
Example #25
0
def checkout(request):
    if request.user.is_authenticated:
        stripe_public_key = settings.STRIPE_PUBLIC_KEY
        stripe_secret_key = settings.STRIPE_SECRET_KEY
        basket = request.session.get('basket', {})

        current_basket = basket_contents(request)
        delivery = current_basket['delivery']
        order_total = current_basket['total']
        total = current_basket['grand_total']

        if not basket:
            messages.error(request, 'Your shopping basket is empty')
            if request.user.is_authenticated:
                return redirect(reverse('films/index.html'))
            else:
                return redirect(reverse('films'))

        if request.method == 'POST':
            for basket_item, basket_value in current_basket.items():
                if basket_item == 'basket_items':
                    try:
                        for film_purchase in basket_value:
                            film_id = film_purchase['film_id']
                            Film = film.objects.get(id=film_id)
                            messages.success(request,
                                             (f'{Film} Added to Order'))
                    except Film.DoesNotExist:
                        messages.error(request, (
                            "An item in your basket was not found in our database.\
                            Please try again."))

            form_data = {
                'first_name': request.POST['first_name'],
                'last_name': request.POST['last_name'],
                'email': request.POST['email'],
                'phone_number': request.POST['phone_number'],
                'delivery_add1': request.POST['delivery_add1'],
                'delivery_add2': request.POST['delivery_add2'],
                'delivery_town': request.POST['delivery_town'],
                'delivery_county': request.POST['delivery_county'],
                'delivery_postcode': request.POST['delivery_postcode'],
                'delivery_country': request.POST['delivery_country'],
                'billing_add1': request.POST['billing_add1'],
                'billing_add2': request.POST['billing_add2'],
                'billing_town': request.POST['billing_town'],
                'billing_county': request.POST['billing_county'],
                'billing_postcode': request.POST['billing_postcode'],
                'billing_country': request.POST['billing_country'],
            }
            order_form = OrderForm(form_data)
            if order_form.is_valid():
                order = order_form.save(commit=False)
                pid = request.POST.get('client_secret').split('_secret')[0]
                order.stripe_pid = pid
                order.basket = current_basket
                order.delivery_charge = delivery
                order.order_charge = order_total
                order.total_charge = total
                order.save()
                request.session['save_delivery'] = ('save_delivery'
                                                    in request.POST)
                request.session['save_billing'] = ('save_billing'
                                                   in request.POST)
                return redirect(
                    reverse('checkout_success', args=[order.order_number]))
            else:
                messages.error(
                    request, "Error detected in your details.\
                    correct to process your order.")
        else:
            order_form = OrderForm()

        stripe_total = round(total * 100)  # stripe req. integer
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        # Pre-populate the order form with saved profile data
        try:
            profile = users.objects.get(user=request.user)
            order_form = OrderForm(
                initial={
                    'first_name': profile.first_name,
                    'last_name': profile.last_name,
                    'email': profile.user.email,
                    'phone_number': profile.phone_number,
                    'delivery_add1': profile.delivery_add1,
                    'delivery_add2': profile.delivery_add2,
                    'delivery_town': profile.delivery_town,
                    'delivery_county': profile.delivery_county,
                    'delivery_postcode': profile.delivery_postcode,
                    'delivery_country': profile.delivery_country,
                    'billing_add1': profile.billing_add1,
                    'billing_add2': profile.billing_add2,
                    'billing_town': profile.billing_town,
                    'billing_county': profile.first_name,
                    'billing_postcode': profile.billing_postcode,
                    'billing_country': profile.billing_country,
                })
        except users.DoesNotExist:
            order_form = OrderForm()

        template = 'checkout/checkout.html'
        context = {
            'order_form': order_form,
            'stripe_public_key': stripe_public_key,
            'client_secret': intent.client_secret,
        }

        return render(request, template, context)

    else:
        return redirect(reverse('films'))