diff --git a/source/.gitignore b/source/.gitignore new file mode 100644 index 00000000..362552bf --- /dev/null +++ b/source/.gitignore @@ -0,0 +1,150 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +.DS_Store +.vscode/ + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints +*.ipynb + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +# .env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ +media/ +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# cdk +*.pem +*.swp +package-lock.json +__pycache__ +.pytest_cache +.venv +*.egg-info + +# CDK asset staging directory +.cdk.staging +cdk.out + +# Terraform bookkeeping +*.tfstate +*.tfstate.* +*.terraform \ No newline at end of file diff --git a/source/RewardsService/data/db/WiredTiger b/source/RewardsService/data/db/WiredTiger new file mode 100644 index 00000000..1bc57bae --- /dev/null +++ b/source/RewardsService/data/db/WiredTiger @@ -0,0 +1,2 @@ +WiredTiger +WiredTiger 11.2.0: (November 10, 2022) diff --git a/source/RewardsService/data/db/WiredTiger.lock b/source/RewardsService/data/db/WiredTiger.lock new file mode 100644 index 00000000..3d842068 --- /dev/null +++ b/source/RewardsService/data/db/WiredTiger.lock @@ -0,0 +1 @@ +WiredTiger lock file diff --git a/source/RewardsService/data/db/WiredTiger.turtle b/source/RewardsService/data/db/WiredTiger.turtle new file mode 100644 index 00000000..8fd9d336 --- /dev/null +++ b/source/RewardsService/data/db/WiredTiger.turtle @@ -0,0 +1,6 @@ +WiredTiger version string +WiredTiger 11.2.0: (November 10, 2022) +WiredTiger version +major=11,minor=2,patch=0 +file:WiredTiger.wt +access_pattern_hint=none,allocation_size=4KB,app_metadata=,assert=(commit_timestamp=none,durable_timestamp=none,read_timestamp=none,write_timestamp=off),block_allocation=best,block_compressor=,cache_resident=false,checksum=on,collator=,columns=,dictionary=0,encryption=(keyid=,name=),format=btree,huffman_key=,huffman_value=,id=0,ignore_in_memory_cache_size=false,internal_item_max=0,internal_key_max=0,internal_key_truncate=true,internal_page_max=4KB,key_format=S,key_gap=10,leaf_item_max=0,leaf_key_max=0,leaf_page_max=32KB,leaf_value_max=0,log=(enabled=true),memory_page_image_max=0,memory_page_max=5MB,os_cache_dirty_max=0,os_cache_max=0,prefix_compression=false,prefix_compression_min=4,readonly=false,split_deepen_min_child=0,split_deepen_per_child=0,split_pct=90,tiered_object=false,tiered_storage=(auth_token=,bucket=,bucket_prefix=,cache_directory=,local_retention=300,name=,object_target_size=0),value_format=S,verbose=[],version=(major=1,minor=1),write_timestamp_usage=none,checkpoint=(WiredTigerCheckpoint.278=(addr="018381e43833b1bc8481e4fa3c33458581e41b6d9956808080e3018fc0e24fc0",order=278,time=1714664785,size=32768,newest_start_durable_ts=0,oldest_start_ts=0,newest_txn=1,newest_stop_durable_ts=0,newest_stop_ts=-1,newest_stop_txn=-11,prepare=0,write_gen=833,run_write_gen=831)),checkpoint_backup_info=,checkpoint_lsn=(3,256) diff --git a/source/RewardsService/data/db/WiredTiger.wt b/source/RewardsService/data/db/WiredTiger.wt new file mode 100644 index 00000000..c3184a18 Binary files /dev/null and b/source/RewardsService/data/db/WiredTiger.wt differ diff --git a/source/RewardsService/data/db/WiredTigerHS.wt b/source/RewardsService/data/db/WiredTigerHS.wt new file mode 100644 index 00000000..3f019cba Binary files /dev/null and b/source/RewardsService/data/db/WiredTigerHS.wt differ diff --git a/source/RewardsService/data/db/_mdb_catalog.wt b/source/RewardsService/data/db/_mdb_catalog.wt new file mode 100644 index 00000000..e664f7fa Binary files /dev/null and b/source/RewardsService/data/db/_mdb_catalog.wt differ diff --git a/source/RewardsService/data/db/collection-0--6695832865021636644.wt b/source/RewardsService/data/db/collection-0--6695832865021636644.wt new file mode 100644 index 00000000..3645f876 Binary files /dev/null and b/source/RewardsService/data/db/collection-0--6695832865021636644.wt differ diff --git a/source/RewardsService/data/db/collection-0-8325661258714547486.wt b/source/RewardsService/data/db/collection-0-8325661258714547486.wt new file mode 100644 index 00000000..2d189493 Binary files /dev/null and b/source/RewardsService/data/db/collection-0-8325661258714547486.wt differ diff --git a/source/RewardsService/data/db/collection-2-8325661258714547486.wt b/source/RewardsService/data/db/collection-2-8325661258714547486.wt new file mode 100644 index 00000000..b802a1ac Binary files /dev/null and b/source/RewardsService/data/db/collection-2-8325661258714547486.wt differ diff --git a/source/RewardsService/data/db/collection-4-8325661258714547486.wt b/source/RewardsService/data/db/collection-4-8325661258714547486.wt new file mode 100644 index 00000000..e8c78f34 Binary files /dev/null and b/source/RewardsService/data/db/collection-4-8325661258714547486.wt differ diff --git a/source/RewardsService/data/db/collection-7-8325661258714547486.wt b/source/RewardsService/data/db/collection-7-8325661258714547486.wt new file mode 100644 index 00000000..16b14ede Binary files /dev/null and b/source/RewardsService/data/db/collection-7-8325661258714547486.wt differ diff --git a/source/RewardsService/data/db/diagnostic.data/metrics.2024-05-02T08-20-31Z-00000 b/source/RewardsService/data/db/diagnostic.data/metrics.2024-05-02T08-20-31Z-00000 new file mode 100644 index 00000000..6426ee67 Binary files /dev/null and b/source/RewardsService/data/db/diagnostic.data/metrics.2024-05-02T08-20-31Z-00000 differ diff --git a/source/RewardsService/data/db/diagnostic.data/metrics.2024-05-02T13-00-20Z-00000 b/source/RewardsService/data/db/diagnostic.data/metrics.2024-05-02T13-00-20Z-00000 new file mode 100644 index 00000000..697a8c93 Binary files /dev/null and b/source/RewardsService/data/db/diagnostic.data/metrics.2024-05-02T13-00-20Z-00000 differ diff --git a/source/RewardsService/data/db/diagnostic.data/metrics.2024-05-02T15-46-27Z-00000 b/source/RewardsService/data/db/diagnostic.data/metrics.2024-05-02T15-46-27Z-00000 new file mode 100644 index 00000000..2b6dc81a Binary files /dev/null and b/source/RewardsService/data/db/diagnostic.data/metrics.2024-05-02T15-46-27Z-00000 differ diff --git a/source/RewardsService/data/db/diagnostic.data/metrics.interim b/source/RewardsService/data/db/diagnostic.data/metrics.interim new file mode 100644 index 00000000..25b0db11 Binary files /dev/null and b/source/RewardsService/data/db/diagnostic.data/metrics.interim differ diff --git a/source/RewardsService/data/db/index-1--6695832865021636644.wt b/source/RewardsService/data/db/index-1--6695832865021636644.wt new file mode 100644 index 00000000..d006016c Binary files /dev/null and b/source/RewardsService/data/db/index-1--6695832865021636644.wt differ diff --git a/source/RewardsService/data/db/index-1-8325661258714547486.wt b/source/RewardsService/data/db/index-1-8325661258714547486.wt new file mode 100644 index 00000000..1cc7ff47 Binary files /dev/null and b/source/RewardsService/data/db/index-1-8325661258714547486.wt differ diff --git a/source/RewardsService/data/db/index-3-8325661258714547486.wt b/source/RewardsService/data/db/index-3-8325661258714547486.wt new file mode 100644 index 00000000..c4fa97d8 Binary files /dev/null and b/source/RewardsService/data/db/index-3-8325661258714547486.wt differ diff --git a/source/RewardsService/data/db/index-5-8325661258714547486.wt b/source/RewardsService/data/db/index-5-8325661258714547486.wt new file mode 100644 index 00000000..ee2ec655 Binary files /dev/null and b/source/RewardsService/data/db/index-5-8325661258714547486.wt differ diff --git a/source/RewardsService/data/db/index-6-8325661258714547486.wt b/source/RewardsService/data/db/index-6-8325661258714547486.wt new file mode 100644 index 00000000..ed4f0102 Binary files /dev/null and b/source/RewardsService/data/db/index-6-8325661258714547486.wt differ diff --git a/source/RewardsService/data/db/index-8-8325661258714547486.wt b/source/RewardsService/data/db/index-8-8325661258714547486.wt new file mode 100644 index 00000000..02d7520f Binary files /dev/null and b/source/RewardsService/data/db/index-8-8325661258714547486.wt differ diff --git a/source/RewardsService/data/db/journal/WiredTigerLog.0000000002 b/source/RewardsService/data/db/journal/WiredTigerLog.0000000002 new file mode 100644 index 00000000..06d26101 Binary files /dev/null and b/source/RewardsService/data/db/journal/WiredTigerLog.0000000002 differ diff --git a/source/RewardsService/data/db/journal/WiredTigerLog.0000000003 b/source/RewardsService/data/db/journal/WiredTigerLog.0000000003 new file mode 100644 index 00000000..c0a97621 Binary files /dev/null and b/source/RewardsService/data/db/journal/WiredTigerLog.0000000003 differ diff --git a/source/RewardsService/data/db/journal/WiredTigerTmplog.0000000002 b/source/RewardsService/data/db/journal/WiredTigerTmplog.0000000002 new file mode 100644 index 00000000..aa52a216 Binary files /dev/null and b/source/RewardsService/data/db/journal/WiredTigerTmplog.0000000002 differ diff --git a/source/RewardsService/data/db/mongod.lock b/source/RewardsService/data/db/mongod.lock new file mode 100644 index 00000000..d00491fd --- /dev/null +++ b/source/RewardsService/data/db/mongod.lock @@ -0,0 +1 @@ +1 diff --git a/source/RewardsService/data/db/sizeStorer.wt b/source/RewardsService/data/db/sizeStorer.wt new file mode 100644 index 00000000..6ddeb45f Binary files /dev/null and b/source/RewardsService/data/db/sizeStorer.wt differ diff --git a/source/RewardsService/data/db/storage.bson b/source/RewardsService/data/db/storage.bson new file mode 100644 index 00000000..276b6945 Binary files /dev/null and b/source/RewardsService/data/db/storage.bson differ diff --git a/source/RewardsService/rewardsservice/handlers/customer_handler.py b/source/RewardsService/rewardsservice/handlers/customer_handler.py new file mode 100644 index 00000000..066557e9 --- /dev/null +++ b/source/RewardsService/rewardsservice/handlers/customer_handler.py @@ -0,0 +1,76 @@ +import re +import json +import tornado.web +from pymongo import MongoClient +from tornado.gen import coroutine + + +class CustomerHandler(tornado.web.RequestHandler): + """ + Request handler for managing customer data. + """ + + @coroutine + def get(self, email): + """ + GET method to retrieve a customer's rewards data. + + Request Arguments: + - email: Customer's email address + + Response: + - 200 OK: Customer rewards data retrieved successfully + - 400 Bad Request: Missing or invalid email address + - 404 Not Found: Customer not found + """ + + # Validate email + if not email or not self._is_valid_email(email): + self.set_status(400) + self.write("Missing or invalid email address") + return + + # Retrieve customer rewards data from MongoDB (implementation required) + rewards_data = self._retrieve_rewards_data(email) + + if rewards_data: + # Respond with customer rewards data + self.set_status(200) + self.write(json.dumps(rewards_data)) + else: + # Respond with customer not found + self.set_status(404) + self.write("Customer not found") + + def _retrieve_rewards_data(self, email): + """ + Retrieve customer rewards data from MongoDB. + + Args: + email (str): Customer's email address. + + Returns: + dict: Customer rewards data if found, None otherwise. + """ + # Connect to MongoDB + client = MongoClient("mongodb", 27017) + db = client["Rewards"] + + # Query MongoDB to retrieve customer rewards data + reward = list(db.customers.find({"email": email}, {"_id": 0})) + + return reward + + def _is_valid_email(self, email): + """ + Validate email address format. + + Args: + email (str): Email address to validate. + + Returns: + bool: True if the email address is valid, False otherwise. + """ + # Regular expression for email validation + regex = r"^[\w\.-]+@[\w\.-]+\.\w+$" + return re.match(regex, email) is not None diff --git a/source/RewardsService/rewardsservice/handlers/customers_rewards_handler.py b/source/RewardsService/rewardsservice/handlers/customers_rewards_handler.py new file mode 100644 index 00000000..67608a5c --- /dev/null +++ b/source/RewardsService/rewardsservice/handlers/customers_rewards_handler.py @@ -0,0 +1,43 @@ +import json +import tornado.web +from pymongo import MongoClient +from tornado.gen import coroutine + + +class CustomersRewardsHandler(tornado.web.RequestHandler): + """ + Request handler for managing customers rewards data. + """ + + @coroutine + def get(self): + """ + GET method to retrieve rewards data for all customers. + + Request Arguments: + - None + + Response: + - 200 OK: Customers rewards data retrieved successfully + """ + # Retrieve rewards data for all customers + rewards_data = self._retrieve_rewards_data() + + # Respond with rewards data + self.write(json.dumps(rewards_data)) + + def _retrieve_rewards_data(self): + """ + Retrieve rewards data for all customers from MongoDB. + + Returns: + list: List of rewards data for all customers. + """ + # Connect to MongoDB + client = MongoClient("mongodb", 27017) + db = client["Rewards"] + + # Retrieve rewards data for all customers + rewards_data = list(db.customers.find({}, {"_id": 0})) + + return rewards_data \ No newline at end of file diff --git a/source/RewardsService/rewardsservice/handlers/order_handler.py b/source/RewardsService/rewardsservice/handlers/order_handler.py new file mode 100644 index 00000000..1993ad45 --- /dev/null +++ b/source/RewardsService/rewardsservice/handlers/order_handler.py @@ -0,0 +1,104 @@ +import json +import tornado.web +from pymongo import MongoClient +from tornado.gen import coroutine + +""" +Endpoint 1 Specs:: + +* Accept a customer's order data: email adress (ex. "customer01@gmail.com") and order total (ex. 100.80). +* Calculate and store the following customer rewards data into MongoDB. For each dollar a customer spends, the customer will earn 1 reward point. For example, an order of $100.80 earns 100 points. Once a customer has reached the top rewards tier, there are no more rewards the customer can earn. + Email Address: the customer's email address (ex. "customer01@gmail.com") + Reward Points: the customer's rewards points (ex. 100) + Reward Tier: the rewards tier the customer has reached (ex. "A") + Reward Tier Name: the name of the rewards tier (ex. "5% off purchase") + Next Reward Tier: the next rewards tier the customer can reach (ex. "B") + Next Reward Tier Name: the name of next rewards tier (ex. "10% off purchase") + Next Reward Tier Progress: the percentage the customer is away from reaching the next rewards tier (ex. 0.5) +""" + + +class OrderHandler(tornado.web.RequestHandler): + """ + Endpoint for accepting customer's order data and calculating rewards. + + Request Payload: + { + "email": "customer01@gmail.com", + "total_amount": 100.80 + } + + Response: + { + "message": "Reward data stored successfully" + } + """ + + @coroutine + def post(self): + """ + Accepts customer's order data and calculates rewards. + + Parameters: + email (str): Customer's email address. + total_amount (float): Total amount of the order. + + Returns: + None + """ + try: + data = json.loads(self.request.body.decode('utf-8')) + except json.JSONDecodeError: + self.set_status(400) + self.write("Invalid JSON format in the request body.") + return + + email = data.get("email") + total_amount = data.get("total_amount") + + # Validate email and order total + if not email or not total_amount or total_amount <= 0: + self.set_status(400) + self.write("Invalid email or order total") + return + + # Calculate reward points + reward_points = int(total_amount) + + # Retrieve rewards data from MongoDB + client = MongoClient("mongodb", 27017) + db = client["Rewards"] + rewards = list(db.rewards.find({}, {"_id": 0})) + + # Calculate reward tier + reward_tier = None + reward_tier_name = None + next_reward_tier = None + next_reward_tier_name = None + next_reward_tier_progress = None + + for reward in rewards: + if reward_points >= reward["points"]: + reward_tier = reward["tier"] + reward_tier_name = reward["rewardName"] + else: + next_reward_tier = reward["tier"] + next_reward_tier_name = reward["rewardName"] + next_reward_tier_progress = min(reward_points / reward["points"], 1.0) + break + + # Store rewards data + db.customers.insert_one( + { + "email": email, + "reward_points": reward_points, + "reward_tier": reward_tier, + "reward_tier_name": reward_tier_name, + "next_reward_tier": next_reward_tier, + "next_reward_tier_name": next_reward_tier_name, + "next_reward_tier_progress": next_reward_tier_progress + } + ) + + self.set_status(201) + self.write({"message": "Reward data stored successfully"}) diff --git a/source/RewardsService/rewardsservice/settings.py b/source/RewardsService/rewardsservice/settings.py index 94ad9e55..dd48d1b0 100644 --- a/source/RewardsService/rewardsservice/settings.py +++ b/source/RewardsService/rewardsservice/settings.py @@ -14,5 +14,9 @@ settings = { 'debug': True, 'static_path': STATIC_ROOT, - 'template_loader': tornado.template.Loader(TEMPLATE_ROOT) + 'template_loader': tornado.template.Loader(TEMPLATE_ROOT), + "allow_origin": "*", # Allow requests from any origin + "allow_credentials": True, # Allow credentials (e.g., cookies, authorization headers) + "allow_methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"], # Allowed HTTP methods + "allow_headers": ["Content-Type", "Authorization"], # Allowed request headers } diff --git a/source/RewardsService/rewardsservice/url_patterns.py b/source/RewardsService/rewardsservice/url_patterns.py index 55e471d6..046dbf1e 100644 --- a/source/RewardsService/rewardsservice/url_patterns.py +++ b/source/RewardsService/rewardsservice/url_patterns.py @@ -1,5 +1,13 @@ +from handlers.order_handler import OrderHandler +from handlers.customer_handler import CustomerHandler +from handlers.customers_rewards_handler import ( + CustomersRewardsHandler, +) from handlers.rewards_handler import RewardsHandler url_patterns = [ - (r'/rewards', RewardsHandler), + (r"/orders", OrderHandler), + (r"/customers", CustomersRewardsHandler), + (r"/customers/([^/]+)", CustomerHandler), + (r"/rewards", RewardsHandler), ] diff --git a/source/RewardsUI/global/settings.py b/source/RewardsUI/global/settings.py index 5fe952e5..843c8941 100644 --- a/source/RewardsUI/global/settings.py +++ b/source/RewardsUI/global/settings.py @@ -25,7 +25,7 @@ # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True -ALLOWED_HOSTS = [] +ALLOWED_HOSTS = ['*'] # Application definition @@ -37,6 +37,7 @@ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', + 'rewards' ] MIDDLEWARE = [ diff --git a/source/RewardsUI/rewards/clients/rewards_service_client.py b/source/RewardsUI/rewards/clients/rewards_service_client.py index 70b56545..1a57e9a9 100644 --- a/source/RewardsUI/rewards/clients/rewards_service_client.py +++ b/source/RewardsUI/rewards/clients/rewards_service_client.py @@ -1,11 +1,65 @@ import requests - class RewardsServiceClient: + """ + Client for interacting with the RewardsService API. + """ def __init__(self): + """ + Initializes the RewardsServiceClient with base URLs for different endpoints. + """ self.rewards_url = "http://rewardsservice:7050/rewards" + self.order_url = "http://rewardsservice:7050/orders" + self.customers_url = "http://rewardsservice:7050/customers" def get_rewards(self): + """ + Retrieves reward data from the RewardsService API. + + Returns: + dict: Reward data as JSON. + """ response = requests.get(self.rewards_url) return response.json() + + def submit_order(self, email, total_amount): + """ + Submits an order to the RewardsService API. + + Args: + email (str): The customer's email address. + total_amount (float): The total amount of the order. + + Returns: + str: A message indicating the success or failure of the order submission. + """ + order_data = { + 'email': email, + 'total_amount': int(total_amount) + } + try: + response = requests.post(self.order_url, json=order_data) + response.raise_for_status() # Raise an exception for HTTP errors + if response.status_code == 200: + return "Order submitted successfully." + else: + return "Failed to submit order. Please try again later." + except requests.RequestException as e: + return "Failed to submit order. Please try again later." + + def get_customers_rewards(self, email=None): + """ + Retrieves customer rewards data from the RewardsService API. + + Args: + email (str, optional): The customer's email address. If provided, retrieves rewards data for the specific customer. Defaults to None. + + Returns: + dict: Customer rewards data as JSON. + """ + if email: + response = requests.get(self.customers_url + '/' + email) + else: + response = requests.get(self.customers_url) + return response.json() \ No newline at end of file diff --git a/source/RewardsUI/rewards/index.html b/source/RewardsUI/rewards/index.html index cdab1ee4..5cf36dd6 100644 --- a/source/RewardsUI/rewards/index.html +++ b/source/RewardsUI/rewards/index.html @@ -1,63 +1,235 @@ - + + + + + Rewards Dashboard + -

