Skip to content

Commit

Permalink
Merge pull request #86 from DostEducation/develop
Browse files Browse the repository at this point in the history
Release v0.2.0
  • Loading branch information
Satendra-SR authored Apr 26, 2021
2 parents 0e9a777 + 8aec79c commit e6b607f
Show file tree
Hide file tree
Showing 14 changed files with 398 additions and 5 deletions.
31 changes: 31 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#[ISSUE_ID]
<!--- If there is an open issue, please link to the issue here by replacing [ISSUE_ID]-->
<!-- Make sure the PR is against the `develop` branch -->

### Please complete the following steps and check these boxes before filing your PR:


### Types of changes
<!--- What types of changes does your code introduce? -->
- [ ] Bug fix (a change which fixes an issue)
- [ ] New feature (a change which adds functionality)


### Short description of what this resolves:
<!--- Describe your changes in detail -->
<!--- Why these change required? What problem does it solve? -->


### Checklist:
<!--- Mark the checkboxes accordingly. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
- [ ] I have performed a self-review of my own code.
- [ ] The code follows the style guidelines of this project.
- [ ] The code changes are passing the CI checks
- [ ] I have documented my code wherever required.
- [ ] The changes requires a change to the documentation.
- [ ] I have updated the documentation based on the my changes.
<!--- TODO: need to uncomment these two checklist once we start with test cases.
- [ ] I have added tests to cover my changes (if not applicable, please state why)
- [ ] All new and existing tests are passing.
-->
23 changes: 23 additions & 0 deletions api/helpers/common_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,29 @@ def sanitize_phone_string(phoneString):


def fetch_by_key(key, data):
"""Checks whether a key is present in a json array
Args:
key (string): The key which we will be searching for
data (json): The json array in which we are going to make the search
Returns:
string: It will return either string or null if not available
"""
if key in data:
return data[key]
return None


def list_having_string(input_string, list_data):
"""The function checks whether the input string contains one of the list item.
The list items will act as sub string.
Args:
input_string (string): The function will compare the substring against this string.
list_data (list): The list that contains substrings which will be use to compare.
Returns:
[list]: It will returns the list of maching substrings
"""
return list(filter(lambda x: x in input_string.lower(), list_data))
13 changes: 13 additions & 0 deletions api/helpers/db_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,16 @@ def get_program_prompt_id(jsonData):
def save(data):
db.session.add(data)
db.session.commit()


def save_batch(dataObject):
db.session.add_all(dataObject)
db.session.commit()


def get_user_by_phone(phone):
return models.User.query.get_by_phone(phone)


def get_registrant_by_phone(phone):
return models.Registration.query.get_latest_by_phone(phone)
2 changes: 2 additions & 0 deletions api/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@
from .user_module_content import *
from .ivr_prompt import *
from .ivr_prompt_response import *
from .user_group import *
from .user_custom_fields import *
21 changes: 21 additions & 0 deletions api/models/call_log.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,20 @@ def get_by_flow_run_uuid(self, flow_run_uuid):

class CallLog(TimestampMixin, db.Model):
query_class = CallLogQuery

class CallCategories(object):
SCHEDULED = "scheduled"
CALLBACK = "callback"
LIVECALL = "livecall"

class FlowCategories(object):
REGISTRATION = "registration"
CONTENT = "content"
NUDGE = "nudge"
SURVEY = "survey"
BLAST = "blast"
OTHER = "other"

__tablename__ = "call_log"
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey("user.id"))
Expand All @@ -30,3 +44,10 @@ class CallLog(TimestampMixin, db.Model):
dial_time = db.Column(db.DateTime)
start_time = db.Column(db.DateTime)
end_time = db.Column(db.DateTime)
flow_category = db.Column(db.String(50))
call_category = db.Column(db.String(50))
parent_flow_run_uuid = db.Column(db.String(255))
parent_flow_name = db.Column(db.String(255))
flow_run_created_on = db.Column(db.DateTime)
content_id = db.Column(db.Integer)
flow_name = db.Column(db.String(255))
7 changes: 7 additions & 0 deletions api/models/content.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
from api.mixins import TimestampMixin
from api import db
from flask_sqlalchemy import BaseQuery


