Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v0.4.0 #137

Merged
merged 29 commits into from
Jun 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
dea9ade
Added supports for tables:
Satendra-SR May 9, 2021
7ce353c
Update feature_request.md
Satendra-SR May 20, 2021
09bc7eb
Update bug_report.md
Satendra-SR May 20, 2021
a8b5486
Merge pull request #113 from DostEducation/fix-bug-issue-template
Satendra-SR May 21, 2021
39debd0
Merge pull request #112 from DostEducation/fix-issue-template
Satendra-SR May 21, 2021
0802e0b
Changes include:
Satendra-SR May 25, 2021
308f8cf
Merge pull request #117 from DostEducation/feature/116-check-for-modu…
Satendra-SR May 25, 2021
a900f4d
Revisited reg, user and user program workflow
Satendra-SR May 27, 2021
e2cf01c
Merge pull request #121 from DostEducation/feature/enhancements-to-mu…
Satendra-SR Jun 3, 2021
4210d82
Function renaming
Satendra-SR Jun 7, 2021
d39c98b
Merge pull request #120 from DostEducation/feature/registration-user-…
Satendra-SR Jun 8, 2021
e84e684
Added check for registration
Satendra-SR Jun 16, 2021
b8a4626
Updated the query to get user registration data using last 10 digit o…
Satendra-SR Jun 16, 2021
79ca48b
Merge branch 'feature/multiple-registration-entry-for-one-phone-numbe…
Satendra-SR Jun 16, 2021
e6944b5
Code refactoring
Satendra-SR Jun 21, 2021
473f79b
Added model based status
Satendra-SR Jun 21, 2021
03d9d09
Fetch default program value from config
Satendra-SR Jun 21, 2021
4ec0a2d
set default program value in config
Satendra-SR Jun 21, 2021
674e486
Bug fix creating database uri
Satendra-SR Jun 22, 2021
f4d010f
Registration statuses
Satendra-SR Jun 22, 2021
ede80a0
fix Registration status workflow
Satendra-SR Jun 22, 2021
2c7461f
Fixed issues with phone comparision
Satendra-SR Jun 22, 2021
2c99eb0
Merge pull request #129 from DostEducation/feature/15-load-env-variab…
Satendra-SR Jun 23, 2021
4a8c03c
Fixed wording for registration status
Satendra-SR Jun 23, 2021
918070d
Merge pull request #130 from DostEducation/feature/126/default-progra…
Satendra-SR Jun 23, 2021
4ae8de3
Fixed user program logic
Satendra-SR Jun 23, 2021
f7f56ac
Removed unused function
Satendra-SR Jun 23, 2021
00e8121
Updated program selection logic
Satendra-SR Jun 23, 2021
d49ee2b
Merge pull request #132 from DostEducation/feature/126-default-progra…
Satendra-SR Jun 25, 2021
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
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
name: Bug report
about: Create a report to help us improve
title: "[BUG] "
labels: bug
assignees: Satendra-SR
labels: bug 🐛
assignees: Satendra-SR, rudresh

---

Expand Down
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
name: Feature request
about: Suggest an idea for this project
title: "[FEATURE] "
labels: enhancement
assignees: Satendra-SR
labels: enhancement 💥
assignees: Satendra-SR, rudresh

---

Expand Down
26 changes: 1 addition & 25 deletions api/helpers/db_helper.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from api import models, db, helpers
from api import models, db

# TODO: Need to refactor this and try using ORM
def get_partner_id_by_system_phone(system_phone):
Expand All @@ -12,30 +12,6 @@ def get_partner_id_by_system_phone(system_phone):
return None


def get_program_prompt_id(jsonData):
"""
Expected program_details categories format (for ex): INTRO_1-SIGNUP_1-SELECTION_PROGRAM-OPTIN_2
Value returned by this function: 2
"""
if "program_details" in jsonData:
program_categories = helpers.fetch_by_key(
"categories", jsonData["program_details"]
)
if len(program_categories) > 0:
split_prompt_by_hyphen = helpers.split_prompt_by_hyphen(
program_categories[0]
)
split_prompt_by_underscore = helpers.split_prompt_by_underscore(
split_prompt_by_hyphen[-1]
)
return (
split_prompt_by_underscore[1]
if len(split_prompt_by_underscore) > 1
else None
)
return None


def save(data):
db.session.add(data)
db.session.commit()
Expand Down
27 changes: 27 additions & 0 deletions api/helpers/prompt_helper.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from api import helpers


def split_prompt_by_hyphen(data):
split_prompt = data.split("-")
return split_prompt
Expand All @@ -6,3 +9,27 @@ def split_prompt_by_hyphen(data):
def split_prompt_by_underscore(data):
program_sub_prompt = data.split("_")
return program_sub_prompt


