File: //home/arjun/projects/buyercall_forms/buyercall/buyercall/blueprints/phonenumbers/models.py
import re
import logging
from flask import (
current_app as app,
url_for
)
from sqlalchemy import or_, and_, func, select
from sqlalchemy.dialects import postgresql as pg
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import load_only, joinedload, column_property
from sqlalchemy.sql import text
from sqlalchemy.orm.attributes import flag_modified
from datetime import datetime
from buyercall.lib.util_twilio import (
bw_client
)
from buyercall.lib.util_sqlalchemy import ResourceMixin
from buyercall.blueprints.user.models import User
from buyercall.blueprints.agents.models import Agent
from buyercall.blueprints.filters import format_phone_number
from buyercall.lib.util_bandwidth import bw_client as bw_dashboard_client
from buyercall.blueprints.partnership.models import PartnershipAccount
from buyercall.blueprints.leads.models import Lead
from buyercall.blueprints.sms.models import Message
from buyercall.blueprints.widgets.models import Widget
from buyercall.extensions import db
log = logging.getLogger(__name__)
class Phone(ResourceMixin, db.Model):
__tablename__ = 'phonenumbers'
id = db.Column(db.Integer, primary_key=True)
# Relationships.
leads = db.relationship(Lead, backref='inbound')
messages = db.relationship(Message, backref="inbound")
partnership_account = db.relationship(PartnershipAccount)
widgets = db.relationship(Widget, backref="inbound")
partnership_account_id = db.Column(
db.Integer,
db.ForeignKey(
'partnership_accounts.id',
onupdate='CASCADE',
ondelete='CASCADE'),
index=True, nullable=False
)
# Phone numbers.
phonenumber = db.Column(db.String(20), nullable=False,
server_default='')
# Local phone number.
local = db.Column('is_local', db.Boolean(), nullable=False,
server_default='0')
# Tollfree phone number.
tollfree = db.Column('is_tollfree', db.Boolean(), nullable=False,
server_default='0')
# Phone number type (tracking/priority)
type = db.Column('type', db.String(), nullable=False,
server_default='priority')
# Is an active phone number.
active = db.Column('is_active', db.Boolean(), nullable=False,
server_default='1')
# Column to determine if callerid is enabled for whisper message.
caller_id = db.Column(
'is_callerid', db.Boolean(),
nullable=False, server_default='0'
)
# Phone Number friendly name.
friendly_name = db.Column(db.String(128), nullable=False,
server_default='')
# Phone Number source name.
source = db.Column(db.String(256), nullable=False, server_default='')
# Marketing channel for the phone number
channel = db.Column(db.String(256), nullable=True)
# Twilio phone number sid.
twilio_number_sid = db.Column(db.String(34), nullable=False,
server_default='')
# Bandwidth application id.
application_id = db.Column(db.String(256), nullable=False,
server_default='')
# See assets/components/inbound/models.js for JSON fields
routing_config = db.Column(
'routings', pg.JSON, nullable=False, server_default='{}')
notifications = db.Column(
pg.JSON, nullable=False, server_default='{}')
provider = db.Column(db.String(10), nullable=False, index=True)
deactivated_on = db.Column(db.DateTime(), nullable=True)
is_deactivated = db.Column(db.Boolean(), nullable=False,
server_default='0', default=False)
lead_count = column_property(select([func.count(Lead.id)]).where(Lead.inbound_id == id))
@classmethod
def search(cls, query):
"""
Search a resource by 1 or more fields.
:param query: Search query
:type query: str
:return: SQLAlchemy filter
"""
if not query:
return text('')
search_query = '%{0}%'.format(query)
return or_(Phone.phonenumber.ilike(search_query),
Phone.friendly_name.ilike(search_query),
Phone.type.ilike(search_query)
)
@classmethod
def create(cls, params):
"""
Return whether or not the phonenumber was created successfully.
:return: bool
"""
phone_params = params
phone = Phone(**phone_params)
db.session.add(phone)
db.session.commit()
return True
@classmethod
def update(cls, id, partnership_account_id, new_phonenumber, friendly_name,
twilio_number_sid, source, channel, is_local, is_tollfree):
"""
Return whether or not the phonenumber was update successfully.
:return: bool
"""
phonenumber = db.session.query(Phone).filter(
and_(Phone.id == id, Phone.partnership_account_id == partnership_account_id)
).first()
if phonenumber is not None:
phonenumber.friendly_name = friendly_name
phonenumber.twilio_number_sid = twilio_number_sid
phonenumber.source = source
phonenumber.channel = channel
phonenumber.is_local = is_local
phonenumber.is_tollfree = is_tollfree
phonenumber.phonenumber = new_phonenumber
db.session.commit()
return True
else:
return False
@classmethod
def api_update(cls, id, partnership_account_id, friendly_name, source, channel, routing_type,
record_calls, config_sms_setup, greeting_message, language, sms_auto_reply, sms_auto_reply_image,
sms_auto_reply_image_url, sms_auto_reply_text, voicemail, voicemail_message, voicemail_message_type,
whisper_message, whisper_message_type, retry_routing, call_order, dial_digit, digital_prompt, agents,
transcribe_answered_call, transcribe_voicemail):
"""
Return whether or not the phonenumber was updated successfully.
:return: bool
"""
result = False
phone = Phone.query.filter(
Phone.partnership_account_id == partnership_account_id,
Phone.id == id,
).first()
default_routing = None
routing_config = None
if phone is not None:
routing_config = phone.routing_config
if friendly_name is not None:
phone.friendly_name = friendly_name
if source is not None:
phone.source = source
if channel is not None:
phone.channel = channel
if routing_type is not None:
routing_config['routingType'] = routing_type
if record_calls is not None:
routing_config['recordCalls'] = record_calls
if config_sms_setup is not None:
routing_config['configSMSSetup'] = config_sms_setup
if greeting_message is not None:
routing_config['greetingMessage'] = greeting_message
if language is not None:
routing_config['language'] = language
if sms_auto_reply is not None:
routing_config['SMSAutoReply'] = sms_auto_reply
if sms_auto_reply_image is not None:
routing_config['SMSAutoReplyImage'] = sms_auto_reply_image
if sms_auto_reply_image_url is not None:
routing_config['SMSAutoReplyImageUrl'] = sms_auto_reply_image_url
if sms_auto_reply_text is not None:
routing_config['SMSAutoReplyText'] = sms_auto_reply_text
if voicemail is not None:
routing_config['voicemail'] = voicemail
if voicemail_message is not None:
routing_config['voicemailMessage'] = voicemail_message
if voicemail_message_type is not None:
routing_config['voicemailMessageType'] = voicemail_message_type
if whisper_message is not None:
routing_config['whisperMessage'] = whisper_message
if whisper_message_type is not None:
routing_config['whisperMessageType'] = whisper_message_type
if digital_prompt is not None:
default_routing = routing_config['defaultRouting']
if default_routing is not None:
default_routing['digitalPrompt'] = digital_prompt
if dial_digit is not None:
default_routing = routing_config['defaultRouting']
if default_routing is not None:
default_routing['dialDigit'] = dial_digit
if retry_routing is not None:
default_routing = routing_config['defaultRouting']
if default_routing is not None:
default_routing['retryRouting'] = retry_routing
if call_order is not None:
default_routing = routing_config['defaultRouting']
if default_routing is not None:
default_routing['callOrder'] = call_order
if agents is not None and len(agents) > 0:
default_routing_agents = []
default_routing = routing_config['defaultRouting']
for agent in agents:
if agent['id'] is not None:
if agent['contactUsing'] is None:
agent['contactUsing'] = 'phone'
if agent['fullName'] is None:
agent['fullName'] = ''
default_routing_agents.append(agent)
default_routing['agents'] = default_routing_agents
if default_routing is not None:
routing_config['defaultRouting'] = default_routing
if transcribe_answered_call is not None:
routing_config['transcribeAnsweredCall'] = transcribe_answered_call
if transcribe_voicemail is not None:
routing_config['transcribeVoiceMail'] = transcribe_voicemail
phone.routing_config = routing_config
flag_modified(phone, 'routing_config')
db.session.commit()
result = True
# If the sms config is set to True lets set a messaging url variable otherwise leave it empty
if routing_config["configSMSSetup"] or phone.type == 'mobile':
sms_enabled = 'on'
else:
sms_enabled = 'off'
# If it's a bandwidth number update the SMS enable status for the TN
if phone.provider == 'bandwidth':
partner_account = PartnershipAccount.query\
.filter(PartnershipAccount.id == partnership_account_id).first()
dashboard_client = bw_dashboard_client(partner_account.partnership_id)
unformatted_phone_number = phone.phonenumber
bw_pn_formatted = unformatted_phone_number.replace("+1", "")
if phone.type == 'mobile':
dashboard_client.phone_numbers_options.update(partner_account_id=str(partnership_account_id),
phonenumber=bw_pn_formatted,
sms_option=sms_enabled,
sms_campaign_id=app.config.get(
'SMS_MOBILE_CAMPAIGN_ID'),
sms_campaign_class=app.config.get(
'SMS_MOBILE_CAMPAIGN_CLASS')
)
else:
dashboard_client.phone_numbers_options.update(partner_account_id=str(partnership_account_id),
phonenumber=bw_pn_formatted,
sms_option=sms_enabled)
return result
@classmethod
def api_add_agent_update(cls, id, partnership_account_id, agent_id, agent_full_name, agent_contact_using):
"""
Return whether or not an agent was successfully added to a phone number.
:return: bool
"""
result = False
phone = Phone.query.filter(
Phone.partnership_account_id == partnership_account_id,
Phone.id == id,
).first()
default_routing = None
routing_config = None
default_routing_agents = None
updated_routing_agents = []
found_agent = False
agent_added = False
if phone is not None:
routing_config = phone.routing_config
if routing_config is not None:
if 'defaultRouting' in routing_config:
default_routing = routing_config['defaultRouting']
if 'agents' in default_routing:
default_routing_agents = default_routing['agents']
for agent in default_routing_agents:
if agent['id'] == agent_id:
if agent_full_name is not None:
agent['fullName'] = agent_full_name
if agent_contact_using is not None:
agent['contactUsing'] = agent_contact_using
updated_routing_agents.append(agent)
found_agent = True
else:
updated_routing_agents.append(agent)
if found_agent:
default_routing['agents'] = updated_routing_agents
else:
if agent_full_name is None:
agent_full_name = ''
if agent_contact_using is None:
agent_contact_using = 'phone'
new_agent = {
'id': agent_id,
'fullName': agent_full_name,
'contactUsing': agent_contact_using
}
updated_routing_agents.append(new_agent)
default_routing['agents'] = updated_routing_agents
agent_added = True
if agent_added or found_agent:
flag_modified(phone, 'routing_config')
db.session.commit()
result = True
return result
else:
return result
else:
return result
else:
return result
else:
return result
@classmethod
def api_remove_agent_update(cls, id, partnership_account_id, agent_id):
"""
Return whether or not an agent was successfully removed from a phone number.
:return: bool
"""
result = False
phone = Phone.query.filter(
Phone.partnership_account_id == partnership_account_id,
Phone.id == id,
).first()
default_routing = None
routing_config = None
default_routing_agents = None
updated_routing_agents = []
found_agent = False
if phone is not None:
routing_config = phone.routing_config
if routing_config is not None:
if 'defaultRouting' in routing_config:
default_routing = routing_config['defaultRouting']
if 'agents' in default_routing:
default_routing_agents = default_routing['agents']
for agent in default_routing_agents:
if agent['id'] != agent_id:
updated_routing_agents.append(agent)
else:
found_agent = True
if found_agent:
default_routing['agents'] = updated_routing_agents
flag_modified(phone, 'routing_config')
db.session.commit()
result = True
return result
else:
return result
else:
return result
else:
return result
else:
return result
else:
return result
@classmethod
def api_mobile_update(cls, id, partnership_account_id, friendly_name, record_calls, voicemail, voicemail_message,
voicemail_message_type, greeting_message, whisper_message, whisper_message_type, agent_id,
agent_full_name, agent_contact_using, transcribe_answered_call, transcribe_voicemail):
"""
Return whether or not the phonenumber was updated successfully.
:return: bool
"""
result = False
phone = Phone.query.filter(
Phone.partnership_account_id == partnership_account_id,
Phone.id == id,
).first()
default_routing = None
routing_config = None
if phone is not None:
routing_config = phone.routing_config
if friendly_name is not None:
phone.friendly_name = friendly_name
if record_calls is not None:
routing_config['recordCalls'] = record_calls
if voicemail is not None:
routing_config['voicemail'] = voicemail
if voicemail_message is not None:
routing_config['voicemailMessage'] = voicemail_message
if voicemail_message_type is not None:
routing_config['voicemailMessageType'] = voicemail_message_type
if greeting_message is not None:
routing_config['greetingMessage'] = greeting_message
if whisper_message is not None:
routing_config['whisperMessage'] = whisper_message
if whisper_message_type is not None:
routing_config['whisperMessageType'] = whisper_message_type
if agent_id is not None:
default_routing = routing_config['defaultRouting']
if default_routing is not None:
agents = default_routing['agents']
first_agent = agents[0]
first_agent['id'] = agent_id
if agent_full_name is not None:
default_routing = routing_config['defaultRouting']
if default_routing is not None:
agents = default_routing['agents']
first_agent = agents[0]
first_agent['fullName'] = agent_full_name
if agent_contact_using is not None:
default_routing = routing_config['defaultRouting']
if default_routing is not None:
agents = default_routing['agents']
first_agent = agents[0]
first_agent['contactUsing'] = agent_contact_using
if default_routing is not None:
routing_config['defaultRouting'] = default_routing
if transcribe_answered_call is not None:
routing_config['transcribeAnsweredCall'] = transcribe_answered_call
if transcribe_voicemail is not None:
routing_config['transcribeVoiceMail'] = transcribe_voicemail
phone.routing_config = routing_config
flag_modified(phone, 'routing_config')
db.session.commit()
result = True
return result
@classmethod
def api_delete(cls, id, partnership_account_id):
"""
Return whether or not the phonenumber was deleted successfully.
:return: bool
"""
try:
from buyercall.blueprints.phonenumbers.views import delete_bw, delete_twilio
# import partnership information to get partnership id
from ..partnership.models import Partnership, PartnershipAccount
partner_account = PartnershipAccount.query \
.filter(PartnershipAccount.id == partnership_account_id).first()
partner = Partnership.query.filter(Partnership.id == partner_account.partnership_id).first()
phone = Phone.query.filter(
Phone.partnership_account_id == partnership_account_id,
Phone.id == id,
).first()
if not phone:
return True
# If debugging, do not delete the numbers
if not app.config.get('DEBUG'):
if phone.provider == 'bandwidth':
delete_bw(phone)
elif phone.provider == 'twilio':
delete_twilio(phone)
phone.is_deactivated = True
phone.deactivated_on = datetime.now()
db.session.commit()
if phone.type == 'mobile':
# Get the endpoint associoated with this number
from ..mobile.models import Endpoint
endpoint = Endpoint.query.filter(Endpoint.inbound_id == id).first()
# Lets get the domain now using the partnership_id
from ..mobile.models import Domain
domain = Domain.query.filter(Domain.id == endpoint.domain_id).first()
# Deactivate the sip_endpoint in BuyerCall
Endpoint.deactivate(endpoint.id, partnership_account_id)
# Delete the endpoint from the provider
if phone.provider == 'bandwidth':
client = bw_client(partner.id)
client.domains.delete_endpoint(
domain_id=domain.domain_id,
endpoint_id=endpoint.provider_id
)
return True
except Exception as e:
log.error('Error deactivating phone number. Error: {}'.format(e))
return False
@classmethod
def deactivate(cls, id, partnership_account_id):
"""
Return whether or not the phone number was deactivated successfully.
:return: bool
"""
phonenumber = (db.session.query(Phone)\
.filter(and_(Phone.id == id, Phone.partnership_account_id == partnership_account_id))).first()
if phonenumber is not None:
phonenumber.is_deactivated = True
phonenumber.active = False
phonenumber.deactivated_on = datetime.now()
db.session.commit()
return True
else:
return False
@classmethod
def mobile_sip_uri(cls, phone_number):
"""
Lookup the mobile sip uri for a number
"""
# Check to see if the agent's number is a BuyerCall provisioned number, mostly used for the
# mobile app
bc_phone_number = cls.query.filter(cls.phonenumber == format_phone_number(phone_number)) \
.order_by(cls.created_on.desc()).first()
# Check to see if the inbound/phone number has a sip associated with it
if bc_phone_number:
from buyercall.blueprints.mobile.models import Endpoint
sip_endpoint = Endpoint.query \
.filter(and_(Endpoint.inbound_id == bc_phone_number.id,
Endpoint.partnership_account_id == bc_phone_number.partnership_account_id)).first()
if sip_endpoint:
return sip_endpoint.sip_uri
return ''
@hybrid_property
def subscription(self):
""" Return subscription associated with a phone number
"""
if self.partnership_account.subscription:
return self.partnership_account.subscription.plan
if self.partnership.subscription:
return self.partnership.subscription.plan
if self.partnership_account.partnership and self.partnership_account.partnership.subscription:
return self.partnership_account.partnership.subscription.plan
return None
@hybrid_property
def toll_type(self):
if self.tollfree:
return 'Toll-Free'
else:
return 'Local'
@hybrid_property
def partnership_id(self):
""" Return the partnership id for a phone number
"""
partner_id = self.partnership_account.partnership_id
return partner_id
@toll_type.setter
def toll_type(self, value):
if value.lower() == 'toll-free':
self.tollfree = True
self.local = False
else:
self.tollfree = False
self.local = True
@toll_type.expression
def toll_type(cls):
return db.case([(cls.tollfree == '1', 'Toll-Free')], else_='Local')
@property
def agents_list(self):
if self.routing_config.get('routingType') == 'default':
routings = [self.routing_config.get('defaultRouting')]
elif self.routing_config.get('routingType') == 'digit':
routings = self.routing_config.get('digitRoutings')
else:
return ''
return ', '.join([
agent.get('fullName') or '{} {}'.format(agent.get('firstName', ''), agent.get('lastName', ''))
for r in routings
for agent in r.get('agents', [])
])
@property
def mobile_agent_email(self):
if self.routing_config.get('routingType') == 'default':
routings = [self.routing_config.get('defaultRouting')]
elif self.routing_config.get('routingType') == 'digit':
routings = self.routing_config.get('digitRoutings')
else:
routings = []
agent_id = [
agent.get('id') for r in routings for agent in r.get('agents', [])
]
agent = Agent.query.options(joinedload('agents')).filter(
Agent.id.in_(agent_id),
).first()
if agent:
email = agent.email
else:
email = ''
return email
@property
def mobile_agent_id(self):
if self.routing_config.get('routingType') == 'default':
routings = [self.routing_config.get('defaultRouting')]
elif self.routing_config.get('routingType') == 'digit':
routings = self.routing_config.get('digitRoutings')
else:
routings = []
agent_id = [agent.get('id') for r in routings for agent in r.get('agents', [])]
agent = Agent.query.options(joinedload('agents')).filter(
Agent.id.in_(agent_id),
).first()
if agent:
a_id = agent.id
else:
a_id = ''
return a_id
@property
def recording_enabled(self):
"""
Return whether or not the phonenumber will record the call or voicemail.
:return: bool
"""
record_enabled = False
voicemail_enabled = False
if 'recordCalls' in self.routing_config:
record_enabled = self.routing_config.get('recordCalls')
if 'voicemail' in self.routing_config:
voicemail_enabled = self.routing_config.get('voicemail')
if record_enabled or voicemail_enabled:
return True
else:
return False
@property
def created_datetime(self):
""" Return the date/time this phonenumber was created
"""
return self.created_on.strftime('%Y-%m-%d %H:%M:%S')
@property
def updated_datetime(self):
""" Return the date/time this phonenumber was updated
"""
return self.updated_on.strftime('%Y-%m-%d %H:%M:%S')
@property
def deactivated_on_datetime(self):
""" Return the date/time this phone was deactivated on.
"""
if self.deactivated_on is not None and self.deactivated_on is not '':
return self.deactivated_on.strftime('%Y-%m-%d %H:%M:%S')
else:
return ''
@property
def notification_recipients(self):
""" Return a list of email addresses to whom email notifications will
be sent
"""
notify_leads = self.notifications.get('notifyLeads', 'none')
emails = []
admin = User.query.options(load_only("email")).filter(
User.partnership_account_id == self.partnership_account_id,
User.role == 'admin',
User.is_deactivated.is_(False)
).first()
if self.routing_config.get('routingType') == 'default':
routings = [self.routing_config.get('defaultRouting')]
elif self.routing_config.get('routingType') == 'digit':
routings = self.routing_config.get('digitRoutings')
else:
routings = []
agent_ids = [
agent.get('id') for r in routings for agent in r.get('agents', [])
]
agents = Agent.query.options(joinedload('agents')).filter(
Agent.id.in_(agent_ids),
).all()
agent_emails = []
for a in agents:
if a.is_group:
agent_emails.extend(x.email for x in a.agents)
else:
agent_emails.append(a.email)
if notify_leads == 'missed':
if admin and self.notifications.get('notifyMissedMe'):
emails.append(admin.email)
if self.notifications.get('notifyMissedAgents'):
emails.extend(agent_emails)
emails.extend(re.split('[;,]', self.notifications.get('notifyMissedCustom')))
elif notify_leads == 'all':
if self.notifications.get('notifyAllMe'):
emails.append(admin.email)
if self.notifications.get('notifyAllAgents'):
emails.extend(agent_emails)
emails.extend(re.split('[;,]', self.notifications.get('notifyAllCustom')))
else:
emails = []
return sorted(set(x for x in emails if x))
def as_dict(self):
return {
'id': self.id,
'phoneNumber': self.phonenumber,
'callerId': self.caller_id,
'friendlyName': self.friendly_name,
'typePn': 'tollfree' if self.tollfree else 'local',
'type': self.type,
'active': self.active,
'subscriptionPlan': self.subscription,
'routingConfig': self.routing_config,
'notificationConfig': self.notifications
}
def connect_audio_files(self):
""" Add foreign keys for the uploaded audio files
"""
ids = []
for field in [
'whisperMessage', 'digitWhisperMessage', 'noDigitWhisperMessage',
'voicemailMessage', 'callBackText',
]:
id_ = self.routing_config.get('{}Audio'.format(field))
if id_:
ids.append(id_)
files = Audio.query.filter(
Audio.id.in_(ids), Audio.inbound_id == None, Audio.widget_guid == None
).all()
for f in files:
f.inbound_id = self.id
db.session.commit()
class HoldMusic(ResourceMixin, db.Model):
__tablename__ = 'holdmusic'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
# Relationships.
partnership_account_id = db.Column(
db.Integer,
db.ForeignKey(
'partnership_accounts.id',
onupdate='CASCADE',
ondelete='CASCADE'
),
index=True, nullable=False
)
uuid = db.Column(db.String, nullable=True)
filename = db.Column(db.String, nullable=True)
url = db.Column(db.String, nullable=True)
# Audio url table used for whisper message that used audio files instead of text-to-speech
class Audio(ResourceMixin, db.Model):
__tablename__ = 'audio_urls'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
inbound_id = db.Column(db.Integer, nullable=True)
widget_guid = db.Column(db.String(128), nullable=True)
whisper_message_type = db.Column(db.String(128), nullable=False, server_default='')
audio_url = db.Column(db.String(256), nullable=False, server_default='')
enabled = db.Column('is_enabled', db.Boolean(), nullable=False, server_default='0')
@property
def created_datetime(self):
""" Return the date/time this widget was created
"""
return self.created_on.strftime('%Y-%m-%d %H:%M:%S')
@property
def updated_datetime(self):
""" Return the date/time this widget was updated
"""
return self.updated_on.strftime('%Y-%m-%d %H:%M:%S')
@classmethod
def api_created(cls, params):
"""
Return the audio url id if it was created successfully.
:return: bool
"""
audio_id = -1
audio_params = params
audio = Audio(**audio_params)
db.session.add(audio)
db.session.flush()
audio_id = audio.id
db.session.commit()
return audio_id
@classmethod
def api_update(cls, id, phonenumber_id, widget_guid, whisper_message_type, audio_url, enabled):
"""
Return whether or not the audio url was updated successfully.
:return: bool
"""
result = False
audio = Audio.query.filter(Audio.id == id).first()
if audio is not None:
if phonenumber_id is not None:
audio.inbound_id = phonenumber_id
if widget_guid is not None:
audio.widget_guid = widget_guid
if whisper_message_type is not None:
audio.whisper_message_type = whisper_message_type
if audio_url is not None:
audio.audio_url = audio_url
if enabled is not None:
audio.enabled = enabled
db.session.commit()
result = True
return result
@classmethod
def api_delete(cls, id, partnership_account_id):
"""
Return whether or not the audio url was deleted successfully.
:return: bool
"""
result = False
audio = Audio.query.filter(Audio.id == id).first()
if audio:
phone = Phone.query \
.filter(and_(audio.inbound_id == Phone.id, Phone.partnership_account_id == partnership_account_id)) \
.first()
if phone:
audio.delete()
db.session.commit()
result = True
return result