From f6d788ae775753192ab07471594c926eacdaee3d Mon Sep 17 00:00:00 2001 From: tamirmatok Date: Mon, 2 May 2022 16:41:32 +0300 Subject: [PATCH] Add "capacity dates check" for dog owner search. Capacity dates check for show only available daycares in dates range. "get_capacity_of_daycare_in_dates_range" function took from #95 . waiting for approval. Signed-off-by: tamirmatok --- orders/models.py | 37 +++++++++++++++++++++++++++++++++++++ orders/tests.py | 14 ++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/orders/models.py b/orders/models.py index 105e1f3..9c7ccb4 100644 --- a/orders/models.py +++ b/orders/models.py @@ -1,7 +1,9 @@ from django.db import models +from django.db.models import QuerySet from django.utils import timezone from daycare.models import DayCare from dogowner.models import DogOwner +import datetime class StatusOptions(models.TextChoices): @@ -71,3 +73,38 @@ def cancel_order(self): def get_order_total_price(self): return self.price_per_day * (self.end_date - self.start_date).days + + @staticmethod + def get_capacity_of_daycare_in_dates_range(daycare_id, start_date, end_date): + relevant_orders = Order.objects.filter(daycare_id=daycare_id, status__in=['A', 'O']) + start_date = datetime.date(year=start_date.year, month=start_date.month, day=start_date.day) + end_date = datetime.date(year=end_date.year, month=end_date.month, day=end_date.day) + capacity_per_day_list = [0] * ((end_date - start_date).days + 2) + + for order in relevant_orders: + if end_date < order.start_date or order.end_date < start_date: + continue + + number_of_days = (order.end_date - order.start_date).days + + for day in range(number_of_days): + current_date = order.start_date + datetime.timedelta(days=day) + if current_date < start_date: + continue + elif current_date > end_date: + break + else: + capacity_per_day_list[day] = capacity_per_day_list[day] + 1 + + return capacity_per_day_list + + @staticmethod + def get_all_day_cares_available_on_dates(start_date: str, end_date: str) -> QuerySet: + start_date = datetime.date.fromisoformat(start_date) + end_date = datetime.date.fromisoformat(end_date) + id_list = [] + for day_care in DayCare.objects.all(): + capacity_per_day_list = Order.get_capacity_of_daycare_in_dates_range(day_care.id, start_date, end_date) + if all(current_capacity < day_care.capacity for current_capacity in capacity_per_day_list): + id_list.append(day_care.id) + return DayCare.objects.filter(id__in=id_list) diff --git a/orders/tests.py b/orders/tests.py index e9259ab..ee0bbe4 100644 --- a/orders/tests.py +++ b/orders/tests.py @@ -52,3 +52,17 @@ def test_dog_owner_id_is_deleted_when_dog_owner_is_deleted(self, create_order): def test_daycare_id_is_deleted_when_daycare_is_deleted(self, create_order): DayCare.objects.get(id=1).delete() assert Order.objects.get(id=create_order.id).daycare_id is None + + @pytest.mark.parametrize('start_date, end_date', + [ + ("2022-05-02", "2022-08-02"), + ]) + def test_get_all_day_cares_available_on_dates_after_reducing_capacity_to_0(self, create_daycare_user, + start_date, end_date): + day_care_user = create_daycare_user + assert day_care_user in Order.get_all_day_cares_available_on_dates(start_date, end_date) + + for _ in range(day_care_user.capacity): + Order.create(dog_owner_id=DogOwner.objects.get(id=1), daycare_id=day_care_user, + start_date=start_date, end_date=end_date, price_per_day=500).approve_order() + assert day_care_user not in Order.get_all_day_cares_available_on_dates(start_date, end_date)