Schedule & send rent invoices to tenants at regular intervals using Django & AfricasTalking API

THE PROBLEM

If you are a caretaker or a landlord of a rentals property, chances are every end of the month, you draft paper invoices and then walk door to door issuing each tenant with their specific invoice. Not only is this tedious and time consuming but also you risk walking to a tenant's door and finding that they are not in and you have to come again at a later time or the next day(s).
A hypothetical property, Kwetu Apartments is one such business that has hitherto been doing things this way and they have decided that it is time they embrace technology and become a digital first business by leveraging on automation tools to handle the otherwise daunting manual invoicing method.

THE SOLUTION

The owner of Kwetu Apartments approached our team of software developers and after lengthy talks, we decided to develop a portal for them that will:
1.Send text message reminders to tenants with invoice details every 30th of each month.
2.process rent payments using either card or mpesa and then update each tenant's status as either paid or not.
The portal will then send text messages to those who have not paid to remind them to make payments.
The assumption here is that we have already developed the logic to process tenants payments and now what we have to do is implement the logic to send text reminders every 30th each month. In case you need an article on payment processing then go through this post I wrote a few days back.

PROJECT SETUP

Create a new project and start a new app:

django-admin startproject tenants_project .

python manage.py startapp invoices

Remember to add invoices to the list of installed apps in tenants_project/settings.py
Let's quickly create a database class that will house all our tenants and their details:

from django.db import models

# Create your models here.
class Tenant(models.Model):
    name=models.CharField(max_length=250)
    phone=models.CharField(max_length=250)

    def __str__(self):
        return self.name

Go ahead and makemigrations then migrate. Register the model in admin.py. Also create a superuser, login to the admin section of the project and add a few tenant instances. After that we can begin sending them invoices messages every month!

AFRICASTALKING CONFIG

Stop the server but retain the virtual env. Install AfricasTalking helper library by:

pip  install africastalking

Now log in to their website. Click on 'Sandbox' and from the resulting dashboard click on 'Settings' then 'API Key'. Click to generate a new key which you will copy and store it safe as we are using it in a bit.

SCHEDULER LOGIC

We then move on to install a package that will help us with task scheduling. While still on terminal do this:

pip install apscheduler

Create a file within invoices called invoice_update.py and add the code below to it:

from .models import Tenant
import africastalking

# Initialize SDK
username = "sandbox"    
api_key = "YOUR SANDBOX API KEY" 
africastalking.initialize(username, api_key)

sms = africastalking.SMS

def send_reminders():
    tenants=Tenant.objects.all()
    for tenant in tenants:
        invoice_message=f'Hello, {tenant.name}, your rent payment of shs 10,000 is due on demand. Please plan to pay before 5th.'
        response =sms.send(invoice_message, [str(tenant.phone)]) 
        print(response)

Next, create another file within invoices called updater.py and add the code below to it:

from apscheduler.schedulers.background import BackgroundScheduler
from . import invoice_update

def start():
    scheduler = BackgroundScheduler()
    scheduler.add_job(invoice_update.send_reminders, 'interval', seconds=10)
    scheduler.start()

So here we are scheduling a reminder with invoice details for all the tenants in our database. For testing purposes we are running that task every ten seconds but in production we would put a cron job to run every 30th. Save that file then move to invoices/apps.py and update it like so:

from django.apps import AppConfig

class InvoicesConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'invoices'

    def ready(self):
        from . import updater
        updater.start()

So every time our project boots, our scheduler runs in the background and does its thing.
Let's take it for a spin and see what's what:

python manage.py runserver

Head over to your AT Sandbox and launch it.
You will see an image like below:
sandbox home
Click on the SMS card and you will see:
sms
Great, our tenants got the invoice messages as intended by Kwetu Apartments.

WRAP UP

In this article we have eliminated the need of Kwetu Apartment caretakers and landlords to draft paper invoices and then walk door to door delivering them to tenants. We developed a solution that is robust and scalable that can server as many users as possibles with minimal human input.
The code to this project can be found at my repo.

Thanks for reading and coding along. Go ahead and add creativity and share what you will come up with.
If you have any questions or comment then leave them below or on my Twitter.
Cheers and happy hacking!

30