diff --git a/source/RewardsService/rewardsservice/handlers/rewards_handler.py b/source/RewardsService/rewardsservice/handlers/rewards_handler.py index 4f2aea6e..b9cf1fa1 100644 --- a/source/RewardsService/rewardsservice/handlers/rewards_handler.py +++ b/source/RewardsService/rewardsservice/handlers/rewards_handler.py @@ -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}) + diff --git a/source/RewardsService/rewardsservice/url_patterns.py b/source/RewardsService/rewardsservice/url_patterns.py index 55e471d6..af2a6f77 100644 --- a/source/RewardsService/rewardsservice/url_patterns.py +++ b/source/RewardsService/rewardsservice/url_patterns.py @@ -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), ] diff --git a/source/RewardsService/rewardsservice/utils.py b/source/RewardsService/rewardsservice/utils.py new file mode 100644 index 00000000..accd17c8 --- /dev/null +++ b/source/RewardsService/rewardsservice/utils.py @@ -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" + + diff --git a/source/RewardsUI/global/urls.py b/source/RewardsUI/global/urls.py index dd5c08f0..34118b3a 100644 --- a/source/RewardsUI/global/urls.py +++ b/source/RewardsUI/global/urls.py @@ -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')) ] diff --git a/source/RewardsUI/rewards/clients/rewards_service_client.py b/source/RewardsUI/rewards/clients/rewards_service_client.py index 70b56545..ac1bc100 100644 --- a/source/RewardsUI/rewards/clients/rewards_service_client.py +++ b/source/RewardsUI/rewards/clients/rewards_service_client.py @@ -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() + diff --git a/source/RewardsUI/rewards/index.html b/source/RewardsUI/rewards/index.html index cdab1ee4..91b4d2c5 100644 --- a/source/RewardsUI/rewards/index.html +++ b/source/RewardsUI/rewards/index.html @@ -23,16 +23,29 @@
| customer01@gmail.com | -100 | -A | -5% off purchase | -B | -10% off purchase | -50% | -
| {{ user.email_address }} | +{{ user.reward_points }} | +{{ user.reward_tier }} | +{{ user.reward_tier_name }} | +{{ user.next_reward_tier }} | +{{ user.next_reward_tier_name }} | +{{ user.next_reward_tier_progress }} | +