Merge pull request #1178 from alphagov/ken-use-inbound-number

Use inbound number for delivering sms and to show on service settings
This commit is contained in:
kentsanggds
2017-08-18 11:42:52 +01:00
committed by GitHub
19 changed files with 439 additions and 33 deletions

View File

@@ -93,6 +93,7 @@ def register_blueprint(application):
from app.organisation.rest import organisation_blueprint
from app.dvla_organisation.rest import dvla_organisation_blueprint
from app.delivery.rest import delivery_blueprint
from app.inbound_number.rest import inbound_number_blueprint
from app.inbound_sms.rest import inbound_sms as inbound_sms_blueprint
from app.notifications.receive_notifications import receive_notifications_blueprint
from app.notifications.notifications_ses_callback import ses_callback_blueprint
@@ -135,6 +136,9 @@ def register_blueprint(application):
delivery_blueprint.before_request(requires_admin_auth)
application.register_blueprint(delivery_blueprint)
inbound_number_blueprint.before_request(requires_admin_auth)
application.register_blueprint(inbound_number_blueprint)
inbound_sms_blueprint.before_request(requires_admin_auth)
application.register_blueprint(inbound_sms_blueprint)

View File

@@ -4,7 +4,7 @@ from app.models import InboundNumber
def dao_get_inbound_numbers():
return InboundNumber.query.all()
return InboundNumber.query.order_by(InboundNumber.updated_at).all()
def dao_get_available_inbound_numbers():
@@ -15,16 +15,19 @@ def dao_get_inbound_number_for_service(service_id):
return InboundNumber.query.filter(InboundNumber.service_id == service_id).first()
def dao_get_inbound_number(inbound_number_id):
return InboundNumber.query.filter(InboundNumber.id == inbound_number_id).first()
@transactional
def dao_set_inbound_number_to_service(service_id, inbound_number):
inbound_number.service_id = service_id
db.session.add(inbound_number)
@transactional
def dao_set_inbound_number_active_flag(inbound_number_id, active):
inbound_number = InboundNumber.query.filter(InboundNumber.id == inbound_number_id).first()
def dao_set_inbound_number_active_flag(service_id, active):
inbound_number = InboundNumber.query.filter(InboundNumber.service_id == service_id).first()
inbound_number.active = active
db.session.add(inbound_number)

View File

@@ -1,7 +1,7 @@
import uuid
from datetime import date, datetime, timedelta
from sqlalchemy import asc, func
from sqlalchemy import asc, func, or_
from sqlalchemy.orm import joinedload
from flask import current_app
@@ -19,6 +19,7 @@ from app.models import (
Template,
TemplateHistory,
TemplateRedacted,
InboundNumber,
Job,
NotificationHistory,
Notification,
@@ -65,9 +66,23 @@ def dao_fetch_service_by_id(service_id, only_active=False):
return query.one()
############
# refactor this when API only uses inbound_numbers and not sms_sender
############
def dao_fetch_services_by_sms_sender(sms_sender):
inbound_number = InboundNumber.query.filter(
InboundNumber.number == sms_sender,
InboundNumber.active
).first()
if not inbound_number:
return []
return Service.query.filter(
Service.sms_sender == sms_sender
or_(
Service.sms_sender == sms_sender,
Service.id == inbound_number.service_id
)
).all()

View File

@@ -51,7 +51,7 @@ def send_sms_to_provider(notification):
to=validate_and_format_phone_number(notification.to, international=notification.international),
content=str(template),
reference=str(notification.id),
sender=service.sms_sender or current_app.config['FROM_NUMBER']
sender=service.get_inbound_number()
)
except Exception as e:
dao_toggle_sms_provider(provider.name)

View File

View File

@@ -0,0 +1,53 @@
from flask import Blueprint, jsonify
from app.dao.inbound_numbers_dao import (
dao_get_inbound_numbers,
dao_get_inbound_number_for_service,
dao_get_available_inbound_numbers,
dao_set_inbound_number_to_service,
dao_set_inbound_number_active_flag
)
from app.errors import InvalidRequest, register_errors
inbound_number_blueprint = Blueprint('inbound_number', __name__, url_prefix='/inbound-number')
register_errors(inbound_number_blueprint)
@inbound_number_blueprint.route('', methods=['GET'])
def get_inbound_numbers():
inbound_numbers = [i.serialize() for i in dao_get_inbound_numbers()]
return jsonify(data=inbound_numbers if inbound_numbers else [])
@inbound_number_blueprint.route('/service/<uuid:service_id>', methods=['GET'])
def get_inbound_number_for_service(service_id):
inbound_number = dao_get_inbound_number_for_service(service_id)
return jsonify(data=inbound_number.serialize() if inbound_number else {})
@inbound_number_blueprint.route('/service/<uuid:service_id>', methods=['POST'])
def post_allocate_inbound_number(service_id):
inbound_number = dao_get_inbound_number_for_service(service_id)
if inbound_number:
if not inbound_number.active:
dao_set_inbound_number_active_flag(service_id, active=True)
return jsonify(), 204
else:
return jsonify(), 200
available_numbers = dao_get_available_inbound_numbers()
if len(available_numbers) > 0:
dao_set_inbound_number_to_service(service_id, available_numbers[0])
return jsonify(), 204
else:
raise InvalidRequest('No available inbound numbers', status_code=400)
@inbound_number_blueprint.route('/service/<uuid:service_id>/off', methods=['POST'])
def post_set_inbound_number_off(service_id):
dao_set_inbound_number_active_flag(service_id, active=False)
return jsonify(), 204

View File

@@ -241,6 +241,12 @@ class Service(db.Model, Versioned):
return cls(**fields)
def get_inbound_number(self):
if self.inbound_number and self.inbound_number.active:
return self.inbound_number.number
else:
return self.sms_sender or current_app.config['FROM_NUMBER']
class InboundNumber(db.Model):
__tablename__ = "inbound_numbers"

View File

@@ -107,7 +107,7 @@ def create_inbound_sms_object(service, content, from_number, provider_ref, date_
inbound = InboundSms(
service=service,
notify_number=service.sms_sender,
notify_number=service.get_inbound_number(),
user_number=user_number,
provider_date=provider_date,
provider_reference=provider_ref,

View File

@@ -80,10 +80,9 @@ def post_notification(notification_type):
)
if notification_type == SMS_TYPE:
sms_sender = authenticated_service.sms_sender or current_app.config.get('FROM_NUMBER')
create_resp_partial = functools.partial(
create_post_sms_response_from_notification,
from_number=sms_sender
from_number=authenticated_service.get_inbound_number()
)
elif notification_type == EMAIL_TYPE:
create_resp_partial = functools.partial(