44. Extra adjustments before payment system

Before implementing the payment system, we need to make a few additional adjustments to ensure everything functions correctly. We will start by displaying the error messages we created earlier so that users can see any issues they encounter.

To achieve this, we will update the finish_order view function to handle errors effectively. If an error occurs, the function will redirect the user back to the checkout page, passing along the order details and the associated error message. This will ensure that users receive feedback and can correct any issues before proceeding.

views.py\finish_order
def finish_order(request, order_id) :
    if request.method == "POST" :
        error = None
        data = request.POST.dict()
        total = data.get("total")
        order = Order.objects.get(id=order_id) #? used get because it is only one order

        if float(total) != float(order.total_cost) : #? transformed to float to avoid comparisson errors
            error = "conflicting_cost" #? in case the user tries to manipulate the html

        if not "adress" in data :
            error = "adress"
        else :
            id_adress = data.get("adress")
            adress = Adres.objects.get(id=id_adress)
            order.adress = adress
                
        if not request.user.is_authenticated :
            email = data.get("email")
            try :
                validate_email(email)
            except ValidationError :
                error = "email"
            if not error :
                clients = Client.objects.filter(email=email)
                if clients:
                    order.client = clients[0]
                    
                else:
                    order.client.email = email
                    order.client.save()


        if error :
            addresses = Adres.objects.filter(client=order.client) #? filters all adresses associated with the client
            context = {"error" : error, "order" : order, "addresses" : addresses}
            return render(request,"checkout.html", context)
        return redirect("checkout")
    else :
        return redirect("store")

Note: We also modified the address data collection, as the forms send the address ID through the request, not the address itself.

To ensure that the initial value of the error is set to None, we will include the error variable in the context of the checkout view function and initialize it to None. This value will only be updated if an error occurs during the order process.

views.py\checkout
    context = {"order" : order, "addresses" : addresses, "error" : None}

Next, in the checkout.html file, we need to display the associated error messages. We will use the error context variable to show any errors that occur, providing users with feedback if something goes wrong during the checkout process.

checkout.html
<p>Total Quantity: {{ order.total_quantity }}</p>

{% if error %}

    {% if error == "conflicting_cost" %}
        <p>Invalid product total cost. Try again or return to the cart.</p>
    {% endif %}
        
    {% if error == "adress" %}
        <p>Select a delivery adress to continue.</p>
    {% endif %}
        
    {% if error == "email" %}
        <p>Fill in your email to continue.</p>
    {% endif %}
{% endif %}

Next, we need to generate a transaction ID for each finalized order. This ID will be composed of the order ID and the date when the order was finalized. We can use Python's datetime function to obtain the current date, which is represented as a large number (EPOCH time) that counts the seconds from a reference date around the year 1970.

To do this, at the start of the views.py file, we need to import the datetime function from Python's datetime library:

views.py
from datetime import datetime

We will enhance the finish_order view function by implementing functionality to generate a unique transaction ID for each order:

views.py
def finish_order(request, order_id) :
    if request.method == "POST" :
        error = None
        data = request.POST.dict()
        total = data.get("total")
        order = Order.objects.get(id=order_id) #? used get because it is only one order
        total = total.replace(",",".") #? in case you are using brazilian version

        if float(total) != float(order.total_cost) : #? transformed to float to avoid comparisson errors
            error = "conflicting_cost" #? in case the user tries to manipulate the html

        if not "adress" in data :
            error = "adress"
        else :
            id_adress = data.get("adress")
            adress = Adres.objects.get(id=id_adress)
            order.adress = adress
        
        
        if not request.user.is_authenticated :
            email = data.get("email")
            try :
                validate_email(email)
            except ValidationError :
                error = "email"
            if not error :
                clients = Client.objects.filter(email=email)
                if clients:
                    order.client = clients[0]
                else:
                    order.client.email = email
                    order.client.save()
        
        id_transaction = f"{order.id}-{datetime.now().timestamp()}"
        order.id_transaction = id_transaction
        order.save()

        if error :
            addresses = Adres.objects.filter(client=order.client) #? filters all adresses associated with the client
            context = {"error" : error, "order" : order, "addresses" : addresses}
            return render(request,"checkout.html", context)
        else :
            #? make payment
            return redirect("checkout")
    else :
        return redirect("store")

Note: In this updated segment, in case you are programming using the brazilian settings, we converted any ',' to a '.'.

In the updated implementation of the finish_order view function, if a user attempts to complete an order without providing an email address or shipping address, the system will trigger an error message. Subsequently, the user will be redirected back to the same page to correct the missing information. This ensures that all required fields are filled before proceeding with order finalization.

The user has not provided their email address.

Last updated