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
5 changes: 3 additions & 2 deletions source/RewardsService/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
FROM python:3.5
FROM python:3.9
ENV PYTHONUNBUFFERED 1
ENV PYTHONPATH=$PYTHONPATH:/code/
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
RUN pip install --upgrade pip
RUN pip install --no-cache-dir -r requirements.txt
ADD ./ /code/
2 changes: 2 additions & 0 deletions source/RewardsService/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
fabric==1.10.2
motor==1.1.0
tornado==3.2
jsonschema==4.21.1
black==24.1.1
126 changes: 126 additions & 0 deletions source/RewardsService/rewardsservice/handlers/orders_handlers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import datetime
import operator
import re
import json

import tornado.web
from jsonschema import validate
from jsonschema.exceptions import ValidationError
from pymongo import MongoClient
from tornado.gen import coroutine

regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b'
dt_format = "%Y/%m/%d %H:%M:%S"


class OrdersHandler(tornado.web.RequestHandler):

client = MongoClient("mongodb", 27017)
db = client["Rewards"]
schema = {
"type": "object",
"properties": {
"email": {"type": "string"},
"order_total": {"type": "number"},
},
"required": ["email", "order_total"],
}

@staticmethod
def _serialize_data(data):
for item in data:
item["created"] = item["created"].strftime(dt_format)
item["updated"] = item["updated"].strftime(dt_format)

@coroutine
def get(self):
orders = list(self.db.orders.find({}, {"_id": 0}))
self._serialize_data(orders)
self.write(json.dumps(orders))

@coroutine
def post(self):
try:
data = json.loads(self.request.body.decode("utf-8"))

# input body validation
try:
validate(data, schema=self.schema)
except ValidationError as ve:
self.set_status(400)
self.write(json.dumps({"error_message": ve.message}))
self.finish()

# email validation
# tried using external package was getting installation
# error in docker so moved to regex
if re.fullmatch(regex, data.get("email")):
pass
else:
self.set_status(422)
self.write(json.dumps({"error_message": "Invalid Email ID"}))
self.finish()

record = {
"email": data.get("email"),
"order_total": data.get("order_total", 0.0)
}
rewards_data = list(self.db.rewards.find({}, {"_id": 0}))
# sort by points descending true
rewards_data.sort(key=operator.itemgetter("points"), reverse=True)

# fetch reward match
order_total = data.get('order_total', 0.0)
try:
matching_reward = next((
item for item in rewards_data if order_total >= item["points"]
))
except StopIteration:
matching_reward = None

# update record
if matching_reward:
record.update({
"reward_points": matching_reward["points"],
"reward_tier": matching_reward["tier"],
"reward_tier_name": matching_reward["rewardName"]
})

# finding the next tier
if matching_reward != rewards_data[0]:
next_tier = rewards_data[rewards_data.index(matching_reward) - 1]
record.update({
"next_reward_tier": next_tier["tier"],
"next_reward_tier_name": next_tier["rewardName"],
"next_reward_tier_progress": (order_total / next_tier["points"]) * 100
})

# metadata
record["created"] = datetime.datetime.now()
record["updated"] = datetime.datetime.now()

self.db.orders.insert(record)

self.set_status(201)
self.write(json.dumps({"status": "Order Created"}))
self.finish()
except Exception as e:
self.set_status(400)
self.write(json.dumps({"error_message": f"{str(e)}"}))


class OrderHandler(tornado.web.RequestHandler):
client = MongoClient("mongodb", 27017)
db = client["Rewards"]

def get(self):
query = {}
email = self.get_query_argument("email", default=None)
if not email:
self.write(json.dumps({"error_message": "Please provide email as query params"}))
self.finish()
query["email"] = email
order = self.db.orders.find_one(query, {"_id": 0})
order["created"] = order["created"].strftime(dt_format)
order["updated"] = order["updated"].strftime(dt_format)
self.write(json.dumps(order))
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import json
import tornado.web

import tornado.web
from pymongo import MongoClient
from tornado.gen import coroutine


class RewardsHandler(tornado.web.RequestHandler):

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

@coroutine
def get(self):
client = MongoClient("mongodb", 27017)
db = client["Rewards"]
rewards = list(db.rewards.find({}, {"_id": 0}))
rewards = list(self.db.rewards.find({}, {"_id": 0}))
self.write(json.dumps(rewards))
5 changes: 4 additions & 1 deletion 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 handlers.orders_handlers import OrdersHandler, OrderHandler

url_patterns = [
(r'/rewards', RewardsHandler),
(r"/rewards", RewardsHandler),
(r"/orders", OrdersHandler),
(r"/order", OrderHandler),
]