Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 24 additions & 4 deletions source/RewardsService/rewardsservice/handlers/rewards_handler.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,35 @@
import json
import tornado.web

from pymongo import MongoClient
from tornado.gen import coroutine

from rewardsservice.utils import ComputationUtils


class RewardsHandler(tornado.web.RequestHandler):

@coroutine
def get(self):
client = MongoClient("mongodb", 27017)
db = client["Rewards"]
rewards = list(db.rewards.find({}, {"_id": 0}))
rewards = ComputationUtils.compute_rewards()
self.write(json.dumps(rewards))


class EmailHandler(tornado.web.RequestHandler):

@coroutine
def get(self):
email_address = self.get_argument('email_address', None)
user_details = ComputationUtils.compute_user_details_for_email_address(email_address)
self.write(json.dumps(user_details))


class OrderHandler(tornado.web.RequestHandler):

@coroutine
def post(self):
data = tornado.escape.json_decode(self.request.body)
email_address = data.get('email_address', '')
order_total = data.get('order_total', 0)
success, message = ComputationUtils.add_order(email_address=email_address, order_total=order_total)
self.write({'message': message, "success": success})

3 changes: 3 additions & 0 deletions source/RewardsService/rewardsservice/url_patterns.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
from handlers.rewards_handler import RewardsHandler
from rewardsservice.handlers.rewards_handler import EmailHandler, OrderHandler

url_patterns = [
(r'/rewards', RewardsHandler),
(r'/rewards/users', EmailHandler),
(r'/rewards/order', OrderHandler),
]
114 changes: 114 additions & 0 deletions source/RewardsService/rewardsservice/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
from collections import OrderedDict

from pymongo import MongoClient


class ComputationUtils:
@classmethod
def compute_rewards(cls):
client = MongoClient("mongodb", 27017)
db = client["Rewards"]
return list(db.rewards.find({}, {"_id": 0}))