def get_program_prompt_id(jsonData):
"""
Expected program_details categories format (for ex): INTRO_1-SIGNUP_1-SELECTION_PROGRAM-OPTIN_2
Value returned by this function: 2
"""
if "program_details" in jsonData:
program_categories = helpers.fetch_by_key(
"categories", jsonData["program_details"]
)
if len(program_categories) > 0:
split_prompt_by_hyphen = helpers.split_prompt_by_hyphen(
program_categories[0]
)
split_prompt_by_underscore = helpers.split_prompt_by_underscore(
split_prompt_by_hyphen[-1]
)
return (
split_prompt_by_underscore[1]
if len(split_prompt_by_underscore) > 1
else None
)
return None
17 changes: 15 additions & 2 deletions api/models/registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ def get_by_id(self, id):
)

def get_by_phone(self, phone):
return self.filter(Registration.user_phone == phone).first()
return self.filter(Registration.user_phone.contains(phone[-10:])).first()

def get_by_user_id(self, user_id):
return self.filter(Registration.user_id == user_id).first()

def get_latest_by_phone(self, phone):
return (
self.filter(Registration.user_phone == phone)
self.filter(Registration.user_phone.contains(phone[-10:]))
.order_by(Registration.id.desc())
.first()
)
Expand All @@ -23,6 +26,12 @@ def get_latest_by_phone(self, phone):
class Registration(TimestampMixin, db.Model):
query_class = RegistrationQuery
__tablename__ = "registration"

class RegistrationStatus(object):
PENDING = "pending"
INCOMPLETE = "incomplete"
COMPLETE = "complete"

id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey("user.id"))
user_phone = db.Column(db.String(50), nullable=False)
Expand All @@ -41,3 +50,7 @@ class Registration(TimestampMixin, db.Model):
has_received_callback = db.Column(db.Boolean)
status = db.Column(db.String(50))
signup_date = db.Column(db.DateTime)

@classmethod
def get_by_user_id(self, user_id):
return Registration.query.get_by_user_id(user_id)
2 changes: 1 addition & 1 deletion api/models/system_phone.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

class SystemPhoneQuery(BaseQuery):
def get_by_phone(self, phone):
return self.filter(SystemPhone.phone == phone).first()
return self.filter(SystemPhone.phone.contains(phone[-10:])).first()


class SystemPhone(TimestampMixin, db.Model):
Expand Down
9 changes: 8 additions & 1 deletion api/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@

class UserQuery(BaseQuery):
def get_by_phone(self, phone):
return self.filter(User.phone == phone).first()
return self.filter(User.phone.contains(phone[-10:])).first()

def get_by_id(self, id):
return self.filter(User.id == id).first()


class User(TimestampMixin, db.Model):
Expand All @@ -22,3 +25,7 @@ class User(TimestampMixin, db.Model):
district = db.Column(db.String(100))
state = db.Column(db.String(100))
country = db.Column(db.String(50))

@classmethod
def get_by_user_id(self, user_id):
return User.query.get_by_id(user_id)
57 changes: 28 additions & 29 deletions api/models/user_program.py
Original file line number Diff line number Diff line change
@@ -1,50 +1,44 @@
from api.mixins import TimestampMixin
from api import db, helpers
from api import db, helpers, models
from flask_sqlalchemy import BaseQuery


class UserProgramQuery(BaseQuery):
def upsert_user_program(self, user_id, program_id, data):
user_program_details = self.get_by_user_and_program_ids(user_id, program_id)
program_data = {}
if "preferred_time_slot" in data:
program_data["preferred_time_slot"] = data["preferred_time_slot"]
if "status" in data:
program_data["status"] = data["status"]

user_program_details = self.get_latest_active_user_program(user_id)
if not user_program_details:
user_program = UserProgram(
user_id=user_id,
program_id=program_id,
preferred_time_slot=program_data["preferred_time_slot"]
if "preferred_time_slot" in program_data
else None,
status=data["status"] if "status" in data else "in-progress",
)
helpers.save(user_program)
elif user_program_details and program_data:
self.update(user_program_details, data)
self.create(user_id, program_id, data)
else:
self.update(user_program_details, program_id, data)

def create(self, user_id, program_id, data):
user_program = UserProgram(
user_id=user_id,
program_id=program_id,
status=data["status"]
if "status" in data
else models.UserProgram.UserProgramStatus.IN_PROGRESS,
preferred_time_slot=data["preferred_time_slot"]
if "preferred_time_slot" in data
else None,
)
helpers.save(user_program)

def update(self, user_program_details, data):
def update(self, user_program_details, program_id, data):
try:
for key, value in data.items():
if key == "preferred_time_slot":
user_program_details.preferred_time_slot = value
elif key == "status":
user_program_details.program_id = program_id
if key == "status":
user_program_details.status = value
db.session.commit()
except IndexError:
return "Failed to udpate user program details"

