From d6bed497b0b2f76f4a3b63f218f374d8cb20fc61 Mon Sep 17 00:00:00 2001 From: hemant10yadav Date: Tue, 30 Jul 2024 08:13:13 +0530 Subject: [PATCH 1/8] Created a new app program --- commcare_connect/program/__init__.py | 0 commcare_connect/program/admin.py | 0 commcare_connect/program/apps.py | 7 +++ commcare_connect/program/forms.py | 55 +++++++++++++++++ .../program/migrations/0001_initial.py | 40 +++++++++++++ .../program/migrations/__init__.py | 0 commcare_connect/program/models.py | 16 +++++ commcare_connect/program/tests.py | 0 commcare_connect/program/urls.py | 10 ++++ commcare_connect/program/views.py | 59 +++++++++++++++++++ commcare_connect/templates/program/base.html | 10 ++++ .../templates/program/program_add.html | 25 ++++++++ .../templates/program/program_edit.html | 10 ++++ .../templates/program/program_list.html | 10 ++++ 14 files changed, 242 insertions(+) create mode 100644 commcare_connect/program/__init__.py create mode 100644 commcare_connect/program/admin.py create mode 100644 commcare_connect/program/apps.py create mode 100644 commcare_connect/program/forms.py create mode 100644 commcare_connect/program/migrations/0001_initial.py create mode 100644 commcare_connect/program/migrations/__init__.py create mode 100644 commcare_connect/program/models.py create mode 100644 commcare_connect/program/tests.py create mode 100644 commcare_connect/program/urls.py create mode 100644 commcare_connect/program/views.py create mode 100644 commcare_connect/templates/program/base.html create mode 100644 commcare_connect/templates/program/program_add.html create mode 100644 commcare_connect/templates/program/program_edit.html create mode 100644 commcare_connect/templates/program/program_list.html diff --git a/commcare_connect/program/__init__.py b/commcare_connect/program/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/commcare_connect/program/admin.py b/commcare_connect/program/admin.py new file mode 100644 index 00000000..e69de29b diff --git a/commcare_connect/program/apps.py b/commcare_connect/program/apps.py new file mode 100644 index 00000000..d34beb7f --- /dev/null +++ b/commcare_connect/program/apps.py @@ -0,0 +1,7 @@ +from django.apps import AppConfig +from django.utils.translation import gettext_lazy as _ + + +class ProgramConfig(AppConfig): + name = "commcare_connect.program" + verbose_name = _("Program") diff --git a/commcare_connect/program/forms.py b/commcare_connect/program/forms.py new file mode 100644 index 00000000..f2e08be6 --- /dev/null +++ b/commcare_connect/program/forms.py @@ -0,0 +1,55 @@ +from crispy_forms.helper import FormHelper +from crispy_forms.layout import Field, Layout, Row, Submit +from django import forms + +from commcare_connect.program.models import Program + + +class ProgramInitForm(forms.ModelForm): + class Meta: + model = Program + fields = [ + "name", + "description", + "delivery_type", + ] + + def __init__(self, *args, **kwargs): + self.user = kwargs.pop("user", {}) + super().__init__(*args, **kwargs) + self.helper = FormHelper(self) + self.helper.layout = Layout( + Row(Field("name")), + Row(Field("description")), + Row(Field("delivery_type")), + Submit("submit", "Submit"), + ) + + def save(self, commit=True): + self.instance.created_by = self.user.email + self.instance.modified_by = self.user.email + return super().save(commit=commit) + + +class ProgramForm(forms.ModelForm): + class Meta: + model = Program + fields = ["name", "description", "delivery_type"] + + def __init__(self, *args, **kwargs): + self.user = kwargs.pop("user", None) + super().__init__(*args, **kwargs) + self.helper = FormHelper(self) + self.helper.layout = Layout( + Row(Field("name")), + Row(Field("description")), + Row(Field("delivery_type")), + Submit("submit", "Submit"), + ) + + def save(self, commit=True): + instance = super().save(commit=False) + if not instance.pk: + instance.created_by = self.user.email + instance.modified_by = self.user.email + return super().save(commit=commit) diff --git a/commcare_connect/program/migrations/0001_initial.py b/commcare_connect/program/migrations/0001_initial.py new file mode 100644 index 00000000..721878f0 --- /dev/null +++ b/commcare_connect/program/migrations/0001_initial.py @@ -0,0 +1,40 @@ +# Generated by Django 4.2.5 on 2024-07-30 01:17 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + ("opportunity", "0053_assessment_opportunity_access_and_more"), + ] + + operations = [ + migrations.CreateModel( + name="Program", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("created_by", models.CharField(max_length=255)), + ("modified_by", models.CharField(max_length=255)), + ("date_created", models.DateTimeField(auto_now_add=True)), + ("date_modified", models.DateTimeField(auto_now=True)), + ("name", models.CharField(max_length=255)), + ("slug", models.SlugField(max_length=255, unique=True)), + ("description", models.CharField()), + ( + "delivery_type", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + to="opportunity.deliverytype", + ), + ), + ], + options={ + "abstract": False, + }, + ), + ] diff --git a/commcare_connect/program/migrations/__init__.py b/commcare_connect/program/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/commcare_connect/program/models.py b/commcare_connect/program/models.py new file mode 100644 index 00000000..17856178 --- /dev/null +++ b/commcare_connect/program/models.py @@ -0,0 +1,16 @@ +from django.db import models + +from commcare_connect.opportunity.models import DeliveryType +from commcare_connect.utils.db import BaseModel, slugify_uniquely + + +class Program(BaseModel): + name = models.CharField(max_length=255) + slug = models.SlugField(max_length=255, unique=True) + description = models.CharField() + delivery_type = models.ForeignKey(DeliveryType, null=True, blank=True, on_delete=models.DO_NOTHING) + + def save(self, *args, **kwargs): + if not self.id: + self.slug = slugify_uniquely(self.name, self.__class__) + super().save(*args, **kwargs) diff --git a/commcare_connect/program/tests.py b/commcare_connect/program/tests.py new file mode 100644 index 00000000..e69de29b diff --git a/commcare_connect/program/urls.py b/commcare_connect/program/urls.py new file mode 100644 index 00000000..c3a13228 --- /dev/null +++ b/commcare_connect/program/urls.py @@ -0,0 +1,10 @@ +from django.urls import path + +from commcare_connect.program.views import ProgramCreateOrUpdate, ProgramList + +app_name = "program" +urlpatterns = [ + path("", view=ProgramList.as_view(), name="list"), + path("init/", view=ProgramCreateOrUpdate.as_view(), name="init"), + path("/edit", view=ProgramCreateOrUpdate.as_view(), name="edit"), +] diff --git a/commcare_connect/program/views.py b/commcare_connect/program/views.py new file mode 100644 index 00000000..58f6112d --- /dev/null +++ b/commcare_connect/program/views.py @@ -0,0 +1,59 @@ +from django.contrib import messages +from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin +from django.urls import reverse +from django.views.generic import ListView, UpdateView + +from commcare_connect.program.forms import ProgramForm +from commcare_connect.program.models import Program + + +class SuperUserMixin(LoginRequiredMixin, UserPassesTestMixin): + def test_func(self): + return self.request.user.is_superuser + + +class ProgramList(SuperUserMixin, ListView): + model = Program + paginate_by = 10 + + def get_queryset(self): + return Program.objects.all() + + +class ProgramCreateOrUpdate(SuperUserMixin, UpdateView): + model = Program + form_class = ProgramForm + + def get_object(self, queryset=None): + pk = self.kwargs.get("pk") + if pk: + return super().get_object(queryset) + return None + + def get_form_kwargs(self): + kwargs = super().get_form_kwargs() + kwargs["user"] = self.request.user + return kwargs + + def form_valid(self, form): + is_new = self.object is None + response = super().form_valid(form) + if is_new: + messages.success(self.request, "Program created successfully.") + else: + messages.success(self.request, "Program updated successfully.") + return response + + def get_success_url(self): + return reverse("program:list", kwargs={"org_slug": self.request.org.slug}) + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["is_edit"] = self.object is not None + return context + + def get_template_names(self): + if self.object: + return ["program/program_edit.html"] + else: + return ["program/program_add.html"] diff --git a/commcare_connect/templates/program/base.html b/commcare_connect/templates/program/base.html new file mode 100644 index 00000000..6b6499c3 --- /dev/null +++ b/commcare_connect/templates/program/base.html @@ -0,0 +1,10 @@ + + + + + $Title$ + + +$END$ + + diff --git a/commcare_connect/templates/program/program_add.html b/commcare_connect/templates/program/program_add.html new file mode 100644 index 00000000..ef411110 --- /dev/null +++ b/commcare_connect/templates/program/program_add.html @@ -0,0 +1,25 @@ +{% extends "base.html" %} +{% load static %} +{% load crispy_forms_tags %} + +{% block title %} +{{ request.org }} - {% if is_edit %}Edit Program{% else %}Create Program{% endif %} +{% endblock %} + +{% block breadcrumbs_inner %} +{{ block.super }} +{% if is_edit %} + +{% else %} + +{% endif %} +{% endblock %} + +{% block content %} +

