Merge pull request 'fix_acc_sorting_availability' (#218) from fix_acc_sorting_availability into master
Reviewed-on: SGD-Nord/konova#218
This commit is contained in:
commit
ac443bd9eb
36
compensation/migrations/0011_ecoaccount_deductable_rest.py
Normal file
36
compensation/migrations/0011_ecoaccount_deductable_rest.py
Normal file
@ -0,0 +1,36 @@
|
||||
# Generated by Django 3.1.3 on 2022-10-11 11:39
|
||||
|
||||
from django.db import migrations, models
|
||||
from django.db.models import Sum
|
||||
|
||||
|
||||
def fill_deductable_rest(apps, schema_editor):
|
||||
EcoAccount = apps.get_model("compensation", "EcoAccount")
|
||||
accs = EcoAccount.objects.all()
|
||||
for acc in accs:
|
||||
|
||||
deductions = acc.deductions.filter(
|
||||
intervention__deleted=None,
|
||||
)
|
||||
deductions_surfaces = deductions.aggregate(Sum("surface"))["surface__sum"] or 0
|
||||
available_surfaces = acc.deductable_surface or deductions_surfaces
|
||||
rest = available_surfaces - deductions_surfaces
|
||||
|
||||
acc.deductable_rest = rest
|
||||
acc.save()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('compensation', '0010_auto_20220815_1030'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='ecoaccount',
|
||||
name='deductable_rest',
|
||||
field=models.FloatField(blank=True, default=0, help_text='Amount of deductable rest', null=True),
|
||||
),
|
||||
migrations.RunPython(fill_deductable_rest)
|
||||
]
|
@ -35,6 +35,12 @@ class EcoAccount(AbstractCompensation, ShareableObjectMixin, RecordableObjectMix
|
||||
help_text="Amount of deductable surface - can be lower than the total surface due to deduction limitations",
|
||||
default=0,
|
||||
)
|
||||
deductable_rest = models.FloatField(
|
||||
blank=True,
|
||||
null=True,
|
||||
help_text="Amount of deductable rest",
|
||||
default=0,
|
||||
)
|
||||
|
||||
legal = models.OneToOneField(
|
||||
"intervention.Legal",
|
||||
@ -100,28 +106,22 @@ class EcoAccount(AbstractCompensation, ShareableObjectMixin, RecordableObjectMix
|
||||
"""
|
||||
return self.after_states.all().aggregate(Sum("surface"))["surface__sum"] or 0
|
||||
|
||||
def get_available_rest(self) -> (float, float):
|
||||
def __calculate_deductable_rest(self):
|
||||
""" Calculates available rest surface of the eco account
|
||||
|
||||
Args:
|
||||
|
||||
Returns:
|
||||
ret_val_total (float): Total amount
|
||||
ret_val_relative (float): Amount as percentage (0-100)
|
||||
"""
|
||||
deductions = self.deductions.filter(
|
||||
intervention__deleted=None,
|
||||
)
|
||||
deductions_surfaces = deductions.aggregate(Sum("surface"))["surface__sum"] or 0
|
||||
available_surfaces = self.deductable_surface or deductions_surfaces ## no division by zero
|
||||
ret_val_total = available_surfaces - deductions_surfaces
|
||||
ret_val = available_surfaces - deductions_surfaces
|
||||
|
||||
if available_surfaces > 0:
|
||||
ret_val_relative = int((ret_val_total / available_surfaces) * 100)
|
||||
else:
|
||||
ret_val_relative = 0
|
||||
|
||||
return ret_val_total, ret_val_relative
|
||||
return ret_val
|
||||
|
||||
def quality_check(self) -> EcoAccountQualityChecker:
|
||||
""" Quality check
|
||||
@ -181,6 +181,29 @@ class EcoAccount(AbstractCompensation, ShareableObjectMixin, RecordableObjectMix
|
||||
for team_id in shared_teams:
|
||||
celery_send_mail_deduction_changed_team.delay(self.identifier, self.title, team_id, data_change)
|
||||
|
||||
def update_deductable_rest(self):
|
||||
"""
|
||||
Updates deductable_rest, which holds the amount of rest surface for this account.
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
self.deductable_rest = self.__calculate_deductable_rest()
|
||||
self.save()
|
||||
|
||||
def get_deductable_rest_relative(self):
|
||||
"""
|
||||
Returns deductable_rest relative to deductable_surface mapped to [0,100]
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
try:
|
||||
ret_val = int((self.deductable_rest / (self.deductable_surface or 0)) * 100)
|
||||
except ZeroDivisionError:
|
||||
ret_val = 0
|
||||
return ret_val
|
||||
|
||||
|
||||
class EcoAccountDocument(AbstractDocument):
|
||||
"""
|
||||
@ -272,3 +295,8 @@ class EcoAccountDeduction(BaseResource):
|
||||
self.intervention.mark_as_edited(user, edit_comment=DEDUCTION_REMOVED)
|
||||
self.account.mark_as_edited(user, edit_comment=DEDUCTION_REMOVED)
|
||||
super().delete(*args, **kwargs)
|
||||
self.account.update_deductable_rest()
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
super().save(*args, **kwargs)
|
||||
self.account.update_deductable_rest()
|
||||
|
@ -37,7 +37,7 @@ class EcoAccountTable(BaseTable, TableRenderMixin):
|
||||
av = tables.Column(
|
||||
verbose_name=_("Available"),
|
||||
orderable=True,
|
||||
empty_values=[],
|
||||
accessor="deductable_rest",
|
||||
attrs={
|
||||
"th": {
|
||||
"class": "w-20",
|
||||
@ -100,13 +100,16 @@ class EcoAccountTable(BaseTable, TableRenderMixin):
|
||||
""" Renders the available column for an eco account
|
||||
|
||||
Args:
|
||||
value (str): The identifier value
|
||||
value (float): The deductable_rest
|
||||
record (EcoAccount): The eco account record
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
value_total, value_relative = record.get_available_rest()
|
||||
try:
|
||||
value_relative = record.get_deductable_rest_relative()
|
||||
except ZeroDivisionError:
|
||||
value_relative = 0
|
||||
html = render_to_string("konova/widgets/progressbar.html", {"value": value_relative})
|
||||
return format_html(html)
|
||||
|
||||
|
@ -230,7 +230,7 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
|
||||
self.assertTrue(self.intervention.log.first().action == UserAction.EDITED)
|
||||
|
||||
def test_edit_deduction(self):
|
||||
test_surface = self.eco_account.get_available_rest()[0]
|
||||
test_surface = self.eco_account.deductable_rest
|
||||
self.eco_account.set_recorded(self.superuser)
|
||||
self.intervention.share_with_user(self.superuser)
|
||||
self.eco_account.refresh_from_db()
|
||||
|
@ -200,7 +200,8 @@ def detail_view(request: HttpRequest, id: str):
|
||||
sum_after_states = after_states.aggregate(Sum("surface"))["surface__sum"] or 0
|
||||
diff_states = abs(sum_before_states - sum_after_states)
|
||||
# Calculate rest of available surface for deductions
|
||||
available_total, available_relative = acc.get_available_rest()
|
||||
available_total = acc.deductable_rest
|
||||
available_relative = acc.get_deductable_rest_relative()
|
||||
|
||||
# Prefetch related data to decrease the amount of db connections
|
||||
deductions = acc.deductions.filter(
|
||||
|
Loading…
Reference in New Issue
Block a user