def get_by_user_and_program_ids(self, user_id, program_id):
return self.filter(
UserProgram.user_id == user_id, UserProgram.program_id == program_id
).first()

def get_latest_active_user_program(self, user_id):
return (
self.filter(
UserProgram.user_id == user_id, UserProgram.status != "complete"
UserProgram.user_id == user_id,
UserProgram.status == models.UserProgram.UserProgramStatus.IN_PROGRESS,
)
.order_by(UserProgram.id.desc())
.first()
Expand All @@ -54,6 +48,11 @@ def get_latest_active_user_program(self, user_id):
class UserProgram(TimestampMixin, db.Model):
query_class = UserProgramQuery
__tablename__ = "user_program"

class UserProgramStatus(object):
IN_PROGRESS = "in-progress"
COMPLETE = "complete"

id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey("user.id"))
program_id = db.Column(db.Integer, db.ForeignKey("program.id"))
Expand Down
6 changes: 5 additions & 1 deletion api/services/content_service.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from api import models, db, helpers
from api import models, helpers


class ContentService(object):
Expand All @@ -22,6 +22,10 @@ def add_user_module_content(self, jsonData):
module_content_details = models.ModuleContent.query.get_by_content_id(
self.content_id
)
if not module_content_details:
# it is optional to have Content and Module association
return None

program_module_details = models.ProgramModule.query.get_by_module_id(
module_content_details.module_id
)
Expand Down
66 changes: 17 additions & 49 deletions api/services/prompt_service.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from api import models, db, helpers
from api import models, db, helpers, app


class PromptService(object):
Expand All @@ -25,9 +25,14 @@ def handle_prompt_response(self, jsonData):
self.call_log_id
)
user_details = models.User.query.get_by_phone(self.user_phone)
prompt_program_id = helpers.get_program_prompt_id(jsonData)
updated_registration_data = {}
updated_user_data = {}
if user_details:
prompt_program_id = self.fetch_program_id(jsonData)
user_program_data = {}
user_program_data["preferred_time_slot"] = self.default_time_slot
models.UserProgram.query.upsert_user_program(
user_details.id, prompt_program_id, user_program_data
)

for key in data:
if key != "result" and "category" in data[key] and "name" in data[key]:
prompt_response = data[key]["category"]
Expand All @@ -43,16 +48,10 @@ def handle_prompt_response(self, jsonData):
ivr_prompt_details,
prompt_response_value,
)
if "DISTRICT" in prompt_name:
user_district = prompt_response_value
updated_registration_data["district"] = user_district
updated_user_data["district"] = user_district
elif "PARENT" in prompt_name:
updated_registration_data["parent_type"] = prompt_response_value

response_exists = False
if ivr_prompt_response_details:
response_exists = self.check_if_already_exists(
response_exists = self.if_exists(
ivr_prompt_response_details, prompt_name, prompt_response
)

Expand All @@ -63,19 +62,7 @@ def handle_prompt_response(self, jsonData):
ivr_prompt_data["keypress"] = data[key]["value"]
self.add_prompt_response(ivr_prompt_details, ivr_prompt_data)

if updated_user_data:
self.update_user_details(user_details, updated_user_data)
if user_details and prompt_program_id:
user_program_data = {}
models.UserProgram.query.upsert_user_program(
user_details.id, prompt_program_id, user_program_data
)
if updated_registration_data:
self.update_registration_details(updated_registration_data)

def check_if_already_exists(
self, ivr_prompt_response_details, prompt_name, prompt_response
):
def if_exists(self, ivr_prompt_response_details, prompt_name, prompt_response):
if not ivr_prompt_response_details:
return False
for row in ivr_prompt_response_details:
Expand All @@ -102,31 +89,6 @@ def add_prompt_response(self, ivr_prompt_details, data):
except IndexError:
print("Exception occured")

def update_user_details(self, user_details, data):
if user_details:
try:
for key, value in data.items():
if key == "district":
user_details.district = value
db.session.commit()
except IndexError:
# Need to log this
print("Failed to update user details")

def update_registration_details(self, data):
registrant = models.Registration.query.get_by_phone(self.user_phone)
if registrant:
try:
for key, value in data.items():
if key == "district":
registrant.district = value
if key == "parent_type":
registrant.parent_type = value
db.session.commit()
except IndexError:
# Need to log this
print("Failed to udpate registration details")

def fetch_prompt_response(self, prompt):
split_prompt_by_hyphen = helpers.split_prompt_by_hyphen(prompt)
split_prompt_by_underscore = helpers.split_prompt_by_underscore(
Expand Down Expand Up @@ -193,3 +155,9 @@ def update_mapped_fields(
db.session.commit()
except IndexError:
print("Exception occured")

def fetch_program_id(self, jsonData):
program_id = helpers.get_program_prompt_id(jsonData)
if not program_id:
program_id = app.config["DEFAULT_PROGRAM_ID"]
return program_id
Loading