4

I have three fields start_date, end_date and total_days.

If i enter start_date and end_date field it should automatically display total_days.

This is my Function which is not working.

<field name="start_date" on_change="get_number_of_days(start_date,end_date)"/>
<field name="end_date" on_change="get_number_of_days(end_date,start_date)"/>
<field name="total_days" />

def get_number_of_days(self, cr, uid, ids, start_date, end_date):
        """Returns a float equals to the timedelta between two dates given as string."""
        result = self.browse(cr, uid, ids)
        if (end_date and start_date) and (start_date <= end_date):
            DATETIME_FORMAT = "%d/%m/%Y %H:%M:%S"
            from_dt = datetime.datetime.strptime(start_date, DATETIME_FORMAT)
            to_dt = datetime.datetime.strptime(end_date, DATETIME_FORMAT)
            timedelta = to_dt - from_dt
            diff_day = timedelta.days + float(timedelta.seconds) / 86400
            result['value']['total_days'] = round(math.floor(diff_day))+1
        return result 

Is there any other method? or what may be the issue

Rohan Amrute
  • 764
  • 1
  • 9
  • 23
iam supreeth
  • 497
  • 4
  • 16

3 Answers3

2

The section:

        diff_day = timedelta.days + float(timedelta.seconds) / 86400
        result['value']['total_days'] = round(math.floor(diff_day))+1

is largely unnecessary as datetime.timedelta already has the number of whole days as a value timedelta.days - I suspect that your problem is that you are not converting to a string try:

         result['value']['total_days'] = str(timedelta.days)

You should also consider catching problems when the strptime function cannot convert the current value, e.g. when it is blank.

Steve Barnes
  • 27,618
  • 6
  • 63
  • 73
2

If your dates are given as strings (as your docstring says), the second part of your conditional may behave unexpectedly (depending on the date/time formatting), because you perform a lexicographical comparison:

if (end_date and start_date) and (start_date <= end_date):
    # ...

You should convert them to datetime-objects first and then check your conditional.

jbndlr
  • 4,965
  • 2
  • 21
  • 31
0

Thank You,

I wrote new function for this which helped to give total days:

def _get_days(self, cr, uid, ids, field_name, arg ,context=None):
        res = {}
        fmt = '%Y-%m-%d'
        for object in self.browse(cr, uid, ids, context=context):
            res[object.id] = {'total_days':0, } 
            from_date = object.start_date 
            to_date = object.end_date
            d1 = datetime.strptime(from_date, fmt)
            d2 = datetime.strptime(to_date, fmt)
            daysDiff = str((d2-d1).days+1)
            res[object.id]['total_days'] = daysDiff
            return res

'start_date': fields.date('Start Date', required=True),
        'end_date': fields.date('End Date', required=True),
        'total_days': fields.function(_get_days, string="Diff days", multi='sums', store=True),
iam supreeth
  • 497
  • 4
  • 16