-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added the code to insert quarter data per service (#2345)
- Loading branch information
Showing
9 changed files
with
300 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
from datetime import datetime | ||
|
||
from sqlalchemy.dialects.postgresql import insert | ||
|
||
from app import db | ||
from app.models import AnnualLimitsData | ||
|
||
|
||
def get_previous_quarter(date_to_check): | ||
year = date_to_check.year | ||
month = date_to_check.month | ||
|
||
quarter = "" | ||
start_date = None | ||
end_date = None | ||
if month in [1, 2, 3]: | ||
quarter = "Q3" | ||
year -= 1 | ||
start_date = datetime(year, 10, 1) | ||
end_date = datetime(year, 12, 31, 23, 59, 59) | ||
elif month in [4, 5, 6]: | ||
quarter = "Q4" | ||
start_date = datetime(year, 1, 1) | ||
end_date = datetime(year, 3, 31, 23, 59, 59) | ||
year -= 1 # Cause we want to store it as Q4 of the previous year | ||
elif month in [7, 8, 9]: | ||
quarter = "Q1" | ||
start_date = datetime(year, 4, 1) | ||
end_date = datetime(year, 6, 30, 23, 59, 59) | ||
elif month in [10, 11, 12]: | ||
quarter = "Q2" | ||
start_date = datetime(year, 7, 1) | ||
end_date = datetime(year, 9, 30, 23, 59, 59) | ||
|
||
quarter_name = f"{quarter}-{year}" if quarter else "" | ||
return quarter_name, (start_date, end_date) | ||
|
||
|
||
def insert_quarter_data(data, quarter, service_info): | ||
""" | ||
Insert data for each quarter into the database. | ||
Each row in transit_data is a namedtuple with the following fields: | ||
- service_id, | ||
- notification_type, | ||
- notification_count | ||
""" | ||
|
||
table = AnnualLimitsData.__table__ | ||
|
||
for row in data: | ||
stmt = ( | ||
insert(table) | ||
.values( | ||
service_id=row.service_id, | ||
time_period=quarter, | ||
annual_email_limit=service_info[row.service_id][0], | ||
annual_sms_limit=service_info[row.service_id][1], | ||
notification_type=row.notification_type, | ||
notification_count=row.notification_count, | ||
) | ||
.on_conflict_do_update( | ||
index_elements=["service_id", "time_period", "notification_type"], | ||
set_={ | ||
"annual_email_limit": insert(table).excluded.annual_email_limit, | ||
"annual_sms_limit": insert(table).excluded.annual_sms_limit, | ||
"notification_count": insert(table).excluded.notification_count, | ||
}, | ||
) | ||
) | ||
db.session.connection().execute(stmt) | ||
db.session.commit() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
""" | ||
Revision ID: 0465_add_constraints | ||
Revises: 0464_add_annual_limits_data | ||
Create Date: 2024-10-31 13:32:00 | ||
""" | ||
from alembic import op | ||
|
||
revision = "0465_add_constraints" | ||
down_revision = "0464_add_annual_limits_data" | ||
|
||
|
||
def upgrade(): | ||
op.create_index( | ||
"ix_service_id_notification_type_time", "annual_limits_data", ["time_period", "service_id", "notification_type"] | ||
) | ||
op.create_unique_constraint( | ||
"uq_service_id_notification_type_time_period", "annual_limits_data", ["service_id", "notification_type", "time_period"] | ||
) | ||
|
||
|
||
def downgrade(): | ||
op.drop_constraint("uq_service_id_notification_type_time_period", "annual_limits_data") | ||
op.drop_index("ix_service_id_notification_type_time", "annual_limits_data") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
from collections import namedtuple | ||
from datetime import datetime | ||
|
||
import pytest | ||
|
||
from app.dao.annual_limits_data_dao import get_previous_quarter, insert_quarter_data | ||
from app.models import AnnualLimitsData, Service | ||
from tests.app.db import create_service | ||
|
||
|
||
class TestGetPreviousQuarter: | ||
@pytest.mark.parametrize( | ||
"date_to_check, expected", | ||
[ | ||
(datetime(2021, 4, 1), ("Q4-2020", (datetime(2021, 1, 1, 0, 0), datetime(2021, 3, 31, 23, 59, 59)))), | ||
(datetime(2021, 6, 1), ("Q4-2020", (datetime(2021, 1, 1, 0, 0), datetime(2021, 3, 31, 23, 59, 59)))), | ||
(datetime(2021, 9, 1), ("Q1-2021", (datetime(2021, 4, 1, 0, 0), datetime(2021, 6, 30, 23, 59, 59)))), | ||
(datetime(2021, 12, 1), ("Q2-2021", (datetime(2021, 7, 1, 0, 0), datetime(2021, 9, 30, 23, 59, 59)))), | ||
(datetime(2022, 1, 1), ("Q3-2021", (datetime(2021, 10, 1, 0, 0), datetime(2021, 12, 31, 23, 59, 59)))), | ||
(datetime(2022, 3, 31), ("Q3-2021", (datetime(2021, 10, 1, 0, 0), datetime(2021, 12, 31, 23, 59, 59)))), | ||
(datetime(2023, 5, 5), ("Q4-2022", (datetime(2023, 1, 1, 0, 0), datetime(2023, 3, 31, 23, 59, 59)))), | ||
], | ||
) | ||
def test_get_previous_quarter(self, date_to_check, expected): | ||
assert get_previous_quarter(date_to_check) == expected | ||
|
||
|
||
class TestInsertQuarterData: | ||
def test_insert_quarter_data(self, notify_db_session): | ||
service_1 = create_service(service_name="service_1") | ||
service_2 = create_service(service_name="service_2") | ||
|
||
service_info = {x.id: (x.email_annual_limit, x.sms_annual_limit) for x in Service.query.all()} | ||
NotificationData = namedtuple("NotificationData", ["service_id", "notification_type", "notification_count"]) | ||
|
||
data = [ | ||
NotificationData(service_1.id, "sms", 4), | ||
NotificationData(service_2.id, "sms", 1100), | ||
NotificationData(service_1.id, "email", 2), | ||
] | ||
insert_quarter_data(data, "Q1-2018", service_info) | ||
|
||
assert AnnualLimitsData.query.count() == 3 | ||
|
||
# We want to check what happens when the same primary key but a new notification count is introduced | ||
|
||
assert AnnualLimitsData.query.filter_by(service_id=service_2.id).first().notification_count == 1100 | ||
insert_quarter_data( | ||
[ | ||
NotificationData(service_2.id, "sms", 500), | ||
], | ||
"Q1-2018", | ||
service_info, | ||
) | ||
assert AnnualLimitsData.query.filter_by(service_id=service_2.id).first().notification_count == 500 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters