EcoAccount template and logic

* adds eco-account own includes for simpler maintainability instead of refactoring to generic includes for compensation app and predefining urls and stuff on the backend
* adds before-state, after-state, actions, deadlines, documents and withdraws to eco account detail view
* adds hint for invalid withdraw in intervention detail view in case of deleted eco account
* adds/updates translations
This commit is contained in:
mipel
2021-08-09 15:09:43 +02:00
parent d27a39f6d9
commit 17d697da92
20 changed files with 728 additions and 220 deletions

View File

@@ -12,7 +12,7 @@
<h3>{% trans 'Compensation' %} {{obj.identifier}}</h3>
</div>
<div class="col-sm-12 col-md-12 col-lg-6">
{% include 'compensation/detail/includes/controls.html' %}
{% include 'compensation/detail/compensation/includes/controls.html' %}
</div>
</div>
<hr>
@@ -91,23 +91,23 @@
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-6">
{% include 'compensation/detail/includes/states-before.html' %}
{% include 'compensation/detail/compensation/includes/states-before.html' %}
</div>
<div class="col-sm-12 col-md-12 col-lg-6">
{% include 'compensation/detail/includes/states-after.html' %}
{% include 'compensation/detail/compensation/includes/states-after.html' %}
</div>
</div>
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-6">
{% include 'compensation/detail/includes/actions.html' %}
{% include 'compensation/detail/compensation/includes/actions.html' %}
</div>
<div class="col-sm-12 col-md-12 col-lg-6">
{% include 'compensation/detail/includes/deadlines.html' %}
{% include 'compensation/detail/compensation/includes/deadlines.html' %}
</div>
</div>
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-6">
{% include 'compensation/detail/includes/documents.html' %}
{% include 'compensation/detail/compensation/includes/documents.html' %}
</div>
</div>

View File

@@ -0,0 +1,61 @@
{% load i18n l10n fontawesome_5 humanize %}
<div id="actions" class="card">
<div class="card-header rlp-r">
<div class="row">
<div class="col-sm-6">
<h5>
<span class="badge badge-light">{{obj.actions.count}}</span>
{% trans 'Actions' context 'Compensation' %}
</h5>
</div>
<div class="col-sm-6">
<div class="d-flex justify-content-end">
{% if is_default_member and has_access %}
<button class="btn btn-outline-default btn-modal" data-form-url="{% url 'compensation:acc-new-action' obj.id %}" title="{% trans 'Add new action' %}">
{% fa5_icon 'plus' %}
{% fa5_icon 'seedling' %}
</button>
{% endif %}
</div>
</div>
</div>
</div>
<div class="card-body scroll-300">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">
{% trans 'Action type' %}
</th>
<th scope="col">
{% trans 'Amount' context 'Compensation' %}
</th>
<th scope="col">
{% trans 'Comment' %}
</th>
<th scope="col">
{% trans 'Action' %}
</th>
</tr>
</thead>
<tbody>
{% for action in obj.actions.all %}
<tr>
<td class="align-middle">
{{ action.action_type }}
</td>
<td class="align-middle">{{ action.amount|floatformat:2|intcomma }} {{ action.unit_humanize }}</td>
<td class="align-middle">{{ action.comment|default_if_none:"" }}</td>
<td>
{% if is_default_member and has_access %}
<button data-form-url="{% url 'compensation:action-remove' action.id %}" class="btn btn-default btn-modal" title="{% trans 'Remove action' %}">
{% fa5_icon 'trash' %}
</button>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>

View File