{% if is_edit %}Edit Program{% else %}Create Program{% endif %}

+
+
+ {% csrf_token %} + {% crispy form %} +
+{% endblock content %} diff --git a/commcare_connect/templates/program/program_edit.html b/commcare_connect/templates/program/program_edit.html new file mode 100644 index 00000000..6b6499c3 --- /dev/null +++ b/commcare_connect/templates/program/program_edit.html @@ -0,0 +1,10 @@ + + + + + $Title$ + + +$END$ + + diff --git a/commcare_connect/templates/program/program_list.html b/commcare_connect/templates/program/program_list.html new file mode 100644 index 00000000..6b6499c3 --- /dev/null +++ b/commcare_connect/templates/program/program_list.html @@ -0,0 +1,10 @@ + + + + + $Title$ + + +$END$ + + From 0dcab9db05b7f9eea82a7b05420dd17d169f6d15 Mon Sep 17 00:00:00 2001 From: hemant10yadav Date: Tue, 30 Jul 2024 08:14:11 +0530 Subject: [PATCH 2/8] Added add and edit logic for program --- commcare_connect/templates/base.html | 6 + commcare_connect/templates/program/base.html | 32 +++-- .../templates/program/program_add.html | 20 +--- .../templates/program/program_edit.html | 34 ++++-- .../templates/program/program_list.html | 110 ++++++++++++++++-- 5 files changed, 153 insertions(+), 49 deletions(-) diff --git a/commcare_connect/templates/base.html b/commcare_connect/templates/base.html index 373f9704..ff84ce5a 100644 --- a/commcare_connect/templates/base.html +++ b/commcare_connect/templates/base.html @@ -59,6 +59,12 @@ {% translate "Opportunities" %} + {% if request.user.is_superuser %} + + {% endif %} {% endif %} {% endif %} diff --git a/commcare_connect/templates/program/base.html b/commcare_connect/templates/program/base.html index 6b6499c3..02eeb169 100644 --- a/commcare_connect/templates/program/base.html +++ b/commcare_connect/templates/program/base.html @@ -1,10 +1,22 @@ - - - - - $Title$ - - -$END$ - - +{% extends "base.html" %} + +{% block breadcrumbs %} + +{% endblock %} + +{% block content %} +
+
+ {% block inner %}{% endblock %} +
+
+{% endblock %} diff --git a/commcare_connect/templates/program/program_add.html b/commcare_connect/templates/program/program_add.html index ef411110..e5d280c2 100644 --- a/commcare_connect/templates/program/program_add.html +++ b/commcare_connect/templates/program/program_add.html @@ -2,24 +2,6 @@ {% load static %} {% load crispy_forms_tags %} -{% block title %} -{{ request.org }} - {% if is_edit %}Edit Program{% else %}Create Program{% endif %} -{% endblock %} - -{% block breadcrumbs_inner %} -{{ block.super }} -{% if is_edit %} - -{% else %} - -{% endif %} -{% endblock %} - {% block content %} -

