konova/compensation/tables.py
mpeltriaux aa338e5519 #86 Parcel-Geometry improvement
* improves the way parcel-geometry relations are stored on the DB
    * instead of a numerical sequence we switched to UUID, so no sequence will run out at anytime (new model: ParcelIntersection)
    * instead of dropping all M2M relations between parcel and geometry on each calculation, we keep the ones that still exist, drop the ones that do not exist and add new ones (if new ones exist)
2022-02-09 09:18:35 +01:00

356 lines
10 KiB
Python

"""
Author: Michel Peltriaux
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 01.12.20
"""
from user.models import User
from django.http import HttpRequest
from django.template.loader import render_to_string
from django.urls import reverse
from django.utils.html import format_html
from django.utils.timezone import localtime
from django.utils.translation import gettext_lazy as _
from compensation.filters import CompensationTableFilter, EcoAccountTableFilter
from compensation.models import Compensation, EcoAccount
from konova.sub_settings.django_settings import DEFAULT_DATE_TIME_FORMAT
from konova.utils.tables import BaseTable, TableRenderMixin
import django_tables2 as tables
class CompensationTable(BaseTable, TableRenderMixin):
id = tables.Column(
verbose_name=_("Identifier"),
orderable=True,
accessor="identifier",
)
t = tables.Column(
verbose_name=_("Title"),
orderable=True,
accessor="title",
)
d = tables.Column(
verbose_name=_("Parcel gmrkng"),
orderable=True,
accessor="geometry",
)
c = tables.Column(
verbose_name=_("Checked"),
orderable=True,
empty_values=[],
accessor="intervention__checked",
)
r = tables.Column(
verbose_name=_("Recorded"),
orderable=True,
empty_values=[],
accessor="intervention__recorded",
)
e = tables.Column(
verbose_name=_("Editable"),
orderable=True,
empty_values=[],
accessor="intervention__users",
)
lm = tables.Column(
verbose_name=_("Last edit"),
orderable=True,
accessor="modified__timestamp",
)
class Meta(BaseTable.Meta):
template_name = "django_tables2/bootstrap4.html"
def __init__(self, request: HttpRequest, *args, **kwargs):
self.title = _("Compensations")
self.add_new_url = reverse("compensation:new")
qs = kwargs.get("queryset", None)
self.filter = CompensationTableFilter(
user=request.user,
data=request.GET,
queryset=qs,
)
kwargs["queryset"] = self.filter.qs
super().__init__(request, *args, **kwargs)
def render_id(self, value, record: Compensation):
""" Renders the id column for a compensation
Args:
value (str): The identifier value
record (Compensation): The compensation record
Returns:
"""
context = {
"tooltip": _("Open {}").format(_("Intervention")),
"content": value,
"url": reverse("compensation:detail", args=(record.id,)),
"has_revocations": record.intervention.legal.revocations.exists()
}
html = render_to_string(
"table/revocation_warning_col.html",
context
)
return html
def render_c(self, value, record: Compensation):
""" Renders the checked column for a compensation
checked is set by the main object Intervention
Args:
value (str): The identifier value
record (Compensation): The compensation record
Returns:
"""
html = ""
checked = value is not None
tooltip = _("Not checked yet")
if checked:
value = value.timestamp
value = localtime(value)
checked_on = value.strftime(DEFAULT_DATE_TIME_FORMAT)
tooltip = _("Checked on {} by {}").format(checked_on, record.intervention.checked.user)
html += self.render_checked_star(
tooltip=tooltip,
icn_filled=checked,
)
return format_html(html)
def render_d(self, value, record: Compensation):
""" Renders the parcel district column for a compensation
Args:
value (str): The geometry
record (Compensation): The compensation record
Returns:
"""
parcels = value.parcels.filter(
parcelintersection__calculated_on__isnull=False,
).values_list(
"gmrkng",
flat=True
).distinct()
html = render_to_string(
"table/gmrkng_col.html",
{
"entries": parcels
}
)
return html
def render_r(self, value, record: Compensation):
""" Renders the registered column for a compensation
Args:
value (str): The identifier value
record (Compensation): The compensation record
Returns:
"""
html = ""
recorded = value is not None
tooltip = _("Not recorded yet")
if recorded:
value = value.timestamp
value = localtime(value)
on = value.strftime(DEFAULT_DATE_TIME_FORMAT)
tooltip = _("Recorded on {} by {}").format(on, record.intervention.recorded.user)
html += self.render_bookmark(
tooltip=tooltip,
icn_filled=recorded,
)
return format_html(html)
def render_e(self, value, record: Compensation):
""" Renders the editable column for a compensation
Args:
value (str): The identifier value
record (Compensation): The compensation record
Returns:
"""
if value is None:
value = User.objects.none()
has_access = value.filter(
id=self.user.id
).exists()
html = self.render_icn(
tooltip=_("Full access granted") if has_access else _("Access not granted"),
icn_class="fas fa-edit rlp-r-inv" if has_access else "far fa-edit",
)
return format_html(html)
class EcoAccountTable(BaseTable, TableRenderMixin):
id = tables.Column(
verbose_name=_("Identifier"),
orderable=True,
accessor="identifier",
)
t = tables.Column(
verbose_name=_("Title"),
orderable=True,
accessor="title",
)
d = tables.Column(
verbose_name=_("Parcel gmrkng"),
orderable=True,
accessor="geometry",
)
av = tables.Column(
verbose_name=_("Available"),
orderable=True,
empty_values=[],
attrs={
"th": {
"class": "w-20",
}
}
)
r = tables.Column(
verbose_name=_("Recorded"),
orderable=True,
empty_values=[],
accessor="recorded",
)
e = tables.Column(
verbose_name=_("Editable"),
orderable=True,
empty_values=[],
accessor="users",
)
lm = tables.Column(
verbose_name=_("Last edit"),
orderable=True,
accessor="modified__timestamp",
)
class Meta(BaseTable.Meta):
template_name = "django_tables2/bootstrap4.html"
def __init__(self, request: HttpRequest, *args, **kwargs):
self.title = _("Eco Accounts")
self.add_new_url = reverse("compensation:acc:new")
qs = kwargs.get("queryset", None)
self.filter = EcoAccountTableFilter(
user=request.user,
data=request.GET,
queryset=qs,
)
kwargs["queryset"] = self.filter.qs
super().__init__(request, *args, **kwargs)
def render_id(self, value, record: EcoAccount):
""" Renders the id column for an eco account
Args:
value (str): The identifier value
record (EcoAccount): The eco account record
Returns:
"""
html = ""
html += self.render_link(
tooltip=_("Open {}").format(_("Eco-account")),
href=reverse("compensation:acc:detail", args=(record.id,)),
txt=value,
new_tab=False,
)
return format_html(html)
def render_av(self, value, record: EcoAccount):
""" Renders the available column for an eco account
Args:
value (str): The identifier value
record (EcoAccount): The eco account record
Returns:
"""
value_total, value_relative = record.get_available_rest()
html = render_to_string("konova/widgets/progressbar.html", {"value": value_relative})
return format_html(html)
def render_d(self, value, record: Compensation):
""" Renders the parcel district column for a compensation
Args:
value (str): The geometry
record (Compensation): The compensation record
Returns:
"""
parcels = value.parcels.filter(
parcelintersection__calculated_on__isnull=False,
).values_list(
"gmrkng",
flat=True
).distinct()
html = render_to_string(
"table/gmrkng_col.html",
{
"entries": parcels
}
)
return html
def render_r(self, value, record: EcoAccount):
""" Renders the recorded column for an eco account
Args:
value (str): The identifier value
record (EcoAccount): The eco account record
Returns:
"""
html = ""
checked = value is not None
tooltip = _("Not recorded yet. Can not be used for deductions, yet.")
if checked:
value = value.timestamp
value = localtime(value)
on = value.strftime(DEFAULT_DATE_TIME_FORMAT)
tooltip = _("Recorded on {} by {}").format(on, record.recorded.user)
html += self.render_bookmark(
tooltip=tooltip,
icn_filled=checked,
)
return format_html(html)
def render_e(self, value, record: EcoAccount):
""" Renders the editable column for an eco account
Args:
value (str): The identifier value
record (EcoAccount): The eco account record
Returns:
"""
html = ""
# Do not use value in here, since value does use unprefetched 'users' manager, where record has already
# prefetched users data
has_access = self.user in record.users.all()
html += self.render_icn(
tooltip=_("Full access granted") if has_access else _("Access not granted"),
icn_class="fas fa-edit rlp-r-inv" if has_access else "far fa-edit",
)
return format_html(html)