diff --git a/order-events/app/events/billing/append_enrollment.py b/order-events/app/events/billing/append_enrollment.py index a355cd1..9b8b061 100644 --- a/order-events/app/events/billing/append_enrollment.py +++ b/order-events/app/events/billing/append_enrollment.py @@ -46,21 +46,22 @@ def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool: data = enrollment_layer.collection.get_items( TransactKey(enrollment_id) + SortKey('0') + SortKey('author') ) - created_at: datetime = fromisoformat(data['create_date']) # type: ignore if not data: logger.debug('Enrollment not found') return False + logger.info('Enrollment found', data=data) + # Keep it until the migration has been completed old_course = _get_course(data['course']['id']) if old_course: data['course'] = old_course + created_at: datetime = fromisoformat(data['create_date']) # type: ignore start_date, end_date = get_billing_period( - new_image['billing_day'], - year=created_at.year, - month=created_at.month, + billing_day=new_image['billing_day'], + date_=created_at, ) pk = 'BILLING#ORG#{org_id}'.format(org_id=org_id) sk = 'START#{start}#END#{end}'.format( diff --git a/order-events/app/utils.py b/order-events/app/utils.py index de2bb8d..466e7fd 100644 --- a/order-events/app/utils.py +++ b/order-events/app/utils.py @@ -1,35 +1,39 @@ import calendar -from datetime import date - -from layercake.dateutils import now +from datetime import date, timedelta def get_billing_period( billing_day: int, - year: int | None = None, - month: int | None = None, + date_: date, ) -> tuple[date, date]: - today = now() - year_ = year or today.year - month_ = month or today.month + # Determine the anchor month and year + if date_.day >= billing_day: + anchor_month = date_.month + anchor_year = date_.year + else: + # Move to previous month + if date_.month == 1: + anchor_month = 12 + anchor_year = date_.year - 1 + else: + anchor_month = date_.month - 1 + anchor_year = date_.year - _, last_day = calendar.monthrange(year_, month_) - start_day = min(billing_day, last_day) - start_date = date(year_, month_, start_day) + # Calculate start date + _, last_day = calendar.monthrange(anchor_year, anchor_month) + start_date = date(anchor_year, anchor_month, min(billing_day, last_day)) - if month_ == 12: + # Calculate next month and year + if anchor_month == 12: next_month = 1 - next_year = year_ + 1 + next_year = anchor_year + 1 else: - next_month = month_ + 1 - next_year = year_ + next_month = anchor_month + 1 + next_year = anchor_year - _, last_day_next_month = calendar.monthrange(next_year, next_month) - end_day = min(billing_day, last_day_next_month) - 1 - - if end_day == 0: - end_date = date(year_, month_, last_day) - else: - end_date = date(next_year, next_month, end_day) + # Calculate end date + _, next_last_day = calendar.monthrange(next_year, next_month) + end_day = min(billing_day, next_last_day) + end_date = date(next_year, next_month, end_day) - timedelta(days=1) return start_date, end_date diff --git a/order-events/tests/events/billing/test_append_enrollment.py b/order-events/tests/events/billing/test_append_enrollment.py index eeffddc..90545d5 100644 --- a/order-events/tests/events/billing/test_append_enrollment.py +++ b/order-events/tests/events/billing/test_append_enrollment.py @@ -24,13 +24,13 @@ def test_append_enrollment( assert app.lambda_handler(event, lambda_context) # type: ignore r = dynamodb_persistence_layer.collection.query( - KeyPair('BILLING#ORG#cJtK9SsnJhKPyxESe7g3DG', 'START#2025-06-06#END#2025-07-05') + KeyPair('BILLING#ORG#cJtK9SsnJhKPyxESe7g3DG', 'START#2025-05-06#END#2025-06-05') ) items = r['items'] - assert items[0]['sk'] == 'START#2025-06-06#END#2025-07-05#SCHEDULE#AUTO_CLOSE' + assert items[0]['sk'] == 'START#2025-05-06#END#2025-06-05#SCHEDULE#AUTO_CLOSE' assert ( items[1]['sk'] - == 'START#2025-06-06#END#2025-07-05#ENROLLMENT#945e8672-1d72-45c6-b76c-ac06aa8b52ab' + == 'START#2025-05-06#END#2025-06-05#ENROLLMENT#945e8672-1d72-45c6-b76c-ac06aa8b52ab' ) - assert items[2]['sk'] == 'START#2025-06-06#END#2025-07-05' + assert items[2]['sk'] == 'START#2025-05-06#END#2025-06-05' diff --git a/order-events/tests/test_utils.py b/order-events/tests/test_utils.py index 6d4c416..aacd44c 100644 --- a/order-events/tests/test_utils.py +++ b/order-events/tests/test_utils.py @@ -4,28 +4,61 @@ from utils import get_billing_period def test_get_billing_period(): - assert get_billing_period(billing_day=29, year=2025, month=2) == ( - date(2025, 2, 28), - date(2025, 3, 28), - ) + assert get_billing_period( + billing_day=15, + date_=date(2023, 3, 20), + ) == (date(2023, 3, 15), date(2023, 4, 14)) - assert get_billing_period(billing_day=31, year=2025, month=2) == ( - date(2025, 2, 28), - date(2025, 3, 30), + assert get_billing_period( + billing_day=15, + date_=date(2023, 3, 10), + ) == (date(2023, 2, 15), date(2023, 3, 14)) + + # Leap year + assert get_billing_period( + billing_day=30, + date_=date(year=2028, month=2, day=1), + ) == ( + date(2028, 1, 30), + date(2028, 2, 28), ) # Leap year - assert get_billing_period(billing_day=29, year=2028, month=2) == ( + assert get_billing_period( + billing_day=29, + date_=date(year=2028, month=3, day=1), + ) == ( date(2028, 2, 29), date(2028, 3, 28), ) - assert get_billing_period(billing_day=28, year=2025, month=2) == ( + assert get_billing_period( + billing_day=28, + date_=date(year=2025, month=2, day=28), + ) == ( date(2025, 2, 28), date(2025, 3, 27), ) - assert get_billing_period(billing_day=5, year=2025, month=12) == ( - date(2025, 12, 5), - date(2026, 1, 4), + assert get_billing_period( + billing_day=5, + date_=date(year=2025, month=12, day=1), + ) == ( + date(2025, 11, 5), + date(2025, 12, 4), + ) + + assert get_billing_period(billing_day=25, date_=date(2025, 12, 14)) == ( + date(2025, 11, 25), + date(2025, 12, 24), + ) + + assert get_billing_period(billing_day=25, date_=date(2025, 1, 14)) == ( + date(2024, 12, 25), + date(2025, 1, 24), + ) + + assert get_billing_period(10, date(2024, 1, 5)) == ( + date(2023, 12, 10), + date(2024, 1, 9), )