class ContentQuery(BaseQuery):
def get(self, id):
return self.filter(Content.id == id).first()


class Content(TimestampMixin, db.Model):
query_class = ContentQuery
__tablename__ = "content"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(255), unique=True, nullable=False)
Expand Down
21 changes: 21 additions & 0 deletions api/models/user_custom_fields.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from api.mixins import TimestampMixin
from api import db, helpers
from flask_sqlalchemy import BaseQuery
from sqlalchemy import desc, and_


class UserCustomFieldsQuery(BaseQuery):
def get_by_user_phone(self, phone):
return self.filter(UserCustomFields.user_phone == phone).all()


class UserCustomFields(TimestampMixin, db.Model):
query_class = UserCustomFieldsQuery
__tablename__ = "user_custom_fields"
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey("user.id"))
registration_id = db.Column(db.Integer, db.ForeignKey("registration.id"))
user_phone = db.Column(db.String(50), nullable=False)
flow_run_uuid = db.Column(db.String(255))
field_name = db.Column(db.String(255), nullable=False)
field_value = db.Column(db.String(500), nullable=False)
33 changes: 33 additions & 0 deletions api/models/user_group.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from api.mixins import TimestampMixin
from api import db, helpers
from flask_sqlalchemy import BaseQuery
from sqlalchemy import desc, and_


class UserGroupQuery(BaseQuery):
def get_by_uuid(self, uuid):
return self.filter(UserGroup.group_uuid == uuid).first()

def get_unique(self, uuid, phone):
return (
self.filter(
and_(
UserGroup.group_uuid == uuid,
UserGroup.user_phone == phone,
)
)
.order_by(desc(UserGroup.created_on))
.first()
)


class UserGroup(TimestampMixin, db.Model):
query_class = UserGroupQuery
__tablename__ = "user_group"
id = db.Column(db.Integer, primary_key=True)
user_phone = db.Column(db.String(50), nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey("user.id"))
registration_id = db.Column(db.Integer, db.ForeignKey("registration.id"))
group_name = db.Column(db.String(255), nullable=False)
group_uuid = db.Column(db.String(255))
status = db.Column(db.String(100))
1 change: 1 addition & 0 deletions api/services/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
from .call_log_service import *
from .prompt_service import *
from .content_service import *
from .user_contact_service import *
73 changes: 72 additions & 1 deletion api/services/call_log_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,37 @@ def __init__(self):
self.system_phone = None
self.user_phone = None
self.flow_run_uuid = None
self.flow_run_created_on = None
self.call_log = None
self.missedcall_flow_identifier = ["missedcall", "missed-call"]
self.call_category = models.CallLog.CallCategories.SCHEDULED
self.flow_category = models.CallLog.FlowCategories.OTHER

def set_init_data(self, jsonData):
user_phone = helpers.fetch_by_key("urn", jsonData["contact"])
self.system_phone = helpers.fetch_by_key("address", jsonData["channel"])
self.user_phone = helpers.sanitize_phone_string(user_phone)
self.flow_run_uuid = helpers.fetch_by_key("run_uuid", jsonData)
self.flow_run_uuid = helpers.fetch_by_key(
"run_uuid", jsonData
) # TODO: need to remove this once every flow has flow_run_details variable in webhook
self.handle_flow_run_details(jsonData)

def handle_flow_run_details(self, jsonData):
"""To handle flow run details
Args:
jsonData (json): json data that we are getting from webhook
"""
try:
if "flow_run_details" in jsonData:
self.flow_run_uuid = helpers.fetch_by_key(
"uuid", jsonData["flow_run_details"]
)
self.flow_run_created_on = helpers.fetch_by_key(
"created_on", jsonData["flow_run_details"]
)

except IndexError:
print("Failed to fetch flow run details")

def handle_call_log(self, jsonData):
try:
Expand All @@ -30,21 +54,48 @@ def handle_call_log(self, jsonData):
self.update_call_logs(data)
else:
self.create_call_logs(jsonData)
else:
print("flow_run_uuid is now available.")
except IndexError:
print("Failed to log the call details")

def create_call_logs(self, jsonData):
try:
registration_data = models.Registration.query.get_by_phone(self.user_phone)
user_data = models.User.query.get_by_phone(self.user_phone)
parent_flow_data = self.handle_parent_flow(jsonData)
flow_name = None
if "flow" in jsonData and jsonData["flow"] is not None:
flow_name = helpers.fetch_by_key("name", jsonData["flow"])

content_id = None
if "content_id" in jsonData:
content_id = (jsonData["content_id"],)
content_data = models.Content.query.get(content_id)
if not content_data:
"""If the content id is not available in the system, it will throw the error.
Mark it as None
"""
content_id = None
print("The Content id is not valid")

new_call_log = models.CallLog(
flow_run_uuid=self.flow_run_uuid,
flow_run_created_on=self.flow_run_created_on,
call_type=self.fetch_call_type(),
scheduled_by=self.fetch_call_scheduled_by(),
user_phone_number=self.user_phone,
system_phone_number=helpers.sanitize_phone_string(self.system_phone),
registration_id=registration_data.id if registration_data else None,
user_id=user_data.id if user_data else None,
call_category=self.call_category,
parent_flow_name=parent_flow_data["parent_flow_name"],
parent_flow_run_uuid=parent_flow_data["parent_flow_run_uuid"],
content_id=content_id,
flow_name=flow_name,
flow_category=jsonData["flow_category"]
if "flow_category" in jsonData
else self.flow_category,
)
helpers.save(new_call_log)
except IndexError:
Expand Down Expand Up @@ -74,3 +125,23 @@ def update_user_module_content_id_in_call_log(self, user_module_content_id):
data = {}
data["user_module_content_id"] = user_module_content_id
self.update_call_logs(data)

def handle_parent_flow(self, jsonData):
parent_flow_data = {}
parent_flow_data["parent_flow_name"] = None
parent_flow_data["parent_flow_run_uuid"] = None
if "parent" in jsonData and jsonData["parent"] is not None:
if "flow" in jsonData["parent"]:
parent_flow = jsonData["parent"]["flow"]
parent_flow_data["parent_flow_name"] = parent_flow["name"]
missedcall_category_list = helpers.list_having_string(
parent_flow["name"], self.missedcall_flow_identifier
)
if missedcall_category_list:
"""The call category is set to call back if missedcall flow has ran.
For that, the missed call flow name should contain string "missedcall"
"""
self.call_category = models.CallLog.CallCategories.CALLBACK
if "uuid" in jsonData["parent"]:
parent_flow_data["parent_flow_run_uuid"] = jsonData["parent"]["uuid"]
return parent_flow_data
6 changes: 5 additions & 1 deletion api/services/prompt_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ def __init__(self):
def set_init_data(self, jsonData):
user_phone = helpers.fetch_by_key("urn", jsonData["contact"])
self.user_phone = helpers.sanitize_phone_string(user_phone)
flow_run_uuid = helpers.fetch_by_key("run_uuid", jsonData)
flow_run_uuid = helpers.fetch_by_key(
"run_uuid", jsonData
) # Need to remove once we are done with making changes in webhooks
if "flow_run_details" in jsonData:
flow_run_uuid = helpers.fetch_by_key("uuid", jsonData["flow_run_details"])
call_log_details = models.CallLog.query.get_by_flow_run_uuid(flow_run_uuid)
self.call_log_id = call_log_details.id

Expand Down
8 changes: 7 additions & 1 deletion api/services/registration_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@ def set_init_data(self, jsonData):
def handle_registration(self, jsonData):
try:
self.set_init_data(jsonData)
flow_run_uuid = helpers.fetch_by_key("run_uuid", jsonData)
flow_run_uuid = helpers.fetch_by_key(
"run_uuid", jsonData
) # TODO: need to remove this once every flow has flow_run_details variable in webhook
if "flow_run_details" in jsonData:
flow_run_uuid = helpers.fetch_by_key(
"uuid", jsonData["flow_run_details"]
)
if flow_run_uuid:
call_log = models.CallLog.query.get_by_flow_run_uuid(flow_run_uuid)
if call_log:
Expand Down
Loading

0 comments on commit e6b607f

Please sign in to comment.