{% if is_edit %}Edit Program{% else %}Create Program{% endif %}

-
-
- {% csrf_token %} - {% crispy form %} -
+{% include "partial_form.html" %} {% endblock content %} diff --git a/commcare_connect/templates/program/program_edit.html b/commcare_connect/templates/program/program_edit.html index 6b6499c3..1f3517ce 100644 --- a/commcare_connect/templates/program/program_edit.html +++ b/commcare_connect/templates/program/program_edit.html @@ -1,10 +1,24 @@ - - - - - $Title$ - - -$END$ - - +{% extends "program/base.html" %} +{% load static %} +{% load crispy_forms_tags %} + +{% block title %}{{ request.org }} - {{ program.name }}{% endblock %} + +{% block breadcrumbs_inner %} +{{ block.super }} + + +{% endblock %} + +{% block content %} +

Edit Program

+
+
+ {% csrf_token %} + {% crispy form %} +
+{% endblock content %} diff --git a/commcare_connect/templates/program/program_list.html b/commcare_connect/templates/program/program_list.html index 6b6499c3..303c1701 100644 --- a/commcare_connect/templates/program/program_list.html +++ b/commcare_connect/templates/program/program_list.html @@ -1,10 +1,100 @@ - - - - - $Title$ - - -$END$ - - +{% extends "program/base.html" %} +{% load static %} +{% load sort_link %} + +{% block title %}{{ request.org }} - Program{% endblock %} + +{% block content %} +
+
+

