DEV Community

Alexandr K
Alexandr K

Posted on

Build invoices based on Wunderlist

The last 8 years I am working on contracts on remote and for the clients that are charging by hours, it would require to send invoices hourly every 2 weeks. I was trying to use the different applications for invoicing but then moved away and used google docs to build it.

Then I found Wunderlist, nice todo list application. I created Shopping and TODO lists and started to use daily. as result it became like a habit for me to write there. I decided that it would be awesome to track my hours there as well.

Example format for task hours:

<hours> hours TASK-1 <minutes> minutes TASK-2 <days> days TASK-3 
Enter fullscreen mode Exit fullscreen mode

After month I decided to download this list and calculate hours that spent for the month. As result I did the script for downloading the hours report into csv file.

import wunderpy2 from dateutil import parser from datetime import date from csv import writer ACCESS_TOKEN = '<WUNDERLIST_ACCESS_TOKEN>' CLIENT_ID = '<WUNDERLIST_CLIENT_ID>' PROJECT_BOARD = 'LIST_TITLE' HOUR_RATE = 1 def __build_hour(task): ''' Example: dict(title='1 hour CORE-1234') dict(title='5 hours CORE-4321') dict(title='1 minute CORE-1234') ''' columns = task['title'].strip().split(' ') time, measure, task_id = columns if measure == 'hour' or measure == 'hours': hours = float(time) elif measure == 'minute' or measure == 'minutes': hours = float(time) / 60 elif measure == 'day' or measure == 'days': hours = 24 * float(time) else: raise 'unknown measure from the task title: ' + task['title'] return dict( task_id=task_id, created_at=parser.parse(task['created_at']), hours=hours) def __main__(): api = wunderpy2.WunderApi() client = api.get_client(ACCESS_TOKEN, CLIENT_ID) board = [l for l in client.get_lists() if l['title'] == PROJECT_BOARD][0] active_tasks = [t for t in client.get_tasks(board['id']) if not t['completed']] report = [__build_hour(task) for task in active_tasks] estimated_earnings = sum([task['hours'] for task in report]) * HOUR_RATE print(estimated_earnings) with open(f"report-{date.today()}.csv", 'w+') as f: w = writer(f) rows = [[task['task_id'], task['hours'], task['created_at'].date()] for task in report] w.writerows(rows) for task in active_tasks: client.update_task(task['id'], task['revision'], completed=True) # TODO: make monthly output report to pdf file based on created_at field.  if __name__ == '__main__': __main__() 
Enter fullscreen mode Exit fullscreen mode

Top comments (0)