From 9dfc550f462ad4e161af51f06c0b1f473c89c621 Mon Sep 17 00:00:00 2001 From: Pea Tyczynska Date: Wed, 10 Jul 2019 18:17:33 +0100 Subject: [PATCH] Add org types table --- app/dao/organisation_dao.py | 5 +++ app/dao/services_dao.py | 6 ++- app/models.py | 19 ++++++-- app/service/rest.py | 7 +-- migrations/versions/0299_org_types_table_.py | 47 ++++++++++++++++++++ tests/app/conftest.py | 3 +- tests/app/dao/test_services_dao.py | 2 +- tests/app/db.py | 6 ++- tests/app/service/test_rest.py | 13 ++++-- 9 files changed, 93 insertions(+), 15 deletions(-) create mode 100644 migrations/versions/0299_org_types_table_.py diff --git a/app/dao/organisation_dao.py b/app/dao/organisation_dao.py index 4d4060469..a7a5211a3 100644 --- a/app/dao/organisation_dao.py +++ b/app/dao/organisation_dao.py @@ -101,9 +101,14 @@ def dao_add_service_to_organisation(service, organisation_id): organisation.services.append(service) service.organisation_type = organisation.organisation_type + service.crown = organisation.crown + db.session.add(service) + + + def dao_get_invited_organisation_user(user_id): return InvitedOrganisationUser.query.filter_by(id=user_id).one() diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 2523a4d2a..f67b038d7 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -41,6 +41,7 @@ from app.models import ( EMAIL_TYPE, INTERNATIONAL_SMS_TYPE, KEY_TYPE_TEST, + NON_CROWN_ORGANISATION_TYPES, SMS_TYPE, LETTER_TYPE, ) @@ -282,7 +283,10 @@ def dao_create_service( service.id = service_id or uuid.uuid4() # must be set now so version history model can use same id service.active = True service.research_mode = False - service.crown = service.organisation_type == 'central' + if organisation: + service.crown = organisation.crown + elif service.organisation_type in (NON_CROWN_ORGANISATION_TYPES + ['nhs']): + service.crown = False service.count_as_live = not user.platform_admin for permission in service_permissions: diff --git a/app/models.py b/app/models.py index 3db41ff6d..a0ff1fb71 100644 --- a/app/models.py +++ b/app/models.py @@ -61,8 +61,6 @@ DELIVERY_STATUS_CALLBACK_TYPE = 'delivery_status' COMPLAINT_CALLBACK_TYPE = 'complaint' SERVICE_CALLBACK_TYPES = [DELIVERY_STATUS_CALLBACK_TYPE, COMPLAINT_CALLBACK_TYPE] -ORGANISATION_TYPES = ['central', 'local', 'nhs'] - def filter_null_value_fields(obj): return dict( @@ -326,6 +324,21 @@ class Domain(db.Model): organisation_id = db.Column('organisation_id', UUID(as_uuid=True), db.ForeignKey('organisation.id'), nullable=False) +ORGANISATION_TYPES = [ + "central", "local", "nhs_central", + "nhs_local", "emergency_services", "school_or_college", "other", +] +NON_CROWN_ORGANISATION_TYPES = ["local", "nhs_central", "nhs_local", "emergency_services", "school_or_college"] + + +class OrganisationTypes(db.Model): + __tablename__ = 'organisation_types' + + name = db.Column(db.String(255), primary_key=True) + is_crown = db.Column(db.Boolean, nullable=True) + annual_free_sms_fragment_limit = db.Column(db.BigInteger, nullable=False) + + class Organisation(db.Model): __tablename__ = "organisation" id = db.Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, unique=False) @@ -444,7 +457,7 @@ class Service(db.Model, Versioned): db.String(255), nullable=True, ) - crown = db.Column(db.Boolean, index=False, nullable=False, default=True) + crown = db.Column(db.Boolean, index=False, nullable=True) rate_limit = db.Column(db.Integer, index=False, nullable=False, default=3000) contact_link = db.Column(db.String(255), nullable=True, unique=False) volume_sms = db.Column(db.Integer(), nullable=True, unique=False) diff --git a/app/service/rest.py b/app/service/rest.py index e3f627cb6..997f0d7a6 100644 --- a/app/service/rest.py +++ b/app/service/rest.py @@ -86,7 +86,8 @@ from app.errors import ( ) from app.letters.utils import letter_print_day from app.models import ( - KEY_TYPE_NORMAL, LETTER_TYPE, NOTIFICATION_CANCELLED, Permission, Service, EmailBranding, LetterBranding + KEY_TYPE_NORMAL, LETTER_TYPE, NON_CROWN_ORGANISATION_TYPES, NOTIFICATION_CANCELLED, Permission, Service, + EmailBranding, LetterBranding ) from app.notifications.process_notifications import persist_notification, send_notification_to_queue from app.schema_validation import validate @@ -224,8 +225,8 @@ def update_service(service_id): service = service_schema.load(current_data).data org_type = req_json.get('organisation_type', None) - if org_type: - service.crown = org_type == 'central' + if org_type and service.organisation_type in (NON_CROWN_ORGANISATION_TYPES + ["nhs"]): + service.crown = False if 'email_branding' in req_json: email_branding_id = req_json['email_branding'] diff --git a/migrations/versions/0299_org_types_table_.py b/migrations/versions/0299_org_types_table_.py new file mode 100644 index 000000000..c9c3dca92 --- /dev/null +++ b/migrations/versions/0299_org_types_table_.py @@ -0,0 +1,47 @@ +""" + +Revision ID: 0299_org_types_table +Revises: 0298_add_mou_signed_receipt +Create Date: 2019-07-10 16:07:22.019759 + +""" +from alembic import op +import sqlalchemy as sa + + +revision = '0299_org_types_table' +down_revision = '0298_add_mou_signed_receipt' + + +def upgrade(): + organisation_types_table = op.create_table( + 'organisation_types', + sa.Column('name', sa.String(), nullable=False), + sa.PrimaryKeyConstraint('name'), + sa.Column('is_crown', sa.Boolean, nullable=True), + sa.Column('annual_free_sms_fragment_limit', sa.BigInteger, nullable=False) + + ) + + op.bulk_insert( + organisation_types_table, + [ + {'name': x, 'is_crown': y, 'annual_free_sms_fragment_limit': z} for x, y, z in [ + ["central", None, 250000], + ["local", False, 25000], + ["nhs_central", False, 250000], + ["nhs_local", False, 25000], + ["emergency_services", False, 25000], + ["school_or_college", False, 25000], + ["other", None, 25000], + ] + ] + ) + op.alter_column('services', 'crown', nullable=True) + op.alter_column('services_history', 'crown', nullable=True) + + +def downgrade(): + op.execute('DROP TABLE organisation_types') + op.alter_column('services', 'crown', nullable=False) + op.alter_column('services_history', 'crown', nullable=False) diff --git a/tests/app/conftest.py b/tests/app/conftest.py index 2ed53996b..367b577ee 100644 --- a/tests/app/conftest.py +++ b/tests/app/conftest.py @@ -176,7 +176,8 @@ def sample_service( 'message_limit': limit, 'restricted': restricted, 'email_from': email_from, - 'created_by': user + 'created_by': user, + 'crown': True } service = Service.query.filter_by(name=service_name).first() if not service: diff --git a/tests/app/dao/test_services_dao.py b/tests/app/dao/test_services_dao.py index 4b9b6b774..f69a60f3a 100644 --- a/tests/app/dao/test_services_dao.py +++ b/tests/app/dao/test_services_dao.py @@ -105,7 +105,7 @@ def test_create_service(notify_db_session): assert service.active is True assert user in service_db.users assert service_db.organisation_type == 'central' - assert service_db.crown is True + assert service_db.crown is None assert not service.letter_branding diff --git a/tests/app/db.py b/tests/app/db.py index 38fa3ed92..9a6250769 100644 --- a/tests/app/db.py +++ b/tests/app/db.py @@ -107,7 +107,8 @@ def create_service( organisation_type='central', check_if_service_exists=False, go_live_user=None, - go_live_at=None + go_live_at=None, + crown=True ): if check_if_service_exists: service = Service.query.filter_by(name=service_name).first() @@ -121,7 +122,8 @@ def create_service( prefix_sms=prefix_sms, organisation_type=organisation_type, go_live_user=go_live_user, - go_live_at=go_live_at + go_live_at=go_live_at, + crown=crown ) dao_create_service(service, service.created_by, service_id, service_permissions=service_permissions) diff --git a/tests/app/service/test_rest.py b/tests/app/service/test_rest.py index 0ba6c15a8..f5a40ea68 100644 --- a/tests/app/service/test_rest.py +++ b/tests/app/service/test_rest.py @@ -697,10 +697,15 @@ def test_update_service_flags(client, sample_service): @pytest.mark.parametrize("org_type, expected", - [("central", True), - ('local', False), - ("nhs", False)]) -def test_update_service_sets_crown(client, sample_service, org_type, expected): + [("central", None), + ("local", False), + ("nhs_central", False), + ("nhs_local", False), + ("emergency_services", False), + ("school_or_college", False), + ("other", None)]) +def test_update_service_sets_crown_based_on_org_type(client, sample_service, org_type, expected): + sample_service.crown = None data = { 'organisation_type': org_type, }