Eco Account deduction

* adds deductable_surface to EcoAccount model to provide an easy way to change the deductable amount from an account -> depends on external funding e.g. with AktionBlau or similar
* adds overview of deducted and deductable volume to detail view
* adds check to eco account model, so the deductable_surface can never be larger than the total amount of after_state surface sum
* adds german formating for python logic based number formating
* adds/updates translations
This commit is contained in:
mipel
2021-09-17 13:33:51 +02:00
parent e1ffc53958
commit fbcb2d9afd
5 changed files with 236 additions and 168 deletions

View File

@@ -9,6 +9,7 @@ import shutil
from django.contrib.auth.models import User
from django.contrib.gis.db import models
from django.core.exceptions import ValidationError
from django.core.validators import MinValueValidator
from django.db.models import Sum, QuerySet
from django.utils.translation import gettext_lazy as _
@@ -281,9 +282,22 @@ class EcoAccount(AbstractCompensation):
related_name="+"
)
deductable_surface = models.FloatField(
blank=True,
null=True,
help_text="Amount of deductable surface - can be lower than the total surface due to deduction limitations",
default=0,
)
def __str__(self):
return "{}".format(self.identifier)
def clean(self):
# Deductable surface can not be larger than added states after surface
after_state_sum = self.get_state_after_surface_sum()
if self.deductable_surface > after_state_sum:
raise ValidationError(_("Deductable surface can not be larger than existing surfaces in after states"))
def save(self, *args, **kwargs):
if self.identifier is None or len(self.identifier) == 0:
# Create new identifier
@@ -293,15 +307,34 @@ class EcoAccount(AbstractCompensation):
self.identifier = new_id
super().save(*args, **kwargs)
@property
def deductions_surface_sum(self) -> float:
""" Shortcut for get_deductions_surface.
Can be used in templates
Returns:
sum_surface (float)
"""
return self.get_deductions_surface()
def get_deductions_surface(self) -> float:
""" Calculates the account's deductions sum surface
""" Calculates the account's deductions surface sum
Returns:
sum_surface (float)
"""
return self.deductions.all().aggregate(Sum("surface"))["surface__sum"] or 0
def get_available_rest(self, as_percentage: bool = False):
def get_state_after_surface_sum(self) -> float:
""" Calculates the account's after state surface sum
Returns:
sum_surface (float)
"""
return self.after_states.all().aggregate(Sum("surface"))["surface__sum"] or 0
def get_available_rest(self, as_percentage: bool = False) -> float:
""" Calculates available rest surface of the eco account
Args:
@@ -310,17 +343,16 @@ class EcoAccount(AbstractCompensation):
Returns:
"""
ret_val = 0
deductions = self.deductions.filter(
intervention__deleted=None,
)
deductions_surfaces = deductions.aggregate(Sum("surface"))["surface__sum"] or 0
after_states_surfaces = self.after_states.all().aggregate(Sum("surface"))["surface__sum"] or deductions_surfaces ## no division by zero
ret_val = after_states_surfaces - deductions_surfaces
available_surfaces = self.deductable_surface or deductions_surfaces ## no division by zero
ret_val = available_surfaces - deductions_surfaces
if as_percentage:
if after_states_surfaces > 0:
ret_val = int((ret_val / after_states_surfaces) * 100)
if available_surfaces > 0:
ret_val = int((ret_val / available_surfaces) * 100)
else:
ret_val = 0
return ret_val

View File

@@ -33,6 +33,7 @@
<tr>
<th scope="row">{% trans 'Available' %}</th>
<td class="align-middle">
{{obj.deductions_surface_sum|floatformat:2}} / {{obj.deductable_surface|floatformat:2}} m²
{% with available as value %}
{% include 'konova/custom_widgets/progressbar.html' %}
{% endwith %}