From ae80241d1a21001b04da08bd6ff1e94fd244852a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomi=20J=C3=A4rvi?= Date: Mon, 8 Mar 2021 09:30:43 +0000 Subject: [PATCH] Fix group items by date range function The problem is that `sorted` function can't compare None-value, but ex. RentAdjustment model's date fields can be nullable. By default now, the function converts None date values to min and max values and can be now sorted correctly. --- leasing/models/utils.py | 18 +++++++--- leasing/tests/models/test_utils.py | 54 ++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 5 deletions(-) diff --git a/leasing/models/utils.py b/leasing/models/utils.py index 1984c2de..d9f63a8a 100644 --- a/leasing/models/utils.py +++ b/leasing/models/utils.py @@ -293,14 +293,22 @@ def split_date_range(date_range, count): return result -def _get_date_range_from_item(item): +def _get_date_range_from_item(item, fill_min_max_values=True): if isinstance(item, dict): - return item["date_range"] + start_date, end_date = item["date_range"] else: if callable(item.date_range): - return item.date_range() + start_date, end_date = item.date_range() else: - return item.date_range + start_date, end_date = item.date_range + + if fill_min_max_values: + if start_date is None: + start_date = datetime.date.min + if end_date is None: + end_date = datetime.date.max + + return start_date, end_date def group_items_in_period_by_date_range(items, min_date, max_date): @@ -325,7 +333,7 @@ def group_items_in_period_by_date_range(items, min_date, max_date): while current_date < max_date: current_items = [] for item in sorted_items: - item_range = _get_date_range_from_item(item) + item_range = _get_date_range_from_item(item, fill_min_max_values=False) if (item_range[0] is None or item_range[0] <= current_date) and ( item_range[1] is None or current_date <= item_range[1] ): diff --git a/leasing/tests/models/test_utils.py b/leasing/tests/models/test_utils.py index 32aace03..0b084a07 100644 --- a/leasing/tests/models/test_utils.py +++ b/leasing/tests/models/test_utils.py @@ -3,6 +3,13 @@ import pytest +from leasing.enums import ( + DueDatesType, + RentAdjustmentAmountType, + RentAdjustmentType, + RentCycle, + RentType, +) from leasing.models.utils import ( combine_ranges, fix_amount_for_overlap, @@ -725,6 +732,53 @@ def test_group_items_in_period_by_date_range(items, expected): ) +@pytest.mark.django_db +def test_group_items_in_period_with_nullable_date_model_fields( + lease_test_data, rent_factory, decision_factory, rent_adjustment_factory +): + + lease = lease_test_data["lease"] + + rent = rent_factory( + lease=lease, + type=RentType.FIXED, + cycle=RentCycle.JANUARY_TO_DECEMBER, + due_dates_type=DueDatesType.FIXED, + due_dates_per_year=1, + ) + + decision = decision_factory(lease=lease) + + rent_adjustment = rent_adjustment_factory( + rent=rent, + type=RentAdjustmentType.DISCOUNT, + decision=decision, + intended_use_id=1, + start_date=None, + end_date=date(2021, 1, 1), + full_amount=12345, + amount_type=RentAdjustmentAmountType.AMOUNT_TOTAL, + ) + + rent_adjustment_2 = rent_adjustment_factory( + rent=rent, + type=RentAdjustmentType.DISCOUNT, + decision=decision, + intended_use_id=1, + start_date=date(2021, 1, 1), + end_date=None, + full_amount=12345, + amount_type=RentAdjustmentAmountType.AMOUNT_TOTAL, + ) + + try: + group_items_in_period_by_date_range( + [rent_adjustment, rent_adjustment_2], date(2015, 9, 1), date(2015, 10, 31) + ) + except Exception as exc: + assert False, f"Function raised an exception {exc}" + + @pytest.mark.parametrize( "identifier, expected", [