Programs + + Add new + + +

+
+ +
+ + + + + + + + + + + {% for program in page_obj %} + + + + + + + {% empty %} + + + + {% endfor %} + +
{% sort_link 'name' 'Name' %}DescriptionDelivery TypeManage
{{ program.name }}{{ program.description }}{{ program.delivery_type.name }} +
+  Edit +
+
No programs yet.
+
+ + {% if page_obj.has_other_pages %} + + {% endif %} +
+{% endblock content %} From e3da32c7072222c669d5d3bb169dfb6d3f376f17 Mon Sep 17 00:00:00 2001 From: hemant10yadav Date: Tue, 30 Jul 2024 08:15:02 +0530 Subject: [PATCH 3/8] Added config settings for program app --- config/settings/base.py | 1 + config/urls.py | 1 + 2 files changed, 2 insertions(+) diff --git a/config/settings/base.py b/config/settings/base.py index 681d8778..95b492fb 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -75,6 +75,7 @@ "commcare_connect.reports", "commcare_connect.users", "commcare_connect.web", + "commcare_connect.program", ] INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS diff --git a/config/urls.py b/config/urls.py index 00f7c955..163a4b27 100644 --- a/config/urls.py +++ b/config/urls.py @@ -19,6 +19,7 @@ # Your stuff: custom urls includes go here path("a//", include("commcare_connect.organization.urls")), path("a//opportunity/", include("commcare_connect.opportunity.urls", namespace="opportunity")), + path("a//program/", include("commcare_connect.program.urls", namespace="program")), path("admin_reports/", include("commcare_connect.reports.urls")), ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) From 0ce4d8aae5ff83134e3e795008f7dbde52011fe1 Mon Sep 17 00:00:00 2001 From: hemant10yadav Date: Tue, 30 Jul 2024 08:28:59 +0530 Subject: [PATCH 4/8] Removed duplicate code --- commcare_connect/program/forms.py | 26 ------------------- .../templates/program/program_add.html | 2 ++ 2 files changed, 2 insertions(+), 26 deletions(-) diff --git a/commcare_connect/program/forms.py b/commcare_connect/program/forms.py index f2e08be6..31771982 100644 --- a/commcare_connect/program/forms.py +++ b/commcare_connect/program/forms.py @@ -5,32 +5,6 @@ from commcare_connect.program.models import Program -class ProgramInitForm(forms.ModelForm): - class Meta: - model = Program - fields = [ - "name", - "description", - "delivery_type", - ] - - def __init__(self, *args, **kwargs): - self.user = kwargs.pop("user", {}) - super().__init__(*args, **kwargs) - self.helper = FormHelper(self) - self.helper.layout = Layout( - Row(Field("name")), - Row(Field("description")), - Row(Field("delivery_type")), - Submit("submit", "Submit"), - ) - - def save(self, commit=True): - self.instance.created_by = self.user.email - self.instance.modified_by = self.user.email - return super().save(commit=commit) - - class ProgramForm(forms.ModelForm): class Meta: model = Program diff --git a/commcare_connect/templates/program/program_add.html b/commcare_connect/templates/program/program_add.html index e5d280c2..8dd68b94 100644 --- a/commcare_connect/templates/program/program_add.html +++ b/commcare_connect/templates/program/program_add.html @@ -3,5 +3,7 @@ {% load crispy_forms_tags %} {% block content %} +

Create Program

