# Calculate complete duration of several time periods

Hi once more, folks,

my “daily problem” today is a quite simple one i think and i should have managed it by myself but it seems my brains has quit working for today…

i try to automatically calculate the Sum of active Duration of one or more Employments an Employee had over the time within a company.

This is the model for it:

``````class Employments(models.Model):

status = models.CharField(max_length=50)
work_time_model = models.CharField(max_length=50)
weekly_hours = models.FloatField(default=41)
percent = models.FloatField(default=100)
duty_begin = models.DateField(blank=True)
duty_end = models.DateField(null=True, blank=True)

objects = WorkYearsManager()
``````

and i try to achieve it with this `WorkYearsManage` :

``````class WorkYearsManager(models.Manager):

def with_ongoing_years(self):
today = datetime.date.today()
return self.annotate(
ongoing_years=ExpressionWrapper(
(today - F('duty_begin')), output_field=fields.FloatField()
# Sekunden auf Jahre umrechnen
)/86400/365.2425/1000000*F('percent')/100
)

def with_past_years(self):
return self.annotate(
past_years=ExpressionWrapper(
(F('duty_end') - F('duty_begin')), output_field=fields.FloatField()
# Sekunden auf Jahre umrechnen
) / 86400 / 365.2425 / 1000000*F('percent')/100
)

def total_work_years(self, employee):
ongoing_years =  self.with_ongoing_years().filter(employee=employee).aggregate(Sum('ongoing_years'))
past_years = self.with_past_years().filter(employee=employee).aggregate(Sum('past_years'))
total = ongoing_years | past_years
total_work_years = sum(total.values())
``````

so, concerning the `past_years`, everything is working as intended, concerning the `ongoing_years` ,I have to manage, that only the actual employment is calculated. At the moment, i get an result from the earliest `duty_begin`until today…

edit:
so, I am aware that the code will throw an error if either `ongoing_years` or `past_years` is None.

``````
def total_work_years(self, employee):
ongoing_years = self.with_ongoing_years().filter(employee=employee).aggregate(Sum('ongoing_years'))
past_years = self.with_past_years().filter(employee=employee).aggregate(Sum('past_years'))

ongoing_years = {} if not all(ongoing_years.values()) is True else ongoing_years
past_years = {} if not all(past_years.values()) is True else past_years
total_work_years = sum((ongoing_years | past_years).values())

``````

Thx to everyone who was thinking about it. solved it myself in the meantime:

``````class WorkYearsManager(models.Manager):

def with_past_years(self):
return self.annotate(
past_years=ExpressionWrapper(
(F('duty_end') - F('duty_begin')), output_field=fields.FloatField()
# Sekunden auf Jahre umrechnen
) / 86400 / 365.2425 / 1000000*F('percent')/100
)

def total_work_years(self, employee):

ongoing_years = {}
today = datetime.date.today()
latest_employment = self.filter(employee=employee).latest('duty_begin')
if latest_employment.duty_end is None:
percent = self.filter(employee=employee).latest('duty_begin').percent
sum_ongoing = (today - latest_employment.duty_begin).days * (percent / 100) / 365.2425
ongoing_years = {'ongoing_years__sum': sum_ongoing}

past_years = self.with_past_years().filter(employee=employee).aggregate(Sum('past_years'))

# if None in Dictionary:
past_years = {} if not all(past_years.values()) is True else past_years

total_work_years = sum((ongoing_years | past_years).values())