@@ -0,0 +1,29 @@
{% load i18n l10n fontawesome_5 %}
<div class="d-flex justify-content-end">
<a href="{% url 'home' %}" class="mr-2">
<button class="btn btn-default" title="{% trans 'Open in LANIS' %}">
LANIS
</button>
</a>
<a href="{% url 'home' %}" class="mr-2">
<button class="btn btn-default" title="{% trans 'Public report' %}">
{% fa5_icon 'file-alt' %}
</button>
</a>
{% if has_access %}
{% if is_default_member %}
<a href="{% url 'home' %}" class="mr-2">
<button class="btn btn-default" title="{% trans 'Edit' %}">
{% fa5_icon 'edit' %}
</button>
</a>
<button class="btn btn-default btn-modal mr-2" data-form-url="{% url 'compensation:acc-log' obj.id %}" title="{% trans 'Show log' %}">
{% fa5_icon 'history' %}
</button>
<button class="btn btn-default btn-modal" data-form-url="{% url 'compensation:acc-remove' obj.id %}" title="{% trans 'Delete' %}">
{% fa5_icon 'trash' %}
</button>
{% endif %}
{% endif %}
</div>

View File

@@ -0,0 +1,61 @@
{% load i18n l10n fontawesome_5 %}
<div id="deadlines" class="card">
<div class="card-header rlp-r">
<div class="row">
<div class="col-sm-6">
<h5>
<span class="badge badge-light">{{obj.deadlines.count}}</span>
{% trans 'Deadlines' %}
</h5>
</div>
<div class="col-sm-6">
<div class="d-flex justify-content-end">
{% if is_default_member and has_access %}
<button class="btn btn-outline-default btn-modal" data-form-url="{% url 'compensation:acc-new-deadline' obj.id %}" title="{% trans 'Add new deadline' %}">
{% fa5_icon 'plus' %}
{% fa5_icon 'calendar-check' %}
</button>
{% endif %}
</div>
</div>
</div>
</div>
<div class="card-body scroll-300">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">
{% trans 'Type' %}
</th>
<th scope="col">
{% trans 'Date' %}
</th>
<th scope="col">
{% trans 'Comment' %}
</th>
<th scope="col">
{% trans 'Action' %}
</th>
</tr>
</thead>
<tbody>
{% for deadline in obj.deadlines.all %}
<tr>
<td class="align-middle">
{% trans deadline.type_humanized %}
</td>
<td class="align-middle">{{ deadline.date }}</td>
<td class="align-middle">{{ deadline.comment }}</td>
<td>
{% if is_default_member and has_access %}
<button data-form-url="{% url 'deadline-remove' deadline.id %}" class="btn btn-default btn-modal" title="{% trans 'Remove deadline' %}">
{% fa5_icon 'trash' %}
</button>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>

View File

@@ -0,0 +1,59 @@
{% load i18n l10n fontawesome_5 %}
<div id="documents" class="card">
<div class="card-header rlp-r">
<div class="row">
<div class="col-sm-6">
<h5>
<span class="badge badge-light">{{obj.documents.count}}</span>
{% trans 'Documents' %}
</h5>
</div>
<div class="col-sm-6">
<div class="d-flex justify-content-end">
{% if is_default_member and has_access %}
<button class="btn btn-outline-default btn-modal" data-form-url="{% url 'compensation:acc-new-doc' obj.id %}" title="{% trans 'Add new document' %}">
{% fa5_icon 'plus' %}
{% fa5_icon 'file' %}
</button>
{% endif %}
</div>
</div>
</div>
</div>
<div class="card-body scroll-300">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">
{% trans 'Title' %}
</th>
<th scope="col">
{% trans 'Comment' %}
</th>
<th scope="col">
{% trans 'Action' %}
</th>
</tr>
</thead>
<tbody>
{% for doc in obj.documents.all %}
<tr>
<td class="align-middle">
<a href="{% url 'doc-open' doc.id %}">
{{ doc.title }}
</a>
</td>
<td class="align-middle">{{ doc.comment }}</td>
<td>
{% if is_default_member and has_access %}
<button data-form-url="{% url 'doc-remove' doc.id %}" class="btn btn-default btn-modal" title="{% trans 'Remove document' %}">
{% fa5_icon 'trash' %}
</button>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>

View File

