mirror of
https://github.com/GSA/notifications-api.git
synced 2026-08-26 09:13:40 -04:00
Merge branch 'master' into add-update-multiple-sms-sender
This commit is contained in:
@@ -392,7 +392,7 @@ def check_job_status():
|
|||||||
jobs_not_complete_after_30_minutes = Job.query.filter(
|
jobs_not_complete_after_30_minutes = Job.query.filter(
|
||||||
Job.job_status == JOB_STATUS_IN_PROGRESS,
|
Job.job_status == JOB_STATUS_IN_PROGRESS,
|
||||||
and_(thirty_five_minutes_ago < Job.processing_started, Job.processing_started < thirty_minutes_ago)
|
and_(thirty_five_minutes_ago < Job.processing_started, Job.processing_started < thirty_minutes_ago)
|
||||||
).all()
|
).order_by(Job.processing_started).all()
|
||||||
|
|
||||||
job_ids = [str(x.id) for x in jobs_not_complete_after_30_minutes]
|
job_ids = [str(x.id) for x in jobs_not_complete_after_30_minutes]
|
||||||
if job_ids:
|
if job_ids:
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ def send_sms(self,
|
|||||||
notification_type=SMS_TYPE,
|
notification_type=SMS_TYPE,
|
||||||
api_key_id=api_key_id,
|
api_key_id=api_key_id,
|
||||||
key_type=key_type,
|
key_type=key_type,
|
||||||
created_at=created_at,
|
created_at=datetime.utcnow(),
|
||||||
job_id=notification.get('job', None),
|
job_id=notification.get('job', None),
|
||||||
job_row_number=notification.get('row_number', None),
|
job_row_number=notification.get('row_number', None),
|
||||||
notification_id=notification_id
|
notification_id=notification_id
|
||||||
@@ -254,7 +254,7 @@ def send_email(self,
|
|||||||
notification_type=EMAIL_TYPE,
|
notification_type=EMAIL_TYPE,
|
||||||
api_key_id=api_key_id,
|
api_key_id=api_key_id,
|
||||||
key_type=key_type,
|
key_type=key_type,
|
||||||
created_at=created_at,
|
created_at=datetime.utcnow(),
|
||||||
job_id=notification.get('job', None),
|
job_id=notification.get('job', None),
|
||||||
job_row_number=notification.get('row_number', None),
|
job_row_number=notification.get('row_number', None),
|
||||||
notification_id=notification_id
|
notification_id=notification_id
|
||||||
@@ -295,7 +295,7 @@ def persist_letter(
|
|||||||
notification_type=LETTER_TYPE,
|
notification_type=LETTER_TYPE,
|
||||||
api_key_id=None,
|
api_key_id=None,
|
||||||
key_type=KEY_TYPE_NORMAL,
|
key_type=KEY_TYPE_NORMAL,
|
||||||
created_at=created_at,
|
created_at=datetime.utcnow(),
|
||||||
job_id=notification['job'],
|
job_id=notification['job'],
|
||||||
job_row_number=notification['row_number'],
|
job_row_number=notification['row_number'],
|
||||||
notification_id=notification_id,
|
notification_id=notification_id,
|
||||||
|
|||||||
@@ -247,7 +247,7 @@ class PopulateServiceEmailReplyTo(Command):
|
|||||||
result = db.session.execute(services_to_update)
|
result = db.session.execute(services_to_update)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
print("Populated email reply to adderesses for {}".format(result.rowcount))
|
print("Populated email reply to addresses for {}".format(result.rowcount))
|
||||||
|
|
||||||
|
|
||||||
class PopulateServiceSmsSender(Command):
|
class PopulateServiceSmsSender(Command):
|
||||||
@@ -329,3 +329,25 @@ class PopulateServiceAndServiceHistoryFreeSmsFragmentLimit(Command):
|
|||||||
|
|
||||||
print("Populated free sms fragment limits for {} services".format(services_result.rowcount))
|
print("Populated free sms fragment limits for {} services".format(services_result.rowcount))
|
||||||
print("Populated free sms fragment limits for {} services history".format(services_history_result.rowcount))
|
print("Populated free sms fragment limits for {} services history".format(services_history_result.rowcount))
|
||||||
|
|
||||||
|
|
||||||
|
class PopulateAnnualBilling(Command):
|
||||||
|
def run(self):
|
||||||
|
financial_year = [2016, 2017, 2018]
|
||||||
|
|
||||||
|
for fy in financial_year:
|
||||||
|
populate_data = """
|
||||||
|
INSERT INTO annual_billing(id, service_id, free_sms_fragment_limit, financial_year_start,
|
||||||
|
created_at, updated_at)
|
||||||
|
SELECT uuid_in(md5(random()::text || now()::text)::cstring), id, 250000, {}, '{}', '{}'
|
||||||
|
FROM services
|
||||||
|
WHERE id NOT IN(
|
||||||
|
SELECT service_id
|
||||||
|
FROM annual_billing
|
||||||
|
WHERE financial_year_start={})
|
||||||
|
""".format(fy, datetime.utcnow(), datetime.utcnow(), fy)
|
||||||
|
|
||||||
|
services_result1 = db.session.execute(populate_data)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
print("Populated annual billing {} for {} services".format(fy, services_result1.rowcount))
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ def get_financial_year(year):
|
|||||||
def get_april_fools(year):
|
def get_april_fools(year):
|
||||||
"""
|
"""
|
||||||
This function converts the start of the financial year April 1, 00:00 as BST (British Standard Time) to UTC,
|
This function converts the start of the financial year April 1, 00:00 as BST (British Standard Time) to UTC,
|
||||||
the tzinfo is lastly removed from the datetime becasue the database stores the timestamps without timezone.
|
the tzinfo is lastly removed from the datetime because the database stores the timestamps without timezone.
|
||||||
:param year: the year to calculate the April 1, 00:00 BST for
|
:param year: the year to calculate the April 1, 00:00 BST for
|
||||||
:return: the datetime of April 1 for the given year, for example 2016 = 2016-03-31 23:00:00
|
:return: the datetime of April 1 for the given year, for example 2016 = 2016-03-31 23:00:00
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -179,6 +179,27 @@ class ServicePermissionTypes(db.Model):
|
|||||||
name = db.Column(db.String(255), primary_key=True)
|
name = db.Column(db.String(255), primary_key=True)
|
||||||
|
|
||||||
|
|
||||||
|
class AnnualBilling(db.Model):
|
||||||
|
__tablename__ = "annual_billing"
|
||||||
|
id = db.Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, unique=False)
|
||||||
|
service_id = db.Column(UUID(as_uuid=True), db.ForeignKey('services.id'), unique=False, index=True, nullable=False)
|
||||||
|
financial_year_start = db.Column(db.Integer, nullable=False, default=True, unique=False)
|
||||||
|
free_sms_fragment_limit = db.Column(db.Integer, nullable=False, index=False, unique=False)
|
||||||
|
updated_at = db.Column(db.DateTime, nullable=True, onupdate=datetime.datetime.utcnow)
|
||||||
|
created_at = db.Column(db.DateTime, nullable=False, default=datetime.datetime.utcnow)
|
||||||
|
UniqueConstraint('financial_year_start', 'service_id', name='ix_annual_billing_service_id')
|
||||||
|
|
||||||
|
def serialize(self):
|
||||||
|
return {
|
||||||
|
'id': str(self.id),
|
||||||
|
'service_id': str(self.service_id),
|
||||||
|
'free_sms_fragment_limit': str(self.free_sms_fragment_limit),
|
||||||
|
'financial_year_start': str(self.financial_year_start),
|
||||||
|
'created_at': self.created_at.strftime(DATETIME_FORMAT),
|
||||||
|
'updated_at': self.updated_at.strftime(DATETIME_FORMAT) if self.updated_at else None
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class Service(db.Model, Versioned):
|
class Service(db.Model, Versioned):
|
||||||
__tablename__ = 'services'
|
__tablename__ = 'services'
|
||||||
|
|
||||||
@@ -213,6 +234,7 @@ class Service(db.Model, Versioned):
|
|||||||
organisation_id = db.Column(UUID(as_uuid=True), db.ForeignKey('organisation.id'), index=True, nullable=True)
|
organisation_id = db.Column(UUID(as_uuid=True), db.ForeignKey('organisation.id'), index=True, nullable=True)
|
||||||
free_sms_fragment_limit = db.Column(db.BigInteger, index=False, unique=False, nullable=True)
|
free_sms_fragment_limit = db.Column(db.BigInteger, index=False, unique=False, nullable=True)
|
||||||
organisation = db.relationship('Organisation')
|
organisation = db.relationship('Organisation')
|
||||||
|
annual_billing = db.relationship('AnnualBilling')
|
||||||
dvla_organisation_id = db.Column(
|
dvla_organisation_id = db.Column(
|
||||||
db.String,
|
db.String,
|
||||||
db.ForeignKey('dvla_organisation.id'),
|
db.ForeignKey('dvla_organisation.id'),
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ manager.add_command('populate_service_sms_sender', commands.PopulateServiceSmsSe
|
|||||||
manager.add_command('populate_service_letter_contact', commands.PopulateServiceLetterContact)
|
manager.add_command('populate_service_letter_contact', commands.PopulateServiceLetterContact)
|
||||||
manager.add_command('populate_service_and_service_history_free_sms_fragment_limit',
|
manager.add_command('populate_service_and_service_history_free_sms_fragment_limit',
|
||||||
commands.PopulateServiceAndServiceHistoryFreeSmsFragmentLimit)
|
commands.PopulateServiceAndServiceHistoryFreeSmsFragmentLimit)
|
||||||
|
manager.add_command('populate_annual_billing',
|
||||||
|
commands.PopulateAnnualBilling)
|
||||||
|
|
||||||
|
|
||||||
@manager.command
|
@manager.command
|
||||||
|
|||||||
33
migrations/versions/0126_add_annual_billing.py
Normal file
33
migrations/versions/0126_add_annual_billing.py
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
"""
|
||||||
|
|
||||||
|
Revision ID: 0126_add_annual_billing
|
||||||
|
Revises: 0125_add_organisation_type
|
||||||
|
Create Date: 2017-10-19 11:38:32.849573
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy.dialects import postgresql
|
||||||
|
|
||||||
|
revision = '0126_add_annual_billing'
|
||||||
|
down_revision = '0125_add_organisation_type'
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
op.create_table('annual_billing',
|
||||||
|
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
|
||||||
|
sa.Column('service_id', postgresql.UUID(as_uuid=True), nullable=False),
|
||||||
|
sa.Column('financial_year_start', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('free_sms_fragment_limit', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||||||
|
sa.Column('created_at', sa.DateTime(), nullable=False),
|
||||||
|
sa.ForeignKeyConstraint(['service_id'], ['services.id'], ),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
op.create_index(op.f('ix_annual_billing_service_id'), 'annual_billing', ['service_id'], unique=False)
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
op.drop_index(op.f('ix_annual_billing_service_id'), table_name='annual_billing')
|
||||||
|
op.drop_table('annual_billing')
|
||||||
|
|
||||||
@@ -831,6 +831,6 @@ def test_check_job_status_task_raises_job_incomplete_error_for_multiple_jobs(moc
|
|||||||
|
|
||||||
mock_celery.assert_called_once_with(
|
mock_celery.assert_called_once_with(
|
||||||
name=TaskNames.PROCESS_INCOMPLETE_JOBS,
|
name=TaskNames.PROCESS_INCOMPLETE_JOBS,
|
||||||
args=([str(job_2.id), str(job.id)],),
|
args=([str(job.id), str(job_2.id)],),
|
||||||
queue=QueueNames.JOBS
|
queue=QueueNames.JOBS
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -700,7 +700,7 @@ def test_should_send_sms_template_to_and_persist_with_job_id(sample_job, sample_
|
|||||||
assert persisted_notification.template_id == sample_job.template.id
|
assert persisted_notification.template_id == sample_job.template.id
|
||||||
assert persisted_notification.status == 'created'
|
assert persisted_notification.status == 'created'
|
||||||
assert not persisted_notification.sent_at
|
assert not persisted_notification.sent_at
|
||||||
assert persisted_notification.created_at <= now
|
assert persisted_notification.created_at >= now
|
||||||
assert not persisted_notification.sent_by
|
assert not persisted_notification.sent_by
|
||||||
assert persisted_notification.job_row_number == 2
|
assert persisted_notification.job_row_number == 2
|
||||||
assert persisted_notification.api_key_id == sample_api_key.id
|
assert persisted_notification.api_key_id == sample_api_key.id
|
||||||
@@ -794,7 +794,7 @@ def test_should_use_email_template_and_persist(sample_email_template_with_placeh
|
|||||||
assert persisted_notification.to == 'my_email@my_email.com'
|
assert persisted_notification.to == 'my_email@my_email.com'
|
||||||
assert persisted_notification.template_id == sample_email_template_with_placeholders.id
|
assert persisted_notification.template_id == sample_email_template_with_placeholders.id
|
||||||
assert persisted_notification.template_version == sample_email_template_with_placeholders.version
|
assert persisted_notification.template_version == sample_email_template_with_placeholders.version
|
||||||
assert persisted_notification.created_at == now
|
assert persisted_notification.created_at >= now
|
||||||
assert not persisted_notification.sent_at
|
assert not persisted_notification.sent_at
|
||||||
assert persisted_notification.status == 'created'
|
assert persisted_notification.status == 'created'
|
||||||
assert not persisted_notification.sent_by
|
assert not persisted_notification.sent_by
|
||||||
@@ -831,7 +831,7 @@ def test_send_email_should_use_template_version_from_job_not_latest(sample_email
|
|||||||
assert persisted_notification.to == 'my_email@my_email.com'
|
assert persisted_notification.to == 'my_email@my_email.com'
|
||||||
assert persisted_notification.template_id == sample_email_template.id
|
assert persisted_notification.template_id == sample_email_template.id
|
||||||
assert persisted_notification.template_version == version_on_notification
|
assert persisted_notification.template_version == version_on_notification
|
||||||
assert persisted_notification.created_at == now
|
assert persisted_notification.created_at >= now
|
||||||
assert not persisted_notification.sent_at
|
assert not persisted_notification.sent_at
|
||||||
assert persisted_notification.status == 'created'
|
assert persisted_notification.status == 'created'
|
||||||
assert not persisted_notification.sent_by
|
assert not persisted_notification.sent_by
|
||||||
@@ -857,7 +857,7 @@ def test_should_use_email_template_subject_placeholders(sample_email_template_wi
|
|||||||
assert persisted_notification.to == 'my_email@my_email.com'
|
assert persisted_notification.to == 'my_email@my_email.com'
|
||||||
assert persisted_notification.template_id == sample_email_template_with_placeholders.id
|
assert persisted_notification.template_id == sample_email_template_with_placeholders.id
|
||||||
assert persisted_notification.status == 'created'
|
assert persisted_notification.status == 'created'
|
||||||
assert persisted_notification.created_at == now
|
assert persisted_notification.created_at >= now
|
||||||
assert not persisted_notification.sent_by
|
assert not persisted_notification.sent_by
|
||||||
assert persisted_notification.personalisation == {"name": "Jo"}
|
assert persisted_notification.personalisation == {"name": "Jo"}
|
||||||
assert not persisted_notification.reference
|
assert not persisted_notification.reference
|
||||||
@@ -883,7 +883,7 @@ def test_should_use_email_template_and_persist_without_personalisation(sample_em
|
|||||||
persisted_notification = Notification.query.one()
|
persisted_notification = Notification.query.one()
|
||||||
assert persisted_notification.to == 'my_email@my_email.com'
|
assert persisted_notification.to == 'my_email@my_email.com'
|
||||||
assert persisted_notification.template_id == sample_email_template.id
|
assert persisted_notification.template_id == sample_email_template.id
|
||||||
assert persisted_notification.created_at == now
|
assert persisted_notification.created_at >= now
|
||||||
assert not persisted_notification.sent_at
|
assert not persisted_notification.sent_at
|
||||||
assert persisted_notification.status == 'created'
|
assert persisted_notification.status == 'created'
|
||||||
assert not persisted_notification.sent_by
|
assert not persisted_notification.sent_by
|
||||||
@@ -1019,7 +1019,7 @@ def test_persist_letter_saves_letter_to_database(sample_letter_job, mocker):
|
|||||||
assert notification_db.template_id == sample_letter_job.template.id
|
assert notification_db.template_id == sample_letter_job.template.id
|
||||||
assert notification_db.template_version == sample_letter_job.template.version
|
assert notification_db.template_version == sample_letter_job.template.version
|
||||||
assert notification_db.status == 'created'
|
assert notification_db.status == 'created'
|
||||||
assert notification_db.created_at == created_at
|
assert notification_db.created_at >= created_at
|
||||||
assert notification_db.notification_type == 'letter'
|
assert notification_db.notification_type == 'letter'
|
||||||
assert notification_db.sent_at is None
|
assert notification_db.sent_at is None
|
||||||
assert notification_db.sent_by is None
|
assert notification_db.sent_by is None
|
||||||
|
|||||||
Reference in New Issue
Block a user