Welcome to the Rewards Dashboard

-
-

Reward Tiers

- - - - - - {% for reward in rewards_data %} - - - - - {% endfor %} -
Rewards Tier - Reward PointsRewards Tier Name
{{ reward.tier }} - {{ reward.points }}{{ reward.rewardName }}
-
+ -
-

Add orders

-
-
- -
-
-
-
-

User Rewards

-
- -
- - - - - - - - - - - - - - - - - - - - - - - -
Email AddressReward PointsReward TierReward Tier NameNext Reward TierNext Reward Tier NameNext Reward Tier Progress
customer01@gmail.com100A5% off purchaseB10% off purchase50%
+ +
+
+

Add Orders

+
+ {% csrf_token %} + +
+ +
+ +
+ {% if success_message %} +

{{ success_message }}

+ {% endif %} + {% if error_message %} +

{{ error_message }}

+ {% endif %} +
+
+

Reward Tiers

+ + + + + + + {% for reward in rewards_data %} + + + + + + {% endfor %} +
Rewards TierReward PointsRewards Tier Name
{{ reward.tier }}{{ reward.points }}{{ reward.rewardName }}
+
+
+ +
+

User Rewards

+
+ +
+ +
+ + + + + + + + + + + + + + {% for reward_data in customers_rewards_data %} + + + + + + + + + + {% endfor %} + +
Email AddressReward PointsReward TierReward Tier NameNext Reward TierNext Reward Tier NameNext Reward Tier Progress
{{ reward_data.email }}{{ reward_data.reward_points }}{{ reward_data.reward_tier }}{{ reward_data.reward_tier_name }}{{ reward_data.next_reward_tier }}{{ reward_data.next_reward_tier_name }}{{ reward_data.next_reward_tier_progress }}
+
- \ No newline at end of file + diff --git a/source/RewardsUI/rewards/views.py b/source/RewardsUI/rewards/views.py index 1d5dd537..adf9d370 100644 --- a/source/RewardsUI/rewards/views.py +++ b/source/RewardsUI/rewards/views.py @@ -1,26 +1,102 @@ import logging - from django.template.response import TemplateResponse from django.views.generic.base import TemplateView - from rewards.clients.rewards_service_client import RewardsServiceClient - class RewardsView(TemplateView): + """ + View for rendering the Rewards Dashboard template. + """ + template_name = 'index.html' def __init__(self, logger=logging.getLogger(__name__), rewards_service_client=RewardsServiceClient()): + """ + Initializes the RewardsView with a logger and a RewardsServiceClient instance. + + Args: + logger (Logger, optional): Logger instance for logging messages. Defaults to logging.getLogger(__name__). + rewards_service_client (RewardsServiceClient, optional): Instance of RewardsServiceClient for interacting with the Rewards Service API. Defaults to RewardsServiceClient(). + """ self.logger = logger self.rewards_service_client = rewards_service_client def get(self, request, *args, **kwargs): + """ + Handles GET requests to the view. + + Retrieves rewards data and customer rewards data based on search_email GET parameter. + + Args: + request (HttpRequest): The HTTP request object. + *args: Additional positional arguments. + **kwargs: Additional keyword arguments. + + Returns: + TemplateResponse: Template response object. + """ + context = self.get_context_data(**kwargs) + + # Retrieve rewards data + rewards_data = self.rewards_service_client.get_rewards() + + # Get the search_email from the request GET parameters + search_email = request.GET.get('search_email') + + # Retrieve customer rewards data based on search_email + customers_rewards = self.rewards_service_client.get_customers_rewards(search_email) + + # Add rewards and customers_rewards data to the context + context['rewards_data'] = rewards_data + context['customers_rewards_data'] = customers_rewards + + return TemplateResponse( + request, + self.template_name, + context + ) + + def post(self, request, *args, **kwargs): + """ + Handles POST requests to the view. + + Submits customer's order data and retrieves rewards data and customer rewards data. + + Args: + request (HttpRequest): The HTTP request object. + *args: Additional positional arguments. + **kwargs: Additional keyword arguments. + + Returns: + TemplateResponse: Template response object. + """ context = self.get_context_data(**kwargs) + # Retrieve form data + email = request.POST.get('email') + total_amount = request.POST.get('total_amount') + + # Submit customer's order data + if email and total_amount: + context['success_message'] = self.rewards_service_client.submit_order(email, total_amount) + else: + context['error_message'] = 'Please provide both email address and order total.' + + # Retrieve rewards data rewards_data = self.rewards_service_client.get_rewards() + + # Get the search_email from the request GET parameters + search_email = request.GET.get('search_email', None) + + # Retrieve customer rewards data based on search_email + customers_rewards = self.rewards_service_client.get_customers_rewards(search_email) + + # Add rewards and customers_rewards data to the context context['rewards_data'] = rewards_data + context['customers_rewards_data'] = customers_rewards return TemplateResponse( request, self.template_name, context - ) \ No newline at end of file + )