Compare commits
No commits in common. "8f2f3f348f4e4d992e287819485b67d049e0d24b" and "974c4dbce57f8716548ccd58e814d9b970715d49" have entirely different histories.
8f2f3f348f
...
974c4dbce5
@ -1,36 +0,0 @@
|
|||||||
# 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,12 +35,6 @@ class EcoAccount(AbstractCompensation, ShareableObjectMixin, RecordableObjectMix
|
|||||||
help_text="Amount of deductable surface - can be lower than the total surface due to deduction limitations",
|
help_text="Amount of deductable surface - can be lower than the total surface due to deduction limitations",
|
||||||
default=0,
|
default=0,
|
||||||
)
|
)
|
||||||
deductable_rest = models.FloatField(
|
|
||||||
blank=True,
|
|
||||||
null=True,
|
|
||||||
help_text="Amount of deductable rest",
|
|
||||||
default=0,
|
|
||||||
)
|
|
||||||
|
|
||||||
legal = models.OneToOneField(
|
legal = models.OneToOneField(
|
||||||
"intervention.Legal",
|
"intervention.Legal",
|
||||||
@ -106,22 +100,28 @@ class EcoAccount(AbstractCompensation, ShareableObjectMixin, RecordableObjectMix
|
|||||||
"""
|
"""
|
||||||
return self.after_states.all().aggregate(Sum("surface"))["surface__sum"] or 0
|
return self.after_states.all().aggregate(Sum("surface"))["surface__sum"] or 0
|
||||||
|
|
||||||
def __calculate_deductable_rest(self):
|
def get_available_rest(self) -> (float, float):
|
||||||
""" Calculates available rest surface of the eco account
|
""" Calculates available rest surface of the eco account
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
ret_val_total (float): Total amount
|
ret_val_total (float): Total amount
|
||||||
|
ret_val_relative (float): Amount as percentage (0-100)
|
||||||
"""
|
"""
|
||||||
deductions = self.deductions.filter(
|
deductions = self.deductions.filter(
|
||||||
intervention__deleted=None,
|
intervention__deleted=None,
|
||||||
)
|
)
|
||||||
deductions_surfaces = deductions.aggregate(Sum("surface"))["surface__sum"] or 0
|
deductions_surfaces = deductions.aggregate(Sum("surface"))["surface__sum"] or 0
|
||||||
available_surfaces = self.deductable_surface or deductions_surfaces ## no division by zero
|
available_surfaces = self.deductable_surface or deductions_surfaces ## no division by zero
|
||||||
ret_val = available_surfaces - deductions_surfaces
|
ret_val_total = available_surfaces - deductions_surfaces
|
||||||
|
|
||||||
return ret_val
|
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
|
||||||
|
|
||||||
def quality_check(self) -> EcoAccountQualityChecker:
|
def quality_check(self) -> EcoAccountQualityChecker:
|
||||||
""" Quality check
|
""" Quality check
|
||||||
@ -181,29 +181,6 @@ class EcoAccount(AbstractCompensation, ShareableObjectMixin, RecordableObjectMix
|
|||||||
for team_id in shared_teams:
|
for team_id in shared_teams:
|
||||||
celery_send_mail_deduction_changed_team.delay(self.identifier, self.title, team_id, data_change)
|
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):
|
class EcoAccountDocument(AbstractDocument):
|
||||||
"""
|
"""
|
||||||
@ -295,8 +272,3 @@ class EcoAccountDeduction(BaseResource):
|
|||||||
self.intervention.mark_as_edited(user, edit_comment=DEDUCTION_REMOVED)
|
self.intervention.mark_as_edited(user, edit_comment=DEDUCTION_REMOVED)
|
||||||
self.account.mark_as_edited(user, edit_comment=DEDUCTION_REMOVED)
|
self.account.mark_as_edited(user, edit_comment=DEDUCTION_REMOVED)
|
||||||
super().delete(*args, **kwargs)
|
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(
|
av = tables.Column(
|
||||||
verbose_name=_("Available"),
|
verbose_name=_("Available"),
|
||||||
orderable=True,
|
orderable=True,
|
||||||
accessor="deductable_rest",
|
empty_values=[],
|
||||||
attrs={
|
attrs={
|
||||||
"th": {
|
"th": {
|
||||||
"class": "w-20",
|
"class": "w-20",
|
||||||
@ -100,16 +100,13 @@ class EcoAccountTable(BaseTable, TableRenderMixin):
|
|||||||
""" Renders the available column for an eco account
|
""" Renders the available column for an eco account
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
value (float): The deductable_rest
|
value (str): The identifier value
|
||||||
record (EcoAccount): The eco account record
|
record (EcoAccount): The eco account record
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
value_total, value_relative = record.get_available_rest()
|
||||||
value_relative = record.get_deductable_rest_relative()
|
|
||||||
except ZeroDivisionError:
|
|
||||||
value_relative = 0
|
|
||||||
html = render_to_string("konova/widgets/progressbar.html", {"value": value_relative})
|
html = render_to_string("konova/widgets/progressbar.html", {"value": value_relative})
|
||||||
return format_html(html)
|
return format_html(html)
|
||||||
|
|
||||||
|
@ -230,7 +230,7 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
|
|||||||
self.assertTrue(self.intervention.log.first().action == UserAction.EDITED)
|
self.assertTrue(self.intervention.log.first().action == UserAction.EDITED)
|
||||||
|
|
||||||
def test_edit_deduction(self):
|
def test_edit_deduction(self):
|
||||||
test_surface = self.eco_account.deductable_rest
|
test_surface = self.eco_account.get_available_rest()[0]
|
||||||
self.eco_account.set_recorded(self.superuser)
|
self.eco_account.set_recorded(self.superuser)
|
||||||
self.intervention.share_with_user(self.superuser)
|
self.intervention.share_with_user(self.superuser)
|
||||||
self.eco_account.refresh_from_db()
|
self.eco_account.refresh_from_db()
|
||||||
|
@ -200,8 +200,7 @@ def detail_view(request: HttpRequest, id: str):
|
|||||||
sum_after_states = after_states.aggregate(Sum("surface"))["surface__sum"] or 0
|
sum_after_states = after_states.aggregate(Sum("surface"))["surface__sum"] or 0
|
||||||
diff_states = abs(sum_before_states - sum_after_states)
|
diff_states = abs(sum_before_states - sum_after_states)
|
||||||
# Calculate rest of available surface for deductions
|
# Calculate rest of available surface for deductions
|
||||||
available_total = acc.deductable_rest
|
available_total, available_relative = acc.get_available_rest()
|
||||||
available_relative = acc.get_deductable_rest_relative()
|
|
||||||
|
|
||||||
# Prefetch related data to decrease the amount of db connections
|
# Prefetch related data to decrease the amount of db connections
|
||||||
deductions = acc.deductions.filter(
|
deductions = acc.deductions.filter(
|
||||||
|
Loading…
Reference in New Issue
Block a user