Skip to content

Commit

Permalink
generic updates
Browse files Browse the repository at this point in the history
  • Loading branch information
saxix committed Oct 15, 2024
1 parent 41dfb03 commit 706bbf4
Show file tree
Hide file tree
Showing 19 changed files with 219 additions and 47 deletions.
3 changes: 0 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
name: Test

on:
create:
branches:
- releases/*
push:
branches:
- develop
Expand Down
13 changes: 12 additions & 1 deletion src/country_workspace/admin/batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from admin_extra_buttons.buttons import LinkButton
from admin_extra_buttons.decorators import link
from adminfilters.autocomplete import LinkedAutoCompleteFilter

from ..models import Batch
from .base import BaseModelAdmin
Expand All @@ -11,7 +12,10 @@
@admin.register(Batch)
class BatchAdmin(BaseModelAdmin):
list_display = ("name", "import_date", "imported_by")

list_filter = (
("country_office", LinkedAutoCompleteFilter.factory(parent=None)),
("program", LinkedAutoCompleteFilter.factory(parent="country_office")),
)
readonly_fields = ("country_office", "program")
search_fields = ("name",)

Expand All @@ -20,3 +24,10 @@ def members(self, button: LinkButton) -> None:
base = reverse("admin:country_workspace_individual_changelist")
obj = button.context["original"]
button.href = f"{base}?household__exact={obj.pk}"

@link(change_list=True, change_form=False)
def view_in_workspace(self, btn: "LinkButton") -> None:
if "request" in btn.context:
req = btn.context["request"]
base = reverse("workspace:workspaces_countrybatch_changelist")
btn.href = f"{base}?%s" % req.META["QUERY_STRING"]
7 changes: 7 additions & 0 deletions src/country_workspace/admin/household.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,10 @@ def members(self, button: LinkButton) -> None:
base = reverse("admin:country_workspace_individual_changelist")
obj = button.context["original"]
button.href = f"{base}?household__exact={obj.pk}"

@link(change_list=True, change_form=False)
def view_in_workspace(self, btn: "LinkButton") -> None:
if "request" in btn.context:
req = btn.context["request"]
base = reverse("workspace:workspaces_countryhousehold_changelist")
btn.href = f"{base}?%s" % req.META["QUERY_STRING"]
3 changes: 3 additions & 0 deletions src/country_workspace/models/batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ class Batch(BaseModel):

class Meta:
unique_together = (("import_date", "name"),)

def __str__(self):
return self.name or f"Batch self.pk ({self.country_office})"
25 changes: 19 additions & 6 deletions src/country_workspace/workspaces/admin/batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,37 @@

from django.db.models import QuerySet
from django.http import HttpRequest
from django.urls import reverse

from ...state import state
from admin_extra_buttons.buttons import LinkButton
from admin_extra_buttons.decorators import link

from ..filters import ProgramFilter
from ..options import WorkspaceModelAdmin
from .hh_ind import SelectedProgramMixin

if TYPE_CHECKING:
from ..models import CountryBatch


class CountryBatchAdmin(WorkspaceModelAdmin):
class CountryBatchAdmin(SelectedProgramMixin, WorkspaceModelAdmin):
list_display = ["name", "program", "country_office"]
search_fields = ("label",)

change_list_template = "workspace/household/change_list.html"
change_form_template = "workspace/household/change_form.html"
list_filter = (("program", ProgramFilter),)
change_list_template = "workspace/change_list.html"
change_form_template = "workspace/change_form.html"
ordering = ("name",)
readonly_fields = ("program", "country_office", "imported_by")

def get_queryset(self, request: HttpRequest) -> "QuerySet[CountryBatch]":
return super().get_queryset(request).filter(country_office=state.tenant)
return super().get_queryset(request).all()
# return super().get_queryset(request).filter(country_office=state.tenant)

def has_add_permission(self, request, obj=None):
return False

@link(change_list=False)
def imported_records(self, btn: LinkButton) -> None:
base = reverse("workspace:workspaces_countryhousehold_changelist")
obj = btn.context["original"]
btn.href = f"{base}?batch__exact={obj.pk}&batch__program__exact={obj.program.pk}"
70 changes: 45 additions & 25 deletions src/country_workspace/workspaces/admin/hh_ind.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
from django.http import Http404, HttpRequest, HttpResponse, HttpResponseRedirect
from django.shortcuts import render
from django.template.response import TemplateResponse
from django.urls import reverse
from django.utils.translation import gettext as _

from admin_extra_buttons.decorators import button
from admin_extra_buttons.buttons import LinkButton
from admin_extra_buttons.decorators import button, link
from adminfilters.autocomplete import LinkedAutoCompleteFilter
from adminfilters.mixin import AdminAutoCompleteSearchMixin
from hope_flex_fields.models import DataChecker
Expand All @@ -22,10 +24,45 @@
from .program import CountryProgram


class CountryHouseholdIndividualBaseAdmin(AdminAutoCompleteSearchMixin, WorkspaceModelAdmin):
class SelectedProgramMixin(WorkspaceModelAdmin):

def get_selected_program(self, request: HttpRequest, obj: "Optional[Validable]" = None) -> "CountryProgram | None":
from country_workspace.workspaces.models import CountryProgram

self._selected_program = None
if obj:
self._selected_program = obj.batch.program
elif "program__exact" in request.GET:
self._selected_program = CountryProgram.objects.get(pk=request.GET["program__exact"])
elif "batch__program__exact" in request.GET:
self._selected_program = CountryProgram.objects.get(pk=request.GET["batch__program__exact"])
return self._selected_program

def get_common_context(self, request: HttpRequest, pk: Optional[str] = None, **kwargs: Any) -> dict[str, Any]:
ret = super().get_common_context(request, pk, **kwargs)

ret["selected_program"] = self.get_selected_program(request, ret.get("original"))
ret["preserved_filters"] = request.GET.get("_changelist_filters", "")
return ret

def changelist_view(self, request: HttpRequest, extra_context: Optional[dict[str, Any]] = None) -> HttpResponse:
context = self.get_common_context(request, title="")
context.update(extra_context or {})
return super().changelist_view(request, context)

@link()
def import_rdi(self, btn: LinkButton) -> None:
btn.visible = False
if prg := self.get_selected_program(btn.context["request"]):
btn.href = reverse("workspace:workspaces_countryprogram_import_rdi", args=[prg.pk])
btn.visible = True


class CountryHouseholdIndividualBaseAdmin(AdminAutoCompleteSearchMixin, SelectedProgramMixin, WorkspaceModelAdmin):
list_filter = (
("batch__program", LinkedAutoCompleteFilter.factory(parent=None)),
("batch", LinkedAutoCompleteFilter.factory(parent="batch__program")),
# ("batch", BatchFilter),
)
actions = ["validate_queryset"]

Expand Down Expand Up @@ -66,7 +103,7 @@ def validate_queryset(self, request: HttpRequest, queryset: QuerySet) -> HttpRes

@button()
def view_raw_data(self, request: HttpRequest, pk: str) -> "HttpResponse":
context = self.get_common_context(request, pk)
context = self.get_common_context(request, pk, title="Raw Data")
return render(request, "workspace/raw_data.html", context)

def is_valid(self, obj: "Validable") -> bool | None:
Expand All @@ -80,40 +117,23 @@ def get_changelist(self, request: HttpRequest, **kwargs: Any) -> type:
from ..changelist import FlexFieldsChangeList

if program := self.get_selected_program(request):
return type("FlexFieldsChangeList", (FlexFieldsChangeList,), {"checker": program.household_checker})
return type(
"FlexFieldsChangeList",
(FlexFieldsChangeList,),
{"checker": program.household_checker, "selected_program": self.get_selected_program(request)},
)
return FlexFieldsChangeList

def has_add_permission(self, request: HttpRequest) -> bool:
return False

def get_selected_program(self, request: HttpRequest, obj: "Optional[Validable]" = None) -> "CountryProgram | None":
from country_workspace.workspaces.models import CountryProgram

self._selected_program = None
if obj:
self._selected_program = obj.batch.program
elif "batch__program__exact" in request.GET:
self._selected_program = CountryProgram.objects.get(pk=request.GET["batch__program__exact"])
return self._selected_program

def changelist_view(self, request: HttpRequest, extra_context: Optional[dict[str, Any]] = None) -> HttpResponse:
context = self.get_common_context(request, title="")
context.update(extra_context or {})
return super().changelist_view(request, context)

def get_checker(self, request: HttpRequest, obj: Optional[str] = None) -> "DataChecker":
if obj:
return obj.program.get_checker_for(obj)
elif p := self.get_selected_program(request):
return p.household_checker
raise Http404("No Household checkers available")

def get_common_context(self, request: HttpRequest, pk: Optional[str] = None, **kwargs: Any) -> dict[str, Any]:
ret = super().get_common_context(request, pk, **kwargs)

ret["selected_program"] = self.get_selected_program(request, ret.get("original"))
return ret

def _changeform_view(
self, request: HttpRequest, object_id: str, form_url: str, extra_context: dict[str, Any]
) -> HttpResponse:
Expand Down
2 changes: 1 addition & 1 deletion src/country_workspace/workspaces/admin/program.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ def individual_columns(self, request: HttpResponse, pk: str) -> "HttpResponse |

@button(label=_("Import File"))
def import_rdi(self, request: HttpRequest, pk: str) -> "HttpResponse":
context = self.get_common_context(request, pk)
context = self.get_common_context(request, pk, title="Import RDI file")
program: "CountryProgram" = context["original"]
context["selected_program"] = context["original"]
hh_ids = {}
Expand Down
21 changes: 15 additions & 6 deletions src/country_workspace/workspaces/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,30 @@ def queryset(self, request: HttpRequest, queryset: QuerySet) -> QuerySet:
if self.lookup_val:
p = state.tenant.programs.get(pk=self.lookup_val)
# if request.usser.has_perm()
queryset = super().queryset(request, queryset)
queryset = super().queryset(request, queryset).filter(batch__program=p)
state.program = p
return queryset


class BatchFilter(LinkedAutoCompleteFilter):
# def has_output(self) -> bool:
# return bool("batch__program__exact" in self.request.GET)
def has_output(self) -> bool:
return bool("batch__program__exact" in self.request.GET)

# def get_url(self):
# url = reverse("%s:autocomplete" % self.admin_site.name)
# # if self.parent_lookup_kwarg in self.request.GET:
# # flt = self.parent_lookup_kwarg.split("__")[-2]
# if self.has_output():
# oid = self.request.GET["batch__program__exact"]
# return f"{url}?program__exact={oid}"
# return url

def queryset(self, request: HttpRequest, queryset: QuerySet) -> QuerySet:
if self.lookup_val:
p = state.tenant.programs.get(pk=self.lookup_val)
# p = state.tenant.programs.get(pk=self.lookup_val)
# if request.usser.has_perm()
queryset = super().queryset(request, queryset)
state.program = p
queryset = super().queryset(request, queryset).filter(batch=self.lookup_val)
# state.program = p
return queryset


Expand Down
4 changes: 4 additions & 0 deletions src/country_workspace/workspaces/options.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from urllib.parse import urlencode

from django.contrib import admin
from django.contrib.admin import ShowFacets
from django.http import HttpResponseRedirect
from django.urls import reverse

Expand All @@ -25,6 +26,9 @@ class WorkspaceModelAdmin(ExtraButtonsMixin, AdminFiltersMixin, SmartFilterMixin
delete_confirmation_template = "workspace/delete_confirmation.html"
preserve_filters = True
default_url_filters = {}
actions_selection_counter = False
show_facets = ShowFacets.NEVER
show_full_result_count = False

def __init__(self, model, admin_site):
self._selected_program = None
Expand Down
8 changes: 7 additions & 1 deletion src/country_workspace/workspaces/sites.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ class TenantAutocompleteJsonView(SmartAutocompleteJsonView):
def has_perm(self, request: "HttpRequest", obj: "Model|None" = None) -> bool:
return self.model_admin.has_view_permission(request, obj=obj)

def filter_queryset(self, queryset: QuerySet) -> QuerySet:
params = {
k: v for k, v in self.request.GET.items() if k not in ["app_label", "model_name", "field_name", "term"]
}
return queryset.filter(**params)

def get_queryset(self) -> QuerySet:
"""Return queryset based on ModelAdmin.get_search_results()."""
qs = self.model_admin.get_queryset(self.request)
Expand All @@ -34,7 +40,7 @@ def get_queryset(self) -> QuerySet:
qs, search_use_distinct = self.model_admin.get_search_results(self.request, qs, self.term)
if search_use_distinct:
qs = qs.distinct()
return qs
return self.filter_queryset(qs)

def process_request(self, request: HttpRequest): # noqa C901
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@
{% endif %}

{% block coltype %}{% endblock %}

{% block content_title %}{% endblock %}
{% block pretitle %}
{% include "workspace/includes/program_title.html" with program=selected_program %}
{% endblock %}
{% block content %}
<div id="content-main">
{% block object-tools %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@
{% block content_title %}{% endblock %}
{% block coltype %}colMX{% endblock %}

{% if not is_popup %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'workspace:index' %}">{% translate 'Workspaces' %}</a>
&rsaquo; <a href="{% url 'workspace:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
&rsaquo; {% if has_view_permission %}
{% url opts|workspace_urlname:'changelist' as wcl %}
<a href="{% add_preserved_filters wcl %}">{{ opts.verbose_name_plural|capfirst }}</a>{% else %}{{ opts.verbose_name_plural|capfirst }}{% endif %}

&rsaquo; {% if add %}{% blocktranslate with name=opts.verbose_name %}Add {{ name }}{% endblocktranslate %}{% else %}{{ original|truncatewords:"18" }}{% endif %}
</div>
{% endblock %}
{% endif %}


{% block content %}
<div id="content-main">
{% block object-tools %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@

{% block coltype %}{% endblock %}
{% block pretitle %}
{{ selected_program }}
{% include "workspace/includes/program_title.html" with program=selected_program %}
{% endblock %}


{% block content %}
<div id="content-main">
{% block object-tools %}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<h1>
{% if program %}
<a href="{% url "workspace:workspaces_countryprogram_change" program.pk %}">{{ program }}</a>
&rsaquo; <a href="{% url "workspace:workspaces_countryprogram_change" program.pk %}">{{ program }}</a>

{% if perms.country_workspace.change_program %}
<a class="icon icon-cogs small" target="_admin"
href="{% url "admin:country_workspace_program_change" program.pk %}"></a>
{% endif %}
{% if household %}
<a href="{% url "workspace:workspaces_countryhousehold_change" household.pk %}">{{ household }}</a>
&rsaquo; <a href="{% url "workspace:workspaces_countryhousehold_change" household.pk %}">{{ household }}</a>
{% if perms.country_workspace.change_household %}
<a class="icon icon-cogs small" target="_admin"
href="{% url "admin:country_workspace_household_change" household.pk %}"></a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@

{% block content %}
<h2>{{ checker }}</h2>
{% block object-tools %}
{% if change and not is_popup %}
<ul class="object-tools">
{% block object-tools-items %}
{% include "admin_extra_buttons/includes/change_form_buttons.html" %}
{% endblock %}
</ul>
{% endif %}
{% endblock %}
<form method="post" id="configure-columns">
{% csrf_token %}
<table>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@
{# </h1>#}
{% endblock %}
{% block content %}
{% block object-tools %}
{% if change and not is_popup %}
<ul class="object-tools">
{% block object-tools-items %}
{% include "admin_extra_buttons/includes/change_form_buttons.html" %}
{% endblock %}
</ul>
{% endif %}
{% endblock %}
<form method="post" id="import-file" enctype="multipart/form-data">
{% csrf_token %}
<table>
Expand Down
Loading

0 comments on commit 706bbf4

Please sign in to comment.