@@ -0,0 +1,62 @@
{% load i18n l10n fontawesome_5 %}
<div id="states-after" class="card">
<div class="card-header rlp-r">
<div class="row">
<div class="col-sm-6">
<h5>
<span class="badge badge-light">{{obj.after_states.count}}</span>
{% trans 'States after' %}
</h5>
</div>
<div class="col-sm-6">
<div class="d-flex justify-content-end">
{% if is_default_member and has_access %}
<button class="btn btn-outline-default btn-modal" data-form-url="{% url 'compensation:acc-new-state' obj.id %}" title="{% trans 'Add new state after' %}">
{% fa5_icon 'plus' %}
{% fa5_icon 'layer-group' %}
</button>
{% endif %}
</div>
</div>
</div>
</div>
<div class="card-body scroll-300">
{% if sum_before_states > sum_after_states %}
<div class="row alert alert-danger">
{% trans 'Missing surfaces according to states before: ' %}{{ diff_states|floatformat:2 }} m²
</div>
{% endif %}
<table class="table table-hover">
<thead>
<tr>
<th scope="col">
{% trans 'Biotope type' %}
</th>
<th scope="col">
{% trans 'Surface' %}
</th>
<th scope="col">
{% trans 'Action' %}
</th>
</tr>
</thead>
<tbody>
{% for state in after_states %}
<tr>
<td class="align-middle">
{{ state.biotope_type }}
</td>
<td class="align-middle">{{ state.surface|floatformat:2 }} m²</td>
<td>
{% if is_default_member and has_access %}
<button data-form-url="{% url 'compensation:state-remove' state.id %}" class="btn btn-default btn-modal" title="{% trans 'Remove state' %}">
{% fa5_icon 'trash' %}
</button>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>

View File

@@ -0,0 +1,62 @@
{% load i18n l10n fontawesome_5 %}
<div id="states-before" class="card">
<div class="card-header rlp-r">
<div class="row">
<div class="col-sm-6">
<h5>
<span class="badge badge-light">{{obj.before_states.count}}</span>
{% trans 'States before' %}
</h5>
</div>
<div class="col-sm-6">
<div class="d-flex justify-content-end">
{% if is_default_member and has_access %}
<button class="btn btn-outline-default btn-modal" data-form-url="{% url 'compensation:acc-new-state' obj.id %}?before=true" title="{% trans 'Add new state before' %}">
{% fa5_icon 'plus' %}
{% fa5_icon 'layer-group' %}
</button>
{% endif %}
</div>
</div>
</div>
</div>
<div class="card-body scroll-300">
{% if sum_before_states < sum_after_states %}
<div class="row alert alert-danger">
{% trans 'Missing surfaces according to states after: ' %}{{ diff_states|floatformat:2 }} m²
</div>
{% endif %}
<table class="table table-hover">
<thead>
<tr>
<th scope="col">
{% trans 'Biotope type' %}
</th>
<th scope="col">
{% trans 'Surface' %}
</th>
<th scope="col">
{% trans 'Action' %}
</th>
</tr>
</thead>
<tbody>
{% for state in before_states %}
<tr>
<td class="align-middle">
{{ state.biotope_type }}
</td>
<td class="align-middle">{{ state.surface|floatformat:2 }} m²</td>
<td>
{% if is_default_member and has_access %}
<button data-form-url="{% url 'compensation:state-remove' state.id %}" class="btn btn-default btn-modal" title="{% trans 'Remove state' %}">
{% fa5_icon 'trash' %}
</button>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>

View File

