Skip to content

Commit

Permalink
Merge pull request #499 from Esmat-Farjad/feat/org5w_dashboard
Browse files Browse the repository at this point in the history
filter added to the organization 5w dashboard
  • Loading branch information
shtayeb authored Dec 16, 2024
2 parents 7c47ee5 + 5d1e9c2 commit 8cffb3a
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 40 deletions.
46 changes: 46 additions & 0 deletions src/project_reports/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
from rh.models import (
ActivityDomain,
ActivityType,
Cluster,
Disaggregation,
Indicator,
Location,
Project,
)

from .models import ActivityPlanReport, ProjectMonthlyReport, TargetLocationReport
Expand Down Expand Up @@ -83,3 +86,46 @@ def __init__(self, data=None, *args, **kwargs):
report = kwargs.pop("report", None)
super().__init__(data, *args, **kwargs)
self.form.fields["activity_plan_report"].queryset = report.activityplanreport_set.all()


class Organization5WFilter(django_filters.FilterSet):
cluster = django_filters.ModelMultipleChoiceFilter(
queryset=Cluster.objects.all(),
field_name="activityplanreport__activity_plan__activity_domain__clusters",
label="Cluster",
widget=forms.SelectMultiple(attrs={"class": "custom-select"}),
)
project = django_filters.ModelMultipleChoiceFilter(
field_name="project",
queryset=Project.objects.none(),
widget=forms.SelectMultiple(attrs={"class": "custom-select"}),
)
province = django_filters.ModelMultipleChoiceFilter(
field_name="activityplanreport__targetlocationreport__target_location__province",
queryset=Location.objects.filter(level=1),
label="Province",
widget=forms.SelectMultiple(attrs={"class": "custom-select"}),
)
district = django_filters.ModelMultipleChoiceFilter(
field_name="activityplanreport__targetlocationreport__target_location__district",
queryset=Location.objects.filter(level=2),
label="District",
widget=forms.SelectMultiple(attrs={"class": "custom-select"}),
)
disaggregations = django_filters.ModelMultipleChoiceFilter(
field_name="activityplanreport__targetlocationreport__target_location__disaggregations__name",
queryset=Disaggregation.objects.all(),
label="disaggregations",
widget=forms.SelectMultiple(attrs={"class": "custom-select"}),
)
to_date = django_filters.DateFilter(widget=forms.DateInput(attrs={"type": "date"}))
from_date = django_filters.DateFilter(widget=forms.DateInput(attrs={"type": "date"}))

class Meta:
model = ProjectMonthlyReport
fields = ["from_date", "to_date", "cluster", "project", "province", "district", "disaggregations"]

def __init__(self, data=None, *args, **kwargs):
user = kwargs.pop("user", None)
super().__init__(data, *args, **kwargs)
self.form.fields["project"].queryset = Project.objects.filter(organization=user.profile.organization)
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ <h2 class="locations text-red-be">{{ request.user.profile.organization }}'s 5W D
src="{% static 'images/spinner.gif' %}" />
<!-- spinner end -->
</button>
{% include "components/_filter_drawer.html" with filter=dashboard_filter %}
</div>
</div>
<p class="flex items-center gap-2 pb-3">
Expand All @@ -51,7 +52,7 @@ <h2 class="locations text-red-be">{{ request.user.profile.organization }}'s 5W D
{% comment %} {% endcomment %}
<section class="space-y-4 pt-2">
{% comment %} filter {% endcomment %}
<form id="5w-filter-form" method="GET" class="py-4 bg-gray-fa border border-gray-d1 p-4 rounded-lg">
<!-- <form id="5w-filter-form" method="GET" class="py-4 bg-gray-fa border border-gray-d1 p-4 rounded-lg">
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<div class="flex items-center gap-2">
<div class="inline-flex justify-center rounded-md text-sm font-medium flex-col items-start w-full h-auto">
Expand All @@ -75,13 +76,14 @@ <h2 class="locations text-red-be">{{ request.user.profile.organization }}'s 5W D
{% endfor %}
</select>
</div>
</div>
</div>
<div class="flex items-center justify-end gap-2">
<a class="btn btn-gray-outline" href="{% url 'organizations-5w' user.profile.organization.code %}">Reset</a>
<button type="submit" class="btn btn-red">Filter</button>
</div>
</div>
</form>
</form> -->

{% comment %} cards {% endcomment %}
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
<div class="rounded-lg shadow-sm p-6 border border-gray-d1">
Expand Down
15 changes: 8 additions & 7 deletions src/project_reports/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -406,19 +406,20 @@ def write_import_report_template_sheet(workbook, monthly_report):
dv.add(cell)
# Case when the list values exceed 255 characters
else:

start_row = 2
start_row = 2
for i, item in enumerate(container_dictionary[key][1:]):
sheet[f"{column}{start_row + i}"] = item

# Define a named range for the list of values
named_range = f"{column}_List" # You can name the range based on the column or other criteria
sheet.parent.create_named_range(named_range, sheet, f"{column}{start_row}:{column}{start_row + len(list_values) - 1}")

sheet.parent.create_named_range(
named_range, sheet, f"{column}{start_row}:{column}{start_row + len(list_values) - 1}"
)

