Applying coupons to orders

We are going to store the coupon that was applied to each order. First, we need to modify the Order model to store the related Coupon object, if there is any.

Edit the models.py file of the orders application and add the following imports to it:

from decimal import Decimal
from django.core.validators import MinValueValidator,
MaxValueValidator
from coupons.models import Coupon

Then, add the following fields to the Order model:

class Order(models.Model):
# ...
coupon = models.ForeignKey(Coupon,
related_name='orders',
null=True,
blank=True,
on_delete=models.SET_NULL)

discount = models.IntegerField(default=0,
validators=[MinValueValidator(0),
MaxValueValidator(100)])

These fields allow us to store an optional coupon for the order and the discount percentage applied with the coupon. The discount is stored in the related Coupon object, but we include it in the Order model to preserve it if the coupon is modified or deleted. We set on_delete to models.SET_NULL so that if the coupon gets deleted, the coupon field is set to Null.

We need to create a migration to include the new fields of the Order model. Run the following command from the command line:

python manage.py makemigrations

You should see an output like the following:

Migrations for 'orders':
orders/migrations/0003_auto_20180307_2202.py:
- Add field coupon to order
- Add field discount to order

Apply the new migration with the following command:

python manage.py migrate orders

You should see a confirmation indicating that the new migration has been applied. The Order model field changes are now synced with the database.

Go back to the models.py file and change the get_total_cost() method of the Order model as follows:

class Order(models.Model):
# ...
def get_total_cost(self):
total_cost = sum(item.get_cost() for item in self.items.all())
return total_cost - total_cost *
(self.discount / Decimal('100'))

The get_total_cost() method of the Order model will now take into account the discount applied if there is one.

Edit the views.py file of the orders application and modify the order_create view to save the related coupon and its discount when creating a new order. Find the following line:

order = form.save()

Replace it with the following:

order = form.save(commit=False)
if cart.coupon:
order.coupon = cart.coupon
order.discount = cart.coupon.discount
order.save()

In the new code, we create an Order object using the save() method of the OrderCreateForm form. We avoid saving it to the database yet by using commit=False. If the cart contains a coupon, we store the related coupon and the discount that was applied. Then we save the order object to the database.

Make sure the development server is running with the command python manage.py runserver.

Open http://127.0.0.1:8000/ in your browser and complete a purchase using the coupon you created. When you finish a successful purchase, you can go to http://127.0.0.1:8000/admin/orders/order/ and check that the order object contains the coupon and the applied discount as follows:

You can also modify the admin order detail template and the order PDF bill to display the applied coupon the same way we did for the cart.

Next, we are going to add internationalization to our project.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.152.87