@classmethod
def compute_rewards_for_users(cls, users_data):
"""

:param users_data: [{"email_address": "abc@xyz.com", "order_total": 100.8}]
:return: [{

}]

[
{ "tier": "A", "rewardName": "5% off purchase", "points": 100 },
{ "tier": "B", "rewardName": "10% off purchase", "points": 200 },
{ "tier": "C", "rewardName": "15% off purchase", "points": 300 },
{ "tier": "D", "rewardName": "20% off purchase", "points": 400 },
{ "tier": "E", "rewardName": "25% off purchase", "points": 500 },
{ "tier": "F", "rewardName": "30% off purchase", "points": 600 },
{ "tier": "G", "rewardName": "35% off purchase", "points": 700 },
{ "tier": "H", "rewardName": "40% off purchase", "points": 800 },
{ "tier": "I", "rewardName": "45% off purchase", "points": 900 },
{ "tier": "J", "rewardName": "50% off purchase", "points": 1000 }
]

email_address reward_points reward_tier reward_tier_name next_reward_tier next_reward_tier_name next_reward_tier_progress
"""
data = OrderedDict()
records = cls.compute_rewards()
data[0] = {"current": {}, "next": records[0]}
for i in range(len(records)):
data[records[i]["points"] // 100] = {"current": records[i], "next": records[i + 1] if i + 1 < len(records) else {}}

output = []
for user in users_data:
email_address = user.get("email_address")
order_total = user.get("order_total")
points = min(order_total, 1001) // 100
result = data.get(points)
current = result.get("current")
next = result.get("next")
output.append({
"email_address": email_address,
"reward_points": order_total,
"reward_tier": current.get("tier", ""),
"reward_tier_name": current.get("rewardName", ""),
"next_reward_tier": next.get("tier", ""),
"next_reward_tier_name": next.get("rewardName", ""),
"next_reward_tier_progress": "{} %".format(round((order_total * 100) / ((points + 1) * 100), 2)) if points < 10 else ""
})

return output

@classmethod
def compute_user_details_for_email_address(cls, email_address):
"""

:param email_address: "email_address": "abc@xyz.com"
:return:
"""

client = MongoClient("mongodb", 27017)
db = client["Rewards"]

if email_address:
users = list(db.users.find({"email_address": email_address}, {"email_address": 1, "order_total": 1, "_id": 0}))
else:
users = list(db.users.find({}, {"email_address": 1, "order_total": 1, "_id": 0}))

return cls.compute_rewards_for_users(users)

@classmethod
def add_order(cls, email_address, order_total):
"""

:param email_address:
:param order_total:
:return: None
"""
client = MongoClient("mongodb", 27017)
db = client["Rewards"]

user = db.users.find_one({"email_address": email_address}, {"_id": 0}) or {}
old_order_total = user.get("order_total", 0)

try:
order_total = int(order_total)
if order_total < 0:
return False, "order_total should be positive integer"
except ValueError:
return False, "order_total should be positive integer"

order_total += int(old_order_total)
if email_address and order_total and not user:
db.users.insert_one({"email_address": email_address, "order_total": order_total})

elif email_address and user and order_total:
db.users.update_one({"email_address": email_address}, {"$set": {"order_total": order_total}})

elif not email_address or not order_total:
return False, "Both Email address and order total should be present"

return True, "Updated Successfully"


4 changes: 2 additions & 2 deletions source/RewardsUI/global/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import include, url
from django.urls import include, re_path

urlpatterns = [
url(r'^rewards/', include('rewards.urls'))
re_path(r'^rewards/', include('rewards.urls'))
]
19 changes: 18 additions & 1 deletion source/RewardsUI/rewards/clients/rewards_service_client.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
from urllib.parse import urljoin

import requests


class RewardsServiceClient:

def __init__(self):
self.rewards_url = "http://rewardsservice:7050/rewards"
self.base_url = "http://localhost:7050/"
self.rewards_url = urljoin(base=self.base_url, url="rewards")
self.user_url = urljoin(base=self.base_url, url="rewards/users")
self.order_url = urljoin(base=self.base_url, url="rewards/order")

def get_rewards(self):
response = requests.get(self.rewards_url)
return response.json()

def add_rewards(self, email_address, order_total):
response = requests.post(self.order_url, json=dict(
email_address=email_address,
order_total=order_total
))
return response.json()

def get_users(self, email_address=""):
response = requests.get(self.user_url, params=dict(email_address=email_address))
return response.json()

43 changes: 29 additions & 14 deletions source/RewardsUI/rewards/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,29 @@ <h2>Reward Tiers</h2>
</div>
<div>
<h2>Add orders</h2>
<form>
<label>Enter email address: </label><input type="text"/><br>
<label>Enter order total: </label><input type="text"/><input type="button" value="Submit Order"/>

<form action="" method="post">{% csrf_token %}

<label for="email_address">Enter email address: </label>
<input id="email_address" type="text" name="email_address"/>
<label for="order_total">Enter order total: </label>
<input id="order_total" type="text" name="order_total"/>
<input type="submit" value="Submit Order"/>
</form>
{% if response_data %}
<div>
<h3>{{ response_data.message }}</h3>
</div>
{% endif %}
<hr>

</div>
<div>
<h2>User Rewards</h2>
<form>
<label>Email address: </label><input type="text"/><input type="button" value="Search"/>
<form action="" method="get">
<label for="email">Email address: </label>
<input id="email" type="text" name="email"/>
<input type="submit" value="Search"/>
</form>
<table border="1">
<thead>
Expand All @@ -47,15 +60,17 @@ <h2>User Rewards</h2>
</tr>
</thead>
<tbody>
<tr>
<td>customer01@gmail.com</td>
<td>100</td>
<td>A</td>
<td>5% off purchase</td>
<td>B</td>
<td>10% off purchase</td>
<td>50%</td>
</tr>
{% for user in users_data %}
<tr>
<td>{{ user.email_address }}</td>
<td>{{ user.reward_points }}</td>
<td>{{ user.reward_tier }}</td>
<td>{{ user.reward_tier_name }}</td>
<td>{{ user.next_reward_tier }}</td>
<td>{{ user.next_reward_tier_name }}</td>
<td>{{ user.next_reward_tier_progress }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
Expand Down
7 changes: 3 additions & 4 deletions source/RewardsUI/rewards/urls.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from django.conf.urls import url

from . import views
from django.urls import include, re_path
from rewards import views

urlpatterns = [
url(r'^$', views.RewardsView.as_view(), name='rewards'),
re_path(r'^$', views.RewardsView.as_view(), name='rewards'),
]
30 changes: 28 additions & 2 deletions source/RewardsUI/rewards/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,41 @@ class RewardsView(TemplateView):
def __init__(self, logger=logging.getLogger(__name__), rewards_service_client=RewardsServiceClient()):
self.logger = logger
self.rewards_service_client = rewards_service_client
self.rewards_data = []

def get_rewards_data(self):
if not self.rewards_data:
self.rewards_data = self.rewards_service_client.get_rewards()
return self.rewards_data

def get(self, request, *args, **kwargs):
email_address = request.GET.get("email", "")
context = self.get_context_data(**kwargs)

rewards_data = self.rewards_service_client.get_rewards()
rewards_data = self.get_rewards_data()
users_data = self.rewards_service_client.get_users(email_address=email_address)
context['rewards_data'] = rewards_data
context['users_data'] = users_data

return TemplateResponse(
request,
self.template_name,
context
)

def post(self, request, *args, **kwargs):
email_address = request.POST.get("email_address", "")
order_total = request.POST.get("order_total", 0)
data = self.rewards_service_client.add_rewards(email_address=email_address, order_total=order_total)
context = self.get_context_data(**kwargs)
rewards_data = self.get_rewards_data()
users_data = self.rewards_service_client.get_users()
context['rewards_data'] = rewards_data
context['users_data'] = users_data
context['response_data'] = data

return TemplateResponse(
request,
self.template_name,
context
)
)