# Create a data validation that references the named range
dv = DataValidation(type="list", formula1=f"={named_range}",showDropDown=True)
dv = DataValidation(type="list", formula1=f"={named_range}", showDropDown=True)
sheet.add_data_validation(dv)
for row in range(2, num_rows):
cell = sheet[f"{column}{row}"]
sheet.add_data_validation(dv)
dv.add(cell)
dv.add(cell)
90 changes: 60 additions & 30 deletions src/project_reports/views/dashboards.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from rh.models import Cluster, Organization
from users.utils import is_cluster_lead

from project_reports.filters import Organization5WFilter
from project_reports.models import ProjectMonthlyReport


Expand Down Expand Up @@ -136,7 +137,12 @@ def org_5w_dashboard(request, code):
raise PermissionDenied

user_org = request.user.profile.organization

monthly_report_filter = Organization5WFilter(
request.GET,
queryset=ProjectMonthlyReport.objects.filter(project__organization=user_org),
user=request.user,
)
monthly_reports = monthly_report_filter.qs
from_date = request.GET.get("from")
if not from_date:
from_date = datetime.date(datetime.datetime.now().year, 1, 1)
Expand All @@ -158,7 +164,49 @@ def org_5w_dashboard(request, code):
if cluster_code:
filter_params["project__clusters__code__in"] = [cluster_code]

counts = ProjectMonthlyReport.objects.filter(**filter_params).aggregate(
# counts = ProjectMonthlyReport.objects.filter(**filter_params).aggregate(
# report_indicators_count=Count("activityplanreport__activity_plan__indicator", distinct=True),
# report_implementing_partners_count=Count(
# "activityplanreport__targetlocationreport__target_location__implementing_partner", distinct=True
# ),
# report_target_location_province_count=Count(
# "activityplanreport__targetlocationreport__target_location__province", distinct=True
# ),
# )

# people_reached_data = (
# ProjectMonthlyReport.objects.filter(
# **filter_params,
# )
# .order_by("from_date")
# .values("from_date")
# .annotate(
# total_people_reached=Sum("activityplanreport__targetlocationreport__disaggregationlocationreport__reached")
# )
# )

# people reached by activities
# activity_domains = (
# ProjectMonthlyReport.objects.filter(
# **filter_params,
# )
# .values_list("activityplanreport__activity_plan__activity_domain__name", flat=True)
# .distinct()
# )

# reach_by_activity = (
# ProjectMonthlyReport.objects.filter(
# **filter_params,
# )
# .values(
# "activityplanreport__targetlocationreport__disaggregationlocationreport__disaggregation__name",
# "activityplanreport__activity_plan__activity_domain__name",
# )
# .annotate(
# total_people_reached=Sum("activityplanreport__targetlocationreport__disaggregationlocationreport__reached"),
# )
# )
counts = monthly_reports.aggregate(
report_indicators_count=Count("activityplanreport__activity_plan__indicator", distinct=True),
report_implementing_partners_count=Count(
"activityplanreport__targetlocationreport__target_location__implementing_partner", distinct=True
Expand All @@ -167,48 +215,29 @@ def org_5w_dashboard(request, code):
"activityplanreport__targetlocationreport__target_location__province", distinct=True
),
)

people_reached_data = (
ProjectMonthlyReport.objects.filter(
**filter_params,
)
.order_by("from_date")
monthly_reports.order_by("from_date")
.values("from_date")
.annotate(
total_people_reached=Sum("activityplanreport__targetlocationreport__disaggregationlocationreport__reached")
)
)

counts["people_reached"] = sum(report["total_people_reached"] for report in people_reached_data)

labels = [report["from_date"].strftime("%b") for report in people_reached_data]
data = [
report["total_people_reached"] if report["total_people_reached"] is not None else 0
for report in people_reached_data
]

# people reached by activities
activity_domains = (
ProjectMonthlyReport.objects.filter(
**filter_params,
)
.values_list("activityplanreport__activity_plan__activity_domain__name", flat=True)
.distinct()
activity_domains = monthly_reports.values_list(
"activityplanreport__activity_plan__activity_domain__name", flat=True
).distinct()
reach_by_activity = monthly_reports.values(
"activityplanreport__targetlocationreport__disaggregationlocationreport__disaggregation__name",
"activityplanreport__activity_plan__activity_domain__name",
).annotate(
total_people_reached=Sum("activityplanreport__targetlocationreport__disaggregationlocationreport__reached"),
)

reach_by_activity = (
ProjectMonthlyReport.objects.filter(
**filter_params,
)
.values(
"activityplanreport__targetlocationreport__disaggregationlocationreport__disaggregation__name",
"activityplanreport__activity_plan__activity_domain__name",
)
.annotate(
total_people_reached=Sum("activityplanreport__targetlocationreport__disaggregationlocationreport__reached"),
)
)

# Organize data into a dictionary
data_dict = {}

Expand Down Expand Up @@ -242,6 +271,7 @@ def org_5w_dashboard(request, code):
"activity_domains": activity_domains,
"reach_by_activity": data_dict,
"clusters": clusters,
"dashboard_filter": monthly_report_filter,
}

return render(request, "project_reports/org_5w_dashboard.html", context)

0 comments on commit 8cffb3a

Please sign in to comment.