@@ -12,7 +12,7 @@
<h3>{% trans 'Eco-account' %} {{obj.identifier}}</h3>
</div>
<div class="col-sm-12 col-md-12 col-lg-6">
{% include 'compensation/detail/includes/controls.html' %}
{% include 'compensation/detail/eco_account/includes/controls.html' %}
</div>
</div>
<hr>
@@ -77,23 +77,23 @@
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-6">
{% include 'compensation/detail/includes/states-before.html' %}
{% include 'compensation/detail/eco_account/includes/states-before.html' %}
</div>
<div class="col-sm-12 col-md-12 col-lg-6">
{% include 'compensation/detail/includes/states-after.html' %}
{% include 'compensation/detail/eco_account/includes/states-after.html' %}
</div>
</div>
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-6">
{% include 'compensation/detail/includes/actions.html' %}
{% include 'compensation/detail/eco_account/includes/actions.html' %}
</div>
<div class="col-sm-12 col-md-12 col-lg-6">
{% include 'compensation/detail/includes/deadlines.html' %}
{% include 'compensation/detail/eco_account/includes/deadlines.html' %}
</div>
</div>
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-6">
{% include 'compensation/detail/includes/documents.html' %}
{% include 'compensation/detail/eco_account/includes/documents.html' %}
</div>
<div class="col-sm-12 col-md-12 col-lg-6">
{% include 'compensation/detail/eco_account/includes/withdraws.html' %}

View File