+
{% include "partial_form.html" %} {% endblock content %} From e7df5500bc613208b7fcd69e287691d9a0556cc4 Mon Sep 17 00:00:00 2001 From: hemant10yadav Date: Tue, 30 Jul 2024 18:28:30 +0530 Subject: [PATCH 5/8] Added message on update or create --- commcare_connect/program/views.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/commcare_connect/program/views.py b/commcare_connect/program/views.py index 58f6112d..8684f61a 100644 --- a/commcare_connect/program/views.py +++ b/commcare_connect/program/views.py @@ -36,12 +36,11 @@ def get_form_kwargs(self): return kwargs def form_valid(self, form): - is_new = self.object is None + is_edit = self.object is not None response = super().form_valid(form) - if is_new: - messages.success(self.request, "Program created successfully.") - else: - messages.success(self.request, "Program updated successfully.") + status = ("created", "updated")[is_edit] + message = f"Program '{self.object.name}' {status} successfully." + messages.success(self.request, message) return response def get_success_url(self): @@ -53,7 +52,6 @@ def get_context_data(self, **kwargs): return context def get_template_names(self): - if self.object: - return ["program/program_edit.html"] - else: - return ["program/program_add.html"] + view = ("add", "edit")[self.object is not None] + template = f"program/program_{view}.html" + return template From c8897ec61a8937f3f4fe53f569824edfef2d2b7e Mon Sep 17 00:00:00 2001 From: hemant10yadav Date: Wed, 31 Jul 2024 08:39:50 +0530 Subject: [PATCH 6/8] Changed the order of LOCAL_APPS and made delivery_type required --- commcare_connect/program/migrations/0001_initial.py | 9 ++------- commcare_connect/program/models.py | 2 +- config/settings/base.py | 2 +- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/commcare_connect/program/migrations/0001_initial.py b/commcare_connect/program/migrations/0001_initial.py index 721878f0..0dca577b 100644 --- a/commcare_connect/program/migrations/0001_initial.py +++ b/commcare_connect/program/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2.5 on 2024-07-30 01:17 +# Generated by Django 4.2.5 on 2024-07-31 03:04 from django.db import migrations, models import django.db.models.deletion @@ -25,12 +25,7 @@ class Migration(migrations.Migration): ("description", models.CharField()), ( "delivery_type", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.DO_NOTHING, - to="opportunity.deliverytype", - ), + models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to="opportunity.deliverytype"), ), ], options={ diff --git a/commcare_connect/program/models.py b/commcare_connect/program/models.py index 17856178..edc263e0 100644 --- a/commcare_connect/program/models.py +++ b/commcare_connect/program/models.py @@ -8,7 +8,7 @@ class Program(BaseModel): name = models.CharField(max_length=255) slug = models.SlugField(max_length=255, unique=True) description = models.CharField() - delivery_type = models.ForeignKey(DeliveryType, null=True, blank=True, on_delete=models.DO_NOTHING) + delivery_type = models.ForeignKey(DeliveryType, on_delete=models.PROTECT) def save(self, *args, **kwargs): if not self.id: diff --git a/config/settings/base.py b/config/settings/base.py index 95b492fb..a70bae57 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -72,10 +72,10 @@ "commcare_connect.form_receiver", "commcare_connect.opportunity", "commcare_connect.organization", + "commcare_connect.program", "commcare_connect.reports", "commcare_connect.users", "commcare_connect.web", - "commcare_connect.program", ] INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS From 6c9d05a91b6fe923de569e9bf0b3f078dc992bc6 Mon Sep 17 00:00:00 2001 From: hemant10yadav Date: Thu, 1 Aug 2024 15:34:05 +0530 Subject: [PATCH 7/8] Added budget,currency,date columns in Program Added start_date and end_date in list view Added sorting in table Added these fields in edit and create view --- commcare_connect/program/forms.py | 14 +++++++++++++- .../program/migrations/0001_initial.py | 6 +++++- commcare_connect/program/models.py | 4 ++++ commcare_connect/program/views.py | 13 ++++++++++++- .../templates/program/program_list.html | 6 ++++-- 5 files changed, 38 insertions(+), 5 deletions(-) diff --git a/commcare_connect/program/forms.py b/commcare_connect/program/forms.py index 31771982..307269bb 100644 --- a/commcare_connect/program/forms.py +++ b/commcare_connect/program/forms.py @@ -4,11 +4,15 @@ from commcare_connect.program.models import Program +HALF_WIDTH_FIELD = "form-group col-md-6 mb-0" +DATE_INPUT = forms.DateInput(attrs={"type": "date", "class": "form-control"}) + class ProgramForm(forms.ModelForm): class Meta: model = Program - fields = ["name", "description", "delivery_type"] + fields = ["name", "description", "delivery_type", "budget", "currency", "start_date", "end_date"] + widgets = {"start_date": DATE_INPUT, "end_date": DATE_INPUT} def __init__(self, *args, **kwargs): self.user = kwargs.pop("user", None) @@ -18,6 +22,14 @@ def __init__(self, *args, **kwargs): Row(Field("name")), Row(Field("description")), Row(Field("delivery_type")), + Row( + Field("budget", wrapper_class=HALF_WIDTH_FIELD), + Field("currency", wrapper_class=HALF_WIDTH_FIELD), + ), + Row( + Field("start_date", wrapper_class=HALF_WIDTH_FIELD), + Field("end_date", wrapper_class=HALF_WIDTH_FIELD), + ), Submit("submit", "Submit"), ) diff --git a/commcare_connect/program/migrations/0001_initial.py b/commcare_connect/program/migrations/0001_initial.py index 0dca577b..b6ba5baf 100644 --- a/commcare_connect/program/migrations/0001_initial.py +++ b/commcare_connect/program/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2.5 on 2024-07-31 03:04 +# Generated by Django 4.2.5 on 2024-08-01 03:53 from django.db import migrations, models import django.db.models.deletion @@ -23,6 +23,10 @@ class Migration(migrations.Migration): ("name", models.CharField(max_length=255)), ("slug", models.SlugField(max_length=255, unique=True)), ("description", models.CharField()), + ("budget", models.IntegerField()), + ("currency", models.CharField(max_length=3)), + ("start_date", models.DateField()), + ("end_date", models.DateField()), ( "delivery_type", models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to="opportunity.deliverytype"), diff --git a/commcare_connect/program/models.py b/commcare_connect/program/models.py index edc263e0..57f8a132 100644 --- a/commcare_connect/program/models.py +++ b/commcare_connect/program/models.py @@ -9,6 +9,10 @@ class Program(BaseModel): slug = models.SlugField(max_length=255, unique=True) description = models.CharField() delivery_type = models.ForeignKey(DeliveryType, on_delete=models.PROTECT) + budget = models.IntegerField() + currency = models.CharField(max_length=3) + start_date = models.DateField() + end_date = models.DateField() def save(self, *args, **kwargs): if not self.id: diff --git a/commcare_connect/program/views.py b/commcare_connect/program/views.py index 8684f61a..6e66b076 100644 --- a/commcare_connect/program/views.py +++ b/commcare_connect/program/views.py @@ -15,9 +15,20 @@ def test_func(self): class ProgramList(SuperUserMixin, ListView): model = Program paginate_by = 10 + allowed_orderings = { + "name": "name", + "-name": "-name", + "start_date": "start_date", + "-start_date": "-start_date", + "end_date": "end_date", + "-end_date": "-end_date", + } + default_ordering = "name" def get_queryset(self): - return Program.objects.all() + ordering = self.request.GET.get("sort", self.default_ordering) + ordering = self.allowed_orderings.get(ordering, self.default_ordering) + return Program.objects.all().order_by(ordering) class ProgramCreateOrUpdate(SuperUserMixin, UpdateView): diff --git a/commcare_connect/templates/program/program_list.html b/commcare_connect/templates/program/program_list.html index 303c1701..bedfc688 100644 --- a/commcare_connect/templates/program/program_list.html +++ b/commcare_connect/templates/program/program_list.html @@ -22,7 +22,8 @@

