Dharmik
Dharmik

Reputation: 13

DateTimeField & TimeField Error

My code is working perfectly working fine but due to my change in requirements I had to make DateTimeField to TimeField but after making the changes in my code I faced following error.

Exception Value: unsupported operand type(s) for -: 'datetime.time' and 'datetime.time'

My code is about salary calculation.

class salary(models.Model):
#employee = models.ForeignKey('employee', on_delete=models.CASCADE)
base_salary = models.IntegerField(default=0)
time_in = models.DateTimeField(default=tz.now, null=True, blank=True)
time_out = models.DateTimeField(default=tz.now, null=True, blank=True)
total_salary = models.CharField(max_length=20, default='0')

def calculate_salary(self):
    worked_hours = (self.time_out - self.time_in).total_seconds() / 60 / 60
    overtime_hours = 0

    # make sure you use timezone aware objects
    # https://docs.djangoproject.com/en/2.0/topics/i18n/timezones/#naive-and-aware-datetime-objects
    same_day_8pm = self.time_out.replace(hour=16, minute=0, second=0, microsecond=0)
    if self.time_out > same_day_8pm:
        overtime_hours = (self.time_out - same_day_8pm).total_seconds() / 60 / 60

    salary_1 = worked_hours * self.base_salary
    salary_2 = overtime_hours * self.base_salary * 0.2
    total_salary = salary_1 + salary_2

    # careful: this will be a 'float', not an 'int'
    # with round() using 0 decimal digits you get an 'int'
    # total_salary = round(total_salary, 0)

    return total_salary

def save(self,*args,**kwargs):
    # are you really sure that you want to save a string ???
    self.total_salary = str(self.calculate_salary())
    super().save(*args, **kwargs)

Upvotes: 1

Views: 322

Answers (1)

RishiG
RishiG

Reputation: 2830

Python datetime.datetime objects can be subtracted, but datetime.time objects can't. You can subtract them by combining them into datetime objects using the current date (see, e.g., https://stackoverflow.com/a/5259921/2715819). Specifically, try changing

worked_hours = (self.time_out - self.time_in).total_seconds() / 60 / 60

to:

datetime_in = datetime.combine(date.min, self.time_in)
datetime_out = datetime.combine(date.min, self.time_out)
worked_hours = (datetime_out - datetime_in).total_seconds() / 60 / 60

You'll also have to add from datetime import datetime, date at the top of your file. You'll have to change the calculation of overtime_hours to use datetime_out instead of self.time_out, too.

Upvotes: 1

Related Questions