@@ -20,11 +20,19 @@ urlpatterns_payment = [
]
urlaptterns_eco_acc = [
path("acc/", eco_account_views.account_index_view, name="acc-index"),
path('acc/new/', eco_account_views.account_new_view, name='acc-new'),
path('acc/<id>', eco_account_views.account_open_view, name='acc-open'),
path('acc/<id>/edit', eco_account_views.account_edit_view, name='acc-edit'),
path('acc/<id>/remove', eco_account_views.account_remove_view, name='acc-remove'),
path("acc/", eco_account_views.index_view, name="acc-index"),
path('acc/new/', eco_account_views.new_view, name='acc-new'),
path('acc/<id>', eco_account_views.open_view, name='acc-open'),
path('acc/<id>/log', eco_account_views.log_view, name='acc-log'),
path('acc/<id>/edit', eco_account_views.edit_view, name='acc-edit'),
path('acc/<id>/remove', eco_account_views.remove_view, name='acc-remove'),
path('acc/<id>/state/new', eco_account_views.state_new_view, name='acc-new-state'),
path('acc/<id>/action/new', eco_account_views.action_new_view, name='acc-new-action'),
path('acc/<id>/deadline/new', eco_account_views.deadline_new_view, name="acc-new-deadline"),
# Documents
# Document remove route can be found in konova/urls.py
path('acc/<id>/document/new/', eco_account_views.new_document_view, name='acc-new-doc'),
# Eco-account withdraws
path('acc/<id>/remove/<withdraw_id>', eco_account_views.withdraw_remove_view, name='withdraw-remove'),
@@ -43,6 +51,7 @@ urlpatterns_compensation = [
path('<id>/deadline/new', compensation_views.deadline_new_view, name="new-deadline"),
# Documents
# Document remove route can be found in konova/urls.py
path('<id>/document/new/', compensation_views.new_document_view, name='new-doc'),
# Generic state routes

View File

@@ -67,7 +67,7 @@ def open_view(request: HttpRequest, id: str):
Returns:
"""
template = "compensation/detail/view.html"
template = "compensation/detail/compensation/view.html"
comp = get_object_or_404(Compensation, id=id)
geom_form = SimpleGeomForm(instance=comp)
_user = request.user

View File

@@ -6,24 +6,26 @@ Created on: 09.08.21
"""
from django.db.models import Sum
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.decorators import login_required
from django.core.exceptions import ObjectDoesNotExist
from django.http import HttpRequest, Http404
from django.shortcuts import render, get_object_or_404
from compensation.forms import NewStateModalForm, NewActionModalForm, NewDeadlineModalForm
from compensation.models import EcoAccount
from compensation.tables import EcoAccountTable
from konova.contexts import BaseContext
from konova.decorators import any_group_check, default_group_required
from konova.forms import RemoveModalForm, SimpleGeomForm
from konova.forms import RemoveModalForm, SimpleGeomForm, NewDocumentForm
from konova.settings import DEFAULT_GROUP, ZB_GROUP, ETS_GROUP
from konova.utils.user_checks import in_group
@login_required
@any_group_check
def account_index_view(request: HttpRequest):
def index_view(request: HttpRequest):
"""
Renders the index view for eco accounts
@@ -51,21 +53,21 @@ def account_index_view(request: HttpRequest):
@login_required
@default_group_required
def account_new_view(request: HttpRequest):
def new_view(request: HttpRequest):
# ToDo
pass
@login_required
@default_group_required
def account_edit_view(request: HttpRequest, id: str):
def edit_view(request: HttpRequest, id: str):
# ToDo
pass
@login_required
@any_group_check
def account_open_view(request: HttpRequest, id: str):
def open_view(request: HttpRequest, id: str):
""" Renders a detail view for a compensation
Args:
@@ -115,11 +117,23 @@ def account_open_view(request: HttpRequest, id: str):
@login_required
def account_remove_view(request: HttpRequest, id: str):
# ToDo
pass
def remove_view(request: HttpRequest, id: str):
""" Renders a modal view for removing the eco account
Args:
request (HttpRequest): The incoming request
id (str): The account's id
Returns:
"""
acc = get_object_or_404(EcoAccount, id=id)
form = RemoveModalForm(request.POST or None, instance=acc, user=request.user)
return form.process_request(
request=request,
msg_success=_("Eco-account removed"),
redirect_url=reverse("compensation:acc-index"),
)
@login_required
@@ -147,3 +161,102 @@ def withdraw_remove_view(request: HttpRequest, id: str, withdraw_id: str):
msg_success=_("Withdraw removed")
)
@login_required
@default_group_required
def log_view(request: HttpRequest, id: str):
""" Renders a log view using modal
Args:
request (HttpRequest): The incoming request
id (str): The eco acount's id
Returns:
"""
comp = get_object_or_404(EcoAccount, id=id)
template = "modal/modal_generic.html"
body_template = "log.html"
context = {
"modal_body_template": body_template,
"log": comp.log.all().order_by("-timestamp"),
"modal_title": _("Log"),
}
context = BaseContext(request, context).context
return render(request, template, context)
@login_required
def state_new_view(request: HttpRequest, id: str):
""" Renders a form for adding new states for an eco account
Args:
request (HttpRequest): The incoming request
id (str): The account's id to which the new state will be related
Returns:
"""
acc = get_object_or_404(EcoAccount, id=id)
form = NewStateModalForm(request.POST or None, instance=acc, user=request.user)
return form.process_request(
request,
msg_success=_("State added")
)
@login_required
def action_new_view(request: HttpRequest, id: str):
""" Renders a form for adding new actions for an eco account
Args:
request (HttpRequest): The incoming request
id (str): The account's id to which the new state will be related
Returns:
"""
acc = get_object_or_404(EcoAccount, id=id)
form = NewActionModalForm(request.POST or None, instance=acc, user=request.user)
return form.process_request(
request,
msg_success=_("Action added")
)
@login_required
def deadline_new_view(request: HttpRequest, id: str):
""" Renders a form for adding new states for an eco account
Args:
request (HttpRequest): The incoming request
id (str): The account's id to which the new state will be related
Returns:
"""
acc = get_object_or_404(EcoAccount, id=id)
form = NewDeadlineModalForm(request.POST or None, instance=acc, user=request.user)
return form.process_request(
request,
msg_success=_("Deadline added")
)
@login_required
def new_document_view(request: HttpRequest, id: str):
""" Renders a form for uploading new documents
Args:
request (HttpRequest): The incoming request
id (str): The account's id to which the new document will be related
Returns:
"""
acc = get_object_or_404(EcoAccount, id=id)
form = NewDocumentForm(request.POST or None, request.FILES or None, instance=acc, user=request.user)
return form.process_request(
request,
msg_success=_("Document added")
)