1
I think you should redefine the Benefit
model, add amount
field which will be automatically calculated based on calculation_type
and custom
fields value in model save
:
class Benefit(models.Model):
employee = models.ForeignKey('Employee')
# this field can be
# Percentage (ex %2 from employee main salary)
# Fixed Price (ex $150)
# days
calculation_type = thetopchoices(FIX,PER,DAYS)
# this field should be the value
# of the percentage or the fixed amount
custom = models.PositiveIntegerField(....)
amount = models.PositiveIntegerField(...., editable=False) # auto calculated field in save
def __init__(self, *args, **kwargs):
super(Benefit, self).__init__(*args, **kwargs)
self.__original_calc_type = self.calculation_type
self.__original_custom = self.custom
def calculate(self):
employee = self.employee
if self.calculation_type == 'PER':
amount = employee.salary * self.custom
elif self.calculation_type == 'FIX':
amount = self.custom
else
amount = ( employee.salary / 30 ) * self.custom
return amount
def save(self, *args, **kwargs):
recalculate = kwargs.pop('recalculate', False)
if self.__original_calc_type != self.calculation_type or self.__original_custom != self.custom or recalculate:
self.amount = self.calculate()
super(Benefit, self).save(*args, **kwargs)
self.__original_calc_type = self.calculation_type
self.__original_custom = self.custom
Now to get the amount of all benefits is easy:
from django.db.models import Sum
class Employee(models.Model):
...
...
@property
def benefits_amount(self):
d = self.benefit_set.aggregate(total_amount=Sum('amount'))
return d['total_amount'] if d['total_amount'] else 0
If you want to update the benefits later based on any criteria you have, you need to do it like this:
for benefit in employee.benefit_set.all():
benefit.save(recalculate=True)
Source:stackexchange.com