Programs {% sort_link 'name' 'Name' %} - Description + {% sort_link 'start_date' 'Start Date' %} + {% sort_link 'end_date' 'End Date' %} Delivery Type Manage @@ -31,7 +32,8 @@

Programs {% for program in page_obj %} {{ program.name }} - {{ program.description }} + {{ program.start_date }} + {{ program.end_date }} {{ program.delivery_type.name }}
From 3e4ab97d96c117d8c304f6b7b5d675713da5f26f Mon Sep 17 00:00:00 2001 From: hemant10yadav Date: Thu, 1 Aug 2024 16:06:51 +0530 Subject: [PATCH 8/8] Added date field validation --- commcare_connect/program/forms.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/commcare_connect/program/forms.py b/commcare_connect/program/forms.py index 307269bb..7803e441 100644 --- a/commcare_connect/program/forms.py +++ b/commcare_connect/program/forms.py @@ -5,7 +5,7 @@ from commcare_connect.program.models import Program HALF_WIDTH_FIELD = "form-group col-md-6 mb-0" -DATE_INPUT = forms.DateInput(attrs={"type": "date", "class": "form-control"}) +DATE_INPUT = forms.DateInput(format="%Y-%m-%d", attrs={"type": "date", "class": "form-control"}) class ProgramForm(forms.ModelForm): @@ -33,6 +33,15 @@ def __init__(self, *args, **kwargs): Submit("submit", "Submit"), ) + 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 and end_date <= start_date: + self.add_error("end_date", "End date must be after the start date.") + return cleaned_data + def save(self, commit=True): instance = super().save(commit=False) if not instance.pk: