diff --git a/daycare/forms.py b/daycare/forms.py
new file mode 100644
index 0000000..f6e6067
--- /dev/null
+++ b/daycare/forms.py
@@ -0,0 +1,31 @@
+from django import forms
+from .models import DayCare, Area
+from django.db.models import Max, Min
+
+
+class DayCareSearchForm(forms.Form):
+ min_price = DayCare.objects.all().aggregate(Min('price_per_day')).get('price_per_day__min')
+ max_price = DayCare.objects.all().aggregate(Max('price_per_day')).get('price_per_day__max')
+ start_date = forms.DateField(required=True, label=' Start date',
+ widget=forms.widgets.DateInput(attrs={'class': 'form-control', 'type': 'date'}))
+ end_date = forms.DateField(required=True, label=' End date',
+ widget=forms.widgets.DateInput(attrs={'class': 'form-control', 'type': 'date'}))
+
+ area = forms.ChoiceField(required=False, label='Area',
+ choices=(Area.choices + [('', 'All'), ]), initial="")
+ city = forms.CharField(required=False, label='City')
+ name = forms.CharField(required=False, label='Day care name')
+ price_per_day = forms.ChoiceField(required=False, label='Max price',
+ choices=((str(x), x) for x in range(min_price, max_price + 11, 10)),
+ initial=str(max_price))
+
+ def clean(self):
+ cleaned_data = super().clean()
+ start_date = cleaned_data.get("start_date")
+ end_date = cleaned_data.get("end_date")
+
+ if start_date and end_date:
+ if end_date < start_date:
+ self._errors['end_date'] = self.error_class(["End date should be greater!"])
+
+ return cleaned_data
diff --git a/dogowner/templates/dogowner/dog_owner_homepage.html b/dogowner/templates/dogowner/dog_owner_homepage.html
index 8bb9b37..4bd7d2c 100644
--- a/dogowner/templates/dogowner/dog_owner_homepage.html
+++ b/dogowner/templates/dogowner/dog_owner_homepage.html
@@ -54,4 +54,5 @@
{{ daycare.name }}
-{% endblock %}
\ No newline at end of file
+
+{% endblock %}
diff --git a/dogowner/views.py b/dogowner/views.py
index 53333ed..073bad3 100644
--- a/dogowner/views.py
+++ b/dogowner/views.py
@@ -1,11 +1,32 @@
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from daycare.models import DayCare
+from daycare.forms import DayCareSearchForm
+from orders.models import Order
@login_required()
def dog_owner_home(request):
+ form = DayCareSearchForm(request.POST or None)
+ day_care_queryset = DayCare.objects.all()
context = {
- 'daycares': DayCare.objects.all(),
+ 'day_care_queryset': day_care_queryset,
+ 'form': form
}
+ if request.method == 'POST':
+ if form.is_valid():
+ filter_day_cares = DayCare.objects.filter(area__startswith=form['area'].value(),
+ city__icontains=form['city'].value(),
+ name__icontains=form['name'].value(),
+ price_per_day__lte=form['price_per_day'].value())
+
+ available_day_cares = Order.get_all_day_cares_available_on_dates(form['start_date'].value(),
+ form['end_date'].value())
+ day_care_queryset = filter_day_cares.intersection(available_day_cares)
+
+ context = {
+ 'day_care_queryset': day_care_queryset,
+ 'form': form
+ }
+
return render(request, 'dogowner/dog_owner_homepage.html', context)
diff --git a/main/tests.py b/main/tests.py
index c2044a8..0a71ac6 100644
--- a/main/tests.py
+++ b/main/tests.py
@@ -1,6 +1,7 @@
import pytest
-from orders.models import Order
+from dogowner.models import DogOwner
from daycare.models import DayCare
+from orders.models import Order
@pytest.mark.django_db
@@ -18,6 +19,24 @@ def test_enter_login_page(self, client):
response = client.get('/login/')
assert response.status_code == 200
+ def test_valid_login_dog_owner_user_info(self, client, create_dog_owner_user):
+ previous_logged_user = client.get('/').wsgi_request.user
+ form = {'username': 'dogOwnerUser01',
+ 'password': 'password123',
+ }
+
+ response = client.post('/login/', form, follow=True)
+ current_log_user = response.wsgi_request.user
+ assert current_log_user == create_dog_owner_user.user
+ assert previous_logged_user != current_log_user
+
+ def test_invalid_login_dog_owner_user_info(self, client):
+ form = {'username': "daycare@address.com",
+ 'password': "incorrect",
+ }
+ response = client.post('/login/', form, follow=True)
+ assert response.wsgi_request.user.is_anonymous
+
def test_valid_login_daycare_user_info(self, client, create_daycare_user, daycare_data):
previous_logged_user = client.get('/').wsgi_request.user
form = {'username': pytest.DAYCARE_USERNAME,
@@ -73,6 +92,67 @@ def test_unlogged_user_access_to_homepage(self, client):
assert response.status_code == 302
assert response['Location'] == '/login/?next=/homepage/'
+
+@pytest.mark.django_db
+class TestDogOwnerHomePageView:
+ def test_dog_owner_present_all_day_cares_at_entrypoint(self, client, create_dog_owner_user):
+ client.force_login(user=create_dog_owner_user.user)
+ response = client.get("/homepage/")
+ day_care_queryset = response.context['day_care_queryset']
+ assert set(day_care_queryset) == set(DayCare.objects.all())
+
+ def test_search_daycare_present_only_available_daycares_on_specific_dates(self, client, create_dog_owner_user):
+ test_day_care = DayCare.create(username='testuser', email='test@email.com', password='test_password',
+ name='name', description='test description', price_per_day=100,
+ capacity=1, area='CENTER', city='tel aviv', address='address')
+ client.force_login(user=create_dog_owner_user.user)
+ search_form = {'area': "",
+ 'city': "",
+ 'price_per_day': 100,
+ 'name': "",
+ 'start_date': "2022-05-03",
+ 'end_date': "2022-05-08",
+ }
+ response = client.post('/homepage/', search_form, follow=True)
+ day_care_queryset = response.context['day_care_queryset']
+ assert test_day_care in day_care_queryset
+ Order.create(dog_owner_id=DogOwner.objects.get(id=1), daycare_id=test_day_care,
+ start_date="2022-05-02", end_date="2022-08-02", price_per_day=100).approve_order()
+ response = client.post('/homepage/', search_form, follow=True)
+ assert test_day_care not in response.context['day_care_queryset']
+
+ def test_successful_dog_owner_search_for_day_care(self, client, create_dog_owner_user):
+ client.force_login(user=create_dog_owner_user.user)
+ search_form = {'area': "C",
+ 'city': "tel aviv",
+ 'price_per_day': 800,
+ 'name': "",
+ 'start_date': "2022-05-03",
+ 'end_date': "2022-05-08",
+ }
+ response = client.post('/homepage/', search_form, follow=True)
+ day_care_queryset = response.context['day_care_queryset']
+ available_day_cares = Order.get_all_day_cares_available_on_dates("2022-05-03", "2022-05-08")
+ filters_day_cares = DayCare.objects.filter(area__startswith='C',
+ city__icontains="tel aviv",
+ price_per_day__lte=800)
+ assert set(day_care_queryset) == set(available_day_cares.intersection(filters_day_cares))
+
+ def test_search_for_day_care_with_start_date_greater_than_end_date_show_error_and_present_all_daycares(
+ self, client, create_dog_owner_user):
+ client.force_login(user=create_dog_owner_user.user)
+ search_form = {'area': "C",
+ 'city': "tel aviv",
+ 'price_per_day': 800,
+ 'name': "",
+ 'start_date': "2022-05-03",
+ 'end_date': "2022-05-01",
+ }
+ response = client.post('/homepage/', search_form, follow=True)
+ day_care_queryset = response.context['day_care_queryset']
+ assert set(day_care_queryset) == set(DayCare.objects.all())
+ assert response.context['form']._errors['end_date']
+
def test_dog_owner_homepage_is_visible_for_dog_owner(self, client, create_dog_owner_user):
client.force_login(user=create_dog_owner_user.user)
response = client.get("/homepage/")
diff --git a/static/CSS/dog_owner_homepage.css b/static/CSS/dog_owner_homepage.css
index ef9ed9c..092071b 100644
--- a/static/CSS/dog_owner_homepage.css
+++ b/static/CSS/dog_owner_homepage.css
@@ -1,32 +1,24 @@
.cards
{
- display: flex;
- flex-direction: row;
- flex-wrap: wrap;
- margin-left: 50px;
- justify-content: center;
- align-items: center;
+ float:left;
+ margin: 0 0 0 5em;
+ position:relative;
+ width:100%;
}
-.row
-{
- height: 30rem;
- width: 120rem;
- margin-left: 200px;
+#searchResult {
+ font-weight:bold;
+ position: relative;
+ left: 6.3em;
+ top:30px;
}
.card
{
- width: 18.5%;
+ width: 330px;
height: 30rem;
- margin: 60px 60px 0 60px;
- max-width: 100%;
-}
-
-.card-body
-{
- display: flex;
- flex-direction: column;
+ float:left;
+ margin: 60px 20px 0 20px;
}
.card-body .btn
@@ -39,3 +31,30 @@
{
height: 200px;
}
+
+#searchBoxArea {
+ background-color:#dcdcdc;
+ left:5em;
+ top: 5.2em;
+ max-width:100%;
+ padding: 2em 2em 2em 2em;
+}
+
+#searchBoxArea span {
+ font-weight:bold;
+ font-size:18px;
+ color:#3e3e3e;
+ padding: 5px 0 1em 0;
+ float:left;
+}
+
+#searchBoxArea input[type="submit"] {
+ background-color:#3e3e3e;
+ border: 0;
+ border-radius:12px;
+ color:#FFF;
+}
+
+#searchBoxArea input[type="submit"]:hover {
+ background-color:#1e1e1e;
+}